Search code examples
angularechartsapache-echartsngx-echarts

Customising item style of a specific item of the series using dataset property instead of series.data Apache Echarts


I have a half doughnut chart. When I turn of decal the bottom half becomes visible. I can hide the color of the bottom half as color takes function and I get the item details. But decals color is a string only and same color will be applied to all the decals. But I want to set the decal color as 'none' for the bottom half and for other pie sections as default color.

This I want to achieve using dataset property

const options = {
  dataset: [
    {
      source: [
        {value: 735, name: 'Direct'},
        {value: 580, name: 'Email'},
        {value: 1048, name: 'Search Engine'},
        {value: 484, name: 'Union Ads'},
        {value: 300, name: 'Video Ads'},
        {
          // make an record to fill the bottom 50%
          value: 1048 + 735 + 580 + 484 + 300,
          name: ''
        }
      ]
    }
  ],
  aria: {
        enabled: true,
        decal: {
        show: enabled
        }
  }
  series: [
    {
      name: 'Access From',
      type: 'pie',
      emphasis: {
        label: {
          overflow: 'break'
        }
      },
      radius: ['40%', '70%'],

      center: ['50%', '70%'],

      // adjust the start angle
      startAngle: 180,
      itemStyle: {
        color: (param) => {
          if (param.name === '') {
            return 'none';
          }
          if (param.dataIndex > 8) {
            const randomColor = Math.floor(Math.random() * 16777215).toString(
              16
            );
            return '#' + randomColor;
          } else {
            return halfDoughnutChartColors[param.dataIndex];
          }
        },
        borderRadius: 0,
        borderColor: '#000',
        borderWidth: 0
      },

      label: {
        overflow: 'truncate',
        formatter: (param) => {
          // correct the percentage
          return !!param.name ? `${param.name}: (${param.percent * 2}%)` : '';
        }
      },
      encode: {
        itemName: 'name',
        value: 'value',
        tooltip: 'name'
      }
    }
  ]
}

Solution

  • @Matthias Mertens answer is almost correct. But now all the pie sections are getting the same symbols. And, we have n items in the source array. So, I think this approach can be followed: Example

    source = [
      { value: 735, name: 'Direct' },
      { value: 580, name: 'Email' },
      { value: 1048, name: 'Search Engine' },
      { value: 484, name: 'Union Ads' },
      { value: 300, name: 'Video Ads' },
      { value: 735, name: 'Direct1' },
      { value: 580, name: 'Email1' },
      { value: 1048, name: 'Search Engine1' },
      { value: 484, name: 'Union Ads1' },
      { value: 300, name: 'Video Ads1' },
      {
        // make an record to fill the bottom 50%
        value: 1048 + 735 + 580 + 484 + 300 + 1048 + 735 + 580 + 484 + 300,
        name: ''
      }
    ];
    function getDecals() {
      const decalSymbols = [
        'circle',
        'rect',
        'triangle',
        'roundRect',
        'diamond',
        'pin',
        'arrow'
      ];
      const decals = source.map((item, index) => {
        return index === source.length - 1
          ? { symbolSize: 0 }
          : { symbol: decalSymbols[index % 7] };
      });
      console.log('decals', decals);
      return decals;
    }
    option = {
      dataset: [
        {
          source: source
        }
      ],
      aria: {
        enabled: true,
        decal: {
          decals: getDecals(),
          show: 'enabled'
        }
      },
      series: [
        {
          name: 'Access From',
          type: 'pie',
          emphasis: {
            label: {
              overflow: 'break'
            }
          },
          radius: ['40%', '70%'],
    
          center: ['50%', '70%'],
    
          // adjust the start angle
          startAngle: 180,
          itemStyle: {
            borderRadius: 0,
            borderColor: '#000',
            borderWidth: 0
          },
    
          label: {
            overflow: 'truncate',
            formatter: (param) => {
              // correct the percentage
              return !!param.name ? `${param.name}: (${param.percent * 2}%)` : '';
            }
          },
          encode: {
            itemName: 'name',
            value: 'value',
            tooltip: 'name'
          }
        }
      ]
    };