首先看echarts的官网示例
可见第一幅图是具有离散点的箱图,第三幅是colorBy分组之后的箱图,拿到需求的时候,我寻思这不是都有吗,直接复用官网示例就完事了,但是实际效果不尽人意,因为echarts的同一个x值,如果对应的是三个series的箱子,是左右排列开的,如果对应的是三个series的散点,是在同一条竖线上排列,简单看一下效果
完全对应不上啊!
理解了为什么官网示例要么只有离散点,要么只有colorBy分组,而没有两者都兼顾的示例了。。。
撸起袖子开始找办法
首先,发现了散点图可以这样组织data进行分组,形式
[[x轴的值,对应的y的值],[x轴的值,对应的y的值],[x轴的值,对应的y的值],...]
这要是boxPlot也可以这样写,岂不是就解决解决了这个问题
大胆尝试一波,果然画不出来东西
但是也打开了思路,是不是可以用一个series放所有的箱图,通过itemStyle实现颜色的区分呢,(颜色分组要与series的color颜色分组一致)尝试一下,代码格式与呈现效果如下
那是不是就可以把刚刚的散点也加上,试一下
大概样子有了,但是x轴也不是x1对应两个颜色啊
那么再这么进行一下改造,对于x1对应的不同的颜色,在x轴拼上一个假的id,后面再基于假id之前的名字x1、x2之类的进行合并
options如下:
option = {
xAxis: {
type: 'category',
data: ['x1_fakerId:1', 'x1_fakerId:2', 'x2_fakerId:1', 'x3_fakerId:1', 'x3_fakerId:2', 'x4_fakerId:1', 'x4_fakerId:2']
},
legend: {
show: true,
data: ['color1', 'color2']
},
yAxis: {
type: 'value'
},
series: [
{
data: [
{
value: [1.1, 1.2, 1.3, 1.4, 1.5],
itemStyle: {
borderColor: '#5470c6'
}
},
{
value: [3.1, 3.2, 3.3, 3.4, 3.5],
itemStyle: {
borderColor: '#91cc75'
}
},
{
value: [2.1, 2.2, 2.3, 2.4, 2.5],
itemStyle: {
borderColor: '#5470c6'
}
},
{
value: [5.1, 5.2, 5.3, 5.4, 5.5],
itemStyle: {
borderColor: '#5470c6'
}
},
{
value: [0.6, 2, 3, 4, 5],
itemStyle: {
borderColor: '#91cc75'
}
},
{
value: [2.4, 2.8, 3.5, 4.6, 4.9],
itemStyle: {
borderColor:' #5470c6'
}
},
{
value: [1.5, 2, 2.3, 3.6, 5.7],
itemStyle: {
borderColor: '#91cc75'
}
}
],
type: 'boxplot',
name: 'boxplot'
},
{
data: [
['x1_fakerId:1', 1],
['x1_fakerId:1', 2],
['x2_fakerId:1', 3],
['x2_fakerId:1', 4],
['x3_fakerId:1', 8],
['x3_fakerId:1', 8.9],
['x3_fakerId:1', 8.4],
['x4_fakerId:1', 7.2]
],
itemStyle: {
color: '#5470c6'
},
type: 'scatter',
name: 'color1'
},
{
data: [
['x1_fakerId:2', 5.5],
['x3_fakerId:2', 6.7],
['x3_fakerId:2', 6],
['x3_fakerId:2', 7.6],
['x4_fakerId:2', 8.7],
['x4_fakerId:2', 5.8],
['x4_fakerId:2', 1.3]
],
itemStyle: {
color: '#91cc75'
},
type: 'scatter',
name: 'color2'
}
]
};
对于x轴的合并显示,参考之前的多层x轴的实现https://segmentfault.com/a/11...
最后,
对于lenged的变化,需要去监听legend的变化,去更新boxPlot对应的series
myChart.on('legendselectchanged', (params: any) => {
// console.log(params,'params');
const currentOption = myChart.getOption();
let currentSeries: KeyValue[] = currentOption.series as KeyValue[];
if (currentSeries.length < 1) return;
const currentSeriesBoxPlot = currentSeries[0];
const newboxPloSeriestData: KeyValue[] = [];
//依据个人组织的数据结构,自行处理对应的新的boxPlot的series
points.map((item: KeyValue) => {
const boxData = item.boxData;
const ynName: string = Object.keys(boxData)[0];
if (!isEmpty(params.selected))
//如果选中了对应的yName,则处理填充对应的boxPlot的箱子的部分
newboxPloSeriestData.push({
value: params.selected[ynName] === true ? Object.values(boxData)[0] : [],
itemStyle: {
borderColor: ERCHARTSCOLORS[yn.indexOf(ynName) % 9],
},
});
});
const newSeriesBoxPlot = Object.assign({}, currentSeriesBoxPlot, { data: newboxPloSeriestData });
currentSeries[0] = newSeriesBoxPlot;
const newOption = Object.assign({}, currentOption, { series: currentSeries });
myChart.setOption(newOption);
});
最后的实现效果:
PS:该方案存在一个问题,因没有保存legend的选中状态,每次缩放之后,所有的series会重置为全部的箱图,待优化
PS2:Echarts社区还有另一种方案:https://www.makeapie.cn/echar...
利用pictorialBar类型画出的离散点,但是barGap的设置感觉会有坑,偶尔有离散点对不齐箱子中央的情况,若colorBy数量较少的时候,影响不大
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。