Javascript Canvas labels too long - javascript

When I use small version numbers (the label), my canvas is shown as it should:
But when my labels get too long it starts to look very unreadable, and I don't know how to avoid this?:
Can I change my options to solve this, if yes, how?
Here is my javascript function, and nameArray is the array with version numbers, and I have to shorten these somehow.
function renderBarChart(nameArray, passArray, failArray, divId, title) {
var ctx = document.getElementById(divId).getContext('2d');
var newChart = new Chart(ctx, {
type: 'bar',
data: {
labels: nameArray,
datasets: [{
label: 'Passed',
data: passArray,
backgroundColor: 'rgb(150,238,144)'
},
{
label: 'Failed',
data: failArray,
backgroundColor: 'rgb(204,0,0)'
}
]
},
options: {
title: {
display: true,
text: title
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
responsive: false,
maintainAspectRatio: false,
scales: {
xAxes: [{
stacked: true,
ticks: {
stepSize: 1,
min: 0,
autoSkip: false
}
}],
yAxes: [{
stacked: true,
ticks: {
maxTicksLimit: 5,
min: 0
}
}]
}
}
});
}
EDIT 1
Right now I'm trying to do something like this, but I can't make it work.
Inspiration form: How to shorten Chart.js label
function renderBarChart(nameArray, passArray, failArray, divId, title) {
var ctx = document.getElementById(divId).getContext('2d');
var newChart = new Chart(ctx, {
type: 'bar',
data: {
labels: nameArray,
datasets: [{
label: 'Passed',
data: passArray,
backgroundColor: 'rgb(150,238,144)'
},
{
label: 'Failed',
data: failArray,
backgroundColor: 'rgb(204,0,0)'
}
]
},
options: {
title: {
display: true,
text: title
},
tooltips: {
enabled: true,
mode: 'label',
callbacks: {
title: function(tooltipItems, data) {
var idx = tooltipItems[0].index;
return 'Title:' + data.labels[idx]; //do something with title
},
label: function(tooltipItems, data) {
//var idx = tooltipItems.index;
//return data.labels[idx] + ' €';
return tooltipItems.xLabel + ' €';
}
}
},
hover: {
mode: 'nearest',
intersect: true
},
responsive: false,
maintainAspectRatio: false,
scales: {
xAxes: [{
stacked: true,
ticks: {
stepSize: 1,
min: 0,
autoSkip: false,
callback: function(value) {
if (value.length > 4) {
return value.substr(0, 4) + '...'; //truncate
} else {
return value
}
},
}
}],
yAxes: [{
stacked: true,
ticks: {
maxTicksLimit: 5,
min: 0
}
}]
}
}
});
}

Related

How to add a toggle inside a title of the barchart js

I have this barchart created in the ChartJS last version.
I want to add a toggle button inside the barchart title, as shown in this picture: https://i.stack.imgur.com/1KMyB.png
This is my barchart code:
var ctx = document.getElementById("myBarChart");
var myBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: "Valor",
backgroundColor: "rgba(2,117,216,1)",
borderColor: "rgba(2,117,216,1)",
data: [],
}],
},
options: {
plugins: {
datalabels: {
anchor: 'end',
align: 'top',
formatter: function (value, context) {
if (value != 0) {
return new Date(value * 1000).toISOString().substr(11, 8);
} else {
value = " "
return value;
}
},
font: {
weight: 'bold'
}
}
},
responsive: true,
tooltips: {
/* intersect: false, */
callbacks: {
title: function (tooltipItem, data) {
return data['labels'][tooltipItem[0]['index']];
},
label: function (tooltipItem, data) {
return new Date(parseInt(data['datasets'][0]['data'][tooltipItem[
'index']]) * 1000).toISOString().substr(11,
8);
},
},
},
scales: {
xAxes: [{
time: {
unit: 'month'
},
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
min: 0,
suggestedMax: 36000,
stepSize: 3600,
beginAtZero: true,
},
}],
},
}
});
Is it something possible to do?
If someone know how to do this in the last version of the chartjs, please help me.                                                                  
                                               
You can make use of the core plugin API to write a custom plugin that does it. The better and easyer option to to not use the title of chart.js and put a div above your chart and put your title and the toggle in that div with HTML

ChartJS How to set color to just one bar

I have this barChart and I'm with difficult to set a color by script to just one bar of the index.
Bellow is my chartbar code:
var ctx = document.getElementById("myBarChart");
var myBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: "Valor",
backgroundColor: "rgba(2,117,216,1)",
borderColor: "rgba(2,117,216,1)",
data: [],
}],
},
options: {
plugins: {
datalabels: {
anchor: 'end',
align: 'top',
formatter: function (value, context) {
if (value != 0) {
return new Date(value * 1000).toISOString().substr(11, 8);
} else {
value = " "
return value;
}
},
font: {
weight: 'bold'
}
}
},
responsive: true,
tooltips: {
/* intersect: false, */
callbacks: {
title: function (tooltipItem, data) {
return data['labels'][tooltipItem[0]['index']];
},
label: function (tooltipItem, data) {
return new Date(parseInt(data['datasets'][0]['data'][tooltipItem[
'index']]) * 1000).toISOString().substr(11,
8);
},
},
},
scales: {
xAxes: [{
time: {
unit: 'month'
},
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
min: 0,
suggestedMax: 36000,
stepSize: 3600,
beginAtZero: true,
},
}],
},
}
});
I have tried this:
myBarChart.data.datasets[0].backgroundColor[0]
But it doesnt work.
If someone know how to do this in the last version of the chartjs, please help me.
You can provide an array to the backgroundColor property. In this array you can fill it with the default color except for the index where you want the bar to be a different collor

