Charts.js display two combined line charts for last 7 days - javascript

I have 2 set of datasets I want to display in single line chart for last 7 days, and if possible only show single Y axis with max value from all data sets. I try to use time as xAxes but it is not showing up.
here is my code https://jsfiddle.net/e6trkxL0/

You have to place the labels for datapoints.
let start = new Date(),
end = new Date();
start.setDate(start.getDate() - 7); // set to 'now' minus 7 days.
start.setHours(0, 0, 0, 0); // set to midnight.
let chart = new Chart(document.getElementById("lastSevenDaysOverview"), {
type: "line",
data: {
labels: [],
datasets: [{
label: 'Dataset 1',
data: [1, 4, 66, 7, 12, 3, 8],
borderColor: '#ff3366',
backgroundColor: '#ff3366',
},
{
label: 'Dataset 2',
data: [31, 14, 6, 71, 1, 35, 9],
borderColor: '#880000',
backgroundColor: '#880000',
}
]
},
options: {
interaction: {
mode: 'index',
intersect: true,
},
stacked: false,
responsive: true,
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
},
xAxes: [{
type: "time",
// this is not doing much
// time: {
// min: start,
// max: end,
// unit: "day"
//}
}]
}
}
});
chart.render();
for (let i = 0; i < 7; i++) {
var labelDate = start;
labelDate.setDate(start.getDate() + 1);
chart.data.labels.push(labelDate.toLocaleString())
}
chart.update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="lastSevenDaysOverview"></canvas>

2 things, for a time axis in chart.js you need according to the documentation a time adapter. Also you defined you x axis scales as a array which is incorrect. You need to define all scales as an object where the key of the object is the scale ID, you can read more about it in the migration guide
For points to be mapped in the chart you also need to provide a x place which in this case needs to be the date for which the datapoint is valid.
To just show a single axis with the highest values you can let both datasets be mapped to the same y axis:
let start = new Date(),
end = new Date();
start.setDate(start.getDate() - 7); // set to 'now' minus 7 days.
start.setHours(0, 0, 0, 0); // set to midnight.
new Chart(document.getElementById("lastSevenDaysOverview"), {
type: "line",
data: {
datasets: [{
label: 'Dataset 1',
data: [{
x: new Date('10-16-2021'),
y: 1
}, {
x: new Date('10-18-2021'),
y: 4
}, {
x: new Date('10-19-2021'),
y: 66
}],
borderColor: '#ff3366',
backgroundColor: '#ff3366',
},
{
label: 'Dataset 2',
data: [{
x: new Date('10-14-2021'),
y: 31
}, {
x: new Date('10-18-2021'),
y: 14
}, {
x: new Date('10-19-2021'),
y: 6
}],
borderColor: '#880000',
backgroundColor: '#880000'
}
]
},
options: {
interaction: {
mode: 'index',
intersect: true,
},
responsive: true,
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
},
x: {
type: "time",
min: start,
max: end,
time: {
unit: "day"
}
}
},
}
});
<canvas id="lastSevenDaysOverview"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>

Related

How to render custom yAxis label on Highcharts Gantt with the 'custom' property?

