OxyPlot 自动缩放
OxyPlot AutoScale
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 代码看起来像
<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>
如何实现Y轴拖动后自动缩放?例如,当我在 window 中拖动图表时,只出现一条线 ((1,2),(4,4))。 Y 轴将显示从 2 到 4.Thanks.
如果您只想重置 Y 轴,您需要先为 Y 轴设置一个键。
LAX = new OxyPlot.Axes.LinearAxis()
{
Key = "YAxis",
Position = OxyPlot.Axes.AxisPosition.Bottom,
AbsoluteMaximum = 200,
AbsoluteMinimum = 1,
MinorStep=5,
};
然后您可以使用 LINQ 获取对它的引用。在拖动事件后调用以下命令。
Axis yAxis = PlotModel.Axes.FirstOrDefault(s => s.Key == "YAxis");
yAxis.Reset();
如果您想同时重置 X 轴和 Y 轴,您可以调用
PlotModel.ResetAllAxes();
首先,您将无法使用您正在使用的控制器重新缩放任何东西,因为它会阻止任何 panning/zooming 能力。默认情况下,右键单击平移并在鼠标滚轮上缩放。此外,您在创建时绘制模型会自动绘制所有点,因此无需重新缩放。但是假设您有一种平移和缩放的方法,您可以执行以下操作来自动重新计算 y 轴上应该具有的最大值:
让我们首先创建一个 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);
}
}
它所做的是首先找到适合当前看到的 XAxis 范围内的所有点,并将它们存储在 ptlist 值中。然后它迭代这个列表并找到相应的最大和最小 y。然后你只需要将这些最大值和最小值应用于你的 y 轴。请注意我用来允许在顶部和底部放置额外 space 的边距值。
现在您必须将此方法绑定到 x 轴的 AxisChanged 事件。在将轴添加到绘图之前,在 Chart() 中添加
LAX.AxisChanged += (sender, e) => AdjustYExtent(LS, LAX, LAY); ;
它现在应该会根据您的 x 轴自动缩放您的 y 轴。
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 代码看起来像
<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>
如何实现Y轴拖动后自动缩放?例如,当我在 window 中拖动图表时,只出现一条线 ((1,2),(4,4))。 Y 轴将显示从 2 到 4.Thanks.
如果您只想重置 Y 轴,您需要先为 Y 轴设置一个键。
LAX = new OxyPlot.Axes.LinearAxis()
{
Key = "YAxis",
Position = OxyPlot.Axes.AxisPosition.Bottom,
AbsoluteMaximum = 200,
AbsoluteMinimum = 1,
MinorStep=5,
};
然后您可以使用 LINQ 获取对它的引用。在拖动事件后调用以下命令。
Axis yAxis = PlotModel.Axes.FirstOrDefault(s => s.Key == "YAxis");
yAxis.Reset();
如果您想同时重置 X 轴和 Y 轴,您可以调用
PlotModel.ResetAllAxes();
首先,您将无法使用您正在使用的控制器重新缩放任何东西,因为它会阻止任何 panning/zooming 能力。默认情况下,右键单击平移并在鼠标滚轮上缩放。此外,您在创建时绘制模型会自动绘制所有点,因此无需重新缩放。但是假设您有一种平移和缩放的方法,您可以执行以下操作来自动重新计算 y 轴上应该具有的最大值:
让我们首先创建一个 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);
}
}
它所做的是首先找到适合当前看到的 XAxis 范围内的所有点,并将它们存储在 ptlist 值中。然后它迭代这个列表并找到相应的最大和最小 y。然后你只需要将这些最大值和最小值应用于你的 y 轴。请注意我用来允许在顶部和底部放置额外 space 的边距值。
现在您必须将此方法绑定到 x 轴的 AxisChanged 事件。在将轴添加到绘图之前,在 Chart() 中添加
LAX.AxisChanged += (sender, e) => AdjustYExtent(LS, LAX, LAY); ;
它现在应该会根据您的 x 轴自动缩放您的 y 轴。