Chartjs with multiple y axes and different scales - javascript

How can I use different scales in Y Axes with ChartJs?
I have this datasets:
[ 1450478,2645844,1840524,640057,1145844,1530500,1695844,1778654,1450478,1645844,1450478,1645844 ]
[ 3.14, 4.15, 3.09, 3.48, 4.05, 3.99, 4.39, 4.15, 4.10, 3.98, 3.54, 3.50 ]
https://jsfiddle.net/psycocandy/ad18Lc4u/18/
The smallest scale represented by the line is obviously very close to the scale of 0. How do I make this same line visible without having to filter by legend?

I found the problem, updated fiddle: https://jsfiddle.net/psycocandy/fwncq25a/14/
To set the correspondent ID in the dataset with the yAxes, the correct way is to use yAxisID:
var chartData = [
[1450478, 2645844, 1840524, 640057, 1145844, 1530500, 1695844, 1778654, 1450478, 1645844, 1450478, 1645844],
[3.14, 4.15, 3.09, 3.48, 4.05, 3.99, 4.39, 4.15, 4.10, 3.98, 3.54, 3.50]
];
var dataSet = {
labels: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
],
datasets: [{
type: 'line',
label: 'Preço Médio Mensal',
yAxisID: 'y-axis-0',
borderColor: '#17522f',
fill: false,
backgroundColor: '#17522f',
borderWidth: 3,
radius: 4,
hoverBorderWidth: 4,
rotate: 90,
data: chartData[1],
datalabels: {
display: true,
align: 'end',
anchor: 'end',
rotation: -90,
clamp: true,
clip: true,
color: '#17522f',
padding: 10,
formatter: function (value, context) {
return numeral(value).format('0,0.00');
},
font: {
weight: 'bold',
}
}
},{
type: 'bar',
label: 'Total Mensal',
yAxisID: 'y-axis-1',
backgroundColor: '#7579ef',
borderColor: '#171951',
borderWidth: 2,
data: chartData[0],
datalabels: {
display: true,
clamp: true,
anchor: 'start',
align: 'end',
offset: 10,
rotation: -90,
color: '#171951',
formatter: function (value, context) {
return numeral(value).format('0,0');
},
font: {
weight: 'bold',
}
}
}]
};
var chart = new Chart(document.getElementById('myChart'), {
type: 'bar',
data: dataSet,
options: {
title: {
display: false
},
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
var value = parseFloat(tooltipItem.value);
var formatedValue;
if(tooltipItem.datasetIndex > 0){
formatedValue = numeral(value).format('$ 0,0.00');
}else{
formatedValue = numeral(value).format('$ 0,0.00');
}
return ' ' + formatedValue;
},
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
position: 'left',
type: 'linear',
scaleLabel: {
display: true,
},
id: 'y-axis-1',
ticks: {
beginAtZero:true,
callback: function (tick, index, ticks) {
return numeral(tick).format('(0,0)');
},
}
}, {
stacked: false,
position: 'right',
type: 'linear',
id: 'y-axis-0',
ticks: {
max: 10,
stepSize: 1,
display: true,
beginAtZero: true,
fontSize: 13,
padding: 10,
callback: function (tick, index, ticks) {
return numeral(tick).format('$ 0,0');
}
}
}]
}
}
});

