Snippets

Piotr Szrajber Smart M.App - Stage switching

Created by Piotr Szrajber
//# sourceURL=customization.js

/**
* Generate 2 pairs of WFS requests:
* A) Without any geometry or attribute filters that return data for whole Poland from 2000 to 2014
* B) With geometry and attribute filters narrowing data to eastern Poland from 2005 to 2010
* Note: this is completely irrevelant for stage switching implementation
*/
var baseUrl = "https://dev-test-mapp.hexagongeospatial.com/gsdemo/psz_wojewodztwa_wfs/wfservice.aspx",
    bboxFilterParts = [
        '<fes:BBOX>',
        '<Envelope srsName="EPSG:4326">',
        '<lowerCorner>48.40 20.49</lowerCorner>',
        '<upperCorner>54.82 24.79</upperCorner>',
        '</Envelope>',
        '</fes:BBOX>'
    ],
    filterBeginParts = [
        '<fes:Filter xmlns:fes="http://www.opengis.net/ogc" xmlns="http://www.opengis.net/gml">'
    ],
    filterEndParts = [
        '</fes:Filter>'
    ],
    andBeginParts = [
        '<fes:And>'
    ],
    andEndParts = [
        '</fes:And>'
    ],
    geometryRequest = "?request=getfeature&service=wfs&version=2.0.0&typenames=wojewodztwaFinal&propertyname=geometry,id_woj&outputFormat=application/vnd.geo%2Bjson&filter=",
    attributesRequest = "?request=getfeature&service=wfs&version=2.0.0&typenames=wojewodztwaFinal&outputFormat=text/csv&filter=",
    // filters
    geometryFilterParts = filterBeginParts.concat(andBeginParts).concat(bboxFilterParts).concat([
        '<fes:PropertyIsEqualTo>',
        '<fes:PropertyName>',
        'YEAR',
        '</fes:PropertyName>',
        '<fes:Literal>',
        '2010',
        '</fes:Literal>',
        '</fes:PropertyIsEqualTo>'
    ]).concat(andEndParts).concat(filterEndParts),
    geometryFilter = encodeURI(geometryFilterParts.join("")),
    attributesFilterParts = filterBeginParts.concat(andBeginParts).concat(bboxFilterParts).concat([
        '<fes:PropertyIsBetween>',
            '<fes:PropertyName>',
                'YEAR',
            '</fes:PropertyName>',
            '<fes:LowerBoundary>',
                '<fes:Literal>',
                    '2005',
                '</fes:Literal>',
            '</fes:LowerBoundary>',
            '<fes:UpperBoundary>',
                '<fes:Literal>',
                    '2010',
                '</fes:Literal>',
            '</fes:UpperBoundary>',
        '</fes:PropertyIsBetween>'
    ]).concat(andEndParts).concat(filterEndParts),
    attributesFilter = encodeURI(attributesFilterParts.join("")),
    // data URLs without filters
    geometryUrl = baseUrl + geometryRequest,
    attributesUrl = baseUrl + attributesRequest,
    // data URLs with filters 
    geometryUrlFilt = baseUrl + geometryRequest + geometryFilter,
    attributesUrlFilt = baseUrl + attributesRequest + attributesFilter;

// beign global state variables
var currentModel, currentLayer, currentId, currentWidgetIds;
// end global state variables

var s = gsp.bi.stage;

