chart.js โหลดข้อมูลใหม่ทั้งหมด


89

API สำหรับchart.jsอนุญาตให้หนึ่งแก้ไขจุดของชุดข้อมูลที่โหลดลงในนั้นตัวอย่างเช่น:

.update( )

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

.addData( valuesArray, label )

การเรียก addData (valuesArray, label) บนอินสแตนซ์แผนภูมิของคุณซึ่งส่งผ่านอาร์เรย์ของค่าสำหรับแต่ละชุดข้อมูลพร้อมกับป้ายกำกับสำหรับจุดเหล่านั้น

.removeData( )

การเรียก removeData () บนอินสแตนซ์แผนภูมิของคุณจะลบค่าแรกสำหรับชุดข้อมูลทั้งหมดบนแผนภูมิ

ทั้งหมดนี้ยอดเยี่ยมมาก แต่ฉันไม่สามารถหาวิธีโหลดชุดข้อมูลใหม่ทั้งหมดได้โดยจะลบข้อมูลเก่าออกไป เอกสารประกอบดูเหมือนจะไม่ครอบคลุมถึงเรื่องนี้

คำตอบ:


100

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

ก่อนอื่นฉันลอง.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'); // why use jQuery?
  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);
};

20
คำตอบนี้ใช้ได้ แต่ฉันพบว่าการทำลายยังใช้งานได้ในเวอร์ชันล่าสุด แนะนำในโพสต์นี้ - github.com/nnnick/Chart.js/issues/559
HockeyJ

มันจะช่วยให้ div คอนเทนเนอร์กราฟว่างเปล่าเพื่อลบ iframe เก่า $ ('# results-graph') ลบ (); $ ('# กราฟคอนเทนเนอร์') ว่าง (); $ ('# graph-container') ผนวก ('<canvas id = "results-graph"> <canvas>');
heyyan khan

66

คุณต้องทำลาย:

myLineChart.destroy();

จากนั้นเริ่มต้นแผนภูมิใหม่:

var ctx = document.getElementById("myChartLine").getContext("2d");
myLineChart = new Chart(ctx).Line(data, options);

2
เพียงใช้มันในลักษณะนี้หาก (window.myLine) {window.myLine.destroy (); } หรือถ้า (myLineChart) {myLineChart.destroy (); }
jayant singh

สามารถยืนยันได้ว่าการทำลายแล้วการเริ่มต้นใหม่จะไม่ทำให้เกิดการกะพริบและดูเหมือนว่าจุดข้อมูลได้รับการอัปเดตแบบไดนามิก
ไททัน

40

ด้วย Chart.js V2.0 คุณสามารถทำสิ่งต่อไปนี้:

websiteChart.config.data = some_new_data;
websiteChart.update();

18
สิ่งที่หน่วยงานขอ
Perry

2
เมื่อทำเช่นchart.config.data = newDataนี้ฉันมีข้อผิดพลาด: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') มีคนมีปัญหาเดียวกันหรือไม่?
Benjamin Lucidarme

22

เป็นเธรดเก่า แต่ในเวอร์ชันปัจจุบัน (ณ วันที่ 1 กุมภาพันธ์ 2017) ง่ายต่อการแทนที่ชุดข้อมูลที่ลงจุดใน chart.js:

สมมติว่าค่าแกน x ใหม่ของคุณอยู่ในอาร์เรย์ x และค่าแกน y อยู่ในอาร์เรย์ y คุณสามารถใช้โค้ดด้านล่างเพื่ออัปเดตแผนภูมิได้

var x = [1,2,3];
var y = [1,1,1];

chart.data.datasets[0].data = y;
chart.data.labels = x;

chart.update();

ขอบคุณมากผู้ชาย! เสียเวลาทั้งวัน. ในที่สุดก็สะดุดกับคำตอบของคุณ ขอขอบคุณ.
Dronacharya

นี่เป็นประโยชน์และได้ผลสำหรับฉัน แม้เพียงแค่ใช้ [] เพื่อตั้งค่าชุดข้อมูลที่ว่างเปล่าจากนั้นการ "พุช" ใหม่ก็จะทำเคล็ดลับเช่นกัน
TS

17

ChartJS 2.6 รองรับการแทนที่ข้อมูลอ้างอิง (ดูหมายเหตุในเอกสารประกอบการอัพเดต (config)) ดังนั้นเมื่อคุณมีแผนภูมิคุณสามารถทำได้โดยทั่วไป:

myChart.data.labels = ['1am', '2am', '3am', '4am'];
myChart.data.datasets[0].data = [0, 12, 35, 36];
myChart.update();

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


12

วิธีแก้ปัญหาของฉันค่อนข้างง่าย (รุ่น 1.X)

