2016-07-01 8 views
0

Использование Javascript Мне нужно вызвать веб-сокет (используя stomp.js ...) и построить данные реального времени на графике линии D3.js.Как построить в Javascript и на графике линии D3.js данные в реальном времени, поступающие из сообщений веб-сокетов через stomp.js?

Здесь вы мой фактический код ...

<!DOCTYPE HTML> 
<html> 
<head> 
    <title>Client Stomp 1</title> 

    <style> 
    body { font: 12px Arial;} 

    path { 
     stroke: steelblue; 
     stroke-width: 2; 
     fill: none; 
    } 

    .axis path, 
    .axis line { 
     fill: none; 
     stroke: grey; 
     stroke-width: 1; 
     shape-rendering: crispEdges; 
    } 
    </style> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script> 

    <!-- *** D3.js library inclusion ... *** --> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
</head> 
<body> 
    <script> 
     var urlServer; 
     var topics; 

     // *** Service variable to interrupt te values visualization ... 
     var i = 0; 

     // *** The vector that will mantain the couple values data - temperatura that there will be plotted in the line graph ... 
     var dataLineGraph = []; 

     // *** Setting the server and topic parameters ... 
     urlServer = "ws://stream.smartdatanet.it/ws"; 
     topics = "/topic/output.arpa_rumore.4c5d7481-fa5e-4f2f-d26d-d4e8095b9dd2_s_01"; 

     // *** Create the stomp client and estabilish the connection ... 
     // *** username and password are public 
     client = Stomp.client(urlServer); 
     client.connect("guest" , "Aekieh6F" , connectCallBack, errorCallback); 

     plotLineGraph (dataLineGraph); 

     // *** Manage the connection ... 
     function connectCallBack(x) { 
      client.subscribe(topics, messageCallback); 
      if (i < 1) {alert("Make the connection !")} 
      i = i + 1; 
     } 

     // *** Manage the connection error... 
     function errorCallback(x) { 
      if (i < 1) {alert("Connection error !")} 
      i = i + 1; 
     } 

     // *** Manage the message callback... 
     function messageCallback(x) { 
      if (i < 5) { 
      alert("First messages sent form the platform! To see the others open the web browser console !!!"); 

      // *** Convert the body message in JSON format ... 
      var theJson = JSON.parse(x.body); 

      // *** Alert the time and the b_6300_Hz value ... 
      //alert(theJson.values[0].time + " - " + theJson.values[0].components.b_6300_Hz); 

      // *** Alert the time and the b_6300_Hz value ... 
      time = theJson.values[0].time; 

      // *** Hardcoded but it's only to test the date parsing ... 
      day = time.substring(8,10); 
      //alert ("Day = " + day); 
      month = time.substring(5,7); 
      //alert ("month = " + month); 
      year = time.substring(0,4); 
      //alert ("Year = " + year); 
      hour = time.substring(11,13); 
      //alert ("Hour = " + hour); 
      minutes = time.substring(14,16); 
      //alert ("Minutes = " + minutes); 
      seconds = time.substring(17,19); 
      //alert ("Seconds= " + seconds); 

//    formattedDate = (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear() + "-" + (dt.getHours()) + ":" + dt.getMinutes() + ":" + dt.getSeconds(); 
      formattedDate = month + "/" + day + "/" + year + "-" + hour + ":" + minutes + ":" + seconds; 

      value = theJson.values[0].components.b_6300_Hz; 

//    2016-07-01T15:18:31+0200 - 50.2 
      alert ("formattedDate = " + formattedDate); 

      dataLineGraph.push({time: formattedDate, value:value}); 
      } 

      i = i + 1; 
     } 




     // *** Function for to draw the line graph ... 
     function plotLineGraph (data) { 
      // Set the dimensions of the canvas/graph 
      var margin = {top: 30, right: 20, bottom: 30, left: 50}, 
       width = 600 - margin.left - margin.right, 
       height = 270 - margin.top - margin.bottom; 

      // Set the ranges 
      var x = d3.time.scale().range([0, width]); 
      var y = d3.scale.linear().range([height, 0]); 

      // Define the axes 
      var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5); 
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5); 

      // Define the line 
      var valueline = d3.svg.line() 
       .x(function(d) { return x(d.date); }) 
       .y(function(d) { return y(d.close); }); 

      // Adds the svg canvas 
      var svg = d3.select("body") 
       .append("svg") 
        .attr("width", width + margin.left + margin.right) 
        .attr("height", height + margin.top + margin.bottom) 
       .append("g") 
        .attr("transform", 
         "translate(" + margin.left + "," + margin.top + ")"); 

      // Parse the date/time 
      var parseDate = d3.time.format("%d/%m/%Y-%H:%M:%S").parse; 

      // Get the data 
     // d3.csv("data.csv", function(error, data) { 

       data.forEach(function(d) { 
        d.date = parseDate(d.time); 
        d.close = +d.value; 
       }); 

       // Scale the range of the data 
       x.domain(d3.extent(data, function(d) { return d.date; })); 
       y.domain([0, d3.max(data, function(d) { return d.value; })]); 

       // Add the valueline path. 
       svg.append("path") 
        .attr("class", "line") 
        .attr("d", valueline(data)); 

       // Add the X Axis 
       svg.append("g") 
        .attr("class", "x axis") 
        .attr("transform", "translate(0," + height + ")") 
        .call(xAxis); 

       // Add the Y Axis 
       svg.append("g") 
        .attr("class", "y axis") 
        .call(yAxis); 

     // }); 

     } 


    </script> 
</body> 
</html> 

Вы можете копировать/вставить и попытаться выполнить (... Шоуда будет работать ...).

Я могу потреблять сообщения из потока, как вы можете видеть из предупреждения или просмотра консоли веб-браузера, но я не знаю, как разместить эти данные на динамическом линейном графике, как этот http://jsfiddle.net/peDzT/.

Как добавить данные в массив dataLineGraph на линейном графике и как обновить его при каждом новом добавлении данных в моем векторе?

Обратите внимание, что функция plotLineGraph работает, если я использую его со «статическими» данными, загружаемыми один раз.

Любые предложения/примеры будут оценены!

Чезаре

+0

http://bl.ocks.org/simenbrekken/6634070 , Вот простой пример наличия графика live/update. Надеюсь, вы сможете это понять, а затем подключить его к событиям, которые вы должны получать со своего сетевого разъема stomp.js. – johnsimer

ответ

3

Я очищено и переработан код хороший бит, чтобы показать вам пример реализации. В этом я рисую время против b_400_Hz, так как я не уверен, какой сигнал вы после. Я прокомментировал код ниже довольно хорошо, и это РУНН-состоянии, так что просто спросить, если у вас есть какие-либо вопросы:

<!DOCTYPE HTML> 
 
<html> 
 

 
<head> 
 
    <title>Client Stomp 1</title> 
 

 
    <style> 
 
    body { 
 
     font: 12px Arial; 
 
    } 
 
    
 
    path { 
 
     stroke: steelblue; 
 
     stroke-width: 2; 
 
     fill: none; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
     fill: none; 
 
     stroke: grey; 
 
     stroke-width: 1; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    </style> 
 

 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script> 
 

 
    <!-- *** D3.js library inclusion ... *** --> 
 
    <script src="https://d3js.org/d3.v3.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    var urlServer; 
 
    var topics; 
 

 
    // *** The vector that will mantain the couple values data - temperatura that there will be plotted in the line graph ... 
 
    var dataLineGraph = []; 
 

 
    // *** Setting the server and topic parameters ... 
 
    urlServer = "ws://stream.smartdatanet.it/ws"; 
 
    topics = "/topic/output.arpa_rumore.4c5d7481-fa5e-4f2f-d26d-d4e8095b9dd2_s_01"; 
 

 
    // *** Create the stomp client and estabilish the connection ... 
 
    // *** username and password are public 
 
    client = Stomp.client(urlServer); 
 
    client.connect("guest", "Aekieh6F", connectCallBack, function(){}); 
 

 
    // *** Manage the connection ... 
 
    function connectCallBack(x) { 
 
     client.subscribe(topics, messageCallback); 
 
    } 
 
    
 
    function compare(a,b) { 
 
     if (a.time < b.time) 
 
     return -1; 
 
     if (a.time > b.time) 
 
     return 1; 
 
     return 0; 
 
    } 
 

 
    // parse the times from the server 
 
    var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S%Z").parse; 
 
    
 
    // *** Manage the message callback... 
 
    function messageCallback(x) { 
 

 
     // *** Convert the body message in JSON format ... 
 
     var theJson = JSON.parse(x.body); 
 

 
     // grab the values of interest 
 
     dataLineGraph.push({ 
 
     time: parseDate(theJson.values[0].time), 
 
     value: +theJson.values[0].components.b_400_Hz 
 
     }); 
 
     
 
     // make sure we stay sorted 
 
     dataLineGraph.sort(compare); 
 
     
 
     plotLineGraph(); 
 
    } 
 

 
    // intial graph setup 
 
    setupGraph(); 
 

 
    // keep reference to these variables from setupGraph 
 
    var valueline, x, y, xAxisG, yAxisG, line; 
 
    
 
    function setupGraph() { 
 
     // Set the dimensions of the canvas/graph 
 
     var margin = { 
 
      top: 30, 
 
      right: 20, 
 
      bottom: 30, 
 
      left: 50 
 
     }, 
 
     width = 600 - margin.left - margin.right, 
 
     height = 270 - margin.top - margin.bottom; 
 

 
     // Set the ranges 
 
     x = d3.time.scale().range([0, width]); 
 
     y = d3.scale.linear().range([height, 0]); 
 

 
     // Define the line 
 
     valueline = d3.svg.line() 
 
     .x(function(d) { 
 
      console.log(d) 
 
      return x(d.time); 
 
     }) 
 
     .y(function(d) { 
 
      return y(d.value); 
 
     }); 
 

 
     // Adds the svg canvas 
 
     var svg = d3.select("body") 
 
     .append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
     // Add the X Axis 
 
     xAxisG = svg.append("g") 
 
     .attr("class", "x axis") 
 
     .attr("transform", "translate(0," + height + ")"); 
 

 
     // Add the Y Axis 
 
     yAxisG = svg.append("g") 
 
     .attr("class", "y axis"); 
 

 
     line = svg.append("path"); 
 
    } 
 

 

 
    // *** Function for to draw the line graph ... 
 
    function plotLineGraph() { 
 

 
     // Scale the range of the data 
 
     x.domain(d3.extent(dataLineGraph, function(d) { 
 
     return d.time; 
 
     })); 
 
     y.domain([0, d3.max(dataLineGraph, function(d) { 
 
     return d.value; 
 
     })]); 
 
    
 
     // transistion axis 
 
     xAxisG 
 
     .transition() 
 
     .duration(500) 
 
     .ease("linear") 
 
     .call(d3.svg.axis().scale(x).orient("bottom")); 
 
     
 
     yAxisG 
 
     .transition() 
 
     .duration(500) 
 
     .ease("linear") 
 
     .call(d3.svg.axis().scale(y).orient("left")); 
 

 
     // change the line 
 
     line.transition() 
 
     .duration(500) 
 
     .attr("d", valueline(dataLineGraph)); 
 
    } 
 
    </script> 
 
</body> 
 

 
</html>

+0

Точно, что мне нужно! Отличный ответ с исполняемым и подробным кодом. Ты заставил меня сэкономить много времени. Спасибо за то, что вы потратили на ответ – Cesare