Commit 89c8ea79 authored by Rodrigo Tapia-McClung's avatar Rodrigo Tapia-McClung

Update radar chart on date change

parent c88945e4
......@@ -6,7 +6,7 @@
*/
/* globals updateBarChart, barChartData, am4charts, am4core, am4themes_animated, yearList */
/* export makeRadialChart, makeLineChart, makeAreaChart, makeBarChart */
/* export makeRadarChart, makeLineChart, makeAreaChart, makeBarChart */
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function grijalva_theme(target) {
......@@ -44,29 +44,29 @@ am4core.useTheme(grijalva_theme);
let mainTextColor = getComputedStyle(document.body).getPropertyValue('--main-text-color');
const makeRadialSeries = (chart, value, category, name, color) => {
let radialSeries = chart.series.push(new am4charts.RadarSeries());
radialSeries.dataFields.valueY = value;
radialSeries.dataFields.categoryX = category;
radialSeries.strokeWidth = 1.5;
radialSeries.tooltipText = "{valueY}";
radialSeries.name = name;
//radialSeries.connect = false;
//radialSeries.connectEnds = false;
radialSeries.stroke = am4core.color(color); // red
radialSeries.tooltip.getFillFromObject = false;
radialSeries.tooltipText = "[bold] {name}: [/]{valueY.formatNumber('#,###.0')} Ha[/]";
radialSeries.tooltip.background.fill = am4core.color(color);
const makeRadarSeries = (chart, value, category, name, color) => {
let radarSeries = chart.series.push(new am4charts.RadarSeries());
radarSeries.dataFields.valueY = value;
radarSeries.dataFields.categoryX = category;
radarSeries.strokeWidth = 1.5;
radarSeries.tooltipText = "{valueY}";
radarSeries.name = name;
//radarSeries.connect = false;
//radarSeries.connectEnds = false;
radarSeries.stroke = am4core.color(color); // red
radarSeries.tooltip.getFillFromObject = false;
radarSeries.tooltipText = "[bold] {name}: [/]{valueY.formatNumber('#,###.0')} Ha[/]";
radarSeries.tooltip.background.fill = am4core.color(color);
}
const makeRadialRange = (axis, start, end, color, span) => {
let radialRange = axis.axisRanges.create();
radialRange.category = start;
radialRange.endcategory = end;
radialRange.axisFill.fill = am4core.color(color);
radialRange.axisFill.fillOpacity = 0.4;
radialRange.grid.strokeOpacity = 0;
radialRange.locations.endCategory = span ? span : "";
const makeRadarRange = (axis, start, end, color, span) => {
let radarRange = axis.axisRanges.create();
radarRange.category = start;
radarRange.endcategory = end;
radarRange.axisFill.fill = am4core.color(color);
radarRange.axisFill.fillOpacity = 0.4;
radarRange.grid.strokeOpacity = 0;
radarRange.locations.endCategory = span ? span : "";
}
const makeLineAxisAndSeries = (chart, field, name, opposite, bullet) => {
......@@ -145,64 +145,64 @@ const makeBarSeries = (chart, field, name) => {
barValueLabel.label.fill = am4core.color("#fff");
}
const makeRadialChart = (data, months, years) => {
let radialChart = am4core.create("radial_chart", am4charts.RadarChart);
const makeRadarChart = (data, months, years) => {
let radarChart = am4core.create("radial_chart", am4charts.RadarChart);
let radialTitle = radialChart.titles.create();
radialTitle.text = "Superficie total por año";
radialTitle.fontSize = 10;
radialTitle.marginBottom = 10;
radialTitle.fill = am4core.color(mainTextColor);
let radarTitle = radarChart.titles.create();
radarTitle.text = "Superficie total por año";
radarTitle.fontSize = 10;
radarTitle.marginBottom = 10;
radarTitle.fill = am4core.color(mainTextColor);
radialChart.data = data;
radarChart.data = data;
/* Create axes */
let radialCategoryAxis = radialChart.xAxes.push(new am4charts.CategoryAxis());
radialCategoryAxis.dataFields.category = "month";
radialCategoryAxis.fontSize = 9;
radialCategoryAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
radialCategoryAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
let radialValueAxis = radialChart.yAxes.push(new am4charts.ValueAxis());
radialValueAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
radialValueAxis.extraMin = 0.2;
radialValueAxis.extraMax = 0.2;
radialValueAxis.tooltip.disabled = true;
radialValueAxis.fontSize = 9;
radialValueAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
radialValueAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
//radialValueAxis.renderer.labels.template.fontSize = 15;
let radarCategoryAxis = radarChart.xAxes.push(new am4charts.CategoryAxis());
radarCategoryAxis.dataFields.category = "month";
radarCategoryAxis.fontSize = 9;
radarCategoryAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
radarCategoryAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
let radarValueAxis = radarChart.yAxes.push(new am4charts.ValueAxis());
radarValueAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
radarValueAxis.extraMin = 0.2;
radarValueAxis.extraMax = 0.2;
radarValueAxis.tooltip.disabled = true;
radarValueAxis.fontSize = 9;
radarValueAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
radarValueAxis.renderer.grid.template.stroke = am4core.color(mainTextColor);
//radarValueAxis.renderer.labels.template.fontSize = 15;
/* Create and configure series */
let seriesColor = ["#F98293", "#2AC2BB", "#FDA259"];
years.forEach( (year, i) => {
makeRadialSeries(radialChart, year, "month", year, seriesColor[i]);
makeRadarSeries(radialChart, year, "month", year, seriesColor[i]);
});
radialChart.scrollbarX = new am4core.Scrollbar();
radialChart.scrollbarX.minHeight = 1;
radialChart.scrollbarX.parent = radialChart.bottomAxesContainer;
radialChart.scrollbarY = new am4core.Scrollbar();
radialChart.scrollbarY.minWidth = 1;
customizeGrip(radialChart.scrollbarX.startGrip);
customizeGrip(radialChart.scrollbarX.endGrip);
customizeGrip(radialChart.scrollbarY.startGrip);
customizeGrip(radialChart.scrollbarY.endGrip);
let radialRangeColors = ["#E1DBC8", "#595952", "#838278", "#B1AE9F"];
makeRadialRange(radialCategoryAxis, "enero", "marzo", radialRangeColors[0], 2);
makeRadialRange(radialCategoryAxis, "marzo", "mayo", radialRangeColors[1], 2);
makeRadialRange(radialCategoryAxis, "mayo", "septiembre", radialRangeColors[2], 4);
makeRadialRange(radialCategoryAxis, "septiembre", "diciembre", radialRangeColors[3], 3);
makeRadialRange(radialCategoryAxis, "diciembre", "diciembre", radialRangeColors[0], 1);
radialChart.cursor = new am4charts.RadarCursor();
radarChart.scrollbarX = new am4core.Scrollbar();
radarChart.scrollbarX.minHeight = 1;
radarChart.scrollbarX.parent = radarChart.bottomAxesContainer;
radarChart.scrollbarY = new am4core.Scrollbar();
radarChart.scrollbarY.minWidth = 1;
customizeGrip(radarChart.scrollbarX.startGrip);
customizeGrip(radarChart.scrollbarX.endGrip);
customizeGrip(radarChart.scrollbarY.startGrip);
customizeGrip(radarChart.scrollbarY.endGrip);
let radarRangeColors = ["#E1DBC8", "#595952", "#838278", "#B1AE9F"];
makeRadarRange(radarCategoryAxis, "enero", "marzo", radarRangeColors[0], 2);
makeRadarRange(radarCategoryAxis, "marzo", "mayo", radarRangeColors[1], 2);
makeRadarRange(radarCategoryAxis, "mayo", "septiembre", radarRangeColors[2], 4);
makeRadarRange(radarCategoryAxis, "septiembre", "diciembre", radarRangeColors[3], 3);
makeRadarRange(radarCategoryAxis, "diciembre", "diciembre", radarRangeColors[0], 1);
radarChart.cursor = new am4charts.RadarCursor();
// add line legend
radialChart.legend = new am4charts.Legend();
//radialChart.legend.fontSize = 10;
radialChart.legend.fontSize = 9;
radialChart.legend.labels.template.fill = am4core.color(mainTextColor);
radarChart.legend = new am4charts.Legend();
//radarChart.legend.fontSize = 10;
radarChart.legend.fontSize = 9;
radarChart.legend.labels.template.fill = am4core.color(mainTextColor);
let legenddata = [{ name: "Estiaje", fill: am4core.color("#595952") },
{ name: "Tropical", fill: am4core.color("#838278") },
......@@ -211,11 +211,11 @@ const makeRadialChart = (data, months, years) => {
];
// add second legend
radialChart.legend = new am4charts.Legend();
radialChart.legend.data = legenddata;
radialChart.legend.fontSize = 10;
radialChart.legend.labels.template.fill = am4core.color(mainTextColor);
let markerTemplate = radialChart.legend.markers.template;
radarChart.legend = new am4charts.Legend();
radarChart.legend.data = legenddata;
radarChart.legend.fontSize = 10;
radarChart.legend.labels.template.fill = am4core.color(mainTextColor);
let markerTemplate = radarChart.legend.markers.template;
markerTemplate.width = 20;
markerTemplate.height = 20;
}
......
......@@ -5,7 +5,7 @@
* January 2021
*/
/* globals omnivore, Promise, makeBaseMap, am4core, makeRadialChart, makeLineChart, makeAreaChart, makeBarChart */
/* globals omnivore, Promise, makeBaseMap, am4core, makeRadarChart, makeLineChart, makeAreaChart, makeBarChart */
/* exported. userFiles, userDates, timeParse, layerControl, yearList */
let timeParse,
......@@ -65,10 +65,11 @@ const sortInitialDateAscending = (a, b) => {
return a - b;
}
const baseUrl = new URL(`/data`, window.location.href).href;
// query available dates on DB
const setupDates = () => {
return new Promise(resolve => {
const baseUrl = new URL(`/data`, window.location.href).href;
let layersQuery = `${baseUrl}/list_layers`;
d3.json(layersQuery).then(layers => {
layers.forEach(layer => {
......@@ -179,6 +180,7 @@ const populateDates = (dates) => { // fill out date pickers with available dates
} else {
// FIXME: no need to pass data here?
updateMap({ map: map, min: startUserDate, max: endUserDate });
updateCharts();
}
},
beforeShow: (el, inst) => {
......@@ -317,7 +319,6 @@ const populateMap = async (mapData) => {
// after mapboxGL map is ready with styles do this:
glmap.getMapboxMap().on("style.load", () => {
const baseUrl = new URL(`/data`, window.location.href).href;
glmap.getMapboxMap().addSource("basecuerposagua", {
type: "vector",
//tiles: [`${baseUrl}/basecuerposagua/mvt/{z}/{x}/{y}?geom_column=geom&columns=${indicators.join()},descrip`],
......@@ -426,7 +427,7 @@ const updateMap = (mapData) => {
// define MVT layer for given month table and all indicators
const mapboxLayer = (monthYear) => {
const baseUrl = new URL(`/data`, window.location.href).href;
let pbfLayer = {
id: monthYear,
source: {
......@@ -572,19 +573,20 @@ legend.onAdd = () => {
return div;
};
let barChartData = [],
let radarData = [],
barChartData = [],
yearList;
const makeCharts = () => {
let baseUrl = new URL(`/data`, window.location.href).href;
// create sets of unique months and years
yearList = [... new Set(userDates.map( date => new Date(date).getFullYear() ))];
let allYears = [... new Set(dateArray.map( date => new Date(date).getFullYear() ))];
//let formatter = new Intl.DateTimeFormat('es', { month: 'long' });
// RADIAL CHART
// RADAR CHART
// get am chart - may need this to update chart on date change
//let radialChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "radial_chart");
//let radarChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "radial_chart");
// async queries for each date that has been loaded
const queries = userFiles.map(async (mes, i) => {
......@@ -592,25 +594,26 @@ const makeCharts = () => {
let query = `${baseUrl}/query/${mes}?columns=sum(areacpo)/10000 area`;
const queryData = await d3.json(query);
queryData[0].date = new Date(userDates[i]);
radarData.push(queryData[0]);
return new Promise(resolve => {
resolve(queryData[0]);
});
});
// wait for all queries to complete and then set chart data
Promise.all(queries).then( data => {
radarData.sort((a, b) => (a.date > b.date) ? 1 : -1);
// TODO: maybe make this a function so it can be used to update chart when changing dates
let radialChartData = [];
let radarChartData = [];
monthArray.forEach( (month, index) => {
let element = {};
yearList.forEach( year => {
//element.month = formatter.format(new Date(year, month, 1, 0, 0, 0));
element.month = month.toLowerCase();
let yearData = data.filter(d => new Date(d.date).getMonth() == index && new Date(d.date).getFullYear() == year);
element[year] = yearData.length > 0 ? yearData[0].area : null;
});
radialChartData.push(element);
radarChartData.push(element);
});
makeRadialChart(radialChartData, monthArray, yearList);
makeRadarChart(radarChartData, monthArray, allYears);
});
// LINE + STACKED AREA CHARTS
......@@ -706,4 +709,50 @@ const updateBarChart = (filterDate, data) => {
popBarsChart.data = cart_pb1;
popBarsChart.invalidateRawData();
}
}
const updateCharts = () => {
yearList = [... new Set(userDates.map( date => new Date(date).getFullYear() ))];
// update radar chart
let radarChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "radial_chart");
const queries = userDates.map( async (date, i) => {
let checkDate = new Date(date);
// check what month has not been queried before and query it
if (!radarData.some(d => d.date.valueOf() === checkDate.valueOf())) {
let query = `${baseUrl}/query/${userFiles[i]}?columns=sum(areacpo)/10000 area`;
const queryData = await d3.json(query);
queryData[0].date = new Date(userDates[i]);
radarData.push(queryData[0]);
return new Promise(resolve => {
resolve(queryData[0]);
});
}
})
// wait for all queries to complete and then set chart data
Promise.all(queries).then( () => {
// TODO: maybe make this a function so it can be used to update chart when changing dates
let radarChartData = [];
// check what months should have data
radarData.sort((a, b) => (a.date > b.date) ? 1 : -1);
let booleanCheck = radarData.map( (d,i) => d.date.valueOf() == userDates[i]);
let newRadarData = radarData.map( (d,i) => {
if (booleanCheck[i]) return d;
});
let filtredRadarData = newRadarData.filter( d => d != undefined );
monthArray.forEach( (month, index) => {
let element = {};
yearList.forEach( year => {
element.month = month.toLowerCase();
let yearData = filtredRadarData.filter(d => new Date(d.date).getMonth() == index && new Date(d.date).getFullYear() == year);
element[year] = yearData.length > 0 ? yearData[0].area : null;
});
radarChartData.push(element);
});
radarChart.data = radarChartData;
radarChart.invalidateRawData();
});
}
\ 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