legendechartsapache-echarts

How to hide series name in legend when the series is empty in Apache echarts?


I created a stacked line chart with echarts and I used the built-in transform to filter the provided data and ecSimpleTransform to aggregate the values. However, after filtering some datasets become empty, because none of their values match the filter condition. I would like to add a legend, but it also includes labels for the empty datasets. Is there a way to filter the legend values as well?

I attached a simplified version of the chart config.

I also created a CodeSandbox example.

legendData= [...] //list of possible 'propertyOne' values
const chartConfig = {
      dataset: [
        {
          id: 'raw',
          dimensions: ['date', 'value', 'propertyOne', 'propertyTwo'],
          source: values,
        },
        {
          id: 'filtered',
          fromDatasetId: 'raw',
          transform: [
            {
              type: 'filter',
              config: {
                dimension: 'propertyTwo',
                '=': 'providedValue',
              },
            },
          ],
        },
        ...legendData.map(propertyOneValue=> {
          return {
            id: propertyOneValue,
            fromDatasetId: 'filtered',
            transform: [
              {
                type: 'filter',
                config: {
                  dimension: 'propertyOne',
                  '=': propertyOneValue,
                },
              },
              {
                type: 'ecSimpleTransform:aggregate',
                config: {
                  resultDimensions: [
                    { name: 'propertyOne', from: 'propertyOne' },
                    { name: 'sum', from: 'value', method: 'sum' },
                    { name: 'date', from: 'date' },
                  ],
                  groupBy: 'date',
                },
              },
            ],
          };
        }),
      ],
      tooltip: {
        trigger: 'axis',
        confine: true,
      },
      yAxis: {
        nameLocation: 'middle',
        nameGap: 30,
        scale: true,
      },
      xAxis: {
        type: 'category',
        position: 'top',
      },
      grid: {
        bottom: 50,
        containLabel: true,
      },
      legend: {
        selected: { detail: false },
        data: legendData,
        bottom: 0,
        type: 'scroll',
      },
      series: [
        ...legendData.map(propertyOneValue => {
          return {
            name: propertyOneValue ,
            type: 'line' as 'line',
            areaStyle: {},
            datasetId: propertyOneValue,
            stack: 'Total',
            encode: {
              x: 'date',
              y: 'sum',
              itemName: 'propertyOne',
              tooltip: 'sum',
            },
          };
        }),
      ],
    }

Solution

  • The chart's legend is going to display as many values as there are in legend.data. In your example, legendData still has 4 values when you assign it to legend.data instead of just being ["custom 1", "custom 2"].

    One simple way of doing it would be to only add what you want in legend.data when you create it (instead of filtering legendData later).

    values.forEach((value) => {
      //just addind a second condition when pushing values to legendData
      if (!legendData.includes(value.propertyOne) && value.propertyTwo == "providedValue"){
        legendData.push(value.propertyOne);
      }
    });
    

    I don't know exactly what you intend to do with this application, but this solution works on the sandbox you provided. Even later when you do ...legendData.map(), you won't get poluted with useless values (from custom 3 & 4).