Is there a way to put an image into the legend of a bar chart (chart.js)? - chart.js

A simple stacked bar graph
<head>
<title>Stacked Bar Chart</title>
<script src="Chart.bundle.js"></script>
<script src="utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
chartColors = {
redborder: 'rgba(206, 0, 23, 1)',
darkredborder: 'rgba(206, 0, 23, 0.75)',
lightredborder: 'rgba(206, 0, 23, 0.5)',
};
var barChartData = {
labels: [1<img src='images/badges/Manchester United.png' alt='Manchester United.png' height='30' width='30'>,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],
datasets: [{
label: 'Goals',
backgroundColor: window.chartColors.redborder,
data: [0,1,3,0,2,0,0,2,0,1,0,1,1,0,0,1,0,0,2,1,0,1,2,1,1,0,0,0,2,2,0,3]
}, {
label: 'Assists',
backgroundColor: window.chartColors.darkredborder,
data: [0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1]
}, {
label: 'Indirect',
backgroundColor: window.chartColors.lightredborder,
data: [0,0,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,1,0,1,2,0,0,0,1,0,0,0,0,1]
}]
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
barChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myBar.update();
});
</script>
</body>
</html>
in the x-axis labels, I am trying to get a small icon (image) to be displayed instead of a number. I have tried to put just the image tag in all possible combinations of " and ' as well as with the number. But to no avail. The chart does not render. It seems that the label needs to recognized as a value to render and the html tag knocks this out of place. I don't see why an image tag cannot be put in there, is there a way to do this?

Related

In Chart.js 3.8 (latest release) how to show labels on axis

in Chart.js 3.0 I want to show up the title of x axis.
By reading the documentation at this link
https://www.chartjs.org/docs/latest/axes/labelling.html
I added this code to the options
options: {
scales: {
x: {
display: true,
text: 'Price',
color: 'rgb (12, 70, 14)',
}
}
}
but the labels are not seen, this is the complete code:
<html>
<head>
</head>
<body>
<canvas id="myChart" width="400" height="400"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const labels = [
'1740.00',
'1750.00',
'1760.00',
];
const data = {
labels: labels,
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgb(12, 70, 14)',
borderColor: 'rgb(12, 70, 14)',
data: [444000, 790000, 1550000],
}]
};
const config = {
type: 'line',
data: data,
options: {
scales: {
x: {
display: true,
text: 'Price',
color: 'rgb(12, 70, 14)',
}
}
}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
</script>
</body>
</html>
i found the solution by myself :)
const config = {
type: 'line',
data: data,
options: {
scales: {
x: {
title: {
display: true,
text: 'Date'
},
},
y: {
title: {
display: true,
text: 'value'
}
}
}
}
};

How to align labels at same side chartjs React

