Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to colorize individual rings in polar chart background in chart.js/ng2-charts?

I am trying to change the color of individual polar chart rings using chart.js version and ng2-charts in Angular but in the documentation of particular versions, I haven't found anything related to it and neither searching the solution on web.

"chart.js": "^2.8.0",
"ng2-charts": "^2.3.0",

Code:

  public polarAreaChartLabels: Label[] = [];

  public polarAreaChartData: SingleDataSet = [];

  public polarAreaLegend = true;

  myColors = [{ backgroundColor: ["#cb4b4b", "#edc240", "#afd8f8"] }];

  public polarAreaChartType: ChartType = "polarArea";

  public polarAreaChartOptions: ChartOptions = {
    plugins: {
      datalabels: {
         color: '#000000',
         anchor: 'end',
         align: 'end',
         padding: 50,
         display: true,
         font: {
           weight: 'bolder'
         },
         formatter: function(value, ctx) {
          return `${ctx.chart.data.labels[ctx.dataIndex]} - ${value} %`;
       },
      },
    },
    scale: {
      ticks: {
          beginAtZero: true,
          max: 100,
          min: 0,
          stepSize: 10
      }
    }
  };

  public ChartPlugins = [pluginDataLabels];

HTML:

            <canvas id="polar-chart" baseChart height="40vh" width="120vw" 
                [data]="polarAreaChartData" 
                [labels]="polarAreaChartLabels"
                [legend]="polarAreaLegend"
                [plugins]="ChartPlugins"
                [options]="polarAreaChartOptions"
                [chartType]="polarAreaChartType" 
                [colors]="myColors">        
            </canvas>

Current Output

Current Output

Desired Output

Desired Output

Is there any plugin or solution available for this? Any help would be much appriciated.

like image 626
Muhammad Ahsan Avatar asked Oct 24 '25 06:10

Muhammad Ahsan


1 Answers

This isn't specifically an angular solution, but this video was very helpful if you're looking to highlight only specific rings on the scale and I thought I'd share it for others with this same question: https://www.youtube.com/watch?v=hPGuSNdwOC4

I adapted it a bit to put lines at 100 and 110 on my chart (which represent 100% and 110% of budget) without knowing the number of ticks ahead of time as the video's solution does. The ticks could change depending on the values of the charted numbers, chart size, etc. I use the r.ticks collection to get the number of ticks to properly calculate the circle radius.

const budgetLines = {
    id: "budgetLines",
    afterDatasetsDraw(chart, args, options) {
        var budgetTickCount = 0;
        var overBudgetTickCount = 0;
        const { ctx, chartArea: { top, bottom, left, right, width, height }, scales: { r } } = chart;
        const angle = Math.PI / 180;
        const trueHeight = r.yCenter - r.top;

        r.ticks.forEach(function (tick) {
            if (tick.value < options.budgetValue) {
                budgetTickCount = budgetTickCount + 1;
            }

            if (tick.value < options.budgetValue) {
                overBudgetTickCount = overBudgetTickCount + 1;
            }
        });

        const budgetRadius = ((trueHeight / r.end) * options.budgetValue) - (budgetTickCount + 1);
        const overBudgetRadius = ((trueHeight / r.end) * options.overBudgetValue) - (overBudgetTickCount + 1);

        ctx.save();
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = options.budgetColor;
        ctx.arc(r.xCenter, r.yCenter, budgetRadius, angle * 0, angle * 360, false);
        ctx.stroke();
        ctx.closePath();

        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = options.overBudgetColor;
        ctx.arc(r.xCenter, r.yCenter, overBudgetRadius, angle * 0, angle * 360, false);
        ctx.stroke();
        ctx.closePath();
        ctx.restore();
    }
}

var ctx = document.getElementById("summaryChart");
new Chart(ctx, {
    type: "polarArea",
    data: chartData,
    options: {
        plugins: {
            budgetLines: {
                budgetValue: 100,
                overBudgetValue: 110,
                budgetColor: "rgba(0, 255, 0, 1)",
                overBudgetColor: "rgba(0, 0, 255, 1)"
            },
            legend: {
                display: false
            }
        },
        scales: {
            r: {
                suggestedMax: 100
            }
        }
    },
    plugins: [budgetLines]
});
like image 177
matthew_b Avatar answered Oct 26 '25 14:10

matthew_b