How to make labels on both side from horizontal bar chart js - chart.js

I want to make side labels for double horizontal bar on both side like this: pic 1, pic 2
can someone help me idk how to do it, im new in react and chartjs
this post continued from: How to make multiple horizontal bar chartjs
here's what i code:
this the data:
data for chart
export const dataPasienKeluarMasuk = {
type: 'bar',
labels: [
[0, 1, 2, 3,4], // expect output 0 - 4
[5, 6, 7, 8, 9], // expect output 5 - 9
[10, 14], // ext..
[15, 19],
[20, 24],
[25, 29],
[30, 34],
],
datasets: [
{
label: 'Pasien Masuk',
xAxisID: 'A',
data: [100, 90, 80, 70, 60],
backgroundColor: 'red',
},
{
label: 'Pasien Keluar',
xAxisID: 'A',
data: [-100, -90, -80, -70, -60],
backgroundColor: 'blue',
},
],
}
this the chart:
multiple y horizontal bar
import { HorizontalBar } from 'react-chartjs-2'
import { dataPasienKeluarMasuk } from ...blabla
<HorizontalBar
data={dataPasienKeluarMasuk}
height={227}
options={{
responsive: true,
title: {
display: true,
text: 'Data Pasien Keluar Masuk',
fontSize: 20,
},
legend: {
display: true,
position: 'bottom',
},
scales: {
xAxes: [
{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Jumlah Pasien (orang)',
},
ticks: {
// Include a dollar sign in the ticks
callback: (value) => Math.abs(value),
},
},
],
yAxes: [
{
stacked: true,
ticks: {
display: true,
reverse: true,
},
},
],
},
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let ds = data.datasets[tooltipItem.datasetIndex]
return (
ds.label + ': ' + Math.abs(ds.data[tooltipItem.index])
)
},
},
},
}}
/>

You can obtain the desired result by defining a second y-axis as follows:
{
type: 'category',
position: 'right',
offset: true,
ticks: {
reverse: true,
},
gridLines: {
display: false
}
}
Please take a look at your amended and runnable code below:
new Chart(document.getElementById('canvas'), {
type: 'horizontalBar',
data: {
labels: ['0-4', '5-9', '10-14', '15-19', '20+'],
datasets: [{
label: 'Pasien Masuk',
data: [100, 90, 80, 70, 60],
backgroundColor: 'red',
},
{
label: 'Pasien Keluar',
data: [-100, -75, -60, -75, -70],
backgroundColor: 'blue',
},
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Data Pasien Keluar Masuk',
fontSize: 20,
},
legend: {
position: 'bottom',
},
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let ds = data.datasets[tooltipItem.datasetIndex];
return ds.label + ': ' + Math.abs( ds.data[tooltipItem.index]);
}
}
},
scales: {
xAxes: [{
stacked: true,
ticks: {
callback: value => Math.abs(value)
}
}],
yAxes: [{
stacked: true,
ticks: {
reverse: true,
}
},
{
type: 'category',
position: 'right',
offset: true,
ticks: {
reverse: true,
},
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="canvas" height="100"></canvas>

Related

Chart.Js vers2 multiline to version 3

I try to create a multi axis chart using chart.js ver 3.6.0 but it look nothing like the one displayed in their example found here chart
This is the code I use.
<canvas id="canvas"></canvas>
<script>
const ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.height = 200;
const labels = "11/1/2021,11/2/2021,11/3/2021,11/4/2021,11/5/2021,11/6/2021,11/7/2021,11/8/2021,11/9/2021,11/10/2021";
const data = {
labels: labels,
datasets: [
{
label: "South",
data: "6,4,2,4,3,1,0,9,3,0",
borderColor: "#0d47a1",
backgroundColor: "#2196f3",
yAxisID: "y",
},
{
label: "North",
data: "72,97,88,143,102,0,0,153,100,0",
borderColor: "#e65100",
backgroundColor: "#ff9800",
yAxisID: "y1",
},
],
};
const config = {
type: "line",
data: data,
options: {
responsive: true,
interaction: {
mode: "index",
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: "Test",
},
},
scales: {
y: {
type: "linear",
display: true,
position: "left",
},
y1: {
type: "linear",
display: true,
position: "right",
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
x: {
ticks: {
maxRotation: 65,
minRotation: 65,
fontSize: 11,
},
},
},
},
};
window.myLine = new Chart(ctx, config);
</script>
Why is the lines not connected, and why is the y axis not displaying each datasets max value?
Mine looks like this..
This is because you provide the labels and data as strings while it should be an array with strings for the labels, same goes for the data field:
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
<script>
const ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.height = 200;
const labels = ['11/1/2021', '11/2/2021', '11/3/2021', '11/4/2021', '11/5/2021', '11/6/2021', '11/7/2021', '11/8/2021', '11/9/2021', '11/10/2021'];
const data = {
labels: labels,
datasets: [{
label: 'South',
data: ['6', '4', '2', '4', '3', '1', '0', '9', '3', '0'],
borderColor: '#0d47a1',
backgroundColor: '#2196f3',
yAxisID: 'y',
},
{
label: 'North',
data: ['72', '97', '88', '143', '102', '0', '0', '153', '100', '0'],
borderColor: '#e65100',
backgroundColor: '#ff9800',
yAxisID: 'y1',
}
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Test'
}
},
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
},
y1: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
x: {
ticks: {
maxRotation: 65,
minRotation: 65,
fontSize: 11
}
}
}
},
};
new Chart(ctx, config);
</script>

