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

Improve area chart creation

parent 25d53dee
......@@ -39,7 +39,7 @@ function customizeGrip(grip) {
let mainTextColor = getComputedStyle(document.body).getPropertyValue('--main-text-color');
const createRadialSeries = (chart, value, category, name, color) => {
const makeRadialSeries = (chart, value, category, name, color) => {
let radialSeries = chart.series.push(new am4charts.RadarSeries());
radialSeries.dataFields.valueY = value;
radialSeries.dataFields.categoryX = category;
......@@ -64,7 +64,7 @@ const makeRadialRange = (axis, start, end, color, span) => {
radialRange.locations.endCategory = span ? span : "";
}
const createLineAxisAndSeries = (chart, field, name, opposite, bullet) => {
const makeLineAxisAndSeries = (chart, field, name, opposite, bullet) => {
var lineValueAxis = chart.yAxes.push(new am4charts.ValueAxis());
lineValueAxis.fontSize = 8;
......@@ -91,7 +91,7 @@ const createLineAxisAndSeries = (chart, field, name, opposite, bullet) => {
lineValueAxis.renderer.opposite = opposite;
}
const makeLineRange = (axis, start, width, color) => {
const makeDateRange = (axis, start, width, color) => {
yearList.forEach( y => {
var range = axis.axisRanges.create();
range.date = new Date(y, start, 1, 0, 0, 0);
......@@ -100,6 +100,23 @@ const makeLineRange = (axis, start, width, color) => {
range.axisFill.fillOpacity = 0.4;
})
}
const makeAreaSeries = (chart, field, name) => {
let areasSeries = chart.series.push(new am4charts.LineSeries());
areasSeries.dataFields.dateX = "date";
areasSeries.name = name;
areasSeries.dataFields.valueY = field;
areasSeries.tooltipText = "[bold]{name}: [/]{valueY.formatNumber('#,###.#')} Ha";
//areasSeries.tooltip.background.fill = am4core.color("#FFF");
areasSeries.tooltip.getStrokeFromObject = true;
areasSeries.tooltip.background.strokeWidth = 3;
//areasSeries.tooltip.getFillFromObject = false;
areasSeries.fillOpacity = 0.6;
areasSeries.strokeWidth = 2;
areasSeries.stacked = true;
return areasSeries;
}
const makeRadialChart = (data, months, years) => {
let radialChart = am4core.create("radial_chart", am4charts.RadarChart);
......@@ -131,7 +148,7 @@ const makeRadialChart = (data, months, years) => {
/* Create and configure series */
let seriesColor = ["#F98293", "#2AC2BB", "#FDA259"];
years.forEach( (year, i) => {
createRadialSeries(radialChart, year, "month", year, seriesColor[i]);
makeRadialSeries(radialChart, year, "month", year, seriesColor[i]);
});
radialChart.scrollbarX = new am4core.Scrollbar();
......@@ -153,6 +170,7 @@ const makeRadialChart = (data, months, years) => {
radialChart.cursor = new am4charts.RadarCursor();
// add line legend
radialChart.legend = new am4charts.Legend();
//radialChart.legend.fontSize = 10;
radialChart.legend.fontSize = 9;
......@@ -164,6 +182,8 @@ const makeRadialChart = (data, months, years) => {
{ name: "Invernal", fill: am4core.color("#E1DBC8") }
];
// add second legend
radialChart.legend = new am4charts.Legend();
radialChart.legend.data = legenddata;
radialChart.legend.fontSize = 10;
radialChart.legend.labels.template.fill = am4core.color(mainTextColor);
......@@ -189,16 +209,16 @@ const makeLineChart = (data) => {
lineDateAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
// Create series
createLineAxisAndSeries(lineChart, "permanente", "Agua permanente", false, "circle");
createLineAxisAndSeries(lineChart, "temporal", "Áreas temporalmente inundadas", true, "triangle");
createLineAxisAndSeries(lineChart, "vegetacion", "Suelos húmedos-vegetación acuática", true, "rectangle");
makeLineAxisAndSeries(lineChart, "permanente", "Agua permanente", false, "circle");
makeLineAxisAndSeries(lineChart, "temporal", "Áreas temporalmente inundadas", true, "triangle");
makeLineAxisAndSeries(lineChart, "vegetacion", "Suelos húmedos-vegetación acuática", true, "rectangle");
// create line ranges
makeLineRange(lineDateAxis, 0, 2, "#E1DBC8");
makeLineRange(lineDateAxis, 2, 2, "#595952");
makeLineRange(lineDateAxis, 4, 4, "#838278");
makeLineRange(lineDateAxis, 8, 3, "#B1AE9F");
makeLineRange(lineDateAxis, 11, 1, "#E1DBC8");
makeDateRange(lineDateAxis, 0, 2, "#E1DBC8");
makeDateRange(lineDateAxis, 2, 2, "#595952");
makeDateRange(lineDateAxis, 4, 4, "#838278");
makeDateRange(lineDateAxis, 8, 3, "#B1AE9F");
makeDateRange(lineDateAxis, 11, 1, "#E1DBC8"); // FIXME: this range shows a small line separator between Dec-Jan
// Add cursor
lineChart.cursor = new am4charts.XYCursor();
......@@ -210,15 +230,7 @@ const makeLineChart = (data) => {
// Style scrollbar
}
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
am4core.useTheme(grijalva_theme);
//let mainTextColor = getComputedStyle(document.body).getPropertyValue('--main-text-color');
// Themes end
// area chart
const makeAreaChart = (data) => {
let areaChart = am4core.create("stackedAreaChart", am4charts.XYChart);
let areaTitle = areaChart.titles.create();
......@@ -227,6 +239,8 @@ am4core.ready(function() {
areaTitle.marginBottom = 15;
areaTitle.fill = am4core.color(mainTextColor);
areaChart.data = data;
// chart.dateFormatter.inputDateFormat = "dd-mm-yyyy";
var areaDateAxis = areaChart.xAxes.push(new am4charts.DateAxis());
areaDateAxis.renderer.minGridDistance = 60;
......@@ -244,57 +258,20 @@ am4core.ready(function() {
areaValueAxis.fontSize = 8;
areaValueAxis.renderer.labels.template.fill = am4core.color(mainTextColor);
//TODO: make these series in a more efficient way
var areasSeries = areaChart.series.push(new am4charts.LineSeries());
areasSeries.dataFields.dateX = "date";
areasSeries.name = "Agua permanente";
areasSeries.dataFields.valueY = "permanente";
//areasSeries.tooltipHTML = "<img src='https://www.amcharts.com/lib/3/images/car.png' style='vertical-align:bottom; margin-right: 10px; width:28px; height:21px;'><span style='font-size:14px; color:#000000;'><b>{valueY.value}</b></span>";
//areasSeries.tooltipText = "[#000]{valueY.value}[/]";
areasSeries.tooltipText = "[bold]{name}: [/]{valueY.formatNumber('#,###.#')} Ha";
//areasSeries.tooltip.background.fill = am4core.color("#FFF");
areasSeries.tooltip.getStrokeFromObject = true;
areasSeries.tooltip.background.strokeWidth = 3;
//areasSeries.tooltip.getFillFromObject = false;
areasSeries.fillOpacity = 0.6;
areasSeries.strokeWidth = 2;
areasSeries.stacked = true;
// Create series
let areaSeries1 = makeAreaSeries(areaChart, "permanente", "Agua permanente");
let areaSeries2 = makeAreaSeries(areaChart, "temporal", "Áreas temporalmente inundadas");
let areaSeries3 = makeAreaSeries(areaChart, "vegetacion", "Suelos húmedos-vegetación acuática");
var areasSeries2 = areaChart.series.push(new am4charts.LineSeries());
areasSeries2.name = "Áreas temporalmente inundadas";
areasSeries2.dataFields.dateX = "date";
areasSeries2.dataFields.valueY = "temporal";
//areasSeries2.tooltipHTML = "<img src='https://www.amcharts.com/lib/3/images/motorcycle.png' style='vertical-align:bottom; margin-right: 10px; width:28px; height:21px;'><span style='font-size:14px; color:#000000;'><b>{valueY.value}</b></span>";
//areasSeries2.tooltipText = "[#000]{valueY.value}[/]";
areasSeries2.tooltipText = "[bold]{name}: [/]{valueY.formatNumber('#,###.#')} Ha";
//areasSeries2.tooltip.background.fill = am4core.color("#FFF");
//areasSeries2.tooltip.getFillFromObject = false;
areasSeries2.tooltip.getStrokeFromObject = true;
areasSeries2.tooltip.background.strokeWidth = 3;
areasSeries2.sequencedInterpolation = true;
areasSeries2.fillOpacity = 0.6;
areasSeries2.stacked = true;
areasSeries2.strokeWidth = 2;
var areasSeries3 = areaChart.series.push(new am4charts.LineSeries());
areasSeries3.name = "Suelos húmedos-vegetación acuática";
areasSeries3.dataFields.dateX = "date";
areasSeries3.dataFields.valueY = "vegetacion";
//areasSeries3.tooltipHTML = "<img src='https://www.amcharts.com/lib/3/images/bicycle.png' style='vertical-align:bottom; margin-right: 10px; width:28px; height:21px;'><span style='font-size:14px; color:#000000;'><b>{valueY.value}</b></span>";
//areasSeries3.tooltipText = "[#000]{valueY.value}[/]";
areasSeries3.tooltipText = "[bold]{name}: [/]{valueY.formatNumber('#,###.#')} Ha";
//areasSeries3.tooltip.background.fill = am4core.color("#FFF");
//areasSeries3.tooltip.getFillFromObject = false;
areasSeries3.tooltip.getStrokeFromObject = true;
areasSeries3.tooltip.background.strokeWidth = 3;
areasSeries3.sequencedInterpolation = true;
areasSeries3.fillOpacity = 0.6;
areasSeries3.defaultState.transitionDuration = 1000;
areasSeries3.stacked = true;
areasSeries3.strokeWidth = 2;
// create line ranges
makeDateRange(areaDateAxis, 0, 2, "#E1DBC8");
makeDateRange(areaDateAxis, 2, 2, "#595952");
makeDateRange(areaDateAxis, 4, 4, "#838278");
makeDateRange(areaDateAxis, 8, 3, "#B1AE9F");
makeDateRange(areaDateAxis, 11, 1, "#E1DBC8"); // FIXME: this range shows a small line separator between Dec-Jan
areaChart.cursor = new am4charts.XYCursor();
areaChart.snapToSeries = areasSeries2;
areaChart.snapToSeries = areaSeries2;
areaChart.cursor.xAxis = areaDateAxis;
areaChart.scrollbarX = new am4core.Scrollbar();
areaChart.scrollbarX.minHeight = 1;
......@@ -303,100 +280,13 @@ am4core.ready(function() {
customizeGrip(areaChart.scrollbarX.endGrip);
//areaChart.scrollbarX.position = "bottom";
// Add a legend
// axis ranges
//TODO: make these ranges in a more efficient way
var areaRange = areaDateAxis.axisRanges.create();
areaRange.date = new Date(2016, 0, 1);
areaRange.endDate = new Date(2016, 2, 1);
areaRange.axisFill.fill = am4core.color("#E1DBC8");
areaRange.axisFill.fillOpacity = 0.4;
var areaRange1 = areaDateAxis.axisRanges.create();
areaRange1.date = new Date(2016, 2, 1);
areaRange1.endDate = new Date(2016, 4, 1);
areaRange1.axisFill.fill = am4core.color("#595952");
areaRange1.axisFill.fillOpacity = 0.4;
var areaRange2 = areaDateAxis.axisRanges.create();
areaRange2.date = new Date(2016, 4, 1);
areaRange2.endDate = new Date(2016, 8, 1);
areaRange2.axisFill.fill = am4core.color("#838278");
areaRange2.axisFill.fillOpacity = 0.4;
var areaRange3 = areaDateAxis.axisRanges.create();
areaRange3.date = new Date(2016, 8, 1);
areaRange3.endDate = new Date(2016, 11, 1);
areaRange3.axisFill.fill = am4core.color("#B1AE9F");
areaRange3.axisFill.fillOpacity = 0.4;
var areaRange4 = areaDateAxis.axisRanges.create();
areaRange4.date = new Date(2016, 11, 1);
areaRange4.endDate = new Date(2017, 2, 1);
areaRange4.axisFill.fill = am4core.color("#E1DBC8");
areaRange4.axisFill.fillOpacity = 0.4;
var areaRange5 = areaDateAxis.axisRanges.create();
areaRange5.date = new Date(2017, 2, 1);
areaRange5.endDate = new Date(2017, 4, 1);
areaRange5.axisFill.fill = am4core.color("#595952");
areaRange5.axisFill.fillOpacity = 0.4;
var areaRange6 = areaDateAxis.axisRanges.create();
areaRange6.date = new Date(2017, 4, 1);
areaRange6.endDate = new Date(2017, 8, 1);
areaRange6.axisFill.fill = am4core.color("#838278");
areaRange6.axisFill.fillOpacity = 0.4;
var areaRange7 = areaDateAxis.axisRanges.create();
areaRange7.date = new Date(2017, 8, 1);
areaRange7.endDate = new Date(2017, 11, 1);
areaRange7.axisFill.fill = am4core.color("#B1AE9F");
areaRange7.axisFill.fillOpacity = 0.4;
var areaRange8 = areaDateAxis.axisRanges.create();
areaRange8.date = new Date(2017, 11, 1);
areaRange8.endDate = new Date(2018, 2, 1);
areaRange8.axisFill.fill = am4core.color("#E1DBC8");
areaRange8.axisFill.fillOpacity = 0.4;
var areaRange9 = areaDateAxis.axisRanges.create();
areaRange9.date = new Date(2018, 2, 1);
areaRange9.endDate = new Date(2018, 4, 1);
areaRange9.axisFill.fill = am4core.color("#595952");
areaRange9.axisFill.fillOpacity = 0.4;
var areaRange10 = areaDateAxis.axisRanges.create();
areaRange10.date = new Date(2018, 4, 1);
areaRange10.endDate = new Date(2018, 8, 1);
areaRange10.axisFill.fill = am4core.color("#838278");
areaRange10.axisFill.fillOpacity = 0.4;
var areaRange11 = areaDateAxis.axisRanges.create();
areaRange11.date = new Date(2018, 8, 1);
areaRange11.endDate = new Date(2018, 11, 1);
areaRange11.axisFill.fill = am4core.color("#B1AE9F");
areaRange11.axisFill.fillOpacity = 0.4;
var areaRange12 = areaDateAxis.axisRanges.create();
areaRange12.date = new Date(2018, 11, 1);
areaRange12.endDate = new Date(2019, 0, 1);
areaRange12.axisFill.fill = am4core.color("#E1DBC8");
areaRange12.axisFill.fillOpacity = 0.4;
/* Set up cursor behavior */
let previousDate = "";
areaChart.cursor.events.on("cursorpositionchanged", function(ev) {
let xAxis = ev.target.chart.xAxes.getIndex(0);
/*let axis = dateAxis.positionToDate(dateAxis.toAxisPosition(ev.target.xPosition)),
currentYear = axis.getFullYear().toString(),
currentMonth = axis.getMonth().toString();
console.log(currentYear, currentMonth)*/
let yy = xAxis.positionToDate(xAxis.toAxisPosition(ev.target.xPosition)).getFullYear().toString();
let mm = xAxis.positionToDate(xAxis.toAxisPosition(ev.target.xPosition)).getMonth().toString();
let month = 0,
startDate = 0,
endDate = 0;
let dateAxis = ev.target.chart.xAxes.getIndex(0);
let yy = dateAxis.positionToDate(dateAxis.toAxisPosition(ev.target.xPosition)).getFullYear().toString();
let mm = dateAxis.positionToDate(dateAxis.toAxisPosition(ev.target.xPosition)).getMonth().toString();
let month = 0;
if (mm < 9) { month = "0" + (parseInt(mm) + 1).toString(); } else {
month = parseInt(mm) + 1;
month.toString();
......@@ -408,6 +298,15 @@ am4core.ready(function() {
updateBarChart(filterDate, barChartData);
}
})
}
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
am4core.useTheme(grijalva_theme);
//let mainTextColor = getComputedStyle(document.body).getPropertyValue('--main-text-color');
// Themes end
// bar chart
var barChart = am4core.create("dimfrcpo-graph", am4charts.XYChart);
......
......@@ -5,7 +5,7 @@
* January 2021
*/
/* globals omnivore, Promise, makeBaseMap, am4core, makeRadialChart, makeLineChart */
/* globals omnivore, Promise, makeBaseMap, am4core, makeRadialChart, makeLineChart, makeAreaChart */
/* exported. userFiles, userDates, timeParse, layerControl, yearList */
let timeParse,
......@@ -323,7 +323,7 @@ const populateMap = async(mapData) => {
makeRadialChart(chartData, monthArray, yearList);
});
//LINE CHART
// LINE CHART
// get am chart - may need this to update chart on date change
//let linesChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "linesChart");
......@@ -337,7 +337,6 @@ const populateMap = async(mapData) => {
return new Promise(resolve => {
resolve(queryData);
});
});
// wait for all queries to complete and then set chart data
Promise.all(queries_ls).then( data => {
......@@ -361,45 +360,45 @@ const populateMap = async(mapData) => {
chartData.sort((a, b) => (a.date > b.date) ? 1 : -1);
makeLineChart(chartData);
});
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ STACKED AREAS CHART
let data_sa = [];
let stackedAreaChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "stackedAreaChart");
// STACKED AREA CHART
// get am chart - may need this to update chart on date change
//let stackedAreaChart = am4core.registry.baseSprites.find(c => c.htmlContainer.id === "stackedAreaChart");
// async queries for each date that has been loaded
// TODO: this is the exact same call as in LINE CHART => merge into one
const queries_sa = userFiles.map(async(mes, i) => {
let query_sa = `${baseUrl}/query/${mes}?columns=sum(areacpo)/10000 area, descrip&group=descrip`;
const queryData = await d3.json(query_sa);
let date = new Date(dateArray[i]);
//date.setFullYear(2016)
for (const wbody in queryData) {
queryData[wbody].date = date;
queryData[wbody].date = new Date(userDates[i]);
}
data_sa.push(queryData);
//data_sa.push(queryData);
return new Promise(resolve => {
resolve(queryData);
});
});
// wait for all queries to complete
const dataQueries_sa = await Promise.all(queries_sa);
// and then set chart data
//lineStackedChart.data = data_ls;
var merged_1 = [].concat.apply([], data_sa);
//console.log(data_sa);
let aguaPermanente_1 = merged_1.filter(function(d) { return d.descrip == "Agua permanente" });
let aguaTemporal_1 = merged_1.filter(function(d) { return d.descrip == "Áreas temporalmente inundadas" });
let aguaVegetacion_1 = merged_1.filter(function(d) { return d.descrip == "Suelos húmedos-vegetación acuática" });
let j;
for (j = 0; j < aguaPermanente_1.length; j++) {
aguaPermanente_1[j].permanente = aguaPermanente_1[j].area;
aguaPermanente_1[j].temporal = aguaTemporal_1[j].area;
aguaPermanente_1[j].vegetacion = aguaVegetacion_1[j].area;
delete aguaPermanente_1[j].descrip;
delete aguaPermanente_1[j].area;
}
// wait for all queries to complete and then set chart data
Promise.all(queries_sa).then( data => {
// TODO: maybe make this a function so it can be used to update chart when changing dates
let merged = [].concat.apply([], data);
let aguaPermanente = merged.filter(d => d.descrip == "Agua permanente" );
let aguaTemporal = merged.filter(d => d.descrip == "Áreas temporalmente inundadas" );
let aguaVegetacion = merged.filter(d => d.descrip == "Suelos húmedos-vegetación acuática" );
let chartData = [];
aguaPermanente.forEach( (wb, i) => {
let element = {
permanente: aguaPermanente[i].area,
temporal: aguaTemporal[i].area,
vegetacion: aguaVegetacion[i].area,
date: aguaPermanente[i].date
}
chartData.push(element);
});
let grijalva_bodies_1 = aguaPermanente_1;
grijalva_bodies_1.sort((a, b) => (a.date > b.date) ? 1 : -1)
stackedAreaChart.data = grijalva_bodies_1;
chartData.sort((a, b) => (a.date > b.date) ? 1 : -1);
makeAreaChart(chartData);
});
// populate bars
......
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