Hallo zusammen, ich möchte in einem C# WPF-Programm Messkurven malen, indem ich einer Zeichenfläche zyklisch Messpunkte als Pixel hinzufüge. Im Augenblick mach ich das über ein Canvas mit einer Polyline, wobei ich der Polyline für jeden Messpunkt einen Point hinzufüge. Funktioniert gut, allerdings wird das Programm mit der Zeit immer langsamer, was ich darauf zurückführe, dass die Verwaltung der vielen Point-Objekte immer aufwendiger wird. Denn wenn ich die Points der Polyline lösche, ist die Geschwindigkeit sofort wieder da. Wenn ich hingegen einfach "unverwaltete" Pixel malen könnte, hätte ich das Problem nicht. Beim Googlen hab ich leider keine Alternative gefunden. Was könnte man da machen?
Wie wärs damit: Generating Graphs with WPF https://msdn.microsoft.com/en-us/magazine/ff714591.aspx Ist schon ein paar Jahre alt aber immer noch top.
Zeig mal wie du die Punkte hinzu fügst. Ich denke da kann man noch sehr viel optimieren. Vor allem würde ich immer nur die letzten, sagen wir mal 100, Punkte an die View übergeben, dann hast du ganz bestimmt kein Problem. Einfach im Viewmodel die Polyline Punkte beschneiden und dann haut das sicher hin. So denn,
Günter R. schrieb: > Zeig mal wie du die Punkte hinzu fügst. Ich denke da kann man noch > sehr viel optimieren.
1 | amplitudeLine = new Polyline; |
2 | ...
|
3 | amplitudeLine.Points.Add(new Point(x, y)); |
Was willst Du da groß optimieren? > Vor allem würde ich immer nur die letzten, sagen wir mal 100, Punkte an > die View übergeben, Aber dann werden alle älteren gelöscht/verdrängt, oder? Ich brauche die aber noch.
Speichere den Rest doch einfach in nem normalen Array ab und bei Bedarf rufst du sie daraus auf?!?
Bronco schrieb: > Aber dann werden alle älteren gelöscht/verdrängt, oder? Ich brauche die > aber noch. Du kannst ja im Viewmodel die Daten für die Polyline filtern und nur die letzten anzeigen. Je nach Größe des Controls auf dem die Polyline gezeichnet wird, würde ich das anpassen. Alles zusammen würde ich das ca. so machen:
1 | class ViewModel : INotifyPropertyChanged |
2 | {
|
3 | public event PropertyChangedEventHandler PropertyChanged; |
4 | |
5 | private const int NumberOfDrawingPoints = 100; |
6 | private readonly List<double> amplitudes; |
7 | |
8 | private PointCollection polylinePoints; |
9 | |
10 | |
11 | public ViewModel() |
12 | {
|
13 | amplitudes = new List<double>(); |
14 | PolylinePoints = new PointCollection(); |
15 | }
|
16 | |
17 | public PointCollection PolylinePoints |
18 | {
|
19 | get { return polylinePoints; } |
20 | set
|
21 | {
|
22 | polylinePoints = value; |
23 | NotifyOfPropertyChange(); |
24 | }
|
25 | }
|
26 | |
27 | public void AddMeasurement(double value) |
28 | {
|
29 | amplitudes.Add(value); |
30 | CalculatePoints(); |
31 | }
|
32 | |
33 | private void CalculatePoints() |
34 | {
|
35 | // take only last 100 points of amplitudes
|
36 | var drawingPoints = amplitudes.Skip(Math.Max(0, amplitudes.Count() - NumberOfDrawingPoints)).ToArray(); |
37 | var points = new PointCollection(); |
38 | for (int i = 0; i < drawingPoints.Count(); i++) |
39 | {
|
40 | // TODO: X scale
|
41 | points.Add(new Point(i, drawingPoints[i])); |
42 | }
|
43 | PolylinePoints = points; |
44 | }
|
45 | |
46 | protected virtual void NotifyOfPropertyChange([CallerMemberName] string propertyName = null) |
47 | {
|
48 | var handler = PropertyChanged; |
49 | if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); |
50 | }
|
51 | }
|
Denkbar wäre auch eine eigene Queue die INotifyPropertyChanged implementiert. Damit hast du zwar nur die letzten x Samples zu Anzeige verfügbar, musst dich jedoch nicht um irgendwelche ArrayGrenzen usw kümmern. Damit wird das Zeichnen zu reinem und lesbaren XAML Code.
Danke für die Tips, aber die Beschränkung der Anzahl von Punkten geht an meinem Ziel vorbei. Ich will Meßkurven über einen längeren Zeitraum aufzeichnen können. Natürlich gäbe es da Möglichkeiten, z.B. nur größere Änderungen anzuzeigen und die kleineren unter den Tisch fallen zulassen, aber im Grunde möchte ich einfach "malen können".
Das kann man auch, wenn man es richtig macht... Wieviel Messwerte hast pro Stunde und wie groß ist die "Zeichenfläche"? Ab wieviel Punkten fängt es an merklich zu bremsen?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.