Knowledge Base Article

Centering bars and columns when no categories or break by are present in Sisense [linux]

When a Sisense bar or column chart contains only Values and no items in the Break By or Categories panels, Highcharts — the charting library used by Sisense for rendering visualizations still reserves space for grouped series. This can cause the bars or columns to appear offset from their category labels.

When a Sisense bar or column chart contains only Values and no items in the Break By or Categories panels, Highcharts — the charting library used by Sisense for rendering visualizations still reserves space for grouped series; this can cause the bars or columns to appear offset from their category labels.

By using the beforeviewloaded event, we can modify the Highcharts options for a widget before it is rendered, disabling the grouping property so that the bars or columns are centered with their labels. This improves readability and ensures the chart accurately reflects the data layout. (Applicable to Sisense version 2023.11 and later | Cloud and On-Prem deployments.)

 

 

 

 

 

 

Step-by-Step Guide:

  1. Navigate to the dashboard containing the chart you want to adjust.
  2. Create a new bar or column chart widget, or select an existing one that meets the conditions (only Values panel populated, no Break By or Categories).
  3. Open the Widget Script Editor.
  4. Paste the following snippet into the script editor:

    // Purpose:
    // Disables Highcharts series grouping for bar/column charts that have no Categories or Break By,
    // ensuring bars/columns are centered with their labels.
    
    
    function findPanelByTitle(panels, title) {
      var normalizedTitle = String(title || '').toLowerCase();
      return panels.find(function (panel) {
        return panel &&
               typeof panel.title === 'string' &&
               panel.title.toLowerCase() === normalizedTitle;
      });
    }
    
    
    widget.on('beforeviewloaded', function (widget, env) {
      var chartOptions = (env && env.options) ? env.options : {};
      try {
        var panels = (widget.metadata && widget.metadata.panels) || [];
    
    
        var isBarOrColumnChart =
          widget.type === 'chart/bar' || widget.type === 'chart/column';
    
    
        var breakByPanel    = findPanelByTitle(panels, 'break by');
        var categoriesPanel = findPanelByTitle(panels, 'categories');
        var valuesPanel     = findPanelByTitle(panels, 'values');
    
    
        var breakByIsEmpty =
          !breakByPanel || !Array.isArray(breakByPanel.items) || breakByPanel.items.length === 0;
        var categoriesIsEmpty =
          !categoriesPanel || !Array.isArray(categoriesPanel.items) || categoriesPanel.items.length === 0;
        var valuesHasItems =
          !!valuesPanel && Array.isArray(valuesPanel.items) && valuesPanel.items.length > 0;
    
    
        // Apply only if:
        // - The widget is a bar or column chart
        // - Break By panel is empty
        // - Categories panel is empty
        // - Values panel exists and has items
        if (isBarOrColumnChart && breakByIsEmpty && categoriesIsEmpty && valuesHasItems) {
          chartOptions.plotOptions = chartOptions.plotOptions || {};
          chartOptions.plotOptions.series = Object.assign({}, chartOptions.plotOptions.series, {
            grouping: false
          });
        }
      } catch (_) {
        // Do nothing if metadata structure is unexpected
      }
    });


  5. Save and refresh the widget. If the conditions are met, the bars or columns will now be centered with their labels.

Extended Example (Plugin Version):

For a solution that automatically applies to all applicable bar and column charts across all dashboards, the following plugin version can be used. This version attaches the same logic globally via the dashboardloaded and widgetinitialized events.

/**
 * Plugin: BarColumnCentering
 * Purpose: Disables series grouping for bar/column charts with only Values, no Categories or Break By.
 */


function hasEventHandler(model, eventName, handler) {
  var eventHandlers = model.$ngscope
    ? ($$get(prism, '$ngscope.$$listeners.' + eventName) || [])
    : model.$$eventHandlers(eventName);
  return eventHandlers.indexOf(handler) >= 0;
}


function findPanelByTitle(panels, title) {
  var normalizedTitle = String(title || '').toLowerCase();
  return panels.find(function (panel) {
    return panel &&
           typeof panel.title === 'string' &&
           panel.title.toLowerCase() === normalizedTitle;
  });
}


function onBeforeviewloadedCenter(widget, env) {
  var chartOptions = (env && env.options) ? env.options : {};
  try {
    var panels = (widget.metadata && widget.metadata.panels) || [];


    var isBarOrColumnChart =
      widget.type === 'chart/bar' || widget.type === 'chart/column';


    var breakByPanel    = findPanelByTitle(panels, 'break by');
    var categoriesPanel = findPanelByTitle(panels, 'categories');
    var valuesPanel     = findPanelByTitle(panels, 'values');


    var breakByIsEmpty =
      !breakByPanel || !Array.isArray(breakByPanel.items) || breakByPanel.items.length === 0;
    var categoriesIsEmpty =
      !categoriesPanel || !Array.isArray(categoriesPanel.items) || categoriesPanel.items.length === 0;
    var valuesHasItems =
      !!valuesPanel && Array.isArray(valuesPanel.items) && valuesPanel.items.length > 0;


    if (isBarOrColumnChart && breakByIsEmpty && categoriesIsEmpty && valuesHasItems) {
      chartOptions.plotOptions = chartOptions.plotOptions || {};
      chartOptions.plotOptions.series = Object.assign({}, chartOptions.plotOptions.series, {
        grouping: false
      });
    }
  } catch (_) {}
}


prism.on('dashboardloaded', function (e, args) {
  args.dashboard.on('widgetinitialized', function (_, initArgs) {
    var widget = initArgs && initArgs.widget;
    if (!widget || !widget.on) return;


    if (!hasEventHandler(widget, 'beforeviewloaded', onBeforeviewloadedCenter)) {
      widget.on('beforeviewloaded', onBeforeviewloadedCenter);
    }
  });
});

The plugin is available for download below and includes a README file with additional details.

Conclusion

Whether applied to a single widget or deployed globally via a plugin for all widgets, disabling grouping for bar and column charts that have only Values ensures that data is visually aligned with labels. This change reduces confusion and improves chart readability without altering the underlying data.

Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a particular task. The solution may not work in all scenarios or Sisense versions, so we strongly recommend testing it in your environment before deployment. If you need further assistance with this, please let us know.

Published 09-11-2025
No CommentsBe the first to comment