操作方法通过socket.io和幻灯片视图动态更新图表作为滑动窗口?

时间:2017-02-16 09:04:03

标签: javascript node.js highcharts socket.io

有人可以帮我弄清楚我在图表中只显示最后X个样本时遗漏了什么吗?

查看this示例和this线程,我正在开发一个简单的页面,它通过socket.io从服务器接收样本并绘制最后10个样本。 然而,它不起作用,我正在努力弄清楚我错过了什么。

server.js是一个简单的样本生成器:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function (req, res) {
    res.sendfile('index.html');
});

// On connection event.
io.on('connection', function (socket) {
    console.log('a user connected');

    socket.on('disconnect', function () {
        console.log('user disconnected');
        // TODO (How-to) release connection (?)
    });

    var max = 100;  // Scale samples from 0 to 100.

    // Generate random samples.
    setInterval(function () {
        var x = (new Date()).getTime(), // current time
            y = Math.floor((Math.random() * max) + 1);
        socket.emit('chart_data', {
            x: x,
            y: y
        });
        console.info("emitted: [" + x + "," + y + "]");
    }, 2000); //update every sec.
});

http.listen(3000, function () {
    console.log('listening on *:3000');
});

html文件包含处理情节的脚本:

    $(function() {
      Highcharts.setOptions({
          global: {
              useUTC: false
          }
      });

      // Instantiate the chart object which plots the samples.
      var graph = new Highcharts.chart('graph_container', {
          chart: {
              type: 'spline',
              animation: Highcharts.svg, // don't animate in old IE
              marginRight: 10,
              events: {
                  load: function () {
                      // set up the updating of the chart on each sample
                      var series = this.series[0];
                      socket.on('chart_data', function (sample) {
                          //add chart data to series
                          series.addPoint([sample.x, sample.y], true, false);
                      });
                  }
              }
          },
          title: {
              text: 'Live random data'
          },
          xAxis: {
              type: 'datetime',
              tickPixelInterval: 150
          },
          yAxis: {
              title: {
                  text: 'Value'
              },
              plotLines: [{
                  value: 0,
                  width: 1,
                  color: '#808080'
              }]
          },
          tooltip: {
              formatter: function () {
                  return '<b>' + this.series.name + '</b><br/>' +
                      Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
                      Highcharts.numberFormat(this.y, 2);
              }
          },
          legend: {
              enabled: false
          },
          exporting: {
              enabled: false
          },
          series: [{
              name: 'Random data',
              data: (function () {
                  // generate an array of random data
                  var data = [],
                      time = 0,
                      i;

                  socket.on('chart_data', function (sample) {
                      //add chart data to series
                      time = sample.x;
                      for (i = -19; i <= 0; i += 2) {
                          data.push({
                              x: time + i
                          });
                      }
                  });
                  return data;
              }())
          }]
      });

    });

我是node.js的新手,但我相信我的错误就是在没有y的情况下推送样本&#34; data.push&#34;。然而,情节是有效的,但没有&#34;滑动窗口&#34;最后X个样本(例如10个)。

有没有人建议让#34;滑动窗口&#34;好吗?

1 个答案:

答案 0 :(得分:2)

你应该发出两个事件 - 一个用数据初始化,例如10点的样本,第二点 - 在时间间隔内取点。

您不应该以行series.data = (function () ...中的方式初始化数据。而是在加载事件上移动初始化并使用series.setData

你的系列应该是这样的:

series: [{
  name: 'Random data',
  data: []
}]

和这样的加载事件:

events: {
load: function () {
          var series = this.series[0];
          var socket = io.connect('http://localhost:3000');


          socket.on('chart_data_init', function (sample) {
            series.setData(sample.data);
          });

          socket.on('chart_data', function (sample) {
              //add chart data to series
              series.addPoint([sample.x, sample.y], true, false);
          });
      }
  }

然后修改您的服务器文件,您需要添加chart_data_init发射和一些初始化数据

var initData = (function () {
  var data = [], i = 0, time = new Date().getTime() - 2000 * 10;

  for (; i < 10; i++) {
    data.push({
      x: time + i * 2000,
      y: Math.floor((Math.random() * max) + 1)
    });
  }

  return data;
})();

socket.emit('chart_data_init', {
  data: initData
});

您必须按升序排序数据 - 否则Highcharts将无法正确呈现数据。

文件

的index.html

    <html>
<head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="graph_container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>


<script>
 // Instantiate the chart object which plots the samples.
 console.log
      var graph = new Highcharts.chart('graph_container', {
          chart: {
              type: 'spline',
              animation: Highcharts.svg, // don't animate in old IE
              marginRight: 10,
              events: {
                  load: function () {
                      // set up the updating of the chart on each sample
                      var series = this.series[0];
                      var socket = io.connect('http://localhost:3000');


                      socket.on('chart_data_init', function (sample) {
                        series.setData(sample.data);
                      });

                      socket.on('chart_data', function (sample) {
                          //add chart data to series
                          series.addPoint([sample.x, sample.y], true, false);
                      });
                  }
              }
          },
          title: {
              text: 'Live random data'
          },
          xAxis: {
              type: 'datetime',
              tickPixelInterval: 150
          },
          yAxis: {
              title: {
                  text: 'Value'
              },
              plotLines: [{
                  value: 0,
                  width: 1,
                  color: '#808080'
              }]
          },
          tooltip: {
              formatter: function () {
                  return '<b>' + this.series.name + '</b><br/>' +
                      Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
                      Highcharts.numberFormat(this.y, 2);
              }
          },
          legend: {
              enabled: false
          },
          exporting: {
              enabled: false
          },
          series: [{
              name: 'Random data',
              data: []
          }]
      });
</script>

</body>
</html>

server.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.sockets.on('connection', function (socket) {
    console.log('a user connected');

    socket.on('disconnect', function () {
        console.log('user disconnected');
        // TODO (How-to) release connection (?)
    });

    var max = 100;  // Scale samples from 0 to 100.

    var initData = (function () {
      var data = [], i = 0, time = new Date().getTime() - 2000 * 10;

      for (; i < 10; i++) {
        data.push({
          x: time + i * 2000,
          y: Math.floor((Math.random() * max) + 1)
        });
      }

      return data;
    })();

    socket.emit('chart_data_init', {
      data: initData
    });

    // Generate random samples.
    setInterval(function () {
        var x = (new Date()).getTime(), // current time
            y = Math.floor((Math.random() * max) + 1);

        socket.emit('chart_data', {
            x: x,
            y: y
        });
        console.info("emitted: [" + x + "," + y + "]");
    }, 2000); //update every sec.
});

http.listen(3000, function(){
  console.log('listening on *:3000'); //jalankan server di port 3000
});