这周在做可视化图表的时候,遇到一些复杂的需求,最后效果如下图所示: 折柱混合图
难点:后端接口的返回值数据结构很难符合前端开发所需的数据结构,因此面对 echarts 这类固定输入得到固定输出的库时,我们需要做一遍数据处理。
官方示例写法
那么首先我们需要清楚,在 echarts 中想要完成折柱混合图需要什么数据结构?
官方折柱混合图示例
官方的示例中,重点代码在这里:不难看出,官方是将 x 轴数据和 y 轴数据分开了,然后数据源按照index一一对应。这会加大我们的数据处理难度,因为后端返回的数据通常是Object[]
// 这里仅保留重点代码
option = {
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
}
],
// ....
series: [
{
name: 'Evaporation',
type: 'bar',
data: [
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
]
},
{
name: 'Precipitation',
type: 'bar',
data: [
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
]
},
{
name: 'Temperature',
type: 'line',
yAxisIndex: 1,
data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
]
};
更简单的写法(?)
为了简化数据处理,我们可以用dimensions映射的方式来完成这个需求。重点代码如下:
const options = {
dataset: [
{
source: data, // [{a: 1, timestamp: xxx, name: '用于 tooltip 映射也是可以的哦'}, {...}]
dimensions: ['timestamp', 'a', 'name'],
},
{
source: lineData, // { key: 1, timestamp: xxx }[]
dimensions: ['timestamp', 'key'],
},
],
series: [
{
type: 'line',
name: '折线图名称',
yAxisIndex: 1,
datasetIndex: 1,
},
{
name: '柱状图名称',
type: 'bar',
stack: 'a' // 需要映射的 key,
data: // 需要处理成 ['timestamp', 'a'] 的形式,就跟上面一样,
},
{
name: '2 号柱状图名称',
type: 'bar',
stack: dimensionKey,
barMaxWidth: 100,
barWidth: '50%',
data: // 需要,
},
],
tooltip: {
formatter: (val) => {
val.map((item) => {
if (item.componentSubType === 'line') {
const yData = item?.data['key']
let xData = item?.data?.timestamp
console.log(item?.marker) // 圆点
}
if (item.componentSubType === 'bar') {
xData = item?.data[0]
const barYData = item?.data[1]
})
return `
<div>
....
</div>
`
},
}
}
总结
在本次需求中,数据是从多个接口获取的:折线图的数据是一个接口,柱状图的数据是一个接口。
const lineData = [
{
timestamp: ...,
y: ...
},
{...}
]
const barData = [
{
timestamp: ...,
y: ....
},
{ ... }
]
如何将这样的两个数据水合在一起组成折柱混合图,用 dimension 是一个容易的办法