/**
* First configuration uses
*/
var nf = {
    stageModel: {
        "id": "stageWithoutFilter",
        "fields": [{
            "id": "ac2016e27b3e84215bd114745d17c2ad6",
            "name": "id_woj",
            "value": "id_woj"
        }, {
            "id": "a694945b7789743798d3b27acae05de94",
            "name": "NUTS1",
            "value": "NUTS1"
        }],
        "totals": [],
        "features": [{
            "id": "labour_geom",
            "key": "id_woj",
            "name": "Adminstrative Zones"
        }],
        "values": [{
            "id": "vCount",
            "name": "Count",
            "value": "$count"
        }, {
            "id": "vAverageWage",
            "name": "Average_wage",
            "value": "$sum(WAGES_TO_1)"
        }, {
            "id": "vYear",
            "name": "year_m",
            "value": "YEAR"
        }]
    },
    tableSource: attributesUrl,
    chartDescriptors: [{
        chartM: {
            "id": "ab993d83ce0634681acb1f5984070df98",
            "name": "AVERAGE GROSS SALARY BY NUTS1 REGION IN CURRENT ZŁ",
            "title": "AVERAGE GROSS SALARY BY NUTS1 REGION IN CURRENT ZŁ",
            "placement": "left",
            "key": ["a694945b7789743798d3b27acae05de94"],
            "values": ["vAverageWage"],
            "tooltips": "{vAverageWage}",
            "colors": ["#ffbf00", "#ffbf00", "#ffbf00", "#ffbf00", "#ffbf00"],
            "axis": {
                "x": {
                    "ticks": 2,
                    "rotation": "",
                    "units": 70
                },
                "y": {
                    "ticks": 2,
                    "units": 70
                }
            },
            "chart": "bar",
            "margins": {
                "top": 50,
                "right": 30,
                "bottom": 50,
                "left": 60
            }
        }
    }],
    choroplethModel: {
        chart: "choropleth",
        name: "Average Wage",
        target: "map",
        layer: "labour_geom",
        key: "id_woj",
        values: "vCount",
        id: "choropleth_id"
    },
    legendModel: {
        definitionName: "MAppPlatformGeoJson",
        url: geometryUrl,
        name: "Average Wage",
        id: "labour_geom",
        bbox: [0, 0, 0, 0],
        bboxCrs: "EPSG:4326",
        supportedCrses: ["EPSG:4326", "EPSG:3857"],
        style: {
            display: "thematicLayer"
        }
    }
};

/**
* Second configuration uses:
*/
var wf = {
    stageModel: {
        "id": "stageModelWithFilter",
        "fields": [{
            "id": "ac2016e27b3e84215bd114745d17c2ad6",
            "name": "id_woj",
            "value": "id_woj"
        }, {
            "id": "a694945b7789743798d3b27acae05de94",
            "name": "NUTS1",
            "value": "NUTS1"
        }],
        "totals": [],
        "features": [{
            "id": "labour_geom",
            "key": "id_woj",
            "name": "Adminstrative Zones"
        }],
        "colors": {
            "paletteYellow": {
                "range": ["#fff0b3", "#ffeb99", "#ffe066", "#ffd633", "#ffcc00", "#cca300", "#997a00", "#665200", "#4d3d00", "#332900"],
                "domain": ["2500", "5000"],
                "type": "quantize"
            }
        },
        "values": [{
            "id": "vCount",
            "name": "Count",
            "value": "$count"
        }, {
            "id": "vPopulationMaleEmployed",
            "name": "POPULATION_M_EMPLOYED",
            "value": "$sum(POPULATI_3)"
        }, {
            "id": "vPopulationFemaleEmployed",
            "name": "POPULATION_F_EMPLOYED",
            "value": "$sum(POPULATI_4)"
        }]
    },
    tableSource: attributesUrlFilt,
    chartDescriptors: [{
        chartM: {
            "id": "ac303bbaf331945c98950a6219e07d883",
            "name": "EMPLOYED POPULATION BY SEX AND NUTS1 REGION",
            "title": "EMPLOYED POPULATION BY SEX AND NUTS1 REGION",
            "placement": "left",
            "key": ["a694945b7789743798d3b27acae05de94"],
            "values": ["vPopulationMaleEmployed", "vPopulationFemaleEmployed"],
            "tooltips": "{vPopulationMaleEmployed} and {vPopulationFemaleEmployed}",
            "colors": ["#2f69f6", "#ffaea1"],
            "axis": {
                "x": {
                    "ticks": 2,
                    "rotation": "",
                    "units": 70
                },
                "y": {
                    "ticks": 2,
                    "units": 70
                }
            },
            "chart": "bar",
            "margins": {
                "top": 50,
                "right": 30,
                "bottom": 50,
                "left": 60
            }
        }
    }],
    choroplethModel: {
        chart: "choropleth",
        name: "Average Wage",
        target: "map",
        layer: "labour_geom",
        key: "id_woj",
        values: "vCount",
        id: "choropleth_filter_id"
    },
    legendModel: {
        definitionName: "MAppPlatformGeoJson",
        url: geometryUrlFilt,
        name: "Average Wage",
        id: "labour_geom",
        bbox: [0, 0, 0, 0],
        bboxCrs: "EPSG:4326",
        supportedCrses: ["EPSG:4326", "EPSG:3857"],
        style: {
            display: "thematicLayer"
        }
    }
};

