Chart.js timeline [Group for single bar] - javascript

I would like to create a time line like this:
[1]: https://i.stack.imgur.com/RQ819.png
But I don't understand how to put green into the top bar and yellow into the bottom bar.
This is what I got so far but I don't find anything how to make group only for one bar.
// Set Up
const labels = ["ONLINE", "IDLE"];
const data = {
labels: labels,
datasets: [
{
label: "ONLINE",
data: [
["2022-01-01", "2022-01-02"],
["2022-01-03", "2022-01-04"],
],
backgroundColor: ["green"],
},
{
label: "IDLE",
data: [
["2022-01-02", "2022-01-03"],
["2022-01-04", "2022-01-05"],
],
backgroundColor: ["orange"],
},
],
};
// Config
const config = {
type: "bar",
data: data,
options: {
responsive: true,
indexAxis: "y",
scales: {
xAxis: {
min: "2022-01-01",
type: "time",
time: {
unit: "day",
},
ticks: {
display: false,
},
},
yAxes: {
stacked: true,
beginAtZero: true,
},
},
},
};
// Render Chart
const myChart = new Chart(document.getElementById("myChart"), config);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<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>
<div>
<canvas id="myChart"></canvas>
</div>

You need to define a separate datasets for each floating bar.
Please take a look at your amended code and see how it works.
const data = {
labels: ["ONLINE", "IDLE"],
datasets: [{
label: "Jan 1 - Jan 2",
data: [["2022-01-01", "2022-01-02"],],
backgroundColor: "green"
},
{
label: "Jan 2 - Jan 3",
data: [,["2022-01-02", "2022-01-03"]],
backgroundColor: "orange"
},
{
label: "Jan 3 - Jan 4",
data: [["2022-01-03", "2022-01-04"],],
backgroundColor: "green"
},
{
label: "Jan 4 - Jan 5",
data: [,["2022-01-04", "2022-01-05"]],
backgroundColor: "orange"
}
]
};
const config = {
type: "bar",
data: data,
options: {
responsive: true,
indexAxis: "y",
scales: {
x: {
min: "2022-01-01",
type: "time",
time: {
unit: "day"
}
},
y: {
stacked: true
}
}
}
};
const myChart = new Chart("myChart", config);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<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>
<div>
<canvas id="myChart"></canvas>
</div>

Related

Handle Date Gaps in Chart JS

I am plotting a graph using chart js. I have a couple of inconsistent data. For instance, the example data I have shared starts with 1909 and the next is 1960. In other cases, they are properly displayed: 1980, 1981, 1982...
Is there a way for me to handle specific data with gaps? For instance, have the year displayed sequentially.
const ctx = canvas.getContext("2d");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
label: "Country Population",
data: data,
}, ],
},
options: {
scales: {
x: {
title: {
display: true,
text: "Year",
},
xAxes: [{
type: 'time',
time: {
unit: 'year'
}
}]
},
y: {
title: {
display: true,
text: "Population",
},
},
},
},
});
How library you are using time and chart? I use chart(v3.8) and luxon(time) seems to work
const exampleData = [{
"x": +new Date('1909'),
"y": 48900202
},
{
"x": +new Date('1960'),
"y": 889030
},
{
"x": +new Date('1961'),
"y": 890203
},
{
"x": +new Date('1983'),
"y": 8904
},
]
const chartCfg = {
type: 'line',
data: {
datasets: [{
borderColor: 'green',
backgroundColor: 'green',
borderWidth: 1,
pointStyle: 'cross',
data: exampleData,
label: 'example',
}, ],
},
options: {
maintainAspectRatio: false,
animation: false,
parsing: false,
interaction: {
mode: 'index',
},
scales: {
x: {
type: 'time',
time: {
displayFormats: {
year: 'yyyy',
},
},
},
},
},
};
const chartCtx = document.getElementById('chart').getContext('2d');
const chart = new Chart(chartCtx, chartCfg);
chart.canvas.parentNode.style.height = '300px';
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.4.0/luxon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-luxon/1.1.0/chartjs-adapter-luxon.min.js"></script>
<canvas id="chart""></canvas>

