ECharts图表参数配置与SQL查询数据联动 - 第3节
3.1 折线图与柱状图:数据可视化的两大基石
折线图(Line Chart)与柱状图(Bar Chart)是 ECharts 中最基础、使用频率最高的两种图表类型。它们分别擅长展示数据趋势与数据对比。本章将深入剖析这两种核心图表的参数配置,并结合 SQL 查询数据联动的实际场景,帮助你掌握从数据获取到图表渲染的完整链路。
3.2 折线图参数配置详解
折线图通过连接数据点的线段来展示数据随时间或有序类别变化的趋势。在 ECharts 中,折线图的系列类型为 type: 'line'。以下从基础配置、样式增强、标记与辅助线三个维度进行拆解。
3.2.1 基础折线图配置
一个最简单的折线图至少需要 xAxis、yAxis 和 series 三个核心组件。以下是一个从 SQL 查询结果映射到折线图的典型配置:
// 假设从 SQL 查询得到的数据
const sqlResult = [
{ month: '2024-01', sales: 1200 },
{ month: '2024-02', sales: 1350 },
{ month: '2024-03', sales: 1100 },
{ month: '2024-04', sales: 1500 },
{ month: '2024-05', sales: 1700 }
];
// ECharts 配置
option = {
xAxis: {
type: 'category',
data: sqlResult.map(item => item.month), // 从 SQL 数据提取
axisLabel: { rotate: 30 } // 标签旋转防重叠
},
yAxis: {
type: 'value',
name: '销售额 (万元)'
},
series: [{
type: 'line',
data: sqlResult.map(item => item.sales),
smooth: true, // 平滑曲线
lineStyle: { width: 3, color: '#3498db' },
symbol: 'circle',
symbolSize: 8
}],
tooltip: {
trigger: 'axis',
formatter: function(params) {
return `${params[0].axisValue}<br/>销售额:${params[0].value} 万元`;
}
}
};
- smooth:布尔值,控制折线是否平滑。设为
true时使用贝塞尔曲线拟合,适合展示连续变化趋势。 - symbol:数据标记点形状,可选
'circle'、'rect'、'diamond'、'triangle'等,也可设为'none'隐藏。 - lineStyle.type:线型,支持
'solid'、'dashed'、'dotted'。
3.2.2 折线图高级标记:markPoint 与 markLine
在实际业务中,我们经常需要高亮显示数据的最大值、最小值或平均值。ECharts 提供了 markPoint 和 markLine 来实现这一需求。
| 参数 | 子属性 | 说明 | 示例值 |
|---|---|---|---|
| markPoint | data.type | 标记点类型:'max' / 'min' / 'average' | { type: 'max', name: '最大值' } |
| symbol | 标记点形状,默认 'pin' 图钉 | 'circle' |
|
| symbolSize | 标记点大小 | 50 |
|
| markLine | data.type | 标记线类型:'average' / 'min' / 'max' | { type: 'average', name: '平均值' } |
| lineStyle | 标记线样式 | { color: '#e74c3c', type: 'dashed' } |
|
| label | 标记线标签显示 | { formatter: '均值: {c}' } |
// 在 series 中添加 markPoint 和 markLine
series: [{
type: 'line',
data: [1200, 1350, 1100, 1500, 1700],
markPoint: {
data: [
{ type: 'max', name: '最高销售额' },
{ type: 'min', name: '最低销售额' }
]
},
markLine: {
data: [
{ type: 'average', name: '平均销售额' }
],
lineStyle: { color: '#e74c3c', type: 'dashed' },
label: { formatter: '均值: {c} 万元' }
}
}]
3.3 柱状图参数配置详解
柱状图通过矩形柱体的高度来表示数值大小,适合进行类别间的对比。ECharts 中柱状图的系列类型为 type: 'bar'。柱状图的配置重点在于柱体尺寸、间距控制以及堆叠逻辑。
3.3.1 柱状图基础配置与间距控制
柱状图的视觉舒适度很大程度上取决于柱体宽度和间距的合理设置。以下参数需要重点掌握:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| barWidth | number / string | 自适应 | 柱体宽度,可设固定像素(如 30)或百分比(如 '40%') |
| barGap | number / string | '30%' | 同一类别内不同系列柱体之间的间距,百分比基于柱体宽度 |
| barCategoryGap | number / string | '20%' | 不同类别之间的间距,百分比基于柱体宽度 |
| barMaxWidth | number | 无 | 柱体最大宽度限制,防止数据量少时柱体过宽 |
// 柱状图间距配置示例
option = {
xAxis: {
type: 'category',
data: ['Q1', 'Q2', 'Q3', 'Q4']
},
yAxis: { type: 'value' },
series: [{
type: 'bar',
data: [320, 450, 380, 520],
barWidth: '40%', // 柱体宽度占类目宽度的 40%
barGap: '10%', // 多系列时柱间间距
barCategoryGap: '30%', // 类目间距
itemStyle: {
borderRadius: [4, 4, 0, 0], // 柱体顶部圆角
color: '#3498db'
}
}]
};
barWidth 设置过大(如超过类目宽度的 80%)时,柱体之间可能发生视觉重叠。建议在数据量较大的场景下使用 barMaxWidth 进行上限约束,或采用百分比值让 ECharts 自动计算。
3.3.2 堆叠柱状图与分组柱状图
当需要展示多个维度的数据对比时,堆叠柱状图和分组柱状图是两种常用变体。它们的核心区别在于 stack 参数的设置。
- 堆叠柱状图:多个系列共享同一个
stack名称,柱体上下堆叠,展示部分与整体的关系。 - 分组柱状图:不设置
stack或设置不同的stack名称,柱体并排显示,便于不同系列间的直接对比。
// 堆叠柱状图配置
option = {
xAxis: { type: 'category', data: ['一月', '二月', '三月'] },
yAxis: { type: 'value' },
series: [
{
name: '直接销售',
type: 'bar',
stack: 'total', // 同一 stack 名称即堆叠
data: [120, 150, 100]
},
{
name: '渠道销售',
type: 'bar',
stack: 'total',
data: [80, 90, 130]
},
{
name: '线上销售',
type: 'bar',
stack: 'total',
data: [60, 70, 80]
}
]
};
// 分组柱状图(不设置 stack 或 stack 不同)
// 只需移除 stack 属性,或为每个系列设置不同的 stack 名称即可
3.4 折线图与柱状图的组合应用
在实际项目中,经常需要将折线图和柱状图组合在同一个图表中,以同时展示趋势和对比。例如,用柱状图展示每月销售额,用折线图展示同比增长率。组合图的关键在于 双 Y 轴 的配置。
// 折线图与柱状图组合配置
option = {
tooltip: { trigger: 'axis' },
legend: { data: ['销售额', '同比增长率'] },
xAxis: {
type: 'category',
data: ['一月', '二月', '三月', '四月', '五月']
},
yAxis: [
{
type: 'value',
name: '销售额 (万元)',
position: 'left'
},
{
type: 'value',
name: '增长率 (%)',
position: 'right',
axisLabel: { formatter: '{value}%' }
}
],
series: [
{
name: '销售额',
type: 'bar',
data: [120, 150, 130, 170, 190],
yAxisIndex: 0 // 关联左侧 Y 轴
},
{
name: '同比增长率',
type: 'line',
data: [5.2, 8.1, 3.5, 10.2, 12.5],
yAxisIndex: 1, // 关联右侧 Y 轴
smooth: true,
lineStyle: { color: '#e74c3c', width: 3 },
symbol: 'diamond',
symbolSize: 10
}
]
};
- yAxis 数组:定义两个 Y 轴,分别设置
position: 'left'和position: 'right'。 - yAxisIndex:在 series 中通过
yAxisIndex: 0或yAxisIndex: 1指定系列关联哪个 Y 轴。 - 数据量级差异:当两组数据量级相差过大时,建议使用双 Y 轴,否则量级小的数据趋势会被淹没。
3.5 从 SQL 到 ECharts:数据映射实战
在实际开发中,图表的数据通常来自 SQL 查询结果。以下是一个从 SQL 查询到折线图配置的完整映射流程。
3.5.1 SQL 查询与数据预处理
假设我们有一张销售表 sales_records,需要按月份统计销售额并绘制折线图。
-- SQL 查询:按月统计销售额
SELECT
DATE_FORMAT(sale_date, '%Y-%m') AS month,
SUM(amount) AS total_sales
FROM sales_records
WHERE sale_date BETWEEN '2024-01-01' AND '2024-06-30'
GROUP BY month
ORDER BY month;
查询结果示例:
| month | total_sales |
|---|---|
| 2024-01 | 12500 |
| 2024-02 | 13800 |
| 2024-03 | 11200 |
| 2024-04 | 15600 |
| 2024-05 | 17200 |
| 2024-06 | 18900 |
3.5.2 数据映射到 ECharts 配置
将 SQL 查询结果通过 JavaScript 的 map 方法转换为 ECharts 所需的格式:
// 假设从后端 API 获取的 SQL 查询结果
const sqlData = [
{ month: '2024-01', total_sales: 12500 },
{ month: '2024-02', total_sales: 13800 },
{ month: '2024-03', total_sales: 11200 },
{ month: '2024-04', total_sales: 15600 },
{ month: '2024-05', total_sales: 17200 },
{ month: '2024-06', total_sales: 18900 }
];
// 映射为 ECharts 配置
const option = {
xAxis: {
type: 'category',
data: sqlData.map(item => item.month),
axisLabel: { rotate: 30 }
},
yAxis: {
type: 'value',
name: '销售额 (元)',
axisLabel: {
formatter: function(value) {
return (value / 10000).toFixed(1) + '万';
}
}
},
series: [{
type: 'line',
data: sqlData.map(item => item.total_sales),
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(52, 152, 219, 0.5)' },
{ offset: 1, color: 'rgba(52, 152, 219, 0.1)' }
])
},
markPoint: {
data: [
{ type: 'max', name: '最高' },
{ type: 'min', name: '最低' }
]
},
markLine: {
data: [{ type: 'average', name: '均值' }]
}
}],
tooltip: {
trigger: 'axis',
formatter: function(params) {
const p = params[0];
return `${p.axisValue}<br/>销售额:${(p.value / 10000).toFixed(2)} 万元`;
}
}
};