Home > other >  place images over pie chart slices using chartjs
place images over pie chart slices using chartjs

Time:12-06

chartjs version: 3.6.0 vue version: 2.6.11. I am trying to build charts using chartjs and vue. Everything went fine. But there is a challenge that i could not ressolve. I am trying to place images on the pie chart slices as shown in the picture below enter image description here

it is just a reference of the idea that i want to achieve. if you know about the solution please help me out. Thank you!

CodePudding user response:

You can draw the images directly on the canvas using the Plugin Core API. The API offers a number of hooks that can be used to perform custom code. In your case, you could use the afterDatasetsDraw hook together with CanvasRenderingContext2D.

Please take a look at below runnable sample code and see how it works.

const imageURLs = [
  'https://i.stack.imgur.com/2RAv2.png',
  'https://i.stack.imgur.com/Tq5DA.png',
  'https://i.stack.imgur.com/3KRtW.png',
  'https://i.stack.imgur.com/iLyVi.png'
];
const images = imageURLs.map(v => {
  var image = new Image();
  image.src = v;
  return image;
});

new Chart('myChart', {
  type: 'pie',
  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;
        var x = xCenter   Math.cos(radians) * r / 2;
        var y = yCenter   Math.sin(radians) * r / 2;
        ctx.translate(x, y);
        var image = images[i];
        ctx.drawImage(image, -image.width / 2, -image.height / 2);
        ctx.translate(-x, -y);
      });
      ctx.restore();
    }
  }],
  data: {
    labels: ['red vans', 'blue vans', 'green vans', 'gray vans'],
    datasets: [{
      label: 'My Dataset',
      data: [48, 56, 33, 44],
      backgroundColor: ['rgba(255, 0, 0, 0.4)', 'rgba(0, 0, 255, 0.4)', 'rgba(0, 255, 0, 0.4)', 'rgba(124, 124, 124, 0.4)']
    }]
  },
  options: {
    responsive: false,
    plugins: {
      legend: {
        display: false
      }
    },
    scales: {
      ticks: {
        display: false
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.1/chart.min.js"></script>
<canvas id="myChart" width="250"></canvas>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related