我正在使用HTML画布元素和fillText()将标签放在图表上的香草JavaScript编写甜甜圈饼图。我很难将标签放置在图表的外部,并且它们被画布的宽度切断了。这是问题的working Codepen

javascript - 甜甜圈图 Vanilla JS和HTML Canvas-LMLPHP

这是实际将标签打印到图表的代码片段:

start_angle = 0;
for (categ in catergories) {
    let categoryLabel = categ;
    val = catergories[categ];
    let slice_angle = 2 * Math.PI * val / total_value;
    let pieRadius = Math.min(this.canvas.width / 2,this.canvas.height / 2);
    let labelX = this.canvas.width / 2 + (pieRadius / 2) * Math.cos(start_angle + slice_angle / 2);
    let labelY = this.canvas.height / 2 + (pieRadius / 2) * Math.sin(start_angle + slice_angle / 2);

    if (this.options.doughnutHoleSize){
        let offset = (pieRadius * this.options.doughnutHoleSize ) / 2;
        labelX = this.canvas.width / 2 + (offset + pieRadius / 2) * Math.cos(start_angle + slice_angle / 2);
        labelY = this.canvas.height / 2 + (offset + pieRadius / 2) * Math.sin(start_angle + slice_angle / 2);
    }

    this.ctx.fillStyle = "black";
    this.ctx.font = "bold 11px Arial";
    this.ctx.fillText(`${categoryLabel} ${val}`, labelX, labelY);
    start_angle += slice_angle;
}


期望的定位:

javascript - 甜甜圈图 Vanilla JS和HTML Canvas-LMLPHP

最佳答案

这是了解一些三角函数和画布文本API的简单情况。

我从各个切片的中心角度使用cos和sin值来设置文本的水平和垂直对齐方式,如下所示:

    this.ctx.textAlign = cos > 0 ? 'start' : 'end';
    this.ctx.textBaseline = sin > 0 ? 'top' : 'bottom';


此外,我还向饼图构造函数添加了两个选项:

    const monthlyPaymentChart = new Piechart({
        canvas: canvas,
        data: paymentInformation,
        colors: pieChartColors,
        doughnutHoleSize: 0.85,

        labelDistanceFromOuterEdge: 5,
        roomForLabels: 65,
    });



roomForLabels-告诉标签保留多少空间
以像素为单位显示在饼图的外部。如果任何宽度
标签将不适合画布,此值增加以适应
它。
labelDistanceFromOuterEdge-标签与标签之间的距离
饼图的边缘(以像素为单位)。


为了测量文本,我使用了canvas 2d上下文API的measureText函数。这就是为什么在Piechart的构造函数的开头还设置了字体和文本大小的原因

完整的代码可以在这里找到:
https://codepen.io/prtjohanson/pen/bZgQmY

关于javascript - 甜甜圈图 Vanilla JS和HTML Canvas ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55006531/

10-10 02:02