Chart.js圆环图段内的图片

5us2dqdw  于 2022-11-07  发布在  Chart.js
关注(0)|答案(2)|浏览(156)

我发现了关于chart.js,我正在寻找使用一个甜甜圈图为我的网站,我发现了一个例子,我可以采取的基本知识:https://jsfiddle.net/9wp4f693/2/
我只找到了这样的东西,但它是在片段内绘制文本,而不是添加图片。

function drawSegmentValues()
{
    for(var i=0; i<myDoughnutChart.segments.length; i++) 
    {
        ctx.fillStyle="white";
        var textSize = myChart.width/10;
        ctx.font= textSize+"px Verdana";
        // Get needed variables
        var value = myDoughnutChart.segments[i].value;
        var startAngle = myDoughnutChart.segments[i].startAngle;
        var endAngle = myDoughnutChart.segments[i].endAngle;
        var middleAngle = startAngle + ((endAngle - startAngle)/2);

        // Compute text location
        var posX = (radius/2) * Math.cos(middleAngle) + midX;
        var posY = (radius/2) * Math.sin(middleAngle) + midY;

        // Text offside by middle
        var w_offset = ctx.measureText(value).width/2;
        var h_offset = textSize/4;

        ctx.fillText(value, posX - w_offset, posY + h_offset);
    }
}

但我希望在我的片段中有图片,类似这样的东西,但我不知道我将如何做到这一点:

ehxuflar

ehxuflar1#

没有用于在圆环图中绘制图像的本机ChartJS API。
但您可以在绘制图表后手动添加图像。

对于圆环中的每个楔形块:

  • 警告:未经测试的代码...可能需要进行一些调整 *

1.向内平移到甜甜圈的中间。

// calculate donut center (cx,cy) & translate to it
var cx=chart.width/2;
var cy=chart.height/2;
context.translate(cx,cy);

1.旋转到目标圆环楔形块的中间Angular

var startAngle = chart.segments[thisWedgeIndex].startAngle;
var endAngle = chart.segments[thisWedgeIndex].endAngle;
var midAngle = startAngle+(endAngle-startAngle)/2;

// rotate by the midAngle
context.rotate(midAngle);

1.向外平移到目标圆环楔体的中点:

// given the donut radius (innerRadius) and donut radius (radius)
var midWedgeRadius=chart.innerRadius+(chart.radius-chart.innerRadius)/2;
context.translate(midWedgeRadius,0);

1.以图像宽度和高度的一半偏移量绘制图像:

// given the image width & height
context.drawImage(theImage,-theImage.width/2,-theImage.height/2);

1.通过将变换矩阵重置为默认值来清除变换:

// undo translate & rotate
context.setTransform(1,0,0,1,0,0);
w41d8nur

w41d8nur2#

在新版本中,使用以下示例(它需要chartjs-plugin-labels):

import React from 'react';
import { Doughnut } from 'react-chartjs-2';
import 'chartjs-plugin-labels';

const imageURLs = [
  'https://avatars.githubusercontent.com/u/43679262?v=4',
  'https://avatars.githubusercontent.com/u/43679262?v=4',
  'https://avatars.githubusercontent.com/u/43679262?v=4',
];
const images = imageURLs.map((v) => {
  var image = new Image();
  image.src = v;
  return image;
});

export const data_doughnut = {
  labels: ['a', 'b', 'c'],
  datasets: [
    {
      data: [30, 15, 10],
      backgroundColor: [
        '#B1A9FF',
        '#877CF8',
        '#6456F2',
      ],
      weight: 1,
    },
  ],
};

export const chartOptions = {
  responsive: true,
  plugins: {
    legend: {
      display: false,
    },
  },
  scales: {
    ticks: {
      display: false,
    },
  },
};

export const plugins = [
  {
    afterDatasetsDraw: (chart) => {
      var ctx = chart.ctx;
      ctx.save();
      var xCenter = chart.canvas.width / 2;
      var yCenter = chart.canvas.height / 2;
      var data = chart.config.data.datasets[0].data;
      var vTotal = data.reduce((a, b) => a + b, 0);
      data.forEach((v, i) => {
        var vAngle =
          data.slice(0, i).reduce((a, b) => a + b, 0) + v / 2;
        var angle = (360 / vTotal) * vAngle - 90;
        var radians = angle * (Math.PI / 180);
        var r = yCenter;
        // modify position
        var x = xCenter + (Math.cos(radians) * r) / 1.4;
        var y = yCenter + (Math.sin(radians) * r) / 1.4;
        ctx.translate(x, y);
        var image = images[i];
        ctx.drawImage(image, -image.width / 2, -image.height / 2);
        ctx.translate(-x, -y);
      });
      ctx.restore();
    },
  },
];

export function DoughnutChartFeekers() {
  return (
    <Doughnut
      data={data_doughnut}
      plugins={plugins}
      options={chartOptions}
    />
  );
}

相关问题