chart.js tải dữ liệu hoàn toàn mới


87

API chochart.js phép một người chỉnh sửa các điểm của tập dữ liệu được tải vào đó, ví dụ:

.update( )

Việc gọi update () trên bản sao Biểu đồ của bạn sẽ hiển thị lại biểu đồ với mọi giá trị được cập nhật, cho phép bạn chỉnh sửa giá trị của nhiều điểm hiện có, sau đó hiển thị những điểm đó trong một vòng kết xuất động.

.addData( valuesArray, label )

Gọi addData (valuesArray, label) trên cá thể Biểu đồ của bạn truyền một mảng giá trị cho mỗi tập dữ liệu, cùng với một nhãn cho các điểm đó.

.removeData( )

Gọi removeData () trên cá thể Biểu đồ của bạn sẽ xóa giá trị đầu tiên cho tất cả các tập dữ liệu trên biểu đồ.

Tất cả những điều này đều tuyệt vời, nhưng tôi không thể tìm ra cách tải một tập dữ liệu hoàn toàn mới vào, xóa sạch tập dữ liệu cũ. Tài liệu dường như không đề cập đến điều này.

Câu trả lời:


98

Tôi đã gặp vấn đề lớn với điều này

Đầu tiên tôi đã thử .clear()sau đó tôi đã thử .destroy()và tôi đã thử đặt tham chiếu biểu đồ của mình thành null

Điều cuối cùng đã khắc phục sự cố cho tôi: xóa <canvas>phần tử và sau đó xuất hiện lại một phần tử mới <canvas>vào vùng chứa mẹ


Có một triệu cách để làm điều này:

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
Câu trả lời này hoạt động, nhưng tôi thấy hủy cũng hoạt động trong phiên bản mới nhất. Được đề xuất trên bài đăng này - github.com/nnnick/Chart.js/issues/559
HockeyJ

nó sẽ giúp div graph-container trống để xóa iframe cũ $ ('# results-graph'). remove (); $ ('# graph-container'). blank (); $ ('# graph-container'). append ('<canvas id = "results-graph"> <canvas>');
heyyan khan

66

Bạn cần tiêu diệt:

myLineChart.destroy();

Sau đó khởi tạo lại biểu đồ:

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

2
chỉ cần sử dụng nó như thế này if (window.myLine) {window.myLine.destroy (); } HOẶC if (myLineChart) {myLineChart.destroy (); }
jayant singh

Có thể xác nhận việc phá hủy sau đó khởi tạo lại không gây ra bất kỳ nhấp nháy nào và có vẻ như các điểm dữ liệu đã được cập nhật động
Titan

40

Với Chart.js V2.0, bạn có thể làm như sau:

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

18
Chính xác những gì op yêu cầu.
Perry

2
Khi tôi làm vậy chart.config.data = newData, tôi gặp lỗi này: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') Ai đó có cùng vấn đề?
Benjamin Lucidarme

21

Đây là một chủ đề cũ, nhưng trong phiên bản hiện tại (kể từ 1-feb-2017), có thể dễ dàng thay thế các tập dữ liệu được vẽ trên chart.js:

giả sử các giá trị trục x mới của bạn nằm trong mảng x và các giá trị trục y nằm trong mảng y, bạn có thể sử dụng mã bên dưới để cập nhật biểu đồ.

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

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

chart.update();

Cảm ơn rất nhiều, Man! Lãng phí cả ngày. Cuối cùng tình cờ gặp câu trả lời của bạn. Cảm ơn bạn.
Dronacharya

Điều này rất hữu ích và làm việc cho tôi. Ngay cả khi chỉ sử dụng [] để đặt một tập dữ liệu trống, và sau đó thực hiện một "lần đẩy" mới cũng sẽ thực hiện được thủ thuật.
TS

17

ChartJS 2.6 hỗ trợ thay thế tham chiếu dữ liệu (xem Lưu ý trong tài liệu cập nhật (cấu hình)). Vì vậy, khi bạn có Biểu đồ của mình, về cơ bản bạn có thể thực hiện điều này:

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

Nó không tạo hoạt ảnh mà bạn nhận được khi thêm điểm, nhưng các điểm hiện có trên biểu đồ sẽ được làm động.


12