Hello i am rendering these charts using chart js but i am unable to align these charts in the same order my config file and options file is given below
can anyone please help me with this. i tried with below options and data
const options = {
indexAxis: "y",
maintainAspectRatio: false,
aspectRatio: 0.8,
barThickness: 20,
responsive: true,
layout: {
padding: {
left: 1
}
},
plugins: {
legend: {
display: false
}
},
scales: {
x: {
ticks: {
color: "#495057"
},
grid: {
color: "#ebedef"
}
},
y: {
ticks: {
color: "#495057",
crossAlign: "near"
},
grid: {
color: "#ebedef"
},
gridLines: {
offsetGridLines: true,
display: true
}
}
}
};
const data = {
labels: ["red"],
datasets: [{
backgroundColor: "#42A5F5",
data: [65],
borderWidth: 2,
borderRadius: 75,
borderSkipped: false
},
{
backgroundColor: "#FFA726",
data: [28],
borderWidth: 2,
borderRadius: 50,
borderSkipped: false
}
]
};
how to align one below the other labels
As far as I know chart.js does not provide an option to set a minimum distance for the labels, a workaround to achieve this is to add spaces the the labels of the charts where the labels are shorter as the longest one so you will get something like this:
var options = {
type: 'bar',
data: {
labels: [" Red"],
datasets: [{
label: '# of Votes',
data: [12],
backgroundColor: 'pink'
}]
},
options: {
indexAxis: 'y'
}
}
var 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.5.0/chart.js"></script>
</body>
var options = {
type: 'bar',
data: {
labels: [" Red"],
datasets: [{
label: '# of Votes',
data: [12],
backgroundColor: 'pink'
}]
},
options: {
indexAxis: 'y'
}
}
var options2 = {
type: 'bar',
data: {
labels: [" Yellowwwww"],
datasets: [{
label: '# of Votes',
data: [12],
backgroundColor: 'pink'
}]
},
options: {
indexAxis: 'y'
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
var ctx2 = document.getElementById('chartJSContainer2').getContext('2d');
new Chart(ctx2, options2);
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<canvas id="chartJSContainer2" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>

Datasets in Chart.js stacked barchart appear overlaid instead of stacked

I'm trying to create a stacked barchart using 2 datasets with Chart.js but I find they overlay instead of stack. Is this because of the known bug with a time series for the x-axis or have I done something wrong?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chart.js test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
</head>
<body>
<div style="width:90%;margin:20px auto">
<canvas id="myChart" width="90%"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["6 Mar","7 Mar","8 Mar","9 Mar","10 Mar","11 Mar","12 Mar","13 Mar","14 Mar","15 Mar","16 Mar","17 Mar","18 Mar","19 Mar","20 Mar","21 Mar","22 Mar","23 Mar","24 Mar","25 Mar","26 Mar","27 Mar","28 Mar","29 Mar","30 Mar","31 Mar","1 Apr","2 Apr","3 Apr","4 Apr","5 Apr","6 Apr","7 Apr","8 Apr","9 Apr","10 Apr","11 Apr","12 Apr","13 Apr","14 Apr","15 Apr","16 Apr","17 Apr","18 Apr","19 Apr","20 Apr","21 Apr","22 Apr","23 Apr","24 Apr","25 Apr","26 Apr","27 Apr","28 Apr","29 Apr","30 Apr","1 May","2 May","3 May","4 May","5 May","6 May","7 May","8 May","9 May","10 May","11 May","12 May","13 May"],
datasets: [
{
label: 'dataset1',
data: [163,43,67,48,61,74,0,342,342,0,403,407,676,63,1294,1035,665,967,1427,1452,2129,2885,2546,2433,2619,3009,4324,4244,4450,3735,5903,3802,3634,5491,4344,8681,5233,5288,4342,5252,4603,4617,5599,5525,5850,4676,4301,4451,4583,5386,4913,4463,4309,3996,4076,6032,6201,4806,4339,3985,4406,6111,5614,4649,3896,3923,3877,3403,3242],
backgroundColor:'rgb(0,102,204,0.8)'
},{
label: 'dataset2',
data: [1,1,0,1,4,0,2,1,18,15,22,16,34,43,36,56,35,74,149,186,183,284,294,214,374,382,670,652,714,760,644,568,1038,1034,1103,1152,839,686,744,1044,842,1029,935,1115,498,559,1172,837,727,1005,843,420,338,909,795,674,739,621,315,288,693,649,539,626,346,268,210,627,494],
backgroundColor:'rgb(204,0,102,1)'
} ]
},
options: {
layout: {
padding: {
left: 10,
right: 10,
top: 10,
bottom: 10
}
},
legend: {
display: true,
position: 'bottom'
},
scales: {
xAxes: [{
display: true,
stacked: true,
scaleLabel: {
display: true,
labelString: 'Date'
},
ticks: {
autoSkip: true,
maxTicksLimit: 20,
maxRotation: 0,
minRotation: 0,
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
}],
yAxes: [{
scaleLabel: {
display: true,
stacked: true,
labelString: 'Number'
},
ticks: {
beginAtZero: true
}
}]
},
title: {
display: true,
text: 'Chart title'
},
responsive: true
}
});
</script>
</div>
</body>
</html>
jsfiddle
Hopefully the above jsfiddle explains the issue pictorially. The barchart shows daily data for two datasets which are supposed to be stacked, but dataset1 overlays dataset2 and therefore obscures dataset2 unless transparency is set for dataset1, and then the colour is not correct because it's a combination of one colour over another.
Simply define your yAxes as stacked also as shown below.
yAxes: [{
stacked: true,
Also try to use the latest stable version of Chart.js (currently v2.9.3)
Please have a look at your amended code.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Chart.js test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
</head>
<body>
<div style="width:90%;margin:20px auto">
<canvas id="myChart" width="90%"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["6 Mar","7 Mar","8 Mar","9 Mar","10 Mar","11 Mar","12 Mar","13 Mar","14 Mar","15 Mar","16 Mar","17 Mar","18 Mar","19 Mar","20 Mar","21 Mar","22 Mar","23 Mar","24 Mar","25 Mar","26 Mar","27 Mar","28 Mar","29 Mar","30 Mar","31 Mar","1 Apr","2 Apr","3 Apr","4 Apr","5 Apr","6 Apr","7 Apr","8 Apr","9 Apr","10 Apr","11 Apr","12 Apr","13 Apr","14 Apr","15 Apr","16 Apr","17 Apr","18 Apr","19 Apr","20 Apr","21 Apr","22 Apr","23 Apr","24 Apr","25 Apr","26 Apr","27 Apr","28 Apr","29 Apr","30 Apr","1 May","2 May","3 May","4 May","5 May","6 May","7 May","8 May","9 May","10 May","11 May","12 May","13 May"],
datasets: [
{
label: 'dataset1',
data: [163,43,67,48,61,74,0,342,342,0,403,407,676,63,1294,1035,665,967,1427,1452,2129,2885,2546,2433,2619,3009,4324,4244,4450,3735,5903,3802,3634,5491,4344,8681,5233,5288,4342,5252,4603,4617,5599,5525,5850,4676,4301,4451,4583,5386,4913,4463,4309,3996,4076,6032,6201,4806,4339,3985,4406,6111,5614,4649,3896,3923,3877,3403,3242],
backgroundColor:'rgb(0,102,204,0.8)'
},{
label: 'dataset2',
data: [1,1,0,1,4,0,2,1,18,15,22,16,34,43,36,56,35,74,149,186,183,284,294,214,374,382,670,652,714,760,644,568,1038,1034,1103,1152,839,686,744,1044,842,1029,935,1115,498,559,1172,837,727,1005,843,420,338,909,795,674,739,621,315,288,693,649,539,626,346,268,210,627,494],
backgroundColor:'rgb(204,0,102,1)'
} ]
},
options: {
layout: {
padding: {
left: 10,
right: 10,
top: 10,
bottom: 10
}
},
legend: {
display: true,
position: 'bottom'
},
scales: {
xAxes: [{
display: true,
stacked: true,
scaleLabel: {
display: true,
labelString: 'Date'
},
ticks: {
autoSkip: true,
maxTicksLimit: 20,
maxRotation: 0,
minRotation: 0,
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
stacked: true,
labelString: 'Number'
},
ticks: {
beginAtZero: true
}
}]
},
title: {
display: true,
text: 'Chart title'
},
responsive: true
}
});
</script>
</div>
</body>
</html>

