最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Display Doughnut Pie Chart As Circle Progress Chart.js - Stack Overflow

programmeradmin3浏览0评论

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:

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

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:

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

Share Improve this question edited Feb 8, 2019 at 9:48 Cœur 38.7k26 gold badges202 silver badges277 bronze badges asked Apr 25, 2018 at 10:09 Aymen bzAymen bz 3881 gold badge5 silver badges12 bronze badges 2
  • off the top of my head, you could probably get the required effect by putting a dummy value (like 68 - 32). But it may be difficult to get the text in the middle without some custom code or customisation – Chirag Ravindra Commented Apr 25, 2018 at 10:31
  • What amazing approach. I never thinked before use ChartJS to create a Circular Progressbar. It comes already with animation and no problems about the size of the canvas, it will be rendered correctly. – Bruno Freire Commented Sep 16, 2021 at 0:36
Add a comment  | 

1 Answer 1

Reset to default 16

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>

发布评论

评论列表(0)

  1. 暂无评论