Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs @ 17105

Last change on this file since 17105 was 17105, checked in by mkommend, 5 years ago

#2520: Merged 16584, 16585,16594,16595, 16625, 16658, 16659, 16672, 16707, 16729, 16792, 16796, 16797, 16799, 16819, 16906, 16907, 16908, 16933, 16945, 16992, 16994, 16995, 16996, 16997, 17014, 17015, 17017, 17020, 17021, 17022, 17023, 17024, 17029, 17086, 17087, 17088, 17089 into stable.

File size: 13.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HEAL.Attic;
32
33namespace HeuristicLab.Analysis {
34  [Item("ScatterPlot", "A scatter plot of 2D data")]
35  [StorableType("9706C8CB-4118-400B-9AE2-A4F00D7580B5")]
36  public class ScatterPlot : NamedItem, IStringConvertibleMatrix {
37    public static new Image StaticItemImage {
38      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
39    }
40
41    private ScatterPlotVisualProperties visualProperties;
42    public ScatterPlotVisualProperties VisualProperties {
43      get { return visualProperties; }
44      set {
45        if (visualProperties != value) {
46          if (value == null) throw new ArgumentNullException("VisualProperties");
47          if (visualProperties != null) visualProperties.PropertyChanged -= new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
48          visualProperties = value;
49          visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
50          OnVisualPropertiesChanged();
51        }
52      }
53    }
54
55    private NamedItemCollection<ScatterPlotDataRow> rows;
56    public NamedItemCollection<ScatterPlotDataRow> Rows {
57      get { return rows; }
58      private set {
59        if (rows != null) throw new InvalidOperationException("Rows already set");
60        rows = value;
61        if (rows != null) RegisterRowsEvents();
62      }
63    }
64
65    #region Persistence Properties
66    [Storable(Name = "VisualProperties")]
67    private ScatterPlotVisualProperties StorableVisualProperties {
68      get { return visualProperties; }
69      set {
70        visualProperties = value;
71        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
72      }
73    }
74    [Storable(Name = "Rows")]
75    private IEnumerable<ScatterPlotDataRow> StorableRows {
76      get { return rows; }
77      set { Rows = new NamedItemCollection<ScatterPlotDataRow>(value); }
78    }
79    #endregion
80
81    [StorableConstructor]
82    protected ScatterPlot(StorableConstructorFlag _) : base(_) { }
83    protected ScatterPlot(ScatterPlot original, Cloner cloner)
84      : base(original, cloner) {
85      VisualProperties = cloner.Clone(original.visualProperties);
86      Rows = cloner.Clone(original.rows);
87    }
88    public ScatterPlot()
89      : base() {
90      this.Name = ItemName;
91      this.Description = ItemDescription;
92      VisualProperties = new ScatterPlotVisualProperties();
93      Rows = new NamedItemCollection<ScatterPlotDataRow>();
94    }
95    public ScatterPlot(string name, string description)
96      : base(name, description) {
97      VisualProperties = new ScatterPlotVisualProperties(name);
98      Rows = new NamedItemCollection<ScatterPlotDataRow>();
99    }
100    public ScatterPlot(string name, string description, ScatterPlotVisualProperties visualProperties)
101      : base(name, description) {
102      VisualProperties = visualProperties;
103      Rows = new NamedItemCollection<ScatterPlotDataRow>();
104    }
105
106    // BackwardsCompatibility3.3
107    #region Backwards compatible code, remove with 3.4
108    private ObservableList<PointF> points;
109    [Storable(OldName = "points")]
110    private ObservableList<PointF> StorablePoints {
111      set { points = value; }
112    }
113    private string xAxisName;
114    [Storable(OldName = "xAxisName")]
115    private string StorableXAxisName {
116      set { xAxisName = value; }
117    }
118    private string yAxisName;
119    [Storable(OldName = "yAxisName")]
120    private string StorableYAxisName {
121      set { yAxisName = value; }
122    }
123    [StorableHook(HookType.AfterDeserialization)]
124    private void AfterDeserialization() {
125      if (VisualProperties == null) VisualProperties = new ScatterPlotVisualProperties(name);
126      if (string.IsNullOrEmpty(VisualProperties.XAxisTitle) && !string.IsNullOrEmpty(xAxisName)) VisualProperties.XAxisTitle = xAxisName;
127      if (string.IsNullOrEmpty(VisualProperties.YAxisTitle) && !string.IsNullOrEmpty(yAxisName)) VisualProperties.YAxisTitle = yAxisName;
128      if (rows == null) Rows = new NamedItemCollection<ScatterPlotDataRow>();
129      if ((Rows.Count == 0) && (points != null)) Rows.Add(new ScatterPlotDataRow(name, null, points.Select(p => new Point2D<double>(p.X, p.Y))));
130      if (string.IsNullOrEmpty(this.name)) this.name = ItemName;
131      if (string.IsNullOrEmpty(this.description)) this.description = ItemDescription;
132    }
133    #endregion
134
135    public override IDeepCloneable Clone(Cloner cloner) {
136      return new ScatterPlot(this, cloner);
137    }
138
139    public event EventHandler VisualPropertiesChanged;
140    protected virtual void OnVisualPropertiesChanged() {
141      EventHandler handler = VisualPropertiesChanged;
142      if (handler != null) handler(this, EventArgs.Empty);
143    }
144
145    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
146      OnVisualPropertiesChanged();
147    }
148
149    protected virtual void RegisterRowsEvents() {
150      rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsAdded);
151      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsRemoved);
152      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsReplaced);
153      rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_CollectionReset);
154    }
155    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
156      foreach (ScatterPlotDataRow row in e.Items)
157        this.RegisterRowEvents(row);
158
159      this.OnColumnsChanged();
160      this.OnColumnNamesChanged();
161      this.OnReset();
162    }
163    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
164      foreach (ScatterPlotDataRow row in e.Items)
165        this.DeregisterRowEvents(row);
166
167      this.OnColumnsChanged();
168      this.OnColumnNamesChanged();
169      this.OnReset();
170    }
171    private void rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
172      foreach (ScatterPlotDataRow row in e.OldItems)
173        this.DeregisterRowEvents(row);
174      foreach (ScatterPlotDataRow row in e.Items)
175        this.RegisterRowEvents(row);
176
177      this.OnColumnsChanged();
178      this.OnColumnNamesChanged();
179      this.OnReset();
180    }
181    private void rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
182      foreach (ScatterPlotDataRow row in e.OldItems)
183        this.DeregisterRowEvents(row);
184      foreach (ScatterPlotDataRow row in e.Items)
185        this.RegisterRowEvents(row);
186
187      if (e.OldItems.Count() != e.Items.Count())
188        this.OnColumnsChanged();
189      this.OnColumnNamesChanged();
190      this.OnReset();
191    }
192
193    protected virtual void RegisterRowEvents(ScatterPlotDataRow row) {
194      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
195      row.Points.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
196      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
197      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
198      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
199    }
200    protected virtual void DeregisterRowEvents(ScatterPlotDataRow row) {
201      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
202      row.Points.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
203      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
204      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
205      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
206    }
207
208    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
209      this.OnReset();
210    }
211    private void Points_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
212      this.OnReset();
213    }
214    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
215      this.OnReset();
216    }
217    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
218      this.OnReset();
219    }
220    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
221      this.OnReset();
222    }
223
224    #region IStringConvertibleMatrix Members
225    int IStringConvertibleMatrix.Rows {
226      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Points.Count); }
227      set { throw new NotSupportedException(); }
228    }
229    int IStringConvertibleMatrix.Columns {
230      get { return rows.Count; }
231      set { throw new NotSupportedException(); }
232    }
233    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
234      get { return rows.Select(r => r.Name); }
235      set { throw new NotSupportedException(); }
236    }
237    IEnumerable<string> IStringConvertibleMatrix.RowNames {
238      get { return Enumerable.Empty<string>(); }
239      set { throw new NotSupportedException(); }
240    }
241
242    bool IStringConvertibleMatrix.SortableView {
243      get { return true; }
244      set { throw new NotSupportedException(); }
245    }
246    bool IStringConvertibleMatrix.ReadOnly {
247      get { return true; }
248    }
249
250    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
251      if (columnIndex < rows.Count) {
252        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
253        if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Points.Count)
254          return string.Format("{0};{1}", rows[columnName].Points[rowIndex].X, rows[columnName].Points[rowIndex].Y);
255      }
256      return string.Empty;
257    }
258
259    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
260      throw new NotSupportedException();
261    }
262    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
263      throw new NotSupportedException();
264    }
265
266    public event EventHandler<EventArgs<int, int>> ItemChanged;
267    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
268      var handler = ItemChanged;
269      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
270      OnToStringChanged();
271    }
272    public event EventHandler Reset;
273    protected virtual void OnReset() {
274      var handler = Reset;
275      if (handler != null) handler(this, EventArgs.Empty);
276    }
277    public event EventHandler ColumnsChanged;
278    protected virtual void OnColumnsChanged() {
279      var handler = ColumnsChanged;
280      if (handler != null) handler(this, EventArgs.Empty);
281    }
282    public event EventHandler RowsChanged;
283    protected virtual void OnRowsChanged() {
284      var handler = RowsChanged;
285      if (handler != null) handler(this, EventArgs.Empty);
286    }
287    public event EventHandler ColumnNamesChanged;
288    protected virtual void OnColumnNamesChanged() {
289      var handler = ColumnNamesChanged;
290      if (handler != null) handler(this, EventArgs.Empty);
291    }
292    public event EventHandler RowNamesChanged;
293    protected virtual void OnRowNamesChanged() {
294      var handler = RowNamesChanged;
295      if (handler != null) handler(this, EventArgs.Empty);
296    }
297    public event EventHandler SortableViewChanged;
298    protected virtual void OnSortableViewChanged() {
299      var handler = SortableViewChanged;
300      if (handler != null) handler(this, EventArgs.Empty);
301    }
302    #endregion
303  }
304}
Note: See TracBrowser for help on using the repository browser.