wpf OxyPlot 自动缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29608087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OxyPlot AutoScale
提问by A191919
AutoScale OxyPlot Chart. For example i have something like this.
AutoScale OxyPlot 图表。例如我有这样的事情。
using OxyPlot;
using OxyPlot.Axes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OxyPlot.Wpf;
using PlotControllerTest.Properties;
using System.Diagnostics;
namespace PlotControllerTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public class Chart
{
public PlotController myController { get; set; }
private OxyPlot.Series.LineSeries LS;
OxyPlot.Axes.LinearAxis LAY;
OxyPlot.Axes.LinearAxis LAX;
private int i = 0;
public PlotModel PlotModel {get;set;}
public Chart()
{
PlotModel = new PlotModel();
myController = new PlotController();
myController.UnbindAll();
myController.BindMouseDown(OxyMouseButton.Left, OxyPlot.PlotCommands.PanAt);
LS = new OxyPlot.Series.LineSeries();
LAY = new OxyPlot.Axes.LinearAxis()
{
Position = OxyPlot.Axes.AxisPosition.Left,
AbsoluteMaximum = 100,
AbsoluteMinimum = 1,
};
LAX = new OxyPlot.Axes.LinearAxis()
{
Position = OxyPlot.Axes.AxisPosition.Bottom,
AbsoluteMaximum = 200,
AbsoluteMinimum = 1,
MinorStep=5,
};
PlotModel.Series.Add(LS);
PlotModel.Axes.Add(LAY);
PlotModel.Axes.Add(LAX);
}
public void BeginAddPoints()
{
Random rnd = new Random();
do
{
int temp=rnd.Next(1, 100);
LS.Points.Add(new DataPoint( ++i,temp));
System.Threading.Thread.Sleep(100);
Update();
} while (i<30);
Update();
}
public void Update()
{
PlotModel.InvalidatePlot(true);
}
}
public partial class MainWindow : Window
{
Chart TChart;
delegate void BeginUpdate();
private Stopwatch stopwatch = new Stopwatch();
private long lastUpdateMilliSeconds;
public MainWindow()
{
TChart = new Chart();
BeginUpdate BU = new BeginUpdate(TChart.BeginAddPoints);
IAsyncResult result = BU.BeginInvoke(null,null);
DataContext = TChart;
CompositionTarget.Rendering += CompositionTargetRendering;
InitializeComponent();
}
private void CompositionTargetRendering(object sender, EventArgs e)
{
if (stopwatch.ElapsedMilliseconds > lastUpdateMilliSeconds + 300)
{
TChart.Update();
}
}
}
}
}
Xaml code look's like
Xaml 代码看起来像
<Window x:Class="PlotControllerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
Title="MainWindow" Height="350" Width="525">
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" DefaultTrackerTemplate="{x:Null}" Controller="{Binding myController}"></oxy:PlotView>
</Grid>
How to implement autoscale of Y Axes after dragging? For example when i drag chart in window, and there appears only one Line ((1,2),(4,4)). Y axis will show from 2 to 4.Thanks.
拖动后如何实现Y轴的自动缩放?例如,当我在窗口中拖动图表时,只出现一条线 ((1,2),(4,4))。Y 轴将显示从 2 到 4。谢谢。
回答by Kurtis Aung
If you would like to reset just the Y Axis, you would need to set a Key to your Y-Axis first.
如果您只想重置 Y 轴,则需要先为 Y 轴设置一个关键点。
LAX = new OxyPlot.Axes.LinearAxis()
{
Key = "YAxis",
Position = OxyPlot.Axes.AxisPosition.Bottom,
AbsoluteMaximum = 200,
AbsoluteMinimum = 1,
MinorStep=5,
};
Then you could get a reference to it by using LINQ. Call the following after your dragging event.
然后您可以使用 LINQ 获得对它的引用。在拖动事件后调用以下命令。
Axis yAxis = PlotModel.Axes.FirstOrDefault(s => s.Key == "YAxis");
yAxis.Reset();
If you would like to reset both the X and Y Axis then, you could just call
如果您想同时重置 X 轴和 Y 轴,则可以调用
PlotModel.ResetAllAxes();
回答by samuel guedon
First thing, you will not have anything to rescale with the controller you are using as it blocks any panning/zooming abilities. By default panning is on the right click and zooming on mouse wheel. Also you plotmodel at creation will automatically plot all your points, so there is nothing to rescale. But let's assume you have a way to pan and zoom, what you can do to auto recalculate the maximum values you should have on your y axis is as following :
首先,您将无法使用正在使用的控制器重新缩放,因为它会阻止任何平移/缩放功能。默认情况下,平移是在鼠标滚轮上单击鼠标右键和缩放。此外,您在创建时 plotmodel 将自动绘制所有点,因此无需重新缩放。但是让我们假设您有一种平移和缩放的方法,您可以执行以下操作来自动重新计算 y 轴上应具有的最大值:
Let's first create a AdustYExtent method :
让我们首先创建一个 AdustYExtent 方法:
private void AdjustYExtent(OxyPlot.Series.LineSeries lserie, OxyPlot.Axes.LinearAxis xaxis, OxyPlot.Axes.LinearAxis yaxis)
{
if (xaxis != null && yaxis != null && lserie.Points.Count() != 0)
{
double istart = xaxis.ActualMinimum;
double iend = xaxis.ActualMaximum;
var ptlist = lserie.Points.FindAll(p => p.X >= istart && p.X <= iend);
double ymin = double.MaxValue;
double ymax = double.MinValue;
for (int i = 0; i <= ptlist.Count()-1; i++)
{
ymin = Math.Min(ymin, ptlist[i].Y);
ymax = Math.Max(ymax, ptlist[i].Y);
}
var extent = ymax - ymin;
var margin = extent * 0; //change the 0 by a value to add some extra up and down margin
yaxis.Zoom(ymin - margin, ymax + margin);
}
}
What it does is first to find all your points that fit in the XAxis range currently seen and store them in the ptlist value. Then it iterates this list and find the corresponding max and min y. Then you just have to apply those maximum and minimum to your y axis. Note the margin value that I use to allow to put extra space on top and bottom.
它的作用是首先找到适合当前看到的 XAxis 范围的所有点,并将它们存储在 ptlist 值中。然后它迭代这个列表并找到相应的最大值和最小值 y。然后你只需要将这些最大值和最小值应用于你的 y 轴。请注意我用来允许在顶部和底部放置额外空间的边距值。
Now you have to bind this method to the AxisChanged event of the x axis. In Chart() before adding your axes to the plot, add
现在您必须将此方法绑定到 x 轴的 AxisChanged 事件。在将轴添加到绘图之前,在 Chart() 中,添加
LAX.AxisChanged += (sender, e) => AdjustYExtent(LS, LAX, LAY); ;
It should now auto scale your y axis depending on your x axis.
它现在应该根据您的 x 轴自动缩放您的 y 轴。

