Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/14/12 18:58:15 (12 years ago)
Author:
gkronber
Message:

#1847 merged r8205:8635 from trunk into branch

Location:
branches/GP-MoveOperators
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/GP-MoveOperators

  • branches/GP-MoveOperators/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs

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