OxyPlot实时数据系列绘图中的自动滚动/窗格

时间:2014-02-10 20:18:23

标签: c# real-time oxyplot

我在C#winforms应用程序中使用OxyPlot。我的axese是LinearAxis类型。

我试图绘制一些实时数据,我已经设法通过在我的系列中添加点并在数据可用时刷新绘图。但是,我无法弄清楚如何使用时间序列使图表向右移动。

每个时间序列数据点的X值增加(int)1,我试图使用.Pan()来自动滚动:

xAxis.Pan(-1);

显然这没有用,因为我假设该方法采用像素输入或其他东西,因此平移比数据增量慢得多。

我也尝试用-MajorTIckSize和-MajorStepSize替换-1而没有运气,因为这些通常都太小了。

我的问题是,如何确定我需要用于平移真实数据的delta?我假设这将取决于缩放级别,显然它会很好,如果它会继续工作,因为我放大和缩小。我想解决方案涉及某种功能,依赖于滴答间隔的像素宽度或某事但我无法弄清楚。

PS:我在OxyPlot讨论页面上也问了this question

谢谢,

阿尔钦

3 个答案:

答案 0 :(得分:7)

感谢 decatf 发布我的问题here的答案并说:

  

Axis类中的Transform函数将转换数据坐标   屏幕坐标。有一个InverseTransform来做   对面。

     

所以你可以试试:

double panStep = xAxis.Transform(-1 + xAxis.Offset);
xAxis.Pan(panStep); 
     

轴零位置有一些偏移(我认为?)所以我们需要   在转换中考虑到了单位步骤。

答案 1 :(得分:0)

这是我的解决方案,假设您使用DateTimeAxis作为X坐标。

代码将在一个方向上平移轴,具体取决于两个值之间的时差。它还考虑缩放因子,因此您也不必担心这一点。

您应该使用Axis Transform和Pan方法:

//Assuming you've got two data points, 1 minute apart
//and you want to pan only the time axis of your plot (in this example the x-Axis).
double firstValue = DateTime.Now.ToOADate();
double secondValue = DateTime.Now.AddMinutes(1).ToOADate();

//Transfrom the x-Values (DateTime-Value in OLE Automation format) to screen-coordinates
double transformedfirstValue = YourAxis.Transform(firstValue);
double transformedsecondValue = YourAxis.Transform(secondValue);

//the pan method will calculate the screen coordinate difference/distance and will pan you axsis based on this amount
//if you are planing on panning your y-Axis or both at the same time, you  will need to create different ScreenPoints accordingly
YourAxis.Pan(
  new ScreenPoint(transformedfirstValue,0),
  new ScreenPoint(transformedsecondValue,0)
);

//Afterwards you will need to refresh you plot

答案 2 :(得分:0)

我搜索了一会儿,发现了一些过时的解决方案或者没有按预期工作。经过一些实验,我确定了 Axes.ActualMaximum是当前可见的最大值。 Axes.DataMaximum是数据的最大值(顾名思义)。 您想要取两者的差值并乘以比例值 Axes.Scale。然后使用计算值调用Axes.Pan。像这样:

public PlotModel GraphModel { get; private set; }

    public void AddPoints(double xPoint, double yPoint)
    {
        (this.GraphModel.Series[0] as LineSeries).Points.Add(new DataPoint(xPoint, yPoint));
        GraphModel.InvalidatePlot(true);

        //if autopan is on and actually neccessary
        if ((AutoPan) && (xPoint > GraphModel.Axes[0].Maximum))
        {
            //the pan is the actual max position of the observed Axis minus the maximum data position times the scaling factor
            var xPan = (GraphModel.Axes[0].ActualMaximum - GraphModel.Axes[0].DataMaximum) * GraphModel.Axes[0].Scale;
            GraphModel.Axes[0].Pan(xPan);
        }          
    }