My problem is similar to How to show bar labels in legend in Chart.js 2.1.6?
I want to have to same output a pie chart give, but I do not want to create multiple datasets. I managed to do this, but now I can't find how.
Here is my code sample :
var myChart = new Chart(ctx, {
type: type_p,
data: {
labels: ['Lundi','Mardi'],
datasets: [{
data: [50,20],
backgroundColor: color,
borderColor: color,
borderWidth: 1
}]
}
I want the same legend as a pie chart, but with a bar chart:
Is this a way to do this?
To accomplish this, you would have to generate custom labels (using generateLabels() function) based on the labels array of your dataset.
legend: {
labels: {
generateLabels: function(chart) {
var labels = chart.data.labels;
var dataset = chart.data.datasets[0];
var legend = labels.map(function(label, index) {
return {
datasetIndex: 0,
fillStyle: dataset.backgroundColor && dataset.backgroundColor[index],
strokeStyle: dataset.borderColor && dataset.borderColor[index],
lineWidth: dataset.borderWidth,
text: label
}
});
return legend;
}
}
}
add this in your chart options
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var ctx = canvas.getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi'],
datasets: [{
data: [1, 2, 3, 4, 5],
backgroundColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff'],
borderColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff'],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
labels: {
generateLabels: function(chart) {
var labels = chart.data.labels;
var dataset = chart.data.datasets[0];
var legend = labels.map(function(label, index) {
return {
datasetIndex: 0,
fillStyle: dataset.backgroundColor && dataset.backgroundColor[index],
strokeStyle: dataset.borderColor && dataset.borderColor[index],
lineWidth: dataset.borderWidth,
text: label
}
});
return legend;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="canvas"></canvas>
Related
I need to make a chart at the level with a row in the table, are there any tips on how to implement this enter image description here
I need the chart lines to match the row level in the table
and this code draws a separate chart
const diag = () => {
document.getElementById("canvasic").innerHTML = ' ';
document.getElementById("canvasic").innerHTML = '<canvas id="densityChart" className="canav"></canvas>';
densityCanvas = document.getElementById("densityChart");
//remove canvas from container
Chart.defaults.global.defaultFontFamily = "Arial";
Chart.defaults.global.defaultFontSize = 16;
var densityData = {
label: 'CallVol',
data:calloiList1,
backgroundColor: 'rgba(0,128,0, 0.6)',
borderColor: 'rgba(0,128,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var densityData1 = {
label: 'PutVol',
data:calloiList3 ,
backgroundColor: 'rgba(255,0,0, 0.6)',
borderColor: 'rgba(255,0,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var chartOptions = {
scales: {
yAxes: [{
barPercentage: 0.5
}]
},
elements: {
rectangle: {
borderSkipped: 'left',
}
}
};
var barChart = new Chart(densityCanvas, {
type: 'horizontalBar',
data: {
labels: calloiList4,
datasets: [densityData,densityData1],
},
options: chartOptions
}
);
}
enter image description here
I am using chart.js to develop a TreeMap. It works great but the issue is each rectangle only shows the value of the data. I want to add some custom text next to the value. How do I achieve this?
var topTags = [
{tag:'python',num:133269},{tag:'javascript',num:109742},{tag:'java',num:65490},{tag:'c#',num:45445},{tag:'html',num:43767},{tag:'android',num:42657},{tag:'reactjs',num:38844},{tag:'php',num:34381},{tag:'sql',num:29996},{tag:'python',num:29942},{tag:'css',num:29654},{tag:'r',num:28319},{tag:'c++',num:27389},{tag:'node.js',num:25415},{tag:'angular',num:24093},{tag:'pandas',num:23826},{tag:'arrays',num:23075},{tag:'jquery',num:18968},{tag:'mysql',num:18863},{tag:'swift',num:17971},{tag:'ios',num:17600},{tag:'json',num:15589},{tag:'laravel',num:15537},{tag:'flutter',num:15201},{tag:'c',num:15195},{tag:'django',num:14748},{tag:'sql',num:12752},{tag:'reactjs',num:10974},{tag:'excel',num:10962},{tag:'list',num:10726},{tag:'regex',num:10676}
];
var canvas = document.getElementById("treemap");
var ctx = canvas.getContext("2d");
var chart = window.chart = new Chart(ctx, {
type: "treemap",
data: {
datasets: [{
tree: topTags,
key: "num",
groups: ['num'],
spacing: 0.5,
borderWidth: 1.5,
fontColor: "black",
borderColor: "grey"
}]
},
options: {
maintainAspectRatio: false,
legend: { display: false },
tooltips: { enabled: false }
}
});
When running this code, I get the numbers in each rectangle but I need some text to be appended next to the numbers for each rectangle. How do I achieve this?
You can use the formatter options in the labels section:
const options = {
type: 'treemap',
data: {
datasets: [{
label: '# of Votes',
tree: [12, 19, 3, 5, 2, 3],
backgroundColor: 'pink',
labels: {
display: true,
formatter(ctx) {
const data = ctx.chart.data;
return `Custom Text: ${data.datasets[ctx.datasetIndex].tree[ctx.dataIndex]}`;
}
},
}]
},
options: {}
}
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.7.0/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-chart-treemap#2.0.1/dist/chartjs-chart-treemap.js"></script>
</body>
I'm having some issues when trying to update a chart's data using $scope.
I know there's a function to update charts myChart.update(); but I can't get to update the char when I put it in a $scope.
The following code gets the chart's data and then tries to update the chart. The problem comes at $scope.lineChart.update();. It looks like chartjs can't detect any changes.
The following code is executed after triggering a select, so the chart has an initial data and the following code just tries to update it.
This does not work: $scope.lineChart.update();
$scope.getLineChartMaxData().then(function () {
$scope.getLineChartMinData().then(function () {
$scope.lineChart.update();
});
});
The chart function:
$scope.fillLineChart = function () {
console.log("FILLING LINE CHART");
const brandProduct = 'rgba(0,181,233,0.5)'
const brandService = 'rgba(0,173,95,0.5)'
var data1 = $scope.lineChartMaxWeekData;
var data2 = $scope.lineChartMinWeekData;
var maxValue1 = Math.max.apply(null, data1)
var maxValue2 = Math.max.apply(null, data2)
var minValue1 = Math.min.apply(null, data1)
var minValue2 = Math.min.apply(null, data2)
var maxValue;
var minValue;
if (maxValue1 >= maxValue2) {
maxValue = maxValue1;
} else {
maxValue = maxValue2;
}
if (minValue1 >= minValue2) {
minValue = minValue2;
} else {
minValue = minValue1;
}
$scope.minValue = minValue;
$scope.maxValue = maxValue;
var ctx = document.getElementById("recent-rep-chart");
if (ctx) {
ctx.height = 250;
$scope.lineChart = new Chart(ctx, {
type: 'line',
data: {
labels: $scope.lineChartMaxWeekLabels,
datasets: [{
label: 'Valor',
backgroundColor: brandService,
borderColor: 'transparent',
pointHoverBackgroundColor: '#fff',
borderWidth: 0,
data: data1
},
{
label: 'My Second dataset',
backgroundColor: brandProduct,
borderColor: 'transparent',
pointHoverBackgroundColor: '#fff',
borderWidth: 0,
data: data2
}
]
},
options: {
maintainAspectRatio: true,
legend: {
display: false
},
responsive: true,
scales: {
xAxes: [{
gridLines: {
drawOnChartArea: true,
color: '#f2f2f2'
},
ticks: {
fontFamily: "Poppins",
fontSize: 12
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
stepSize: 50,
max: maxValue,
fontFamily: "Poppins",
fontSize: 12
},
gridLines: {
display: true,
color: '#f2f2f2'
}
}]
},
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4,
hoverBorderWidth: 3
}
}
}
});
}
};
UPDATE: $scope.lineChart.destroy(); works well, but I don't want to destroy the chart and build it again because it is built with another sizes.
How do I modify an existing legend in Chart.js?
I've seen complex methods of creating a custom HTML legend (using generateLegend or legendCallback), and a simple method of options.legend.legendText which should accept an array, but saw no change so assumed that was for version 1.
I'm looking to add text to the default legend:
type: 'doughnut',
data: {
datasets: [{
data: series,
}],
labels: labels,
},
options: {
legend: {
legendText = labels.map((label, index) => `${label} - ${series[index]}%`);
}
}
Edit:
I noticed that if the chart was redrawn (e.g. if the browser window is resized) the legend would lose the extra text.
I've modified the approach to work as an inline plugin so that the label object is modified before the legend is drawn.
let labels = ['a', 'b', 'c', 'd'],
series = [4, 2, 1, 3],
myChart = new Chart(document.getElementById('chart'), {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: series,
backgroundColor: ['red', 'blue', 'green', 'orange']
}]
},
options: {
maintainAspectRatio: false
},
plugins: [{
afterLayout: function(chart) {
let total = chart.data.datasets[0].data.reduce((a, b) => {
return a + b;
});
chart.legend.legendItems.forEach(
(label) => {
let value = chart.data.datasets[0].data[label.index];
label.text += ' - ' + (value / total * 100).toFixed(0) + '%'
return label;
}
)
}
}]
});
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="chart"></canvas>
Chart.js 3.xx
I've included a sample for version 3.5 too.
You can alter the legend text by overriding the generateLabels method.
let labels = ['a', 'b', 'c', 'd'],
series = [4, 2, 1, 3],
myChart = new Chart(document.getElementById('chart'), {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: series,
backgroundColor: ['red', 'blue', 'green', 'orange']
}]
},
options: {
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: "bottom",
align: "center",
fontFamily: "Arial",
labels: {
usePointStyle: true,
fontColor: "red",
generateLabels(chart) {
const data = chart.data;
if (data.labels.length && data.datasets.length) {
const {labels: {pointStyle}} = chart.legend.options;
return data.labels.map((label, i) => {
const meta = chart.getDatasetMeta(0);
const style = meta.controller.getStyle(i);
return {
text: 'This is ' + label + ' - ' + chart.data.datasets[0].data[i],
fillStyle: style.backgroundColor,
strokeStyle: style.borderColor,
lineWidth: style.borderWidth,
pointStyle: pointStyle,
hidden: !chart.getDataVisibility(i),
index: i
};
});
}
return [];
}
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="chart"></canvas>
Just wondering if there is any way to set the horizontal bar labels for y-axis using chart.js. Here is how I set up the chart:
<div class="box-body">
<canvas id="chart" style="position: relative; height: 300px;"></canvas>
</div>
Javascript:
var ctx = document.getElementById('chart').getContext("2d");
var options = {
layout: {
padding: {
top: 5,
}
},
responsive: true,
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: {
labels: label,
datasets: [{
data: price,
}]
},
options: options
};
if (chart) chart.destroy();
chart= new Chart(ctx, opt);
chart.update();
As you all can see, the first and third labels are too long and cut off. Is there a way to make the label multi-line?
If you want to have full control over how long labels are broken down across lines you can specify the breaking point by providing labels in a nested array. For example:
var chart = new Chart(ctx, {
...
data: {
labels: [["Label1 Line1:","Label1 Line2"],["Label2 Line1","Label2 Line2"]],
datasets: [{
...
});
You can use the following chart plugin :
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
add this followed by your chart options
ᴜꜱᴀɢᴇ :
add a new line character (\n) to your label, wherever you wish to add a line break.
ᴅᴇᴍᴏ
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Jan\n2017', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'BAR',
data: [1, 2, 3, 4],
backgroundColor: 'rgba(0, 119, 290, 0.7)'
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
}
},
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>