Accessing data from the callback function of a bar chart using chart js

I am currently trying to show a text stocked in the data in the tooltip, I can#t figure how to make it work, I have tried many things.
You can find below an example of what I#m trying to do, I want that the "text" value is displayed when hovering one of the bar.
I tried this
let data = [{
label: 'Available',
backgroundColor: '#3366ff',
data: [500],
text : "test1"
}, {
label: 'Budget',
backgroundColor: '#009999',
data: [5000, 6500],
text : "test2"
}, {
label: 'Actual',
backgroundColor: '#92d400',
data: [5200, 7245],
text : "test3"
}];
new Chart(document.getElementById("bar-chart-horizontal"), {
type: 'horizontalBar',
data: {
labels: ["Rooms", "Guests"],
datasets: data,
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var item = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return item.text;
}
}
}
}
});
But this is not working, it is not even displaying anything logical, only "Room" and "Guests".
What should I do to retrieve the correct informations ? I tried doing it like this : Fiddle
But it doesn't work when applied to my code... I'm probably missing something pretty stupid but I can't figure what.
Thanks to all the people that will read this and try to help me.
You just need to update the version of chart.js you are using to the latest V2 version since V3 has breaking changes.
Also you need to specify the x for the number for a horizontalBar instead of a y in both the dataset and the tooltip callback:
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['2017/06/12', '2017/06/23', '2017/07/12', '2017/07/23', '2017/08/12', '2017/08/23', '2017/09/12'],
datasets: [{
label: 'Values',
data: [{
x: 12,
value: 12,
text: "test1"
},
{
x: 3,
value: 13,
text: "test2"
},
{
x: 1,
value: 15,
text: "test3"
},
{
x: -3,
value: 5,
text: "test4"
},
{
x: 67,
value: 18,
text: "test5"
},
{
x: 12,
value: 11,
text: "test6"
},
{
x: 13,
value: 19,
text: "test7"
}
],
fill: false,
borderWidth: 2
}]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var item = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return item.x + ' ' + item.value + item.text;
}
}
},
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
This should work:
...
options: {
tooltips: {
callbacks: {
label: (context, data) => data.datasets[context.datasetIndex].data[context.index].text
}
}
...
jsfiddle

getting chartsjs to show key of data label instead of value

I am having trouble with my chartsjs labels.
my graph generates fine, I am trying to set the chart so that the data labels are for the text part of the data and not the numbers part. my code shows the data labels as 4, 6 and 2 where as i need them to show the text: me, you and them.
<script>
var ctx = document.getElementById('myChart4').getContext('2d');
var myChart4 = new Chart(ctx, {
plugins: [ChartDataLabels],
type: 'doughnut',
data: {
labels: ['me','you','them'
],
datasets: [{
label: false,
data: [4,6,2
],
}]
},
options: {
responsive: false,
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
align: 'end',
offset: 15
},
legend: {
display: false
},
title: {
display: true,
text:'Reason'
}
},
responsive: false,
onClick: (evt, activeEls) => {
show();
},
}
});
You can use the formatter function for this:
Chart.register(ChartDataLabels)
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'orange'
}]
},
options: {
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
align: 'end',
offset: 15,
formatter: (val, ctx) => (ctx.chart.data.labels[ctx.dataIndex])
},
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.js"></script>
</body>

chartjs display data in one bar line with 3 different data sets in 3 different colors

