簡體   English   中英

Chart.js 控制台 JS 在單擊事件時銷毀圖表時出錯

[英]Chart.js Console JS Error while destroy the Chart on click event

在第一個圖表“config.categoriesChart”的欄點擊事件得到控制台錯誤“ chart.js:10403 Uncaught TypeError:無法讀取未定義的屬性‘handleEvent’在此處輸入圖像描述,顯示為chart.legend.handleEvent(args.event );

問題發生在銷毀欄上的第一個圖表單擊第一個圖表的事件后。

但是如果我使用 $('#how_i_spend_canvas').replaceWith($('')); 它在不破壞圖表的情況下工作正常。 在此處輸入圖片說明

請讓我看看是什么問題?

document.ready 中的所有代碼

let Chart = require('chart.js');/
let ChartDataLabels = require('chartjs-plugin-datalabels');
let config = window.MvpFE.globalConfiguration.howISpend; 
let dataChart = window.dataHowISpendCharts;
   let labels = dataChart.howISpendDataCatgories.map(function (e) {
    return e.label;
});

let data = dataChart.howISpendDataCatgories.map(function (e) {
    return e.data;
});

//Chart Axis's
let scales = {
    x: {
        ticks: {
            font: {
                size: config.size,
            },
            color: config.dataLabelsColor,
        },
    },
    y: {
        display: false,
    }
};
//Chart legend
let plugins = {

    legend: {
        display: false,
    },
    tooltip: {
        enabled: true,
    },

};
//Chart Data Labels
let dataLabels = {
    color: config.dataLabelsColor,
    anchor: 'end',
    align: 'top',
    offset: 0,
    formatter: function (value) {
        //Include a dollar sign 
        return '$' + value.toLocaleString();
    },
};
//chart data 
let howISpendChartdata = {
    labels: labels,
    datasets: [{
        data: data,
        backgroundColor: config.catogriesBackgroundColor,
        borderColor: config.catogriesBorderColor,
        hoverBackgroundColor: config.unSelectedColor,
        hoverBorderColor: config.unSelectedColor,
        borderWidth: config.barWidth,
        borderRadius: config.barRadius,
        borderSkipped: 'false',
        datalabels: dataLabels
    }]
}

// Category heading label text will be from json data
let categoryLabel = "";
//Array to store the bar background colors.
const barColors = [];

//Code to draw Chart 
var ctx = document.getElementById('how_i_spend_canvas').getContext('2d');
config.categoriesChart = new Chart(ctx, {
    type: 'bar',
    data: howISpendChartdata,
    // Chart pulgins & Options
    plugins: [ChartDataLabels],
    options: {
        responsive: true,
        maintainAspectRatio: false,
        aspectRatio: 2,
        plugins: plugins,
        scales: scales,
        onClick: function (evt, element) {
            if (element.length > 0) {
                const categoriesChart = config.categoriesChart;
                let activeBarIndex = element[0].index;
                categoryLabel = categoriesChart.data.labels[activeBarIndex];
                
                // destroy any chart instances that are created
                if (categoriesChart instanceof Chart) {
                    categoriesChart.destroy();
                }

                //$('#how_i_spend_canvas').replaceWith($('<canvas id="SelectedCategory" height="400px"></canvas>')); //replace current canvas
                // Code to draw Chart
                config.monthlyChart = new Chart(ctx, {
                    type: 'bar',
                    data: howISpendChartdata,
                    plugins: [ChartDataLabels],
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        aspectRatio: 2,
                        plugins: plugins,
                        scales: scales,
                        onClick: function (e, activeElements) {
                            //get the colors for bars 
                            if (activeElements.length > 0) { // check the element is selected
                                const monthlyChart = config.monthlyChart;
                                monthlyChart.options.animation.colors = false;
                                                                
                                    monthlyChart.update();
                                                                        
                                }
                            }

                        }
                    },

                });
                config.monthlyChart.render();
            }
        },
    }
}); // document.Ready Ends()

警告:只有當您不使用圖例插件或不需要處理圖例項單擊事件時,此解決方案才有意義。

就我而言,即使我在圖表選項中禁用了legend插件,我也會收到此錯誤,如下所示:

plugins: {
  legend: {
      display: false
    }
  }

在我過濾了由圖例插件處理的事件后,錯誤停止發生,如下所示:

plugins: {
  legend: {
      display: false,
      events: [] // this line was the key
    },
  }

我遇到了同樣的問題,異常的原因是:在 onclick 事件中,如果您嘗試銷毀同一個圖表,則在事件回調函數返回之前圖表引用變為空。 這就是拋出異常的原因。 您可以通過在事件回調完成后銷毀圖表實例來解決此問題,即使用 setTimeout 函數您可以在 100 毫秒左右后銷毀圖表。 你可以這樣做:

    options: {
    onClick: function (evt, element) {
        if (element.length > 0) {
            const categoriesChart = config.categoriesChart;
            let activeBarIndex = element[0].index;
            categoryLabel = categoriesChart.data.labels[activeBarIndex];

            setTimeout(() => {
                // destroy any chart instances that are created
                if (categoriesChart instanceof Chart) {
                    categoriesChart.destroy();
                }

                //$('#how_i_spend_canvas').replaceWith($('<canvas id="SelectedCategory" height="400px"></canvas>')); //replace current canvas
                // Code to draw Chart
                config.monthlyChart = new Chart(ctx, {
                    type: 'bar',
                    data: howISpendChartdata,
                    plugins: [ChartDataLabels],
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        aspectRatio: 2,
                        plugins: plugins,
                        scales: scales,
                        onClick: function (e, activeElements) {
                            //get the colors for bars 
                            if (activeElements.length > 0) { // check the element is selected
                                const monthlyChart = config.monthlyChart;
                                monthlyChart.options.animation.colors = false;
                                monthlyChart.update();
                            }
                        }
                    }
                });
                config.monthlyChart.render();
            }, 100);
        }
    }
}

以下是任何面臨類似問題的人的解決方案:

options: {
    onClick: function (evt, element) {
        // get the require data from click event 
        let chart = Chart.getChart(e.chart.canvas.id);
        const points = chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, true);
        if (points.length) {
            const firstPoint = points[0];
            const elementIndex = firstPoint.index;
            const datasetIndex = firstPoint.datasetIndex;
            const dataset = chart.data.datasets[datasetIndex];
            const datasetFieldLabel = dataset.label;
            const itemLabel = chart.data.labels[elementIndex];
            const itemValue = dataset.data[elementIndex];
            
            setTimeout(() => {
                // destroy the chart
                // Render another chart
            }, 100);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM