Search code examples
javascriptjqueryhighchartslive

Highcharts multiple charts, each with live data


I have the following files: rsrp.txt, sinr.txt, rssi.txt

each of them containg information like this:

[1433289760000,-83.5]

I want to use multiple charts on the same page.

I tried to use the sample script from the Highcharts page:

        var chart; // global

    /**
     * Request data from the server, add it to the graph and set a timeout to request again
     */
    function requestData() {
        $.ajax({
            url: 'rssi.txt', 
            success: function(point) {
                var series = chart.series[0],
                    shift = series.data.length > 30; // shift if the series is longer than 20

                // add the point
                chart.series[0].addPoint(eval(point), true, shift);

                // call it again after one second
                setTimeout(requestData, 1700);  
            },
            cache: false
        });

    }

    $(document).ready(function() {
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container',
                defaultSeriesType: 'spline',
                events: {
                    load: requestData
                }
            },
            title: {
                text: 'RSSI'
            },
            xAxis: {
                type: 'datetime',
                tickPixelInterval: 150,
                maxZoom: 20 * 1000
            },
            yAxis: {
                minPadding: 2.5,
                maxPadding: 2.5,
                title: {
                    text: 'dBm',
                    margin: 80
                }
            },
            series: [{
                name: 'RSSI',
                data: []
            }]
        }); 

    });

Copy pasting the script outside the and changing the URL does not work. (only one chart is getting updates)

If I create a second requestData()-function and copy the $(document).ready part does not work either.

Is this possible in Highcharts? It would be not a problem to combine the input files into a single file, if that would help.

Edit:

I tried to solve it using the answers here:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Signal</title>


  <!-- 1. Add these JavaScript inclusions in the head of your page -->
  <script type="text/javascript" src="jquery-1.10.1.js"></script>
  <script type="text/javascript" src="highcharts.js"></script>

  <!-- 2. Add the JavaScript to initialize the chart on document ready -->
  <script>
    var chart; // global
    var chartRsrp;

    /**
     * Request data from the server, add it to the graph and set a timeout to request again
     */
    function requestData() {
      $.ajax({
        url: 'rssi.txt',
        success: function(point) {
          var series = chart.series[0],
            shift = series.data.length > 30; // shift if the series is longer than 20

          // add the point
          chart.series[0].addPoint(eval(point), true, shift);

          // call it again after one second
          setTimeout(requestData, 1700);
        },
        cache: false
      });
    }

    function requestData2() {
      $.ajax({
        url: 'rsrp.txt',
        success: function(point) {
          var series = chartRsrp.series[0],
            shift = series.data.length > 30; // shift if the series is longer than 20

          // add the point
          chartRsrp.series[0].addPoint(eval(point), true, shift);

          // call it again after one second
          setTimeout(requestData, 1700);
        },
        cache: false
      });
    }


    $(document).ready(function() {
      chart = new Highcharts.Chart({
        chart: {
          renderTo: 'container',
          defaultSeriesType: 'spline',
          events: {
            load: requestData
          }
        },
        title: {
          text: 'RSSI'
        },
        xAxis: {
          type: 'datetime',
          tickPixelInterval: 150,
          maxZoom: 20 * 1000
        },
        yAxis: {
          minPadding: 2.5,
          maxPadding: 2.5,
          title: {
            text: 'dBm',
            margin: 80
          }
        },
        series: [{
          name: 'RSSI',
          data: []
        }]
      });

      chartRsrp = new Highcharts.Chart({
        chart: {
          renderTo: 'container2',
          defaultSeriesType: 'spline',
          events: {
            load: requestData2
          }
        },
        title: {
          text: 'RSRP'
        },
        xAxis: {
          type: 'datetime',
          tickPixelInterval: 150,
          maxZoom: 20 * 1000
        },
        yAxis: {
          minPadding: 2.5,
          maxPadding: 2.5,
          title: {
            text: 'dBm',
            margin: 80
          }
        },
        series: [{
          name: 'RSRP',
          data: []
        }]
      });

    });
  </script>

</head>

<body>

  <!-- 3. Add the container -->
  <div id="container" style="width: 800px; height: 400px; margin: 0 auto"></div>

  <div id="container2" style="width: 800px; height: 400px; margin: 0 auto"></div>

Edit 2: solved it that way:

                requestData2();
                requestData3();
                requestData4();
                setTimeout(requestData, 1300);

in the first requestData()


Solution

  • In Highcharts-land, each chart needs to be its own object. It's certainly possible to have multiple charts on the same page, but you'd have to make sure that:

    • Each chart is instantiated separately (in this case, if you're just copying/pasting the $(document).ready part, you're probably stepping on your chart variable. So, instead of a single chart variable you could set these up separately (e.g. chartRsrp = new Highcharts.Chart(...)) and be sure to reference them differently in your requestData calls.
    • Each chart is rendered to a different DOM element. So, you might render to "container-rsrp", "container-sinr", "container-rssi" etc.

    Hopefully this helps!