Dynamic Chart from mongoDB issue


#1

Hi there,

First of all … I’m new to Meteor !

I would like to create dynamic chart from my DB.
One uplet of my collection :

{ "_id" : ObjectId("599d91c32885f81da2b1700d"), "ipSrc" : "X.X.X.X", "occuSrc" : 12 }

From my .html :

<template name="dhcp">
  <canvas id="myChart" width="50" height="20"></canvas>
</template>

From my .js :

Template.dhcp.onCreated(function() {
  this.subscribe('linkDB');
});
Template.dhcp.rendered = function() {
  Tracker.autorun(function () {
    data = AuthOccuIPsrc.find({});
    data.forEach(function(line){
      ipSrc.push(line.ipSrc);
      occuIPsrc.push(line.occuSrc);
    })
    myChart = new Chart($('#myChart').get(0), {
      type : 'bar',
      data:{
        labels: ipSrc,
        datasets: [{
          label: '# Ip Src',
          data: occuIPsrc,
          borderWidth: 1
        }]
      }
    });
  });
};

My code should replace the currently chart by a newest, created each time new data is registered in my DB.
I already tried tu update the chart by different ways. For example:

  • update “chart.data.labels & datasets” each time new data is registered in my DB.

What should I change in my code to have a dynamic chart ?

Appreciate any help !


#2

Why do you need to replace the chart? Shouldn’t the chart update when the date updates? I guess you need to set the new data to the existing chart with the autorun function. Otherwise you will have to remove the d chart from the from the dom which will cause flicker.


#3

Can you explain me how can I do this (update with the autorun function) please ?
I already read some docs and related issues but what i tried didn’t work. That’s why I replace the existing chart. :roll_eyes:

Thks


#4

I think it depends on the chart library on how it’s update. I was assuming it has an update function (like chart.setData(someData) where it takes new data list and then it will update the chart.


#5

Sure.

I tried to set data fields in the current Chart using :

chart.datas.labels = [ipSrc]
chart.datas.datasets.data = [occuIPsrc]

in the autorun function.

But that didn’t work well.


#6

Which chart library are you using? the chart library needs to update based on the new data, so there could an update call or refresh or something, otherwise it won’t know that it has new data.


#7

I’m using ChartJS.
http://www.chartjs.org/docs/latest/developers/updates.html


#8

Yeah, so you modify the data using the remove/add functions and then call chart.update() as per the example on the link you provided, did you try that already?


#9

Yes :

Template.auth.rendered = function() {
  Tracker.autorun(function () {
    var ipSrce = [];
    var occuIPsrc = [];
    data = AuthOccuIPsrc.find({});
    data.forEach(function(line){
      ipSrce.push(line.ipSrc);
      occuIPsrc.push(line.occuSrc);
    })
   addData(chart,ipSrce,occuIPsrc);
  });
};
function addData(chart, label, data) {
    chart.data.labels.push(label);
    chart.data.datasets.forEach((dataset) => {
        dataset.data.push(data);
    });
    chart.update();
}

console.logs(label) :

  • Array [ “122.225.109.123”, “218.2.0.129”, “218.2.0.121”, “62.210.172.145”, “124.95.165.186”, “124.205.250.51”, “218.26.11.118” ]

console.logs(data):

  • Array [ 3, 3, 1, 1, 2, 6, 66 ]

That what I get in the UI :
image


#10

That code looks fine to me…maybe you need to clean the data before adding more or the data is not valid? I did similar code back when I was using blaze and here is what I did before, in case it helps.

var myPieChart = new Chart(ctx).Pie(data,options);


    if(this!=undefined && this.data!=undefined) {
         Events.find(this.data._id).observeChanges({
            added: function (id, fields) {
                update();
            },
            changed: function (id, fields) {
                update();
            },
            removed: function () {
                update();
            }
        });
    }

    var template=this;
    function update(){
        if(template!=undefined&&template.data!=undefined){

            var event=Events.findOne(template.data._id);

            console.log(event.confirmedCount+","+event.waitingCount+","+"0"+event.openSlotsCount);
            myPieChart.segments[0].value=event.confirmedCount;
            myPieChart.segments[1].value=event.waitingCount;
            myPieChart.segments[2].value=0;
            myPieChart.segments[3].value=event.openSlotsCount;
            myPieChart.update();
        }
    }

#11

Thks for this share. :slight_smile: