Chart.js - horizontal alignment of multiple canvas-elements - javascript

I have multiple dynamically created canvas - elements using chart.js.
All elements have the same structure (but different chart data).
Chart.js is not rendering them with the same alignment, as shown in the attached image. Is there a way to set something like 'alignment - left' in chart.js?
Edit: Sourcecode:
Generated HTML:
<canvas id="chartQ1"></canvas>
<script>DrawChart("chartQ1",
[
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
],[
"2",
"1",
"2",
"0"
],[
"rgba(0,150,64,0.2)",
"rgba(255,0,0,0.2)",
"rgba(0,150,64,0.2)",
"rgba(255,0,0,0.2)"
],[
"rgba(0,150,64,0.8)",
"rgba(255,0,0,0.8)",
"rgba(0,150,64,0.8)",
"rgba(255,0,0,0.8)"
])
<canvas id="chartQ2"></canvas>
<script>DrawChart("chartQ2",
[
"{a,b,e,f}",
"{c,d}",
"{e,f}",
"{}"
],[
"2",
"1",
"0",
"0"
],[
"rgba(0,150,64,0.2)",
"rgba(255,0,0,0.2)",
"rgba(255,0,0,0.2)",
"rgba(255,0,0,0.2)"
],[
"rgba(0,150,64,0.8)",
"rgba(255,0,0,0.8)",
"rgba(255,0,0,0.8)",
"rgba(255,0,0,0.8)"
])
</script>
Function used to create graphs:
function DrawChart(canvasID, remoteFields, remoteData, remoteColors, remoteBorderColors) {
var ctx = document.getElementById(canvasID).getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: remoteFields,
datasets: [{
data: remoteData,
backgroundColor: remoteColors,
borderColor: remoteBorderColors,
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
ticks: {
callback: function(t) {
var maxLabelLength = 25;
if (t.length > maxLabelLength) return t.substr(0, maxLabelLength) + '...';
else return t;
}
}
}],
yAxes: [{
ticks: {
beginAtZero:true,
stepSize: 1
}
}]
},
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
tooltips: {
callbacks: {
title: function(t, d) {
return d.labels[t[0].index];
}
}
}
}
});
}

Related

Chart.js timeline [Group for single bar]

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>

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

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.

Stack grouped xAxes in bar chart

I'm using Chart.js 2.7.0 and I'd like to make bar stacked by xAxes, but grouped by type.
Let's say I have something like this:
I would like to stack values 49 and 59 in one bar and 29 with 32 together.
When I'm using options stacked true it stack everything...
It becomes:
When I tried to add xAxisID to dataset then second dataset with id x-axis-1 is hidden and not visible at all. X-Axis looks like is duplicated...
Look at snippet to see it.
var ctx = document.getElementById("chart1").getContext('2d');
var ctx2 = document.getElementById("chart2").getContext('2d');
var labels = [
"2018_4",
"2018_5",
"2018_6",
"2018_7",
"2018_8",
"2018_9",
"2018_10",
"2018_11",
];
var data = {
"labels": labels,
"datasets": [
{
"label": "t1",
xAxisID: "x-axis-0",
"data": [
29,19,26,28,20,21,11
],
backgroundColor: 'blue'
},
{
"label": "t1_SUM",
xAxisID: "x-axis-0",
"data": [
32,29,36,38,30,31,31
],
backgroundColor: 'red'
},
{
"label": "t2",
xAxisID: "x-axis-1",
"data": [
49,37,39,40,15,34,36,52
],
backgroundColor: 'blue'
},
{
"label": "t2_SUM",
xAxisID: "x-axis-1",
"data": [
59,47,49,50,25,44,46,62
],
backgroundColor: 'red'
}
]
};
new Chart(ctx, {
type: "bar",
data: data,
options: {
scales: {
xAxes:
[
{
stacked: true,
id: "x-axis-0",
},
{
stacked: true,
id: "x-axis-1",
}
],
}
}});
var data2 = {
"labels": labels,
"datasets": [
{
"label": "t1",
"data": [
29,19,26,28,20,21,11
],
backgroundColor: 'blue'
},
{
"label": "t1_SUM",
"data": [
32,29,36,38,30,31,31
],
backgroundColor: 'red'
},
{
"label": "t2",
"data": [
49,37,39,40,15,34,36,52
],
backgroundColor: 'blue'
},
{
"label": "t2_SUM",
"data": [
59,47,49,50,25,44,46,62
],
backgroundColor: 'red'
}
]
};
new Chart(ctx2, {
type: "bar",
data: data2,
options: {
scales: {
xAxes:
[
{
stacked: false,
}
],
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="chart1"></canvas>
<canvas id="chart2"></canvas>
<canvas id="chart3"></canvas>
From this snippet I want to connect
t1 and t1_SUM
t2 and t2_SUM
Ok,
I misread documentation.
I should use stack option in dataset and then it is working.
Sorry for troubles...

Categories