web-dev-qa-db-fra.com

Comment actualiser le tracé oxyplot lorsque les données changent

GUI for the program

Oxyplot représente graphiquement 13 points dérivés des 6 zones de texte saisies par l'utilisateur. Les valeurs dans les zones de texte sont conservées dans des variables publiques de la classe MainWindow.xaml.cs. Les variables sont mises à jour lorsque l'utilisateur appuie sur entrer dans la zone de texte. Comment pourrais-je rendre le bouton d'actualisation actualiser le graphique.

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

Je pense que cela se ferait en utilisant le 

PlotModel.RefreshPlot() 

méthode, mais je ne sais pas comment la mettre en œuvre à cause de la médiocre documentation d’Oxyplot.

18
Jkallus

Je viens de mettre à jour une nouvelle version d'OxyPlot via NuGet. J'utilise OxyPlot.Wpf v20014.1.277.1 et je pense que vous devez maintenant appeler InvalidatePlot(bool updateData) sur la PlotModel au lieu de RefreshPlot (qui n'est plus disponible). J'ai testé cela dans mon exemple de code et cela a fonctionné comme prévu.

Si vous souhaitez actualiser le tracé et mettre à jour les collections de données, vous devez passer true à l'appel:

PlotModel.InvalidatePlot(true)
30
ruttopia

Donnez x:Name à l'instance OxyPlot en XAML:

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

et sur le gestionnaire de clic de bouton, actualisez comme ceci:

private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
   Plot1.RefreshPlot(true);
}
5
Rohit Vats

La méthode la plus propre que j'ai trouvée pour obtenir une "mise à jour automatique" consiste à réagir à CollectionChanged sur la collection qui est ItemsSource de LineSeries.

Dans ViewModel:

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);
3
heltonbiker

Dans l'actuel OxyPlot.Wpf (1.0.0-unstable1983), vous avez deux options:

  1. Liez la propriété Series.ItemsSource de XAML à une collection de votre modèle de vue et échangez la collection entière lorsque vous avez besoin d'une mise à jour. Cela permet également des mises à jour asynchrones simultanées avec des ensembles de données plus volumineux.
  2. Liez la propriété Plot.InvalidateFlag de type int à votre modèle de vue et incrémentez chaque fois que vous avez besoin d'une mise à jour. Je n'ai pas testé cette approche, cependant.

Le code suivant illustre les deux options (choisissez-en une). XAML:

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

Mises à jour sur le 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++;
}
2
Patrick Stalph

Trois options existent pour actualiser le tracé (à partir de documentation OxyPlot ):

  • Modifier la propriété Model du contrôle PlotView
  • Appelez Invalidate sur le contrôle PlotView
  • Appelez Invalidate sur le PlotModel
1
honzakuzel1989

Encore deux ans plus tard ... cette solution fonctionne pour moi, car je n’ai pas de modèle oxyplot et il me manque certaines des fonctions nommées ci-dessus.

code derrière:

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

Pour mettre à jour vos données n'échangez pas toute la liste IList, ajoutez-lui plutôt de nouveaux DataPoints et supprimez les anciens en 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>

importants sont les x: Name = "myChart" et ItemsSource = "{Binding Points}"

J'espère que cela est utile pour quelqu'un

0
prototype0815