【问题标题】:Highcharts - Redundant Y Axis Point Markers (Any insight welcome!)Highcharts - 冗余 Y 轴点标记(欢迎任何见解!)
【发布时间】:2018-01-11 16:33:05
【问题描述】:

动态多 Y 轴存在问题。有时,样条线会记录两个数据点并弄乱样条线。 此代码位于可编程逻辑控制器中,该控制器采用“小部件适配器”,其中 HTML 被单独处理。 诚然,我对此很擅长,并且已经成功地接近了我想要的结果。但是,我遇到了这个障碍,这些重复的点标记正在破坏作品。 欢迎任何建议。

MultiYAxesPointMarker Image

   // define javascript methods that will be called when widget need to be initialized or data updated. 
   // in these methods' context, beside jQuery, following variables are accessible:
   //   * this.elem - parent DOM element 
   //   * this.datas - data object, you can access data by this.datas['data1'], this.datas['data2'] ... this.datas['data16'].
   //                  data may be undefined if it is not binded in CPT

   // [optional] if this method defined, it should return a array of required javascript files
   // below is an example for highcharts:
   //
   this.requiredScripts = function() {   
   return ["../user_codes/highcharts/js/highcharts.js",
       "../user_codes/highcharts/js/highcharts-more.js",
       "../user_codes/highcharts/js/exporting.js"];
   };

    this.init = function() {   
   // PUT INITIALIZATION CODES BELOW         
   Highcharts.setOptions({
        global: {
            useUTC: false
        }
       });

   $(this.elem).highcharts({
        chart: {
            //type: 'line',
            animation: Highcharts.svg, // don't animate in old IE
            duration:250,
            marginRight: 250,
            marginLeft:  125,
            events: {
            }
        },
        credits: { enabled: false },
        title: {
            text: 'Energy Valve'
        },
        xAxis: {
            type: 'datetime',
            tickPixelInterval: 100,
        },  
    //yAxisyAxisyAxisyAxisyAxisyAxisyAxisyAxisyAxisyAxisyAxis                

        yAxis: [{//-------------------------------FLOW
            yAxis:0,
            min:0,
            max:10,
            startOnTick:false,
            endOnTick:false,
            title: {
              text: 'Flow',
              style:{
                 color: '#0b8dbc'
              }
            },

            labels: {
              format: '{value}gpm',
              style: {
                color:'#0b8dbc'
              }
            },
            opposite:false
        },{      //-----------------------------------Valve Position  
            yAxis:1,
            min:0,
            max:100,
            startOnTick:false,
            endOnTick:false,
            title: {
            text: 'Valve Position',
            style:{
              color: '#046804'
              }
            },
            labels: {
              format: '{value}%',
              style: {
                color: '#046804'
              }
            },
            opposite:true

        },{     //------------------------------- Diff Pressure
            yAxis:2,
            min:0,
            max:20,
            startOnTick:false,
            endOnTick:false,
            title: {
            text: 'Diff Pressure',
            style:{
              color: 'rgb(255,124,14)'
              }
            },
            labels: {
              format: '{value}psi',
              style: {
                color: 'rgb(255,124,14)'
              }
            },
            opposite:true
        }],

        legend: {
            enabled:true,
            layout: 'vertical',
            align: 'left',
            x: 110,
            verticalAlign: 'top',
            y: 37,
            floating: false,
            backgroundColor:  'rgba(252, 249, 237,0.52)'
                },
        exporting: {
            enabled: false
        },
   //SeriesSeriesSeriesSeriesSeriesSeriesSeriesSeries            
        series: [{
           //-------------------------------Flow 
            yAxis:0,
            name: 'Flow',
            color:'#0b8dbc',
            type: 'spline',
            lineColor:'#0b8dbc',
            //fillColor:'rgba(174, 222, 239,0.2)',
            marker: {
              fillColor: '#aedeef',
              lineWidth: 1,
              lineColor: '#0878a0' // inherit from series
            },

            data: (function () {
                // generate an array of random data
                var data = [],
                    time = (new Date()).getTime(),
                    i;

                for (i = -19; i <= 0; i += 1) {
                    data.push({
                        x: time + i * 1000,
                        y: Math.floor((Math.random() * 3) + 1)
                    });
                }
                return data;
            }()),

        },{ 
          //-----------------------------------Valve Position  
            yAxis:1,
            name: 'Valve Position',
            color:'#046804',
            type: 'spline',
            lineColor:'#046804',
            //fillColor:'rgba(174, 222, 239,0.2)',
            marker: {
              fillColor: '#5cd12e',
              lineWidth: 1,
              lineColor: '#046804' // inherit from series
            },
            data: (function () {
                // generate an array of random data
                var data = [],
                    time = (new Date()).getTime(),
                    i;

                for (i = -19; i <= 0; i += 1) {
                    data.push({
                        x: time + i * 1000,
                        y: Math.floor((Math.random() * 3) + 1)
                    });
                }
                return data;

            }()),


        },{ 
          //------------------------------- Diff Pressure
          yAxis:2,
          name: 'Diff Pressure',
            color:'rgba(255, 124, 14,0.2)',
            type: 'areaspline',
            lineColor:'#ff7c0e',
            fillColor:'rgba(255, 124, 14,0.2)',
            marker: {
              fillColor: '#eda66a',
              lineWidth: 1,
              lineColor: '#bc5905' // inherit from series
            },
            data: (function () {
                // generate an array of random data
                var data = [],
                    time = (new Date()).getTime(),
                    i;

                for (i = -19; i <= 0; i += 1) {
                    data.push({
                        x: time + i * 1000,
                        y: Math.floor((Math.random() * 4) + 1)
                    });
                }
                return data;
            }
            ()),







        }]
    });
};