charts js have a bar spanning negative/positive on y-axis

Is there a way in chartjs to have a bar span across the zero line? As an example,
lets say I have a bar with
data:[x:1, y:100]
How do I tell it to span the y-axis from -100 to 100 (instead of from 0 to 100)?
I have sort of a playground here where I can do either negative or positive per bar, but not both for one bar.
https://jsbin.com/dufonoceja/1/edit?js,output
This can be done since Chart.js v2.9.0, which now supports floating bars. Individual bars can now be specified with the syntax [min, max].
<html>
<head>
<title>Floating Bars</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div>
<canvas id="canvas" height="120"></canvas>
</div>
<script>
var chartData = {
labels: [1,2,3,4,5,6],
datasets: [{
type: 'bar',
label: 'Red Bar',
borderColor: 'black',
borderWidth: 1,
backgroundColor: 'rgba(128,0,0,0.2)',
data: [[0, 100], [-100, 100], [-30, 40], 0, 0, 0],
}, {
type: 'bar',
label: 'Green Bar',
backgroundColor: 'rgba(0,128,0,0.2)',
borderColor: 'black',
borderWidth: 1,
data: [0, 0, 0, 0, [-50, 70], 100],
}
]
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scaleBeginAtZero: false,
responsive: true,
spanGaps: true,
tooltips: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
gridLines: {
display: false
},
}],
yAxes: [{
type: 'linear',
ticks: {
beginAtZero: false,
min:-100,
max:100,
stepSize:30
}
}],
}
}
});
};
</script>
</body>
</html>

