chart.js加载全新数据


87

该APIchart.js允许您编辑加载到其中的数据集的点,例如:

.update( )

在Chart实例上调用update()将使用任何更新的值重新渲染图表,从而允许您编辑多个现有点的值,然后在一个动画渲染循环中渲染这些点。

.addData( valuesArray, label )

在Chart实例上调用addData(valuesArray,label),以传递每个数据集的值数组以及这些点的标签。

.removeData( )

在Chart实例上调用removeData()将删除图表上所有数据集的第一个值。

所有这些都很棒,但是我无法弄清楚如何加载一个全新的数据集,从而清除掉旧数据集。该文档似乎没有涵盖此内容。

Answers:


98

我对此有很大的问题

首先我尝试了.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);
};

19
这个答案有效,但是我发现destroy在最新版本中也有效。在这篇文章中推荐-github.com/nnnick/Chart.js/issues/559
HockeyJ 2014年

这将有助于清空图形容器div删除旧的iframe $('#results-graph')。remove(); $('#graph-container')。empty(); $('#graph-container')。append('<canvas id =“ results-graph”> <canvas>');
heyyan khan

65

您需要销毁:

myLineChart.destroy();

然后重新初始化图表:

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

2
就像这样使用它if(window.myLine){window.myLine.destroy(); }或if(myLineChart){myLineChart.destroy(); }
jayant singh's

可以确认销毁然后重新初始化不会引起任何闪烁,并且看起来数据点是动态更新的
Titan

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

它是一个旧线程,但是在当前版本(截至2017年2月1日)中,它很容易替换在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支持数据引用替换(请参阅update(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的估算

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()清除画布。可以将其视为Paint中的橡皮擦工具。它与图表实例中当前加载的数据无关。

销毁实例并创建一个新实例是浪费的。相反,请使用API​​方法removeData()addData()。这些将向/从图表实例添加/删除单个细分。因此,如果要加载全新的数据,只需循环一个图表数据数组,然后调用removeData(index)(数组索引应对应于当前段索引)。然后,使用addData(index)填充新数据。我建议包装两种用于循环数据的方法,因为它们期望单个段索引。我使用resetChartupdateChart在继续之前,请确保您检查了Chart.js最新版本和文档。他们可能添加了新方法来完全替换数据


3
我喜欢您的答案,它与我在网上阅读的信息一致。如果您能够展示和举例说明,那将非常有帮助。我在网上看到的两个类似的示例是:jsbin.com/yitep/5/edit?html , js,
Rethabile 2016年

唯一的问题是,如果必须用本质上完全不同的数据集替换图表数据,则更新图表将变得非常繁琐且非常缓慢。首先,我还没有找到更新现有x轴标签的方法。在这种情况下,销毁并重新实例化整个图表是唯一真正的解决方案。
deceze

不幸的是,我只处理了一个不那么复杂的Donut图表。您是否签出了最新的API?
adi518 '16

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

我尝试了神经音乐方法,但是后来发现,destroy唯一的问题是范围

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.jsnpm中的常规软件包。)

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

请假设您想完全更新您的数据集。这很简单。请查看上面的代码,看看从图表变量到数据的路径如何,然后遵循以下路径:

  • 选择chartInstance变种
  • 然后选择data node里面的chartInstance
  • 然后选择datasets node里面的data node
    (注意:如您所见,thedatasets 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 2014年

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

我基本上会废弃创建时加载的数据,然后使用add data方法进行重整。这意味着我可以访问所有要点。每当我尝试访问由以下对象创建的数据结构时:

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.