Draw stacked horizontal bar chart with Average line using ChartJS

I am trying to create a stacked horizontal bar chart with an average line on each bar using the ChartJS library. I tried several times and searched on the Internet but I did not find out any satisfying answers. I appreciate your helping. Thanks.
Example:
.
In this example, the red line on each bar implies the average value of its group.
To create the stacked horizontal bar chart, please see
https://jsfiddle.net/lamtn862004/9wm1krqf/10/.
var data = {
labels: ["January", "February", "March"],
datasets: [
{
label: "Dogs",
backgroundColor: "rgba(237, 192, 169)",
data: [20, 10, 25],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
{
label: "Cats",
backgroundColor: "rgba(253, 234, 175)",
data: [70, 85, 65],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
{
label: "Birds",
backgroundColor: "rgba(179, 211, 200)",
data: [10, 5, 10],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
]
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: 'groupableHBar',
data: data,
options: {
scales: {
yAxes: [{
stacked: true,
type: 'category',
id: 'y-axis-0'
}],
xAxes: [{
stacked: true,
type: 'linear',
ticks: {
beginAtZero:true
},
gridLines: {
display: false,
drawTicks: true,
},
id: 'x-axis-0'
},
{
stacked: true,
position: 'top',
type: 'linear',
ticks: {
beginAtZero:true
},
id: 'x-axis-1',
gridLines: {
display: true,
drawTicks: true,
},
display: false
}]
}
}
});
Now, I want to add the average line to each bar (as shown in the image).
Also, do you know the other solutions with open-source libraries for doing this?
The lines can be drawn using floating bars tied to the separate axis y2. To do so, you need to add another dataset as follows (I don't exactly understand what values you want to display, hence I randomly chose 40, 65 and 55):
{
label: "Lines",
backgroundColor: "rgb(255, 0, 0)",
data: [40, 65, 55].map(v => [v - 0.3, v + 0.3]),
yAxisID: 'y2',
order: -1
}
Further you must define a new scales option as shown below:
y2: {
display: false
}
Please take a look at your amended runnable code and see how it works.
var data = {
labels: ["January", "February", "March"],
datasets: [{
label: "Dogs",
backgroundColor: "rgba(237, 192, 169)",
data: [20, 10, 25]
},
{
label: "Cats",
backgroundColor: "rgba(253, 234, 175)",
data: [70, 85, 65]
},
{
label: "Birds",
backgroundColor: "rgba(179, 211, 200)",
data: [10, 5, 10]
},
{
label: "Lines",
backgroundColor: "rgb(255, 0, 0)",
data: [40, 65, 55].map(v => [v - 0.3, v + 0.3]),
yAxisID: 'y2',
order: -1
}
]
};
new Chart('myChart', {
type: 'bar',
data: data,
options: {
indexAxis: 'y',
plugins: {
legend: {
display: false
}
},
scales: {
y: {
stacked: true,
grid: {
display: false
}
},
y2: {
display: false
},
x: {
stacked: true,
beginAtZero: true,
grid: {
display: false
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

Chart.js move x axis labels to the right

I'm using the latest chart.js to draw a simple histogram.
The histogram is fine but I actually need the x labels to be between the borders of every bar like this histogram_right_labels, are there any methods to approach this?
I've tried offsetGridLines: true and offsetGridLines: false, but what they actually did is moving the grid lines and not the labels, unlike what I read about their actual behaviors, I think it might be a conflict in my option settings but I don't know which, any help would be appreciated.
options: {
maintainAspectRatio: false,
layout: {
padding: {
left: 10,
right: 25,
top: 25,
bottom: 0
}
},
scales: {
xAxes: [{
gridLines: {
//display: false,
drawBorder: false,
padding: 20,
offsetGridLines: true
},
ticks: {
beginAtZero: true,
}
}],
yAxes: [{
ticks: {
padding: 10,
},
gridLines: {
color: "rgb(234, 236, 244)",
zeroLineColor: "rgb(234, 236, 244)",
drawBorder: false,
borderDash: [2],
zeroLineBorderDash: [2]
}
}],
},
legend: {
labels: {
boxWidth: 20
},
display: false
},
tooltips: {
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
titleMarginBottom: 10,
titleFontColor: '#6e707e',
titleFontSize: 14,
borderColor: '#dddfeb',
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
intersect: false,
mode: 'index',
caretPadding: 10,
},
}
You can add a second x-axis of type: 'linear' as follows.
{
type: 'linear',
ticks: {
min: 0,
max: labels.length,
stepSize: 1,
callback: (v, i) => i == 0 ? '' : labels[i - 1]
}
}
Note that I use a ticks callback method in order to provide the desired tick label at given index.
Then you should also hide the grid lines and ticks of the default x-axis.
{
gridLines: {
display: false
},
ticks: {
display: false
}
}
Please take a look at below runnable sample code and see how it works.
const labels = ['4.80', '9.60', '14.40', '19.20', '24.00', '28.80'];
new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: "My Dataset",
data: [4, 8, 5, 7, 2, 4],
backgroundColor: 'orange',
categoryPercentage: 1,
barPercentage: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
gridLines: {
display: false
},
ticks: {
display: false
}
},
{
type: 'linear',
ticks: {
min: 0,
max: labels.length,
stepSize: 1,
callback: (v, i) => i == 0 ? '' : labels[i - 1]
}
}
]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<canvas id="myChart" height="90"></canvas>
you can use this to put the tooltips to the right. Possibilities are top, left, right and bottom
options: {
title: {
display: true,
position: 'right'
}
}

How to make multiple horizontal bar chartjs

I want to make horizontal bar chart using chartjs in react like this: chart i want to make
but i end up doing like this chart i make
can someon help me please, im new in react and chartjs
Here's the continuation of this post: How to make labels on both side from horizontal bar chart js
here's what i code:
this the data:
export const dataPasienKeluarMasuk = {
type: 'bar',
labels: [
[0, 1, 2, 3,4], // expect output 0 - 4
[5, 6, 7, 8, 9], // expect output 5 - 9
[10, 14], // ext..
[15, 19],
[20, 24],
[25, 29],
[30, 34],
],
datasets: [
{
label: 'Pasien Masuk',
xAxisID: 'A',
data: [100, 90, 80, 70, 60],
backgroundColor: 'red',
},
{
label: 'Pasien Keluar',
xAxisID: 'A',
data: [-100, -90, -80, -70, -60],
backgroundColor: 'blue',
},
],
}
here's the chart:
import { HorizontalBar } from 'react-chartjs-2'
import { dataPasienKeluarMasuk } from ...blabla
<HorizontalBar
data={dataPasienKeluarMasuk}
height={227}
options={{
responsive: true,
title: {
display: true,
text: 'Data Pasien Keluar Masuk',
fontSize: 20,
},
legend: {
display: true,
position: 'bottom',
},
scales: {
xAxes: [
{
id: 'A',
position: 'left',
},
],
},
}}
/>
You should define both axes as stacked:
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
In order to see only positive values displayed on the x-axis ticks, you need to define a ticks.callback function on the x-axis.
ticks: {
callback: value => Math.abs(value)
}
To have only positive values displayed in the tooltips, you further need to define a tooltips.callback.label functions as shown below.
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let ds = data.datasets[tooltipItem.datasetIndex];
return ds.label + ': ' + Math.abs( ds.data[tooltipItem.index]);
}
}
},
Please take a look at the runnable code snippet below and see how it works (this is a pure Chart.js solution but it should easily be adaptable to react-chart.js).
new Chart(document.getElementById('canvas'), {
type: 'horizontalBar',
data: {
labels: ['a', 'b', 'c', 'd', 'e'],
datasets: [{
label: 'Pasien Masuk',
data: [100, 90, 80, 70, 60],
backgroundColor: 'red',
},
{
label: 'Pasien Keluar',
data: [-100, -90, -80, -70, -60],
backgroundColor: 'blue',
},
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Data Pasien Keluar Masuk',
fontSize: 20,
},
legend: {
position: 'bottom',
},
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
let ds = data.datasets[tooltipItem.datasetIndex];
return ds.label + ': ' + Math.abs( ds.data[tooltipItem.index]);
}
}
},
scales: {
xAxes: [{
stacked: true,
ticks: {
callback: value => Math.abs(value)
}
}],
yAxes: [{
stacked: true
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="canvas"></canvas>
this snippet is based from uminder's answer
new Chart(document.getElementById('canvas'), {
type: 'horizontalBar',
data: {
labels: ['a', 'b', 'c', 'd', 'e'],
datasets: [{
label: 'Pasien Masuk',
data: [100, 90, 80, 70, 60],
backgroundColor: 'red',
},
{
label: 'Pasien Keluar',
data: [-100, -90, -80, -70, -60],
backgroundColor: 'blue',
},
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Data Pasien Keluar Masuk',
fontSize: 20,
},
legend: {
display: true,
position: 'bottom',
},
scales: {
xAxes: [{
stacked: true,
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value < 0? -(value) : value
}
}
}],
yAxes: [{
stacked: true
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
var value = tooltipItem.xLabel;
value = value < 0? -(value) : value
return label + ': ' + value;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="canvas"></canvas>

How can I show chartjs datalabels only last bar?

I need to show the last bar value only. like this image:
I try this code but it shows all values.
var dataX = {
labels: [['Personne', 'seule'], ['Couple sans', 'enfant'], ['Couple avec', 'enfant(s)'], ['Famille', 'monoparentale'], 'Autres'],
datasets: [{
label: 'Data 1',
data: [33,28,25,8,2.5],
backgroundColor: '#00BBF1',
borderWidth: 0
},
{
label: 'Data 2',
data: [29,30,30,8,2],
backgroundColor: '#3CC6F4',
borderWidth: 0
},
{
label: 'Data 3',
data: [41,22,22,11,3],
backgroundColor: '#92D9F8',
borderWidth: 0
}]
};
var optionsX = {
tooltips: {
enabled: false
},
responsive: true,
maintainAspectRatio: false,
legend: false,
scales: {
xAxes: [{
gridLines : {
color: "#fff"
},
}],
yAxes: [{
gridLines : {
display : false
},
ticks: {
min: 0,
max: 50,
stepSize: 10,
callback: function(value) {
return value + "%"
},
}
}]
},
plugins: {
datalabels: {
color: '#59595B',
font: {
weight: 'bold',
size: 14,
},
align: 'end',
anchor: 'end',
formatter: function(value, context) {
return value +'%';
}
}
},
};
var ctx = document.getElementById('chart-one');
var myChart = new Chart(ctx, {
type: 'bar',
data: dataX,
options: optionsX
});
You can change the plugins.datalabels.formatter function as follows:
plugins: {
...
datalabels: {
formatter: (value, context) => context.datasetIndex == 2 ? value + '%' : ''
}
}
Please take a look at your amended code below and see how it works.
var dataX = {
labels: [
['Personne', 'seule'],
['Couple sans', 'enfant'],
['Couple avec', 'enfant(s)'],
['Famille', 'monoparentale'], 'Autres'
],
datasets: [{
label: 'Data 1',
data: [33, 28, 25, 8, 2.5],
backgroundColor: '#00BBF1',
borderWidth: 0
},
{
label: 'Data 2',
data: [29, 30, 30, 8, 2],
backgroundColor: '#3CC6F4',
borderWidth: 0
},
{
label: 'Data 3',
data: [41, 22, 22, 11, 3],
backgroundColor: '#92D9F8',
borderWidth: 0
}
]
};
var optionsX = {
tooltips: {
enabled: false
},
responsive: true,
maintainAspectRatio: false,
legend: false,
scales: {
xAxes: [{
gridLines: {
color: "#fff"
},
}],
yAxes: [{
gridLines: {
display: false
},
ticks: {
min: 0,
max: 50,
stepSize: 10,
callback: function(value) {
return value + "%"
},
}
}]
},
plugins: {
datalabels: {
color: '#59595B',
font: {
weight: 'bold',
size: 14,
},
align: 'end',
anchor: 'end',
formatter: (value, context) => context.datasetIndex == 2 ? value + '%' : ''
}
},
};
var ctx = document.getElementById('chart-one');
var myChart = new Chart(ctx, {
type: 'bar',
data: dataX,
options: optionsX
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
<canvas id="chart-one"></canvas>