จะล้างแผนภูมิจากผืนผ้าใบเพื่อไม่ให้เกิดเหตุการณ์โฮเวอร์ได้อย่างไร


112

ฉันใช้ 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
เพื่อนนี่คือปัญหาที่ฉันมี เมธอด "destroy ()" ไม่ได้ผลและทำให้ฉันรู้สึกแย่
neaumusic

ฉันขอถามว่าคุณเข้าถึงวัตถุแผนภูมิได้อย่างไร ฉันมีปัญหาเดียวกันฉันสร้างแผนภูมิจากนั้นในการจัดการการคลิกปุ่มฉันต้องการทำลายมัน แต่มันอยู่ในฟังก์ชั่นที่แตกต่างไปจากเดิมอย่างสิ้นเชิงและฉันไม่สามารถหาวิธีเข้าถึงวัตถุแผนภูมิผ่านผืนผ้าใบหรือบริบทได้ วัตถุ
Matt Williams

มีข้อบกพร่องที่เปิดขึ้นสำหรับปัญหานี้โปรดดูที่นี่ github.com/jtblin/angular-chart.js/issues/187
MDT

มีปัญหานี้ วิธีสร้าง / สร้างใหม่stackoverflow.com/a/51882403/1181367
คริส

คำตอบ:


143

ฉันมีปัญหาใหญ่กับเรื่องนี้

ก่อนอื่นฉันลอง.clear()จากนั้นฉันก็ลอง.destroy()และฉันลองตั้งค่าการอ้างอิงแผนภูมิเป็น null

สิ่งที่แก้ไขปัญหาให้ฉันได้ในที่สุด: การลบ<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
ทำงานเหมือนแชมป์ หากใครทราบว่า Chart.js เวอร์ชัน 2 แก้ไขปัญหานี้ได้โปรดโพสต์ไว้ที่นี่ ฉันสงสัยว่าการทำลายนั้นพังหรือว่าเราใช้มันไม่ถูกต้อง
TheLettuceMaster

2
ดี! ขอบคุณ! ฉันเพิ่งเพิ่ม $ ('# results-graph') ลบ (); $ ('# graph-container') ผนวก ('<canvas id = "results-graph"> <canvas>'); ก่อนสร้างแผนภูมิ
Ignacio

.destroy () ควรใช้งานได้ดี หากไม่เป็นเช่นนั้นหลังจากเรียก. ทำลาย () เพื่อวาดแผนภูมิใหม่ให้ใช้ setTimeout ()
Sumeet Kale

นั่นเป็นทางออกเดียวที่ใช้ได้สำหรับฉันขอบคุณมาก แต่สำหรับความกว้างและความสูงหากคุณตั้งค่าไว้แล้วคุณควรรีเซ็ตเป็นค่าเดียวกันในฟังก์ชันรีเซ็ต
Sandy Elkassar

