Skip to content

Multiple graphs & multiple data sources bug #1175

Closed
jas- opened this Issue Oct 28, 2013 · 8 comments

2 participants

@jas-
jas- commented Oct 28, 2013

I have come across what I consider a bug.

My goal is to utilize socket.io to emit streams of data for multiple live graphs using flot.

I am not quite certain how to resolve the problem as after some internal examinations of the selectors used & the data sources (each different) I am seeing one data source applied across multiple graphs.

My primary assumption is that the selector was being applied incorrectly but after adding some simple debugging to the arg list passed into the plugin I see the correct div#selector name.

I am using socket.io to emit a random data source (for testing purposes) on the server like so:

var app = require('express'),
      http = require('http')

var server = http.createServer(opts, app).listen(3000)

var io = require('socket.io').listen(server)

io.sockets.on('connection', function(socket) {
  socket.on('traffic', function(data) {
    start(socket, data)
  })
})

function start(socket, srv) {
  setInterval(function() {
    socket.emit('traffic', getData(srv))
  }, 300)
}

function getData(srv) {
  return {
    server: srv,
    traffic: getRandomData()
  }
}

var data = [], totalPoints = 300
function getRandomData() {
  if (data.length > 0)
    data = data.slice(1)

  while (data.length < totalPoints) {
    var prev = data.length > 0 ? data[data.length - 1] : 50
    var y = prev + Math.random() * 10 - 5
    if (y < 0)
      y = 0;
    if (y > 100)
      y = 100;
      data.push(y)
    }

    var res = []
    for (var i = 0; i < data.length; ++i)
      res.push([i, data[i]])
      return res
}

The websocket datastream is accurate in terms of separate streams per selector as show in this sample:

5:::{"name":"traffic","args":[{"server":{"data":"test01"},"traffic":[[0,6.19492547120899],[1,7.066787923686206],/* ... more ... */]}
5:::{"name":"traffic","args":[{"server":{"data":"test02"},"traffic":[[0,3.59492547120899],[1,9.145887923686206],/* ... more ... */]}
5:::{"name":"traffic","args":[{"server":{"data":"test03"},"traffic":[[0,6.7853547120899],[1,6.98767923686206],/* ... more ... */]}

I also realize the above snippet is out of your region of support I just wanted you to know that this portion is working as expected.

Here is the JS I am using on the client to apply the above streams to the jQuery.flot plugin..

function opts(id){
  if($('#'+id).length) {
    var options = {
      yaxis: {
        min: 0,
        max: 100
      },
      xaxis: {
        show: false
      },
      grid: {
        borderWidth: 0 
      },
    }
    return options
  }
  return false
}

function update(id, data, options){
  var plot = $.plot($('#'+id), [data], options)
  plot.setData([data])
  plot.draw()
}

function pollServers(uri, srv, cmd, id){
  var opt = opts(id),
      socket = io.connect(uri)

  socket.emit(cmd, {
    data: srv
  })

  socket.on(cmd, function(data) {
    if (data.server.data === srv) {
      update(data.server.data, data.traffic , opt)
    }
  })
}

And last but not least the HTML used to control the three div elements used to render.

          <script type='text/javascript'>
            jQuery(document).ready(function($){

              var uri = 'https://node.dev:3000',
                  srv = 'test01',
                  cmd = 'traffic',
                  id = 'test01',
                  color = '#336666',
                  pin = '#800000'

              pollServers(uri, srv, cmd, id, color, pin)
            })
          </script>
         <div style="height: 120px; padding: 0px; position: relative;" id="test01">

          <script type='text/javascript'>
            jQuery(document).ready(function($){

              var uri = 'https://node.dev:3000',
                  srv = 'test02',
                  cmd = 'traffic',
                  id = 'test02',
                  color = '#336666',
                  pin = '#800000'

              pollServers(uri, srv, cmd, id, color, pin)
            })
          </script>
         <div style="height: 120px; padding: 0px; position: relative;" id="test02">

          <script type='text/javascript'>
            jQuery(document).ready(function($){

              var uri = 'https://node.dev:3000',
                  srv = 'test03',
                  cmd = 'traffic',
                  id = 'test03',
                  color = '#336666',
                  pin = '#800000'

              pollServers(uri, srv, cmd, id, color, pin)
            })
          </script>
         <div style="height: 120px; padding: 0px; position: relative;" id="test03">

I realize this is a lot of code to sift, so I must apologize in advance. Thanks.

@dnschnur
Flot member

So, to clarify, the bug is that all three of your divs are showing the same data? Which of the three datasets are they showing?

It seems very unlikely that this is a bug in Flot, given that the data and selector are both entirely under your control.

@jas-
jas- commented Oct 29, 2013

Correct. To be quite honest I am not certain which data set flot is using currently.

You could be right, perhaps I am overlooking something trivial.

Here is some more information regarding the data streams from the server:

5:::{"name":"traffic","args":[{"server":{"data":"test01"},"traffic":[[0,45.68176065105945],[1,48.13035383587703],[2,45.728431090246886],/* ... */]}
5:::{"name":"traffic","args":[{"server":{"data":"test02"},"traffic":[[0,48.13035383587703],[1,45.728431090246886],[2,45.18669594544917],/* ... */]}
5:::{"name":"traffic","args":[{"server":{"data":"test03"},"traffic":[[0,45.728431090246886],[1,45.18669594544917],[2,41.67939780512825],/* ... */]}

And here is some debugging output from socket.io regarding the streams as they are being retrieved (pre-flot):

test01 => [[0,45.68176065105945],[1,48.13035383587703],[2,45.7284310902468
test02 => [[0,48.13035383587703],[1,45.728431090246886],[2,45.186695945449
test03 => [[0,45.728431090246886],[1,45.18669594544917],[2,41.679397805128

And some debugging out put from flot using this snippit console.log(placeholder.selector+' => '+JSON.stringify(data_).substr(0, 64))

#test01 => [[[0,45.68176065105945],[1,48.13035383587703],[2,45.7284310902468
#test02 => [[[0,48.13035383587703],[1,45.728431090246886],[2,45.186695945449
#test03 => [[[0,45.728431090246886],[1,45.18669594544917],[2,41.679397805128

As you can see the data emitted from the server, as it is retrieved by the client & passed to flot the selector and the stream all match, but for whatever reason they are not isolated to the div specified and instead applied to all three at once.

If you are interested in taking a look at the implementation it can be replicated quickly with from node-dhcp-manager, or if there is any debugging information I can get you please let me know. I appreciate your assistance.

@dnschnur
Flot member

Where are you placing that console.log? I don't see data_ anywhere in the code you posted.

@jas-
jas- commented Oct 29, 2013

Just below function Plot(placeholder, data_, options_, plugins) { on line #36

@dnschnur
Flot member

Okay, two more things to take a look at: first, in addition to placeholder.selector, try logging placeholder.get(0), to verify that the actual elements aren't somehow being matched the same. Second, I notice that you're still using Flot 0.7, which is a little old; could you try master and see if the problem still comes up?

@jas-
jas- commented Oct 29, 2013

I have migrated to the latest and also examined placeholder.get(0) but the results are the same. I think it might have to do with the socket.io client stream parsing so I am going to take a look at that a bit further

@jas- jas- closed this Oct 29, 2013
@dnschnur
Flot member

Okay; please reopen this issue if you can't solve it, but so far I'm not able to reproduce the problem for myself.

@jas-
jas- commented Oct 30, 2013

Thanks @dnschnur, I do appreciate your assistance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.