Pergunta

Estou usando o Chart.js (documentação), mas não consigo definir um cor de fundo para o donut caminho. Nem sequer é mencionado nos documentos.

O que estou tentando alcançar:

enter image description here

Código atual:

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);

ATUALIZAR: Atualmente resolvi usando um duplicado Donut (2ª tela) com um valor de 100, sem animação e minha cor desejada (em segundo plano), e posicionou-a absoluta, embaixo da 1ª.

No entanto, este é um truque desagradável e muito ineficiente, então ainda estou esperando uma resposta correta.

Foi útil?

Solução 3

Eu o resolvi usando uma donut duplicada (2ª tela) com um valor de 100, sem animação e minha cor de fundo desejada, e posicionei-o absoluto, embaixo do primeiro.

No entanto, este é um truque desagradável e muito ineficiente, então ainda estou esperando uma resposta correta.

Outras dicas

Pensei em postar uma solução recente que funcionou para mim, usando v2.1.0 que introduziu plugins.

Gráfico sem valor exibindo um gráfico de fundo versus com valor que cobre o plano de fundo, apenas o gráfico principal animará, o fundo é apenas um arco simples:

Chart with no value displaying a background Chart with value covering the background


Eu registrei um plugin pela primeira vez seus documentos:

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());

A sintaxe singleton era apenas para poder reduzir a duplicação e usar o mesmo draw Método para vários eventos de plug -in.


Então eu usei meu novo plug -in registrado como assim:

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 Fiddle aqui

Eu usei o código de @jonlunsford, mas não funcionou quando atualizei o ChartJs para 3.x.

De acordo com Guia de migração, Diz

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

Então eu mudei o código para:

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,
}

Então, ao criar um gráfico, você pode usar as opções da seguinte forma:

  ...
  plugins: {
    legend: {
      display: false,
    },
    doughnutBackground: {
      enabled: true,
      color: '#E4E6E6',
    },
    ...
  },

Provavelmente não há como você fazer isso no elemento de tela. Eu colocaria um elemento posicionado absoluto além da tela. Aqui está um exemplo:

.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: "";
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top