Problem generating pie charts in Vue (ECharts)

45 views Asked by At

I have the following code written in ECharts and you can replace it in the link: https://echarts.apache.org/examples/en/editor.html?c=pie-rich-text&lang=ts

import * as echarts from 'echarts';

type EChartsOption = echarts.EChartsOption;

var chartDom = document.getElementById('main')!;
var myChart = echarts.init(chartDom);
var option: EChartsOption;

const values = [0, 0, 0, 0, 1];
const names = ['A', 'B', 'C', 'D', 'E'];

const initialValues = values.map((v, i) => ({ name: names[i], value: v }));

option = {
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b} : {c} ({d}%)'
  },
  legend: {
    bottom: 10,
    left: 'center',
    data: names
  },
  series: [
    {
      type: 'pie',
      radius: '65%',
      center: ['50%', '50%'],
      selectedMode: 'single',
      data: initialValues,
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
};

option && myChart.setOption(option);

The problem occurs when I have only one value.

const values = [0, 0, 0, 0, 1];

When selecting item E to remove the labels, 1/4 of all items appear, but they are zero.

problem

My question is how to ensure that none of these items appear and there is 0% in item E.

Something similar to this

enter image description here

1

There are 1 answers

0
rozsazoltan On

The values are actually ratios, as the pie chart can only represent proportions. Therefore, if all values are 0, the chart correctly draws that the values cut out the same proportion from the chart. If the value is "empty", meaning there is "none", then null should be applied. If all values are null, then it is correct not to draw a pie chart, as we have no data for it.

By the way, the community has already discussed the error:

Solution

So, the answer is how we can draw a circle indicating an "empty pie chart" if all values are null, meaning we have no values.

graphic: { 
  elements: [
    {
      type: 'circle',
      left: 'center', // Position at horizontal center according to its parent.
      top: 'middle',  // Position at vertical center according to its parent.
      shape: {
        r: 100,
      },
      style: {
        fill: '#f7f7f7',
        stroke: '#ddd',
        lineWidth: 1
      }
    }
  ]
}

If all values are null, a gray circle will appear; unfortunately, the R cannot contain a percentage, so the circle must have a fixed width OR you need to dynamically calculate and provide the value of r. I have now fixed it to 100, so the circle and the gray graphic element have a fixed width.

Example

/**
 ** Initialize
 */
const chartDom = document.getElementById('chart')
const chart = echarts.init(chartDom)

/**
 ** Data
 */
let values = [null, null, null, null, null]
const names = ['A', 'B', 'C', 'D', 'E']

// Just for the sake of example, it's here so you can see it both with data and without.
document.getElementById('showNullChart').addEventListener('click', (e) => {
  const showNull = e.target.checked

  if (showNull) {
    values.fill(null)
  } else {
    values = [10, 20, 30, 40, 50]
  }
  
  updateChart()
})

/**
 ** Chart
 */
function updateChart () {
  /**
   ** Option
   */
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b} : {c} ({d}%)'
    },
    legend: {
      bottom: 10,
      left: 'center',
      data: names
    },
    series: [
      {
        type: 'pie',
        radius: '100',
        center: ['50%', '50%'],
        selectedMode: 'single',
        data: values.map((v, i) => ({ name: names[i], value: v })),
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        },
      }
    ],
    // Extra graphics
    graphic: { 
      elements: [
        {
          type: 'circle',
          left: 'center', // Position at horizontal center according to its parent.
          top: 'middle',  // Position at vertical center according to its parent.
          shape: {
            r: 100,
          },
          style: {
            fill: '#f7f7f7',
            stroke: '#ddd',
            lineWidth: 1
          }
        }
      ]
    }
  }

  /**
   ** Render Chart
   */
  chart.setOption(option)
}
// First render
updateChart() 
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js" integrity="sha512-VdqgeoWrVJcsDXFlQEKqE5MyhaIgB9yXUVaiUa8DR2J4Lr1uWcFm+ZH/YnzV5WqgKf4GPyHQ64vVLgzqGIchyw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<input type="checkbox" id="showNullChart" checked> Null (Empty Chart)

<div id="chart" style="width: 300px; height: 300px;"></div>

Extra

I omitted the variable named initialValues from the formula, you'll find it inserted into the data parameter. If you additionally include there that every 0 value should be converted to null, the chart will consider 0 as empty as well.

const initialValues = values.map((v, i) => ({ name: names[i], value: v === 0 ? null : v }));