I'm using vanilla JS with Chart.js. I want to make this line graph into something parallelogram.
Currently looks like this | Want something like this |
---|---|
![]() |
![]() |
And my code is this:
var chart = function () {
var ctx = document.getElementById('kt_chartjs_1');
// Define colors
var primaryColor = KTUtil.getCssVariableValue('--kt-primary');
var dangerColor = KTUtil.getCssVariableValue('--kt-danger');
var successColor = KTUtil.getCssVariableValue('--kt-success');
// Define fonts
var fontFamily = KTUtil.getCssVariableValue('--bs-font-sans-serif');
// Chart labels
const labels = Array.from({ length: 34 }, (_, i) => `${i + 1}`);
// Chart data
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
],
backgroundColor: ['#fff'] // Bar color
},
{
label: 'Line Dataset',
data: [
11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27,
],
borderColor: ['#eee'], // Line color
backgroundColor: ['#eee'], // No fill
borderWidth: 2,
fill: false, // Do not fill under the line
type: 'line' // Specify this dataset as a line
}
]
};
// Chart config
const config = {
type: 'bar', // Base type is bar
data: data,
options: {
plugins: {
title: {
display: false,
}
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
},
defaults:{
global: {
defaultFont: fontFamily
}
}
};
// Init ChartJS
var myChart = new Chart(ctx, config);
}
Can you guys help me, I think I'm stuck. Thanks guys :)
You could just add a new dataset with the vertices of the parallelogram.
Since this dataset will not use labels sequentially, you have to define
its data
points as objects,
{x: ..., y: ...}
; if you know the indices of the line data points that will be the
vertices of the parallelogram (0, 16, 34, 17), it will be just:
const lineData = data.datasets[1].data;
const P1 = {x: labels[0], y: lineData[0]},
P2 = {x: labels[16], y: lineData[16]},
P3 = {x: labels[34], y: lineData[34]},
P4 = {x: labels[17], y: lineData[17]};
const parallelogram = {
type: 'line',
data: [P1, P2, P3, P4, {...P1}],
borderColor: 'red',
borderWidth: 4,
label: 'Parallelogram'
};
data.datasets.push(parallelogram);
Or you can identify dynamically the "break" point of the original data, where's a drop in value, as in the following snippet:
const labels = Array.from({ length: 34 }, (_, i) => `${i + 1}`);
// Chart data
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
],
backgroundColor: ['rgba(242, 242, 242, 0.5)'], // Bar color
},
{
label: 'Line Dataset',
data: [
11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27,
],
borderColor: ['#eee'], // Line color
backgroundColor: ['#eee'], // No fill
borderWidth: 2,
fill: false, // Do not fill under the line
type: 'line', // Specify this dataset as a line
}
]
};
const lineData = data.datasets[1].data;
let iBreak = 0, yPrevious = -1/0;
while(iBreak < lineData.length){
if(lineData[iBreak] < yPrevious){
break;
}
yPrevious = lineData[iBreak];
iBreak++;
}
const P1 = {x: labels[0], y: lineData[0]},
P2 = {x: labels[iBreak-1], y: lineData[iBreak-1]},
P3 = {x: labels[lineData.length - 1], y: lineData[lineData.length-1]},
P4 = {x: labels[iBreak], y: lineData[iBreak]};
const parallelogram = {
type: 'line',
data: [P1, P2, P3, P4, {...P1}],
borderColor: 'red',
borderWidth: 4,
label: 'Parallelogram'
};
data.datasets.push(parallelogram);
// Chart config
const config = {
type: 'bar', // Base type is bar
data: data,
options: {
plugins: {
title: {
display: false,
},
filler:{
drawTime: "beforeDraw"
}
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: { // not stacked
//stacked: true,
},
y: { // not stacked
//stacked: true
}
}
},
defaults:{
global: {
//defaultFont: fontFamily
}
}
};
// Init ChartJS
new Chart('chart', config);
<div style="min-width: 600px; height: 350px; background-color: black">
<canvas id="chart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>