Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2713 Hide the chart-title if the title is empty (to avoid unnecessary empty space)

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