I am new to using Highcharts, so this may be a trivial issue. However, I have not had much success through my own googling about this.
I am trying to get a line graph to display strength progress over time, but every time I plug in the keySet() (of type java.util.Date) to be what is on the X-axis, the graph disappears from the web page.
I want the record of an event being done and the date it was done on to be a point on the graph (i.e. the (x,y) would be (action, date)).
Java stuff:
List<StrengthProgressPoint> records = getAllStrengthLogsForExercise(session, exerciseName);
Map<Date, Double> strengthGraph = new LinkedHashMap<>();
for(StrengthProgressPoint p : records) {
strengthGraph.put(p.getDate(), p.getWeight());
}
Highcharts stuff:
<script>
$(function () {
$('#progressGraphContainer').highcharts({
title: {
text: ''
},
subtitle: {
text: ''
},
yAxis: {
min: 0,
title: {
text: 'Weight Lifted'
}
},
xAxis: {
categories: [[${strengthGraph.keySet()}]],
},
legend: {
enabled: false
},
plotOptions: {
series: {
label: {
connectorAllowed: false,
connectNulls: true
},
}
},
series: [{
name: 'Weight',
data: [[${strengthGraph.values()}]]
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
enabled: false
}
}
}]
}
});
});
</script>
I did get a graph to display on my web page a few times, but never what I wanted. I have seemingly narrowed it down to the 'categories: [[${strengthGraph.keySet()}]]' being the culprit of causing the graph to just not show up on the web page. I just want the dates in the HashMap to display on the x-axis (and correspond to the appropriate values of course).
Because you are using Thymeleaf with JavaScript, you need to indicate this in your <script>
tag:
<script th:inline="javascript">
Without this, the rendering from your Java objects to the equivalent JavaScript objects will not take place.
I assume you have already included the Thymeleaf namespace in the page's <html>
tag:
<html xmlns:th="http://www.thymeleaf.org">
Dates will be displayed on the x-axis - but the format may be a bit cumbersome - for example:
2021-03-15T00:00:00.000-04:00
So, you can add a label formatter. There are many ways to format a date, and I expect HighCharts has built-in ways to do this, but I am not familiar with them - so here is a plain JavaScript way:
xAxis: {
categories: [[${strengthGraph.keySet()}]],
labels: {
formatter: function () {
var d = Date.parse(this.value);
const ye = new Intl.DateTimeFormat('en', {year: 'numeric'}).format(d);
const mo = new Intl.DateTimeFormat('en', {month: 'short'}).format(d);
const da = new Intl.DateTimeFormat('en', {day: '2-digit'}).format(d);
return `${da}-${mo}-${ye}`;
}
}
},
...
Now the axis will use labels such as this:
15-Mar-2021
I took this formatter code from this question, where there are other approaches also.
Worth mentioning: When you place Thymeleaf expressions in JavaScript, you can suppress JavaScript syntax errors by placing the Thymeleaf expression inside comments - and by also providing a default value in its place:
categories: /*[[${strengthGraph.keySet()}]]*/ []
In this case the []
is the default value. When Thymeleaf renders the expression, it will remove the /*
and */
comment delimiters, and also remove the default expression.