Dawood Awan
Dawood Awan

Reputation: 7338

Refresh Google Chart Dashboard

I am trying to refresh a Google Chart Dashboard, with data from the server. but I am getting an error with the ControlWrapper when I refresh the data. The initial load is working fine - but when I get another set of Data from the server I can't seem to use the Slider - I get an Error Message:

enter image description here

JSFIDDLE: https://jsfiddle.net/9aktz4s3/4/

Note: In the JSFiddle it doesn't work on Initial load because I have not set any default data - but the issue in JSFiddle is the same I get when I refresh data

This is my HTML:

<!--Div that will hold the dashboard-->
<div id="scorecard_dashboard_div" class="row">
    <!--Divs that will hold each control and chart-->
    <div id="scorecard_chart_div"></div>
    <div id="scorecard_filter_div"></div>
</div>

And this is how I initialize the dashboard:

var scorecardChartData;
var scorecardChart;
var scorecardDashboard;
var scoreCardRangeSelector;

var scorecardChartOptions = {
  legend: {    position: "top"  },
  chartArea: {    width: "90%"  },
  xptColumns: [{
    id: "dateid",    label: "Date",    type: "date"  }, {
    id: "brakingid",    label: "Brakings",    type: "number"  }, {
    id: "distanceTravelledid",    label: "Distance Travelled",    type: "number"  }, ]
};


function initViolationChart() {
  scorecardChartData = new google.visualization.DataTable();

  // add columns to the chart
  for (let i = 0; i < scorecardChartOptions.xptColumns.length; i++) {
    var column = scorecardChartOptions.xptColumns[i];
    scorecardChartData.addColumn(column.type, column.label, column.id);
  }

  // Create a dashboard.
  scorecardDashboard = new google.visualization.Dashboard(document.getElementById('scorecard_dashboard_div'));

  // Create a range slider, passing some options
  scoreCardRangeSelector = new google.visualization.ControlWrapper({
    controlType: "ChartRangeFilter",
    containerId: "scorecard_filter_div",
    options: {
      filterColumnIndex: 0,
      ui: { chartOptions: {legend: {position: "top" },height: 50, chartArea: {width: '90%'}}}    }
  });

  // Create the Chart Wrapper
  scorecardChart = new google.visualization.ChartWrapper({
    chartType: 'ColumnChart',
    containerId: 'scorecard_chart_div',
    options: {legend: {position: "top"},
      chartArea: {width: "90%"},
    }

  });

  // Bind the both with Dashboard
  scorecardDashboard.bind(scoreCardRangeSelector, scorecardChart);

  // Draw it
  scorecardDashboard.draw(scorecardChartData);

}

Here is how I refresh the graph data:

refreshData function(){


    var rows = [];

   //NORMALLY HERE THERE WILL BE AN AJAX REQUEST TO GET DATA FROM SERVER

    var items = jsonData.driverScorecardItems;

    for (var i = 0; i < items.length; i++) {

      var item = items[i];

      // 
      var thisRow = [{
        v: new Date(item.dateFormatted),
        f: item.dateFormatted
      }, {
        v: item.harshBrakings
      }, {
        v: item.distanceTravelledKM
      }];


      rows.push(thisRow);
    }

    // Add the rows to my Data Table
    scorecardChartData.addRows(rows);

    // Redraw the Chart
    scorecardDashboard.draw(scorecardChartData);

}

Upvotes: 2

Views: 3602

Answers (2)

Dawood Awan
Dawood Awan

Reputation: 7338

My work around -

If I call the initViolationChart() function when I refresh the data/graph everything seems to work fine.

So I change my refresh function the following:

  $('#refreshChart').click(function() {

    // HERE - I re-initalise the chart dashboard. And then it works
    initViolationChart()

    var rows = [];
    var items = jsonData.driverScorecardItems;

    for (var i = 0; i < items.length; i++) {

      var item = items[i];

      var thisRow = [{
        v: new Date(item.dateFormatted),
        f: item.dateFormatted
      }, {
        v: item.harshBrakings
      }, {
        v: item.distanceTravelledKM
      }];
      rows.push(thisRow);
    }

    scorecardChartData.addRows(rows);
    scorecardDashboard.draw(scorecardChartData);


  });

Working Fiddle: https://jsfiddle.net/40ta8xvu/

Upvotes: 0

WhiteHat
WhiteHat

Reputation: 61230

looks like you've stumbled upon some sort of bug...

taking the code from the fiddle, everything works fine, after making the following modification...

just remove 'corechart' from 'packages' when loading...

