Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs @ 15344

Last change on this file since 15344 was 9363, checked in by spimming, 12 years ago

#1888:

  • Merged revisions from trunk
File size: 12.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Analysis {
34  [Item("ScatterPlot", "A scatter plot of 2D data")]
35  [StorableClass]
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(bool 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      VisualProperties = new ScatterPlotVisualProperties();
91      Rows = new NamedItemCollection<ScatterPlotDataRow>();
92    }
93    public ScatterPlot(string name, string description)
94      : base(name, description) {
95      VisualProperties = new ScatterPlotVisualProperties(name);
96      Rows = new NamedItemCollection<ScatterPlotDataRow>();
97    }
98    public ScatterPlot(string name, string description, ScatterPlotVisualProperties visualProperties)
99      : base(name, description) {
100      VisualProperties = visualProperties;
101      Rows = new NamedItemCollection<ScatterPlotDataRow>();
102    }
103
104    // BackwardsCompatibility3.3
105    #region Backwards compatible code, remove with 3.4
106    private ObservableList<PointF> points;
107    [Storable(Name = "points", AllowOneWay = true)]
108    private ObservableList<PointF> StorablePoints {
109      set { points = value; }
110    }
111    private string xAxisName;
112    [Storable(Name = "xAxisName", AllowOneWay = true)]
113    private string StorableXAxisName {
114      set { xAxisName = value; }
115    }
116    private string yAxisName;
117    [Storable(Name = "yAxisName", AllowOneWay = true)]
118    private string StorableYAxisName {
119      set { yAxisName = value; }
120    }
121    [StorableHook(HookType.AfterDeserialization)]
122    private void AfterDeserialization() {
123      if (VisualProperties == null) VisualProperties = new ScatterPlotVisualProperties(name);
124      if (string.IsNullOrEmpty(VisualProperties.XAxisTitle) && !string.IsNullOrEmpty(xAxisName)) VisualProperties.XAxisTitle = xAxisName;
125      if (string.IsNullOrEmpty(VisualProperties.YAxisTitle) && !string.IsNullOrEmpty(yAxisName)) VisualProperties.YAxisTitle = yAxisName;
126      if (rows == null) Rows = new NamedItemCollection<ScatterPlotDataRow>();
127      if ((Rows.Count == 0) && (points != null)) Rows.Add(new ScatterPlotDataRow(name, null, points.Select(p => new Point2D<double>(p.X, p.Y))));
128    }
129    #endregion
130
131    public override IDeepCloneable Clone(Cloner cloner) {
132      return new ScatterPlot(this, cloner);
133    }
134
135    public event EventHandler VisualPropertiesChanged;
136    protected virtual void OnVisualPropertiesChanged() {
137      EventHandler handler = VisualPropertiesChanged;
138      if (handler != null) handler(this, EventArgs.Empty);
139    }
140
141    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
142      OnVisualPropertiesChanged();
143    }
144
145    protected virtual void RegisterRowsEvents() {
146      rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsAdded);
147      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsRemoved);
148      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsReplaced);
149      rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_CollectionReset);
150    }
151    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
152      foreach (ScatterPlotDataRow row in e.Items)
153        this.RegisterRowEvents(row);
154
155      this.OnColumnsChanged();
156      this.OnColumnNamesChanged();
157      this.OnReset();
158    }
159    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
160      foreach (ScatterPlotDataRow row in e.Items)
161        this.DeregisterRowEvents(row);
162
163      this.OnColumnsChanged();
164      this.OnColumnNamesChanged();
165      this.OnReset();
166    }
167    private void rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
168      foreach (ScatterPlotDataRow row in e.OldItems)
169        this.DeregisterRowEvents(row);
170      foreach (ScatterPlotDataRow row in e.Items)
171        this.RegisterRowEvents(row);
172
173      this.OnColumnsChanged();
174      this.OnColumnNamesChanged();
175      this.OnReset();
176    }
177    private void rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
178      foreach (ScatterPlotDataRow row in e.OldItems)
179        this.DeregisterRowEvents(row);
180      foreach (ScatterPlotDataRow row in e.Items)
181        this.RegisterRowEvents(row);
182
183      if (e.OldItems.Count() != e.Items.Count())
184        this.OnColumnsChanged();
185      this.OnColumnNamesChanged();
186      this.OnReset();
187    }
188
189    protected virtual void RegisterRowEvents(ScatterPlotDataRow row) {
190      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
191      row.Points.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
192      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
193      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
194      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
195    }
196    protected virtual void DeregisterRowEvents(ScatterPlotDataRow row) {
197      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
198      row.Points.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
199      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
200      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
201      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
202    }
203
204    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
205      this.OnReset();
206    }
207    private void Points_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
208      this.OnReset();
209    }
210    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
211      this.OnReset();
212    }
213    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
214      this.OnReset();
215    }
216    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
217      this.OnReset();
218    }
219
220    #region IStringConvertibleMatrix Members
221    int IStringConvertibleMatrix.Rows {
222      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Points.Count); }
223      set { throw new NotSupportedException(); }
224    }
225    int IStringConvertibleMatrix.Columns {
226      get { return rows.Count; }
227      set { throw new NotSupportedException(); }
228    }
229    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
230      get { return rows.Select(r => r.Name); }
231      set { throw new NotSupportedException(); }
232    }
233    IEnumerable<string> IStringConvertibleMatrix.RowNames {
234      get { return Enumerable.Empty<string>(); }
235      set { throw new NotSupportedException(); }
236    }
237
238    bool IStringConvertibleMatrix.SortableView {
239      get { return true; }
240      set { throw new NotSupportedException(); }
241    }
242    bool IStringConvertibleMatrix.ReadOnly {
243      get { return true; }
244    }
245
246    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
247      if (columnIndex < rows.Count) {
248        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
249        if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Points.Count)
250          return string.Format("{0};{1}", rows[columnName].Points[rowIndex].X, rows[columnName].Points[rowIndex].Y);
251      }
252      return string.Empty;
253    }
254
255    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
256      throw new NotSupportedException();
257    }
258    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
259      throw new NotSupportedException();
260    }
261
262    public event EventHandler<EventArgs<int, int>> ItemChanged;
263    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
264      var handler = ItemChanged;
265      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
266      OnToStringChanged();
267    }
268    public event EventHandler Reset;
269    protected virtual void OnReset() {
270      var handler = Reset;
271      if (handler != null) handler(this, EventArgs.Empty);
272    }
273    public event EventHandler ColumnsChanged;
274    protected virtual void OnColumnsChanged() {
275      var handler = ColumnsChanged;
276      if (handler != null) handler(this, EventArgs.Empty);
277    }
278    public event EventHandler RowsChanged;
279    protected virtual void OnRowsChanged() {
280      var handler = RowsChanged;
281      if (handler != null) handler(this, EventArgs.Empty);
282    }
283    public event EventHandler ColumnNamesChanged;
284    protected virtual void OnColumnNamesChanged() {
285      var handler = ColumnNamesChanged;
286      if (handler != null) handler(this, EventArgs.Empty);
287    }
288    public event EventHandler RowNamesChanged;
289    protected virtual void OnRowNamesChanged() {
290      var handler = RowNamesChanged;
291      if (handler != null) handler(this, EventArgs.Empty);
292    }
293    public event EventHandler SortableViewChanged;
294    protected virtual void OnSortableViewChanged() {
295      var handler = SortableViewChanged;
296      if (handler != null) handler(this, EventArgs.Empty);
297    }
298    #endregion
299  }
300}
Note: See TracBrowser for help on using the repository browser.