18
Views
5
Comments
Inconsistent X-Axis Label Behavior When Hiding Legend Series in OutSystems Chart
Application Type
Reactive

In my chart, the legend contains multiple series such as A, B, C, and D, and the X-axis contains categories like Red, Green, Blue, and Yellow. When I click on a legend item—for example, series A—the category “Red,” which only contains data for series A, automatically disappears from the X-axis as expected since it no longer has any associated data.

However, for another category like “Green,” which only contains data for series B and is positioned in the middle, clicking on series B in the legend does not remove “Green” from the X-axis even though it no longer has any valid data. I would like to understand why this inconsistency is occurring and how to ensure that X-axis labels without any remaining data are always removed consistently.

2025-09-23 21-03-15
MUKESH ROBIN SAMYNATHAN

Hi Varsha,
Could you please share the JavaScript code for this scenario? When a legend item  is unchecked, any category whose total becomes zero across all visible series should be completely removed from the chart. Right?

UserImage.jpg
Varsha A

Highcharts.chart('container', {

  chart: {

    type: 'column'

  },

  title: {

    text: 'Major trophies for some English teams',

    align: 'left'

  },

  xAxis: {

    categories: ['Arsenal', 'Chelsea', 'Liverpool', 'Manchester United'],

    labels: {

      useHTML: true

    }

  },

  yAxis: {

    min: 0,

    title: {

      text: 'Count trophies'

    },

    stackLabels: {

      enabled: true

    }

  },

  legend: {

    align: 'left',

    x: 70,

    verticalAlign: 'top',

    y: 70,

    floating: true,

    borderWidth: 1

  },

  plotOptions: {

    series: {

      events: {

        legendItemClick: function () {

          const chart = this.chart;

 

          // Wait until visibility toggles

          setTimeout(() => {

            const visibleSeries = chart.series.filter(s => s.visible);

            const categoryTotals = [];

 

            // Initialize per category total = 0

            for (let i = 0; i < chart.xAxis[0].categories.length; i++) {

              categoryTotals[i] = 0;

            }

 

            // Sum visible values per category

            visibleSeries.forEach(series => {

              series.yData.forEach((v, idx) => {

                categoryTotals[idx] += v;

              });

            });

 

            // Update X-axis labels based on totals

            chart.xAxis[0].setCategories(

              chart.xAxis[0].categories.map((cat, idx) =>

                categoryTotals[idx] > 0 ? cat : "" // hide by empty label

              )

            );

           

          }, 0);

 

          return true; // allow default toggle

        }

      }

    },

    column: {

      stacking: 'normal',

      dataLabels: {

        enabled: true

      }

    }

  },

  series: [

    { name: 'BPL', data: [0, 0, 1, 13] },

    { name: 'FA Cup', data: [14, 0, 8, 12] },

    { name: 'CL', data: [0, 2, 6, 3] }

  ]

});

UserImage.jpg
Varsha A

After hiding all the legend items and enabling them again, bars with null values are reappearing on the chart. 

image (2).png
2025-09-23 21-03-15
MUKESH ROBIN SAMYNATHAN


Hi Varsha, Can yo please try this code



const originalCategories = ['Arsenal', 'Chelsea', 'Liverpool', 'Manchester United'];

 

const originalData = {

  'BPL': [0, 0, 1, 13],

  'FA Cup': [14, 0, 8, 12],

  'CL': [0, 2, 6, 3]

};

 

