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...
Related
I tried to pass data from data.json to mustache template in order to create bar graph.
I am unable to figure out where exactly I need to pass the data to get the graph right.
Please help me to figure out by reviewing the following code snippets.
<html>
<body>
<div>
<canvas height="200px" width="300px" id="bar-graph"></canvas>
</div>
<script>
const barCtx = document.getElementById('bar-graph').getContext('2d');
new Chart(barCtx, barGraphConfig());
function barGraphConfig() {
return {
type: 'bar',
data: {
datasets: [{
data: {{barGraph}},
borderRadius: 5,
backgroundColor: [
'#fece8c',
'#a28cfe',
'#a28cfe',
'#feab8c',
'#8ca2fe',
'#8ca2fe',
],
barThickness: 20
}],
labels: ['AAA', 'AA', 'A', 'BBB', 'BB', 'B']
},
options: {
plugins: { legend: { display: false } },
showTooltip: false,
animation: {
duration: 0,
onComplete: renderDataLabel,
},
parsing: {
xAxisKey: 'sector',
yAxisKey: 'value'
},
scales: {
x: {
grid: {
borderWidth: 3,
borderColor: '#232323',
display: false,
},
},
y: {
display: false,
beginAtZero: true
}
}
},
};
}
</script>
</body>
</html>
data.json
barGraph: [
{
"name": "A",
"value": 4
},
{
"name": "AAA",
"value": 10
},
{
"name": "B",
"value": 40
},
{
"name": "BB",
"value": 20
},
{
"name": "BBB",
"value": 7
}
]
The error we are getting
You can use the structure of the data.json as dataset.data. But to enable CHART.JS to read correctly the data, you should set options.parsing option at chart level, as following:
options: {
parsing: {
xAxisKey: 'name',
yAxisKey: 'value'
}
}
See documentation of CHART.JS: https://www.chartjs.org/docs/latest/general/data-structures.html#object-using-custom-properties
const barGraph = [
{
"name": "A",
"value": 4
},
{
"name": "AAA",
"value": 10
},
{
"name": "B",
"value": 40
},
{
"name": "BB",
"value": 20
},
{
"name": "BBB",
"value": 7
}
];
const barCtx = document.getElementById('myChart').getContext('2d');
new Chart(barCtx, barGraphConfig());
function barGraphConfig() {
return {
type: 'bar',
data: {
datasets: [
{
data: barGraph,
borderRadius: 5,
backgroundColor: [
'#fece8c',
'#a28cfe',
'#a28cfe',
'#feab8c',
'#8ca2fe',
'#8ca2fe',
],
barThickness: 20
}
],
},
options: {
parsing: {
xAxisKey: 'name',
yAxisKey: 'value'
}
}
};
}
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>
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>
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
}
}
}
};
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];
}
}
}
}
});
}
I have created a fiddle derived from a fork supplied by the vendor. I would want only the label of the smaller chart segments to be displayed on the outside as shown on the left. This works as expected for a column chart. Is there an easier way to do this before I start fiddling with the canvas.js source code.
To the right is what my chart looks like, using this code
var chart = new CanvasJS.Chart("chartContainer",
{
data: [
{
type: "doughnut",
dataPoints: [
{ y: 1,indexLabel:"A",indexLabelPlacement:"outside"},
{ y: 50,indexLabel:"B",indexLabelPlacement:"inside"},
{ y: 28 ,indexLabel:"C",indexLabelPlacement:"inside"},
{ y: 31 ,indexLabel:"D",indexLabelPlacement:"inside"},
]
}
]
});
chart.render();
The fiddle I created is found here
Before burying myself deep into canvas.js code , I visited google one more time and stumbled upon a rich library, ZingChart which does exactly what I was looking for(mixing the label positions) without tampering with the library's source code
Snippet for usage
$scope.myJson = {
globals: {
fontFamily: "MuseoSans-700"
},
type: 'pie',
backgroundColor: "transparent",
plot: {
detach: false,
"slice": 55,
"shadow": 0,
refAngle: -90,
valueBox: {
fontColor: "black",
fontSize: 16,
connector: {
lineWidth: 1,
height: "50px"
},
rules: [
{
rule: "%v > 30",
placement: "in",
offsetR: 1
},
{
rule: "%v <= 30",
placement: "out"
}
]
}
},
series: [
{ "values": [32], "text": "A", backgroundColor: "#c4f0ac" },
{ "values": [32], "text": "B", backgroundColor: "#FF9097" },
{ "values": [1], "text": "C", backgroundColor: "#FF9097" },
{ "values": [1], "text": "D", backgroundColor: "#FF9097" },
{ "values": [1], "text": "NS", backgroundColor: "#bcbcbc" }
]
And the resulting chart was like this