The API for chart.js
允许用户编辑加载到其中的数据集的点,例如:
.update( )
在Chart实例上调用update()将重新渲染图表 任何更新的值,允许您编辑多个值 现有的点,然后在一个动画渲染循环中渲染它们。
.addData( valuesArray, label )
在Chart实例上调用addData(valuesArray,label)并传递 每个数据集的值数组,以及这些点的标签。
.removeData( )
在Chart实例上调用removeData()将删除第一个 图表上所有数据集的值。
所有这些都很棒,但我无法弄清楚如何加载一个全新的数据集,消除旧的数据集。文档似乎没有涵盖这一点。
答案 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)
将其填入新数据。我建议包装两种方法来循环数据,因为他们期望单个段索引。我使用resetChart
和updateChart
。 在继续之前,请务必查看Chart.js
最新版本和文档。他们可能已经添加了完全替换数据的新方法。
答案 8 :(得分: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();
&#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)的工作原理,并针对所需的任何属性进行操作:
<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
键值是一个由 labels
和 datasets
两个键组成的对象。 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();