getDataSet:function(valuesArr1,valuesArr2){
        var dataset = [];
        var arr1 = {
            label: " (myvalues1)",
            fillColor: "rgba(0, 138, 212,0.5)",
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(0, 138, 212,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: valuesArr1
        };
        var arr2 = {
            label: " (myvalues2)",
            fillColor: "rgba(255, 174, 087,0.5)",
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(255, 174, 087,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: valuesArr2
        };
        /*Example conditions*/
        if(condition 1)
          dataset.push(arr1);
        }
        if(condition 2){
          dataset.push(arr1);
          dataset.push(arr2);
        }

        return dataset;
    }

var data = {
    labels: mylabelone,
    datasets: getDataSet()
};
if(myBarChart != null) // i initialize myBarChart var with null
    myBarChart.destroy(); // if not null call destroy
    myBarChart = new Chart(ctxmini).Bar(data, options);//render it again ...

ไม่มีริบหรี่หรือปัญหา getDataSetเป็นฟังก์ชั่นที่ใช้ควบคุมชุดข้อมูลที่ฉันต้องนำเสนอ


คุณสามารถเพิ่มข้อมูลโค้ดของ getDataSet () ด้วยได้หรือไม่?
Gotham's Reckoning

1
เพิ่มตัวอย่าง getDataSet ()
Henrique C.

8

ฉันตอบสิ่งนี้ที่นี่ดูวิธีการล้างแผนภูมิจากผืนผ้าใบเพื่อไม่ให้เกิดเหตุการณ์โฮเวอร์?

แต่นี่คือทางออก:

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});
}

6

ตามเอกสารให้clear()ล้างผ้าใบ คิดว่าเป็นเครื่องมือยางลบในโปรแกรมระบายสี ไม่มีส่วนเกี่ยวข้องกับข้อมูลที่โหลดในอินสแตนซ์แผนภูมิ

การทำลายอินสแตนซ์และสร้างใหม่นั้นสิ้นเปลือง ให้ใช้เมธอด API removeData()และaddData(). สิ่งเหล่านี้จะเพิ่ม / ลบกลุ่มเดียวไปยัง / จากอินสแตนซ์แผนภูมิ ดังนั้นหากคุณต้องการโหลดข้อมูลใหม่ทั้งหมดให้วนซ้ำอาร์เรย์ข้อมูลแผนภูมิแล้วเรียกremoveData(index)(ดัชนีอาร์เรย์ควรสอดคล้องกับดัชนีเซ็กเมนต์ปัจจุบัน) จากนั้นใช้addData(index)เพื่อเติมข้อมูลใหม่ ฉันขอแนะนำให้รวมสองวิธีในการวนซ้ำข้อมูลเนื่องจากคาดว่าจะมีดัชนีกลุ่มเดียว ฉันใช้resetChartและupdateChart. ก่อนดำเนินการต่อโปรดตรวจสอบChart.jsเวอร์ชันล่าสุดและเอกสารประกอบ พวกเขาอาจเพิ่มวิธีการใหม่ในการแทนที่ข้อมูลทั้งหมดพวกเขาอาจจะได้เพิ่มวิธีการใหม่สำหรับการเปลี่ยนข้อมูลที่สมบูรณ์


3
ฉันชอบคำตอบของคุณและสอดคล้องกับข้อมูลที่ฉันอ่านทางออนไลน์ หากคุณสามารถแสดงและเป็นตัวอย่างที่จะเป็นประโยชน์จริงๆ สองตัวอย่างที่ฉันได้เห็นทางออนไลน์ที่คล้ายกันคือ: jsbin.com/yitep/5/edit?html,js,outputและjsbin.com/yitep/4/edit?html,js,output
Rethabile

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

น่าเสียดายที่ฉันจัดการกับแผนภูมิโดนัทซึ่งมีความซับซ้อนน้อยกว่า คุณตรวจสอบ API ล่าสุดหรือไม่
adi518

4

ฉันพบปัญหาเดียวกันฉันมีแผนภูมิวงกลม 6 รายการในหน้าซึ่งสามารถอัปเดตพร้อมกันได้ทั้งหมด ฉันกำลังใช้ฟังก์ชันต่อไปนี้เพื่อรีเซ็ตข้อมูลแผนภูมิ

// sets chart segment data for previously rendered charts
function _resetChartData(chart, new_segments) {
    // remove all the segments
    while (chart.segments.length) {
        chart.removeData();
    };

    // add the new data fresh
    new_segments.forEach (function (segment, index) {
        chart.addData(segment, index);
    });
};

// when I want to reset my data I call
_resetChartData(some_chart, new_data_segments);
some_chart.update();


