23

程序的图形用户界面

Oxyplot 绘制了 13 个点,这些点来自 6 个用户输入文本框。文本框中的值保存在 MainWindow.xaml.cs 类的公共变量中。当用户在文本框中按下回车键时,变量会更新。我如何让刷新按钮刷新图表。

private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            //Refresh The Graph
        }

我认为这将使用

PlotModel.RefreshPlot() 

方法,但我不确定如何实现它,因为 Oxyplot 的文档很差。

4

7 回答 7

39

我刚刚通过 NuGet 更新到新版本的 OxyPlot。我正在使用 OxyPlot.Wpf v20014.1.277.1,我认为您现在需要调用InvalidatePlot(bool updateData)PlotModel不是 RefreshPlot (不再可用)。我在我的示例代码中对此进行了测试,它按预期工作。

如果要刷新绘图更新数据集合,则需要传递true给调用:

PlotModel.InvalidatePlot(true)
于 2014-04-10T13:50:55.120 回答
7

Give x:Name to OxyPlot instance in XAML:

<oxy:Plot x:Name="Plot1"/>

and on button click handler, refresh like this:

private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
   Plot1.RefreshPlot(true);
}
于 2014-01-05T09:57:53.040 回答
7

我发现获得“某种”自动更新的最干净的方法是对 LineSeries 的 ItemsSource 集合上的 CollectionChanged 做出反应。

在视图模型中:

ObservableCollection<DataPoint> Data { get; set; } 
    = new ObservableCollection<DataPoint>();

public PlotModel PlotModel
{
    get { return _plot_model; }
    set
    {
        _plot_model = value;
        RaisePropertyChanged(() => PlotModel);
    }
}
PlotModel _plot_model;

// Inside constructor:
Data.CollectionChanged += (a, b) => PlotModel.InvalidatePlot(true);
于 2017-01-04T16:25:25.380 回答
5

在当前的 OxyPlot.Wpf (1.0.0-unstable1983) 中,您有两个选择:

  1. 将 XAML 中的属性绑定Series.ItemsSource到视图模型中的集合,并在需要更新时交换整个集合。这也允许使用更大的数据集进行并发异步更新。
  2. Plot.InvalidateFlag将type 的属性绑定int到您的视图模型,并在您需要更新时递增。不过,我还没有测试过这种方法。

以下代码说明了这两个选项(选择一个)。XAML:

<oxy:Plot InvalidateFlag="{Binding InvalidateFlag}">
    <oxy:Plot.Series>
        <oxy:LineSeries ItemsSource="{Binding DataSeries}" />
      </oxy:Plot.Series>
 </oxy:Plot>

ViewModel 的更新:

private async Task UpdateAsync()
{
    // TODO do some heavy computation here
    List<DataPoint> data = await ...

    // option 1: Trigger INotifyPropertyChanged on the ItemsSource.
    //           Concurrent access is ok here.
    this.DataSeries = data; // switch data sets

    // option 2: Update the data in place and trigger via flag
    //           Only one update at a time.
    this.DataSeries.Clear();
    data.ForEach(this.DataSeries.Add);
    this.InvalidateFlag++;
}
于 2016-02-24T08:06:07.283 回答
4

在对同样的问题提出同样的问题之后,似乎唯一可行的解​​决方案(至少在我看来)如下:

PlotView.InvalidatePlot(true)

这样做,在更新一个或多个之后Series刷新你的PlotView.

刷新率取决于您的系列更新的频率或频率。

这是一个代码片段(在 Xamarin Android 上,但应该可以工作):

PlotView resultsChart = FindViewById<PlotView>(Resource.Id.resultsChart);
PlotModel plotModel = new PlotModel
{
    // set here main properties such as the legend, the title, etc. example :
    Title = "My Awesome Real-Time Updated Chart",
    TitleHorizontalAlignment = TitleHorizontalAlignment.CenteredWithinPlotArea,
    LegendTitle = "I am a Legend",
    LegendOrientation = LegendOrientation.Horizontal,
    LegendPlacement = LegendPlacement.Inside,
    LegendPosition = LegendPosition.TopRight
    // there are many other properties you can set here
}

// now let's define X and Y axis for the plot model

LinearAxis xAxis = new LinearAxis();
xAxis.Position = AxisPosition.Bottom;
xAxis.Title = "Time (hours)";

LinearAxis yAxis = new LinearAxis();
yAxis.Position = AxisPosition.Left;
yAxis.Title = "Values";

plotModel.Axes.Add(xAxis);
plotModel.Axes.Add(yAxis);

// Finally let's define a LineSerie

LineSeries lineSerie = new LineSeries
 {
    StrokeThickness = 2,
    CanTrackerInterpolatePoints = false,
    Title =  "Value",
    Smooth = false
  };
plotModel.Series.Add(lineSerie);
resultsChart.Model = plotModel;

DataPoints现在,每当您需要添加LineSerie并相应地自动更新时PlotView,只需执行以下操作:

resultsChart.InvalidatePlot(true);

这样做会自动刷新您的PlotView.

附带说明一下,PlotView当事件发生时也会更新,例如触摸、捏缩放或任何类型的 UI 相关事件。

我希望我能帮上忙。很长一段时间以来,我都遇到了麻烦。

于 2014-11-10T16:08:28.847 回答
3

存在三种如何刷新绘图的替代方案(来自OxyPlot 文档):

  • 更改控件的Model属性PlotView
  • 调用控件Invalidate_PlotView
  • 致电Invalidate_PlotModel
于 2016-10-25T10:02:39.987 回答
1

又过了两年……这个解决方案对我有用,因为我没有 oxyplot 模型,而且我错过了上面的一些命名函数。

后面的代码:

public partial class LineChart : UserControl
{
    public LineChart()
    {
        InitializeComponent();

        DataContext = this;
        myChart.Title = "hier könnte Ihr Text stehen!";

        this.Points = new List<DataPoint>();
        randomPoints();
    }


    public IList<DataPoint> Points { get; private set; }

    public void randomPoints()
    {
        Random rd = new Random();
        String myText = "";

        int anz = rd.Next(30, 60);

        for (int i = 0; i < anz; i++)
            myText += i + "," + rd.Next(0, 99) + ";";

        myText = myText.Substring(0, myText.Length - 1);
        String[] splitText = myText.Split(';');

        for (int i = 0; i < splitText.Length; i++)
        {
            String[] tmp = splitText[i].Split(',');
            Points.Add(new DataPoint(Double.Parse(tmp[0].Trim()), Double.Parse(tmp[1].Trim())));
        }

        while (Points.Count > anz)
            Points.RemoveAt(0);

        myChart.InvalidatePlot(true);
    }
}

要更新您的数据,请不要交换整个 IList,而是向其中添加一些新的数据点并删除位置 0 处的旧数据点。

XAML:

<UserControl x:Class="UxHMI.LineChart"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:UxHMI"
         xmlns:oxy="http://oxyplot.org/wpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="Container" Background="White">
    <oxy:Plot x:Name="myChart" Title="{Binding Title}" FontFamily="Bosch Sans Medium" Foreground="#FF0C6596" FontSize="19" Canvas.Left="298" Canvas.Top="32" Background="AliceBlue" Margin="0,0,10,0">
        <oxy:Plot.Series>
            <oxy:LineSeries x:Name="ls" Background="White" ItemsSource="{Binding Points}" LineStyle="Solid" Color="ForestGreen" MarkerType="None" MarkerSize="5" MarkerFill="Black">

            </oxy:LineSeries>
        </oxy:Plot.Series>
    </oxy:Plot>
    <Button x:Name="button" Content="Random" HorizontalAlignment="Left" Margin="0,278,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
</Grid>

重要的是x:Name="myChart"ItemsSource="{Binding Points}"

我希望这对那里的人有用

于 2019-01-03T10:42:25.070 回答