Snippets

Piotr Szrajber Smart M.App - synchronize widgets from two BI stages

Created by Piotr Szrajber last modified
//# sourceURL=customization.js
/**
 * Synchronize chart from stage B with map from stage A.
 *
 * Assumptions: 
 *     - there are two stages - A and B.
 *     - Stage A contains 1 choropleth (it can also contain other charts that are not subject of interest)
 *     - Stage B contains 1 line chart (and other charts that are not subject of interest)
 * 
 * 2017-07-11 Piotr Szrajber <piotr.szrajber@hexagongeospatial.com>
 */
var STAGE_ID1 = "zbyszek", // default stage
    STAGE_ID2 = "stage_zbvr", // TODO: modify here. Currently there is no public method for finding stage identifiers. In order to find all avaliable stage identifiers execute this in your javascript console: console.log(mainContext.businessIntelligence.stageManager.__stages.map(function(stage){return stage.id();})) 
    TIMEOUT,
    GLOBAL_VARIABLES = {};

/**
 * Function that waits for the choropleth on the first stage
 * @param {Function} callback - callback function
 * @param {gvc.chart.choropleth} callback.chart
 * @return {void}
 */
function waitForChoropleth(callback) {
    gsp.bi.stage.findWidgets({
        stageId: STAGE_ID1,
        descriptors: [{
            chartM: {
                chart: "choropleth"
            }
        }]
    }, function(widgets) {
        if (!widgets || !widgets[0]) {
            TIMEOUT = setTimeout(function() {
                waitForChoropleth(callback);
            }, 500);
        } else {
            clearTimeout(TIMEOUT);
            callback(widgets[0]);
        }
    });
}

// !!! MODIFY HERE !!!
waitForChoropleth(function(ch) {
    // when the choropleth's filters are changed...
    ch.chart.on("filtered", function() {
        // ...find current filters of the choropleth
        var filters = ch.chart.filters();

        console.log("Updating filters", filters);

        // if the chart from the second stage is not ready yet, do nothing
        if (!GLOBAL_VARIABLES.secondStageById || !GLOBAL_VARIABLES.secondStageChart) return;
        if (!filters || !filters.length) {
            // if there are no filters, remove filters from the chart on the second stage
            GLOBAL_VARIABLES.secondStageById.filter(null);
        } else {
            // apply filters on the chart on the second stage
            GLOBAL_VARIABLES.secondStageById.filter(function(d) {
                return filters.indexOf(d) >= 0;
            });
        }
        // redraw the chart on the second stage
        GLOBAL_VARIABLES.secondStageChart.chart.redraw();
    });
});

/**
 * Function that waits till the charts are ready (they already have SVG element)
 * @param {Function} fn callback
 * @return {void}
 */
function chartsReady(fn) {
    var observer = new MutationObserver(function(mutations, me) {
        var chartWithSvg = document.querySelector(".widget-chart.dc-chart>svg");
        if (chartWithSvg) {
            fn();
            me.disconnect();
        }
    });

    observer.observe(document, {
        childList: true,
        subtree: true
    });
}

// !!! MODIFY HERE !!!
function updateGlobals() {
    chartsReady(function() {
        // create dimension by id (it is possible that you want to change it)
        // TODO: adapt to your data model (change ID to the key you want to use)
        gsp.bi.stage.findStage(STAGE_ID2, function(stage) {
            GLOBAL_VARIABLES.secondStageById = stage.facts().dimension(function(d) {
                return d.region
            });
        });

        // find charts of intereset on the second stage and store references to them in the global object
        // TODO: modify the chart descriptor to match your chart
        gsp.bi.stage.findWidgets({
            stageId: STAGE_ID2,
            descriptors: [{
                chartM: {
                    chart: "bar"
                }
            }]
        }, function(widgets) {
            var chart = widgets[0];
            GLOBAL_VARIABLES.secondStageChart = chart;
        });
    });
}

// initial execute
updateGlobals();

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.