ในขณะที่ใช้งานได้ฉันพบว่ามันช้ากว่ามาก (เนื่องจากภาพเคลื่อนไหวเมื่อเพิ่มแต่ละจุด) เมื่อเทียบกับการสร้างแผนภูมิใหม่ทั้งหมด
Danila Vershinin

3

ฉันพยายามneaumusicวิธีการแก้ปัญหา แต่ต่อมาพบว่าปัญหาเฉพาะกับทำลายเป็นขอบเขต

var chart;

function renderGraph() {
    // Destroy old graph
    if (chart) {
        chart.destroy();
    }

    // Render chart
    chart = new Chart(
        document.getElementById(idChartMainWrapperCanvas),
        chartOptions
    );
}

การย้ายตัวแปรแผนภูมิของฉันออกนอกขอบเขตฟังก์ชันทำให้ฉันได้ผล


3

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

หมายเหตุ: อย่าลืมเรียกใช้ chart.update () เมื่อคุณโหลดข้อมูลใหม่ทั้งหมดลงในออบเจ็กต์ชุดข้อมูลแล้ว หวังว่านี่จะช่วยใครสักคน

function removeData(chart) {
   chart.data.datasets.length = 0;
}

function addData(chart, data) {
  chart.data.datasets.push(data);
}

2

คุณต้องล้างข้อมูลเก่า ไม่จำเป็นต้องเริ่มต้นใหม่:

for (i in myChartLine.datasets[0].points)
    myChartLine.removeData();

1

หากใครกำลังมองหาวิธีการทำใน React สำหรับ linechart สมมติว่าคุณมีส่วนประกอบของ wrapper รอบ ๆ แผนภูมิ:

(สมมติว่าคุณกำลังใช้ v2 คุณไม่จำเป็นต้องใช้react-chartjsนี่เป็นการใช้chart.jsแพ็คเกจปกติจาก npm)

propTypes: {
  data: React.PropTypes.shape({
    datasets: React.PropTypes.arrayOf(
      React.PropTypes.shape({

      })
    ),
    labels: React.PropTypes.array.isRequired
  }).isRequired
},
componentDidMount () {
  let chartCanvas = this.refs.chart;

  let myChart = new Chart(chartCanvas, {
    type: 'line',
    data: this.props.data,
    options: {
      ...
    }
  });

  this.setState({chart: myChart});
},
componentDidUpdate () {
    let chart = this.state.chart;
    let data = this.props.data;

    data.datasets.forEach((dataset, i) => chart.data.datasets[i].data = dataset.data);

    chart.data.labels = data.labels;
    chart.update();
},
render () {
  return (
    <canvas ref={'chart'} height={'400'} width={'600'}></canvas>
  );
}

componentDidUpdateฟังก์ชันการทำงานที่ช่วยให้คุณสามารถปรับปรุงเพิ่มหรือลบข้อมูลใด ๆ this.props.dataจาก


1

ไม่จำเป็นต้องทำลายแผนภูมิ ลองกับสิ่งนี้

function removeData(chart) {

        let total = chart.data.labels.length;

        while (total >= 0) {
            chart.data.labels.pop();
            chart.data.datasets[0].data.pop();
            total--;
        }

        chart.update();
    }

1

โปรดเรียนรู้วิธีการทำงานของ Chart.js (เวอร์ชัน 2 ที่นี่) และทำกับแอตทริบิวต์ใดก็ได้ที่คุณต้องการ:


1. โปรดสมมติว่าคุณมีแผนภูมิแท่งดังต่อไปนี้ใน HTML ของคุณ:

<canvas id="your-chart-id" height="your-height" width="your-width"></canvas>

2. โปรดสมมติว่าคุณมีโค้ดจาวาสคริปต์ที่เติมแผนภูมิของคุณเป็นครั้งแรก (ตัวอย่างเช่นเมื่อโหลดหน้า):

