How to refresh oxyplot plot when data changes

前端 未结 7 1343
予麋鹿
予麋鹿 2021-02-07 02:10

\"GUI

Oxyplot graphs 13 points which are derived from the 6 user input text boxes. The values in

相关标签:
7条回答
  • 2021-02-07 02:38

    After having the same question with the same issue, it would seem that the only working solution (at least to my point of view) is as followed :

    PlotView.InvalidatePlot(true)

    Doing so, after updating one or multple Series do refresh your PlotView.

    The refresh rate depends on how often, or at which rate your serie(s) is/are updated.

    Here is a code snippet (on Xamarin Android but should work anyway) :

    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;
    

    Now, whenever you need to add DataPoints to your LineSerie and to updated automatically the PlotView accordingly, just do as followed :

    resultsChart.InvalidatePlot(true);
    

    Doing so will automatically refresh your PlotView.

    On a side note, the PlotView will also be updated when an event occurs such as a touch, a pinch to zoom, or any kind of UI-related events.

    I hope I could help. I had trouble with this for a very long time.

    0 讨论(0)
  • 2021-02-07 02:44

    In the current OxyPlot.Wpf (1.0.0-unstable1983) you have two options:

    1. Bind the Series.ItemsSource property from XAML to a collection in your viewmodel and exchange the whole collection, when you need an update. This also allows for concurrent async updates with larger data sets.
    2. Bind the Plot.InvalidateFlag property of type int to your viewmodel and increment whenever you need an update. I haven't tested this approach, though.

    The following code illustrates both options (pick one). XAML:

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

    Updates on the 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++;
    }
    
    0 讨论(0)
  • 2021-02-07 02:49

    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);
    }
    
    0 讨论(0)
  • 2021-02-07 02:52

    Exists three alternatives how refresh plot (from OxyPlot documentation):

    • Change the Model property of the PlotView control
    • Call Invalidate on the PlotView control
    • Call Invalidate on the PlotModel
    0 讨论(0)
  • 2021-02-07 02:53

    I just updated to a new version of OxyPlot via NuGet. I'm using OxyPlot.Wpf v20014.1.277.1 and I think you now need to call InvalidatePlot(bool updateData) on the PlotModel instead of RefreshPlot (which is no longer available). I tested this in my sample code and it worked as expected.

    If you want to refresh the plot and update the data collections, you need to pass true to the call:

    PlotModel.InvalidatePlot(true)
    
    0 讨论(0)
  • 2021-02-07 02:53

    Another two years later... this solution works for me, because I have no oxyplot models and I´m missing some of the named functions from above.

    code behind:

    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);
        }
    }
    

    To update your data don't exchange the whole IList, rather add some new DataPoints to it and remove old ones at position 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>
    

    important are the x:Name="myChart" and ItemsSource="{Binding Points}"

    I hope this is useful for someone out there

    0 讨论(0)
提交回复
热议问题