Reputation: 24778
I use https://www.chartjs.org/. In the example below I list values for every day for two weeks. For that I want a line of the average values for this period.
Is it possible with chartjs and if so how?
I've started but it follows the bar locations and it should create a new path with fewer points.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<script>
var ctx = document.getElementById('canvas').getContext('2d');
var mixedChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: 'Bar Dataset',
data: [1, 2, 3, 1, 3, 4, 7, 2, 4, 3, 1, 6, 5, 2],
backgroundColor: "#FF9881",
order: 2
}, {
label: 'Line Dataset',
data: [1, 2],
type: 'line',
borderColor: "#FF312D",
fill: false,
borderWidth: 1,
order: 1
}],
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
},
options: {
"scales": {
"yAxes": [{
"ticks": {
"beginAtZero": true
}
}]
}
}
});
</script>
</body>
</html>
Upvotes: 2
Views: 6884
Reputation: 43
If your requirements are to draw just a flat, average line, I would go for their official annotation plugin [chartjs-plugin-annotation].
I will insert a really basic, self-consistent example here, adapted from their documentation.
index.html:
<html>
<head>
<script src="index.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
anyname.js [which you then need to browserify into the index.js source file]:
/* the following is just a shortcut to register all the needed elements, for any chart.
more info here:
https://www.chartjs.org/docs/3.3.0/getting-started/integration.html#bundlers-webpack-rollup-etc */
const Chart = require("chart.js/auto");
const annotationPlugin = require("chartjs-plugin-annotation");
function average(ctx) {
const values = ctx.chart.data.datasets[0].data;
return values.reduce((a, b) => a + b, 0) / values.length;
}
const data = {
labels: ["1", "2", "3", "4", "5", "6", "7"],
datasets: [
{
label: "Sample Series",
data: [40, 100, 54, 34, 13, 78, 41]
}
]
};
const annotation = {
type: 'line',
borderColor: 'black',
borderDash: [6, 6],
borderDashOffset: 0,
borderWidth: 3,
label: {
enabled: true,
content: (ctx) => "Average: " + average(ctx).toFixed(2),
position: 'end'
},
scaleID: 'y',
value: (ctx) => average(ctx)
};
const config = {
type: 'bar',
data,
options: {
plugins: {
title: {
display: true,
text: "Sample Chart",
font: {
size: 14
}
},
annotation: {
annotations: {
annotation
}
}
}
}
};
// the annotation plugin needs to be registered, too
Chart.register(annotationPlugin);
document.addEventListener('DOMContentLoaded', () => {
const myChart = new Chart(document.getElementById('canvas'), config);
}, false);
Node required libraries [which you need to install for browserify to work]:
References:
https://www.chartjs.org/chartjs-plugin-annotation/1.2.0/samples/line/average.html
Upvotes: 2
Reputation: 1224
I would calculate the average and spread it over the whole graph like this:
const getLineData = (initialData, lengthOfDataChunks) => {
const numOfChunks = Math.ceil(initialData.length / lengthOfDataChunks);
const dataChunks = [];
for (var i = 0; i < numOfChunks; i++) dataChunks[i] = [];
initialData.forEach((entry, index) => {
const chunkNumber = Math.floor(index / lengthOfDataChunks);
dataChunks[chunkNumber]
dataChunks[chunkNumber].push(entry);
});
const averagedChunks = dataChunks.map(chunkEntry => {
const chunkAverage = chunkEntry.reduce(sumArray) / lengthOfDataChunks;
return chunkEntry.map(chunkEntryValue => chunkAverage);
});
return averagedChunks.flat();
}
const ctx = document.getElementById('canvas').getContext('2d');
const barData = [1, 2, 3, 1, 3, 4, 7, 2, 4, 3, 1, 6, 5, 2];
const sumArray = (accumulator, currentValue) => accumulator + currentValue;
const averageBarValue = barData.reduce(sumArray) / barData.length;
const lineData = getLineData(barData, 7);
var mixedChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: 'Bar Dataset',
data: barData,
backgroundColor: "#FF9881",
order: 2
}, {
label: 'Line Dataset',
data: lineData,
type: 'line',
borderColor: "#FF312D",
fill: false,
borderWidth: 1,
order: 1
}],
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
},
options: {
"scales": {
"yAxes": [{
"ticks": {
"beginAtZero": true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="canvas"></canvas>
I hope I got your question right. If not, please let me know!
Upvotes: 2