乐趣区

关于前端:Echarts的custom类型绘制同一metrics的不同区间范围

接到的需要是为一个在大数据分析上叫做 ABTest 的后果绘制可视化图像,通过这个需要再一次刷新了对 ECharts 的认知,感觉这个弱小的库简直无所不能。
先附上一张实现之后的效果图:

讲述一下从开始选类型到最初确定的过程,需要是为每一个 metrics 展现它的三个区间范畴以及一个两头值,相当于 1 个纵轴值对应 4 个横轴值,并且横轴的值包含三对范畴值和一个确定的值。我刚开始找了一个叫做 rangbar 的第三方类库实现了局部需要,起因是两头确切的值也是取了一个范畴,导致最终的显示成果并不是齐全符合需要,并且这个累类库是免费的。起初就选用了 ECharts,一个精通 ECharts 的共事举荐了自定义系列里的 Profile, 就是如下:

而后,把这些断续的区间,取成重合的区间范畴,就能够满足需要,同时还有一个问题,跟 rangebar 一样的问题,两头确切值也是一个范畴。起初发现 ECharts 还有一项配置,在 renderItem 的时候能够 return 一组图形,并且图形也是自定义的,这样的话,就能够返回三个矩形和一条直线,完满合乎需要,以下别离是 data 数据结构,options 的配置,以及 renderItem 的配置:

dataSource = {categories: [metrics1,metrics2,metrics3],
    data: [
        {value: [index, rangeStart1, rangeEnd1,rangeStart2, rangeEnd2,rangeStart3, rangeEnd3, mean],
            itemStyle: {}},
    ]
};

option = {
    tooltip: {formatter(params: any) {return `${params.marker + params.name}: ${params.value[7]}%`;
      },
    },
    dataZoom: [
      {
        type: 'slider',
        filterMode: 'weakFilter',
      },
    ],
    grid: {top: 30,},
    xAxis: {
      axisLabel: {formatter: '{value}%',
      },
    },
    yAxis: {
      type: 'category',
      data: dataSource.categories,
      inverse: true,
    },
    series: [
      {
        type: 'custom',
        renderItem: renderMetricItem,
        itemStyle: {opacity: 0.8,},
        encode: {x: [1, 2],
          y: 0,
        },
        data: dataSource.data,
      },
    ],
};

renderMetricItem (params, api){const children = [];
    const colors = [RANGE_LEVEL1, RANGE_LEVEL2, RANGE_LEVEL3];
    const categoryIndex = api.value(0);
    const height = api.size([0, 1])[1] * 0.5;
    // confidence interval rect shapes
    for (let i = 0; i < 3; i += 1) {const start = api.coord([api.value(i * 2 + 1), categoryIndex]);
        const end = api.coord([api.value(i * 2 + 2), categoryIndex]);
        const rectShape = echarts.graphic.clipRectByRect(
        {x: start[0],
          y: start[1] - height / 2,
          width: end[0] - start[0],
          height,
          },
        {
          x: params.coordSys.x,
          y: params.coordSys.y,
          width: params.coordSys.width,
          height: params.coordSys.height,
        },
    );

    const item = {
      type: 'rect',
      transition: ['shape'],
      shape: rectShape,
      style: {fill: colors[i],
      },
    };

    children.push(item);

    const s = api.coord([api.value(7), categoryIndex]);
      children.push({
      type: 'line',
      shape: {x1: s[0],
        y1: s[1] - height / 2,
        x2: s[0],
        y2: s[1] + height / 2,
        },
      style: {
          stroke: RANGE_LEVEL4,
          lineWidth: 5,
      },
      });

    return {
      type: 'group',
      children,
    };
}
退出移动版