Removing little gap on left side Chart JS

I don't know how to remove space on left side which you can see on the image. I tried things like aspectRatio: 1 but doesn't work.
Here's the current config
const config = {
type: "line",
data: dataSets,
options: {
responsive: false,
maintainAspectRatio: false,
elements: {
point: { radius: 0 },
line: {
tension: 0,
},
},
scales: {
xAxes: [{
type: "time",
time: {
unit: "day",
},
ticks: {
display: false,
},
gridLines: {
tickMarkLength: 1,
color: "#d8d8d8",
zeroLineColor: "#d8d8d8",
},
}],
yAxes: [{
ticks: {
display: false,
},
}],
},
legend: {
display: false,
},
},
};

White Space in stacked bar using chart.js

I'm using chart.js version 2.7.2 to plot some charts.
The chart is a bar chart, and i'm using a time axis to set the dataset points.
If i use a normal graph the dataset is showed correctly, but if i set the stacked axis, at the first item the render show a strange white space!
Look at the charts, with stacked:false its all ok, with stacked:true there's a strange white space at the first bar!
Is there a way to remove that white space?
Thanks
function newDate(days) {
return moment().add(days, 'd').toDate();
}
const lineData = {
labels: null,
datasets:
[
{
label: 'A',
fill: false,
backgroundColor: "hsl(50, 50%, 80%)",
data:
[
{
x: newDate(1),
y: 12
},
{
x: newDate(2),
y: 15
},
],
},
{
label: 'B',
fill: false,
backgroundColor: "hsl(250, 50%, 80%)",
data:
[
{
x: newDate(0),
y: 23
},
{
x: newDate(2),
y: 34
},
{
x: newDate(3),
y: 45
},
]
}
],
}
const lineOptions = {
type: 'bar',
data: lineData,
options:
{
title:
{
display: true,
text: 'STACKED TRUE'
},
legend:
{
display: true,
},
hover:
{
mode: 'nearest'
},
fill: false,
responsive: true,
scales:
{
xAxes:
[
{
stacked: true,
display: true,
ticks:
{
beginAtZero: false,
},
scaleLabel:
{
display: true,
labelString: "Day",
},
barThickness: 15,
type: 'time',
distribution: 'linear',
bounds: 'ticks',
time:
{
unit: 'day',
unitStepSize: 1,
displayFormats:
{
'day': 'DD/MM',
},
tooltipFormat: 'DD/MM',
}
}
],
yAxes:
[
{
ticks:
{
beginAtZero: true,
},
display: true,
stacked: true,
scaleLabel:
{
display: true,
labelString: "Items",
}
}
]
},
tooltips:
{
mode: 'x',
},
}
}
const chart = new Chart(document.getElementById("chart").getContext("2d"), lineOptions);
const lineOptions2 = {
type: 'bar',
data: lineData,
options:
{
title:
{
display: true,
text: 'STACKED FALSE'
},
legend:
{
display: true
},
hover:
{
mode: 'nearest'
},
fill: false,
responsive: true,
scales:
{
xAxes:
[
{
//stacked: true,
display: true,
ticks:
{
beginAtZero: false,
},
scaleLabel:
{
display: true,
labelString: "Day",
},
barThickness: 15,
type: 'time',
distribution: 'linear',
bounds: 'ticks',
time:
{
unit: 'day',
unitStepSize: 1,
displayFormats:
{
'day': 'DD/MM',
},
tooltipFormat: 'DD/MM',
}
}
],
yAxes:
[
{
ticks:
{
beginAtZero: true,
},
display: true,
//stacked: true,
scaleLabel:
{
display: true,
labelString: "Items",
}
}
]
},
tooltips:
{
mode: 'x',
},
}
}
const chart2 = new Chart(document.getElementById("chart2").getContext("2d"), lineOptions2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<body>
<canvas id="chart" width="600" height="400"></canvas>
<canvas id="chart2" width="600" height="400"></canvas>
</body>
https://jsfiddle.net/tgfy6q82/42/
You have both xAxes and yAxes set to stacked:true.
Commenting out stacked:true on the yAxes will do the trick;
function newDate(days) {
return moment().add(days, 'd').toDate();
}
const lineData = {
labels: null,
datasets: [{
label: 'A',
fill: false,
backgroundColor: "hsl(50, 50%, 80%)",
data: [{
x: newDate(1),
y: 12
},
{
x: newDate(2),
y: 15
},
],
},
{
label: 'B',
fill: false,
backgroundColor: "hsl(250, 50%, 80%)",
data: [{
x: newDate(0),
y: 23
},
{
x: newDate(2),
y: 34
},
{
x: newDate(3),
y: 45
},
]
}
],
}
const lineOptions = {
type: 'bar',
data: lineData,
options: {
title: {
display: true,
text: 'STACKED TRUE'
},
legend: {
display: true,
},
hover: {
mode: 'nearest'
},
fill: false,
responsive: true,
scales: {
xAxes: [{
stacked: true,
display: true,
ticks: {
beginAtZero: false,
},
scaleLabel: {
display: true,
labelString: "Day",
},
barThickness: 15,
type: 'time',
distribution: 'linear',
bounds: 'ticks',
time: {
unit: 'day',
unitStepSize: 1,
displayFormats: {
'day': 'DD/MM',
},
tooltipFormat: 'DD/MM',
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
},
display: true,
// stacked: true,
scaleLabel: {
display: true,
labelString: "Items",
}
}]
},
tooltips: {
mode: 'x',
},
}
}
const chart = new Chart(document.getElementById("chart").getContext("2d"), lineOptions);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<body>
<canvas id="chart" width="600" height="400"></canvas>
</body>
Alternatively, since setting yAxes stacked:true should be intended, data can be updated such that there exists data for A and B, even if one of them is 0. https://jsfiddle.net/zqrp0w76/2/

Chart.js stacked bar chart in opposite direction

I am trying to achieve something like this using chart.js. I wanted to show data of male/female according to each age group:
Here is my chart options:
var options = {
layout: {
padding: {
top: 5,
}
},
scales:
{
yAxes: [{
display: true,
barPercentage: 0.4,
ticks: {
fontSize: 12
},
stacked: true,
}],
xAxes: [{
stacked: true,
}]
},
responsive: true,
maintainAspectRatio: false,
legend: {
display: false,
},
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: {
labels: ageGroup,
datasets: [{
label: 'Male',
data: maleData,
backgroundColor: '#2196F3',
hoverBackgroundColor: '#2196F3'
},
{
label: 'Female',
data: femaleData,
backgroundColor: '#E91E63',
hoverBackgroundColor: '#E91E63'
}]
},
options: options
};
I changed the positive in femaleData array into a negative number to achieve the result above:
for (var i = 0; i < femaleData.length; i++) {
femaleData[i] = -Math.abs(femaleData[i]);
}
However, the y-axis at 0 is not centralized as it pushed to the right hand side since left hand side got more data. I not even sure if this is the correct way to set the chart in opposite direction. How can I do this correctly?
as per the requirements mentioned in OP­'s comment section
ꜱʜᴏᴡ ᴘᴏꜱɪᴛɪᴠᴇ ᴠᴀʟᴜᴇꜱ ᴏɴ x-ᴀxɪꜱ
use the following callback function for x-axis ticks :
callback: function(t, i) {
return t < 0 ? Math.abs(t) : t;
}
ꜱʜᴏᴡ ᴘᴏꜱɪᴛɪᴠᴇ ᴠᴀʟᴜᴇ ᴏɴ ᴛᴏᴏʟᴛɪᴘ
use the following callback function for tooltips :
callbacks: {
label: function(t, d) {
var datasetLabel = d.datasets[t.datasetIndex].label;
var xLabel = Math.abs(t.xLabel);
return datasetLabel + ': ' + xLabel;
}
}
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var ageGroup = ['0-10', '11-20', '21-30', '31-40', '41-50', '51-60', '61-70', '71-80', '80+'];
var maleData = [30, 0, 0, 0, 10, 0, 0, 0, 0];
var femaleData = [0, 0, 0, -20, -50, -20, 0, 0, 0];
var options = {
layout: {
padding: {
top: 5,
}
},
scales: {
yAxes: [{
display: true,
barPercentage: 0.4,
ticks: {
fontSize: 12
},
stacked: true,
}],
xAxes: [{
stacked: true,
ticks: {
callback: function(t, i) {
return t < 0 ? Math.abs(t) : t;
}
}
}]
},
tooltips: {
callbacks: {
label: function(t, d) {
var datasetLabel = d.datasets[t.datasetIndex].label;
var xLabel = Math.abs(t.xLabel);
return datasetLabel + ': ' + xLabel;
}
}
},
responsive: true,
//maintainAspectRatio: false,
legend: {
display: false,
},
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: {
labels: ageGroup,
datasets: [{
label: 'Male',
data: maleData,
backgroundColor: '#2196F3',
hoverBackgroundColor: '#2196F3'
}, {
label: 'Female',
data: femaleData,
backgroundColor: '#E91E63',
hoverBackgroundColor: '#E91E63'
}]
},
options: options
};
new Chart(ctx, opt);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>

Categories

Resources