7

我正在使用 Chart.js(文档),但我似乎无法为 Donut path设置背景颜色。文档中甚至都没有提到它。

我想要达到的目标:

在此处输入图像描述

当前代码:

var meterInvoicesData = [
    {
        value: 75,
        color: '#22d319'
    },
    {
        value: 25,     // rest
        color: 'transparent'  // invisible (setting this as background color will animate it too)
    }
];

var meterOptions =
{
    percentageInnerCutout : 80,
    animationEasing : 'easeInQuint'
};

var meterInvoices = new Chart(document.getElementById('meterInvoices').getContext('2d')).Doughnut(meterInvoicesData,meterOptions);

更新:我目前通过使用值为 100、没有动画和我想要的(背景)颜色的重复甜甜圈(第二个画布)来解决它,并将其绝对定位在第一个下方。

但是,这是一个讨厌的技巧,而且效率很低,所以我仍然希望得到正确的答案。

4

4 回答 4

11

以为我会发布一个最近对我有用的解决方案,使用 v2.1.0 引入了plugins

没有值显示背景的图表与有值覆盖背景的图表,只有主图表会动画,背景只是一个简单的弧线:

没有显示背景值的图表 具有覆盖背景的值的图表


我首先根据他们的文档注册了一个插件:

var radiusBackground = function() {
  var self = this;

  self.draw = function(chartInstance) {
    if(chartInstance.options.radiusBackground) {
      var x = chartInstance.chart.canvas.clientWidth / 2,
          y = chartInstance.chart.canvas.clientHeight / 2,
          ctx = chartInstance.chart.ctx;

      ctx.beginPath();
      ctx.arc(x, y, chartInstance.outerRadius - (chartInstance.radiusLength / 2), 0, 2 * Math.PI);
      ctx.lineWidth = chartInstance.radiusLength;
      ctx.strokeStyle = chartInstance.options.radiusBackground.color || '#d1d1d1';
      ctx.stroke();
    }
  };

  // see http://www.chartjs.org/docs/#advanced-usage-creating-plugins for plugin interface
  return {
    beforeDatasetsDraw: self.draw,
    onResize: self.draw
  }
};

// Register with Chart JS
Chart.plugins.register(new radiusBackground());

单例语法只是为了能够减少重复并draw为多个插件事件使用相同的方法。


然后我像这样使用我的新注册插件:

var chartElement = document.getElementById('doughnut-chart');

var chart = new Chart(chartElement, {
  type: 'doughnut',
  options: {
    // Here is where we enable the 'radiusBackground'
    radiusBackground: {
      color: '#d1d1d1' // Set your color per instance if you like
    },
    cutoutPercentage: 90,
    title: {
      display: false,
    },
    legend: {
      display: false,
    },
  },
  data: {
    labels: ["Type 1", "Type 2", "Type 3"],
    datasets: [{
      data: [2, 5, 1],
      backgroundColor: ["#a3c7c9","#889d9e","#647678"],
      borderWidth: 0,
      hoverBackgroundColor: ["#96b7b9","#718283","#5c6b6d"]
    }]
  }
});

JS小提琴在这里

于 2016-08-22T19:21:25.923 回答
2

我使用了@Jonlunsford 的代码,但是当我将 ChartJS 升级到 3.x 时它不起作用。

根据迁移指南,它说

Chart.innerRadius now lives on doughnut, pie, and polarArea controllers

所以我将代码更改为:

import { Chart, DoughnutController } from 'chart.js'

type DoughnutChartBackgroundPluginOptions = {
  enabled: boolean
  color: string
}

function handler(chart: Chart<'doughnut'>, args, options: DoughnutChartBackgroundPluginOptions) {
  const { ctx, width, height } = chart

  const { innerRadius } = chart.getDatasetMeta(chart.data.datasets.length - 1).controller as DoughnutController
  const { outerRadius } = chart.getDatasetMeta(0).controller as DoughnutController
  const radiusLength = outerRadius - innerRadius

  if (options.enabled) {
    const x = width / 2,
      y = height / 2

    ctx.beginPath()
    ctx.arc(x, y, outerRadius - radiusLength / 2, 0, 2 * Math.PI)
    ctx.lineWidth = radiusLength
    ctx.strokeStyle = options.color
    ctx.stroke()
  }
}

export default {
  id: 'doughnutChartBackground',
  beforeDatasetsDraw: handler,
}

然后,在创建图表时,您可以使用如下选项:

  ...
  plugins: {
    legend: {
      display: false,
    },
    doughnutBackground: {
      enabled: true,
      color: '#E4E6E6',
    },
    ...
  },
于 2021-05-30T18:46:39.773 回答
1

我通过使用值为 100、没有动画和我想要的背景颜色的重复甜甜圈(第二个画布)来解决它,并将其绝对定位在第一个下方。

但是,这是一个讨厌的技巧,而且效率很低,所以我仍然希望得到正确的答案。

于 2014-03-01T23:38:28.373 回答
0

可能没有办法在画布元素中做到这一点。我会在画布之外放置一个绝对定位的元素。这是一个例子:

.fakeCircle {
    position: absolute;
    z-index: 0;
    border-radius: 90px;
    -webkit-border-radius: 90px;
    -moz-border-radius: 90px;
    background-color: #dadce8;
    width: 50px;
    height: 50px;
    top: 12px;
    left: 12px;
}
.fakeCircle:after {
    position: absolute;
    z-index: 0;
    border-radius: 50px;
    -webkit-border-radius: 50px;
    -moz-border-radius: 50px;
    background-color: #fff;
    width: 34px;
    height: 34px;
    content: "";
}
于 2015-03-11T13:24:13.527 回答