Commit bdb7e537 authored by Rodrigo Tapia-McClung's avatar Rodrigo Tapia-McClung

Updateable OD matrix amchart w/ gradient heatLegend

parent 3172bb29
......@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<title>Crecimiento urbano en la regi&oacute;n metropolitana centro pa&iacute</title>
<title>Crecimiento urbano en la regi&oacute;n metropolitana centro pa&iacute;s</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
......@@ -76,8 +76,8 @@
<div class="loader"></div>
<div class="row h-50 border-bottom">
<div class="col-6 border-right">
<div id="area-graph">
<table class="table table-dark table-striped" id="tblViajesDesde">
<div id="tablediv">
<table class="table table-dark table-striped" id="tblViajes">
<thead>
<tr>
<th scope="col">Origen</th>
......@@ -95,7 +95,7 @@
</div>
<div class="row h-50">
<div class="col-6 border-right">
<div id="costa-graph"></div>
<div id="amchartdiv"></div>
</div>
<div class="col-6">
<div id="df-graph"></div>
......@@ -163,9 +163,15 @@
<!-- load animation tweening lib requirement for CanvasFlowMapLayer -->
<script src="https://unpkg.com/@tweenjs/tween.js@18.5/dist/tween.umd.js"></script>
<script src="../js/CanvasFlowmapLayer.js"></script>
<!-- amcharts-->
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<script src="../js/centropais_functions.js"></script>
<script src="../js/centropais_basemap.js"></script>
<!--<script src="../js/grijalva_charts.js"></script>-->
<script src="../js/centropais_charts.js"></script>
</body>
......
:root {
--main-bg-color: #262626;
--main-text-color: #b2b2b2;
--main-bg-color:#262626;
--main-text-color:#b2b2b2;
--cell-bg-color:#333;
}
*{
......@@ -15,6 +16,10 @@ body {
color:#333;
font-family:sans-serif;
background-color: var(--main-bg-color);
/*line-height: 1.5;
font: 12px sans-serif;
/*color: var(--main-text-color);
background-color: var(--cell-bg-color);*/
}
.img_bg{
......@@ -237,6 +242,10 @@ span.frac > span {
display: none;
}
#tblViajes {
font: 12px sans-serif;
}
/******
Icons
******/
......@@ -328,7 +337,7 @@ Icons
[class^="fa-"], [class*=" fa-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
font-family: 'icomoon' /*!important*/;
speak: none;
font-style: normal;
font-weight: normal;
......@@ -428,6 +437,16 @@ Icons
}
/* Graphs */
#amchartdiv {
width: 100%;
height: 100%;
}
.amcharttooltip {
font: 12px sans-serif;
}
.active {
text-decoration: underline;
font-weight: 600;
......@@ -482,7 +501,7 @@ Icons
.tooltip {
position: absolute;
bottom: 50%; /* so it is not added below the map and scroll bars appear */
/*bottom: 50%; /* so it is not added below the map and scroll bars appear */
/*width: 120px;
height: 20px;*/
z-index: 1001;
......
/*
* Copyright 2019 - All rights reserved.
* Copyright 2019-2020 - All rights reserved.
* Rodrigo Tapia-McClung
*
* August-September 2019
* August 2019 - June 2020
*/
/* global baseFileSize, formatBytes, Promise, omnivore, JSZip, map, layerControl, intervals, updateCharts, odClick*/
/* exported makeBaseMap, baseLayerPromises, drawnItems */
/* global baseFileSize, formatBytes, Promise, omnivore, JSZip, map, layerControl, intervals, updateCharts, odClick, am4core*/
/* exported, odData, makeBaseMap, baseLayerPromises, drawnItems */
/* Lines related to displaying loading bar are commented */
......@@ -18,8 +18,8 @@ let baseLayerPromises = [];
baseLayerCounter = 0,
currentBaseLayer = 1;*/
let drawnItems;
let od, flowMapsArray = [];
//let drawnItems;
let od, flowMapsArray = [], odData = {};
/*Object.keys(baseFileSize).forEach((name) => {
if (name.split(".")[1] == "zip") {
......@@ -29,6 +29,10 @@ let od, flowMapsArray = [];
}
});*/
function compare(el1, el2, index) {
return el1[index] == el2[index] ? 0 : (el1[index] < el2[index] ? -1 : 1);
}
// function to read compressed json and create a leaflet layer
const zip2Lyr = (zipFile, layerName, layerTemplate) => {
baseLayerPromises.push(
......@@ -924,6 +928,39 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
});
$.getJSON(geojson, data => {
// 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}) );
let origins= [],
destinations = [];
newData.forEach( data => {
origins.push(data.xVar); // all origins
destinations.push(data.yVar) // all destinations
});
origins = origins.filter((v, i, a) => a.indexOf(v) === i); // get unique ones
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});
}
})
});
// sort array by origins and then by destinations
newData.sort( (el1,el2) => {
let compared = compare(el1, el2, "xVar")
return compared == 0 ? compare(el1, el2, "yVar") : compared;
});
odData[type] = newData; // push to chart data object to reuse
// TODO: add heatColors to each data array
let flowMapLayer = L.canvasFlowmapLayer(data, {
// Define origins and destination from json values
originAndDestinationFieldIds: {
......@@ -989,9 +1026,11 @@ const createFlowLayer = (geojson, type, addOnCreate) => {
return label[0].properties.nombre;
})
// if layer is to be added to on creation, add click funcionality
// if layer is to be added on creation, add click funcionality and populate chart
if (addOnCreate) {
flowMapLayer.addTo(map).on('click', odClick);
let amchart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "amchartdiv");
amchart.data = newData;
}
flowMapsArray.push(flowMapLayer);
resolve(flowMapsArray);
......@@ -1114,9 +1153,12 @@ const makeBaseMap = () => {
}
});
layer._resetCanvas();
$("#tblViajesDesde tbody").html("");
$("#tblViajes tbody").html("");
}
});
// TODO: reset amchart
//let amchart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "amchartdiv")
//amchart.data = odData.ocupadosDesde;
});
//resolve(layers);
});
......
This diff is collapsed.
/*
* Copyright 2019 - All rights reserved.
* Copyright 2019-2020 - All rights reserved.
* Rodrigo Tapia-McClung
*
* August-September 2019
* August 2019 - June 2020
*/
/* globals omnivore, Promise, chroma, makeBaseMap, makeIndicatorGraph, getData, getDataInSelection */
......@@ -71,7 +71,7 @@ let intervals = {
},
"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, 533000],
"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]
......@@ -423,9 +423,10 @@ const odClick = (e) => {
e.target.selectFeaturesForPathDisplay(dests, "SELECTION_ADD");
dests.forEach( dest => {
//origins += `${dest.properties.muni_origen} &rarr; ${dest.properties.muni_destino}: ${dest.properties.viajes} viajes <br>`;
origins += `<tr><td>${dest.properties.muni_origen}</td><td>${dest.properties.muni_destino}</td><td>${dest.properties.viajes}</td></tr>`;
// 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>`;
});
$("#tblViajesDesde tbody").html(origins);
$("#tblViajes tbody").html(origins);
if (e.sharedDestinationFeatures.length) {
//e.target.selectFeaturesForPathDisplay(e.sharedDestinationFeatures, "SELECTION_ADD");
......@@ -435,6 +436,8 @@ const odClick = (e) => {
/*if (e.sharedDestinationFeatures.length) {
e.target.selectFeaturesForPathDisplay(e.sharedDestinationFeatures, "SELECTION_NEW");
}*/
// TODO: trigger chart update to only draw selected origins and destinations?
}
const populateMap = async(mapData) => {
......@@ -784,7 +787,6 @@ L.timeDimension.layer.Tile = (layer, options) => {
return new L.TimeDimension.Layer.Tile(layer, options);
};
// When selecting indicator from dropdown, style tiles.
$("#indicatorSelect").on("change", function() {
// style currentTiles
......@@ -806,6 +808,10 @@ $("#indicatorSelect").on("change", function() {
}
});
// 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
// FIXME: re-adding control updates its contents... why?
......
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