In Chart.js 3, the syntax is slightly different. The axes are identified by their scaleId:
Namespace: options.scales[scaleId]
datasets: [
{
type: 'line',
yAxisID: 'y1',
},
{
type: 'line',
yAxisID: 'y2',
}
]
scales: {
x: {
stacked: false,
y1: {
position: 'left',
stacked: false,
},
y2: {
position: 'right',
stacked: false,
},
}
See the Charts.js axes documentation for more.

Related

How to increase font size in the legend of your chart.js plot?

I am trying to increase labels' font size in the legend of a plot that I have done with chart.js.
Attached there is a screenshot:
I want to increase the font size of "Label 1,2,3".
Below the javascript configuration that I am using right now:
var data = {
labels: x_axis_labels,
datasets: [
{
label: 'Label 1',
data: data_1,
borderColor: 'rgb(46,138,207)',
backgroundColor: 'rgb(46,138,207)',
yAxisID: 'y',
},
{
label: 'Label 2',
data: data_2,
borderColor: 'rgb(214,224,52)',
backgroundColor: 'rgb(214,224,52)',
yAxisID: 'y1',
},
{
data: data_3,
label:'Label 3',
borderColor: 'rgb(244,67,54)',
backgroundColor: 'rgb(244,67,54)',
yAxisID: 'y1',
pointStyle:'dash',
borderDash: [20, 30],
pointBackgroundColor: "transparent",
},
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
}
},
scales: {
x:{
title:{
display: true,
text: 'X axis name',
font: {size:30},
},
ticks: {
font: {
size: 20,
}
}
},
y: {
title:{
display: true,
text: 'First y axis name',
font: {size:30}
},
type: 'linear',
display: true,
position: 'left',
ticks: {
font: {
size: 24,
}
}
},
y1: {
title:{
display: true,
text: 'Second Y axis name',
font: {size:30}
},
type: 'linear',
display: true,
position: 'right',
ticks:{
font:{
size:24,
}
},
// grid line settings
grid: {
drawOnChartArea: false,
},
},
},
},
};
I have tried Font Documnetation and Legend Documentation but I got nothing.
Someone had experience in this?
Thanks in advance
As described in the docs you can set the size in the options.plugins.legend.labels.font.size namespace
options: {
plugins: {
legend: {
labels: {
font: {
size: 20
}
}
}
}
}

Chart JS Tooltip Currency Problem - Stacked Bar Chart

