Sisense Community logo
    • Community Feedback
    • Chapters
    • Events
    • Forums
      • Help and How To
      • Product Feedback Forum
      • Strategy & Use Cases
    • Blogs
    • KB Docs
      • KB Docs
      • Add-Ons & Plug-Ins
      • APIs
      • Best Practices
      • Blox
      • CDT
      • Cloud Managed Service
      • Data Models
      • Data Sources
      • Embedding Analytics
      • How-Tos & FAQs
      • Onboarding
      • PySisense
      • Security
      • Sisense Administration
      • Sisense Intelligence & AI
      • Troubleshooting
      • Widget & Dashboard Scripts
    • Support
    • Learning
      • Sisense Academy: Free Courses and Certifications
      • Official Developer Documentation
      • Official Product Documentation
      • Official Sisense Youtube Channel
      • Sisense Compose SDK Playground
    • Use Case Gallery
    All PostsDiscussionsBlogsIdeasQuestions
    Leaderboards
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    Discussions
    • TagsChevronRightIcon
    SCRIPTS
    • Blog banner
      • Widget & Dashboard ScriptsChevronRightIcon

      [Linux] Accessibility in Sisense Fusion with Scripts

                       

      Accessibility (often abbreviated as a11y ) is about building applications that everyone can use, including people who rely on assistive technologies such as screen readers, keyboard navigation, voice control, or high contrast themes. If you're new to accessibility or would like to learn more about how it applies to Sisense and Compose SDK applications, check out our previous article: Accessibility in Compose SDK This article focuses specifically on Fusion Highcharts widgets and shows how to enhance the accessibility features already available in Sisense using Widget Scripts, Dashboard Scripts, or Plugins. Accessibility in Fusion Widgets Some Fusion widgets uses Highcharts to render. Highcharts includes an extensive Accessibility Module that helps charts become usable for users with disabilities by providing: Keyboard navigation Screen reader support Automatic chart descriptions High contrast compatibility Sisense do not enable the Highcharts accessibility module by default, so you will need an additional configuration options. Which approach should I use? There are three different ways to apply this configuration depending on your needs. Widget Script, rely on one widget. Dashboard Script, rely on all widgets in a dashboard. Plugins Entire Fusion, or in selected dashboards ids. All three approaches can use exactly the same Highcharts configuration. The only difference is where the code is executed. Option 1: Widget Script If you only need to improve accessibility for a single visualization, open the widget editor and navigate to: Edit Widget → Script Then paste the following script. (function () { widget.on("beforeviewloaded", function (se, ev) { var options = ev.options; // This configuration can be reused for the others scripts options.accessibility = { enabled: true, landmarkVerbosity: "all", highContrastTheme: true, keyboardNavigation: { enabled: true, seriesNavigation: { mode: "normal", }, }, point: { describeNull: true, }, series: { describeSingleSeries: true, pointDescriptionEnabledThreshold: 200, }, screenReaderSection: { beforeChartFormat: "<{headingTagName}>{chartTitle}</{headingTagName}>" + "<div>{typeDescription}</div>" + "<div>{chartSubtitle}</div>" + "<div>{chartLongdesc}</div>" + "<div>{viewTableButton}</div>", }, }; if (options.title && !options.title.text && ev.widget && ev.widget.title) { options.title.text = ev.widget.title; } if (options.exporting) { options.exporting.accessibility = { enabled: true, }; } }); })(); Option 2: Dashboard Script To apply the same accessibility improvements to every widget in a dashboard, move the same logic into a Dashboard Script. /** * Chart Accessibility (Highcharts) for All Widgets * This script turns on the Highcharts accessibility module with a fuller set of * options (keyboard navigation, screen-reader descriptions, live-data * announcements) for every chart widget on the dashboard, instead of requiring * the script to be added widget-by-widget. * * Features: * - Applies to all chart-type widgets currently on the dashboard * - Automatically wires up widgets added to the dashboard afterwards * - Ensures a screen-reader-visible chart title even if the widget title is hidden * - Enables accessible exporting menu * * Before Implementation: * - Only widgets whose type starts with "chart/" are targeted (Highcharts-based * widgets). Pivot, indicator, and map widgets are skipped since the Highcharts * accessibility module does not apply to them. */ (function () { // Applies the accessibility options to a single widget's Highcharts config function applyAccessibility(widget) { // Only Highcharts-based widgets support the accessibility module if (!widget.type || !widget.type.startsWith("chart/")) return; widget.on("beforeviewloaded", function (se, ev) { var options = ev.options; options.accessibility = { enabled: true, // How many ARIA landmarks are exposed to screen readers ("all" | "one" | "disabled"). landmarkVerbosity: "all", // Respect the OS/browser high-contrast setting instead of the widget's own colors. highContrastTheme: true, keyboardNavigation: { enabled: true, seriesNavigation: { // Lets arrow keys move between individual points, not just series. mode: "normal", }, }, point: { // Fallback wording for null/empty data points instead of skipping them silently. describeNull: true, }, series: { describeSingleSeries: true, // Avoid announcing every single point on very large series (perf + noise). pointDescriptionEnabledThreshold: 200, }, screenReaderSection: { // Surface a "View as data table" link for screen-reader users. beforeChartFormat: "<{headingTagName}>{chartTitle}</{headingTagName}>" + "<div>{typeDescription}</div>" + "<div>{chartSubtitle}</div>" + "<div>{chartLongdesc}</div>" + "<div>{viewTableButton}</div>", }, }; // Screen readers read the chart title first — make sure one exists even if // the widget's own title is visually hidden. if (options.title && !options.title.text && ev.widget && ev.widget.title) { options.title.text = ev.widget.title; } if (options.exporting) { options.exporting.accessibility = { enabled: true }; } }); } // Event Listeners // Wire up every widget already on the dashboard when it first loads dashboard.on("initialized", function () { for (const widget of dashboard.widgets.$$widgets) { applyAccessibility(widget); } }); // Wire up widgets added to the dashboard afterwards (e.g. via "Add Widget") dashboard.widgets.on("widgetadded", function (se, ev) { applyAccessibility(ev.widget); }); })(); This approach avoids duplicating Widget Scripts while keeping the changes limited to a single dashboard. Option 3: Plugin If accessibility improvements should be available throughout your Sisense environment, the same configuration can be added to a plugin. Once installed, you can configurate with specific dashboards that you want to apply and every compatible Highcharts widget automatically receives the enhanced accessibility configuration. You can download found the plugin here . Understanding the configuration Although the script is relatively small, it enables several useful Highcharts accessibility features. Keyboard Navigation keyboardNavigation: { enabled: true, seriesNavigation: { mode: "normal" } } Allows users to navigate through individual chart points using only the keyboard, improving accessibility for users who cannot use a mouse. High Contrast Support highContrastTheme: true Automatically adapts the chart colors when users enable High Contrast Mode in their operating system. Screen Reader Improvements screenReaderSection: { beforeChartFormat: ... } Creates a richer description for screen readers by including: Chart Title Chart Description Subtitle Long Description View as Data Table button This gives users additional context before interacting with the visualization. Better Handling of Missing Data point: { describeNull: true } Instead of silently skipping empty values, screen readers describe null data points. Large Dataset Optimization pointDescriptionEnabledThreshold: 200 Reading every point in a chart containing hundreds or thousands of values quickly becomes overwhelming. This threshold limits detailed point descriptions for large datasets while maintaining overall chart accessibility. Single-Series Improvements describeSingleSeries: true Provides more meaningful descriptions for charts containing only one series. Automatic Widget Titles if (options.title && !options.title.text && ev.widget && ev.widget.title) { options.title.text = ev.widget.title; } Screen readers announce the chart title before reading its contents. If the Highcharts title is empty but the Sisense widget has a title, this code copies the widget title into the Highcharts configuration, ensuring users always hear a meaningful title. Export Accessibility options.exporting.accessibility = { enabled: true }; When exporting is enabled, exported charts retain accessibility metadata whenever supported. Testing Your Changes After applying the script, it's a good idea to verify the accessibility improvements. Some useful testing methods include: Navigating the chart using only the keyboard Running Lighthouse accessibility audits Testing with screen readers such as: NVDA VoiceOver Windows/Mac Narrator Accessibility testing should always include real keyboard navigation and screen reader testing whenever possible. Limitations This solution applies only to Highcharts-based widgets available in Sisense Linux. It does not affect: Pivot tables BloX widgets Custom React visualizations Compose SDK custom widgets Those components require their own accessibility implementation. Conclusion Accessibility is an ongoing process rather than a one-time configuration. While Sisense provides a option through Highcharts, taking advantage of the additional accessibility options available can help create dashboards that are more inclusive and easier to use. We encourage you to experiment with these settings, adapt them to your organization's needs, and share any additional accessibility improvements. References/Related Content  Compose SDK Accessibility Scripting in Sisense Plugins in Sisense Highcharts Accessibility Module Plugin Repository Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a specific 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.

      Micael Santana
      Micael SantanaPosted 1 month ago
      0
               
    • Discussion
      Mia Isaacson
      • Help and How-To
               
      Mia Isaacson
      Dashboard script: automatically reset filters to default when a dashboard is opened
                                               

      Hey everyone 👋 Here's one that comes up more than you'd think. You've got a dashboard with filters. A user applies a bunch of selections, and the next time they (or someone else) opens it, those filters are still there from the last session. Depending on your use case, that might be exactly what you want... but sometimes it isn't. If you'd rather your dashboard always open in a clean, predictable state, with filters resetting to the defaults you set at design time, this dashboard script does exactly that. Every time the dashboard is activated, it removes whatever filters are currently applied and restores the defaults automatically. Here's the full script: dashboard.on("activated", (e, args) => { const dashFilters = args.dashboard.filters; dashFilters.$$items = dashFilters.$$items.splice(0, dashFilters.$$items.length); let filters = args.dashboard.defaultFilters; var options = { save: true, refresh: true, unionIfSameDimensionAndSameType: false, }; if (!Array.isArray(filters)) { filters = [filters]; } dashFilters.update(filters, options); }); Here's what each part is doing: Trigger This fires whenever the dashboard becomes active (when a user opens it or navigates to it). That's the moment everything below kicks off. dashboard.on("activated", (e, args) => { ... }) Step 1: Clear the current filters This grabs the live filter collection and empties it out completely — whatever the user had applied before is gone. const dashFilters = args.dashboard.filters; dashFilters.$$items = dashFilters.$$items.splice(0, dashFilters.$$items.length); Step 2: Grab the default filters defaultFilters is the filter state saved at design time. Whatever you configured as the intended starting point when you built the dashboard. const filters = args.dashboard.defaultFilters; Step 3: Apply the defaults This normalizes the filters into an array, then applies them back with save: true so the reset persists, and refresh: true so the data reloads immediately. The unionIfSameDimensionAndSameType: false setting makes sure it replaces rather than tries to merge with anything. var options = { save: true, refresh: true, unionIfSameDimensionAndSameType: false, }; if (!Array.isArray(filters)) { filters = [filters]; } dashFilters.update(filters, options); When would you actually use this? Shared dashboards where you don't want one user's filter selections to carry over for the next person who opens it Executive or presentation dashboards where the default view is intentional and should always be what people land on Dashboards embedded in portals or apps where a consistent starting state matters Anywhere you've had someone complain that the dashboard "looks different than it usually does" — often it's just leftover filters from a previous session One thing worth knowing The $$items approach in Step 1 is manipulating an internal Sisense array directly. The $$ prefix is a convention for internal Angular properties. It works well, but it's worth keeping in mind that if Sisense changes the internal structure down the road, that line could break without much warning. Something to keep an eye on if you're on this script after an upgrade. Hope this is useful for someone, and happy to answer questions if you run into anything! Mia from QBeeQ, a Sisense Gold Implementation Partner www.qbeeq.io

      4 months ago
      0
               
    • Discussion
      Mia Isaacson
      • Help and How-To
               
      Mia Isaacson
      Widget script: hide value labels and empty legend items on native bar and column charts
                                                       

      Hey everyone 👋 Ever built a stacked bar or column chart and found yourself wishing you could just... turn the labels off? Maybe you've got a lot of segments, and they're all squishing together, or the chart just doesn't have quite enough room to breathe in your dashboard layout, and the labels end up overlapping and making things harder to read rather than easier. Or, does it bother you that your legend still shows entries for categories that have no data at all for certain dimension values? So you've got these ghost entries sitting in the legend that don't correspond to anything visible in the chart. Sisense doesn't have a native toggle for either of these, so here's a widget script that handles both. It works on bar and column charts (stacked or single value) and does two things: Hides the value labels from displaying on the bars or columns Removes any series from the legend if all of its values are null or zero widget.on("beforeviewloaded", function(w, args){ var allEmpty = arr => arr.every(v => v.y === null || v.y === 0); for (e in args.options.series) { var serie = args.options.series[e]; if (allEmpty(serie.data)) { serie.showInLegend = false; } } }); A few situations where this comes in handy: You have a stacked chart with a lot of segments where the labels are colliding with each other Your dashboard is on the tighter side, and there just isn't room to make the chart large enough for labels to display cleanly Your legend is cluttered with entries for categories that have no data for certain dimension values, which can confuse users into thinking something is missing The chart is more of a visual overview and the exact values aren't the point, users can always hover for tooltips anyway You just prefer a cleaner, less noisy look overall Nothing groundbreaking, just a handy little script if you've ever hit this wall.  Mia from QBeeQ, a Sisense Gold Implementation Partner www.qbeeq.io

      5 months ago
      0