2

使用G2 3.x实现自定义饼图。左侧图例可自定义html,右侧饼图可跟随左侧图例点击的情况,激活对应的数据区域,展示选中状态。
image

1、创建基础饼图

从G2官网拿到基本饼图的示例代码
image

const dataSource = [
  { reason: '分类一', ratio: '62.22', count: 28 },
  { reason: '分类二', ratio: '13.33', count: 6 },
  { reason: '分类三', ratio: '13.33', count: 6 },
  { reason: '分类四', ratio: '6.67', count: 3 },
  { reason: '分类五', ratio: '2.22', count: 1 },
  { reason: '其他', ratio: '2.23', count: 1 },
];
const chart = new G2.Chart({
  container: 'pieChart',
  forceFit: true,
  height: 230,
});
chart.source(dataSource);
chart.coord('theta', {
  innerRadius: 0.6,
  radius: 0.85,
});
chart.tooltip({
  showTitle: false,
  containerTpl: '<div class="g2-tooltip">'
  + '<ul class="g2-tooltip-list"></ul></div>', // tooltip 容器模板
  itemTpl: '<li data-index={index}>'
  + '<span style="background-color:{color};width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:8px;">'
  + '</span>{reason}: {ratio}</li>', // tooltip 每项记录的默认模板,
});
chart.intervalStack()
.position('count')
.color('reason', ['#4BD3EE', '#3BA1FF', '#385EFB', '#26C686', '#F16D83', '#FFC847'])
.tooltip('reason*ratio', (reason, ratio) => {
  return {
    reason,
    ratio: `${ratio}%`,
  };
})
.style({
  lineWidth: 1,
  stroke: '#fff',
  shadowBlur: 14,
  shadowColor: 'rgba(75,175,238,0.35)',
});
chart.render();

2、自定义lengnd

默认图例的样式无法满足,需要自定义html。api传送门
image

chart.legend({
  title: null,
  position: 'left-center',
  slidable: false, // 关闭图例筛选功能
  allowAllCanceled: true, // 图例每一项都支持选择、取消选择
  useHtml: true, // 申明可支持html自定义
  containerTpl: '<div class="g2-legend">' +
  '<table class="g2-legend-list" style="list-style-type:none;margin:0;padding:0;"></table>' +
  '</div>',
  itemTpl: (value, color, checked, index) => {
    checked = checked ? 'checked' : 'unChecked';
    const _data = dataSource;
    return (
      `<tr
        class="g2-legend-list-item item-${index} g2-legend-list-item-${checked}"
        data-value="${value}"
        data-color=${color}
        style="cursor: pointer;font-size: 14px;"
      >
        <td
          width=150
          style="border: none;padding:0;"
        >
          <i class="g2-legend-marker"></i>
          <span class="g2-legend-text ${`${index}`}">
            <span>${_data[index].reason}</span>
          </span>
        </td>
        <td style="text-align: right;border: none;padding:0;color:#343434;font-weight:500;">${_data[index].ratio}%</td>` +
      '</tr>'
    );
  },
});

3、图例、饼图点击联动

调用chart.legend.onClick方法,监听图例的点击事件。
点击事件触发后获取到图表,并触发图表的setSelected方法,激活图例选择的对应图形块的选中状态。
在调起激活状态之前,先清除其余图形块的激活状态。
image

// 点击图例触发筛选
onClick: (val) => {
    const geom = chart.get('geoms')[0]; // 获取所有的图形
    const items = geom.get('data'); // 获取图形对应的数据
    const index = (val.currentTarget.classList[1]).split('-')[1];
    if (classname && classname == `pieChart-item-${index}`) {
      classname = '';
      document.getElementById('pieChart').className = '';
      geom.clearActivedShapes();
      geom.clearSelected();
    } else {
      classname = `pieChart-item-${index}`;
      document.getElementById('pieChart').className = `pieChart-item-${index}`;
      geom.clearActivedShapes(); // 选择之前先清除其余图形块的激活状态
      geom.clearSelected(); // 选择之前先清除其余图形块的激活状态
      geom.setSelected(items[index]); // 激活当前选中的图例对应的图形块
    }
},

调用chart.on('interval:click', ev => {}),监听图表的点击事件。api传送门
拿到点击事件回执的数据,计算当前图形块的下标位置,给对应的图例添加选中样式。

// 点击图表触发筛选
chart.on('interval:click', ev => {
  const data = ev.data;
  const index = dataSource.findIndex(item => item.reason == data._origin.reason); // 计算当前点击的图形块的下标位置
  if (classname && classname == `pieChart-item-${index}`) {
    classname = '';
    document.getElementById('pieChart').className = '';
  } else {
    classname = `pieChart-item-${index}`;
    document.getElementById('pieChart').className = `pieChart-item-${index}`;
  }
});

到此联动的效果就完成了。
完整代码传送门


大橘咋
257 声望4 粉丝