Chart.js sum y values depending on time unit - javascript

New to Chart.js, I was wondering if there is a built in method to sum y values depending on time unit.
Asking here after a lot of search in the docs.
For now, the bar for March shows 20 and the bar for June shows 10.
I want to have 25 for March and 15 for June, so to sum y for the same month.
const ctx = document.getElementById("tests-chart")
const testsChart = new Chart(ctx, {
type: "bar",
data: {
datasets: [
{
label: 'Dataset 1',
data: [
{ x: "24/03/2022", y: 20 },
{ x: "25/03/2022", y: 5 },
{ x: "24/06/2022", y: 10 },
{ x: "25/06/2022", y: 5 },
],
backgroundColor: 'rgb(255, 99, 132)',
},
],
},
options: {
scales: {
x: {
type: "time",
time: {
parser: "dd/MM/yyyy",
unit: "month",
// Luxon format string
tooltipFormat: "MM",
round: 'month'
},
},
},
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.1/build/global/luxon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#1.1.0/dist/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="tests-chart"></canvas>
</div>

You can manipulate your dataset as mentioned below and achieve your expected output.
const ctx = document.getElementById("tests-chart");
const data =[
{ x: "24/03/2022", y: 20 },
{ x: "25/03/2022", y: 5 },
{ x: "24/06/2022", y: 10 },
{ x: "25/06/2022", y: 5 }
];
let updatedData =[];
let tempDateCollection =[];
data.map((yData , index)=> {
const formatedDate = moment(yData.x, "DD/MM/YYYY").format('MMM/YYYY');
if(tempDateCollection.includes(formatedDate)){
const index = tempDateCollection.indexOf(formatedDate);
const element = updatedData[index];
updatedData[index] = {...element, y: element.y + yData.y}
} else{
tempDateCollection.push(formatedDate);
updatedData.push(yData);
}
})
const testsChart = new Chart(ctx, {
type: "bar",
data: {
datasets: [
{
label: 'Dataset 1',
data:updatedData,
backgroundColor: 'rgb(255, 99, 132)',
},
],
},
options: {
scales: {
x: {
type: "time",
time: {
parser: "dd/MM/yyyy",
unit: "month",
// Luxon format string
tooltipFormat: "MM",
round: 'month'
},
},
},
},
})
<script type = "text/JavaScript" src = " https://MomentJS.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.1/build/global/luxon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#1.1.0/dist/chartjs-adapter-luxon.min.js"></script>
<div>
<canvas id="tests-chart"></canvas>
</div>

Related

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>

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

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>

Chart.js time scale graph - xAxis labelling

I'm trying to set my own labels on the xAxis however I'm not sure how to do it using the example code I found.
I want it to look like this essentially: https://www.chartjs.org/samples/latest/scales/time/line.html
var result = [{ x: "00:01:53", y: "22" }, { x: "00:02:13", y: "45" }, { x: "00:02:43", y: "46" }, { x: "00:02:51", y: "51" }];
var result2 = [{ x: "00:01:52", y: "20" }, { x: "00:02:11", y: "42" }, { x: "00:02:41", y: "43" }, { x: "00:02:38", y: "50" }];
var labels = result.map(e => moment(e.x, 'h:mm:ss'));
var data = result.map(e => +e.y);
var data2 = result2.map(e => +e.y);
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [
{
label: 'g-force',
data: data,
borderColor: "#3e95cd",
borderWidth: 1
},
{
label: 'g-force',
data: data2,
borderColor: "#8e5ea2",
borderWidth: 1
}
],
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'second',
displayFormats: {
second: 'h:mm:ss'
}
}
}]
},
}
});
This seems to work. This code starts from today and adds in the next 10 days. You'll have to change date to whenever you want your start date to be as well as how many dates you need.
let labels = [];
var date = new Date();
var options = {
month: "long",
day: "numeric"
};
for (i = 0; i < 10; i++) {
date.setDate(date.getDate() + i);
labels.push(date.toLocaleDateString("en-US", options));
}
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
...

ChartJS Scatter Graph X Axis Label Not showing up properly

