एक कैनवास से एक चार्ट को कैसे साफ़ करें ताकि होवर की घटनाओं को ट्रिगर न किया जा सके?


109

मैं एक चार्ट चार्ट प्रदर्शित करने के लिए Chartjs का उपयोग कर रहा हूं और यह ठीक काम करता है:

// get line chart canvas
var targetCanvas = document.getElementById('chartCanvas').getContext('2d');

// draw line chart
var chart = new Chart(targetCanvas).Line(chartData);

लेकिन समस्या तब होती है जब मैं चार्ट के लिए डेटा बदलने की कोशिश करता हूं। मैं नए डेटा बिंदुओं के साथ चार्ट का एक नया उदाहरण बनाकर ग्राफ को अपडेट करता हूं, और इस तरह कैनवास को फिर से संगठित करता हूं।

यह ठीक काम करता है। हालाँकि, जब मैं नए चार्ट पर होवर करता हूं, अगर मैं पुराने चार्ट पर प्रदर्शित बिंदुओं के अनुरूप विशिष्ट स्थानों पर जाता हूं, तो होवर / लेबल अभी भी चालू है और अचानक पुराना चार्ट दिखाई दे रहा है। यह तब दिखाई देता है जब मेरा माउस इस स्थान पर होता है और उस बिंदु से दूर जाने पर गायब हो जाता है। मैं पुराने चार्ट को प्रदर्शित नहीं करना चाहता। मैं इसे पूरी तरह से हटाना चाहता हूं।

मैंने नया लोड करने से पहले कैनवास और मौजूदा चार्ट दोनों को साफ़ करने की कोशिश की है। पसंद:

targetCanvas.clearRect(0,0, targetCanvas.canvas.width, targetCanvas.canvas.height);

तथा

chart.clear();

लेकिन इनमें से किसी ने भी अब तक काम नहीं किया है। इस बारे में कोई विचार कि मैं इसे होने से कैसे रोक सकता हूं?


18
यार, यह वास्तव में मैं कर रहा हूँ समस्या है। "नष्ट ()" विधि काम नहीं करती है और यह मुझे बंद कर रही है।
नेउम्यूजिक जूल

क्या मैं पूछ सकता हूं कि आप चार्ट ऑब्जेक्ट तक कैसे पहुंच रहे हैं? मुझे वही समस्या हो रही है, मैं एक चार्ट बनाता हूं और फिर एक बटन पर क्लिक करने पर मुझे इसे नष्ट करने की आवश्यकता होती है, लेकिन यह पूरी तरह से अलग कार्य में है और मैं कैनवास या संदर्भ के माध्यम से चार्ट ऑब्जेक्ट तक पहुंचने का एक तरीका नहीं ढूंढ सकता हूं वस्तुओं।
मैट विलियम्स

इस मुद्दे के लिए एक बग खोला गया है, इसे यहां देखें। github.com/jtblin/angular-chart.js/issues/187
MDT

यह समस्या थी। बनाने के लिए समाधान / फिर से बनाने के stackoverflow.com/a/51882403/1181367
क्रिस

जवाबों:


142

मुझे इससे बहुत समस्याएँ थीं

पहले मैंने कोशिश की .clear()फिर मैंने कोशिश की .destroy()और मैंने अपने चार्ट संदर्भ को शून्य करने की कोशिश की

आखिरकार मेरे लिए क्या मुद्दा तय किया गया है: <canvas>तत्व को हटाना और फिर <canvas>मूल कंटेनर में एक नया पुन: लागू करना


मेरा विशिष्ट कोड (जाहिर है ऐसा करने के लिए एक लाख तरीके हैं):

var resetCanvas = function(){
  $('#results-graph').remove(); // this is my <canvas> element
  $('#graph-container').append('<canvas id="results-graph"><canvas>');
  canvas = document.querySelector('#results-graph');
  ctx = canvas.getContext('2d');
  ctx.canvas.width = $('#graph').width(); // resize to parent width
  ctx.canvas.height = $('#graph').height(); // resize to parent height
  var x = canvas.width/2;
  var y = canvas.height/2;
  ctx.font = '10pt Verdana';
  ctx.textAlign = 'center';
  ctx.fillText('This text is centered on the canvas', x, y);
};

