需求:用户手动设置换行图例数(n),实现图例每n项换行的效果
实例
以官网实例为例
option = {
legend: {
data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', '2012', '2013', '2014', '2015']
},
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
['Milk Tea', 86.5, 92.1, 85.7, 83.1],
['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0},
{type: 'category', gridIndex: 1}
],
yAxis: [
{gridIndex: 0},
{gridIndex: 1}
],
grid: [
{bottom: '55%'},
{top: '55%'}
],
series: [
// These series are in the first grid.
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// These series are in the second grid.
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
};
方案
思路1
legend使用数组格式,通过把data分割实现,如下
option = {
legend: [
{
data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa']
},
{
data: ['2012', '2013', '2014', '2015']
}
],
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
['Milk Tea', 86.5, 92.1, 85.7, 83.1],
['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0},
{type: 'category', gridIndex: 1}
],
yAxis: [
{gridIndex: 0},
{gridIndex: 1}
],
grid: [
{bottom: '55%'},
{top: '55%'}
],
series: [
// These series are in the first grid.
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// These series are in the second grid.
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
};
然而会发现图例会有重叠效果,只能通过对每个legend项设置left、top、right、bottom控制显示位置优化
option = {
legend: [
{
data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa']
},
{
data: ['2012', '2013', '2014', '2015'],
top: 30
}
],
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
['Milk Tea', 86.5, 92.1, 85.7, 83.1],
['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0},
{type: 'category', gridIndex: 1}
],
yAxis: [
{gridIndex: 0},
{gridIndex: 1}
],
grid: [
{bottom: '55%'},
{top: '55%'}
],
series: [
// These series are in the first grid.
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// These series are in the second grid.
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
};
但需要计算字符长度、字号大小、图例间距等因素,可控性很差,so pass!
思路2
翻看官方文档发现,原来官方针对图例换行的需求已经做了适配,论仔细看文档的重要性!
官方描述如下: legend.data - 图例的数据数组。 数组项通常为一个字符串,每一项代表一个系列的 name(如果是饼图,也可以是饼图单个数据的 name)。图例组件会自动根据对应系列的图形标记(symbol)来绘制自己的颜色和标记,特殊字符串 ''(空字符串)或者 '\n'(换行字符串)用于图例的换行。
🔎详细信息见ECharts3.0官方文档 www.echartsjs.com/option.html…
原来ECharts接受识别空字符串和换行字符串来实现图例的换行,如下
option = {
legend: {
data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', '', '2012', '2013', '2014', '2015']
},
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
['Milk Tea', 86.5, 92.1, 85.7, 83.1],
['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0},
{type: 'category', gridIndex: 1}
],
yAxis: [
{gridIndex: 0},
{gridIndex: 1}
],
grid: [
{bottom: '55%'},
{top: '55%'}
],
series: [
// These series are in the first grid.
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// These series are in the second grid.
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
};
效果很完美,perfect!
结合项目实战
let wrapData = [];
while (data.length > 0) {
if (wrapData.length === 0) {
wrapData = data.splice(0, wrapNum);
} else {
wrapData = [
...wrapData,
{ name: "" },
...data.splice(0, wrapNum)
];
}
}
return {
data: wrapData
};