Commit 94fcb056 authored by Tania Gómez's avatar Tania Gómez

Chords diagram plot

parent 8884b2e5
......@@ -19,7 +19,8 @@ let baseLayerPromises = [];
currentBaseLayer = 1;*/
//let drawnItems;
let od, flowMapsArray = [], odData = {};
let od, flowMapsArray = [],
odData = {};
/*Object.keys(baseFileSize).forEach((name) => {
if (name.split(".")[1] == "zip") {
......@@ -103,7 +104,7 @@ const createPane = (layerPane, zIndex) => {
const getCentrosColor = s => {
return s == "Primario" ? "#ff5500" :
s == "Secundario" ? "#8e1973" :
"#d1ff73";
"#d1ff73";
}
// const getCultivoBorder = s => {
......@@ -132,43 +133,43 @@ const getCentrosColor = s => {
const getHaciaColor = s => {
return s > 32000 ? "#00451c" :
s > 6000 ? "#218542" :
s > 2000 ? "#4bc44f" :
s > 1000 ? "#b4d787" :
"#e3fcd9";
s > 2000 ? "#4bc44f" :
s > 1000 ? "#b4d787" :
"#e3fcd9";
}
const getDesdeColor = s => {
return s > 6000 ? "#b30000" :
s > 2000 ? "#fc7f44" :
s > 1000 ? "#ffaa00" :
"#ffebbf";
s > 1000 ? "#ffaa00" :
"#ffebbf";
}
const getHaciaPOICColor = s => {
return s > 4000 ? "#00451c" :
s > 2000 ? "#218542" :
s > 1000 ? "#4bc44f" :
s > 500 ? "#b4d787" :
"#e3fcd9";
s > 1000 ? "#4bc44f" :
s > 500 ? "#b4d787" :
"#e3fcd9";
}
const getDesdePOICColor = s => {
return s > 1000 ? "#fc7f44" :
s > 500 ? "#ffaa00" :
"#ffebbf";
"#ffebbf";
}
const getEntreColor = s => {
return s > 3500 ? "#a80000" :
s > 2000 ? "#e64c00" :
s > 1000 ? "#ffaa00" :
"#70a800";
s > 1000 ? "#ffaa00" :
"#70a800";
}
const getCuencasColor = s => {
return s == "Bajo Grijalva o Grijalva-Villahermosa" ? "rgba(255,255,190,0.3)" :
s == "Medio Grijalva o Grijalva-Tuxtla Gutiérrez" ? "rgba(255,170,0,0.3)" :
"rgba(168,56,0,0.3)";
"rgba(168,56,0,0.3)";
}
let munis_contexto, lim_zms, zms, conurbaciones, agebs2005, agebs2010, agebs2015, auto2010, auto2014, auto2018, tecnologia2010, tecnologia2014, tecnologia2018, centros, hacia, desde, centrosPOIC, haciaPOIC, desdePOIC;
......@@ -267,7 +268,7 @@ let layer_auto2010 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -296,7 +297,7 @@ let layer_auto2014 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -325,7 +326,7 @@ let layer_auto2018 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -354,7 +355,7 @@ let layer_tecnologia2010 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -383,7 +384,7 @@ let layer_tecnologia2014 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -412,7 +413,7 @@ let layer_tecnologia2018 = new L.geoJson(null, {
borderWidth: 0,
borderColor: "transparent",
backgroundColor: "transparent" //,
// textColor: "#C0C0C0"
// textColor: "#C0C0C0"
});
return new L.Marker(latlng, {
icon: autoMarker
......@@ -900,9 +901,9 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
animatedCanvasBezierStyle = [];
// define styles based on properties and values
intervals[type].values.forEach( (val, idx) => {
intervals[type].values.forEach((val, idx) => {
canvasBezierStyle.push({
classMinValue: idx == 0 ? 0 : intervals[type].values[idx-1] + 1,
classMinValue: idx == 0 ? 0 : intervals[type].values[idx - 1] + 1,
classMaxValue: val,
symbol: {
strokeStyle: intervals[type].colors[idx],
......@@ -914,7 +915,7 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
});
animatedCanvasBezierStyle.push({
classMinValue: idx == 0 ? 0 : intervals[type].values[idx-1] + 1,
classMinValue: idx == 0 ? 0 : intervals[type].values[idx - 1] + 1,
classMaxValue: val,
symbol: {
strokeStyle: intervals[type].colors[idx],
......@@ -931,12 +932,12 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
// build data array from geojson to be used in amchart
let source = data.features;
let newData = [];
source.forEach(o => newData.push({'xVar': o.properties.muni_origen, 'yVar': o.properties.muni_destino, 'flowCount': o.properties.viajes}) );
source.forEach(o => newData.push({ 'xVar': o.properties.muni_origen, 'yVar': o.properties.muni_destino, 'flowCount': o.properties.viajes }));
let origins= [],
let origins = [],
destinations = [];
newData.forEach( data => {
newData.forEach(data => {
origins.push(data.xVar); // all origins
destinations.push(data.yVar) // all destinations
});
......@@ -944,16 +945,16 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
destinations = destinations.filter((v, i, a) => a.indexOf(v) === i); // get unique ones
// add missing combinations with 0 trips
origins.forEach( (o) => {
destinations.forEach( (d) => {
if (!newData.some( data => data.xVar === o && data.yVar === d ) ) {
newData.push({'xVar': o, 'yVar': d, 'flowCount': 0});
origins.forEach((o) => {
destinations.forEach((d) => {
if (!newData.some(data => data.xVar === o && data.yVar === d)) {
newData.push({ 'xVar': o, 'yVar': d, 'flowCount': 0 });
}
})
});
// sort array by origins and then by destinations
newData.sort( (el1,el2) => {
newData.sort((el1, el2) => {
let compared = compare(el1, el2, "xVar")
return compared == 0 ? compare(el1, el2, "yVar") : compared;
});
......@@ -989,7 +990,7 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
},
// dot styles
style: function (geoJsonFeature) {
style: function(geoJsonFeature) {
if (geoJsonFeature.properties.isOrigin) {
return {
renderer: canvasPointRenderer,
......@@ -1020,9 +1021,9 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
animationDuration: 2000,
customLayerId: type,
pane: "pane_flujos"
}).bindTooltip( layer => { // what to display on hover
}).bindTooltip(layer => { // what to display on hover
let coords = layer.getLatLng();
let label = od.features.filter( f => f.properties.lng == coords.lng && f.properties.lat == coords.lat);
let label = od.features.filter(f => f.properties.lng == coords.lng && f.properties.lat == coords.lat);
return label[0].properties.nombre;
})
......@@ -1031,6 +1032,10 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
flowMapLayer.addTo(map).on('click', odClick);
let amchart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "amchartdiv");
amchart.data = newData;
let amchart2 = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "prueba2");
amchart2.data = newData;
amchart2.data = amchart2.data.filter(function(e) { return e.flowCount > 0 });
}
flowMapsArray.push(flowMapLayer);
resolve(flowMapsArray);
......@@ -1135,15 +1140,15 @@ const makeBaseMap = () => {
// create one flow, then another, then another...
// and finally set reset control funcionality
createFlowLayer("data/viajes_ocupados_desde.geojson", "ocupadosDesde", true)
.then( () => createFlowLayer("data/viajes_ocupados_hacia.geojson", "ocupadosHacia") )
.then( () => createFlowLayer("data/viajes_ocupados_entre.geojson", "ocupadosEntre") )
.then( () => createFlowLayer("data/viajes_ocupados_POIC_desde.geojson", "poicDesde") )
.then( () => createFlowLayer("data/viajes_ocupados_POIC_hacia.geojson", "poicHacia") )
.then( () => createFlowLayer("data/viajes_ocupados_POIC_entre.geojson", "poicEntre") )
.then( layers => {
.then(() => createFlowLayer("data/viajes_ocupados_hacia.geojson", "ocupadosHacia"))
.then(() => createFlowLayer("data/viajes_ocupados_entre.geojson", "ocupadosEntre"))
.then(() => createFlowLayer("data/viajes_ocupados_POIC_desde.geojson", "poicDesde"))
.then(() => createFlowLayer("data/viajes_ocupados_POIC_hacia.geojson", "poicHacia"))
.then(() => createFlowLayer("data/viajes_ocupados_POIC_entre.geojson", "poicEntre"))
.then(layers => {
// reset to all flows displayed
$("#resetFlows").on("click", () => {
layers.forEach( layer => {
layers.forEach(layer => {
if (map.hasLayer(layer)) {
layer.originAndDestinationGeoJsonPoints.features.forEach(function(feature) {
if (feature.properties.isOrigin === true) {
......
......@@ -40,23 +40,23 @@ am4core.ready(function() {
//heatLegend.minValue = minValue;
//heatLegend.maxValue = maxValue;
heatLegend.minValue = 0;
heatLegend.maxValue = intervals[option].values[intervals[option].values.length-1];
heatLegend.maxValue = intervals[option].values[intervals[option].values.length - 1];
// update heatLegend colors
let heatColors = [];
["#333", ...intervals[option].colors].forEach( c => heatColors.push(am4core.color(c)) );
["#333", ...intervals[option].colors].forEach(c => heatColors.push(am4core.color(c)));
heatLegend.minColor = heatColors[0];
heatLegend.maxColor = heatColors[intervals[option].colors.length - 1];
//let checkConditions = [minValue, ...intervals[option].values.slice(1)];
let checkConditions = [minValue, ...intervals[option].values];
let lastValue = intervals[option].values[intervals[option].values.length-1]
let lastValue = intervals[option].values[intervals[option].values.length - 1]
// Override heatLegend gradient
let gradient = new am4core.LinearGradient();
heatColors.forEach(function(color, index) {
// addColor(color, opacity, offset) use offset to put colors in proper alignment
gradient.addColor(color, undefined, (checkConditions[index] - checkConditions[0])/lastValue);
gradient.addColor(color, undefined, (checkConditions[index] - checkConditions[0]) / lastValue);
});
//heatLegend.markers.template.applyOnClones = true;
......@@ -70,20 +70,20 @@ am4core.ready(function() {
let workingValue = column.dataItem.values["value"].workingValue;
// use min max values calculated from data on beforedatavalidated
if (am4core.type.isNumber(workingValue)) {
checkConditions.forEach( (condition, index) => {
if ( index < checkConditions.length-1 ) {
if (workingValue >= condition && workingValue <= checkConditions[index+1]) {
checkConditions.forEach((condition, index) => {
if (index < checkConditions.length - 1) {
if (workingValue >= condition && workingValue <= checkConditions[index + 1]) {
//console.log(`${workingValue} entre ${condition} y ${checkConditions[index+1]}`)
fill = new am4core.Color(
am4core.colors.interpolate(
heatColors[index].rgb,
heatColors[index+1].rgb,
heatColors[index + 1].rgb,
workingValue
)
);
//console.log(workingValue, intervals.ocupadosDesde.colors[index])
} else if (workingValue < checkConditions[0]) {
fill = new am4core.color(cellbgColor);
fill = new am4core.color(cellbgColor);
}
}
});
......@@ -119,7 +119,7 @@ am4core.ready(function() {
xAxis.events.on("sizechanged", function(ev) {
let axis = ev.target;
let cellWidth = axis.pixelWidth / (axis.endIndex - axis.startIndex);
axis.renderer.labels.template.maxWidth = 2*Math.ceil(cellWidth)*0.8;
axis.renderer.labels.template.maxWidth = 2 * Math.ceil(cellWidth) * 0.8;
});
// on data change change, resize labels
......@@ -127,7 +127,7 @@ am4core.ready(function() {
xAxis.events.on("datarangechanged", function(ev) {
let axis = ev.target;
let cellWidth = axis.pixelWidth / (axis.endIndex - axis.startIndex);
axis.renderer.labels.template.maxWidth = 2*Math.ceil(cellWidth)*0.8;
axis.renderer.labels.template.maxWidth = 2 * Math.ceil(cellWidth) * 0.8;
});
xAxis.renderer.labels.template.fontSize = 12;
......@@ -184,7 +184,7 @@ am4core.ready(function() {
columnTemplate.adapter.add("strokeWidth", function(width, column) {
var workingValue = column.dataItem.values["value"].workingValue;
if (am4core.type.isNumber(workingValue)) {
width = workingValue != 0 ? 1: 0;
width = workingValue != 0 ? 1 : 0;
}
return width;
});
......@@ -227,8 +227,7 @@ am4core.ready(function() {
column.strokeWidth = 2;
column.strokeOpacity = 0.2;
heatLegend.valueAxis.showTooltipAt(column.dataItem.value);
}
else {
} else {
column.strokeWidth = 0;
column.strokeOpacity = 0;
heatLegend.valueAxis.hideTooltip();
......@@ -246,4 +245,85 @@ am4core.ready(function() {
chart.responsive.enabled = true;
}); // end am4core.ready()
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++CC
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var cd_chart = am4core.create("prueba2", am4charts.ChordDiagram);
var cd_title = cd_chart.titles.create();
//cd_title.text = "Viajes de ocupados desde centros de mercado";
cd_title.fill = am4core.color(mainTextColor);
cd_title.fontSize = 13;
cd_title.align = "left";
cd_title.marginBottom = 20;
cd_title.paddingLeft = 10;
cd_chart.events.on("beforedatavalidated", function(ev) {
let option = $("#indicatorSelect").val();
let optionTitle = $("#indicatorSelect option:selected").text();
cd_title.text = "[bold]Conectividad origen -destino entre \n" + optionTitle.toLowerCase();
//var data = ev.target.data;
//let data = data.filter(function(e) { return e.flowCount > 0 });
//console.log(data);
});
cd_chart.dataFields.fromName = "xVar";
cd_chart.dataFields.toName = "yVar";
cd_chart.dataFields.value = "flowCount";
//cd_chart.labels.fontSize = 15;
// make nodes draggable
var nodeTemplate = cd_chart.nodes.template;
nodeTemplate.readerTitle = "Oculta/muestra para reorganizar la red"; //"Click to show/hide or drag to rearrange";
nodeTemplate.showSystemTooltip = true;
var nodeLink = cd_chart.links.template;
var bullet = nodeLink.bullets.push(new am4charts.CircleBullet());
bullet.fillOpacity = 0.8;
bullet.circle.radius = 3;
bullet.locationX = 0.5;
// create animations
cd_chart.events.on("over", function() {
// nodeTemplate.events.on("ready", function() {
for (var i = 0; i < cd_chart.links.length; i++) {
var link = cd_chart.links.getIndex(i);
var bullet = link.bullets.getIndex(0);
animateBullet(bullet);
}
})
function animateBullet(bullet) {
var duration = 3000 * Math.random() + 2000;
var animation = bullet.animate([{ property: "locationX", from: 0, to: 1 }], duration)
animation.events.on("animationended", function(event) {
animateBullet(event.target.object)
})
}
var label = nodeTemplate.label;
label.relativeRotation = 90;
label.fontSize = 10;
label.fill = am4core.color(mainTextColor);
//label.wrap = true;
//label.bent = true;
//cd_chart.responsive.enabled = true;
}); // end am4core.ready()
\ No newline at end of file
......@@ -33,11 +33,13 @@ let maxIndicators = {},
//indicators = ["area", "perimeter", "costa", "df"],
indicators = ["ocupadosDesde", "ocupadosHacia", "ocupadosEntre", "poicDesde", "poicHacia", "poicEntre"],
indicatorsNames = ["Viajes de ocupados desde centros de mercado", "Viajes de ocupados hacia centros de mercado",
"Viajes de ocupados entre zonas", "Viajes de personas en OIC desde centros de mercado",
"Viajes de personas en OIC hacia centros de mercado", "Viajes de personas en OIC entre zonas"],
"Viajes de ocupados entre zonas", "Viajes de personas en OIC desde centros de mercado",
"Viajes de personas en OIC hacia centros de mercado", "Viajes de personas en OIC entre zonas"
],
indicatorsShortNames = ["Ocupados desde <br/> centros de mercado", "Ocupados hacia <br/> centros de mercado",
"Ocupados entre zonas", "OIC desde centros <br/> de mercado",
"OIC hacia centros <br/> de mercado", "OIC entre zonas"],
"Ocupados entre zonas", "OIC desde centros <br/> de mercado",
"OIC hacia centros <br/> de mercado", "OIC entre zonas"
],
//indicatorsUnits = ["m\u00B2", "m", "", ""],
indicatorsxAxisFormat = [".2s", ".2s", ".2f", ".2f"],
indicatorVars = {},
......@@ -64,42 +66,42 @@ indicators.forEach((indicator, index) => {
let intervals = {
"ocupadosDesde": {
"classes": ["Menos de 1,000", "1,001 - 2,000", "2,001 - 6,000", "6,001 - 7,200"],
"values" : [1000, 2000, 6000, 7200],
"values": [1000, 2000, 6000, 7200],
"colors": ["#00c5ff", "#008fdc", "#005ce6", "#4c0073"],
"thickness": [0.5, 1.5, 2, 10],
"animThickness": [0.5, 1.5, 4, 15]
},
"ocupadosHacia": {
"classes": ["Menos de 1,000", "1,001 - 2,000", "2,001 - 6,000", "6,001 - 32,000", "32,001 - 53,300"],
"values" : [1000, 2000, 6000, 32000, 53300],
"values": [1000, 2000, 6000, 32000, 53300],
"colors": ["#ffbee8", "#ff73df", "#ff00c5", "#ad027d", "#80006b"],
"thickness": [0.5, 1.5, 2, 4, 10],
"animThickness": [0.5, 1.5, 4, 10, 15]
},
"ocupadosEntre": {
"classes": ["Menos de 1,000", "1,001 - 2,000", "2,001 - 3,500", "3,501 - 8,000"],
"values" : [1000, 2000, 3500, 8000],
"values": [1000, 2000, 3500, 8000],
"colors": ["#70a800", "#ffaa00", "#e64c00", "#a80000"],
"thickness": [0.5, 1.5, 2, 4],
"animThickness": [0.5, 1.5, 4, 10]
},
"poicDesde": {
"classes": ["Menos de 150", "151 - 500", "501 - 1,000", "1,001 - 1,500"],
"values" : [150, 500, 1000, 1500],
"values": [150, 500, 1000, 1500],
"colors": ["#00c5ff", "#008fe6", "#005ce6", "#002673"],
"thickness": [0.5, 1.5, 2, 4],
"animThickness": [0.5, 1.5, 4, 10]
},
"poicHacia": {
"classes": ["Menos de 200", "201 - 400", "401 - 600", "601 - 3,000", "3,001 - 10,700"],
"values" : [200, 400, 600, 3000, 10700],
"values": [200, 400, 600, 3000, 10700],
"colors": ["#ffbee8", "#ff73df", "#ff00c5", "#ad027d", "#80006b"],
"thickness": [0.5, 1.5, 2, 4, 10],
"animThickness": [0.5, 1.5, 4, 10, 15]
},
"poicEntre": {
"classes": ["150 - 500", "501 - 700", "701 - 950", "951 - 1,200"],
"values" : [500, 700, 950, 1200],
"values": [500, 700, 950, 1200],
"colors": ["#70a800", "#ffaa00", "#e64c00", "#a80000"],
"thickness": [0.5, 1.5, 2, 4],
"animThickness": [0.5, 1.5, 4, 10]
......@@ -138,23 +140,23 @@ d3.json("https://unpkg.com/d3-time-format@2.1.1/locale/es-MX.json").then(locale
timeFormat = d3.timeFormat("%B_%Y");
//setupTimeDimensionControl();
// FIX: Need to remove setup and populate dates and only setup and populate map
// FIX: Need to remove setup and populate dates and only setup and populate map
/*setupDates()
.then(dates => populateDates(dates))
.then(userData => setupMap(userData))
.then(map => populateMap(map));*/
//$("#showMap").on("click", () => {
// hide initial screen and show map
// TODO: don't need outer call to d3.json, do I? Move this to the bottom after functions definitions
//TODO: remove unused functions
$("#startHeader").remove();
$("#initial-backdrop").remove();
$("#mainContainer")[0].style.setProperty("display", "flex", "important")
$("#mexmap").show();
setupMap()
// hide initial screen and show map
// TODO: don't need outer call to d3.json, do I? Move this to the bottom after functions definitions
//TODO: remove unused functions
$("#startHeader").remove();
$("#initial-backdrop").remove();
$("#mainContainer")[0].style.setProperty("display", "flex", "important")
$("#mexmap").show();
setupMap()
.then(map => populateMap(map));
//});
});
......@@ -284,7 +286,7 @@ const populateDates = (dates) => { // fill out date pickers with available dates
})
}
const setupMap = () => {//(dates) => {
const setupMap = () => { //(dates) => {
return new Promise(resolve => {
// make body tag to have style height: 100%
......@@ -376,7 +378,7 @@ const setupMap = () => {//(dates) => {
//console.log(userFiles);
// query db to get min/max values per month and indicator and store them in an object
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
/*queryFiles().then(minmax => {
minmax.map(minmaxMonth => {
indicators.forEach((indicator) => {
......@@ -386,7 +388,7 @@ const setupMap = () => {//(dates) => {
});
resolve({ "map": map, "minIndicators": minIndicators, "maxIndicators": maxIndicators });
});*/
// FIX: resolve with fake values
// FIX: resolve with fake values
resolve({ "map": map, "minIndicators": minIndicators, "maxIndicators": maxIndicators });
});
}
......@@ -422,9 +424,9 @@ const odClick = (e) => {
});*/
}
// select and add flows toward those origins, i.e., for dots that are both origins and destinations
let dests = e.target.originAndDestinationGeoJsonPoints.features.filter( f => f.geometry.coordinates[0] === e.latlng.lng && f.geometry.coordinates[1] === e.latlng.lat);
let dests = e.target.originAndDestinationGeoJsonPoints.features.filter(f => f.geometry.coordinates[0] === e.latlng.lng && f.geometry.coordinates[1] === e.latlng.lat);
e.target.selectFeaturesForPathDisplay(dests, "SELECTION_ADD");
dests.forEach( dest => {
dests.forEach(dest => {
//origins += `${dest.properties.muni_origen} &rarr; ${dest.properties.muni_destino}: ${dest.properties.viajes} viajes <br>`;
// style viajes thousands with #,###
origins += `<tr><td>${dest.properties.muni_origen}</td><td>${dest.properties.muni_destino}</td><td>${dest.properties.viajes.toLocaleString()}</td></tr>`;
......@@ -445,13 +447,13 @@ const odClick = (e) => {
const populateMap = async(mapData) => {
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
//const chartData = await getData();
// fake null data to avoid DB requests
chartData = [];
indicators.map( indicator => {
indicators.map(indicator => {
chartData[indicator] = [];
chartData[indicator].push({name: `${indicator}0`, values: [{"date": new Date("2016-01-01T06:00:00.000Z"),"value":0}]});
chartData[indicator].push({ name: `${indicator}0`, values: [{ "date": new Date("2016-01-01T06:00:00.000Z"), "value": 0 }] });
})
// Define charts with reusable components
......@@ -495,7 +497,7 @@ const populateMap = async(mapData) => {
//map.createPane("wb-Tiles");
//map.getPane("wb-Tiles").style.zIndex = 450;
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
// create mvt layers
/*userFiles.forEach(f => {
f = mapboxLayer(f);
......@@ -512,7 +514,7 @@ const populateMap = async(mapData) => {
// after mapboxGL map is ready with styles do this:
glmap.getMapboxMap().on("style.load", () => {
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
/*userFiles.forEach(monthYear => {
glmap.getMapboxMap().addLayer(currentTiles[monthYear]);
});
......@@ -533,7 +535,7 @@ const populateMap = async(mapData) => {
});
timeLayer.addTo(map);*/
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
// style currentTiles
/*let option = $("#indicatorSelect").val(); // option selected from dropdrown
styleTiles(option, minIndicators, maxIndicators)
......@@ -546,77 +548,77 @@ const populateMap = async(mapData) => {
"OpenStreetMap": osmLayer
};
var overlays = {
// "<span id=\"cuencaOverlay\">Agua en la cuenca del Grijalva</span>": timeLayer
// "<span id=\"cuencaOverlay\">Agua en la cuenca del Grijalva</span>": timeLayer
};
layerControl = L.control.layers(baseLayers, overlays).addTo(map);
makeBaseMap() // basemap.js
//.then( flowLayers => { });
legend.addTo(map);
// fix for leaflet-mapbox-gl v. 0.0.11 that adds map's to tile pane:
// get children of map tile pane, create array from it and iterate
// setting their z-index
let glmapChildren = map.getPanes().tilePane.children,
children = Array.from(glmapChildren);
children.forEach( c => c.style.zIndex = "inherit" );
children.forEach(c => c.style.zIndex = "inherit");
});
}
const updateMap = (mapData) => {
//console.log(userFiles);
// FIX: comment out to avoid DB calls
// FIX: comment out to avoid DB calls
// clear tiles
/* currentTiles = {};
//retrieve or create tiles for current dates
userFiles.forEach(monthYear => {
if (Object.keys(allTiles).includes(monthYear)) {
currentTiles[monthYear] = allTiles[monthYear]; // recover tile if it has already been created
//currentJSONs[monthYear] = allJSONs[monthYear]; // recover json if it has already been created
return; // if file has already been processed, exit
} else { // if file cannot be found in allTiles, then add 1 to the number of files to process
let newTile = mapboxLayer(monthYear);
glmap.getMapboxMap().addLayer(newTile);
if (monthYear == userFiles[0]) {
glmap.getMapboxMap().setPaintProperty(monthYear, "fill-opacity", 0.7)
/* currentTiles = {};
//retrieve or create tiles for current dates
userFiles.forEach(monthYear => {
if (Object.keys(allTiles).includes(monthYear)) {
currentTiles[monthYear] = allTiles[monthYear]; // recover tile if it has already been created
//currentJSONs[monthYear] = allJSONs[monthYear]; // recover json if it has already been created
return; // if file has already been processed, exit
} else { // if file cannot be found in allTiles, then add 1 to the number of files to process
let newTile = mapboxLayer(monthYear);
glmap.getMapboxMap().addLayer(newTile);
if (monthYear == userFiles[0]) {
glmap.getMapboxMap().setPaintProperty(monthYear, "fill-opacity", 0.7)
}
}
}
});
});
// update timeDimension times
timeLayer._timeDimension.setAvailableTimes(userDates, "replace");
timeLayer._timeDimension.setCurrentTime(mapData.min);
// update timeDimension times
timeLayer._timeDimension.setAvailableTimes(userDates, "replace");
timeLayer._timeDimension.setCurrentTime(mapData.min);
// clear minmax indicators objects
maxIndicators = {},
minIndicators = {};
indicators.forEach((indicator) => {
maxIndicators[indicator] = 0;
minIndicators[indicator] = 1e30;
});
// clear minmax indicators objects
maxIndicators = {},
minIndicators = {};
indicators.forEach((indicator) => {
maxIndicators[indicator] = 0;
minIndicators[indicator] = 1e30;
});
// query db for new minmax values then style tiles
new Promise(resolve => {
queryFiles().then(minmax => {
minmax.map(minmaxMonth => {
indicators.forEach((indicator) => {
minIndicators[indicator] = Math.min(minIndicators[indicator], minmaxMonth[`min${indicator}`]);
maxIndicators[indicator] = Math.max(maxIndicators[indicator], minmaxMonth[`max${indicator}`]);
// query db for new minmax values then style tiles
new Promise(resolve => {
queryFiles().then(minmax => {
minmax.map(minmaxMonth => {
indicators.forEach((indicator) => {
minIndicators[indicator] = Math.min(minIndicators[indicator], minmaxMonth[`min${indicator}`]);
maxIndicators[indicator] = Math.max(maxIndicators[indicator], minmaxMonth[`max${indicator}`]);
});
});
});
resolve({ "map": map, "minIndicators": minIndicators, "maxIndicators": maxIndicators });
})
}).then(values => { // once we have new minmax values, style all tiles
let option = $("#indicatorSelect").val(), // option selected from dropdrown
min = values.minIndicators,
max = values.maxIndicators;
styleTiles(option, min, max)
.then(legend.addTo(map)); // add legend control -> it updates
});
// Update charts
updateCharts();
*/
resolve({ "map": map, "minIndicators": minIndicators, "maxIndicators": maxIndicators });
})
}).then(values => { // once we have new minmax values, style all tiles
let option = $("#indicatorSelect").val(), // option selected from dropdrown
min = values.minIndicators,
max = values.maxIndicators;
styleTiles(option, min, max)
.then(legend.addTo(map)); // add legend control -> it updates
});
// Update charts
updateCharts();
*/
}
const updateCharts = async() => {
......@@ -628,12 +630,14 @@ const updateCharts = async() => {
let allData = await getDataInSelection();
indicators.map(async indicator => {
indicatorVars[indicator].chart.data(summarizeData(allData, indicator));
// indicatorVars[indicator].cd_chart.data(summarizeData(allData, indicator));
});
} else {
// otherwise use all data
let allData = await getData();
indicators.map(async indicator => {
indicatorVars[indicator].chart.data(allData[indicator]);
// indicatorVars[indicator].cd_chart.data(allData[indicator]);
});
}
$(".loader").hide("fade", 750);
......@@ -770,6 +774,7 @@ L.TimeDimension.Layer.Tile = L.TimeDimension.Layer.extend({
indicators.forEach(indicator => {
indicatorVars[indicator].chartData = indicatorVars[indicator].chart.data(); // get chart data
indicatorVars[indicator].chart.data(indicatorVars[indicator].chartData); // set chart data
// indicatorVars[indicator].cd_chart.data(indicatorVars[indicator].chartData); // set chart data
});
//console.time("process");
......@@ -795,7 +800,7 @@ $("#indicatorSelect").on("change", function() {
// style currentTiles
let option = this.value; // option selected from dropdrown
flowMapsArray.forEach( layer => {
flowMapsArray.forEach(layer => {
if (layer.options.customLayerId === option) {
map.addLayer(layer);
layer.on('click', odClick);
......@@ -809,11 +814,23 @@ $("#indicatorSelect").on("change", function() {
layer.off("click", odClick);
map.removeLayer(layer);
}
});
});
// on select, update chart data
let amchart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "amchartdiv")
amchart.data = odData[option];
let amchart2 = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "prueba2")
amchart2.data = odData[option];
amchart2.data = amchart2.data.filter(function(e) { return e.flowCount > 0 });
//console.log(amchart2.data.filter(function(e) { return e.flowCount > 0 }))
/* let amchart1 = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "prueba")
amchart1.data = odData[option];
amchart1.data = amchart1.data.filter(function(e) { return e.flowCount > 0 });*/
// on select, update chart data
let amchart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "amchartdiv")
amchart.data = odData[option];
styleTiles(option, minIndicators, maxIndicators)
.then(legend.addTo(map)); // add legend control -> it updates
......@@ -864,7 +881,7 @@ legend.onAdd = function() {
//var html = `<h6>${indicatorsShortNames[optionIndex]}</h6><ul>`;
//let domain =
//scale = chroma.scale("PuBu").padding([0.5, 0]).domain(domain).classes(5);
// data
let classes = intervals[option].classes;
......@@ -876,7 +893,7 @@ legend.onAdd = function() {
});*/
// create stuff for each type of flow
classes.forEach( (c, idx) => {
classes.forEach((c, idx) => {
// create list element
let item = L.DomUtil.create('li');
// create canvas element with arc of appropriate thickness ad color
......@@ -905,10 +922,9 @@ legend.onAdd = function() {
// append text to list item
item.appendChild(span)
// lastly, append item to list
// lastly, append item to list
list.appendChild(item);
});
return div;
};
};
\ No newline at end of file
......@@ -494,4 +494,4 @@ am4core.ready(function() {
}); // end am4core.ready()*/
\ No newline at end of file
}); // end am4core.ready */
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment