chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.42k stars 11.89k forks source link

data variable is being over written after chart update #1522

Closed dvenkatsagar closed 8 years ago

dvenkatsagar commented 8 years ago

Hi, This is a very weird bug that Im facing here. What I'm basically trying to do is update the chart with new labels.

Here are the steps that Im following:

  1. Initialize chart with data 1.
  2. Update data with in chart after a set amount of time with data 2.
  3. After step 2 update, Update the data with in chart again after a set amount of time with data 3.
  4. In this manner, finally update the chart with data 1 Here the Labels, dont change but value does. I understood where the bug is. It basically overwrites the data that the chart is initialized with. Here is my code:
// data 1
var skills_program = {
  labels: ["C", "C++", "JAVA", "PYTHON", "SHELL SCRIPT"],
  datasets: [
    {
      label: "Programming Skills",
      fillColor: "rgba(151,187,205,0.5)",
      strokeColor: "rgba(151,187,205,0.8)",
      highlightFill: "rgba(151,187,205,0.75)",
      highlightStroke: "rgba(151,187,205,1)",
      data: [8,8.5,7.5,9.5,8.5]
    }
  ]
}

// data 2
var skills_media = {
  labels: ["Adobe Suite","Maya","3DS Max","Cinema 4D","Open Source"],
  datasets: [
    {
      label: "Media Creation Skills",
      fillColor: "rgba(204,255,153,0.5)",
      strokeColor: "rgba(204,255,153,0.8)",
      highlightFill: "rgba(204,255,153,0.75)",
      highlightStroke: "rgba(204,255,153,1)",
      data: [8,6.5,6,7.5,8.5]
    }
  ]
}

// data 3
var skills_web = {
  labels: ["HTML5", "CSS3", "PHP", "JS", "NODEJS", "SQL", "MONGO-DB"],
  datasets: [
    {
      label: "Web Development Skills",
      fillColor: "rgba(220,220,220,0.5)",
      strokeColor: "rgba(220,220,220,0.8)",
      highlightFill: "rgba(220,220,220,0.75)",
      highlightStroke: "rgba(220,220,220,1)",
      data: [9.5, 9.5, 9.5, 9.5, 8.5, 8, 8]
    }
  ]
}

// options
var options = {
  scaleLineColor: "rgba(128,128,128,0.5)",
  scaleFontColor: "#888",
  scaleFontSize : 13,
  scaleOverride: true,
  scaleSteps: 5,
  scaleStepWidth: 2,
  scaleStartValue: 0,
  scaleGridLineColor : "rgba(0,0,0,0.2)",
  barStrokeWidth : 1,
  barValueSpacing : 15
};

var ctx = document.getElementById("skills-chart").getContext("2d");

// using skills_program as initializing data
var chart = new Chart(ctx).Bar(skills_program, options);

// function to update data
function load_skills(main_chart, load_data){
  if (main_chart.datasets[0].bars.length > load_data.labels.length){
    var diff = main_chart.datasets[0].bars.length - load_data.labels.length;
    for(var i = 0; i < diff; i++){
      main_chart.removeData();
    }
  }else if (main_chart.datasets[0].bars.length < load_data.labels.length) {
    var diff = load_data.labels.length - main_chart.datasets[0].bars.length;
    for(var i = 0; i < diff; i++){
      main_chart.addData([0],"");
    }
  }

  for(var i = 0; i < load_data.labels.length; i++){
    // update value of bar
    main_chart.datasets[0].bars[i].value = load_data.datasets[0].data[i];
    // update label of bar
    main_chart.datasets[0].bars[i].label = load_data.labels[i];

    // update fill color of bar
    main_chart.datasets[0].bars[i].fillColor = load_data.datasets[0].fillColor;
    // update hightlight fill of bar
    main_chart.datasets[0].bars[i].highlightFill = load_data.datasets[0].highlightFill;
    // update hightlight stroke of bar
    main_chart.datasets[0].bars[i].highlightStroke = load_data.datasets[0].highlightStroke;
    // update stroke color of bar
    main_chart.datasets[0].bars[i].strokeColor = load_data.datasets[0].strokeColor;
    // update datasetLabel of bar
    main_chart.datasets[0].bars[i].datasetLabel = load_data.datasets[0].label;
    // update scale label of bar
    main_chart.scale.xLabels[i] = load_data.labels[i];
  }

  // update dataset label, fillcolor and stroke color
  main_chart.datasets[0].label = load_data.datasets[0].label;
  main_chart.datasets[0].fillColor = load_data.datasets[0].fillColor;
  main_chart.datasets[0].strokeColor = load_data.datasets[0].strokeColor;
  main_chart.update();
}

console.log(skills_program.labels); // ["C", "C++", "JAVA", "PYTHON", "SHELL SCRIPT"]
setTimeout(function(){
  // load with data 2
  load_skills(charts.skills_chart, skills_media);

  console.log(skills_program.labels); // ["Adobe Suite","Maya","3DS Max","Cinema 4D","Open Source"]<-- bug here: labels just changed
},3000);

setTimeout(function(){
  // load with data 3
  load_skills(charts.skills_chart, skills_web);
  console.log(skills_program.labels); // changes again 
},6000);

setTimeout(function(){
  // Load data 1
  load_skills(charts.skills_chart, skills_program); // labels are from skills_web.labels but values are from skills_program.values
},9000);

The only work around is to create a deep copy of the skills_program variable and send that copy to the new Chart(ctx).Bar()

Kindly help me out here.

Thank you

etimberg commented 8 years ago

In v1, the data object is copied all over the place. In v2, what you are trying to do will work. The docs for V2 can be found at http://nnnick.github.io/Chart.js/docs-v2/