Free cookie consent management tool by TermsFeed Policy Generator

Changeset 8280 for trunk


Ignore:
Timestamp:
07/11/12 00:25:26 (12 years ago)
Author:
swagner
Message:

Added enhanced version of ScatterPlot (#1892)

Location:
trunk/sources
Files:
7 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.cs

    r7259 r8280  
    2626
    2727namespace HeuristicLab.Analysis.Views {
    28   [View("DataRow Visual Properties")]
     28  [View("DataTable Visual Properties")]
    2929  public partial class DataTableVisualPropertiesControl : UserControl {
    3030    protected bool SuppressEvents { get; set; }
  • trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj

    r7978 r8280  
    122122      <DependentUpon>ScatterPlotView.cs</DependentUpon>
    123123    </Compile>
     124    <Compile Include="ScatterPlotHistoryView.cs">
     125      <SubType>UserControl</SubType>
     126    </Compile>
     127    <Compile Include="ScatterPlotHistoryView.Designer.cs">
     128      <DependentUpon>ScatterPlotHistoryView.cs</DependentUpon>
     129    </Compile>
    124130    <None Include="Plugin.cs.frame" />
    125131    <Compile Include="AlleleFrequencyCollectionView.cs">
  • trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.Designer.cs

    r7829 r8280  
    1 #region License Information
     1#region License Information
    22/* HeuristicLab
    33 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    2222namespace HeuristicLab.Analysis.Views {
    2323  partial class ScatterPlotView {
    24     /// <summary>
     24    /// <summary> 
    2525    /// Required designer variable.
    2626    /// </summary>
    2727    private System.ComponentModel.IContainer components = null;
    2828
    29     /// <summary>
     29    /// <summary> 
    3030    /// Clean up any resources being used.
    3131    /// </summary>
    3232    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    3333    protected override void Dispose(bool disposing) {
    34       if (disposing && (components != null)) {
    35         components.Dispose();
     34      if (disposing) {
     35        if (components != null) components.Dispose();
    3636      }
    3737      base.Dispose(disposing);
    3838    }
    3939
    40     #region Windows Form Designer generated code
     40    #region Component Designer generated code
    4141
    42     /// <summary>
    43     /// Required method for Designer support - do not modify
     42    /// <summary> 
     43    /// Required method for Designer support - do not modify 
    4444    /// the contents of this method with the code editor.
    4545    /// </summary>
    4646    private void InitializeComponent() {
    4747      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
     48      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
    4849      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
    4950      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
     
    5758      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
    5859      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
    59       this.nameTextBox.Size = new System.Drawing.Size(596, 20);
     60      this.nameTextBox.Location = new System.Drawing.Point(55, 0);
     61      this.nameTextBox.Size = new System.Drawing.Size(279, 20);
     62      //
     63      // infoLabel
     64      //
     65      this.infoLabel.Location = new System.Drawing.Point(340, 3);
    6066      //
    6167      // chart
    6268      //
    63       this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
    64             | System.Windows.Forms.AnchorStyles.Left)
    65             | System.Windows.Forms.AnchorStyles.Right)));
    66       chartArea1.Name = "ChartArea1";
     69      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
     70                  | System.Windows.Forms.AnchorStyles.Left)
     71                  | System.Windows.Forms.AnchorStyles.Right)));
     72      this.chart.BorderlineColor = System.Drawing.Color.Black;
     73      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
     74      chartArea1.AxisX.Minimum = 0D;
     75      chartArea1.CursorX.IsUserEnabled = true;
     76      chartArea1.CursorX.IsUserSelectionEnabled = true;
     77      chartArea1.CursorY.IsUserEnabled = true;
     78      chartArea1.CursorY.IsUserSelectionEnabled = true;
     79      chartArea1.Name = "Default";
    6780      this.chart.ChartAreas.Add(chartArea1);
     81      legend1.Alignment = System.Drawing.StringAlignment.Center;
     82      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
     83      legend1.Name = "Default";
     84      this.chart.Legends.Add(legend1);
    6885      this.chart.Location = new System.Drawing.Point(0, 26);
    6986      this.chart.Name = "chart";
    70       series1.ChartArea = "ChartArea1";
    71       series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastPoint;
    72       series1.EmptyPointStyle.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.LeftRight;
    73       series1.MarkerSize = 3;
    74       series1.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
    75       series1.Name = "Series1";
     87      series1.ChartArea = "Default";
     88      series1.Legend = "Default";
     89      series1.Name = "Default";
    7690      this.chart.Series.Add(series1);
    77       this.chart.Size = new System.Drawing.Size(668, 378);
    78       this.chart.TabIndex = 5;
    79       title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
    80       title1.Name = "Title1";
    81       title1.Text = "Scatter Plot";
     91      this.chart.Size = new System.Drawing.Size(359, 248);
     92      this.chart.TabIndex = 3;
     93      this.chart.Text = "chart";
     94      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
     95      title1.Name = "Default";
     96      title1.Text = "Title";
    8297      this.chart.Titles.Add(title1);
     98      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
     99      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
     100      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
    83101      //
    84102      // ScatterPlotView
    85103      //
    86       this.AllowDrop = true;
    87104      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
     105      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
    88106      this.Controls.Add(this.chart);
    89107      this.Name = "ScatterPlotView";
    90       this.Size = new System.Drawing.Size(668, 404);
     108      this.Size = new System.Drawing.Size(359, 274);
    91109      this.Controls.SetChildIndex(this.infoLabel, 0);
    92110      this.Controls.SetChildIndex(this.chart, 0);
     
    102120    #endregion
    103121
    104     private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
     122    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
     123
    105124  }
    106125}
  • trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs

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

    r7259 r8280  
    5959    public NamedItemCollection<DataRow> Rows {
    6060      get { return rows; }
     61      private set {
     62        if (rows != null) throw new InvalidOperationException("Rows already set");
     63        rows = value;
     64        if (rows != null) RegisterRowsEvents();
     65      }
    6166    }
    6267
     
    7378    private IEnumerable<DataRow> StorableRows {
    7479      get { return rows; }
    75       set { rows = new NamedItemCollection<DataRow>(value); }
     80      set { Rows = new NamedItemCollection<DataRow>(value); }
    7681    }
    7782    #endregion
     
    8186    protected DataTable(DataTable original, Cloner cloner)
    8287      : base(original, cloner) {
    83       this.VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
    84       this.rows = cloner.Clone(original.rows);
    85       this.RegisterRowsEvents();
     88      VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
     89      Rows = cloner.Clone(original.rows);
    8690    }
    8791    public DataTable()
    8892      : base() {
    8993      VisualProperties = new DataTableVisualProperties();
    90       rows = new NamedItemCollection<DataRow>();
    91       this.RegisterRowsEvents();
     94      Rows = new NamedItemCollection<DataRow>();
    9295    }
    9396    public DataTable(string name)
    9497      : base(name) {
    9598      VisualProperties = new DataTableVisualProperties(name);
    96       rows = new NamedItemCollection<DataRow>();
    97       this.RegisterRowsEvents();
     99      Rows = new NamedItemCollection<DataRow>();
    98100    }
    99101    public DataTable(string name, string description)
    100102      : base(name, description) {
    101103      VisualProperties = new DataTableVisualProperties(name);
    102       rows = new NamedItemCollection<DataRow>();
    103       this.RegisterRowsEvents();
     104      Rows = new NamedItemCollection<DataRow>();
    104105    }
    105106
     
    217218    }
    218219    IEnumerable<string> IStringConvertibleMatrix.RowNames {
    219       get { return new List<string>(); }
     220      get { return Enumerable.Empty<string>(); }
    220221      set { throw new NotSupportedException(); }
    221222    }
  • trunk/sources/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs

    r7829 r8280  
    2222using System;
    2323using System.Collections.Generic;
     24using System.ComponentModel;
    2425using System.Drawing;
    2526using System.Linq;
     
    3839    }
    3940
    40     [Storable]
    41     private ObservableList<PointF> points;
    42     public ObservableList<PointF> Points {
    43       get { return points; }
    44     }
    45 
    46     [Storable]
    47     private string xAxisName;
    48     public string XAxisName {
    49       get { return xAxisName; }
     41    private ScatterPlotVisualProperties visualProperties;
     42    public ScatterPlotVisualProperties VisualProperties {
     43      get { return visualProperties; }
    5044      set {
    51         if (value == xAxisName) return;
    52         xAxisName = value;
    53         OnAxesNameChanged();
     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        }
    5452      }
    5553    }
    5654
    57     [Storable]
    58     private string yAxisName;
    59     public string YAxisName {
    60       get { return yAxisName; }
     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; }
    6169      set {
    62         if (value == yAxisName) return;
    63         yAxisName = value;
    64         OnAxesNameChanged();
     70        visualProperties = value;
     71        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
    6572      }
    6673    }
     74    [Storable(Name = "Rows")]
     75    private IEnumerable<ScatterPlotDataRow> StorableRows {
     76      get { return rows; }
     77      set { Rows = new NamedItemCollection<ScatterPlotDataRow>(value); }
     78    }
     79    #endregion
    6780
    6881    [StorableConstructor]
     
    7083    protected ScatterPlot(ScatterPlot original, Cloner cloner)
    7184      : base(original, cloner) {
    72       points = new ObservableList<PointF>(original.points);
    73       xAxisName = original.xAxisName;
    74       yAxisName = original.yAxisName;
     85      VisualProperties = cloner.Clone(original.visualProperties);
     86      Rows = cloner.Clone(original.rows);
    7587    }
    7688    public ScatterPlot()
    7789      : base() {
    78       this.points = new ObservableList<PointF>();
    79     }
    80     public ScatterPlot(string name)
    81       : base(name) {
    82       this.points = new ObservableList<PointF>();
     90      VisualProperties = new ScatterPlotVisualProperties();
     91      Rows = new NamedItemCollection<ScatterPlotDataRow>();
    8392    }
    8493    public ScatterPlot(string name, string description)
    8594      : base(name, description) {
    86       this.points = new ObservableList<PointF>();
    87     }
    88     public ScatterPlot(string name, string description, string xAxisName, string yAxisName)
     95      VisualProperties = new ScatterPlotVisualProperties(name);
     96      Rows = new NamedItemCollection<ScatterPlotDataRow>();
     97    }
     98    public ScatterPlot(string name, string description, ScatterPlotVisualProperties visualProperties)
    8999      : base(name, description) {
    90       this.points = new ObservableList<PointF>();
    91       this.xAxisName = xAxisName;
    92       this.yAxisName = yAxisName;
    93     }
    94     public ScatterPlot(IEnumerable<PointF> points)
    95       : base() {
    96       this.points = new ObservableList<PointF>(points);
    97     }
    98     public ScatterPlot(IEnumerable<PointF> points, string name)
    99       : base(name) {
    100       this.points = new ObservableList<PointF>(points);
    101     }
    102     public ScatterPlot(IEnumerable<PointF> points, string name, string description)
    103       : base(name, description) {
    104       this.points = new ObservableList<PointF>(points);
    105     }
    106     public ScatterPlot(IEnumerable<PointF> points, string name, string description, string xAxisName, string yAxisName)
    107       : base(name, description) {
    108       this.points = new ObservableList<PointF>(points);
    109       this.xAxisName = xAxisName;
    110       this.yAxisName = yAxisName;
    111     }
     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")]
     108    private ObservableList<PointF> StorablePoints {
     109      set { points = value; }
     110    }
     111    private string xAxisName;
     112    [Storable(Name = "xAxisName")]
     113    private string StorableXAxisName {
     114      set { xAxisName = value; }
     115    }
     116    private string yAxisName;
     117    [Storable(Name = "yAxisName")]
     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
    112130
    113131    public override IDeepCloneable Clone(Cloner cloner) {
     
    115133    }
    116134
    117     public event EventHandler AxisNameChanged;
    118     protected virtual void OnAxesNameChanged() {
    119       EventHandler handler = AxisNameChanged;
    120       if (handler != null)
    121         handler(this, EventArgs.Empty);
     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();
    122218    }
    123219
    124220    #region IStringConvertibleMatrix Members
    125 
    126221    int IStringConvertibleMatrix.Rows {
    127       get { return points.Count; }
     222      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Points.Count); }
    128223      set { throw new NotSupportedException(); }
    129224    }
    130225    int IStringConvertibleMatrix.Columns {
    131       get { return 2; }
     226      get { return rows.Count; }
    132227      set { throw new NotSupportedException(); }
    133228    }
    134229    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
    135       get { return new string[] { xAxisName, yAxisName }; }
     230      get { return rows.Select(r => r.Name); }
    136231      set { throw new NotSupportedException(); }
    137232    }
     
    142237
    143238    bool IStringConvertibleMatrix.SortableView {
    144       get { return false; }
     239      get { return true; }
    145240      set { throw new NotSupportedException(); }
    146241    }
     
    150245
    151246    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
    152       if (rowIndex < points.Count && columnIndex < 2) {
    153         return columnIndex == 0 ? points[rowIndex].X.ToString() : points[rowIndex].Y.ToString();
     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);
    154251      }
    155252      return string.Empty;
  • trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj

    r8016 r8280  
    125125    <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyCollectionHistory.cs" />
    126126    <Compile Include="BestScopeSolutionAnalyzer.cs" />
     127    <Compile Include="DataVisualization\ScatterPlotDataRowVisualProperties.cs" />
     128    <Compile Include="DataVisualization\ScatterPlotDataRow.cs" />
     129    <Compile Include="DataVisualization\ScatterPlotVisualProperties.cs" />
     130    <Compile Include="DataVisualization\ScatterPlotHistory.cs" />
    127131    <Compile Include="DataVisualization\DataRow.cs" />
    128132    <Compile Include="DataVisualization\DataRowVisualProperties.cs" />
  • trunk/sources/HeuristicLab.Common/3.3/HeuristicLab.Common-3.3.csproj

    r7812 r8280  
    124124    <Compile Include="Content\IStorableContent.cs" />
    125125    <Compile Include="Constants.cs" />
     126    <Compile Include="Point2D.cs" />
    126127    <Compile Include="EnumerableExtensions.cs" />
    127128    <Compile Include="MatrixExtensions.cs" />
Note: See TracChangeset for help on using the changeset viewer.