How to implement aggregate on chart js


#1

I have a use case of mongo agggregation and display the result on a chart. I use chartjs but I don’t have any idea on how to implement the aggregation.

here’s my aggregate method:

      Meteor.methods({
           casesCount:function() {
           var date = new Date({$gt: new Date('2015'), $lt: new Date('2016')});
           var pipeline = [
           {
                  $project: { causeOfDeath: 1, medical: 1, dateFiled: 1}
           },
           {
                  $group: {
                        _id: { life: "$causeOfDeath", nonLife: "$medical", dateFiled: date}, count: { $sum: 1 }
            }
         }
         ];
         var result = Claim.aggregate(pipeline);
         console.log("Explain Report:", JSON.stringify(result));
         return result;
         }
       });

What i want is to display the documents count for each aggregate fields (life, nonLife) based on specific time between date.

The aggregation is working on the console.

My problem on chartjs is it uses canvas element to render the chart :frowning:

I don’t know how to pass the aggregated field on the canvas and render it.

I actually have a working chart without aggregation, displaying total number of documents per month.

Here’s my set up on my other chart:

Template.claimedTable.onRendered(function() {
Tracker.autorun( function() {
var yearLabel = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

var Jan = (Enrollments.find({
 effectivityDate: {
    $gt: new Date('01/01/2015'),
    $lt: new Date('02/01/2015')
  }
  }).count());
 // assuming i have this variable for all months
var myData = [Jan, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec];

var lineData = {
  labels: yearLabel,
  datasets: [{
  label: "Claims",
  fillColor: "rgba(220,220,220,0.5)",
  strokeColor: "red",
  pointColor: "red",
  pointStrokeColor: "#fff",
  pointHighlightFill: "#fff",
  pointHighlightStroke: "rgba(220,220,220,1)",
  data: myData
}
]};
var lineOptions = {
  scaleShowGridLines: true,
  scaleGridLineColor: "rgba(0,0,0,.05)",
  scaleGridLineWidth: 1,
  maintainAspectRatio: true,
  tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= label %>",
  bezierCurve: true,
  bezierCurveTension: 0.4,
  pointDot: true,
  pointDotRadius: 4,
  pointDotStrokeWidth: 1,
  pointHitDetectionRadius: 20,
  datasetStroke: true,
  datasetStrokeWidth: 2,
  datasetFill: true,
  responsive: true,
};
var ctx = document.getElementById("lineChart").getContext("2d");
new Chart(ctx).Line(lineData, lineOptions);
});
});

Here’s on my template:

 <div>
         <canvas id="lineChart" height="70"></canvas>        
</div>

Any help is deeply appreciated.

Thanks,


#2

or is there anyway to do this work


#3

You are using a Meteor method for the aggregation, which means the chart won’t be reactive. However, the principle is straightforward and something like this:

Template.myTemplate.onCreated(function myTemplateOnCreated() {
  this.result = new ReactiveVar();
  Meteor.call('casesCount', (err, res) => {
    if (err) {
      // handle error
    } else {
      this.result.set(res);
    }
  });
});

Template.myTemplate.onRendered(function myTemplateOnRendered() {
  this.autorun(() => {
    const result = this.result.get();
    if (result) {
      // code to render graph - using "result" as the data
    }
  });
});

#4

how I set result to mydata array


#5

result is your mydata array.

If you prefer:

Template.myTemplate.onCreated(function myTemplateOnCreated() {
  this.mydata = new ReactiveVar();
  Meteor.call('casesCount', (err, res) => {
    if (err) {
      // handle error
    } else {
      this.mydata.set(res);
    }
  });
});

Template.myTemplate.onRendered(function myTemplateOnRendered() {
  this.autorun(() => {
    const mydata = this.mydata.get();
    if (result) {
      // code to render graph - using "mydata" as the data
    }
  });
});