Chartjs y axes label overflow - chart.js

We are using react chart js but the problem occurs when we try to show multi-line charts in small widgets with high y-axis values.
Overflow occurs in smaller widths and large y axes numbers. I already try a thousand suffixes but it doesn't work. Is it possible to keep the y-axis constant by making the x-axis smaller? Or handle it responsive.
function randomTwoNumbers(n1, n2) {
return Math.floor(Math.random() * (n2 - n1 + 1) + n1)
}
function generateData(count) {
let data = []
for (let index = 0; index < count; index++) {
data.push({
x: `2022-07-${index}T00:00:00.000Z`,
y: randomTwoNumbers(1000000, 9999999)
})
}
return data
}
const data = {
datasets: [
{
data: generateData(100),
label: 'Temperature',
borderColor: '#236EF1',
tension: 0.5,
pointRadius: 1,
pointHoverRadius: 5,
pointHitRadius: 20,
yAxisID: 'y0'
},
{
data: generateData(100),
label: 'Humidity',
borderColor: '#CA840C',
tension: 0.5,
pointRadius: 1,
pointHoverRadius: 5,
pointHitRadius: 20,
yAxisID: 'y1'
}
]
}
const options = {
responsive: true,
resizeDelay: 300,
scales: {
x: {
display: true,
grid: {
borderColor: '#5E646E',
tickColor: '#5E646E',
display: true,
drawOnChartArea: false
},
ticks: {
autoSkip: false,
maxRotation: 0,
font: {
size: 10,
family: 'Inter',
lineHeight: '12px',
weight: '500'
}
},
time: {
unit: 'day',
displayFormats: {
minute: 'p',
hour: 'p',
day: 'MMM, do'
}
},
type: 'time',
offset: true,
adapters: {
date: {
locale: {
code: 'en-US',
formatLong: {},
localize: {},
match: {}
}
}
}
},
y0: {
display: true,
grid: {
borderColor: '#5E646E',
tickColor: '#5E646E',
display: true,
drawOnChartArea: false
},
ticks: {
font: {
size: 10,
family: 'Inter',
lineHeight: '12px',
weight: '500'
}
},
stack: 'single',
offset: false
},
y1: {
display: true,
grid: {
borderColor: '#5E646E',
tickColor: '#5E646E',
display: true,
drawOnChartArea: false
},
ticks: {
font: {
size: 10,
family: 'Inter',
lineHeight: '12px',
weight: '500'
}
},
stack: 'single',
offset: false
}
},
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: false
},
tooltip: {
displayColors: false
}
}
}
var config = {
type: 'line',
data,
options
}
var ctx = document.getElementById('canvas').getContext('2d')
window.myLine = new Chart(ctx, config)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.2/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-moment/1.0.1/chartjs-adapter-moment.min.js"></script>
<div style="width: 200px">
<canvas id="canvas"></canvas>
</div>

Related

Display Datalabel for an specific point in Chart Js

I'm trying to build a chart.js Line and with scatter points and I would like to have the datalabel to show just on the scatter points, I've tried to do it with datalabels plugin from chart js but it shows the datalabel for all datasets including the line, How can I show just the specific scatter points? this is what the code looks like:
Chart.register(ChartDataLabels);
fetch('https://raw.githubusercontent.com/ConeDigital/assets/main/data.json')
.then(response => response.json())
.then(data => {
var ctx = document.getElementById('myChart2').getContext('2d'),
chart = new Chart(ctx, {
type: 'line',
data: getChartData(data),
options: {
legend: {
display: false
},
plugins: {
datalabels: { // This code is used to display data values
anchor: 'end',
align: 'top',
font: {
weight: 'bold',
size: 16
}
}
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label + ': ' + tooltipItem.yLabel+"%";
},
labelColor: function (tooltipItem, chart) {
let border = ''
let background = ''
let colors
if ( tooltipItem.datasetIndex === 1 ) {
colors = {
borderColor: '#fff',
backgroundColor: '#001F5B'
}
} else {
colors = {
borderColor: '#fff',
backgroundColor: '#eb8484'
}
}
return colors
}
}
},
responsive: true,
scales: {
xAxes: [{
stacked: false,
scaleLabel: {
display: false,
labelString: 'Datum'
},
ticks: {
display: false
},
gridLines: {
display: false,
drawBorder: false,
}
}],
yAxes: [{
stacked: false,
ticks: {
display: false
},
gridLines: {
display: false,
drawBorder: false
},
scaleLabel: {
display: false,
labelString: 'Procent'
}
}]
}
}
});
})
function getChartData(json) {
var labels = [];
var omx_dataset = {
label: 'OMXS30',
borderColor: '#eb8484',
fill: false,
pointRadius: 0,
borderWidth: 1,
data: []
};
var gadd_dataset = {
label: "GADD SMP SEK",
borderColor: '#001F5B',
fill: false,
pointRadius: 0,
borderWidth: 1,
data: []
};
var mark1_dataset = {
label: 'Start',
borderWidth: 2,
borderColor: '#FF0000',
fill: false,
type: 'scatter',
data: [{
x: '2011-03-29',
y: 0
}],
pointRadius: 12
};
var mark2_dataset = {
label: '2016',
borderWidth: 2,
borderColor: '#FF0000',
fill: false,
type: 'scatter',
data: [{
x: '2015-12-31',
y: 20
}],
pointRadius: 12
};
var mark3_dataset = {
label: '2020',
borderWidth: 2,
borderColor: '#FF0000',
fill: false,
type: 'scatter',
data: [{
x: '2020-01-07',
y: 59
}],
pointRadius: 12
};
var mark4_dataset = {
label: '2022',
borderWidth: 2,
borderColor: '#FF0000',
fill: false,
type: 'scatter',
data: [{
x: '2022-01-03',
y: 109
}],
pointRadius: 12
};
json.map((point,i) => {
labels.push(point.Date)
const gadd_num = (point['GADD SMP SEK']*100).toFixed(2)
const omx_num = (point['OMXS30']*100).toFixed(2)
gadd_dataset.data.push(gadd_num)
omx_dataset.data.push(omx_num)
//console.log(point.Date)
//result1_dataset.data.push(point.date)
})
return {
labels: labels,
datasets: [omx_dataset, gadd_dataset, mark1_dataset, mark2_dataset, mark3_dataset, mark4_dataset]
}
}
Right now it shows all the datalabels from all the datasets and it looks messed up,
Thanks in advance
You could add the datalabels config to the line datasets, disabling the plugin, as the following:
var omx_dataset = {
label: 'OMXS30',
borderColor: '#eb8484',
fill: false,
pointRadius: 0,
borderWidth: 1,
data: []
datalabels: {
display: false
}
};
var gadd_dataset = {
label: "GADD SMP SEK",
borderColor: '#001F5B',
fill: false,
pointRadius: 0,
borderWidth: 1,
data: [],
datalabels: {
display: false
}
};