this.update = function() {

 //PUT DATA UPDATE CODES BELOW
 var index = $(this.elem).data("highchartsChart");
 var chart = Highcharts.charts[index];
var series0 = chart.series[0];
var series1 = chart.series[1];
 var series2 = chart.series[2];
 var data0 = this.readData("@GPM");
 var data1 = this.readData("@POS");
 var data2 = this.readData("@DP");
 var x = (new Date()).getTime();
 var y = parseFloat(data0);
 var z = parseFloat(data1);
 var c = parseFloat(data2);


series0.addPoint([x,y], true, true);
 series1.addPoint([x,z], true, true);
 series2.addPoint([x,c], true, true);

};

this.cleanup = function() {
//PUT CLEAN UP CODES BELOW
 //JL 1-9-18
};

【问题讨论】:

  • 也许它们不是重复的,而是真实数据(峰值可能?)
  • 你说得对。这些点背后的数据确实在不断变化。您有什么建议可以分享以降低更新频率?
  • 将我之前的评论和一些建议纳入答案

标签: jquery dynamic charts highcharts yaxis


【解决方案1】:

正如我的comment 中提到的,这些数据值似乎是常规值而不是重复点;他们只是碰巧是真正及时关闭的事件。根据您的评论:

您有什么建议可以分享以降低更新频率?

分析您的代码,我们可以看到您每次调用this.update = function(){} 时都会在图表中绘制新点。您的图表显示了这些非常接近的点,因为该函数肯定是以非固定间隔调用的,因此如果您经常更新,您的 x = (new Date()).getTime(); 值非常接近。

当然,解决此问题的一种方法是定期调用您的update 函数,这样您就不会及时获得彼此过于接近的值。

但是,如果您无法这样做(不过,我建议您尝试一下),另一种解决方案是仅在验证调用 update 之间经过的时间后才添加分数。您可以通过将x 变量存储在别处来实现此目的,以便在下次调用update 时进行比较。

然后您可以检查呼叫之间是否存在最短经过时间(例如 60 秒),然后决定是否要绘制点。这样一来,您就可以消除那些“重复”的值,以防您无法处理对update 的调用频率。

编辑:为了举例说明第二个选项,我的建议如下所示。

首先,您必须将初始时间存储在一个变量中,我们可以使用该变量来跟踪上次更新的时间:

//Somewhere inside your initialization, capture the date you start the program
this.init = function() {
  var previousUpdate = (new Date()).getTime();

  //...the rest of your code...
}

之后,您可以在更新调用中使用该变量来查看是否绘制,如下所示:

//Now, on your update, we can compare time between calls   
this.update = function() {
 //get the time now
 var x = (new Date()).getTime();

 //now, compare if some minimum time interval has elapsed
 var timeInterval = x - previousUpdate 
 //Remember to update your previous time for next comparison
 previousUpdate = x
 //if time ellapsed is more than, say, 1000 units (depends what units you want)
 //then plot, else don't do anything
 if(timeInterval > 1000){
   //PUT DATA UPDATE CODES BELOW
   var index = $(this.elem).data("highchartsChart");
   var chart = Highcharts.charts[index];
   var series0 = chart.series[0];
   var series1 = chart.series[1];
   var series2 = chart.series[2];
   var data0 = this.readData("@GPM");
   var data1 = this.readData("@POS");
   var data2 = this.readData("@DP");
   var y = parseFloat(data0);
   var z = parseFloat(data1);
   var c = parseFloat(data2);

   series0.addPoint([x,y], true, true);
   series1.addPoint([x,z], true, true);
   series2.addPoint([x,c], true, true);
 }
 //else just do nothing :)
};

只有当它们在时间上彼此足够远时,您才会将点绘制到图表上,然后您可以调整最小距离以满足您的需求(较小意味着允许频繁更新,反之亦然)。

【讨论】:

  • 感谢您引导我找到问题的根源。不幸的是,我一直在尝试在更新中使用 setInterval() 一段时间,但没有太多运气。我走在正确的道路上吗?
  • 嘿@JustinLindstrom 我认为你确实走对了,如果你能确定从最后一次调用到更新的时间间隔,那么只有在至少 (>=) 时才能轻松调用 addPoint相隔N秒。这样你就不会太频繁地获得积分
  • 再次感谢。看来我实际上是在让这些图表变得更糟一些。我应该为整个更新调用 setInterval() 还是只调用 series.addPoint?我都尝试过,但遇到了一些错误和控制台警报。可能是时候睡觉了。这是漫长的一天。
  • @JustinLindstrom 是的,有时候睡个好觉可以创造奇迹。我想你可能过于复杂了,如果你想明天联系我,我们可以继续
  • 睡了一小会:)。因此,我退出并查看了“适配器小部件”文档,并且有一条注释说明每当 @userProperty 即“@GPM”、“@DP”和“@PSI”在我的情况下在控制器中更新时this.update 回调将执行并将数据发布到关联的变量中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多