高清图和“几乎经常”的时间间隔数据

时间:2017-11-12 13:11:35

标签: datetime highcharts

对于使用X轴上的日期时间的Highchart折线图,如何使用一个pointInterval的数据初始呈现图表,并使用另一个动态更新图表?

对于我的情况,初始渲染将使用恰好200个样本而不管持续时间。例如,假设给定图表的持续时间为1周。初始页面将接收200个数据点,相隔3,024秒(7 * 24 * 60 * 60/200)。然后,它将每隔60秒通过Ajax动态更新。

我尝试了多种方法,但是,Ajax 60秒刻度产生与初始页面3,024秒刻度相同的更改,或者最初创建的图表刻度更改或某些其他不期望的结果。该图表应该主要保持不变,但会使用新收到的Ajax数据慢慢更新。

以下https://jsbin.com/zuboyeh/edit?html,output显示了其中一些尝试。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Highcharts</title>
        <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
        <script src="https://code.highcharts.com/highcharts.js"></script>
        <script type="text/javascript">

            $(function() {
                /*
                Total of 6 options.

                Using pointAdd or pointUpdate.

                Also, three options this way
                Option 1.  Pre-load w/o time, change pointInterval, then continue with no time.  Doesn't work as it changes past date formats
                Option 2.  Pre-load w/o time, then continue with time.
                Option 3.  Pre-load w/ time, then continue with time.
                */

                //initially page will display daily data for one month
                var numberOfDatapointsToDisplay=200;    //Given
                var chartDuration = 7*24*60*60;  //One week given resulting in 60,4800 seconds
                var secondsInterval = chartDuration/numberOfDatapointsToDisplay;    //3024 seconds
                var pointInterval = 1000*secondsInterval;  //ms
                var tickInterval  = null; //tickInterval is the interval of the tick marks in axis units. Not sure how to handle
                var secondsIntervalAjax=60; //One minute given for ajax request time
                var currentTime=new Date().getTime()/1000; //UTC time
                var secondsStart=currentTime - numberOfDatapointsToDisplay*secondsInterval;   //Start a week in the past and then populate upon page load
                var pointStart = 1000*secondsStart;  //ms

                //Get initial data
                var data1=[],data2=[],data3=[];
                for (var i = 0; i < numberOfDatapointsToDisplay; i++) {
                    var v=gv(pointInterval/1000);   //Data simulator for this example
                    data1[i]=v; //attempt using a single value
                    data2[i]=[secondsStart,v];  //attempt using cartesian values
                    secondsStart+=secondsInterval;
                }

                $("#addPoint").click(function() {
                    //Simulate ajax request using addPoint()
                    currentTime+=secondsIntervalAjax;
                    var v=gv(secondsIntervalAjax);
                    chart1.series[0].addPoint(v, true, true); //attempt using a single value
                    chart2.series[0].addPoint([currentTime,v], true, true);  //attempt using cartesian values
                });
                $("#updateSeries").click(function() {
                    //Simulate ajax request using update()
                    currentTime+=secondsIntervalAjax;
                    var v=gv(secondsIntervalAjax);
                    data1.push(v);
                    data2.push([currentTime,v]);
                    chart1.series[0].update({data: data1}); //attempt using a single value
                    chart2.series[0].update({data: data2});  //attempt using cartesian values
                });

                $("#changePointInterval").click(function() {
                    //Try changing the pointInterval used for the initial page data and ajax data
                    chart1.series[0].update({pointInterval: secondsIntervalAjax*1000});
                    chart2.series[0].update({pointInterval: secondsIntervalAjax*1000});
                })

                var chart1 = new Highcharts.Chart({
                    chart: {
                        type: "line",
                        renderTo: 'container1'
                    },
                    xAxis: {
                        type: "datetime",
                        //tickInterval: tickInterval,
                        //tickPixelInterval: 50
                    },
                    series: [
                        {name: 'SeriesName', data: data1},
                    ],
                    plotOptions: {
                        series: {
                            pointStart: pointStart,
                            pointInterval: pointInterval,
                        }
                    },
                });
                var chart2 = new Highcharts.Chart({
                    chart: {
                        type: "line",
                        renderTo: 'container2'
                    },
                    xAxis: {
                        type: "datetime",
                        //tickInterval: tickInterval,
                        dateTimeLabelFormats: {month: '%e. %b',year: '%b'},
                        tickPixelInterval: 50
                    },
                    series: [
                        {name: 'SeriesName', data: data2},
                    ],
                    plotOptions: {
                        spline: {
                            marker: {
                                enabled: true
                            }
                        }
                    },
                });

                function gv(s) {
                    //Data simulator for new value after s seconds
                    if ( typeof this.v == 'undefined' ) {
                        this.v = 100;
                    }
                    this.v=this.v+50*numberOfDatapointsToDisplay*(Math.random()-.5) * s/chartDuration;
                    return this.v;
                }


            });
        </script>
    </head>
    <body>
        <button id="addPoint">addPoint</button>
        <button id="updateSeries">updateSeries</button>
        <button id="changePointInterval">changePointInterval</button>
        <div id="container1" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
        <div id="container2" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
    </body>
</html>

1 个答案:

答案 0 :(得分:1)

每个系列只能定义一个pointInterval

这个问题有2个最简单的解决方案:

<强> 1。为新值添加另一个链接系列 linkedTo:previous会导致图例切换对两个系列都有效。更改第二个系列的颜色,使其看起来与第一个系列完全相同。使用基本系列中的最后一个值设置pointStart

  events: {
    load: function() {
      var points = this.series[0].points,
        lastPoint = points[points.length - 1];

      this.series[1].update({
        pointStart: lastPoint.x,
        color: this.series[0].color
      });
    }
  }

(...)

series: [{
  name: 'SeriesName',
  data: data1
}, {
  name: 'SeriesName', // same name as the previous series
  pointInterval: secondsIntervalAjax * 10000, // 10 times bigger to see results faster
  linkedTo: ':previous',
  marker: {
    enabled: false
  }
}]

现场演示: http://jsfiddle.net/kkulig/gtsw8t3q/

<强> 2。计算并明确地为每个点分配x值

在这种情况下,不需要pointIntervalpointStart