Doughnut chart, multiple datasets into 1 to only have 1 ring with sections

Discussão em 'Angular' iniciado por Diana, Novembro 20, 2024.

  1. Diana

    Diana Guest

    I have a doughnut chart that has multiple rings but I want to have just one ring with multiple sections. How can I achieve this? This is my code The first code block is the ts file and the second one is the interface file. I have tried combining the datasets but that bring up another issue where I am not able to have all the sections have labels and also can not be removed when the legends are clicked on.

    ts file.

    export class DoughnutChartComponent implements OnInit, AfterViewInit {
    @ViewChild(ChartDirective) chartRef: ChartDirective;
    @Input() data: DataConfig;
    @Input() options: ChartOptions;
    @Input() colorType: ColorType = ColorType.SERIES;
    @Input() countText: string;

    chartConfig: ChartConfiguration;
    chart: Chart;

    constructor() {}
    ngOnInit(): void {
    this.chartConfig = this.buildChartConfig(this.data);
    }
    ngAfterViewInit(): void {
    Chart.register({
    id: 'centerText',
    beforeDraw: (chart) => {
    const chartType = (chart.config as ChartConfiguration).type;
    if (chartType === 'doughnut') {
    const { width, height, ctx } = chart;
    ctx.restore();
    ctx.font = '50px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = '#333';
    const x = width / 2.1;
    const y = height / 2;
    ctx.fillText(this.countText || '', x, y);
    ctx.save();
    }
    },
    });

    this.chart = new Chart(this.chartRef.canvas, this.chartConfig);
    }

    buildChartConfig(data: DataConfig): ChartConfiguration {
    const newData: ChartData = {
    ...data,
    datasets: [
    ...data.datasets.map((value, i) => ({
    ...datasetDefaults(i, this.colorType),

    ...value,
    })),
    ],
    } as ChartData;
    return {
    ...chartDefaults,
    data: newData,
    options: {
    ...chartDefaults.options,
    ...this.options,
    plugins: {
    ...chartDefaults.options.plugins,
    ...(data.datasets.length < 2
    ? {
    legend: {
    display: false,
    },
    }
    : {}),
    ...(this.options?.plugins || {}),
    tooltip: {
    callbacks: {
    label(this, tooltipItem) {
    return [
    ...data.datasets[tooltipItem.datasetIndex].tooltips[
    tooltipItem.dataIndex
    ].map(({ label, value }) => `${label}: ${value}`),
    ];
    },
    },
    },
    },
    },
    };
    }
    }
    interface file
    export const datasetDefaults = (
    index: number,
    colorType?: ColorType | string
    ): ChartDataset => {
    const color = ['#BD0024', '#6C0510', '#CCCCCC', '#878787', '#525252'];
    const hoverBackgroundColor = '#DF002A';
    const newIndex = index % color.length;

    switch (colorType) {
    case ColorType.POINT:
    return {
    label: '',
    data: [] as Array<number | ScatterDataPoint | BubbleDataPoint>,
    backgroundColor: color,
    borderColor: color,
    hoverBackgroundColor: hoverBackgroundColor,
    };
    case ColorType.SERIES:
    default:
    return {
    label: '',
    data: [] as Array<number | ScatterDataPoint | BubbleDataPoint>,
    backgroundColor: color[newIndex],
    borderColor: color[newIndex],
    hoverBackgroundColor: hoverBackgroundColor,
    };
    }
    };

    export const chartDefaults: ChartConfiguration = {
    type: 'doughnut',
    data: {
    datasets: [],
    },
    options: {
    responsive: true,
    maintainAspectRatio: false,

    plugins: {
    legend: {
    position: 'right',
    labels: {
    boxWidth: 10,
    boxHeight: 10,
    },
    },
    },
    layout: {
    padding: 0,
    },
    },
    };


    current chart ^ [​IMG] [​IMG]expected look

    Continue reading...

Compartilhe esta Página