var ctx = document.getElementById('your-chart-id').getContext('2d');
var chartInstance = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: your-lables-array,
        datasets: [{
            data: your-data-array,
            /*you can create random colors dynamically by ColorHash library [https://github.com/zenozeng/color-hash]*/
            backgroundColor: your-lables-array.map(function (item) {
                return colorHash.hex(item);
            })
        }]
    },
    options: {
        maintainAspectRatio: false,
        scales: {
            yAxes: [ { ticks: {beginAtZero: true} } ]
        },
        title: {display: true, fontSize: 16, text: 'chart title'},
        legend: {display: false}
    }
});

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

  • เลือกchartInstancevar.
  • จากนั้นเลือกdata nodeภายในไฟล์chartInstance.
  • จากนั้นเลือกdatasets nodeภายในไฟล์data node.
    (หมายเหตุ: อย่างที่คุณเห็นdatasets nodeคืออาร์เรย์ดังนั้นคุณต้องระบุว่าคุณต้องการองค์ประกอบใดของอาร์เรย์ที่นี่เรามีเพียงองค์ประกอบเดียวเท่านั้นdatasets nodeดังนั้นเราจึงใช้datasets[0]
  • ดังนั้นเลือก datasets[0]
  • จากนั้นเลือกdata nodeภายในในไฟล์datasets[0].


ขั้นตอนนี้ให้คุณchartInstance.data.datasets[0].dataและคุณสามารถตั้งค่าข้อมูลใหม่และอัปเดตแผนภูมิได้:

chartInstance.data.datasets[0].data = NEW-your-data-array
//finally update chart var:
chartInstance.update();


หมายเหตุ: ด้วยการทำตามอัลกอริทึมข้างต้นคุณสามารถบรรลุแต่ละโหนดที่คุณต้องการได้


0

ทางออกเดียวที่ฉันสามารถพบได้ในตอนนี้คือการเริ่มต้นแผนภูมิใหม่ตั้งแต่ต้น:

var myLineChart = new Chart(ctx).Line(data, options);

อย่างไรก็ตามสิ่งนี้ดูเหมือนจะเป็นเรื่องที่น่ายินดีสำหรับฉัน มีโซลูชันที่ดีกว่าและมีมาตรฐานกว่าใคร


1
วิธีนี้ใช้ได้ผลกับฉันมากยกเว้นคุณต้องทำ myLineChart.destroy () ก่อนเพื่อกำจัดอันเก่าไม่งั้นคุณจะสั่นไหวเมื่อวาดใหม่
user3413723

0

ฉันมีปัญหากับเรื่องนี้มากเช่นกัน ฉันมีข้อมูลและป้ายกำกับในอาร์เรย์แยกต่างหากจากนั้นฉันจะเริ่มต้นข้อมูลแผนภูมิใหม่ ฉันเพิ่ม line.destroy (); ตามที่แนะนำไว้ข้างต้นซึ่งได้ทำเคล็ดลับแล้ว

var ctx = document.getElementById("canvas").getContext("2d");
if(window.myLine){
	window.myLine.destroy();
}
window.myLine = new Chart(ctx).Line(lineChartData, {
  etc
  etc


0

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

นี่คือวิธีที่ฉันทำ

    var ctx = document.getElementById("myChart").getContext("2d");
    if (chartExists) {
        for (i=0;i<10;i++){
            myNewChart.scale.xLabels[i]=dbLabels[i]; 
            myNewChart.datasets[0].bars[i].value=dbOnAir[i];
        }
        myNewChart.update();
      }else{
          console.log('chart doesnt exist');
          myNewChart = new Chart(ctx).Bar(dataNew);
          myNewChart.removeData();
          for (i=0;i<10;i++){
              myNewChart.addData([10],dbLabels[i]);
          }
          for (i=0;i<10;i++){      
              myNewChart.datasets[0].bars[i].value=dbOnAir[i];
          }
          myNewChart.update();
          chartExists=true;
        }

โดยพื้นฐานแล้วฉันคัดลอกข้อมูลที่โหลดในการสร้างจากนั้นปฏิรูปด้วยวิธีการเพิ่มข้อมูล ซึ่งหมายความว่าฉันสามารถเข้าถึงทุกจุดได้แล้ว เมื่อใดก็ตามที่ฉันพยายามเข้าถึงโครงสร้างข้อมูลที่สร้างขึ้นโดย:

Chart(ctx).Bar(dataNew);

คำสั่งฉันไม่สามารถเข้าถึงสิ่งที่ต้องการได้ ซึ่งหมายความว่าคุณสามารถเปลี่ยนจุดข้อมูลทั้งหมดได้ในลักษณะเดียวกับที่คุณสร้างขึ้นและยังเรียกอัปเดต () โดยไม่ต้องเคลื่อนไหวอย่างสมบูรณ์ตั้งแต่ต้น


0

แผนภูมิ JS 2.0

เพียงตั้งค่า chart.data.labels = [];

ตัวอย่างเช่น:

function addData(chart, label, data) {
    chart.data.labels.push(label);
    chart.data.datasets.forEach((dataset) => {
       dataset.data.push(data);
    });
    chart.update();
}

$chart.data.labels = [];

$.each(res.grouped, function(i,o) {
   addData($chart, o.age, o.count);
});
$chart.update();

0

เมื่อสร้างวัตถุแผนภูมิคุณต้องบันทึกอินสแตนซ์ในตัวแปร

var currentChart = new Chart(ctx, ...);

และก่อนที่จะโหลดข้อมูลใหม่คุณต้องทำลายมัน:

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