g2中同一折线多个颜色
刷了n久的面经,终于拿到满意的offer,可以做自己想做的事了,比如写写博客(后续考虑也写个面经)
这次的功能就是要在一条折线上,根据是否报警展示蓝色还是红色。本来计划通过color的回调来设置,发现不行,然后陆续试了几种方法都不行。文档是不可能找到答案的,尝试到issues中找找思路。
先是看到了一个不支持的回复,但不忍心这么拒绝设计师;
又找了找发现了分离数据,再创建个view的方法,但这是个多图联动的图,已经创建4个view了,那岂不得8个view(如果类型再多,就更多view了);
又接着在issues里淘,发现可以通过自定义shape的方式来实现g2 demo:
研究demo发现使用了registerShape,它是将每个点加入到path中,并自定义颜色、粗细等属性。demo是将数据按x轴切成连续的两部分,并没有按照数据的类型自定义属性。
按照这个思路尝试去实现这次的需求,期间遇到诸如不同类型之间的第一段或者最后一段未绘制线、最后一大段类型的线未绘制等问题,最终都一一解决实现了想要的效果,完整代码如下:
registerShape('line', 'split-line', {
draw(cfg, container) {
const group = container.addGroup();
const pointArrs = cfg.points;
let path = [];
// 通过flag标记一种类型的线的开头与结尾
let sendAlarmFlag = '';
for (let i = 0; i < cfg.data.length; i++) {
const item = cfg.data[i];
if (i === 0) {
// 开头点的格式
path = [['M', pointArrs[i].x, pointArrs[i].y]];
} else if (item.send_alarm === sendAlarmFlag) {
// 如果和上一个alarm相同就push L进path
path.push(['L', pointArrs[i].x, pointArrs[i].y]);
// 如果最后一个点就渲染
if (i === cfg.data?.length - 1) {
group.addShape('path', {
attrs: {
path,
stroke: sendAlarmFlag ? '#F04943' : '#00BF8A',
lineWidth: 2
}
});
}
} else {
// 如果是报警点,要把非报警点连到这里(绘制正常点的结尾段)
if (item.send_alarm) {
path.push(['L', pointArrs[i].x, pointArrs[i].y]);
}
group.addShape('path', {
attrs: {
path,
stroke: sendAlarmFlag ? '#F04943' : '#00BF8A',
lineWidth: 2
}
});
if (item.send_alarm) {
path = [['M', pointArrs[i].x, pointArrs[i].y]];
} else {
// 绘制正常点的开头段
path = [
['M', pointArrs[i - 1].x, pointArrs[i - 1].y],
['L', pointArrs[i].x, pointArrs[i].y]
];
}
}
sendAlarmFlag = item.send_alarm;
}
return group;
}
});
// 使用
const view = chart.createView({})
view.line().position('time*value').shape('split-line');
效果图: