【问题标题】:OxyPlot AutoScaleOxyPlot 自动缩放
【发布时间】:2015-06-06 06:06:57
【问题描述】:

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轴拖拽后如何实现自动缩放?例如,当我在窗口中拖动图表时,只出现一条线((1,2),(4,4))。 Y 轴将显示 2 到 4。谢谢。

【问题讨论】:

  • 我知道如何使用烛台系列但不使用线条系列。我缺少一种基于 x (1
  • 我刚刚用你的代码创建了一个项目,我不确定你的拖动是什么意思。您的项目会自动调整 x 轴以显示从 0 到 max(x)(oxyplot 的本机函数),并且由于它在 y 轴上也是如此,因此您始终可以看到所有值。

标签: c# wpf oxyplot


【解决方案1】:

如果您只想重置 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();

【讨论】:

    【解决方案2】:

    首先,您将无法使用正在使用的控制器重新调整任何内容,因为它会阻止任何平移/缩放功能。默认情况下,平移是右键单击并在鼠标滚轮上缩放。此外,您在创建时的 plotmodel 将自动绘制所有点,因此无需重新缩放。但是让我们假设你有一种平移和缩放的方法,你可以做些什么来自动重新计算你应该在你的 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 轴。请注意我用来允许在顶部和底部放置额外空间的边距值。

    现在您必须将此方法绑定到 x 轴的 AxisChanged 事件。在将坐标轴添加到绘图之前的 Chart() 中,添加

    LAX.AxisChanged += (sender, e) => AdjustYExtent(LS, LAX, LAY); ;
    

    它现在应该根据您的 x 轴自动缩放您的 y 轴。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 2019-02-24
      • 2019-08-16
      • 2018-12-13
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      相关资源
      最近更新 更多