I currently display my data like this:
Click here
but I would like to display the data like this:
Click here
The idea is that at the bottom it would show the summary of all three colors numbers combined, but once you hover it would show how much each color has.
If all is one bar, if red is 7, blue is 3, the red but be a lot more in the bar.
This is the code for version 1, done with chart js
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: ["Chocolate", "Vanilla", "Strawberry"],
datasets: [
{
label: "Blue",
backgroundColor: "blue",
data: [3, 7, 4]
},
{
label: "Red",
backgroundColor: "red",
data: [4, 3, 5]
},
{
label: "Green",
backgroundColor: "green",
data: [7, 2, 6]
}
]
};
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
barValueSpacing: 20,
scales: {
yAxes: [{
ticks: {
min: 0,
}
}]
}
}
});
const myChart = new Chart(
document.getElementById('myChart'),
config
);
your problem is the next, you are using a wrong config you must something like this:
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.0/dist/chart.min.js"></script>
<canvas id="MyChart" width="400" height="200"></canvas>
<script>
new Chart(document.getElementById("MyChart"), {
type: 'bar',
data: {
labels: [2017],
datasets: [{
label: "Chocolate",
type: "bar",
stack: "Base",
backgroundColor: "#eece01",
data: [30],
}, {
label: "Vanilla",
type: "bar",
stack: "Base",
backgroundColor: "#87d84d",
data: [-15],
}, {
label: "Strawberry",
type: "bar",
stack: "Base",
backgroundColor: "#f8981f",
data: [20],
}, {
label: "candy",
type: "bar",
stack: "Base",
backgroundColor: "#00b300",
backgroundColorHover: "#3e95cd",
data: [-10]
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>
Now you just need to fix the styles and sizes of the graphic
If someone finds this, the solution is this:
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};

How do I create a legend for a bar chart?

How do I create legends like the following:
So far I have the following:
I can't figure out how to specify labels for the legend. They don't provide examples either.
https://www.chartjs.org/docs/latest/configuration/legend.html
So far I have the following code:
var topClickSourcesChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Facebook","Google","NONE",],
datasets: [{
data: [10,5,3,],
backgroundColor: ['#4D90C3', '#866DB2', '#EA6F98', '#61BDF6', '#768BB7'],
}],
},
options: {
scales: {
xAxes: [{
display: false,
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
To show a legend you need to set the label property of a dataset, so the type of output you are expecting can be built by creating a chart from the code as shown below. Fiddle -> https://jsfiddle.net/6nkcx8sq/
var topClickSourcesChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Number of users"],
datasets: [{
label: 'Facebook',
data: [10],
backgroundColor: '#4D90C3',
},
{
label: 'Instagram',
data: [15],
backgroundColor: '#866DB2',
},
{
label: 'Twitter',
data: [7],
backgroundColor: '#EA6F98',
}],
},
options: {
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
I was able to get it with the following, but it was a pain in the ass for loops due to the backgroundColor having to be inside the dataset.
var topClickSourceChart = new Chart('dashboard-click-source-chart', {
type: 'bar',
data: {
labels: ["Facebook","Google","NONE",],
datasets: [
{label: "Facebook", data: [10]},{label: "Google", data: [5]},{label: "NONE", data: [3]},
]
},
options: {
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
legend: {
position: 'right',
labels: {
boxWidth: 10,
}
}
}
});
if (topClickSourceChart.data.datasets.length > 0) topClickSourceChart.data.datasets[0].backgroundColor = '#4D90C3';
if (topClickSourceChart.data.datasets.length > 1) topClickSourceChart.data.datasets[1].backgroundColor = '#866DB2';
if (topClickSourceChart.data.datasets.length > 2) topClickSourceChart.data.datasets[2].backgroundColor = '#EA6F98';
if (topClickSourceChart.data.datasets.length > 3) topClickSourceChart.data.datasets[3].backgroundColor = '#61BDF6';
if (topClickSourceChart.data.datasets.length > 4) topClickSourceChart.data.datasets[4].backgroundColor = '#768BB7';
Here is the JSP/JSTL loop:
data: {
labels: [<c:forEach items="${clickSources}" var="cs">"${cs.key}",</c:forEach>],
datasets: [
<c:forEach items="${clickSources}" var="cs">{label: "${cs.key}", data: [${cs.value}]},</c:forEach>
]
},
I still could not find a way to make the top of the bars rounded.

Categories