I am fairly new to javascript world, so bear with me if there is an obvious solution to this, but I'm struggling to graph the dates (X-points) on the X axis of the chartjs graph. I get some weird times there that you can check on jsfiddle. What am I doing wrong?
var ctx = document.getElementById("myChart");
var data = {
datasets: [{
label: " Property",
lineTension: 0.1,
data: [{
x: 2017 - 04 - 11,
y: 2000000.00
},
{
x: 2017 - 04 - 12,
y: 1000000.00
},
{
x: 2017 - 04 - 13,
y: 3000000.00
},
]
},
{
label: " Property",
lineTension: 0.1,
data: [{
x: 2017 - 04 - 12,
y: 472943.00
},
{
x: 2017 - 04 - 13,
y: 1000000.00
},
]
},
]
};
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
xAxes: [{
id: 'ScartCharxAxes',
type: 'time',
unit: 'day',
time: {
displayFormats: {
day: 'D MMM YYYY'
},
}
}]
}
}
});
My code is available on http://jsfiddle.net/py1bpf02/3/
In your datasets, dates should be strings. What you did is math, not dates. 2017-04-11 = 2002.
var ctx = document.getElementById("myChart");
var data = {
datasets: [
{
label: " Property",
lineTension: 0.1,
data: [{
x: "2017-04-11",
y: 2000000.00
},
{
x: "2017-04-12",
y: 1000000.00
},
{
x: "2017-04-13",
y: 3000000.00
},
]
},
{
label: " Property",
lineTension: 0.1,
data: [{
x: "2017-04-12",
y: 472943.00
},
{
x: "2017-04-13",
y: 1000000.00
},
]
},
]
};
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
xAxes: [{
id: 'ScartCharxAxes',
type: 'time',
time: {
unit: 'day',
displayFormats: {
day: 'D MMM'
},
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.min.js"></script>
<canvas id="myChart"></canvas>

2 canvasjs chart in one pageproblem,

i tried to put 2 Canvasjs chart in one html page. i have included jquery, and it works when i put only one chart div, once i add second chart, it show error, only show up one chart.
I want to show 2 or more chart in a page, is it possible?
here's my code. thank you
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="canvas/js/jquery.canvasjs.min.js"></script>
<!FIRST JAVASCRIPT>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
data: [
{
type: "column",
dataPoints: [
{ x: 10, y: 10 },
{ x: 20, y: 15 },
{ x: 30, y: 25 },
{ x: 40, y: 30 },
{ x: 50, y: 28 }
]
}
]
});
chart.render();
}
</script>
<!SECOND JAVASCRIPT>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer2");
chart.options.axisY = { prefix: "$", suffix: "K" };
chart.options.title = { text: "Fruits sold in First & Second Quarter" };
var series1 = { //dataSeries - first quarter
type: "column",
name: "First Quarter",
showInLegend: true
};
var series2 = { //dataSeries - second quarter
type: "column",
name: "Second Quarter",
showInLegend: true
};
chart.options.data = [];
chart.options.data.push(series1);
chart.options.data.push(series2);
series1.dataPoints = [
{ label: "banana", y: 18 },
{ label: "orange", y: 29 },
{ label: "apple", y: 40 },
{ label: "mango", y: 34 },
{ label: "grape", y: 24 }
];
series2.dataPoints = [
{ label: "banana", y: 23 },
{ label: "orange", y: 33 },
{ label: "apple", y: 48 },
{ label: "mango", y: 37 },
{ label: "grape", y: 20 }
];
chart.render();
}
</script>
</head>
<body>
<!FIRST CHART SHOW>
<div id="chartContainer1" style="height: 500px; width: 50%;"></div>
<!SECOND CHART SHOW>
<div id="chartContainer2" style="height: 500px; width: 50%;"></div>
</body>
</html>
Firstly, you don't need two window.onload functions. The second onload function will override the first one. So just have one and include both the charts code in the one of them.
Also, the first chart being created requires an element with id as chartContainer which is not present in the DOM. Replace that with chartContainer1.
Replace
var chart = new CanvasJS.Chart("chartContainer", {...});
with
var chart = new CanvasJS.Chart("chartContainer1", {...});
Instead of using one variable chart for both the charts use two variables so that the variable is not overridden. Something like this
window.onload = function(){
var chart1 = new CanvasJS.Chart("chartContainer1", {
data: [{
type: "column",
dataPoints: [{
x: 10,
y: 10
}, {
x: 20,
y: 15
}, {
x: 30,
y: 25
}, {
x: 40,
y: 30
}, {
x: 50,
y: 28
}]
}]
});
chart1.render();
var chart2 = new CanvasJS.Chart("chartContainer2");
chart2.options.axisY = {
prefix: "$",
suffix: "K"
};
chart2.options.title = {
text: "Fruits sold in First & Second Quarter"
};
var series1 = { //dataSeries - first quarter
type: "column",
name: "First Quarter",
showInLegend: true
};
var series2 = { //dataSeries - second quarter
type: "column",
name: "Second Quarter",
showInLegend: true
};
chart2.options.data = [];
chart2.options.data.push(series1);
chart2.options.data.push(series2);
series1.dataPoints = [{
label: "banana",
y: 18
}, {
label: "orange",
y: 29
}, {
label: "apple",
y: 40
}, {
label: "mango",
y: 34
}, {
label: "grape",
y: 24
}];
series2.dataPoints = [{
label: "banana",
y: 23
}, {
label: "orange",
y: 33
}, {
label: "apple",
y: 48
}, {
label: "mango",
y: 37
}, {
label: "grape",
y: 20
}];
chart2.render();
};
Here is a demo http://jsbin.com/rocusuhevo/edit?html,js,output

Categories

Resources