Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceReintegration/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs @ 15428

Last change on this file since 15428 was 15018, checked in by gkronber, 8 years ago

#2520 introduced StorableConstructorFlag type for StorableConstructors

File size: 13.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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 HeuristicLab.Persistence;
32
33namespace HeuristicLab.Analysis {
34  [Item("ScatterPlot", "A scatter plot of 2D data")]
35  [StorableType("064b03cc-5364-4923-851c-301d65a78196")]
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 deserializing) : base(deserializing) { }
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(Name = "points", AllowOneWay = true)]
110    private ObservableList<PointF> StorablePoints {
111      set { points = value; }
112    }
113    private string xAxisName;
114    [Storable(Name = "xAxisName", AllowOneWay = true)]
115    private string StorableXAxisName {
116      set { xAxisName = value; }
117    }
118    private string yAxisName;
119    [Storable(Name = "yAxisName", AllowOneWay = true)]
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.