Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs @ 14435

Last change on this file since 14435 was 14435, checked in by pfleck, 7 years ago

#2713 Added new ToolStripMenuItem to the chart for DataTableView and ScatterPlotView to open the configuration dialog.

File size: 22.7 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.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using System.Windows.Forms.DataVisualization.Charting;
28using HeuristicLab.Collections;
29using HeuristicLab.Common;
30using HeuristicLab.Core.Views;
31using HeuristicLab.MainForm;
32
33namespace HeuristicLab.Analysis.Views {
34  [View("ScatterPlot View")]
35  [Content(typeof(ScatterPlot), true)]
36  public partial class ScatterPlotView : NamedItemView, IConfigureableView {
37    protected List<Series> invisibleSeries;
38    protected Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow> pointsRowsTable;
39    private double xMin, xMax, yMin, yMax;
40
41    public new ScatterPlot Content {
42      get { return (ScatterPlot)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public ScatterPlotView() {
47      InitializeComponent();
48      pointsRowsTable = new Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow>();
49      invisibleSeries = new List<Series>();
50      chart.CustomizeAllChartAreas();
51      chart.ChartAreas[0].CursorX.Interval = 1;
52      chart.ContextMenuStrip.Items.Add(configureToolStripMenuItem);
53    }
54
55    #region Event Handler Registration
56    protected override void DeregisterContentEvents() {
57      foreach (ScatterPlotDataRow row in Content.Rows)
58        DeregisterScatterPlotDataRowEvents(row);
59      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
60      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
61      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
62      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
63      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
64      base.DeregisterContentEvents();
65    }
66    protected override void RegisterContentEvents() {
67      base.RegisterContentEvents();
68      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
69      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
70      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
71      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
72      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
73    }
74
75    protected virtual void RegisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
76      row.NameChanged += new EventHandler(Row_NameChanged);
77      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
78      pointsRowsTable.Add(row.Points, row);
79      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
80      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
81      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
82      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
83    }
84    protected virtual void DeregisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
85      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
86      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
87      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
88      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
89      pointsRowsTable.Remove(row.Points);
90      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
91      row.NameChanged -= new EventHandler(Row_NameChanged);
92    }
93    #endregion
94
95    protected override void OnContentChanged() {
96      base.OnContentChanged();
97      invisibleSeries.Clear();
98      chart.Titles[0].Text = string.Empty;
99      chart.ChartAreas[0].AxisX.Title = string.Empty;
100      chart.ChartAreas[0].AxisY.Title = string.Empty;
101      chart.Series.Clear();
102      if (Content != null) {
103        chart.Titles[0].Text = Content.Name;
104        AddScatterPlotDataRows(Content.Rows);
105        ConfigureChartArea(chart.ChartAreas[0]);
106        RecalculateMinMaxPointValues();
107        RecalculateAxesScale(chart.ChartAreas[0]);
108      }
109    }
110
111    protected override void SetEnabledStateOfControls() {
112      base.SetEnabledStateOfControls();
113      chart.Enabled = Content != null;
114    }
115
116    public void ShowConfiguration() {
117      if (Content != null) {
118        using (ScatterPlotVisualPropertiesDialog dialog = new ScatterPlotVisualPropertiesDialog(Content)) {
119          dialog.ShowDialog(this);
120        }
121      } else MessageBox.Show("Nothing to configure.");
122    }
123
124    protected virtual void AddScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
125      foreach (var row in rows) {
126        RegisterScatterPlotDataRowEvents(row);
127        Series series = new Series(row.Name);
128        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
129        else series.LegendText = row.Name;
130        ConfigureSeries(series, row);
131        FillSeriesWithRowValues(series, row);
132        chart.Series.Add(series);
133      }
134      ConfigureChartArea(chart.ChartAreas[0]);
135      RecalculateMinMaxPointValues();
136      RecalculateAxesScale(chart.ChartAreas[0]);
137      UpdateYCursorInterval();
138    }
139
140    protected virtual void RemoveScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
141      foreach (var row in rows) {
142        DeregisterScatterPlotDataRowEvents(row);
143        Series series = chart.Series[row.Name];
144        chart.Series.Remove(series);
145        if (invisibleSeries.Contains(series))
146          invisibleSeries.Remove(series);
147      }
148      RecalculateMinMaxPointValues();
149      RecalculateAxesScale(chart.ChartAreas[0]);
150    }
151
152    private void ConfigureSeries(Series series, ScatterPlotDataRow row) {
153      series.BorderWidth = 1;
154      series.BorderDashStyle = ChartDashStyle.Solid;
155      series.BorderColor = Color.Empty;
156
157      if (row.VisualProperties.Color != Color.Empty)
158        series.Color = row.VisualProperties.Color;
159      else series.Color = Color.Empty;
160      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
161      series.ChartType = SeriesChartType.FastPoint;
162      series.MarkerSize = row.VisualProperties.PointSize;
163      series.MarkerStyle = ConvertPointStyle(row.VisualProperties.PointStyle);
164      series.XAxisType = AxisType.Primary;
165      series.YAxisType = AxisType.Primary;
166
167      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
168      else series.LegendText = row.Name;
169
170      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
171                      ? "X"
172                      : Content.VisualProperties.XAxisTitle;
173      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
174                            ? "Y"
175                            : Content.VisualProperties.YAxisTitle;
176      series.ToolTip =
177        series.LegendText + Environment.NewLine +
178        xAxisTitle + " = " + "#VALX," + Environment.NewLine +
179        yAxisTitle + " = " + "#VAL";
180    }
181
182    private void ConfigureChartArea(ChartArea area) {
183      if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;
184      if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;
185      chart.Titles[0].Text = Content.VisualProperties.Title;
186
187      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
188      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
189      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
190      area.AxisX.MajorGrid.Enabled = Content.VisualProperties.XAxisGrid;
191
192      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
193      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
194      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
195      area.AxisY.MajorGrid.Enabled = Content.VisualProperties.YAxisGrid;
196    }
197
198    private void RecalculateAxesScale(ChartArea area) {
199      area.AxisX.Minimum = CalculateMinBound(xMin);
200      area.AxisX.Maximum = CalculateMaxBound(xMax);
201      if (area.AxisX.Minimum == area.AxisX.Maximum) {
202        area.AxisX.Minimum = xMin - 0.5;
203        area.AxisX.Maximum = xMax + 0.5;
204      }
205      area.AxisY.Minimum = CalculateMinBound(yMin);
206      area.AxisY.Maximum = CalculateMaxBound(yMax);
207      if (area.AxisY.Minimum == area.AxisY.Maximum) {
208        area.AxisY.Minimum = yMin - 0.5;
209        area.AxisY.Maximum = yMax + 0.5;
210      }
211      if (xMax - xMin > 0) area.CursorX.Interval = Math.Pow(10, Math.Floor(Math.Log10(area.AxisX.Maximum - area.AxisX.Minimum) - 3));
212      else area.CursorX.Interval = 1;
213      area.AxisX.IsMarginVisible = false;
214
215      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
216      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
217      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
218      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
219    }
220
221    private static double CalculateMinBound(double min) {
222      if (min == 0) return 0;
223      var scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(min))));
224      return scale * (Math.Floor(min / scale));
225    }
226
227    private static double CalculateMaxBound(double max) {
228      if (max == 0) return 0;
229      var scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(max))));
230      return scale * (Math.Ceiling(max / scale));
231    }
232
233    protected virtual void UpdateYCursorInterval() {
234      double interestingValuesRange = (
235        from series in chart.Series
236        where series.Enabled
237        let values = (from point in series.Points
238                      where !point.IsEmpty
239                      select point.YValues[0]).DefaultIfEmpty(1.0)
240        let range = values.Max() - values.Min()
241        where range > 0.0
242        select range
243        ).DefaultIfEmpty(1.0).Min();
244
245      double digits = (int)Math.Log10(interestingValuesRange) - 3;
246      double yZoomInterval = Math.Pow(10, digits);
247      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
248    }
249
250    #region Event Handlers
251    #region Content Event Handlers
252    protected override void Content_NameChanged(object sender, EventArgs e) {
253      if (InvokeRequired)
254        Invoke(new EventHandler(Content_NameChanged), sender, e);
255      else {
256        chart.Titles[0].Text = Content.Name;
257        base.Content_NameChanged(sender, e);
258      }
259    }
260    private void Content_VisualPropertiesChanged(object sender, EventArgs e) {
261      if (InvokeRequired)
262        Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);
263      else {
264        ConfigureChartArea(chart.ChartAreas[0]);
265        RecalculateAxesScale(chart.ChartAreas[0]); // axes min/max could have changed
266      }
267    }
268    #endregion
269    #region Rows Event Handlers
270    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
271      if (InvokeRequired)
272        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded), sender, e);
273      else {
274        AddScatterPlotDataRows(e.Items);
275      }
276    }
277    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
278      if (InvokeRequired)
279        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved), sender, e);
280      else {
281        RemoveScatterPlotDataRows(e.Items);
282      }
283    }
284    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
285      if (InvokeRequired)
286        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced), sender, e);
287      else {
288        RemoveScatterPlotDataRows(e.OldItems);
289        AddScatterPlotDataRows(e.Items);
290      }
291    }
292    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
293      if (InvokeRequired)
294        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset), sender, e);
295      else {
296        RemoveScatterPlotDataRows(e.OldItems);
297        AddScatterPlotDataRows(e.Items);
298      }
299    }
300    #endregion
301    #region Row Event Handlers
302    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
303      if (InvokeRequired)
304        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
305      else {
306        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
307        Series series = chart.Series[row.Name];
308        series.Points.Clear();
309        ConfigureSeries(series, row);
310        FillSeriesWithRowValues(series, row);
311        RecalculateMinMaxPointValues();
312        RecalculateAxesScale(chart.ChartAreas[0]);
313      }
314    }
315    private void Row_NameChanged(object sender, EventArgs e) {
316      if (InvokeRequired)
317        Invoke(new EventHandler(Row_NameChanged), sender, e);
318      else {
319        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
320        chart.Series[row.Name].Name = row.Name;
321      }
322    }
323    #endregion
324    #region Points Event Handlers
325    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
326      if (InvokeRequired)
327        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded), sender, e);
328      else {
329        ScatterPlotDataRow row = null;
330        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
331        if (row != null) {
332          Series rowSeries = chart.Series[row.Name];
333          if (!invisibleSeries.Contains(rowSeries)) {
334            rowSeries.Points.Clear();
335            FillSeriesWithRowValues(rowSeries, row);
336            RecalculateMinMaxPointValues();
337            RecalculateAxesScale(chart.ChartAreas[0]);
338            UpdateYCursorInterval();
339          }
340        }
341      }
342    }
343    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
344      if (InvokeRequired)
345        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved), sender, e);
346      else {
347        ScatterPlotDataRow row = null;
348        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
349        if (row != null) {
350          Series rowSeries = chart.Series[row.Name];
351          if (!invisibleSeries.Contains(rowSeries)) {
352            rowSeries.Points.Clear();
353            FillSeriesWithRowValues(rowSeries, row);
354            RecalculateMinMaxPointValues();
355            RecalculateAxesScale(chart.ChartAreas[0]);
356            UpdateYCursorInterval();
357          }
358        }
359      }
360    }
361    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
362      if (InvokeRequired)
363        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced), sender, e);
364      else {
365        ScatterPlotDataRow row = null;
366        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
367        if (row != null) {
368          Series rowSeries = chart.Series[row.Name];
369          if (!invisibleSeries.Contains(rowSeries)) {
370            rowSeries.Points.Clear();
371            FillSeriesWithRowValues(rowSeries, row);
372            RecalculateMinMaxPointValues();
373            RecalculateAxesScale(chart.ChartAreas[0]);
374            UpdateYCursorInterval();
375          }
376        }
377      }
378    }
379    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
380      if (InvokeRequired)
381        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset), sender, e);
382      else {
383        ScatterPlotDataRow row = null;
384        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
385        if (row != null) {
386          Series rowSeries = chart.Series[row.Name];
387          if (!invisibleSeries.Contains(rowSeries)) {
388            rowSeries.Points.Clear();
389            FillSeriesWithRowValues(rowSeries, row);
390            RecalculateMinMaxPointValues();
391            RecalculateAxesScale(chart.ChartAreas[0]);
392            UpdateYCursorInterval();
393          }
394        }
395      }
396    }
397    #endregion
398    private void configureToolStripMenuItem_Click(object sender, System.EventArgs e) {
399      ShowConfiguration();
400    }
401    #endregion
402
403    #region Chart Event Handlers
404    private void chart_MouseDown(object sender, MouseEventArgs e) {
405      HitTestResult result = chart.HitTest(e.X, e.Y);
406      if (result.ChartElementType == ChartElementType.LegendItem) {
407        ToggleSeriesVisible(result.Series);
408      }
409    }
410    private void chart_MouseMove(object sender, MouseEventArgs e) {
411      HitTestResult result = chart.HitTest(e.X, e.Y);
412      if (result.ChartElementType == ChartElementType.LegendItem)
413        this.Cursor = Cursors.Hand;
414      else
415        this.Cursor = Cursors.Default;
416    }
417    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
418      foreach (LegendItem legendItem in e.LegendItems) {
419        var series = chart.Series[legendItem.SeriesName];
420        if (series != null) {
421          bool seriesIsInvisible = invisibleSeries.Contains(series);
422          foreach (LegendCell cell in legendItem.Cells) {
423            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
424          }
425        }
426      }
427    }
428    #endregion
429
430    private void ToggleSeriesVisible(Series series) {
431      if (!invisibleSeries.Contains(series)) {
432        series.Points.Clear();
433        invisibleSeries.Add(series);
434        RecalculateMinMaxPointValues();
435      } else {
436        invisibleSeries.Remove(series);
437        if (Content != null) {
438
439          var row = (from r in Content.Rows
440                     where r.Name == series.Name
441                     select r).Single();
442          FillSeriesWithRowValues(series, row);
443          RecalculateMinMaxPointValues();
444          this.chart.Legends[series.Legend].ForeColor = Color.Black;
445          RecalculateAxesScale(chart.ChartAreas[0]);
446          UpdateYCursorInterval();
447        }
448      }
449    }
450
451    private void RecalculateMinMaxPointValues() {
452      yMin = xMin = double.MaxValue;
453      yMax = xMax = double.MinValue;
454      foreach (var s in chart.Series.Where(x => x.Enabled)) {
455        foreach (var p in s.Points) {
456          double x = p.XValue, y = p.YValues[0];
457          if (xMin > x) xMin = x;
458          if (xMax < x) xMax = x;
459          if (yMin > y) yMin = y;
460          if (yMax < y) yMax = y;
461        }
462      }
463    }
464
465    private void FillSeriesWithRowValues(Series series, ScatterPlotDataRow row) {
466      for (int i = 0; i < row.Points.Count; i++) {
467        var value = row.Points[i];
468        DataPoint point = new DataPoint();
469        if (IsInvalidValue(value.X) || IsInvalidValue(value.Y))
470          point.IsEmpty = true;
471        else {
472          point.XValue = value.X;
473          point.YValues = new double[] { value.Y };
474        }
475        series.Points.Add(point);
476      }
477    }
478
479    #region Helpers
480    private MarkerStyle ConvertPointStyle(ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle pointStyle) {
481      switch (pointStyle) {
482        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle:
483          return MarkerStyle.Circle;
484        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Cross:
485          return MarkerStyle.Cross;
486        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Diamond:
487          return MarkerStyle.Diamond;
488        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square:
489          return MarkerStyle.Square;
490        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star4:
491          return MarkerStyle.Star4;
492        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star5:
493          return MarkerStyle.Star5;
494        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star6:
495          return MarkerStyle.Star6;
496        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star10:
497          return MarkerStyle.Star10;
498        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Triangle:
499          return MarkerStyle.Triangle;
500        default:
501          return MarkerStyle.None;
502      }
503    }
504
505    protected static bool IsInvalidValue(double x) {
506      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
507    }
508    #endregion
509  }
510}
Note: See TracBrowser for help on using the repository browser.