Giải pháp của tôi cho điều này là khá đơn giản. (PHIÊN BẢN 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 ...

Không nhấp nháy hoặc các vấn đề. getDataSetlà một chức năng để kiểm soát tập dữ liệu nào tôi cần trình bày


Bạn có thể thêm đoạn mã của getDataSet () không?
Gotham's Reckoning

1
Thêm getDataSet () Ví dụ
Henrique C.


6

Theo tài liệu, hãy clear()xóa canvas. Hãy coi nó như công cụ Eraser trong Paint. Nó không liên quan gì đến dữ liệu hiện được tải trong phiên bản biểu đồ.

Việc phá hủy phiên bản và tạo một phiên bản mới là lãng phí. Thay vào đó, hãy sử dụng các phương thức API removeData()addData(). Những điều này sẽ thêm / bớt một phân đoạn vào / khỏi phiên bản biểu đồ. Vì vậy, nếu bạn muốn tải dữ liệu hoàn toàn mới, chỉ cần lặp một mảng dữ liệu biểu đồ và gọi removeData(index)(chỉ mục mảng phải tương ứng với chỉ mục phân đoạn hiện tại). Sau đó, sử dụng addData(index)để điền vào nó với dữ liệu mới. Tôi đề xuất gói hai phương pháp để lặp lại dữ liệu, vì chúng mong đợi một chỉ mục phân đoạn duy nhất. Tôi sử dụng resetChartupdateChart. Trước khi tiếp tục, hãy đảm bảo bạn kiểm tra Chart.jsphiên bản và tài liệu mới nhất. Họ có thể đã thêm các phương pháp mới để thay thế dữ liệu hoàn toàn .


3
Tôi thích câu trả lời của bạn và nó phù hợp với thông tin tôi đã đọc trên mạng. Nếu bạn có thể chỉ ra và ví dụ điều đó sẽ thực sự hữu ích. Hai ví dụ mà tôi đã thấy trực tuyến tương tự là: jsbin.com/yitep/5/edit?html,js,outputjsbin.com/yitep/4/edit?html,js,output
Rethabile

Vấn đề duy nhất là việc cập nhật biểu đồ trở nên cực kỳ cồng kềnh và cực kỳ chậm nếu bạn phải thay thế dữ liệu biểu đồ bằng một tập dữ liệu hoàn toàn khác. Đối với người mới bắt đầu, tôi chưa tìm thấy cách cập nhật các nhãn trục x hiện có . Phá hủy và phục hồi toàn bộ biểu đồ là giải pháp thực sự duy nhất trong những trường hợp như vậy.
dối trá

Thật không may, tôi chỉ xử lý một biểu đồ Donut, ít phức tạp hơn. Bạn đã kiểm tra API mới nhất chưa?
adi518

4

Tôi gặp phải vấn đề tương tự, tôi có 6 biểu đồ hình tròn trên một trang mà tất cả có thể được cập nhật cùng một lúc. Tôi đang sử dụng chức năng sau để đặt lại dữ liệu biểu đồ.

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


Trong khi điều này hoạt động, tôi thấy rằng nó chậm hơn nhiều (do hoạt ảnh khi thêm từng điểm) so với việc tạo lại biểu đồ hoàn toàn.
Danila Vershinin

3

Tôi đã thử giải pháp neaumusic , nhưng sau đó phát hiện ra rằng vấn đề duy nhất với tiêu diệt là phạm vi .

var chart;

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

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

Di chuyển biến biểu đồ của tôi ra ngoài phạm vi chức năng, biến nó hoạt động cho tôi.


3

Không có câu trả lời nào ở trên giúp ích cho tình huống cụ thể của tôi một cách rất rõ ràng với mã tối thiểu. Tôi cần xóa tất cả các tập dữ liệu và sau đó lặp lại để thêm động một số tập dữ liệu vào. Vì vậy, đoạn trích này là dành cho những người tìm đến tận cuối trang mà không tìm thấy câu trả lời :)

Lưu ý: hãy đảm bảo gọi chart.update () khi bạn đã tải tất cả dữ liệu mới của mình vào đối tượng tập dữ liệu. Hy vọng điều này sẽ giúp ai đó

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

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

2

Bạn cần làm sạch dữ liệu cũ. Không cần khởi tạo lại:

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

1

Nếu ai đang tìm cách thực hiện điều này trong React. Đối với sơ đồ dòng, giả sử bạn có thành phần trình bao bọc xung quanh biểu đồ:

(Điều này giả sử bạn đang sử dụng v2. Bạn không cần phải sử dụng react-chartjs. Đây là sử dụng chart.jsgói thông thường từ 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>
  );
}

Các componentDidUpdatechức năng cho phép bạn cập nhật, bổ sung hoặc xóa bất kỳ dữ liệu từ this.props.data.


1

Không cần thiết phải phá hủy biểu đồ. Hãy thử với cái này

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

Vui lòng Tìm hiểu cách Chart.js (phiên bản 2 tại đây) hoạt động và làm điều đó cho bất kỳ thuộc tính nào bạn muốn:


1.Vui lòng giả sử bạn có một biểu đồ thanh như bên dưới trong HTML của mình:

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

2.Vui lòng giả sử bạn có mã javascript lấp đầy biểu đồ của bạn lần đầu tiên (ví dụ: khi trang được tải):

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

Hãy giả sử bạn muốn cập nhật đầy đủ tập dữ liệu của mình. Nó rất đơn giản. Vui lòng nhìn vào đoạn mã trên và xem đường dẫn từ biến biểu đồ của bạn đến dữ liệu như thế nào rồi làm theo đường dẫn bên dưới:

  • lựa chọn chartInstance var.
  • Sau đó chọn data nodebên trongchartInstance .
  • Sau đó chọn datasets nodebên trong data node.
    (lưu ý: Như bạn có thể thấy, datasets nodemảng là một mảng. Vì vậy, bạn phải chỉ định phần tử nào của mảng này mà bạn muốn. Ở đây chúng tôi chỉ có một phần tử trongdatasets node . Vì vậy, chúng tôi sử dụngdatasets[0]
  • Vì vậy, hãy chọn datasets[0]
  • Sau đó, chọn data nodebên trong trong datasets[0].


Các bước này cung cấp cho bạn chartInstance.data.datasets[0].datavà bạn có thể đặt dữ liệu mới và cập nhật biểu đồ:

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


Lưu ý: Bằng cách làm theo thuật toán trên, bạn có thể đạt được từng nút bạn muốn .


0

Giải pháp duy nhất mà tôi có thể tìm thấy cho đến nay là khởi tạo lại biểu đồ từ đầu:

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

Tuy nhiên điều này có vẻ hơi khó đối với tôi. Có ai tốt hơn, giải pháp tiêu chuẩn hơn không?


1
Điều này khá hiệu quả đối với tôi ngoại trừ trước tiên bạn cần thực hiện myLineChart.destroy () để loại bỏ cái cũ nếu không bạn sẽ gặp phải hiện tượng nhấp nháy khi nó vẽ lại.
user3413723

0

Tôi cũng gặp vô số rắc rối với điều này. Tôi có dữ liệu và nhãn trong các mảng riêng biệt, sau đó tôi khởi động lại dữ liệu biểu đồ. Tôi đã thêm dòng.destroy (); như đã đề xuất ở trên đã thực hiện thủ thuật

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


0

một cách để làm điều này mà không cần thanh toán bù trừ các vải hoặc bắt đầu lại, nhưng bạn phải cho con người xử lý việc tạo ra các biểu đồ để các dữ liệu có định dạng tương tự cho khi bạn cập nhật.

Đây là cách tôi đã làm điều đó.

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

Về cơ bản, tôi loại bỏ dữ liệu được tải vào khi tạo, và sau đó cải cách bằng phương pháp thêm dữ liệu. Điều này có nghĩa là sau đó tôi có thể truy cập tất cả các điểm. Bất cứ khi nào tôi cố gắng truy cập cấu trúc dữ liệu được tạo bởi:

Chart(ctx).Bar(dataNew);

lệnh, tôi không thể truy cập những gì tôi cần. Điều này có nghĩa là bạn có thể thay đổi tất cả các điểm dữ liệu, giống như cách bạn đã tạo chúng và cũng có thể gọi update () mà không cần tạo hoạt ảnh hoàn toàn từ đầu.


0

Biểu đồ JS 2.0

Chỉ cần đặt chart.data.labels = [];

Ví dụ:

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

Khi tạo đối tượng biểu đồ, bạn cần lưu thể hiện trong một biến.

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

Và trước khi tải dữ liệu mới, bạn cần hủy nó:

currentChart.destroy();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.