function onError(e) {
    console.log("Something went wrong");
    console.log(e);
}

function display (config) {
    var stageModel = config.stageModel,
        tableSource = config.tableSource,
        chartDescriptors = config.chartDescriptors,
        choroplethModel = config.choroplethModel,
        legendModel = config.legendModel;

    // store widget ids to remove them later by id
    currentWidgetIds = chartDescriptors.map(function(obj){
        return obj.chartM.id;
    });
    s.registerStageModel({
        stageModel: stageModel
    }, function() {
        s.registerDataTable({
            tableSource: tableSource
        }, function() {
            s.addWidgets({
                descriptors: chartDescriptors
            }, function() {
                s.registerChoropleth({
                    model: choroplethModel,
                    mapTitleEnabled: true,
                    mapLegendEnabled: true,
                    mapLegendPlacement: "map"
                }, function(layerName) {
                    // begin workaround
                    // legend.add adds properties to the 
                    // legendModel and it would not be usable later
                    var legendModelClone = JSON.parse(JSON.stringify(legendModel));
                    // end workaround
                    gsp.legend.add(legendModelClone, function() {
                        console.log("Registered layer");
                        currentModel = choroplethModel;
                        currentLayer = legendModel;
                    }, onError);
                }, onError);
            });
        }, onError);
        currentId = stageModel.id;
    }, onError);
}

function cleanup(callback, errback) {
    s.unregisterChoropleth(currentModel, function() {
        s.removeWidgets({
            widgetIds: currentWidgetIds
        }, gsp.legend.find({
            name: currentLayer.name
        }, function(ret) {
            if (!ret.legendItems || !ret.legendItems[0]) {
                if (typeof errback === "function")
                    errback({
                        message:"No legend item with name: " + currentLayer.name
                    });
                return;
            }
            ret.legendItems[0].remove(function () {
                if (typeof callback === "function") {
                    resetStage();
                    callback();
                }
            });
        }, function (){
            if (typeof callback === "function") {
                resetStage();
                callback();
            }
        }));
    });
}

// begin hack
function resetStage() {
    s.requireLibraries(function(gvc) {
        var stages = mainContext.businessIntelligence.stageManager.__stages,
            index = 0;
        stageId = stages[index].id();
        stages[index] = gvc.dataStage(stageId);
    });    
}
// end hack

function changeStage() {
    cleanup(function () {
        var config;
        switch (currentId) {
            case "stageModelWithFilter":
                config = nf;
                break;
            case "stageWithoutFilter":
                config = wf;
                break;
            default:
                alert("Unknown stage ID. Using WF.");
                config = wf;
        }
        display(config);
    }, onError);
}

gsp.ui.toolbar.add({
    id: "tool-ne",
    title: "Change config"
}, function(ret) {
    ret.div.onclick = function() {
        console.log("Current stage ID: " + currentId);
        changeStage();
    };
});

display(nf);

Comments (0)

HTTPS SSH

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