5

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

我正在尝试绘制一些实时数据,我通过在我的系列中添加点并在数据可用时刷新绘图来设法做到这一点。但是,我无法弄清楚如何使情节随着时间序列向右移动。

每个时间序列数据点都有一个以 (int) 1 递增的 X 值,我尝试使用 .Pan() 来实现自动滚动,如下所示:

xAxis.Pan(-1);

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

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

我的问题是,我怎样才能确定我需要用来平移真实数据的增量?我假设这将取决于缩放级别,显然如果它在我放大和缩小时继续工作会很好。我想解决方案涉及某种依赖于刻度间隔的像素宽度或其他东西的功能但我无法弄清楚。

PS:我也在 OxyPlot 讨论页面上问过这个问题

谢谢,

阿门

4

3 回答 3

8

感谢decatf在这里发布我的问题的答案并说:

Axis 类中的 Transform 函数将数据坐标转换为屏幕坐标。有一个 InverseTransform 可以做相反的事情。

所以你可以尝试:

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

与轴零位置有一些偏移(我认为?)所以我们需要在变换中考虑到这一点以获得单位步长。

于 2014-02-12T12:27:51.757 回答
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
于 2015-10-18T12:09:25.797 回答
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);
        }          
    }
于 2017-02-12T17:03:10.993 回答