I use ChatJS and i want to add an € Symbol after every number in the Tooltip.
On my most charts it works perfectly but the Stacked Bar Chart makes me problems.
Here is an example Code like mine (Just a basic Example)
var barChart = new Chart(ctx_barChart, {
type: 'bar',
data: {
labels: ["Fruits"],
datasets: [{
label: [
["Apple"]
],
data: [12],
backgroundColor: 'blue',
barThickness: 80,
},
{
label: ["Banana"],
data: [15],
backgroundColor: 'red',
barThickness: 80,
},
]
},
options: {
maintainAspectRatio: false,
indexAxis: 'y',
responsive: true,
scales: {
x: {
stacked: true,
display: false,
},
y: {
stacked: true,
display: false,
mirror: true,
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'EUR'
}).format(context.parsed.y);
}
return label;
}
}
},
legend: {
display: false
},
title: {
display: false,
},
},
},
});
The tooltips both show 0,00$, but not my Values 12 and 15. Anyone have an suggestiont?
You should use context.parsed.x instead of context.parsed.y since it's a horizontal bar chart.
Please take a look at your amended code and see how it works.
new Chart('barChart', {
type: 'bar',
data: {
labels: ["Fruits"],
datasets: [{
label: "Apple",
data: [12],
backgroundColor: 'blue',
barThickness: 80,
},
{
label: "Banana",
data: [15],
backgroundColor: 'red',
barThickness: 80,
},
]
},
options: {
maintainAspectRatio: false,
indexAxis: 'y',
responsive: true,
scales: {
x: {
stacked: true,
display: false,
},
y: {
stacked: true,
display: false,
mirror: true,
}
},
plugins: {
tooltip: {
callbacks: {
label: ctx => ctx.dataset.label + ': ' + new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(ctx.parsed.x)
}
},
legend: {
display: false
},
title: {
display: false,
},
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<canvas id="barChart" height="100"></canvas>

How to add margin bottom in Tittle ChartJS

I would like to know how to add bottom margin to my title in ChartJS to prevent Datalabels from overlapping the title, thanks.
you can view the graph in that link
View Image
I use:
ChartJS
ChartJS Datalabels
This is my code
//chart por rango de edad
var ctx_age_range = document.getElementById('chart_age_range');
var myDoughnutChart = new Chart(ctx_age_range, {
type: 'bar',
data: {
labels: ["<20", "20-29", "30-39", "40-55", ">56"],
datasets: [{
label: "Cantidad",
backgroundColor: ["#47b3d5", "#47b3d5","#47b3d5","#47b3d5","#47b3d5"],
data: [0.32,34.55,34.79,25.32,5.02]
}]
},
options: {
legend: {
display: false,
},
title: {
display: true,
text: 'CASOS POR RANGO DE EDAD',
fontSize:15,
color:"black"
},
scales: {
xAxes: [{
gridLines: {display: false},
ticks: {
stepSize: 1,
min: 0,
fontSize:12
},
barPercentage: 0.8,
categoryPercentage: 1,
}],
yAxes: [{
scaleLabel: {
display: false,
},
gridLines: {display: false,drawBorder:false},
ticks:{
display:false,
},
}]
},
plugins: {
datalabels: {
display: true,
align: 'end',
anchor: 'end',
formatter: function(value, ctx) {
return value+'%';
},
color:'black',
font:{
size: 11
}
}
}
}
});
I would like to know how add margin bottom to the title or how to add margin/padding top top of graphic.
You can use padding property on the title option to achieve that:
var ctx_age_range = document.getElementById('chart_age_range');
var myDoughnutChart = new Chart(ctx_age_range, {
type: 'bar',
data: {
labels: ["<20", "20-29", "30-39", "40-55", ">56"],
datasets: [{
label: "Cantidad",
backgroundColor: ["#47b3d5", "#47b3d5","#47b3d5","#47b3d5","#47b3d5"],
data: [0.32,34.55,34.79,25.32,5.02]
}]
},
options: {
legend: {
display: false,
},
title: {
display: true,
text: 'CASOS POR RANGO DE EDAD',
fontSize:15,
color:"black",
padding: 30
},
scales: {
xAxes: [{
gridLines: {display: false},
ticks: {
stepSize: 1,
min: 0,
fontSize:12
},
barPercentage: 0.8,
categoryPercentage: 1,
}],
yAxes: [{
scaleLabel: {
display: false,
},
gridLines: {display: false,drawBorder:false},
ticks:{
display:false,
},
}]
},
plugins: {
datalabels: {
display: true,
align: 'end',
anchor: 'end',
formatter: function(value, ctx) {
return value+'%';
},
color:'black',
font:{
size: 11
}
}
}
}
});
<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#0.7.0/dist/chartjs-plugin-datalabels.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="chart_age_range" width="400" height="400"></canvas>

chart js in an especific label

I need to put a line in my chart to indicate where the day changes to the next. The initial label of the day is 00:00. Is there a function to put a line like this in my chart, that will always appear in the labels at 00:00?
The config of the chart below:
Chart.defaults.global.defaultFontColor = 'white';
graffic = new Chart(document.getElementById("graffic").getContext('2d'), {
type: 'line',
fill: false,
data: {
labels : date_label,
fill: false,
datasets:data_to_grafic
},
options: {
title: {
position:'top',
display: true,
text: device
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'HRS'
}
}],
yAxes: [{
ticks: {beginAtZero:true},
display: true,
scaleLabel: {
display: true,
labelString: 'BPS'
}
}]
}
}
});
graffic.update();
Solution using chartjs-plugin-annotation (https://github.com/chartjs/chartjs-plugin-annotation)
var date_label = ['8:00', '9:00', '10:00', '11:00', '00:00', '01:00', '02:00', '03:00', '4:00'];
var data_to_grafic = [{
label: "My First dataset",
backgroundColor: '#ddd',
borderColor: '#f00',
fill: false,
data: [0, 0, 15000, 35000, 10000, 36000, 0, 0, 0, 0]
}];
var graffic = new Chart(document.getElementById("graffic").getContext('2d'),{
type: 'line',
data: {
labels: date_label,
fill: false,
datasets: data_to_grafic
},
options: {
title: {
position: 'top',
display: true,
text: 'My Title'
},
annotation: {
annotations: [{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
value: "00:00",
borderColor: "red",
borderWidth: 2
}]
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'HRS'
}
}],
yAxes: [{
ticks: {
beginAtZero: true
},
display: true,
scaleLabel: {
display: true,
labelString: 'BPS'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.5/chartjs-plugin-annotation.js"></script>
<canvas id="graffic"></canvas>

chart.js v2: Align time scale labels with the center of the bars

I am trying to align the generated time scale labels using Chart.js v2.2 with the centre of the bars of a bar chart. I have tried the offsetGridLines option but this seems to have no effect when using Xaxis scale type time.
Here is an example, maybe I have missed something:
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
,
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
min: '2014-12-01' ,
max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
}
}
});
};
</script>
This fiddle may help to place the data label in the center of the bar
https://jsfiddle.net/tea8dhgy/
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
// min: '2014-12-01' ,
// max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
},
animation: {
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(10, "bold", Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'center';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
//var data = dataset.data[index];
var data = dataset.data[index];
console.log(bar);
if (data > 0) {
ctx.fillText(data, bar._model.x, bar._model.base - (bar._model.base - bar._model.y) / 2 - 5);
}
});
});
}
}
}
});
I was able to get a working chart by removing the min and max values set.
Here is the JSFiddle
Was the following image the desired outcome?

Categories