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.
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)
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);
}
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);
Dans l'actuel OxyPlot.Wpf (1.0.0-unstable1983), vous avez deux options:
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.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++;
}
Trois options existent pour actualiser le tracé (à partir de documentation OxyPlot ):
Model
du contrôle PlotView
Invalidate
sur le contrôle PlotView
Invalidate
sur le PlotModel
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