vue3.0+echarts 嵌套数据的饼图并有联动效果

想要实现的效果:
1、默认选中外层的第一个。
2、点击外层的饼图,里层的饼图实时变动。
3、始终保持外层饼图有选中的状态
效果如下:
vue3.0+echarts 嵌套数据的饼图并有联动效果_第1张图片
vue3.0+echarts 嵌套数据的饼图并有联动效果_第2张图片
实现如下:
1、数据结构

  let chartsArray = [
            {
              name: '外层1',
              value: 2,
              selected:true,
              children: [
                {
                  name: '内层1-1',
                  value: 3,
                },
                {
                  name: '内层1-2',
                  value: 4,
                },
                {
                  name: '内层1-3',
                  value: 4,
                },
              ],
            },
            {
              name: '外层2',
              value: 5,
              children: [
                {
                  name: '内层2-1',
                  value: 3,
                },
                {
                  name: '内层2-2',
                  value: 4,
                },
              ],
            },
            {
              name: '外层3',
              value: 6,
              children: [
                {
                  name: '内层3-1',
                  value: 3,
                },
                {
                  name: '内层3-2',
                  value: 4,
                },
              ],
            }
          ],

2、完整代码

<div  id="chartsDiv"></div>
import {ref, markRaw} from 'vue';
import * as echarts from 'echarts';
const myChart2 = ref();
let firstArray = chartsArray;
let firstTotal =0;
let secondArray = chartsArray[0].children;
let secondTotal = 0;
function initCharts() {
firstTotal  = 0;
secondTotal = 0;
  firstArray.forEach(item=>{
  firstTotal += item.value;
  })
  secondArray.forEach(item=>{
  secondTotal += item.value
  })
  var option = {
    color: [
      '#FF8585',
      '#FF9D4D',
      '#DE85EF',
      '#7686A3',
      '#5ED2A5',
      '#6597FF',
      '#8070F8',
    ],
    tooltip: {
      trigger: 'item',
      formatter: function (params) {
        var color = params.color; // 获取数据点的颜色
        var icon =
          '+
          color +
          ';">';
        var seriesName = params.name; // 数据系列名称
        var value = params.value; // 数据值
        return (
          icon +
          seriesName +
          '
'
+ '    ' + value + ' (' + params.percent + '%)' ); // 返回自定义的字符串 }, backgroundColor: '#000000', textStyle: { color: '#fff', }, }, legend: { type: 'scroll', orient: 'vertical', right: '10px', top: 'middle', icon: 'circle', textStyle: { color: '#8C8C8C', }, height: '300', formatter: function (name) { let tempItem = firstArray.find((item) => item.name == name); let percent = 0; if (!tempItem) { tempItem = secondArray.find((item) => item.name == name); percent = ((tempItem.value / secondTotal) * 100).toFixed(2) + '%'; } else { percent = ((tempItem.value / firstTotal) * 100).toFixed(2) + '%'; } let number = tempItem ? tempItem.value : 0; if (name.length > 6) { return ( name.substr(0, 3) + '...' + name.substr(name.length - 2, 2) + ':' + number + '(' + percent + ')' ); } else { return name + ':' + number + '(' + percent + ')'; } }, }, series: [ { type: 'pie', right: '150px', radius: ['55%', '70%'], padAngle: 1, selectedMode: 'single', labelLine: { length: 15, lineStyle: { color: '#999', }, }, label: { formatter: '{b}\n {c} ({value|{d}%})', minMargin: 10, edgeDistance: 120, lineHeight: 15, rich: { b: { color: 'rgba(0, 0, 0, 0.65)', fontSize: 14, fontWeight: 'bold', lineHeight: 33, }, }, }, data: firstArray, }, { type: 'pie', right: '150px', padAngle: 2, radius: [0, '40%'], label: { show: false, }, labelLine: { show: false, }, data: secondArray, }, ], }; const chartDom = document.getElementById('chartsDiv'); if (chartDom) { if (!myChart2.value) { myChart2.value = markRaw(echarts.init(chartDom)); } myChart2.value.clear(); option && myChart2.value.setOption(option); //监听饼图的点击事件 myChart2.value.on('click', function (params) { // 判断点击的是否为外层,内层点击不做处理 if (params.componentIndex != 0) { return; } let item = chartsArray[params.dataIndex]; secondArray = []; secondTotal = 0; item && item.children && item.children.forEach((element) => { secondArray.push({ name: element.name, value: element.value}); secondTotal += element.failNum; }); //获取当前的charts 配置 设置第二层的数据 let tempOption = myChart2.value.getOption(); tempOption.series[1].data = secondArray; myChart2.value.setOption(tempOption); //始终保持当前有选中的状态 myChart2.value.dispatchAction({ type: 'select', seriesIndex: 0, dataIndex: params.dataIndex, }); }); } }

监听浏览器的大小,动态的改变echarts

onMounted(() => {
  window.addEventListener('resize', () => {
    if (myChart2.value) {
      myChart2.value.resize();
    }
  });
});
onUnmounted(() => {
  window.removeEventListener('resize', () => {
    if (myChart2.value) {
      myChart2.value.dispose();
    }
  });
});

其中:
markRaw是使echarts不具有响应式。

你可能感兴趣的:(echarts,javascript,前端)