I've got a Gantt chart:
And I want to use the series.gantt.custom object to set specific properties for each series on the yAxis.
From these properties I want to construct the yAxis labels.
My code:
Highcharts.ganttChart('container', {
yAxis: {
categories: ['1', '2'],
labels: {
formatter() {
return this.value
/* + this.chart.series[this.pos].custom.size */
},
}
},
series: [{
groupPadding: 1,
custom: {
size: "small",
},
type: 'line',
zoneAxis: 'x',
data: [{
y: 0,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1,
}
}, {
y: 0,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}, {
type: 'line',
zoneAxis: 'x',
custom: {
size: "large",
},
data: [{
y: 1,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1
}
}, {
y: 1,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}]
});
this.chart.series[this.pos].custom.size it's the bit that is not working.
The labels should be 1 small and 2 large.
A fiddle
You can reach this property through the series.options:
this.chart.series[this.pos].options.custom.size
Demo:
https://jsfiddle.net/BlackLabel/gLkn9uqf/

How to adjust spaces between points in chart js?

I am trying to make a line chart by using chart.js. But I facing a problem. I want to control the space between points, but the chart.js makes it equal.
Here is my code:
<canvas id="myChart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js" integrity="sha512-OD9Gn6cAUQezuljS6411uRFr84pkrCtw23Hl5TYzmGyD0YcunJIPSBDzrV8EeCiFxGWWvtJOfVo5pOgB++Jsag==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var ctx = document.getElementById("myChart");
var points = [1,1,9,9.3];
var Dates = ["Dec 29th", "jan 10th", "Feb 21st", "Feb 25th"];
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: Dates,
datasets: [
{
label: "My chart",
data: points,
backgroundColor: "black",
borderColor: "blue",
borderWidth: 3,
fill: false,
lineTension: 0.4,
}
]
},
options: {
legend: {display: false},
scales: {
yAxes:[{
ticks: {
min:1,
max: 9.9,
callback: function(value, index, values) {
return '$' + value;
}
}
}],
},
elements: {
point:{
radius: 0
}
}
}
});
</script>
Here is the result of my code:
But I want the big space in middle like this:
How can I make the big space between point 3 and point4, please?
Can you use time on the x axis?
Below is an example
// "+" before (new Date(2021,11,29)) return miliseconds from 1970 year
const dataA = [
{x:+new Date(2021,11,29), y:1}, // { x: 1640732400000, y: 1},
{x:+new Date(2022,0,10), y:1}, // { x: 1641769200000, y: 1},
{x:+new Date(2022,1,21), y:9}, // { x: 1645398000000, y: 9},
{x:+new Date(2022,1,25), y:9.3}, // { x: 1645743600000, y: 9.3}
];
const cfgChart = {
type: 'line',
data: {
datasets: [
{
backgroundColor: '#74adf7',
borderColor: '#74adf7',
data: dataA,
label: 'A',
lineTension: 0.4,
},
],
},
options: {
animation: false,
parsing: false,
interaction: {
mode: 'index',
axis: 'x',
intersect: false,
},
scales: {
x: {
type: 'time',
},
},
},
};
const chart = new Chart(document.querySelector('#chart').getContext('2d'), cfgChart);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.1/luxon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-luxon/1.1.0/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="chart"></canvas>
</div>

How to show area chart with timeseries configuration with different datasets in Chart.js v3?