2
ทำลาย () ล้มเหลวสำหรับฉันด้วย chartjs 2.8.0 แต่โซลูชันของคุณใช้งานได้! ในกรณีของฉันฉันใช้$('#results-graph').remove(); $('#graph-container').append('<canvas id="results-graph"><canvas>');ก่อนnew Chart(document.getElementById("myCanvas")
mimi

40

ฉันประสบปัญหาเดียวกันเมื่อไม่กี่ชั่วโมงที่ผ่านมา

เมธอด ".clear ()" จะล้างผ้าใบจริง ๆ แต่ (เห็นได้ชัดว่า) ทำให้วัตถุมีชีวิตและมีปฏิกิริยา

เมื่ออ่านเอกสารอย่างเป็นทางการอย่างละเอียดในส่วน "การใช้งานขั้นสูง" ฉันสังเกตเห็นวิธีการ ".destroy ()" ซึ่งอธิบายไว้ดังนี้:

"ใช้สิ่งนี้เพื่อทำลายอินสแตนซ์แผนภูมิที่สร้างขึ้นซึ่งจะล้างข้อมูลอ้างอิงที่จัดเก็บไว้ในออบเจ็กต์แผนภูมิภายใน Chart.js พร้อมกับผู้ฟังเหตุการณ์ที่เกี่ยวข้องที่แนบมาโดย Chart.js"

มันทำตามที่กล่าวอ้างจริง ๆ และใช้ได้ผลดีสำหรับฉันฉันขอแนะนำให้คุณลองดู


ช่วยดูตัวอย่างได้ไหม ฉันพยายามใช้การบล็อกหลายครั้ง แต่ก็ไม่ได้ผล ฉันมักจะได้รับข้อผิดพลาดว่าวิธีนี้ไม่มีอยู่จริง
Ben Hoffman

3
(<ChartInstance> this.chart) .destroy ();
David Dal Busco

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
นี่คือทางเลือกที่ดีที่สุด
RafaSashi

สิ่งที่ดี. ขอบคุณ
Manjunath Siddappa

11

นี่เป็นสิ่งเดียวที่เหมาะกับฉัน:

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

9

ฉันมีปัญหาเดียวกันที่นี่ ... ฉันพยายามใช้เมธอด destroy () และ clear () แต่ไม่ประสบความสำเร็จ

ฉันแก้ไขด้วยวิธีต่อไป:

HTML:

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

Javascript:

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นี้เพื่อทำลายกรณีแผนภูมิใด ๆ ที่ถูกสร้างขึ้น การดำเนินการนี้จะล้างข้อมูลอ้างอิงที่จัดเก็บไว้ในออบเจ็กต์แผนภูมิภายใน Chart.js พร้อมกับผู้ฟังเหตุการณ์ที่เกี่ยวข้องที่แนบมาโดย Chart.js ต้องเรียกสิ่งนี้ก่อนที่จะนำผืนผ้าใบมาใช้ใหม่สำหรับแผนภูมิใหม่


วิธีนี้ใช้ได้ผลสำหรับฉันดูเหมือนว่ามันจะทำลายการเรียกกลับแบบโฮเวอร์ รถถังมาก !!
Antoine Pointeau

4

เราสามารถอัปเดตข้อมูลแผนภูมิใน Chart.js V2.0 ได้ดังนี้:

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

1
ฉันเห็นด้วยกับสิ่งนี้ว่าเป็นทางออกที่ดีกว่ามาก - Destroy นั้นรุนแรงเกินไปเมื่อเราต้องการเพียงแค่รีสตาร์ท "ข้อมูล"
TS

2

แก้ไขอย่างง่ายสำหรับปี 2020:

สิ่งนี้ได้ผลสำหรับฉัน เปลี่ยนแผนภูมิเป็นส่วนกลางโดยทำให้หน้าต่างเป็นเจ้าของ (เปลี่ยนการประกาศจากvar myChartเป็นwindow myChart )

ตรวจสอบว่าตัวแปรแผนภูมิเริ่มต้นเป็นแผนภูมิแล้วหรือไม่ถ้าเป็นเช่นนั้นให้ทำลายและสร้างใหม่แม้ว่าคุณจะสร้างตัวแปรอื่นในชื่อเดียวกันได้ ด้านล่างนี้คือรหัส:

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

หวังว่าจะได้ผล!


1

การใช้ CanvasJS วิธีนี้ใช้ได้ผลสำหรับฉันในการล้างแผนภูมิและทุกอย่างอาจเหมาะกับคุณเช่นกันโดยให้คุณตั้งค่าผืนผ้าใบ / แผนภูมิให้สมบูรณ์ก่อนที่จะประมวลผลที่อื่น:

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

สำหรับฉันวิธีการข้างต้นไม่ได้ผล สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบ ขอบคุณมาก.
เริ่มต้น

1

ฉันไม่สามารถทำให้. ทำลาย () ทำงานได้ดังนั้นนี่คือสิ่งที่ฉันกำลังทำอยู่ chart_parent div คือที่ที่ฉันต้องการให้แคนวาสแสดง ฉันต้องการผืนผ้าใบเพื่อปรับขนาดทุกครั้งดังนั้นคำตอบนี้จึงเป็นส่วนเสริมจากข้อข้างบน

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

เมื่อคุณสร้างผืนผ้าใบ chart.js ใหม่สิ่งนี้จะสร้าง iframe ใหม่ที่ซ่อนอยู่คุณต้องลบแคนวาสและ iframe แบบเก่า

$('#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

สิ่งนี้ได้ผลสำหรับฉัน เพิ่มการโทรไปที่ clearChart ที่ด้านบนของ updateChart ของคุณ ()

`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

หากคุณใช้ chart.js ในโครงการเชิงมุมที่มี typescript คุณสามารถลองทำสิ่งต่อไปนี้

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

เสริมคำตอบของอดัม

ด้วย Vanilla JS:

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


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()

แต่ในการสร้างแผนภูมิ Chart.js ยังเขียน._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 propertyChart.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 ...

0

ก่อนอื่นให้ใส่แผนภูมิในตัวแปรบางตัวจากนั้นบันทึกในครั้งต่อไปก่อนที่จะเริ่มต้น

# ตรวจสอบว่ามีวัตถุ myChart หรือไม่จากนั้นบิดเบือน

    if($scope.myChart) {
      $scope.myChart.destroy();
    }

    $scope.myChart  = new Chart(targetCanvas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.