Related
I've been using ChartJS with PrimeNG, in Angular. Need to make a doughnut chart with i believe one dataset. I need to make it so each value has a different thickness, like this
So far I've tried a lot of things and read a lot of ChartJS documentation on Doughnut charts, but none of the options have helped me.
Here's how I implement my chart in HTML
<p-chart type="doughnut" [data]="donutData" [options]="donutChartOptions" class="h-10 my-4"></p-chart>
And here's the .ts to it
this.donutData = {
labels: ['A', 'B', 'C'],
datasets: [
{
data: [300, 50, 100],
backgroundColor: ['#F36F56', '#FFC300', '#B8A3FF'],
hoverBackgroundColor: ['#F36F56', '#FFC300', '#B8A3FF'],
},
],
};
this.donutChartOptions = {
cutout: 50,
plugins: {
legend: {
display: false,
labels: {
color: '#ebedef',
},
},
},
};
Here you can find the answer of your question: https://github.com/chartjs/Chart.js/issues/6195
I transferred the answer of "ex47" to chart.js 3
I put the constant "data" into the html file just to have less double code, it should better be in the javascript file.
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<script>
const data = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)"
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)"
],
borderWidth: 1
}
]
}
</script>
<style>
#chartWrapper {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<div id="chartWrapper">
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</body>
<script src="myChart.js"></script>
</html>
myChart.js
var thickness = {
id: "thickness",
beforeDraw: function (chart, options) {
let thickness = chart.options.plugins.thickness.thickness;
thickness.forEach((item,index) => {
chart.getDatasetMeta(0).data[index].innerRadius = item[0];
chart.getDatasetMeta(0).data[index].outerRadius = item[1];
});
}
};
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: "doughnut",
plugins: [thickness],
data: data,
options: {
plugins: {
thickness: {
thickness: [[100,130],[80,150],[70,160],[100,130],[100,130],[100,130]],
}
},
}
});
"Spirit04eK"'s solution sets the thickness in descending order of the magnitude of the value
myChart.js
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'doughnut',
plugins: [
{
beforeDraw: function (chart) {
const datasetMeta = chart.getDatasetMeta(0);
const innerRadius = datasetMeta.controller.innerRadius;
const outerRadius = datasetMeta.controller.outerRadius;
const heightOfItem = outerRadius - innerRadius;
const countOfData = chart.getDatasetMeta(0).data.length;
const additionalRadius = Math.floor(heightOfItem / countOfData);
const weightsMap = datasetMeta.data
.map(v => v.circumference)
.sort((a, b) => a - b)
.reduce((a, c, ci) => {
a.set(c, ci + 1);
return a;
}, new Map());
datasetMeta.data.forEach(dataItem => {
const weight = weightsMap.get(dataItem.circumference);
dataItem.outerRadius = innerRadius + additionalRadius * weight;
});
}
}
],
data: data,
options: {
layout: {
padding: 10,
},
plugins: {
legend: false,
datalabels: {
display: false
},
},
maintainAspectRatio: false,
responsive: true,
}
});
I was using a different chart on my site which was causing some issues so we migrated to chartjs. Everything works fine but I have one requirement which I cannot find in chartjs.
In the site I am working on, the user gives an assessment and it shows the graph based on the assessment results.
So in the assessment, there is a question "Are you feeling exacerbation?" If the user selects yes then in the graph it shows an image above that bar like below image.
In the picture you can see "E" above the two bars.
I want to achieve the same in chartjs. Is it possible? If not then can you guys suggest a way to notify the user that they have selected "exacerbation".
Thank you
You can place images on top of individual bars using chartjs-plugin-labels.
Please have a look at the following runnable code snippet:
new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
label: 'My Dataset',
data: [25, 59, 80, 76],
fill: false,
backgroundColor: ['rgba(255, 99, 132, 0.2)', 'rgba(255, 159, 64, 0.2)', 'rgba(255, 205, 86, 0.2)', 'rgba(75, 192, 192, 0.2)'],
borderColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)'],
borderWidth: 1
}]
},
options: {
plugins: {
labels: {
render: 'image',
textMargin: 10,
images: [
{
src: 'https://i.stack.imgur.com/9EMtU.png',
width: 20,
height: 20
},
null,
{
src: 'https://i.stack.imgur.com/9EMtU.png',
width: 20,
height: 20
},
null
]
}
},
layout: {
padding: {
top: 30
}
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
<canvas id="myChart" width="10" height="6"></canvas>
I'm implementing Chart.js into my AngularJS app, and I'm loading the chart data from server API into $scope.chartData that is an array of numbers.
I need to access this variable from Chart.js, and using the script example on their website, I'm not sure how to access the variable. Trying something like:
home.html:
<!-- A bunch of HTML, then -->
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Balance',
data: {{chartData}}, //this is where I need to access the variable
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
What would be the best way (not a work around) to accomplish loading this data into the chart script?
You should use the library angular-chart.js inorder to use with angularjs.
You can assign the data part to the options config.
DEMO
angular.module("app", ["chart.js"])
.controller("ChartCtrl", function($scope) {
$scope.labelsPercent = ['Equipment 1', 'Equipment 2', 'Equipment 3', 'Equipment 4'];
$scope.chartOptionsPercent = {
title: {
display: true,
text: "Downtime Percentage of Equipment",
fontSize: 20
},
legend: {
text: "Hello"
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
id: 'y-axis-1',
type: 'linear',
position: 'left',
ticks: {
min: 0,
max: 100
}
}],
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Name of Equipment'
},
gridLines: {
color: "rgba(0, 0, 0, 0)",
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Percentage of Downtime (%)'
},
gridLines: {
color: "rgba(0, 0, 0, 0)",
}
}]
}
}
$scope.dataPercent = [5, 6, 7, 12];
});
<!DOCTYPE html>
<html>
<head>
<title>radar Chart</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.0.3/angular-chart.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="ChartCtrl" style="width:360px">
<canvas class="chart chart-bar" chart-click="onClick" chart-data="dataPercent" chart-labels="labelsPercent" chart-options="chartOptionsPercent" ></canvas>
</div>
</body>
</html>
I have a pie chart defined like so,
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: data.labels,
datasets: [{
data: data.values,
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 206, 86)',
'rgb(75, 192, 192)',
'rgb(153, 102, 255)',
'rgb(255, 159, 64)',
'rgb(204, 255, 64)',
'rgb(64, 159, 255)',
'rgb(175, 64, 255)'
],
options: {
responsive : true,
}
}],
fontColor : '#FFFFFF'
}
});
how the chart looks,
This however is setting the font color of the labels to black, how can I change this color. Any pointers on this is highly appreciated. Thanks!
You can change the font color of legend's label, in the following way ...
options: {
legend: {
labels: {
fontColor: 'white'
}
},
...
}
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['A', 'B', 'C', 'D', 'E'],
datasets: [{
data: [1, 1, 1, 1, 1],
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 206, 86)',
'rgb(75, 192, 192)',
'rgb(153, 102, 255)'
]
}]
},
options: {
legend: {
labels: {
fontColor: 'white' //set your desired color
}
}
}
});
canvas{background: #222}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
To change label color with Chart.js, you must set the fontColor.
to set the fontColor of the labels by setting the fontColor in the options object property.
for example;
fontColor: "white", // set color
or you can visit the following link : https://thewebdev.info/2022/06/27/how-to-change-label-color-with-chart-js-and-javascript/
Sorry to unbury this but trying any solutions and only this works. create plugin before chart :
Chart.plugins.register({
beforeDraw: function(c) {
c.legend.options.labels.fontColor = 'hsl(0,0%,85%)';
}
});
var chart = new Chart(ctx, {
....
The only solution i found to work for this problem is the following line
Chart.defaults.color = '#fff';
Hope it helps
I'm making a chart with chart.js and I'm trying to figure out how I can change the label/legend styling.
I want to remove the rectangle part and instead use a circle. I've read that you can make your custom legend (using legendCallback), but for the life of me I cannot figure out how to do it. This is how my chart looks now - image.
This is my HTML:
<div class="container">
<canvas id="myChart"></canvas>
</div>
And this is my JS:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Link One',
data: [1, 2, 3, 2, 1, 1.5, 1],
backgroundColor: [
'#D3E4F3'
],
borderColor: [
'#D3E4F3',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: '#333',
}
}
}
});
I'm new to JS in general, so please be as specific as possible with your answers. Thank you so much!
No need to use legendCallback function. You can set usePointStyle = true to turn that rectangle into a circle.
Chart.defaults.global.legend.labels.usePointStyle = true;
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Link One',
data: [1, 2, 3, 2, 1, 1.5, 1],
backgroundColor: [
'#D3E4F3'
],
borderColor: [
'#D3E4F3',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: '#333'
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="container">
<canvas id="myChart"></canvas>
</div>
for angular4-chart.js you could use the options attribute like so:
options = {
legend:{
display: true,
labels: {
usePointStyle: true,
}
}
}
Step 1:
Change options to this:
options: {
legend: {
display: false,
}
}
Step 2:
Append to your canvas this code (just after canvas):
<div id='chartjsLegend' class='chartjsLegend'></div> //Or prepend to show the legend at top, if you append then it will show to bottom.
Step 3:
Generate this legend instead of default with this (just after mychart):
document.getElementById('chartjsLegend').innerHTML = myChart.generateLegend();
Step 4:
Make css so it generates as circle:
.chartjsLegend li span {
display: inline-block;
width: 12px;
height: 12px;
margin-right: 5px;
border-radius: 25px;
}
Step 5:
Change css with what ever you feel like should be better.
Time for some chimichangas now.
Use usePointStyle:true
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Link One',
data: [1, 2, 3, 2, 1, 1.5, 1],
backgroundColor: [
'#D3E4F3'
],
borderColor: [
'#D3E4F3',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: '#333',
usePointStyle:true
}
}
}
});
Additional information on #GRUNT 's answer
I assign usePointStyle inside legend.labels not what #GRUNT did Chart.defaults.global.legend.labels.usePointStyle = true;
This is useful when you are using react
legend: {
labels: {
usePointStyle: true,
},
}
more info here
Display point style on legend in chart.js
add this in your options
legend: {
display: true,
position: 'bottom',
labels: {
boxWidth: 9,
fontColor: '#474747',
fontFamily: '6px Montserrat',
},
},
for example :
this.testChart = new Chart('testPie', {
type: 'doughnut',
data: {
labels: [ 'Success','Failure','Aborted'],
datasets: [
{
data: [],
backgroundColor: [ '#45D78F', '#F58220','#FFD403'],
},
],
},
options: {
maintainAspectRatio: false,
cutoutPercentage: 50, // for thikness of doughnut
title: {
display: false,
text: 'Runs',
fontSize: 14,
fontFamily: 'Roboto',
fontColor: '#474747',
},
legend: {
display: true,
position: 'bottom',
labels: {
boxWidth: 9,
fontColor: '#474747',
fontFamily: '6px Montserrat',
},
},
},
});