Show Dates in x-axis when using chart.js

I am using chart.js library. I am creating a graph and want to show dates in x-axis like here: http://www.chartjs.org/samples/latest/scales/time/line.html
I have provided the same configuration (except the date format of graph data) for graph as the above example provides but my graph showing time i.e 2 am, 2 am, .. instead of dates i.e 2018-02-01, 2018-02-10, ...
For date formatting i am using the moment.js library recommended by Chart.js
I am using following code:
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var timeFormat = 'YYYY-MM-DD';
var config = {
type: 'line',
data: {
datasets: [{
label: "Thi is graph label",
backgroundColor: "rgb(54, 162, 235)",
borderColor: "rgb(255, 159, 64)",
fill: false,
data: [{
x: moment("2010-03-01").format(timeFormat),
y: 0.668525
}, {
x: moment("2010-03-02").format(timeFormat),
y: 0.668827
}],
}]
},
options: {
title: {
text: "This is title"
},
scales: {
xAxes: [{
type: "time",
time: {
parser: timeFormat,
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
},],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
}
};
window.onload = function () {
var ctx = document.getElementById("canvas").getContext("2d");
console.log(config);
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>
<html>
<head>
<title>Line Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var timeFormat = 'MM/DD/YYYY HH:mm';
function newDate(days) {
return moment().add(days, 'd').toDate();
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
labels: [ // Date Objects
newDate(0),
newDate(1),
newDate(2),
newDate(3),
newDate(4),
newDate(5),
newDate(6)
],
datasets: [{
label: 'My First dataset',
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: 'My Second dataset',
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: 'Dataset with point data',
backgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),
borderColor: window.chartColors.green,
fill: false,
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}, {
x: newDateString(7),
y: randomScalingFactor()
}, {
x: newDateString(15),
y: randomScalingFactor()
}],
}]
},
options: {
title: {
text: 'Chart.js Time Scale'
},
scales: {
xAxes: [{
type: 'time',
time: {
format: timeFormat,
// round: 'day'
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj, j) {
if (typeof dataObj === 'object') {
dataObj.y = randomScalingFactor();
} else {
dataset.data[j] = randomScalingFactor();
}
});
});
window.myLine.update();
});
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: newColor,
backgroundColor: color(newColor).alpha(0.5).rgbString(),
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(newDate(config.data.labels.length));
for (var index = 0; index < config.data.datasets.length; ++index) {
if (typeof config.data.datasets[index].data[0] === 'object') {
config.data.datasets[index].data.push({
x: newDate(config.data.datasets[index].data.length),
y: randomScalingFactor(),
});
} else {
config.data.datasets[index].data.push(randomScalingFactor());
}
}
window.myLine.update();
}
});
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
You need to set:
scales: {
xAxes: [
{
.....
ticks: {
source: 'date'
},
}
......
],