I am working with a custom gauge using chart.js doughnut type and it's working fine. Now I am trying to change the color of each elements of gauge when the theme button is triggered. So, I have created a update function to do the task. But the plugins are updating but inversely. Also, don't know how to get the needleColor plugin path location for changing the needle color dynamically.
Images are linked below:
lightmood-without-trigger
darkmood-without-trigger
lightmood-after-trigger-theme-button-from-night-to-day
darkmood-after-trigger-theme-button-from-day-to-night
HTML
<div class="gauge_container">
<canvas class="gauge" id="gauge"> </canvas>
</div>
<i onclick="changeColor();" class="uil uil-moon change-theme" id="theme-button"
><span class="theme-name">Dark</span>
</i>
CSS
:root {
--hue-color: 5;
--gauge-color: hsl(var(--hue-color), 69%, 61%);
--gauge-color-border: #fff;
}
body.dark-theme {
--gauge-color: #fff;
--gauge-color-border: hsl(var(--hue-color), 30%, 8%);
}
.gauge_container {
width: 250px;
height: 200px;
margin-left: auto;
margin-right: auto;
}
JavaScript
const gaugeStyle = getComputedStyle(document.body);
var gaugeColor = gaugeStyle.getPropertyValue("--gauge-color");
var gaugeColorBorder = gaugeStyle.getPropertyValue("--gauge-color-border");
function changeColor() {
var gaugeColor = gaugeStyle.getPropertyValue("--gauge-color");
var gaugeColorBorder = gaugeStyle.getPropertyValue("--gauge-color-border");
myGauge.options.plugins.tooltip.backgroundColor = gaugeColor;
myGauge.options.plugins.tooltip.bodyColor = gaugeColorBorder;
myGauge.data.datasets[0].borderColor = gaugeColorBorder;
// Don't know how to get the needle color location path
myGauge.update();
}
const gaugeData = {
labels: ["Safe", "Risky", "High Risk"],
datasets: [
{
label: "Gauge",
data: [100, 65, 35],
backgroundColor: [
"rgba(75, 192, 192, 0.8)",
"rgba(255, 206, 86, 0.8)",
"rgba(255, 26, 104, 0.8)",
],
needleValue: 50,
borderColor: gaugeColorBorder,
borderWidth: 1,
cutout: "95%",
circumference: 180,
rotation: 270,
borderRadius: 5,
},
],
};
//gaugeNeedle
const gaugeNeedle = {
id: "gaugeNeedle",
afterDatasetDraw(chart) {
const {
ctx,
data,
chartArea: { width, height },
} = chart;
ctx.save();
const needleValue = data.datasets[0].needleValue;
if (needleValue <= 100) {
var angle = Math.PI + (1 / 200) * needleValue * Math.PI;
} else if (needleValue <= 10000) {
var angle =
Math.PI +
(1 / 200) * 100 * Math.PI +
((1 / 200) * needleValue * Math.PI * 65) / 10000;
} else if (needleValue <= 1000000) {
var angle =
Math.PI +
(1 / 200) * 100 * Math.PI +
((1 / 200) * 10000 * Math.PI * 65) / 10000 +
((1 / 200) * needleValue * Math.PI * 35) / 1000000;
} else {
var angle = 0;
}
const cx = width / 2;
const cy = chart._metasets[0].data[0].y;
//needle
ctx.translate(cx, cy);
ctx.rotate(angle);
ctx.beginPath();
ctx.moveTo(0, -2);
ctx.lineTo(height - ctx.canvas.offsetTop - 130, 0);
ctx.lineTo(0, 2);
ctx.fillStyle = gaugeColor; // Don't how to get this in changeColor function
ctx.fill();
//needle dot
ctx.translate(-cx, -cy);
ctx.beginPath();
ctx.arc(cx, cy, 5, 0, 10);
ctx.fill();
ctx.restore();
//text
ctx.font = "20px Ubuntu";
ctx.fillStyle = gaugeColor;
ctx.fillText(needleValue + " CPM", cx, cy + 50);
ctx.font = "10px Ubuntu";
ctx.fillText(0, 3, cy + 20);
ctx.fillText(100, cx, 50);
ctx.fillText("10k", cx + 115, 115);
ctx.fillText("1M", cx + 118, 205);
ctx.textAlign = "center";
ctx.restore();
},
};
// config
const gaugeConfig = {
type: "doughnut",
data: gaugeData,
options: {
plugins: {
legend: {
display: false,
},
tooltip: {
yAlign: "bottom",
displayColors: false,
callbacks: {
label: function (tooltipItem) {
return tooltipItem.label;
},
},
backgroundColor: gaugeColor,
bodyColor: gaugeColorBorder,
},
},
},
plugins: [gaugeNeedle],
};
// render init block
var myGauge = new Chart(document.getElementById("gauge"), gaugeConfig);