2
एक विजेता की तरह काम किया। अगर किसी को पता है कि क्या चार्ट.जेएस संस्करण 2 इसे ठीक करता है, तो इसे यहां पोस्ट करें। मुझे आश्चर्य है कि अगर तोड़ दिया गया है या अगर हम इसे गलत तरीके से उपयोग कर रहे हैं।
TheLettuceMaster

2
अच्छा! धन्यवाद! मैंने अभी $ ('# परिणाम-ग्राफ') जोड़ा है। $ ('# ग्राफ-कंटेनर')। परिशिष्ट ('<कैनवास आईडी = "परिणाम-ग्राफ"> <कैनवास>'); चार्ट निर्माण से पहले।
इग्नासियो

.destroy () को ठीक काम करना चाहिए। यदि नया चार्ट बनाने के लिए .destroy () कॉल करने के बाद, यह सेटटाइमआउट () का उपयोग नहीं करता है
Sumeet Kale

यही एकमात्र समाधान मेरे लिए बहुत धन्यवाद का काम किया, लेकिन चौड़ाई और ऊंचाई के लिए यदि आपने पहले से ही उन्हें निर्धारित किया है तो आपको उन्हें रीसेट फ़ंक्शन में उसी मान पर रीसेट करना चाहिए
सैंडी एल्केसर

