chart.js завантажує абсолютно нові дані


87

API дляchart.js дозволяє редагувати точки завантажених у нього наборів даних, наприклад:

.update( )

Виклик update () на вашому екземплярі діаграми повторно відтворить діаграму з будь-якими оновленими значеннями, що дозволить вам редагувати значення декількох існуючих точок, а потім відтворювати їх в одному анімованому циклі візуалізації.

.addData( valuesArray, label )

Виклик addData (valuesArray, label) у вашому екземплярі Chart, передаючи масив значень для кожного набору даних, разом із міткою для цих точок.

.removeData( )

Виклик removeData () у вашому екземплярі діаграми видалить перше значення для всіх наборів даних на діаграмі.

Все це чудово, але я не можу зрозуміти, як завантажити абсолютно новий набір даних, видаляючи старий. Здається, документація цього не охоплює.

Відповіді:


98

У мене з цим були величезні проблеми

Спочатку я спробував, .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'); // 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);
};

19
Ця відповідь працює, але я виявив, що знищення також працює в останній версії. Рекомендовано в цій публікації - github.com/nnnick/Chart.js/issues/559
HockeyJ

це допомогло б порожньому div-контейнеру div видалити старі фрейми $ ('# results-graph'). remove (); $ ('# graph-container'). empty (); $ ('# graph-container'). append ('<canvas id = "results-graph"> <canvas>');
хай хейян

65

Вам потрібно знищити:

myLineChart.destroy();

Потім повторно ініціалізуйте діаграму:

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

2
просто використовуйте його таким чином if (window.myLine) {window.myLine.destroy (); } АБО якщо (myLineChart) {myLineChart.destroy (); }
jayant singh

Може підтвердити знищення, тоді повторна ініціалізація не спричиняє мерехтіння, і схоже, що точки даних динамічно оновлювались
Титан,

40

За допомогою Chart.js V2.0 ви можете зробити наступне:

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

18
Саме те, про що просив оператор.
Перрі

2
Коли я це роблю chart.config.data = newData, у мене виникає така помилка: TypeError: undefined is not an object (evaluating 'i.data.datasets.length') хтось має таку ж проблему?
Бенджамін Люсідарме

21

Це старий потік, але в поточній версії (станом на 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();

Дякую тонна, Чоловіче! Протрачено цілий день. Нарешті натрапив на вашу відповідь. Дякую.
Дроначаря,

Це було корисно і спрацювало для мене. Навіть просто використання [] для встановлення порожнього набору даних, а потім новий "натиск" також зробить трюк.
TS

17

ChartJS 2.6 підтримує заміну посилань на дані (див. Примітку в документації щодо оновлення (конфігурації)). Отже, коли у вас є ваша діаграма, ви можете в основному просто зробити це:

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 ()?
Розрахунок Готема

1
Додав приклад getDataSet ()
Енріке К.

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()очищає полотно. Подумайте про це як про інструмент «Ластик» у програмі Paint. Це не має нічого спільного з даними, завантаженими в даний момент в екземплярі діаграми.

Знищувати екземпляр і створювати новий марнотратно. Натомість використовуйте методи 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

Єдина проблема полягає в тому, що оновлення діаграми стає надзвичайно громіздким і надмірно повільним, якщо вам доводиться замінювати дані діаграми по суті зовсім іншим набором даних. Для початку я не знайшов способу оновити існуючі мітки осей х . Знищення та відновлення всієї діаграми є єдиним реальним рішенням за таких обставин.
обдурити

На жаль, я мав справу лише з діаграмою пончиків, яка є менш складною. Ви перевіряли найновіший 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();


Хоча це працює, я виявив, що це набагато повільніше (через анімацію при додаванні кожної точки) порівняно із відтворенням діаграми взагалі.
Даніла Вершинін,

3

Я спробував неаумузичне рішення, але пізніше з'ясував, що єдиною проблемою знищення є область дії .

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. Для лінійної діаграми, якщо ви маєте компонент-обгортку навколо діаграми:

(Це передбачає, що ви використовуєте 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. Будь ласка, припустимо, у вас є код JavaScript, який заповнює вашу діаграму вперше (наприклад, коли сторінка завантажується):

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

У мене з цим теж було багато клопоту. У мене є дані та мітки в окремих масивах, тоді я повторно ініціалізую дані діаграми. Я додав рядок.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);

команда, я не можу отримати доступ до того, що мені потрібно. Це означає, що ви можете змінити всі точки даних таким же чином, як ви їх створили, а також викликати update (), не анімуючи повністю з нуля.


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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.