পূর্ববর্তী সমাধান
এটি অর্জনের জন্য আপনি আপনার ডেটাসেটটি কিছুটা পরিবর্তন করতে পারেন:
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>