2
नष्ट () मेरे लिए 2.8.0 चार्ट के साथ विफल रहा, लेकिन आपके समाधान ने सिर्फ काम किया! मेरे मामले में मैं ही प्रयोग किया जाता $('#results-graph').remove(); $('#graph-container').append('<canvas id="results-graph"><canvas>');से पहलेnew Chart(document.getElementById("myCanvas")
मिमी

40

मैंने कुछ घंटों पहले भी इसी समस्या का सामना किया है।

".Clear ()" विधि वास्तव में कैनवास को साफ करती है, लेकिन (जाहिर है) यह वस्तु को जीवित और प्रतिक्रियाशील छोड़ देती है।

"उन्नत उपयोग" अनुभाग में आधिकारिक दस्तावेज को ध्यान से पढ़ते हुए , मैंने विधि ".destroy ()" पर ध्यान दिया है, जो इस प्रकार है:

"किसी भी चार्ट इंस्टेंसेस को नष्ट करने के लिए इसका उपयोग करें। इससे चार्ट ऑब्जेक्ट के भीतर चार्ट ऑब्जेक्ट पर संग्रहीत किसी भी संदर्भ को साफ किया जाएगा, साथ ही चार्ट.जेएस द्वारा संलग्न किसी भी संबंधित घटना श्रोताओं के साथ।"

यह वास्तव में वही करता है जो यह दावा करता है और इसने मेरे लिए ठीक काम किया है, मैं आपको यह कोशिश करने का सुझाव देता हूं।


क्या आप एक उदाहरण दिखा सकते हैं? मैंने कई बार ब्लॉकिंग का उपयोग करने की कोशिश की है और यह कभी काम नहीं करता है। मुझे हमेशा एक त्रुटि मिलती है कि विधि मौजूद नहीं है।
बेन हॉफमैन

3
(<चार्टइनस्टांस> this.chart) .destroy ();
डेविड दल बुस्को

2
यह सही anszwer है। भविष्य के संदर्भों के लिए देखें: stackoverflow.com/questions/40056555/…
ThePhi

29
var myPieChart=null;

function drawChart(objChart,data){
    if(myPieChart!=null){
        myPieChart.destroy();
    }
    // Get the context of the canvas element we want to select
    var ctx = objChart.getContext("2d");
    myPieChart = new Chart(ctx).Pie(data, {animateScale: true});
}

1
यह सबसे अच्छा विकल्प है
राफाशीष

अच्छा था। धन्यवाद
मंजूनाथ Siddappa

11

यह केवल एक चीज है जो मेरे लिए काम करती है:

document.getElementById("chartContainer").innerHTML = '&nbsp;';
document.getElementById("chartContainer").innerHTML = '<canvas id="myCanvas"></canvas>';
var ctx = document.getElementById("myCanvas").getContext("2d");

9

मुझे यहाँ भी यही समस्या थी ... मैंने नष्ट () और स्पष्ट () पद्धति का उपयोग करने की कोशिश की, लेकिन सफलता के बिना।

मैंने इसे अगले तरीके से हल किया:

HTML:

<div id="pieChartContent">
    <canvas id="pieChart" width="300" height="300"></canvas>
</div>

जावास्क्रिप्ट:

var pieChartContent = document.getElementById('pieChartContent');
pieChartContent.innerHTML = '&nbsp;';
$('#pieChartContent').append('<canvas id="pieChart" width="300" height="300"><canvas>');

ctx = $("#pieChart").get(0).getContext("2d");        
var myPieChart = new Chart(ctx).Pie(data, options);

यह मेरे लिए सही काम करता है ... मुझे आशा है कि यह मदद करता है।


5

इसने मेरे लिए बहुत अच्छा काम किया

    var ctx = $("#mycanvas");
     var LineGraph = new Chart(ctx, {
        type: 'line',
        data: chartdata});
        LineGraph.destroy();

किसी भी चार्ट इंस्टेंसेस को नष्ट करने के लिए .destroy का उपयोग करें । यह चार्ट ऑब्जेक्ट के भीतर चार्ट ऑब्जेक्ट में संग्रहीत किसी भी संदर्भ को साफ करेगा, साथ ही चार्ट.जेएस द्वारा संलग्न किसी भी संबंधित घटना श्रोताओं के साथ। कैनवास को नए चार्ट के लिए पुन: उपयोग करने से पहले इसे कॉल किया जाना चाहिए।


इस तरह मेरे लिए ठीक से काम करते हैं, ऐसा लगता है कि यह हॉवर कॉलबैक को नष्ट कर देता है। टैंक बहुत ज्यादा !!
एंटोनी पॉइंटू

4

हम चार्ट डेटा को चार्ट.जैस V2.0 में निम्नानुसार अपडेट कर सकते हैं:

var myChart = new Chart(ctx, data);
myChart.config.data = new_data;
myChart.update();

मैं इससे बेहतर समाधान के रूप में सहमत हूं - विनाश बेतहाशा बहुत कट्टरपंथी है, जब हम वास्तव में चाहते हैं कि केवल "डेटा" को पुनरारंभ करना है।
टीएस

1

कैनवस जेएस का उपयोग करते हुए, यह मेरे लिए चार्ट और अन्य सभी चीज़ों को साफ़ करने के लिए काम करता है, आपके लिए भी काम कर सकता है, और आपको अपना कैनवास / चार्ट पूरी तरह से प्रत्येक प्रसंस्करण से पहले सेट करने की अनुमति देता है:

var myDiv= document.getElementById("my_chart_container{0}";
myDiv.innerHTML = "";

मेरे लिए उपरोक्त विधियों में से गैर ने काम किया। यह पूरी तरह से काम किया। बहुत बहुत धन्यवाद।
शुरुआती

1

मैं .destroy () काम नहीं कर सका या तो मैं यही कर रहा हूं। चाट_परेंट डिव वह जगह है जहां मैं चाहता हूं कि कैनवास दिखे। मुझे हर बार आकार बदलने के लिए कैनवास की आवश्यकता है, इसलिए यह उत्तर उपरोक्त का एक विस्तार है।

HTML:

<div class="main_section" > <div id="chart_parent"></div> <div id="legend"></div> </div>

JQuery:

  $('#chart').remove(); // this is my <canvas> element
  $('#chart_parent').append('<label for = "chart">Total<br /><canvas class="chart" id="chart" width='+$('#chart_parent').width()+'><canvas></label>');

1

जब आप एक नया चार्ट बनाते हैं। जेएस कैनवस, यह एक नया आइफ्रेम छिपा हुआ उत्पन्न करता है, आपको कैनवस और ओलेड्स के नाम को हटाने की जरूरत है।

$('#canvasChart').remove(); 
$('iframe.chartjs-hidden-iframe').remove(); 
$('#graph-container').append('<canvas id="canvasChart"><canvas>'); 
var ctx = document.getElementById("canvasChart"); 
var myChart = new Chart(ctx, { blablabla });

संदर्भ: https://github.com/zebus3d/javascript/blob/master/chartJS_filtering_with_checkboxs.html


1

इसने मेरे लिए काम किया। क्लियरचैट पर कॉल जोड़ें, शीर्ष ओएफ पर अपना अपडेटचार्ट ()

`function clearChart() {
    event.preventDefault();
    var parent = document.getElementById('parent-canvas');
    var child = document.getElementById('myChart');          
    parent.removeChild(child);            
    parent.innerHTML ='<canvas id="myChart" width="350" height="99" ></canvas>';             
    return;
}`

1

यदि आप टाइपस्क्रिप्ट के साथ एक कोणीय परियोजना में चार्ट.जेएस का उपयोग कर रहे हैं, तो आप निम्नलिखित की कोशिश कर सकते हैं;

Import the library:
    import { Chart } from 'chart.js';

In your Component Class declare the variable and define a method:

  chart: Chart;

  drawGraph(): void {
    if (this.chart) {
      this.chart.destroy();
    }

    this.chart = new Chart('myChart', {
       .........
    });
  }


In HTML Template:
<canvas id="myChart"></canvas>

1

हमने जो किया, नए चार्ट के आरंभ से पहले, पूर्वावलोकन चार्ट उदाहरण को हटा दें / नष्ट कर दें, यदि पहले से मौजूद हैं, तो एक नया चार्ट बनाएं, उदाहरण के लिए

if(myGraf != undefined)
    myGraf.destroy();
    myGraf= new Chart(document.getElementById("CanvasID"),
    { 
      ...
    }

उम्मीद है की यह मदद करेगा।


1

एडम के जवाब को लागू करना

वेनिला जेएस के साथ:

document.getElementById("results-graph").remove(); //canvas
div = document.querySelector("#graph-container"); //canvas parent element
div.insertAdjacentHTML("afterbegin", "<canvas id='results-graph'></canvas>"); //adding the canvas again


1

2020 के लिए सरल संपादन:

इसने मेरे लिए काम किया। (से घोषणा बदलें यह स्वामित्व वाली खिड़की बनाकर वैश्विक करने के लिए चार्ट बदलें var myChartकरने के लिए window myChart)

जांचें कि क्या चार्ट चर पहले से ही चार्ट के रूप में आरंभीकृत है, यदि हां, तो इसे नष्ट करें और एक नया बनाएं, यहां तक ​​कि आप एक ही नाम पर एक और बना सकते हैं। नीचे कोड है:

if(window.myChart instanceof Chart)
{
    window.myChart.destroy();
}
var ctx = document.getElementById('myChart').getContext("2d");

मुझे भरोसा है ये काम करेगा!


1
बहुत बहुत धन्यवाद। यह मेरे लिए काम करता है।
दांते

0

मेरे लिए यह काम किया:

		var in_canvas = document.getElementById('chart_holder');
	//remove canvas if present
			while (in_canvas.hasChildNodes()) {
				  in_canvas.removeChild(in_canvas.lastChild);
				} 
	//insert canvas
			var newDiv = document.createElement('canvas');
			in_canvas.appendChild(newDiv);
			newDiv.id = "myChart";


0

Chart.js में एक बग है: Chart.controller(instance)एक वैश्विक संपत्ति में किसी भी नए चार्ट को पंजीकृत करता है Chart.instances[]और इसे इस संपत्ति से हटा देता है .destroy()

लेकिन चार्ट निर्माण में चार्ट.जेएस ._metaडेटासेट वेरिएबल के लिए भी संपत्ति लिखते हैं:

var meta = dataset._meta[me.id];
if (!meta) {
   meta = dataset._meta[me.id] = {
       type: null,
       data: [],
       dataset: null,
       controller: null,
       hidden: null,     // See isDatasetVisible() comment
       xAxisID: null,
       yAxisID: null
   };

और यह इस संपत्ति को नष्ट नहीं करता है destroy()

यदि आप अपने पुराने डेटासेट ऑब्जेक्ट को हटाए बिना उपयोग करते हैं ._meta property, तो चार्ट .js नए डेटासेट को ._metaबिना डिलीट किए पिछले डेटा में जोड़ देगा । इस प्रकार, प्रत्येक चार्ट के पुनः आरंभ में आपका डेटासेट ऑब्जेक्ट पिछले सभी डेटा को जमा करता है।

इससे बचने के लिए, कॉल करने के बाद डेटासेट ऑब्जेक्ट को नष्ट करें Chart.destroy()


0

चूंकि "सब कुछ" को नष्ट कर देता है, एक सस्ता और सरल समाधान जब आप वास्तव में चाहते हैं तो बस "डेटा रीसेट करें"। अपने डेटासेट को किसी खाली सरणी में रीसेट करना पूरी तरह से ठीक काम करेगा। इसलिए, यदि आपके पास लेबल वाला डेटासेट है, और हर तरफ एक धुरी है:

window.myLine2.data.labels = [];
window.myLine2.data.datasets[0].data = [];
window.myLine2.data.datasets[1].data = [];

इसके बाद, आप बस कॉल कर सकते हैं:

window.myLine2.data.labels.push(x);
window.myLine2.data.datasets[0].data.push(y);

या, इस बात पर निर्भर करता है कि आप 2d डेटासेट का उपयोग कर रहे हैं:

window.myLine2.data.datasets[0].data.push({ x: x, y: y});

यह आपके पूरे चार्ट / डेटासेट को पूरी तरह से नष्ट करने और सब कुछ पुनर्निर्माण करने की तुलना में बहुत अधिक हल्का होगा।


0

मेरे जैसे जो लोग कई ग्राफिक्स बनाने के लिए एक फ़ंक्शन का उपयोग करते हैं और उन्हें एक ब्लॉक भी अपडेट करना चाहते हैं, केवल फ़ंक्शन .destroy () ने मेरे लिए काम किया है, मुझे एक .update () बनाना पसंद है, जो क्लीनर लगता है लेकिन .. यहाँ एक कोड स्निपेट है जो मदद कर सकता है।

var SNS_Chart = {};

// IF LABELS IS EMPTY (after update my datas)
if( labels.length != 0 ){

      if( Object.entries(SNS_Chart).length != 0 ){

            array_items_datas.forEach(function(for_item, k_arr){
                SNS_Chart[''+for_item+''].destroy();
            });

       }

       // LOOP OVER ARRAY_ITEMS
       array_items_datas.forEach(function(for_item, k_arr){

             // chart
             OPTIONS.title.text = array_str[k_arr];
             var elem = document.getElementById(for_item);
             SNS_Chart[''+for_item+''] = new Chart(elem, {
                 type: 'doughnut',
                 data: {
                     labels: labels[''+for_item+''],
                     datasets: [{
                        // label: '',
                        backgroundColor: [
                            '#5b9aa0',
                            '#c6bcb6',
                            '#eeac99',
                            '#a79e84',
                            '#dbceb0',
                            '#8ca3a3',
                            '#82b74b',
                            '#454140',
                            '#c1502e',
                            '#bd5734'
                        ],
                        borderColor: '#757575',
                        borderWidth : 2,
                        // hoverBackgroundColor : '#616161',
                        data: datas[''+for_item+''],
                     }]
                 },
                 options: OPTIONS

             });
             // chart
       });
       // END LOOP ARRAY_ITEMS

  }
 // END IF LABELS IS EMPTY ...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.