Forum Discussion

MikeGre's avatar
05-30-2024
Solved

Sunburst Chart issue

Hello everyone,

I want to use a Sunburst widget in order to show a breakdown based on 2 dimensions.

What we realized is that Sunburst is not clickable when enabling "Widget affects dashboard filters".

Has anyone managed to use it and make it clickable? Is this a known issue?

Thanks in advance for your feedback

  • steve's avatar
    steve
    06-20-2024

    Hi MikeGre 

    Can you please share any screen capture / GIF of where the subsequent clicks are not working? Do you see any errors in the browser console (developer tools?)

    Also I want to highlight a feature of the sunburst which can be less obvious initially, that when you hover over a segment a white border appears and this is not part of the clickable area, so where you have lots of very small segments it is easy to miss - the mouse cursor (hand vs pointer) should let you know when you're in the right spot in this case. Sharing this knowledge in case it's relevant, but appreciate it might not be the issue.

     

    Thanks

    Steve

11 Replies

  • Hello MikeGre,

    I am looking into this with internal resources and will get back to you.

    • Hi DRay ,

      Thanks for replying. This was tested on L2023.9.0.308, as well as L2023.11.0471

      Let me know if there is something from internal sources that can help.

  • Hi MikeGre 

    I was able to find out that this is a known issue. You may be able to use this widget script as a workaround until the issue is resolved.

    /*
    Welcome to your Widget's Script.

    To learn how you can access the Widget and Dashboard objects, see the online documentation at https://sisense.dev/guides/js/extensions
    */
    var filtersAddedFromSunburst = [];

    widget.on('ready', function(widget, event) {

    // limit selector scope to this widgetid, in case there is more than one sunburst widget
    var widgetid = element.parent().attr('widgetid');
    var this_widget_selector = "widget[widgetid='" + widgetid + "']";
    var this_toolbar_selector = "widget[widgetid='" + widgetid + "'] widget-toolbar";
    var this_sunburst_selector = "widget[widgetid='" + widgetid + "'] .chart > svg >g > path";

    //check if there are existing filters that were applied by this sunburst, and they are not currently set to 'include all'
    //used in decision on whether to show 'clear selection' button or not.
    let areThereFilters = checkIfFiltersExistForSunburstDims();

    //check if button is already there - so not to add it more than once
    let existingBtn = $('button[id="clear-selection-' + widgetid + '"]')
    let doesClearButtonExist = existingBtn.length > 0 ? true : false;

    if (areThereFilters && !doesClearButtonExist) {
    //create the 'clear selection button
    let btn = $('<button id="clear-selection-' + widgetid + '">Clear Selection</button>')
    .on("click", function(event) {
    clearSunburstFilters();
    });
    let elemToolbar = $(this_toolbar_selector);
    elemToolbar.prepend(btn);
    } else if (!areThereFilters) {
    //if filters are reset to 'include all' or deleted then remove the button
    $('button[id=clear-selection-' + widgetid + ']').remove();
    }

    // select d3 segment elements, add onclick function to add dashboard filter
    var sunburst_chart_segments = $(this_sunburst_selector)
    .css({
    cursor: 'pointer'
    })
    .on("click", function(event) {
    // getting all the relevant JAQL info from the segment
    let panelDepth = this.__data__.depth - 1;
    let dim = widget.metadata.panels[0].items[panelDepth].jaql.dim;
    let column = widget.metadata.panels[0].items[panelDepth].jaql.column;
    let datatype = widget.metadata.panels[0].items[panelDepth].jaql.datatype;
    let table = widget.metadata.panels[0].items[panelDepth].jaql.table;
    let title = widget.metadata.panels[0].items[panelDepth].jaql.title;

    //2023.3 moved the name attribute for the selected value to __data__.data.name
    let selectedVal = this.__data__.data ? this.__data__.data.name : this.__data__.name;

    let filterJaql = {
    jaql: {
    'column': column,
    'datatype': datatype,
    'dim': dim,
    'filter': {
    'explicit': true,
    'members': [selectedVal],
    'multiSelection': true
    },
    'table': table,
    'title': title
    }
    };

    let options = {
    refresh: true,
    save: true,
    unionIfSameDimensionAndSameType: true,
    reason: 'widgetSelection'
    };

    let selectionDataItem = {
    'dim': dim,
    'members': [selectedVal]
    };

    //add filter to array, to be able to check later which filters to clear
    //check if it already exists first, to avoid duplicates
    let sbFilterAlreadyExistsIndex = filtersAddedFromSunburst.findIndex(getFilterIndexForDim, filterJaql.jaql.dim);

    if (sbFilterAlreadyExistsIndex != -1) {
    //already exists, so remove it - will be re-added with new selection
    filtersAddedFromSunburst.splice(sbFilterAlreadyExistsIndex, 1);
    }

    filtersAddedFromSunburst.push(filterJaql);

    // setting the new filter from the segment info
    widget.dashboard.filters.update([filterJaql], options);
    });
    })

    function checkIfFiltersExistForSunburstDims() {

    let filterCount = 0
    //as sunburst is cliced to filter, we store the filter selection in filtersAddedFromSunburst array
    filtersAddedFromSunburst.forEach(sbFilter => {
    let filteredDim = sbFilter.jaql.dim;
    //find the dashboard filter object for our stored filter reference
    let dashFilterIndex = widget.dashboard.filters.$$items.findIndex(getFilterIndexForDim, filteredDim);
    //store the index for the matching filter in our array, so we can use it to reset that filter on 'clear selection' click
    sbFilter.dashboardFilterIndex = dashFilterIndex;

    let isDashFilterIncludeAll = widget.dashboard.filters.$$items[dashFilterIndex].jaql.filter.all;

    if (dashFilterIndex > -1 && !isDashFilterIncludeAll) {
    filterCount = filterCount + 1
    }
    });

    //if there is one or more filters that were applied from the sunburst AND they are not currently set to 'include all' then return true
    return filterCount > 0;
    }

    function getFilterIndexForDim(flt) {
    return flt.jaql.dim === this.toString();
    }

    function clearSunburstFilters() {
    //loop through filters that were updated by clicking this sunburst
    filtersAddedFromSunburst.forEach(sbFilter => {
    //copy the filter to a new variable
    let flt = widget.dashboard.filters.$$items[sbFilter.dashboardFilterIndex];
    //set filter to include all = clearing the filter
    flt.jaql.filter.all = true;
    flt.jaql.filter.explicit = false;

    let options = {
    refresh: true,
    save: true,
    unionIfSameDimensionAndSameType: true,
    reason: 'widgetSelection'
    };

    //update the dashboard filter to be 'include all' = clearing the filter
    widget.dashboard.filters.update([flt], options);
    });
    }

  • Hello MikeGre 

    I wanted to follow up to see if the solution offered by DRay worked for you.

    If so, please click the 'Accept as Solution' button so other users with the same questions can find the answer faster. If not, please let us know so that we can continue to help.

    Thank you.

  • Hello both, jpacheco DRay 

    Sorry for late reply, it seems that the script partially works..

    I added the script, and the filter is changed, but this happens only once.... I can't click it again, only if I refresh my browser...

     

    • DRay's avatar
      DRay
      Admin

      Hi MikeGre.

      That's probably because of the widget.on('ready'  trigger. You may be able to add script that forces the page to refresh. 

    • steve's avatar
      steve
      Sisense Employee

      Hi MikeGre 

      Can you please share any screen capture / GIF of where the subsequent clicks are not working? Do you see any errors in the browser console (developer tools?)

      Also I want to highlight a feature of the sunburst which can be less obvious initially, that when you hover over a segment a white border appears and this is not part of the clickable area, so where you have lots of very small segments it is easy to miss - the mouse cursor (hand vs pointer) should let you know when you're in the right spot in this case. Sharing this knowledge in case it's relevant, but appreciate it might not be the issue.

       

      Thanks

      Steve

  • So how does the script needs to be changed so that it will update every time I click?

  • Hi steve ,

    Thanks for your reply, and thanks for the knowledge shared about the Sunburst! I don't see any issues on the browser console while clicking on the Sunburst 😕

    The use case we would like to use Sunburst for, is to show the breakdown of a segmentation, in multiple hierarchies. The idea is to be able to click on any of the segments from the Sunburst which consequently, will affect the relevant filter(s), and narrow down our selection.