admin管理员组

文章数量:1356775

I have created SPFx React project and integrate chart js library in that projecct

I have used "chart.js": "^3.3.2" version.

I need to add an image/icon in data labels and legends.

Also, I need to add a border outside of the image/icon added in legends.

Below is my code snippet.

<Chart type="pie" data={chartData} options={chartOptions} plugins={pluginsForShowDataOnPieChart} />

    const iconImageArray = [
      '.jpg',
      '.jpg',
      '.jpg',
    ];

    const labelsNameArray = ["Label 1","Label 2","Label 3"]

    const pieChartData = () => {
            const documentStyle = getComputedStyle(document.documentElement);
            const data = {
                labels: labelsNameArray,
                datasets: [
                    {
                        data: percentageDataArray,
                        backgroundColor: [
                            '#5066BB',
                            '#6FC66E',
                            '#ECAD68',
                            '#EF876C',
                            documentStyle.getPropertyValue('--cyan-500'),
                            documentStyle.getPropertyValue('--teal-500'),
                            documentStyle.getPropertyValue('--pink-500'),
                        ],
                        hoverBackgroundColor: [
                            '#5066BB',
                            '#6FC66E',
                            '#ECAD68',
                            '#EF876C',
                            documentStyle.getPropertyValue('--cyan-500'),
                            documentStyle.getPropertyValue('--teal-500'),
                            documentStyle.getPropertyValue('--pink-500'),
                        ],
                        toggledVisibility: Array(productArray.length).fill(true)
                    }
                ]
            };
    
            const options = {
                aspectRatio: 2,
                plugins: {
                    legend: {
                        position: 'right',
                        labels: {
                            usePointStyle: true,
                            padding: 20,
                            generateLabels: (chart) => {
                                const dataset = chart.data.datasets[0];
                                return dataset.data.map((data, i) => {
                                    const img = new Image();
                                    img.src = iconImageArray[i]; // Ensure iconImageArray contains valid image URLs
                                    img.height = 10;
                                    img.width = 10;
                                    img.style.border = '1px solid';
                                    img.style.borderColor = legendColor[i];
                                    return {
                                        text: chart.data.labels[i],
                                        fillStyle: dataset.backgroundColor[i],
                                        hidden: chart.getDatasetMeta(0).data[i].hidden,
                                        index: i,
                                        fontColor: dataset.toggledVisibility[i] ? '#495057' : '#888888',
                                        textDecoration: dataset.toggledVisibility[i] ? 'none' : 'line-through', // Add strikethrough
                                        pointStyle: img // Assign image as the point style
                                    };
                                });
                            }
                        },
                        onClick: function (event, legendItem, legend) {
                            const ci = legend.chart;
                            const index = legendItem.index;
                            //below 2 lines for toggle visibility for clicked doughnut chart portion
                            const meta = ci.getDatasetMeta(0);
                            meta.data[index].hidden = !meta.data[index].hidden;
                            //below lines for number shown visibility on doughnut chart 
                            const dataset = ci.data.datasets[0];
                            dataset.toggledVisibility[index] = !dataset.toggledVisibility[index];
                            ci.update();
                        }
                    },
                    tooltip: {
                        callbacks: {
                            label: (tooltipItem) => {
                                const countValue = productArray[tooltipItem.dataIndex]?.count || 0;
                                const renewCountValue = productArray[tooltipItem.dataIndex]?.renewCount || 0;
                                return `${tooltipItem.label}: ${countValue} | ${renewCountValue}`;
                            },
                        },
                    },
                    datalabels: {
                        formatter: (value) => `${value}%`,
                        color: '#fff',
                        anchor: 'end',
                        align: 'start',
                        offset: -10,
                        font: {
                            weight: 'bold',
                        },
                    },
                },
            };
    
            setChartData(data);
            setChartOptions(options);
        };
    
        // Plugin to display percentage inside the Pie Chart
        const pluginsForShowDataOnPieChart = [
            {
                afterDraw: (chart) => {
                    const { ctx } = chart;
                    chart.data.datasets.forEach((dataset, i) => {
    
                        // Convert data values from string to number
                        const numericData = dataset.data.map(value => parseFloat(value) || 0);
    
                        const total = numericData.reduce((sum, value) => sum + value, 0);
    
                        chart.getDatasetMeta(i).data.forEach((datapoint, index) => {
                            if (dataset.toggledVisibility[index] && dataset.data[index] != 0) {
                                if (numericData[index] !== 0) {
                                    const { x, y } = datapoint.tooltipPosition();
                                    const percentage = ((numericData[index] / total) * 100).toFixed(1);
    
                                    ctx.fillStyle = '#495057';
                                    ctx.font = 'bold 12px Open Sans';
                                    ctx.textAlign = 'center';
                                    ctx.textBaseline = 'middle';
    
                                    ctx.fillText(`${percentage}%`, x, y + 7);
                                }
                            }
                        });
                    });
                },
                beforeDraw: (chart) => {
                    const { ctx } = chart;
                    ctx.restore();
                    ctx.fillStyle = '#495057';
                    ctx.font = 'bold 12px Open Sans';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
    
                    let total = 0;
                    let isTotalVisible = false;
    
                    if (chart.data.datasets[0] && chart.data.datasets[0].data) {
                        total = chart.data.datasets[0].data.reduce((sum, value) => sum + value, 0);
                        chart.data.datasets.forEach((dataset, i) => {
                            chart.getDatasetMeta(i).data.forEach((datapoint, index) => {
                                if (dataset.data[index] !== 0) {
                                    isTotalVisible = true;
                                    return;
                                }
                            });
                        });
                    }
    
                    ctx.save();
                }
            }
        ];

Can anyone help with the same?

Thanks in Advance.

本文标签: chartjsHow to add Image and text in data label and legend in pie chartStack Overflow