Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display Doughnut Pie Chart As Circle Progress Chart.js

I want to ask if there is a way to make Pie Chart As Circle Progress with percent value, I want just one slice colored something like this:

enter image description here

This is my fiddle for now I want just one data.

HTML:

<canvas id="chartProgress" width="300px" height="200"></canvas>

JS:

var chartProgress = document.getElementById("chartProgress");
if (chartProgress) {
var myChartCircle = new Chart(chartProgress, {
type: 'doughnut',
data: {
  labels: ["Africa", 'null'],
  datasets: [{
    label: "Population (millions)",
    backgroundColor: ["#5283ff"],
    data: [68, 48]
  }]
},
plugins: [{
  beforeDraw: function(chart) {
    var width = chart.chart.width,
        height = chart.chart.height,
        ctx = chart.chart.ctx;

    ctx.restore();
    var fontSize = (height / 150).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.fillStyle = "#9b9b9b";
    ctx.textBaseline = "middle";

    var text = "68%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

    ctx.fillText(text, textX, textY);
    ctx.save();
  }
}],
options: {
  legend: {
    display: false,
  },
  responsive: true,
  maintainAspectRatio: false,
  cutoutPercentage: 85
}
});
}

I know I can do it with normal HTML&CSS or using simple plugin but I want to do it using Chart.js

like image 354
Aymen bz Avatar asked Apr 25 '18 10:04

Aymen bz


1 Answers

The Plugin Core API offers different hooks that may be used for executing custom code. You already use the beforeDraw hook to draw text in the middle of the doughnut.

You could now also use the beforeInit hook to modify the chart configuration in order to fit your needs:

beforeInit: (chart) => {
  const dataset = chart.data.datasets[0];
  chart.data.labels = [dataset.label];
  dataset.data = [dataset.percent, 100 - dataset.percent];
}

Given this code, the definition of your dataset would look simple as follows:

{
  label: 'Africa / Population (millions)',
  percent: 68,
  backgroundColor: ['#5283ff']
}

Last you have to define a tooltips.filter, so that the tooltip appears only at the relevant segment.

tooltips: {
  filter: tooltipItem => tooltipItem.index == 0
}

Please take a look at your amended code and see how it works.

var myChartCircle = new Chart('chartProgress', {
  type: 'doughnut',
  data: {
    datasets: [{
      label: 'Africa / Population (millions)',
      percent: 68,
      backgroundColor: ['#5283ff']
    }]
  },
  plugins: [{
      beforeInit: (chart) => {
        const dataset = chart.data.datasets[0];
        chart.data.labels = [dataset.label];
        dataset.data = [dataset.percent, 100 - dataset.percent];
      }
    },
    {
      beforeDraw: (chart) => {
        var width = chart.chart.width,
          height = chart.chart.height,
          ctx = chart.chart.ctx;
        ctx.restore();
        var fontSize = (height / 150).toFixed(2);
        ctx.font = fontSize + "em sans-serif";
        ctx.fillStyle = "#9b9b9b";
        ctx.textBaseline = "middle";
        var text = chart.data.datasets[0].percent + "%",
          textX = Math.round((width - ctx.measureText(text).width) / 2),
          textY = height / 2;
        ctx.fillText(text, textX, textY);
        ctx.save();
      }
    }
  ],
  options: {
    maintainAspectRatio: false,
    cutoutPercentage: 85,
    rotation: Math.PI / 2,
    legend: {
      display: false,
    },
    tooltips: {
      filter: tooltipItem => tooltipItem.index == 0
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chartProgress"></canvas>
like image 165
uminder Avatar answered Sep 28 '22 18:09

uminder