So I tried to make a gradient fill for the ChartJS doughnut chart, but this only works horizontal and not in a circle.
This is the code that I'm using:
var ctx = document.getElementById("chart-area").getContext("2d");
var gradient1 = ctx.createLinearGradient(0, 0, 0, 175);
gradient1.addColorStop(0.0, '#ACE1DB');
gradient1.addColorStop(1.0, '#7FBDB9');
var gradient2 = ctx.createLinearGradient(0, 0, 400, 400);
gradient2.addColorStop(0, '#B5D57B');
gradient2.addColorStop(1, '#98AF6E');
var gradient3 = ctx.createLinearGradient(0, 0, 0, 175);
gradient3.addColorStop(0, '#E36392');
gradient3.addColorStop(1, '#FE92BD');
var gradient4 = ctx.createLinearGradient(0, 0, 0, 175);
gradient4.addColorStop(1, '#FAD35E');
gradient4.addColorStop(0, '#F4AD4F');
/* ADD DATA TO THE DOUGHNUT CHART */
var doughnutData = [
{
value: 80,
color: gradient1,
highlight: "#E6E6E6",
label: "NUTRIENTS"
},
{
value: 20,
color:"#E6F1EE"
},
{
value:50,
color: gradient2,
highlight: "#E6E6E6",
label: "PROTEINE"
},
{
value: 50,
color:"#E6F1EE"
},
{
value: 75,
color: gradient3,
highlight: "#E6E6E6",
label: "FETTE"
},
{
value:25,
color:"#E6F1EE"
},
{
value: 77,
color: gradient4,
highlight: "#E6E6E6",
label: "CARBS"
}
{
value: 23,
color:"#E6F1EE"
},
];
Is it possible to implement the gradient on a radius, as seen on this design?
Thanks!
So I tried to make a gradient fill for the ChartJS doughnut chart, but this only works horizontal and not in a circle.
This is the code that I'm using:
var ctx = document.getElementById("chart-area").getContext("2d");
var gradient1 = ctx.createLinearGradient(0, 0, 0, 175);
gradient1.addColorStop(0.0, '#ACE1DB');
gradient1.addColorStop(1.0, '#7FBDB9');
var gradient2 = ctx.createLinearGradient(0, 0, 400, 400);
gradient2.addColorStop(0, '#B5D57B');
gradient2.addColorStop(1, '#98AF6E');
var gradient3 = ctx.createLinearGradient(0, 0, 0, 175);
gradient3.addColorStop(0, '#E36392');
gradient3.addColorStop(1, '#FE92BD');
var gradient4 = ctx.createLinearGradient(0, 0, 0, 175);
gradient4.addColorStop(1, '#FAD35E');
gradient4.addColorStop(0, '#F4AD4F');
/* ADD DATA TO THE DOUGHNUT CHART */
var doughnutData = [
{
value: 80,
color: gradient1,
highlight: "#E6E6E6",
label: "NUTRIENTS"
},
{
value: 20,
color:"#E6F1EE"
},
{
value:50,
color: gradient2,
highlight: "#E6E6E6",
label: "PROTEINE"
},
{
value: 50,
color:"#E6F1EE"
},
{
value: 75,
color: gradient3,
highlight: "#E6E6E6",
label: "FETTE"
},
{
value:25,
color:"#E6F1EE"
},
{
value: 77,
color: gradient4,
highlight: "#E6E6E6",
label: "CARBS"
}
{
value: 23,
color:"#E6F1EE"
},
];
Is it possible to implement the gradient on a radius, as seen on this design?
Thanks!
Share Improve this question edited May 14, 2015 at 9:39 user1693593 asked May 12, 2015 at 9:11 T.B.T.B. 1131 gold badge1 silver badge5 bronze badges 2- This workaround works, it fills a gradient, but the problem is the angle of the gradient, because it is a circle! – T.B. Commented May 13, 2015 at 9:17
- I've posted an answer with a couple of possible options to create you gradient donut chart. – markE Commented May 13, 2015 at 15:57
3 Answers
Reset to default 11ChartJS will not (properly) use gradient fill colors when drawing a linear gradient on non-linear paths like your donut chart. A linear gradient does not curve.
Possibility #1 -- use a radial gradient
You might experiment with a radial gradient and see if the results meets your design needs.
Possibility #2 -- use a gradient stroke (a DIY project)
Also, canvas's stroke will curve around a circle.
If you want to "roll-your-own" gradient donut chart, here's example code and a Demo that uses a gradient strokeStyle on a circular path (see my previous answer here: Angle gradient in canvas):
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
function drawMultiRadiantCircle(xc, yc, r, radientColors) {
var partLength = (2 * Math.PI) / radientColors.length;
var start = 0;
var gradient = null;
var startColor = null,
endColor = null;
for (var i = 0; i < radientColors.length; i++) {
startColor = radientColors[i];
endColor = radientColors[(i + 1) % radientColors.length];
// x start / end of the next arc to draw
var xStart = xc + Math.cos(start) * r;
var xEnd = xc + Math.cos(start + partLength) * r;
// y start / end of the next arc to draw
var yStart = yc + Math.sin(start) * r;
var yEnd = yc + Math.sin(start + partLength) * r;
ctx.beginPath();
gradient = ctx.createLinearGradient(xStart, yStart, xEnd, yEnd);
gradient.addColorStop(0, startColor);
gradient.addColorStop(1.0, endColor);
ctx.strokeStyle = gradient;
ctx.arc(xc, yc, r, start, start + partLength);
ctx.lineWidth = 30;
ctx.stroke();
ctx.closePath();
start += partLength;
}
}
var someColors = [];
someColors.push('#0F0');
someColors.push('#0FF');
someColors.push('#F00');
someColors.push('#FF0');
someColors.push('#F0F');
drawMultiRadiantCircle(150, 150, 120, someColors);
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
yes What I did on my end is this.
Step 1 - Grab your chart.
@ViewChild('slideDoughnutChart') slideDoughnutChart: BaseChartDirective;
Step 2 - Declare a const gradient and assign it.
const gradient = this.slideDoughnutChart.chart.ctx.createLinearGradient(0, 0, 0, 220);
Step 3 - Push the colors that you wan to see as Gradient.
const colors = [];
for (let i = 0; i < 4; i++) {
gradient.addColorStop(0, 'rgb(37, 77, 180)');
gradient.addColorStop(1, 'rgb(123, 98, 221)');
colors.push(gradient);
}
Here I have pushed the same color.
Step 4 - Set doughnut chart colors variable to colors array.
this.slideDoughnutChartColors = [{ backgroundColor: colors }];
Step 5 - Assign slideDoughnutChartColors variable to colors binding in canvas.
<canvas class="chartjs canvasResponsive" baseChart #slideDoughnutChart="base-chart" [colors]="slideDoughnutChartColors" ></canvas>
If you follow the steps correctly, You will end with this.
For 4 different colors you need to create 4 different variables. For example something like this.
const gradientOne = this.slideDoughnutChart.chart.ctx.createLinearGradient(0, 0, 0, 400);
const gradientTwo = this.slideDoughnutChart.chart.ctx.createLinearGradient(0, 0, 100, 400);
const gradientThree = this.slideDoughnutChart.chart.ctx.createLinearGradient(0, 0, 0, 400);
const gradientFour = this.slideDoughnutChart.chart.ctx.createLinearGradient(0, 0, 0, 400);
then doing something like this.
for (let i = 0; i < this.slideDoughnutChartData.length; i++) {
switch (i) {
case 0:
gradientOne.addColorStop(0, 'rgb(223, 43, 100)');
gradientOne.addColorStop(1, 'rgb(224, 105, 84)');
colors.push(gradientOne);
break;
case 1:
gradientTwo.addColorStop(0, 'rgb(248, 188, 80)');
gradientTwo.addColorStop(1, 'rgb(243, 217, 53)');
colors.push(gradientTwo);
break;
case 2:
gradientThree.addColorStop(0, 'rgb(147, 229, 151)');
gradientThree.addColorStop(1, 'rgb(3, 220, 179)');
colors.push(gradientThree);
break;
case 3:
gradientFour.addColorStop(0, 'rgb(123, 98, 221)');
gradientFour.addColorStop(1, 'rgb(37, 77, 180)');
colors.push(gradientFour);
break;
}
}
will end you up with.
This is my data for the chart.
this.slideDoughnutChartData = [25, 35, 20, 25, 2];
2023 Answer:
I know this question has been asked long ago and have been answered, but I thought it would be beneficial for anyone looking for an updated answer to know that in addition to the standard built-in linear and radial gradients, there is now a third - conical gradient - that does exactly what we're looking for.
Here's the link to the docs.
And a simple example of how it's implemented to achieve the effect in a Chartjs doughnut chart:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Doughnut Chart Example</title>
<!-- Include Chart.js library -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div style="width: 400px; height: 400px;">
<canvas id="myDoughnutChart" width="400" height="400"></canvas>
</div>
<script>
// Data for the doughnut chart
const chartRef = document.getElementById('myDoughnutChart');
let gradient = chartRef.getContext('2d').createConicGradient(0, 200, 200);
gradient.addColorStop(0, "red");
gradient.addColorStop(0.25, "orange");
gradient.addColorStop(0.5, "yellow");
gradient.addColorStop(0.75, "green");
gradient.addColorStop(1, "blue");
const data = {
labels: ['Red-Orange', 'Orange-Yellow', 'Yellow-Green'],
datasets: [{
label: 'My Doughnut Chart',
data: [30, 20, 50],
backgroundColor: gradient,
hoverOffset: 4
}]
};
// Configuration for the doughnut chart
const config = {
type: 'doughnut',
data: data,
};
// Create the chart
const myDoughnutChart = new Chart(
chartRef,
config
);
</script>
</body>
</html>
The above implementation of the gradient to the chart is simply to display its effect. Ideally, the gradient should be applied to each segment separately, but this would require calculating each segment's starting angle.
Hope it helps!