介绍
ECharts 是一款由百度开源的,基于 JavaScript 的可视化图表库,它提供了丰富的图表类型和强大的交互功能,能将数据以直观、美观的图表形式展示出来,广泛应用于数据可视化、商业智能、数据分析等领域。
官网: Apache ECharts
优势:
- 丰富的图表类型:ECharts 提供了多种图表类型,包括柱状图、折线图、饼图、散点图、地图、雷达图等。每种图表类型都有多种样式和配置选项,可以满足不同数据展示需求。
- 高度可定制化:用户可以通过配置项对图表进行高度定制,包括图表的颜色、字体、线条样式、标记样式等。还可以自定义图表的标题、坐标轴、图例、提示框等组件的样式和布局。
- 数据驱动的可视化:ECharts 通过简单的数据格式,将数据与图表进行绑定。数据的变化会实时驱动图表的更新,方便用户动态展示数据。
- 良好的交互性:支持数据钻取、缩放、平移、筛选等交互操作,能让用户通过交互深入探索数据。还可以为图表元素绑定事件,实现更复杂的交互效果。
- 跨平台兼容:能在多种设备和平台上使用,包括桌面浏览器、移动设备等,并且能够自适应不同的屏幕尺寸,提供一致的可视化体验。
基本使用步骤:
- 引入 ECharts 库:在 HTML 页面中通过
<script>
标签引入 ECharts 的 JavaScript 文件。 - 创建图表容器:在 HTML 中创建一个具有固定宽高的 DOM 元素,作为图表的容器。
- 初始化图表:在 JavaScript 代码中,使用
echarts.init()
方法初始化图表实例,并传入图表容器元素。 - 配置图表:通过设置配置项来定义图表的各种属性,如标题、坐标轴、系列数据等。
- 渲染图表:使用图表实例的
setOption()
方法传入配置项,将图表渲染到页面上。
应用场景:
- 数据可视化分析:在数据分析和业务报表中,用于将数据以直观的图表形式展示出来,帮助用户快速理解数据的分布、趋势和关系,发现数据中的问题和规律。
- 数据监控与预警:在实时数据监控系统中,通过 ECharts 实时更新图表,展示系统的运行状态和关键指标的变化情况,当指标超出阈值时进行预警。
- 数据可视化展示:在数据可视化大屏、展览展示等场景中,使用 ECharts 创建出美观、炫酷的图表,展示数据的魅力,吸引观众的注意力。
- 数据可视化应用:在各种 Web 应用程序中,嵌入 ECharts 图表,为用户提供数据可视化的功能,增强应用程序的用户体验和数据展示效果。
项目中的应用:
1. 引入 echarts
库
在 HTML 文件的 <head>
标签里引入 echarts
库:
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"></script>
这一操作会加载 echarts
库,进而在页面里使用其功能
2. 准备图表容器
在 HTML 文件的 <body>
标签中,创建两个用于放置图表的 <div>
容器
<div class="main-content"><div id="barChart" class="chart-container"></div><div id="pieChart" class="chart-container"></div>
</div>
每个 <div>
容器都有独一无二的 id
(barChart
和 pieChart
),这便于在 JavaScript 代码中定位这些容器。
3. 从后端获取数据
在 JavaScript 代码中,使用 $.ajax
方法从后端获取数据:
$.ajax({url: 'GetSalesDataServlet',type: 'GET',success: function (response) {// 处理成功响应},error: function (error) {// 处理错误响应}
});
此方法会向后端的 GetSalesDataServlet
发送一个 GET
请求,若请求成功,就会在 success
回调函数里处理返回的数据;若请求失败,则会在 error
回调函数里处理错误。
4. 提取数据
在 success
回调函数中,从后端返回的数据里提取类别和销售数量:
const dataList = response.data || [];
const categories = dataList.map(item => item.classfily);
const sales = dataList.map(item => {const count = parseInt(item.sales_count);return isNaN(count)? 0 : count;
});
categories
数组包含书籍的类别,sales
数组包含每个类别的销售数量。
5. 初始化柱状图
定义 initBarChart
函数来初始化柱状图:
function initBarChart(categories, sales) {const barChart = echarts.init(document.getElementById('barChart'));const barOption = {title: {text: '不同类型书籍销售情况'},tooltip: {trigger: 'axis',axisPointer: {type:'shadow'}},xAxis: {type: 'category',data: categories},yAxis: {type: 'value'},series: [{data: sales,type: 'bar'}]};barChart.setOption(barOption);
}
echarts.init
方法会初始化一个echarts
实例,关联到barChart
容器。barOption
对象定义了柱状图的配置选项,像标题、提示框、坐标轴和系列数据等。barChart.setOption(barOption)
方法会将配置选项应用到echarts
实例上,从而绘制出柱状图。
6. 初始化饼图
定义 initPieChart
函数来初始化饼图:
function initPieChart(categories, sales) {const pieChart = echarts.init(document.getElementById('pieChart'));const totalSales = sales.reduce((sum, value) => sum + value, 0);const pieData = categories.map((category, index) => {return {value: sales[index],name: category};});const pieOption = {title: {text: '不同类型书籍销售占比'},tooltip: {trigger: 'item'},series: [{name: '销售占比',type: 'pie',radius: '50%',data: pieData}]};pieChart.setOption(pieOption);
}
echarts.init
方法会初始化一个echarts
实例,关联到pieChart
容器。pieData
数组包含每个类别的销售数量和名称。pieOption
对象定义了饼图的配置选项,像标题、提示框和系列数据等。pieChart.setOption(pieOption)
方法会将配置选项应用到echarts
实例上,进而绘制出饼图。
GetSalesDataServlet
package com.qcby.order;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.qcby.db.MysqlUtil;@WebServlet("/GetSalesDataServlet")
public class GetSalesDataServlet extends HttpServlet {private static final long serialVersionUID = 1L;public GetSalesDataServlet() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 定义 SQL 语句(关联表查询,统计各分类的销售数量)String sql = "SELECT bc.classfily, COUNT(o.id) AS sales_count " +"FROM orders o " +"JOIN books b ON o.bid = b.id " +"JOIN book_categories bc ON b.cid = bc.id " +"GROUP BY bc.classfily";// 定义列名数组(与 SQL 中的 SELECT 字段顺序一致)String[] columns = {"classfily", "sales_count"};// 使用 MysqlUtil 直接获取 JSON 数据String jsonData = MysqlUtil.getJsonBySql(sql, columns);// 设置响应格式并返回数据response.setContentType("text/json;charset=utf-8");response.getWriter().write(jsonData);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
问题:
1. const categories = dataList.map(item => item.classfily);
这段 JavaScript 代码使用map()
方法遍历dataList
数组,并将每个元素的classfily
属性提取出来,组成一个新的数组categories
。
-
map()
方法:map()
是 JavaScript 数组的一个方法,它会对数组中的每个元素执行一个给定的函数,并返回一个新的数组,其中包含了每个元素执行函数后的结果。
-
箭头函数:
item => item.classfily
是一个箭头函数,它接受一个参数item
,表示dataList
数组中的每个元素。- 箭头函数的返回值是
item.classfily
,即每个元素的classfily
属性。
-
执行过程:
map()
方法会遍历dataList
数组中的每个元素,并将每个元素传递给箭头函数。- 箭头函数会返回每个元素的
classfily
属性,map()
方法会将这些返回值组成一个新的数组categories
。
const dataList = [{ classfily: '小说', sales_count: 100 },{ classfily: '传记', sales_count: 50 },{ classfily: '历史', sales_count: 75 }
];
const categories = ['小说', '传记', '历史'];
2.const sales = dataList.map(item => { // 确保 sales_count 能正确转换为数字 const count = parseInt(item.sales_count); return isNaN(count)? 0 : count; });
这段 JavaScript 代码使用map()
方法遍历dataList
数组,并将每个元素的sales_count
属性转换为数字类型。如果转换失败,则将其设置为 0。
-
map()
方法:map()
是 JavaScript 数组的一个方法,它会对数组中的每个元素执行一个给定的函数,并返回一个新的数组,其中包含了每个元素执行函数后的结果。
-
箭头函数:
item => {... }
是一个箭头函数,它接受一个参数item
,表示dataList
数组中的每个元素。- 箭头函数的返回值是经过处理后的
sales_count
属性值。
-
parseInt()
函数:parseInt(item.sales_count)
用于将item.sales_count
转换为整数类型。如果转换成功,则返回转换后的整数;如果转换失败,则返回NaN
(Not a Number)。
-
isNaN()
函数:isNaN(count)
用于检查count
是否为NaN
。如果是,则返回true
;否则返回false
。
-
三元运算符:
isNaN(count)? 0 : count
是一个三元运算符,它根据isNaN(count)
的结果来返回不同的值。如果count
是NaN
,则返回 0;否则返回count
。
-
执行过程:
map()
方法会遍历dataList
数组中的每个元素,并将每个元素传递给箭头函数。- 箭头函数会将每个元素的
sales_count
属性转换为整数类型,并使用isNaN()
函数检查转换结果。如果转换失败,则将其设置为 0。 - 箭头函数会返回经过处理后的
sales_count
属性值,map()
方法会将这些返回值组成一个新的数组sales
。
const dataList = [{ classfily: '小说', sales_count: '100' },{ classfily: '传记', sales_count: '50' },{ classfily: '历史', sales_count: 'abc' }
];
const sales = [100, 50, 0];