Chartjs and datalabels : automatic y axis (and dynamic data) hide datalabels

I have a chart (chartjs) with labels (datalabels).
When my data changes, my chart updates automatically. However, the largest datalabels are most of the time hidden by the automatic resizing of the y axis. Do you have any idea to fix that ?
It should be a 3 up there :)
Here is my code:
const completionOptions = {
responsive: true,
plugins: {
legend: {
display: false,
},
tooltip: {
backgroundColor: 'rgb(85, 85, 85, 1)',
displayColors: false,
// https://www.chartjs.org/docs/latest/configuration/tooltip.html
},
datalabels: {
color: 'rgb(203, 203, 203)',
anchor: 'end',
align: 'end',
labels: {
title: {
font: {
family: 'karla',
weight: '600',
size: 12,
},
}
}
}
},
scales: {
display: false,
y: {
beginAtZero: true,
display: false,
grid: {
display: false,
},
ticks: {
padding: 10
}
},
x: {
grid: {
display: false,
},
ticks: {
autoSkip: false,
maxRotation: 0,
minRotation: 0,
font: {
size: 20,
}
}
},
}
}
You can use the grace option to add extra space to the y axes:
Chart.register(ChartDataLabels)
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 20, 3, 5, 2, 3],
backgroundColor: 'pink'
}]
},
options: {
scales: {
y: {
grace: '10%'
}
},
plugins: {
legend: {
display: false
},
datalabels: {
anchor: 'end',
align: 'end'
}
}
}
}
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.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.js"></script>
</body>

How to make labels on both side from horizontal bar 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>

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>

chart.js bar chart time axis tooltip issue

I am plotting bar chart with time axis, X-Axis unit is 'day' and ticks will be 30 day apart.With this tooltip is not displaying. I am using 2.0 beta2 version. Its a 1 year graph with random time sample data. UserCallBack function skips ticks for 30 days.
Any suggestions why tool tip is not displaying?
var canvas = document.getElementById('myChart');
var labelsArray = ["2017/06/09 00:00:00", "2017/07/05 00:00:00"];
var data = {
labels: labelsArray,
datasets: [{
label: "My First dataset",
data: [10, 50],
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
}]
};
var xAxesConfig = [{
type: "time",
categoryPercentage: 0.1,
barPercentage: 0.2,
time: {
displayFormat: 'MMM-DD',
format: 'YYYY/MM/DD HH:mm:SS',
unit: 'day',
min: '2016/09/12 17:00:00',
max: '2017/09/12 17:00:00'
},
scaleLabel: {
display: true,
labelString: 'Time',
fontSize: 14,
fontStyle: "bold"
},
ticks: {
maxRotation: 0,
autoSkip: false,
userCallback: function(value, index, values) {
return (index % 30 == 0) ? value : null;
//return value;
}
}
}];
var yAxesConfig = [{
position: 'left',
gridLines: {
display: true
},
ticks: {
maxTicksLimit: 5,
suggestedMin: 0,
suggestedMax: 10
},
scaleLabel: {
display: true,
labelString: 'Value',
fontSize: 14,
fontStyle: "bold"
}
}];
var option = {
scales: {
yAxes: yAxesConfig,
xAxes: xAxesConfig,
}
};
var myBarChart = Chart.Bar(canvas, {
data: data,
options: option
});