chart.js加载全新的数据

时间:2014-07-16 16:15:41

标签: javascript chart.js

The API for chart.js允许用户编辑加载到其中的数据集的点,例如:

  

.update( )

     

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

     

.addData( valuesArray, label )

     

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

     

.removeData( )

     

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

所有这些都很棒,但我无法弄清楚如何加载一个全新的数据集,消除旧的数据集。文档似乎没有涵盖这一点。

21 个答案:

答案 0 :(得分:87)

我遇到了很多问题

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

答案 1 :(得分:55)

你需要销毁:

myLineChart.destroy();

然后重新初始化图表:

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

答案 2 :(得分:33)

使用Chart.js V2.0,您可以执行以下操作:

$scope.selOption = "Chest";

$scope.createEx = function() {
   if($scope.selOption === "Chest"){
      $scope.chestEx.push({title:...., reps:....});
      console.log("Test");
   }
   else {// as you need}
};

答案 3 :(得分:15)

这是一个旧线程,但在当前版本中(截至2017年1月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();

答案 4 :(得分:11)

我对此的解决方案非常简单。 (版本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是控制我需要呈现的数据集的函数

答案 5 :(得分:9)

ChartJS 2.6支持数据引用替换(请参阅update(config)文档中的Note)。因此,当您拥有图表时,基本上可以这样做:

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

它不会通过添加点来获得动画,但图表上的现有点将会被动画化。

答案 6 :(得分:6)

我在这里回答了How to clear a chart from a canvas so that hover events cannot be triggered?

但这是解决方案:

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

答案 7 :(得分:6)

根据文档,clear()清除画布。可以把它想象成Paint中的橡皮擦工具。它与图表实例中当前加载的数据无关。

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

答案 8 :(得分:4)

我遇到了同样的问题,我在一个页面上有6个饼图,可以同时更新。我正在使用以下功能重置图表数据。

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

答案 9 :(得分:3)

我尝试了neaumusic解决方案,但后来发现了only problem with destroy is the scope

var chart;

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

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

将我的图表变量移到函数范围之外,让它适合我。

答案 10 :(得分:2)

您需要清理旧数据。无需重新初始化:

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

答案 11 :(得分:2)

上述答案都没有以最少的代码以非常干净的方式帮助我的特殊情况。我需要删除所有数据集,然后循环以动态添加几个数据集。所以这个剪辑是针对那些一直到页面底部而没有找到答案的人:)

注意:确保在将所有新数据加载到数据集对象后调用chart.update()。希望这有助于某人

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

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

答案 12 :(得分:1)

如果有人在React中寻找如何做到这一点。对于折线图,假设图表周围有一个包装器组件:

(这假设您使用的是v2。您不需要使用react-chartjs。这是使用来自npm的普通chart.js包。)

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中的任何数据。

答案 13 :(得分: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();
    }

答案 14 :(得分: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
    (注意: 您会看到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();


注意: 通过遵循上述算法,您可以简单地实现所需的每个节点

答案 15 :(得分:0)

到目前为止,我能找到的唯一解决方案是从头开始重新初始化图表:

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

然而这对我来说似乎有点过分了。任何人都有更好,更标准的解决方案吗?

答案 16 :(得分: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()。

答案 17 :(得分: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

答案 18 :(得分:0)

图表JS 2.0

刚刚设置 chart.data.labels = [];

例如:

10.0.23.0

答案 19 :(得分:0)

创建图表对象时,您需要将实例保存在变量中。

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

在加载新数据之前,您需要销毁它:

currentChart.destroy();

答案 20 :(得分:0)

首先,让变量记住图表的一个实例。

             let yourChart = new Chart(ctxBar, {
                    type: 'bar',
                    data: {
                        labels: labels,
                        datasets: datasets
                    },
                });

其次,我最纠结的事情是在更新图表之前以正确的格式获取数据结构。所以在查看了图表 js 对象的 data 键结构后:

  data: {
        labels: ['Jan', 'Feb'],
        datasets: [{
            label: 'Net sales',
            data: data
        }, {
            label: 'Cost of goods sold',
            data: data
        }, {
            label: 'Gross margin',
            data: data
        }]
    }

请注意,data 键值是一个由 labelsdatasets 两个键组成的对象。 labels key' value 是一个数组,而 datasets key' value 也是一个以对象为值的数组。

因此,从我使用的图表实例中remove 标签和数据集:

yourChart.data.labels = [];
yourChart.data.datasets = [{}];
yourChart.update();

add 标签和数据集添加到我使用的图表实例中:

yourChart.data.labels = ['label 1', 'label 2'];
yourChart.data.datasets = [{
                label: 'column lables',
                data: [450, 50],
                backgroundColor: ["#dc3545", "#ffb759"]
            }];
yourChart.update();

准备服务器端
标签和数据集值可以在服务器端准备如下(在我的例子中是 php):

$datajs = function ($data, $bg_colour) // function emulating chart js datasets key value structure
        {
            return [
                'data' => $data,
                'backgroundColor' => $bg_colour
            ];
        };
$datasets = [];
$labels = ['label 1', 'label 2'];
$datasets[] = $datajs([42,10], ["#dc3545", "#ffb759"]);
$datasets[] = $datajs([100,5], ["#dc3545", "#ffb759"]);

只替换数据集中的数据键值中的数据(我没有测试这个)

yourChart.data.datasets.forEach((dataset) => {
    dataset.data = [];
});
yourChart.update();
// if you have an array of arrays
let array = [[42,20],[58,68],[78,1]];
let length = yourChart.data.datasets.length;
for (let i = 0; i < array.length; i++) {
    const element = array[i];
    if (i < length) {
        yourChart.data.datasets[i].data = element;
    } else {
        yourChart.data.datasets[] = {data: element};
    }
}
yourChart.update();