如何解决ChartJS-甜甜圈段自定义大小
我正在构建一个生成速度表的React组件,我想设置每个段的长度(即红色-30%,黄色-30%,绿色-30%和灰色-10%)。>
我正在使用React-ChartJS-2和动画的onComplete,我正在绘制文本和针。
我已经检查了文档,没有设置每一段的长度或宽度的内容。在理想的情况下,针头会变成绿色...是的,我们的数字允许100%以上
任何人都知道如何执行此操作,我可以绑定一个插件或回调函数,使我可以自定义如何绘制每个段?
<Box>
<Box style={{ position: 'relative',paddingLeft: theme.spacing(1.25),height: 300 }}>
<Doughnut
ref={chartRef}
data={{
labels: labels ?? data,datasets: [
{
data: data,// Use backgroundColor if available or generate colors based on number of data points
backgroundColor: backgroundColor ?? generateColorArray(20,360,data.length),borderWidth: 0
}
]
}}
options={{
legend: {
display: false,position: 'top',fullWidth: true
},layout: {
padding: {
top: 50,left: 25,right: 25,bottom: 25
}
},rotation: 1 * Math.PI,circumference: Math.PI,cutoutPercentage: 70,animation: {
duration: 500,easing: 'easeOutQuart',onComplete: function(e): void {
drawNeedle(e.chart.innerRadius,e.chart.outerRadius);
drawText(`${needleValue.toString()}%`,e.chart.innerRadius,e.chart.outerRadius);
},onProgress: function(e): void {
console.log('e: ',e);
}
},tooltips: {
enabled: false
},// Disable other events from firing which causes the chart elements to get pushed down onHover
events: []
}}
/>
</Box>
</Box>
const drawNeedle = (innerRadius: number,outerRadius: number): void => {
const chart = chartRef.current as Doughnut;
const ctx = chart.chartInstance.ctx;
const maxValue = 180;
if (ctx) {
const rotation = -Math.PI;
const circumference = Math.PI;
const origin = rotation + circumference * (0 / maxValue);
const target = rotation + circumference * (((needleValue / 100) * 180) / maxValue);
const angle = origin + (target - origin) * 1;
const chartArea = chart.chartInstance.chartArea;
const width = chartArea.right - chartArea.left;
const needleRadius = (2 / 100) * width;
const needleWidth = (3.2 / 100) * width;
const needleLength = (20 / 100) * (outerRadius - innerRadius) + innerRadius;
const cw = ctx.canvas.offsetWidth;
const ch = ctx.canvas.offsetHeight;
const cx = cw / 2;
const cy = ch - ch / 14;
ctx.save();
ctx.translate(cx,cy);
ctx.rotate(angle);
ctx.fillStyle = 'rgba(0,1)';
// draw circle
ctx.beginPath();
ctx.ellipse(0,needleRadius,2 * Math.PI);
ctx.fill();
// draw needle
ctx.beginPath();
ctx.moveTo(0,needleWidth / 2);
ctx.lineTo(needleLength,0);
ctx.lineTo(0,-needleWidth / 2);
ctx.fill();
ctx.restore();
}
};
const drawText = (text: string,innerRadius: number,outerRadius: number): void => {
const chart = chartRef.current as Doughnut;
const ctx = chart.chartInstance.ctx;
const minValue = Math.min(...data);
const maxValue = Math.max(...data);
if (ctx) {
ctx.fillStyle = 'rgba(0,1)';
const chartArea = chart.chartInstance.chartArea;
const centerX = (chartArea.left + chartArea.right) / 2;
const centerY = (chartArea.top + chartArea.bottom) / 2;
const textMetrics = ctx.measureText(text);
const textHeight = Math.max(ctx.measureText('m').width,ctx.measureText('\uFF37').width);
const radialDiff = outerRadius - innerRadius;
// Min / Max values
ctx.font = '20px Arial';
ctx.fillText(`${minValue}%`,chartArea.left + radialDiff * 1.1,chartArea.bottom + textHeight * 2);
ctx.fillText(`${maxValue}%`,chartArea.right - radialDiff * 2,chartArea.bottom + textHeight * 2);
// Needle value
ctx.font = '30px Arial';
ctx.fillText(text,centerX - textMetrics.width,centerY + textHeight);
}
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。