简体   繁体   中英

Avoid same points being plotted twice in Google Visualization Chart API

I am plotting a line graph with Google's Visualization Chart API , its simply a change in number of leads(an integer) every 30minutes. here what I have done till now:

  google.load("visualization", "1", {packages:["corechart"]});
  google.setOnLoadCallback(drawChart);
  function drawChart() {
   var jsonData = 'json string goes here';
   var report = $.parseJSON(jsonData); //make it a json object

    var data = new google.visualization.DataTable();
data.addColumn('timeofday', 'Time');
data.addColumn('number', 'Leads');
   var interval = 1000 * 60 * 30; //interval of 30mins
    var graphData = report['rush_hour_reports'];
var length = graphData.length;
var normalized_data = {}; //placeholder object
   for(var i=0; i<length; i++){
var dt = new Date(graphData[i]['my_hour']); //date obj from timestamp
     //next we round of time in chunks of 30mins(interval)
    var dt_rounded = new Date(Math.round(dt.getTime() / interval) * interval);
     //check if that time exits, if yes & sum the new lead count with old one as time is same
     // Else, just create a new key with timestamp
    if(typeof normalized_data[dt_rounded] == 'undefined'){
            normalized_data[dt_rounded] = graphData[i]['lead_count'];
    }else{
            normalized_data[dt_rounded] += graphData[i]['lead_count'];
    }
    for(key in normalized_data){
      if(normalized_data.hasOwnProperty(key)){
        var dt = new Date(key);
        var hrs = parseInt(dt.getHours(), 10);
        var mins = parseInt(dt.getMinutes(), 10);
        //add the data into Google Chart using addRow
        data.addRow([ [hrs, mins,0], parseInt(normalized_data[key], 10) ]);
      }
    }
}
var format = new google.visualization.DateFormat({pattern: 'h:mm a'});
console.log(normalized_data);
data.sort(0); //sort it, just in case its not already sorted
format.format(data, 0);

    var options = {
      title: 'Company Performance',
          fontSize: '12px',
          curveType: 'function',
animation:{
            duration: 1000,
            easing: 'out',
          },
          pointSize: 5,
          hAxis: {title: report.time_format,
                  titleTextStyle: {color: '#FF0000'}
                  },
          vAxis: {title: 'Leads',
                  titleTextStyle: {color: '#FF0000'}}
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

Now, this is how this graph renders: http://ubuntuone.com/3NMEtWYkhQSCHx4RERVcgq

If you closely notice it still have two lead counts being plotted at same time which is wrong(example at 6:30 or 7:30), instead it should be doing a total/sum of leads if they are at same time.

What am I doing wrong here?

Your problem is that you are converting your date objects into the "timeofday" data type, but you are not aggregating data at the timeofday level, so when you have multiple days with data in the same time period (12:00 in your example), you get multiple data points at that time. Try this instead:

for(var i=0; i<length; i++){
    var dt = new Date(graphData[i]['my_hour']);
    var dt_rounded = new Date(Math.round(dt.getTime() / interval) * interval);
    var minutes = (parseInt(dt_rounded.getHours(), 10) * 60) + parseInt(dt_rounded.getMinutes(), 10);
    if(typeof normalized_data[minutes] == 'undefined'){
        normalized_data[minutes] = graphData[i]['lead_count'];
    }else{
        normalized_data[minutes] += graphData[i]['lead_count'];
    }
}
for(var key in normalized_data){
    if(normalized_data.hasOwnProperty(key)){
        var hrs = Math.floor(key / 60);
        var mins = key % 60;
        data.addRow([ [hrs, mins,0], parseInt(normalized_data[key], 10) ]);
    }
}

See it working here: http://jsfiddle.net/asgallant/MYUHw/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM