g2中同一折线多个颜色

833 阅读2分钟

刷了n久的面经,终于拿到满意的offer,可以做自己想做的事了,比如写写博客(后续考虑也写个面经)

这次的功能就是要在一条折线上,根据是否报警展示蓝色还是红色。本来计划通过color的回调来设置,发现不行,然后陆续试了几种方法都不行。文档是不可能找到答案的,尝试到issues中找找思路。

先是看到了一个不支持的回复,但不忍心这么拒绝设计师;

cannot.png

又找了找发现了分离数据,再创建个view的方法,但这是个多图联动的图,已经创建4个view了,那岂不得8个view(如果类型再多,就更多view了);

moreview.png

又接着在issues里淘,发现可以通过自定义shape的方式来实现g2 demo:

shape.png

研究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');

效果图:

morecolor.jpeg