पिछला समाधान
इसे प्राप्त करने के लिए आप अपने डेटासेट को थोड़ा बदल सकते हैं:
backgroundColor: ["green", "green", "green", "yellow", "yellow", "yellow", "yellow", "red", "red", "red"],
gaugeLimits: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
चूंकि आपकी वर्तमान gagueLimits
में एक श्रेणी में विभाजित है 20
, इसलिए आप 30 की सीमा तक नहीं पहुंच सकते हैं,
इसलिए, मैंने यहां क्या किया, इसकी guageLimits
एक विभाजित सीमा तक विस्तृत है 10
और अब 30
सुलभ है, इसलिए 70
,
अब रंगों के बारे में, आपके प्रत्येक guageLimits
को backgroundColor
सरणी में एक रंग की आवश्यकता होती है , मैं उन्हें तदनुसार सेट करता हूं, उपरोक्त सरणी की जांच करता हूं। चूंकि संबंधित रंगों में से कोई भी खाली नहीं हो सकता, इसलिए आपको अगले रंग रेंज तक पहुंचने तक उसी रंग का उपयोग करने की आवश्यकता हो सकती है।
अद्यतन समाधान
अब आपकी आवश्यकताएँ साफ़ हो गई हैं:
- आप चाहते हैं कि गेज लेबल बहुत अधिक आरामदायक न हों, यही कारण है कि 20 की सीमा।
- और आप रंग रेंज को 30 और 70 अंक तक अलग करना चाहते हैं।
अब, तकनीकी रूप से यदि आप किसी विशिष्ट बिंदु पर रंग श्रेणी सेट करना चाहते हैं, तो आपको उस मान को gaugeLimits
सरणी पर रखना होगा , इसलिए आपका कम किया गया gaugeLimits
सरणी अब इस तरह हो जाएगा:
gaugeLimits: [0, 20, 30, 40, 60, 70, 80, 100],
ठीक है, नहीं, आप अपने अनुसार रंग सेट कर सकते हैं क्योंकि आपके पास सरणी में निर्दिष्ट बिंदु हैं। इसलिए, backgroundColor
सरणी है:
backgroundColor: ["#0fdc63", "#0fdc63", "#fd9704", "#fd9704", "#fd9704", "#ff7143", "#ff7143"]
अब, अंतिम चाल
आपको अभी भी 30 को छिपाने की आवश्यकता है, और पैमाने से 70, मैंने showMarkers
आपके कोड में टॉगल करने की कोशिश की , ऐसा लगता है कि यह या तो दृश्य संख्या पैमाने को पूरी तरह से सक्षम या अक्षम करता है, मैंने स्ट्रिंग की एक सरणी प्रदान करने की कोशिश की, लेकिन यह केवल स्वीकार करता हैboolean
Chartjs-tsgauge उपलब्ध विकल्पों के बारे में बहुत अधिक दस्तावेज प्रदान नहीं करता है, इसलिए मैंने कोड में झांका और पायाmarkerFormatFn
यह एक फ़ंक्शन को एक पैरामीटर के रूप में लेता है और आप अपने प्रत्येक मार्कर आइटम के साथ क्या करना है, यह बताते हुए एक फ़ंक्शन प्रदान कर सकते हैं।
इसलिए, मैं एक विचार प्रदान करने के लिए एक फ़ंक्शन प्रदान करने के लिए केवल उन संख्याओं को दिखाने के लिए जो बिना किसी शेष के 20 से विभाजित करने योग्य हैं, अन्यथा खाली स्ट्रिंग लौटें, यहां यह है:
markerFormatFn: n => n % 20 === 0 ? n.toString() : '',
स्निपेट जांचें:
//Gauge Plugin
(function() {
if (!window.Chart) {
return;
}
function GaugeChartHelper() {}
GaugeChartHelper.prototype.setup = function(chart, config) {
this.chart = chart;
this.ctx = chart.ctx;
this.limits = config.data.datasets[0].gaugeLimits;
this.data = config.data.datasets[0].gaugeData;
var options = chart.options;
this.fontSize = options.defaultFontSize;
this.fontStyle = options.defaultFontFamily;
this.fontColor = options.defaultFontColor;
this.ctx.textBaseline = "alphabetic";
this.arrowAngle = 25 * Math.PI / 180;
this.arrowColor = config.options.indicatorColor || options.arrowColor;
this.showMarkers =
typeof config.options.showMarkers === "undefined" ?
true :
config.options.showMarkers;
if (config.options.markerFormatFn) {
this.markerFormatFn = config.options.markerFormatFn;
} else {
this.markerFormatFn = function(value) {
return value;
};
}
};
GaugeChartHelper.prototype.applyGaugeConfig = function(chartConfig) {
this.calcLimits();
chartConfig.data.datasets[0].data = this.doughnutData;
var ctx = this.ctx;
var labelsWidth = this.limits.map(
function(label) {
var text = this.markerFormatFn(label);
return ctx.measureText(text).width;
}.bind(this)
);
var padding = Math.max.apply(this, labelsWidth) + this.chart.width / 35;
var heightRatio = this.chart.height / 50;
chartConfig.options.layout.padding = {
top: this.fontSize + heightRatio,
left: padding,
right: padding,
bottom: heightRatio * 2
};
};
GaugeChartHelper.prototype.calcLimits = function() {
var limits = this.limits;
var data = [];
var total = 0;
for (var i = 1, ln = limits.length; i < ln; i++) {
var dataValue = Math.abs(limits[i] - limits[i - 1]);
total += dataValue;
data.push(dataValue);
}
this.doughnutData = data;
var minValue = limits[0];
var maxValue = limits[limits.length - 1];
this.isRevers = minValue > maxValue;
this.minValue = this.isRevers ? maxValue : minValue;
this.totalValue = total;
};
GaugeChartHelper.prototype.updateGaugeDimensions = function() {
var chartArea = this.chart.chartArea;
this.gaugeRadius = this.chart.innerRadius;
this.gaugeCenterX = (chartArea.left + chartArea.right) / 2;
this.gaugeCenterY =
(chartArea.top + chartArea.bottom + this.chart.outerRadius) / 2;
this.arrowLength = this.chart.radiusLength * 2;
};
GaugeChartHelper.prototype.getCoordOnCircle = function(r, alpha) {
return {
x: r * Math.cos(alpha),
y: r * Math.sin(alpha)
};
};
GaugeChartHelper.prototype.getAngleOfValue = function(value) {
var result = 0;
var gaugeValue = value - this.minValue;
if (gaugeValue <= 0) {
result = 0;
} else if (gaugeValue >= this.totalValue) {
result = Math.PI;
} else {
result = Math.PI * gaugeValue / this.totalValue;
}
if (this.isRevers) {
return Math.PI - result;
} else {
return result;
}
};
GaugeChartHelper.prototype.renderLimitLabel = function(value) {
var ctx = this.ctx;
var angle = this.getAngleOfValue(value);
var coord = this.getCoordOnCircle(
this.chart.outerRadius + this.chart.radiusLength / 2,
angle
);
var align;
var diff = angle - Math.PI / 2;
if (diff > 0) {
align = "left";
} else if (diff < 0) {
align = "right";
} else {
align = "center";
}
ctx.textAlign = align;
ctx.font = this.fontSize + "px " + this.fontStyle;
ctx.fillStyle = this.fontColor;
var text = this.markerFormatFn(value);
ctx.fillText(
text,
this.gaugeCenterX - coord.x,
this.gaugeCenterY - coord.y
);
};
GaugeChartHelper.prototype.renderLimits = function() {
for (var i = 0, ln = this.limits.length; i < ln; i++) {
this.renderLimitLabel(this.limits[i]);
}
};
GaugeChartHelper.prototype.renderValueLabel = function() {
var label = this.data.value.toString();
var ctx = this.ctx;
ctx.font = "30px " + this.fontStyle;
var stringWidth = ctx.measureText(label).width;
var elementWidth = 0.75 * this.gaugeRadius * 2;
var widthRatio = elementWidth / stringWidth;
var newFontSize = Math.floor(30 * widthRatio);
var fontSizeToUse = Math.min(newFontSize, this.gaugeRadius);
ctx.textAlign = "center";
ctx.font = fontSizeToUse + "px " + this.fontStyle;
ctx.fillStyle = this.data.valueColor || this.fontColor;
ctx.fillText(label, this.gaugeCenterX, this.gaugeCenterY);
};
GaugeChartHelper.prototype.renderValueArrow = function(value) {
var angle = this.getAngleOfValue(
typeof value === "number" ? value : this.data.value
);
this.ctx.globalCompositeOperation = "source-over";
this.renderArrow(
this.gaugeRadius,
angle,
this.arrowLength,
this.arrowAngle,
this.arrowColor
);
};
GaugeChartHelper.prototype.renderSmallValueArrow = function(value) {
var angle = this.getAngleOfValue(value);
this.ctx.globalCompositeOperation = "source-over";
this.renderArrow(
this.gaugeRadius - 1,
angle,
this.arrowLength - 1,
this.arrowAngle,
this.arrowColor
);
};
GaugeChartHelper.prototype.clearValueArrow = function(value) {
var angle = this.getAngleOfValue(value);
this.ctx.lineWidth = 2;
this.ctx.globalCompositeOperation = "destination-out";
this.renderArrow(
this.gaugeRadius - 1,
angle,
this.arrowLength + 1,
this.arrowAngle,
"#FFFFFF"
);
this.ctx.stroke();
};
GaugeChartHelper.prototype.renderArrow = function(
radius,
angle,
arrowLength,
arrowAngle,
arrowColor
) {
var coord = this.getCoordOnCircle(radius, angle);
var arrowPoint = {
x: this.gaugeCenterX - coord.x,
y: this.gaugeCenterY - coord.y
};
var ctx = this.ctx;
ctx.fillStyle = arrowColor;
ctx.beginPath();
ctx.moveTo(arrowPoint.x, arrowPoint.y);
coord = this.getCoordOnCircle(arrowLength, angle + arrowAngle);
ctx.lineTo(arrowPoint.x + coord.x, arrowPoint.y + coord.y);
coord = this.getCoordOnCircle(arrowLength, angle - arrowAngle);
ctx.lineTo(arrowPoint.x + coord.x, arrowPoint.y + coord.y);
ctx.closePath();
ctx.fill();
};
GaugeChartHelper.prototype.animateArrow = function() {
var stepCount = 30;
var animateTimeout = 300;
var gaugeValue = this.data.value - this.minValue;
var step = gaugeValue / stepCount;
var i = 0;
var currentValue = this.minValue;
var interval = setInterval(
function() {
i++;
this.clearValueArrow(currentValue);
if (i > stepCount) {
clearInterval(interval);
this.renderValueArrow();
} else {
currentValue += step;
this.renderSmallValueArrow(currentValue);
}
}.bind(this),
animateTimeout / stepCount
);
};
Chart.defaults.tsgauge = {
animation: {
animateRotate: true,
animateScale: false
},
cutoutPercentage: 95,
rotation: Math.PI,
circumference: Math.PI,
legend: {
display: false
},
scales: {},
arrowColor: "#444"
};
Chart.controllers.tsgauge = Chart.controllers.doughnut.extend({
initialize: function(chart) {
var gaugeHelper = (this.gaugeHelper = new GaugeChartHelper());
gaugeHelper.setup(chart, chart.config);
gaugeHelper.applyGaugeConfig(chart.config);
chart.config.options.animation.onComplete = function(chartElement) {
gaugeHelper.updateGaugeDimensions();
gaugeHelper.animateArrow();
};
Chart.controllers.doughnut.prototype.initialize.apply(this, arguments);
},
draw: function() {
Chart.controllers.doughnut.prototype.draw.apply(this, arguments);
var gaugeHelper = this.gaugeHelper;
gaugeHelper.updateGaugeDimensions();
gaugeHelper.renderValueLabel();
if (gaugeHelper.showMarkers) {
gaugeHelper.renderLimits();
}
gaugeHelper.renderSmallValueArrow(gaugeHelper.minValue);
}
});
})();
//Chart setup
var ctx = document.getElementById("chart3").getContext("2d");
new Chart(ctx, {
type: "tsgauge",
data: {
datasets: [{
backgroundColor: ["#0fdc63", "#0fdc63", "#fd9704", "#fd9704", "#fd9704", "#ff7143", "#ff7143"],
borderWidth: 0,
gaugeData: {
value: 50,
valueColor: "#ff7143"
},
gaugeLimits: [0, 20, 30, 40, 60, 70, 80, 100],
}]
},
options: {
events: [],
showMarkers: true,
markerFormatFn: n => n % 20 === 0 ? n.toString() : '',
}
});
.gauge {
width: 500px;
height: 400px;
}
<link href="https://cdn.jsdelivr.net/npm/chart.js@2.9.2/dist/Chart.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.2/dist/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="gauge">
<canvas id="chart3"></canvas>
</div>