before

google.charts.load('current', {
  'packages': ['corechart', 'controls']  // <-- remove 'corechart' 
});

after

google.charts.load('current', {
  'packages': ['controls']
});

see following working snippet...

var scorecardChartData;
var scorecardChart;
var scorecardTable;
var scorecardDashboard;
var scoreCardRangeSelector;

var scorecardChartOptions = {
  legend: {
    position: "top"
  },
  chartArea: {
    width: "90%"
  },
  xptColumns: [{
    id: "dateid",
    label: "Date",
    type: "date"
  }, {
    id: "brakingid",
    label: "Brakings",
    type: "number"
  }, {
    id: "distanceTravelledid",
    label: "Distance Travelled",
    type: "number"
  }, ]
};

google.charts.load('current', {
  'packages': ['controls']
});
google.charts.setOnLoadCallback(initViolationChart);

function initViolationChart() {
  scorecardChartData = new google.visualization.DataTable();

  for (let i = 0; i < scorecardChartOptions.xptColumns.length; i++) {
    var column = scorecardChartOptions.xptColumns[i];
    scorecardChartData.addColumn(column.type, column.label, column.id);
  }

  // Create a dashboard.
  scorecardDashboard = new google.visualization.Dashboard(document.getElementById('scorecard_dashboard_div'));

  // Create a range slider, passing some options
  scoreCardRangeSelector = new google.visualization.ControlWrapper({
    controlType: "ChartRangeFilter",
    containerId: "scorecard_filter_div",
    options: {
      filterColumnIndex: 0,
      ui: {
        chartOptions: {
          legend: {
            position: "top"
          },
          height: 50,
          chartArea: {
            width: '90%'
          }
        }
      }
    }
  });

  scorecardChart = new google.visualization.ChartWrapper({
    chartType: 'ColumnChart',
    containerId: 'scorecard_chart_div',
    options: {
      legend: {
        position: "top"
      },
      chartArea: {
        width: "90%"
      },
    }

  });

  scorecardDashboard.bind(scoreCardRangeSelector, scorecardChart);
  scorecardDashboard.draw(scorecardChartData);
}

var jsonData = {

  driverScorecardItems: [{
    "scoreDate": "2017-02-15T00:00:00",
    "dateFormatted": "15-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 15.7286863,

  }, {
    "scoreDate": "2017-02-16T00:00:00",
    "dateFormatted": "16-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 23.1175938,

  }, {
    "scoreDate": "2017-02-17T00:00:00",
    "dateFormatted": "17-Feb-2017",
    "distanceTravelledKM": 49.20245,

  }, {
    "scoreDate": "2017-02-18T00:00:00",
    "dateFormatted": "18-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 13.8180962,

  }, {
    "scoreDate": "2017-02-19T00:00:00",
    "dateFormatted": "19-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 61.5765,

  }, {
    "scoreDate": "2017-02-20T00:00:00",
    "dateFormatted": "20-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 5.134261,

  }]
}

$(function() {
  $('#refreshChart').click(function() {
    var rows = [];
    var items = jsonData.driverScorecardItems;

    for (var i = 0; i < items.length; i++) {

      var item = items[i];

      var thisRow = [{
        v: new Date(item.dateFormatted),
        f: item.dateFormatted
      }, {
        v: item.harshBrakings
      }, {
        v: item.distanceTravelledKM
      }];
      rows.push(thisRow);
    }

    scorecardChartData.addRows(rows);
    scorecardDashboard.draw(scorecardChartData);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>

<button id="refreshChart">
  Refresh
</button>

<!--Div that will hold the dashboard-->
<div id="scorecard_dashboard_div" class="row">
  <!--Divs that will hold each control and chart-->
  <div id="scorecard_chart_div"></div>
  <div id="scorecard_filter_div"></div>
  <div id="scorecard_table_div"></div>
</div>


note:

the third item in the driverScorecardItems array is missing a property for --> "harshBrakings"

var jsonData = {

  driverScorecardItems: [{
    "scoreDate": "2017-02-15T00:00:00",
    "dateFormatted": "15-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 15.7286863,

  }, {
    "scoreDate": "2017-02-16T00:00:00",
    "dateFormatted": "16-Feb-2017",
    "harshBrakings": 0,
    "distanceTravelledKM": 23.1175938,

  }, {
    "scoreDate": "2017-02-17T00:00:00",
    "dateFormatted": "17-Feb-2017",
    "distanceTravelledKM": 49.20245,

  }, {
  ...

Upvotes: 2

Related Questions