echarts icon indicating copy to clipboard operation
echarts copied to clipboard

How to display sum stack bar in echarts with legend handling

Open cnovelli opened this issue 2 years ago • 3 comments

What problem does this feature solve?

What I need is to show the totals above each column and for the total to be recalculated as the legend is shown or hidden. What is the best practice to do this?

Before: Captura de pantalla de 2022-09-13 15-35-28

After: Captura de pantalla de 2022-09-13 15-46-37

In this code example the total is calculated through a bar below those that are generated through echart, what I want to achieve is that the total of the bar below is recalculated every time the legend is modified

let result = 0;
let array = [];

const series = [
    {
      name: 'Direct',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [320, 302, 301, 334, 390, 330, 320]
    },
    {
      name: 'Mail total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: 'Affiliate total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [220, 182, 191, 234, 290, 330, 310]
    },
    {
      name: 'Video total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [150, 212, 201, 154, 190, 330, 410]
    },
    {
      name: 'Search Engine',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [820, 832, 901, 934, 1290, 1330, 1320]
    },
  ];
  
  sum()

option = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      // Use axis to trigger tooltip
      type: 'shadow', // 'shtotalow' as default; can also be 'line' or 'shtotalow'
      label:{
        formatter: function (params){
          for ( let i = 0; i < params.seriesData.length-1; i++){
            result += params.seriesData[i].value
          } 
          let resultFinal = params.value + " -------------------- total: " + result
          result = 0;
          return resultFinal;
        }
      }
    }
  },
      legend: {
        data: series.map(item => item.name),
    },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'value'
  },
  yAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  series: [
    {
      name: 'Direct',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [320, 302, 301, 334, 390, 330, 320]
    },
    {
      name: 'Mail total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: 'Affiliate total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [220, 182, 191, 234, 290, 330, 310]
    },
    {
      name: 'Video total',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [150, 212, 201, 154, 190, 330, 410]
    },
    {
      name: 'Search Engine',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      emphasis: {
        focus: 'series'
      },
      data: [820, 832, 901, 934, 1290, 1330, 1320]
    },
    {
    
      name: ' A total of ',
      type: 'bar',
      tooltip: {
        show: false
      },
      stack: '',
      color: '#FFFFFF',
      label: {
        normal: {
          show: true,
          position: 'top'
        },
      },
      data: array,
      z: -1,
      barGap: '-100%',
    }
  ]
};


function sum(){
  for ( let z = 0; z < series[0].data.length; z++){
    for( let i = 0; i < series.length; i++){
    result += series[i].data[z];
  }
  array.push(result)
  result = 0;
  }
}

What does the proposed API look like?

the api should have a function to add the total of the data labels and that is modified by handling the legend

cnovelli avatar Sep 14 '22 08:09 cnovelli

You can stack another bar series with transparent background and set label position to be 'insideBottom'.

Ovilia avatar Sep 15 '22 08:09 Ovilia

You can stack another bar series with transparent background and set label position to be 'insideBottom'.

This does not solve the problem that I have of managing the legend so that the total is recalculated

cnovelli avatar Sep 15 '22 08:09 cnovelli

I don't understand how legend is relevant here. Do you meed an image to further illustrate?

Ovilia avatar Sep 21 '22 06:09 Ovilia

You can stack another bar series with transparent background and set label position to be 'insideBottom'.

this will double the length of Value-Axis. how to solve this problem? 21667807708_ pic

liunanchenFYJJ avatar Nov 07 '22 07:11 liunanchenFYJJ

liunanchenFYJJ

Having the same issue, the way I am thinking to bypass that yAxis issue is to put the data not with the sum but with an index [0, 1, 2, 3, 4, 5] and after that I can use the formatter(params) and return the sum data array like this sumData[params.value] , params-value will be the index array, so we can access each value. In your case the graph will go to 15 only, since the biggest index number is 5.

Best regards

PS: But I hope this will be fixed in a future version... stack bar really needs the total sum available

DMOAbove avatar Nov 09 '23 11:11 DMOAbove

Hi Team,

Is there any update on this feature request?

Will it be picked up or included in any upcoming feature releases? This functionality is crucial for our use case, and the current custom handling does not work correctly when some legends are unselected, as the values do not update dynamically.

initial chart render => image

after disabling one of legend (data label is still displayed as 7) => image

@Ovilia FYI

Naik1994 avatar Jun 11 '24 06:06 Naik1994