Snippets
Created by
Piotr Szrajber
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | //# sourceURL=Customizations.js
/**
* Modify BI map behavior, so that the circles radii depend on the measure value
* 2017-07-28 Piotr Szrajber <piotr.szrajber@hexagongeospatial.com>
*/
let CIRCLE_SIZE_RANGE = {min: 10, max: 30}, // radius is going to be from 10px to 30px
MEASURE_NAME = "speed_avg"; // change to your measure value
/**
* Finds minimal and maximal value of the given property in the data stage
* @param {gvc.dataStage} stage GVC data stage
* @param {String} property property name
* @return {Object} range
* @return {Number} range.min minimal value
* @return {Number} range.max maximal value
*/
function getRange(stage, property) {
return stage.rows().reduce((acc, curr) => {
acc.min = Math.min(acc.min, curr[property]);
acc.max = Math.max(acc.max, curr[property]);
return acc;
}, {
min: Infinity,
max: -Infinity
});
}
/**
* Returns radius for a given property using scale computation
* @param {Number} value value to be scaled
* @param {Object} domain
* @param {Number} domain.min
* @param {Number} domain.max
* @param {Object} range
* @param {Number} range.min
* @param {Number} range.max
* @return {Number} radius
*/
function getRadius(value, domain, range) {
let minX = domain.min,
maxX = domain.max,
minY = range.min,
maxY = range.max;
return Math.round(minY + value/(maxX - minX)*(maxY - minY));
}
/**
* Returns measure id by name
* @param {String} name measure name
* @param {gvc.dataStage} stage GVC data stage
* @return {String} id measure id
*/
function getMeasureIdByName(name, stage) {
let measureDef = stage.stageModel().values.find(item => item.name === name);
if (!measureDef) throw `No measure named ${name}`;
return measureDef.id;
}
/**
* Modify painter's behavior
*/
function changeMapBehavior(attempts) {
// find the choropleth
$GP.bi.stage.findWidgets({
descriptors: [{
chartM: {
chart: "choropleth"
}
}]
}, function(widgets) {
if (!widgets || !widgets[0]) {
setTimeout(function() {
if (attempts > 0) {
changeMapBehavior(attempts - 1);
}
}, 300);
return;
}
// main logic
let painter = widgets[0].chart.painter(),
stage = widgets[0].chart.dataStage(),
measureId = getMeasureIdByName(MEASURE_NAME, stage),
speedRange = getRange(stage, measureId),
origPaintStyle = painter.paintStyle();
painter.paintStyle((feature) => {
let style = origPaintStyle.call(this, feature),
averageSpeed = feature.value[measureId],
circleRadius = getRadius(averageSpeed, speedRange, CIRCLE_SIZE_RANGE);
style.radius = circleRadius;
return style;
});
painter.paint();
});
}
// launch the customization
changeMapBehavior(100);
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.