felix.jumanji
felix.jumanji

Reputation: 35

Angular-google-chart - building and sorting the data-table

I'm using the Google Chart Tools Directive Module to draw a line/area chart in my Angularjs application, from rdf data retrieved via sparql queries and available, within the app, in json-like format.

In the main controller I declared my drawing function like this:

$scope.createChart = function () {           

        var json1 = $scope.entities     // here I have my data                   
        var rows = []

        // populate rows with data:
        for (var key in json1) {
            // json1 has extra data I don't need 
            if (json1[key]['sdmx-dimension:refTime'] && json1[key]['dpc:deads']) {
                var date = new Date(json1[key]['sdmx-dimension:refTime']);                           
                var deads = json1[key]['dpc:deads']
                rows.push({ c: [ { v:date }, { v:deads } ] })
            }
        }  

        $scope.myChartObject = {
          "type": "AreaChart",
          "data": {
            "cols": [
              {
                "id": "date",
                "label": "Date",
                "type": "date"
              },
              {
                "id": "deaths",
                "label": "Deaths",
                "type": "number"
              }                     
            ]
          },
          "options": {
            "title": "Deaths trend",                
            "height": 400,
            "width": 600,
            "vAxis": {
              "title": "Deaths",
            },
            "hAxis": {
              "title": "Date"
            }
          }
        }

        // attach the rows to the chart object
        $scope.myChartObject.data.rows = rows

        // template containing the chart
        $scope.callTemplate('drawChart', '#right', true)
}

// wait for sparql query to retrieve data before create chart
// otherwise an empty chart will be drawn!
window.setTimeout( function(){ $scope.createChart() }, 3000);

With this solution I'm able to draw the chart with data but the problem is: dates are not sorted correctly so the trend line is zigzagging over the chart:

area chart

I've tried to use a sort function on rows array:

rows.sort([{column:0}])

but the final order is even worse than initial one.

And I can't use sort on the chart object like this:

$scope.myChartObject.data.sort([{column:0}])

because this is not an array.

Dates come in this format: 'yyyy-mm-dd' (e.g. '2020-02-24') and nothing seems to improve even if I modify it to 'yyyy, mm, dd' before the new Date assignment.

Here console.log(myCharObject):

enter image description here

and here if I print {{myCharObject}} variable in html template:

enter image description here

How to sort this dates? Should I use some other way to define my chart as described here?

Upvotes: 2

Views: 672

Answers (1)

WhiteHat
WhiteHat

Reputation: 61275

to sort an array of objects, you will need to provide a custom sort function.

try using the following to sort rows, before adding to the chart data...

// sort
rows.sort(function (rowA, rowB) {
  return rowA.c[0].v.getTime() - rowB.c[0].v.getTime();
});

e.g.

    // populate rows with data:
    for (var key in json1) {
        // json1 has extra data I don't need 
        if (json1[key]['sdmx-dimension:refTime'] && json1[key]['dpc:deads']) {
            var date = new Date(json1[key]['sdmx-dimension:refTime']);                           
            var deads = json1[key]['dpc:deads']
            rows.push({ c: [ { v:date }, { v:deads } ] })
        }
    }  

    // sort
    rows.sort(function (rowA, rowB) {
      return rowA.c[0].v.getTime() - rowB.c[0].v.getTime();
    });

see following working snippet for an example...

// test data
var rows = [];
rows.push({c: [{v: new Date(2020, 2, 1)}, {v: 7}]});
rows.push({c: [{v: new Date(2020, 1, 1)}, {v: 7}]});
rows.push({c: [{v: new Date(2020, 0, 1)}, {v: 7}]});

// before sort
console.log("row 1 before", rows[0].c[0].v);

// sort
rows.sort(function (rowA, rowB) {
  return rowA.c[0].v.getTime() - rowB.c[0].v.getTime();
});

// after sort
console.log("row 1 after", rows[0].c[0].v);

Upvotes: 0

Related Questions