Highcharts.chart('container', {

  chart: {

    type: 'column'

  },

  title: {

    text: 'Major trophies for some English teams',

    align: 'left'

  },

  xAxis: {

    categories: originalCategories.slice()

  },

  yAxis: {

    min: 0,

    title: { text: 'Count trophies' },

    stackLabels: { enabled: true }

  },

  legend: {

    align: 'left',

    x: 70,

    verticalAlign: 'top',

    y: 70,

    floating: true,

    borderWidth: 1

  },

  plotOptions: {

    series: {

      events: {

        legendItemClick: function () {

          const chart = this.chart;

 

          setTimeout(() => {

 

            const visibleSeries = chart.series.filter(s => s.visible);

 

            // Compute totals for each original category

            const totals = originalCategories.map((_, catIndex) => {

              return visibleSeries.reduce((sum, s) => {

                return sum + originalData[s.name][catIndex];

              }, 0);

            });

 

            // Build a list of categories to KEEP

            const keepIndexes = totals

              .map((t, i) => (t > 0 ? i : -1))

              .filter(i => i !== -1);

 

            // Build new categories

            const newCategories = keepIndexes.map(i => originalCategories[i]);

            chart.xAxis[0].setCategories(newCategories, false);

 

            // Update each series with filtered data

            chart.series.forEach(series => {

              const filteredData = keepIndexes.map(i => originalData[series.name][i]);

              series.setData(filteredData, false);

            });

 

            chart.redraw();

          }, 0);

 

          return true;

        }

      }

    },

    column: {

      stacking: 'normal',

      dataLabels: { enabled: true }

    }

  },

  series: [

    { name: 'BPL', data: originalData['BPL'].slice() },

    { name: 'FA Cup', data: originalData['FA Cup'].slice() },

    { name: 'CL', data: originalData['CL'].slice() }

  ]

});

2026-04-24 12-29-42
Duy Pham Minh

Hi @Varsha A

The inconsistency happens because empty labels only hide text but keep the tick. To remove X-axis labels consistently, you need to filter out categories with zero totals and update both categories and series data, instead of replacing them with "".

I updated the code so categories with zero values are fully removed from the X-axis. Is this what you had in mind? Hope it helps!

// Save original categories and series data for full restoration

const originalCategories = ['Arsenal', 'Chelsea', 'Liverpool', 'Manchester United'];

const originalSeriesData = [

  [0, 0, 1, 13], // BPL

  [14, 0, 8, 12], // FA Cup

  [0, 2, 6, 3]    // CL

];


Highcharts.chart('container', {

  chart: {

    type: 'column'

  },

  title: {

    text: 'Major trophies for some English teams',

    align: 'left'

  },

  xAxis: {

    categories: [...originalCategories],

    labels: {

      useHTML: true

    }

  },

  yAxis: {

    min: 0,

    title: {

      text: 'Count trophies'

    },

    stackLabels: {

      enabled: true

    }

  },

  legend: {

    align: 'left',

    x: 70,

    verticalAlign: 'top',

    y: 70,

    floating: true,

    borderWidth: 1

  },

  plotOptions: {

    series: {

      events: {

        legendItemClick: function () {

          const chart = this.chart;


          // Wait until visibility toggles

          setTimeout(() => {

            const visibleSeries = chart.series.filter(s => s.visible);


            if (visibleSeries.length === chart.series.length) {

              // Case 1: All series are visible → restore original data and categories

              chart.series.forEach((series, idx) => {

                series.setData([...originalSeriesData[idx]], false);

              });

              chart.xAxis[0].setCategories([...originalCategories], false);

            } else {

              // Case 2: Some series are hidden → filter categories with non-zero totals

              const categoryTotals = originalCategories.map((_, idx) => {

                return visibleSeries.reduce((sum, series) => sum + (series.options.data[idx] || 0), 0);

              });


              // Collect indexes of categories that still have data

              const validIndexes = categoryTotals

                .map((val, idx) => (val > 0 ? idx : -1))

                .filter(idx => idx !== -1);


              // Build new categories list

              const newCategories = validIndexes.map(idx => originalCategories[idx]);


              // Update each series with filtered data

              chart.series.forEach((series, idx) => {

                const newData = validIndexes.map(i => originalSeriesData[idx][i]);

                series.setData(newData, false);

              });


              // Update X-axis categories

              chart.xAxis[0].setCategories(newCategories, false);

            }


            // Redraw chart after updates

            chart.redraw();

          }, 0);


          return true; // Allow default toggle behavior

        }

      }

    },

    column: {

      stacking: 'normal',

      dataLabels: {

        enabled: true

      }

    }

  },

  series: [

    { name: 'BPL', data: [...originalSeriesData[0]] },

    { name: 'FA Cup', data: [...originalSeriesData[1]] },

    { name: 'CL', data: [...originalSeriesData[2]] }

  ]

});


Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.