I've been trying to implement area chart which has different datasets and we are following the configuration of timeseries chart by providing the options a min & max value to generate labels automatically. Here is my code :
var feronisData = [398, 445];
var formattedDates = ["Feb 01", "Mar 20"];
var colors = ['#5ba2df', '#e2ac00', '#59b110'];
var data = {
/* labels: formattedDates, */
datasets: [{
type: 'line',
fill: 1,
spanGaps: true,
pointStyle: 'circle',
label: 'Feronis',
data: [{x: moment('2021-02-10 00:00:00.000').format('MMM DD'), y: 250}, {x: moment('2021-02-28 00:00:00.000').format('MMM DD'), y: 350}],
borderColor: '#5ba2df',
labels: [],
borderWidth: 3,
backgroundColor: 'rgba(0, 0, 0,0)',
}, {
type: 'line',
fill: true,
borderColor: '#2187f3',
backgroundColor: '#219634',
borderWidth: 1,
spanGaps: false,
pointStyle: 'circle',
label: 'Others',
data: [{x: moment('2021-01-24 00:00:00.000').format('MMM DD'), y: 150},{x: moment('2021-02-04 00:00:00.000').format('MMM DD'), y: 300}, {x: moment('2021-03-24 00:00:00.000').format('MMM DD'), y: 450}],
borderColor: '#e2ac00',
labels:[],
borderWidth: 3,
backgroundColor: 'rgba(0, 0, 0,0)',
}]
};
var options = {
showLines: true,
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 80
}
},
elements: {
point: {
radius: 1,
hoverRadius: 5,
}
},
hover: {
mode: 'index',
intersect: false
},
responsive: true,
tooltips: {
enabled: true,
mode: 'index',
intersect: false,
yAlign: 'right',
},
scales: {
x : {
type: 'time',
min: 'Jan 01',
max: 'Jul 01',
time: {
unit: 'day',
displayFormats: {
day: 'MMM DD'
}
}
/* xAxes: [{
type: 'time',
time: {
unit: 'day',
unitStepSize: 10,
format: 'MMM DD',
displayFormats: {
'day': 'dddd',
'week': 'MMM DD',
'month': 'MMM DD'
},
min: 'JAN 01',
max: 'JUL 01'
},
display: true,
interval: 5,
intervalType: "month",
gridLines: {
drawOnChartArea: false,
}
}], */
},
y: {
stacked: true,
}
}}
this.chart = new Chart('canvas', {
responsive: true,
data: data,
options: options
});
The same is available on fiddle here : https://jsfiddle.net/erdfs37h/
Configuaration is Backend is not going to provide me any set of labels as labels array shown in each dataset. Instead we are depending directly on the data array which provides values in this format [{x: 'xItem', y: 'someValueToPlot'}]
Note : actually I'm going to render this with React.js where my common component generates chart based on these configuration, but it is almost similar to what I've shown on fiddle link.
Since we are also using the timeseries configuration, can you point out any specific thing that I'm missing here?
Currently, I think the solution can be achieved by adding these key-fields for each dataset
type: 'line',
fill: {
target: 'origin',
above: 'rgb(123, 43, 54)', // Area will be reddish above the origin
below: 'rgb(65, 47, 231)' // And blue below the origin
},
Your issue is that you provided duplicate keys for the backgroundColor and in your duplicate you set it to a fully transparent color so thats why its not showing also the labels array in your dataset config is redundent since you are using object notation
Example:
var feronisData = [398, 445];
var formattedDates = ["Feb 01", "Mar 20"];
var colors = ['#5ba2df', '#e2ac00', '#59b110'];
var data = {
/* labels: formattedDates, */
datasets: [{
type: 'line',
fill: 1,
spanGaps: true,
pointStyle: 'circle',
label: 'Feronis',
data: [{
x: moment('2021-02-10 00:00:00.000').format('MMM DD'),
y: 250
}, {
x: moment('2021-02-28 00:00:00.000').format('MMM DD'),
y: 350
}],
borderColor: '#5ba2df',
borderWidth: 3,
}, {
type: 'line',
fill: true,
borderColor: '#2187f3',
backgroundColor: '#219634',
borderWidth: 1,
spanGaps: false,
pointStyle: 'circle',
label: 'Others',
data: [{
x: moment('2021-01-24 00:00:00.000').format('MMM DD'),
y: 150
}, {
x: moment('2021-02-04 00:00:00.000').format('MMM DD'),
y: 300
}, {
x: moment('2021-03-24 00:00:00.000').format('MMM DD'),
y: 450
}],
}]
};
var options = {
showLines: true,
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 80
}
},
elements: {
point: {
radius: 1,
hoverRadius: 5,
}
},
hover: {
mode: 'index',
intersect: false
},
responsive: true,
plugins: {
tooltip: {
enabled: true,
mode: 'index',
intersect: false,
yAlign: 'right',
},
},
scales: {
x: {
type: 'time',
min: 'Jan 01',
max: 'Jul 01',
time: {
unit: 'day',
displayFormats: {
day: 'MMM DD'
}
}
},
y: {
stacked: true,
}
}
}
this.chart = new Chart('canvas', {
responsive: true,
data: data,
options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#2.27.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-moment/1.0.0/chartjs-adapter-moment.min.js"></script>
<canvas style="height: 400px;" id='canvas' />
You might also want to check the migration guide out since as I can see fast your tooltip is also wrongly configured:https://www.chartjs.org/docs/master/getting-started/v3-migration.html

chart.js display even intervals between two dates and adding label to y axes

I am converting Jqplot chart to ChartJs and I want them both to look the same.
I have the following chart using the chart.js library.
var myChart = new Chart(ctxr, {
type: 'line',
data: {
datasets: [{
label: "Estimated cost",
data: [{
x: new Date("09/24/2020 10:26:20"),
//x: new Date(),
y: 8
}, {
x: new Date("09/24/2020 10:27:56"),
//x: new Date(),
y: 8
}],
borderColor: [
'rgba(196, 217, 45, 1)',
]
},
{
label: "Actual cost",
data: [{
x: new Date("09/24/2020 10:27:56"),
//x: new Date(),
y: 23
}, {
x: new Date("09/24/2020 10:26:20"),
//x: new Date(),
y: 24
}],
borderColor: [
'rgba(75, 178, 197, 1)',
]
}],
labels: [new Date("09/24/2020 10:26:20").toLocaleString(), new Date("09/24/2020 10:27:56").toLocaleString()]
},
options: {
responsive: true,
responsiveAnimationDuration: 1,
maintainAspectRatio: false,
aspectRatio: 1,
title: {
display: true,
text: 'Auction Overview'
},
tooltips: {
mode: 'index',
intersect: true
},
scales: {
yAxes: [{
ticks: {
// Include a GBP in the ticks
callback: function (value, index, values) {
return 'GBP' + value;
}
}
}],
xAxes: [{
type: 'time',
}]
}
}
});
that gives me this chart
I would like to make it have intervals of time between the start date and the end date(like the x axis on the Jqplot chart) and also add string "GBP" in front of each y-value (like y-axis of Jqplot chart).
Both graphs are generated with the same identical data. so they should look the same.
So far everything i have tried from the chart.js docs has failed.
Below is a snipped of my js console:
There is something else wrong with your implementation that you have not told us about, because copy and pasting your code results in a working chart with GBP labels and time span. See below.
Please check your console for errors and also make sure that you are including moment.js, a dependency of Chart.js when work with dates.
I've also set options.yAxes[0].ticks.beginAtZero to true to more closely match the example you gave.
var ctxr = document.getElementById('chart').getContext('2d');
var myChart = new Chart(ctxr, {
type: 'line',
data: {
datasets: [{
label: "Estimated cost",
data: [{
x: new Date("09/24/2020 10:26:20"),
//x: new Date(),
y: 8
}, {
x: new Date("09/24/2020 10:27:56"),
//x: new Date(),
y: 8
}],
borderColor: [
'rgba(196, 217, 45, 1)',
]
},
{
label: "Actual cost",
data: [{
x: new Date("09/24/2020 10:27:56"),
//x: new Date(),
y: 23
}, {
x: new Date("09/24/2020 10:26:20"),
//x: new Date(),
y: 24
}],
borderColor: [
'rgba(75, 178, 197, 1)',
]
}
],
labels: [new Date("09/24/2020 10:26:20").toLocaleString(), new Date("09/24/2020 10:27:56").toLocaleString()]
},
options: {
responsive: true,
responsiveAnimationDuration: 1,
maintainAspectRatio: false,
aspectRatio: 1,
title: {
display: true,
text: 'Auction Overview'
},
tooltips: {
mode: 'index',
intersect: true
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
// Include a GBP in the ticks
callback: function(value, index, values) {
return 'GBP' + value;
}
}
}],
xAxes: [{
type: 'time',
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3"></script>
<canvas id="chart"></canvas>

Bar chart with time series data is not rendering properly using Chart.js

I am trying to render bar chart with time series data but it is not rendering properly, I am getting spaces in between stack bars, I have commented out the sample data which I am receiving from web server via AJAX call.
Here is my code:
let config = {
type: 'bar',
labels: res['labels'],
data: {
datasets: [{
label: "Success",
data: _.map(res['success'], (obj) => { return { x: new Date(obj.x), y: obj.y}; }),
// data: [{
// x: new Date('2017-03-01'),
// y: 1
// }, {
// x: new Date('2017-03-02'),
// y: 2
// }, {
// x: new Date('2017-03-03'),
// y: 3
// }, {
// x: new Date('2017-03-04'),
// y: 4
// }],
backgroundColor: "green"
}, {
label: "Failure",
data: _.map(res['failed'], (obj) => { return { x: new Date(obj.x), y: obj.y}; }),
// data: [{
// x: new Date('2017-03-01'),
// y: 1
// }, {
// x: new Date('2017-03-02'),
// y: 2
// }, {
// x: new Date('2017-03-03'),
// y: 3
// }, {
// x: new Date('2017-03-04'),
// y: 4
// }],
backgroundColor: "red"
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false,
},
tooltips: {
callbacks: {
title: function(tooltipItem, data) {
const [month, year] = tooltipItem[0].label.split(',', 2);
return `${month}, ${year}`;
}
}
},
scales: {
xAxes: [{
type: "time",
stacked: true,
offset: true,
categoryPercentage: 1.0,
barPercentage: 1.0,
barThickness: 20,
maxBarThickness: 25,
minBarLength: 50,
gridLines: {
offsetGridLines: true
},
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D'
}
}
}],
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}]
}
}
}
let chartEl = $('.bart-activity-graph-canvas');
return new Chart(chartEl, config);
----------------- UPDATE --------------------
Solution: The issue is because I used _.map() function which does not guarantee the position in the array.

Categories

Resources