chart.js는 완전히 새로운 데이터를로드합니다.


87

에 대한 API를chart.js 사용하면로드 된 데이터 세트의 포인트를 수정할 수 있습니다. 예를 들면 다음과 같습니다.

.update( )

Chart 인스턴스에서 update ()를 호출하면 업데이트 된 값으로 차트를 다시 렌더링하여 여러 기존 포인트의 값을 편집 한 다음 애니메이션 렌더링 루프 하나로 렌더링 할 수 있습니다.

.addData( valuesArray, label )

Chart 인스턴스에서 addData (valuesArray, label)를 호출하여 각 데이터 세트에 대한 값 배열과 해당 포인트에 대한 레이블을 전달합니다.

.removeData( )

Chart 인스턴스에서 removeData ()를 호출하면 차트의 모든 데이터 세트에 대한 첫 번째 값이 제거됩니다.

이 모든 것이 훌륭하지만 완전히 새로운 데이터 세트를로드하여 이전 데이터를 지우는 방법을 알 수 없습니다. 문서는 이것을 다루지 않는 것 같습니다.

답변:


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

20
이 답변은 작동하지만 destroy는 최신 버전에서도 작동합니다. 이 게시물에 대한 추천 -github.com/nnnick/Chart.js/issues/559
HockeyJ

빈 그래프 컨테이너 div가 오래된 iframe을 제거하는 데 도움이 될 것입니다 $ ( '# results-graph'). remove (); $ ( '# 그래프 컨테이너') .empty (); $ ( '# graph-container'). append ( '<canvas id = "results-graph"> <canvas>');
heyyan 칸

66

다음을 파괴해야합니다.

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

삭제 후 다시 초기화해도 깜박임이 발생하지 않고 데이터 포인트가 동적으로 업데이트 된 것처럼 보이는지 확인할 수 있습니다.
Titan

40

Chart.js V2.0을 사용하면 다음을 수행 할 수 있습니다.

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

18
작전이 요청한 것입니다.
Perry

2
할 때 chart.config.data = newData다음 오류가 발생합니다. TypeError: undefined is not an object (evaluating 'i.data.datasets.length') 누군가 같은 문제가 있습니까?
벤자민 Lucidarme

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

고마워요, Man! 하루 종일 낭비. 마침내 당신의 대답을 우연히 발견했습니다. 감사합니다.
Dronacharya

이것은 도움이되었고 나를 위해 일했습니다. []를 사용하여 빈 데이터 세트를 설정 한 다음 새로운 "푸시"를 수행하는 것도 트릭을 수행합니다.
TS

17

ChartJS 2.6은 데이터 참조 대체를 지원합니다 ( update (config) 문서의 Note 참조 ). 따라서 Chart가 있으면 기본적으로 다음과 같이 할 수 있습니다.

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 's Reckoning

1
getDataSet () 예를 들어 추가
엔리케 C.


6

문서에 따르면 clear()캔버스를 지 웁니다. 그림판의 지우개 도구라고 생각하면됩니다. 현재 차트 인스턴스에로드 된 데이터와 관련이 없습니다.

인스턴스를 삭제하고 새 인스턴스를 만드는 것은 낭비입니다. 대신 API 메서드 removeData()addData(). 이는 차트 인스턴스에서 단일 세그먼트를 추가 / 제거합니다. 따라서 완전히 새로운 데이터를로드하려면 차트 데이터 배열을 반복하고 호출하면됩니다 removeData(index)(배열 인덱스는 현재 세그먼트 인덱스와 일치해야 함). 그런 다음을 사용 addData(index)하여 새 데이터로 채 웁니다. 단일 세그먼트 인덱스를 기대하므로 데이터를 반복하는 두 가지 방법을 래핑하는 것이 좋습니다. 나는 resetChartupdateChart. 계속하기 전에 Chart.js최신 버전과 문서 를 확인하십시오 . 데이터를 완전히 대체하는 새로운 방법을 추가했을 수 있습니다 .


3
나는 당신의 대답과 내가 온라인에서 읽은 정보와 일치하는 것을 좋아합니다. 당신이 보여줄 수 있다면 정말 도움이 될 것입니다. 비슷한 온라인에서 본 두 가지 예는 다음과 같습니다. jsbin.com/yitep/5/edit?html,js,outputjsbin.com/yitep/4/edit?html,js,output
Rethabile

유일한 문제는 차트 데이터를 본질적으로 완전히 다른 데이터 세트로 교체해야하는 경우 차트 업데이트가 매우 번거롭고 매우 느려진다는 것입니다. 우선, 기존 x 축 레이블 을 업데이트하는 방법을 찾지 못했습니다 . 이러한 상황에서 전체 차트를 삭제하고 다시 인스턴스화하는 것이 유일한 해결책입니다.
deceze

불행히도 저는 덜 복잡한 도넛 차트 만 다루었습니다. 최신 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();


이것이 작동하는 동안 차트를 모두 다시 만드는 것과 비교하여 (각 지점을 추가 할 때 애니메이션으로 인해) 훨씬 느리다 는 것을 알았습니다 .
Danila Vershinin 2015 년

3

나는 neaumusic 솔루션을 시도 했지만 나중에 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. 차트를 처음 채우는 자바 스크립트 코드가 있다고 가정합니다 (예 : 페이지가로드 될 때) :

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 dec.

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

기본적으로 생성시로드 된 데이터를 스크랩 한 다음 데이터 추가 방법으로 재구성합니다. 이것은 내가 모든 포인트에 접근 할 수 있다는 것을 의미합니다. 다음에 의해 생성 된 데이터 구조에 액세스하려고 할 때마다 :

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();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.