Changeset 14439 for trunk/sources
- Timestamp:
- 12/02/16 13:06:49 (8 years ago)
- Location:
- trunk/sources/HeuristicLab.Analysis.Views/3.3
- Files:
-
- 5 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableControl.Designer.cs
r14435 r14439 21 21 22 22 namespace HeuristicLab.Analysis.Views { 23 partial class DataTable View{23 partial class DataTableControl { 24 24 /// <summary> 25 25 /// Required designer variable. … … 45 45 /// </summary> 46 46 private void InitializeComponent() { 47 this.components = new System.ComponentModel.Container(); 47 48 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); 48 49 System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); … … 51 52 this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart(); 52 53 this.configureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 53 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();54 54 ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit(); 55 55 this.SuspendLayout(); 56 56 // 57 // nameTextBox58 //59 this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);60 this.errorProvider.SetIconPadding(this.nameTextBox, 2);61 this.nameTextBox.Location = new System.Drawing.Point(55, 0);62 this.nameTextBox.Size = new System.Drawing.Size(279, 20);63 //64 // infoLabel65 //66 this.infoLabel.Location = new System.Drawing.Point(340, 3);67 //68 57 // chart 69 58 // 70 this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 71 | System.Windows.Forms.AnchorStyles.Left)72 59 this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 60 | System.Windows.Forms.AnchorStyles.Left) 61 | System.Windows.Forms.AnchorStyles.Right))); 73 62 this.chart.BorderlineColor = System.Drawing.Color.Black; 74 63 this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid; … … 84 73 legend1.Name = "Default"; 85 74 this.chart.Legends.Add(legend1); 86 this.chart.Location = new System.Drawing.Point(0, 26);75 this.chart.Location = new System.Drawing.Point(0, 0); 87 76 this.chart.Name = "chart"; 88 77 series1.ChartArea = "Default"; … … 90 79 series1.Name = "Default"; 91 80 this.chart.Series.Add(series1); 92 this.chart.Size = new System.Drawing.Size(359, 2 48);81 this.chart.Size = new System.Drawing.Size(359, 274); 93 82 this.chart.TabIndex = 3; 94 83 this.chart.Text = "chart"; … … 108 97 this.configureToolStripMenuItem.Click += new System.EventHandler(this.configureToolStripMenuItem_Click); 109 98 // 110 // DataTable View99 // DataTableControl 111 100 // 112 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);113 101 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; 114 102 this.Controls.Add(this.chart); 115 this.Name = "DataTable View";103 this.Name = "DataTableControl"; 116 104 this.Size = new System.Drawing.Size(359, 274); 117 this.Controls.SetChildIndex(this.infoLabel, 0);118 this.Controls.SetChildIndex(this.chart, 0);119 this.Controls.SetChildIndex(this.nameLabel, 0);120 this.Controls.SetChildIndex(this.nameTextBox, 0);121 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();122 105 ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit(); 123 106 this.ResumeLayout(false); 124 this.PerformLayout();125 107 126 108 } -
trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableControl.cs
r14438 r14439 27 27 using System.Windows.Forms.DataVisualization.Charting; 28 28 using HeuristicLab.Collections; 29 using HeuristicLab.Core.Views;30 using HeuristicLab.MainForm;31 29 32 30 namespace HeuristicLab.Analysis.Views { 33 [View("DataTable View")] 34 [Content(typeof(DataTable), true)] 35 public partial class DataTableView : NamedItemView, IConfigureableView { 31 public partial class DataTableControl : UserControl { 36 32 protected List<Series> invisibleSeries; 37 33 protected Dictionary<IObservableList<double>, DataRow> valuesRowsTable; 38 34 39 public new DataTable Content { 40 get { return (DataTable)base.Content; } 41 set { base.Content = value; } 42 } 43 44 public DataTableView() { 35 private DataTable content; 36 public DataTable Content { 37 get { return content; } 38 set { 39 if (value == content) return; 40 if (content != null) DeregisterContentEvents(); 41 content = value; 42 if (content != null) RegisterContentEvents(); 43 OnContentChanged(); 44 SetEnabledStateOfControls(); 45 } 46 } 47 48 public DataTableControl() { 45 49 InitializeComponent(); 46 50 valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>(); … … 52 56 53 57 #region Event Handler Registration 54 protected overridevoid DeregisterContentEvents() {58 protected virtual void DeregisterContentEvents() { 55 59 foreach (DataRow row in Content.Rows) 56 60 DeregisterDataRowEvents(row); … … 60 64 Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced); 61 65 Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset); 62 base.DeregisterContentEvents(); 63 } 64 protected override void RegisterContentEvents() { 65 base.RegisterContentEvents(); 66 } 67 protected virtual void RegisterContentEvents() { 66 68 Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged); 67 69 Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded); … … 93 95 #endregion 94 96 95 protected override void OnContentChanged() { 96 base.OnContentChanged(); 97 protected virtual void OnContentChanged() { 97 98 invisibleSeries.Clear(); 98 99 chart.Titles[0].Text = string.Empty; … … 110 111 } 111 112 112 protected override void SetEnabledStateOfControls() { 113 base.SetEnabledStateOfControls(); 113 protected virtual void SetEnabledStateOfControls() { 114 114 chart.Enabled = Content != null; 115 115 } … … 284 284 #region Event Handlers 285 285 #region Content Event Handlers 286 protected override void Content_NameChanged(object sender, EventArgs e) {287 if (InvokeRequired)288 Invoke(new EventHandler(Content_NameChanged), sender, e);289 else {290 chart.Titles[0].Text = Content.Name;291 chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.Name);292 base.Content_NameChanged(sender, e);293 }294 }295 286 private void Content_VisualPropertiesChanged(object sender, EventArgs e) { 296 287 if (InvokeRequired) -
trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs
r14435 r14439 45 45 /// </summary> 46 46 private void InitializeComponent() { 47 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(); 49 System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); 50 System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title(); 51 this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart(); 52 this.configureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 this.chart = new HeuristicLab.Analysis.Views.DataTableControl(); 53 48 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); 54 ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();55 49 this.SuspendLayout(); 56 50 // … … 71 65 | System.Windows.Forms.AnchorStyles.Left) 72 66 | System.Windows.Forms.AnchorStyles.Right))); 73 this.chart.BorderlineColor = System.Drawing.Color.Black;74 this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;75 chartArea1.AxisX.Minimum = 0D;76 chartArea1.CursorX.IsUserEnabled = true;77 chartArea1.CursorX.IsUserSelectionEnabled = true;78 chartArea1.CursorY.IsUserEnabled = true;79 chartArea1.CursorY.IsUserSelectionEnabled = true;80 chartArea1.Name = "Default";81 this.chart.ChartAreas.Add(chartArea1);82 legend1.Alignment = System.Drawing.StringAlignment.Center;83 legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;84 legend1.Name = "Default";85 this.chart.Legends.Add(legend1);86 67 this.chart.Location = new System.Drawing.Point(0, 26); 87 68 this.chart.Name = "chart"; 88 series1.ChartArea = "Default";89 series1.Legend = "Default";90 series1.Name = "Default";91 this.chart.Series.Add(series1);92 69 this.chart.Size = new System.Drawing.Size(359, 248); 93 70 this.chart.TabIndex = 3; 94 71 this.chart.Text = "chart"; 95 title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));96 title1.Name = "Default";97 title1.Text = "Title";98 this.chart.Titles.Add(title1);99 this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);100 this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);101 this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);102 //103 // configureToolStripMenuItem104 //105 this.configureToolStripMenuItem.Name = "configureToolStripMenuItem";106 this.configureToolStripMenuItem.Size = new System.Drawing.Size(256, 22);107 this.configureToolStripMenuItem.Text = "Configure Chart";108 this.configureToolStripMenuItem.Click += new System.EventHandler(this.configureToolStripMenuItem_Click);109 72 // 110 73 // DataTableView … … 120 83 this.Controls.SetChildIndex(this.nameTextBox, 0); 121 84 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit(); 122 ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();123 85 this.ResumeLayout(false); 124 86 this.PerformLayout(); 125 126 87 } 127 88 128 89 #endregion 129 90 130 protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart; 131 private System.Windows.Forms.ToolStripMenuItem configureToolStripMenuItem; 91 protected HeuristicLab.Analysis.Views.DataTableControl chart; 132 92 } 133 93 } -
trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs
r14438 r14439 21 21 22 22 using System; 23 using System.Collections.Generic;24 using System.Drawing;25 using System.Linq;26 using System.Windows.Forms;27 using System.Windows.Forms.DataVisualization.Charting;28 using HeuristicLab.Collections;29 23 using HeuristicLab.Core.Views; 30 24 using HeuristicLab.MainForm; … … 34 28 [Content(typeof(DataTable), true)] 35 29 public partial class DataTableView : NamedItemView, IConfigureableView { 36 protected List<Series> invisibleSeries;37 protected Dictionary<IObservableList<double>, DataRow> valuesRowsTable;38 30 39 31 public new DataTable Content { … … 44 36 public DataTableView() { 45 37 InitializeComponent(); 46 valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>();47 invisibleSeries = new List<Series>();48 chart.CustomizeAllChartAreas();49 chart.ChartAreas[0].CursorX.Interval = 1;50 chart.ContextMenuStrip.Items.Add(configureToolStripMenuItem);51 38 } 52 53 #region Event Handler Registration54 protected override void DeregisterContentEvents() {55 foreach (DataRow row in Content.Rows)56 DeregisterDataRowEvents(row);57 Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);58 Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);59 Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);60 Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);61 Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);62 base.DeregisterContentEvents();63 }64 protected override void RegisterContentEvents() {65 base.RegisterContentEvents();66 Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);67 Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);68 Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);69 Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);70 Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);71 }72 73 protected virtual void RegisterDataRowEvents(DataRow row) {74 row.NameChanged += new EventHandler(Row_NameChanged);75 row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);76 valuesRowsTable.Add(row.Values, row);77 row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);78 row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);79 row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);80 row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);81 row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);82 }83 protected virtual void DeregisterDataRowEvents(DataRow row) {84 row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);85 row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);86 row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);87 row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);88 row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);89 valuesRowsTable.Remove(row.Values);90 row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);91 row.NameChanged -= new EventHandler(Row_NameChanged);92 }93 #endregion94 39 95 40 protected override void OnContentChanged() { 96 41 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.ChartAreas[0].AxisY2.Title = string.Empty; 102 chart.Series.Clear(); 103 if (Content != null) { 104 chart.Titles[0].Text = Content.Name; 105 chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.Name); 106 AddDataRows(Content.Rows); 107 ConfigureChartArea(chart.ChartAreas[0]); 108 RecalculateAxesScale(chart.ChartAreas[0]); 109 } 42 chart.Content = Content; 110 43 } 111 44 … … 115 48 } 116 49 117 public void ShowConfiguration() {118 if (Content != null) {119 using (var dialog = new DataTableVisualPropertiesDialog(Content)) {120 dialog.ShowDialog(this);121 }122 } else MessageBox.Show("Nothing to configure.");123 }124 protected virtual void AddDataRows(IEnumerable<DataRow> rows) {125 foreach (var row in rows) {126 RegisterDataRowEvents(row);127 var series = new Series(row.Name);128 if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;129 else series.LegendText = row.Name;130 ConfigureSeries(series, row);131 FillSeriesWithRowValues(series, row);132 chart.Series.Add(series);133 }134 ConfigureChartArea(chart.ChartAreas[0]);135 RecalculateAxesScale(chart.ChartAreas[0]);136 UpdateYCursorInterval();137 }138 139 protected virtual void RemoveDataRows(IEnumerable<DataRow> rows) {140 foreach (var row in rows) {141 DeregisterDataRowEvents(row);142 Series series = chart.Series[row.Name];143 chart.Series.Remove(series);144 if (invisibleSeries.Contains(series))145 invisibleSeries.Remove(series);146 }147 RecalculateAxesScale(chart.ChartAreas[0]);148 }149 150 private void ConfigureSeries(Series series, DataRow row) {151 RemoveCustomPropertyIfExists(series, "PointWidth");152 series.BorderWidth = 1;153 series.BorderDashStyle = ChartDashStyle.Solid;154 series.BorderColor = Color.Empty;155 156 if (row.VisualProperties.Color != Color.Empty)157 series.Color = row.VisualProperties.Color;158 else series.Color = Color.Empty;159 series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;160 161 switch (row.VisualProperties.ChartType) {162 case DataRowVisualProperties.DataRowChartType.Line:163 series.ChartType = SeriesChartType.FastLine;164 series.BorderWidth = row.VisualProperties.LineWidth;165 series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);166 break;167 case DataRowVisualProperties.DataRowChartType.Bars:168 // Bar is incompatible with anything but Bar and StackedBar*169 if (!chart.Series.Any(x => x.ChartType != SeriesChartType.Bar && x.ChartType != SeriesChartType.StackedBar && x.ChartType != SeriesChartType.StackedBar100))170 series.ChartType = SeriesChartType.Bar;171 else {172 series.ChartType = SeriesChartType.FastPoint; //default173 row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;174 }175 break;176 case DataRowVisualProperties.DataRowChartType.Columns:177 series.ChartType = SeriesChartType.Column;178 break;179 case DataRowVisualProperties.DataRowChartType.Points:180 series.ChartType = SeriesChartType.FastPoint;181 break;182 case DataRowVisualProperties.DataRowChartType.Histogram:183 series.ChartType = SeriesChartType.Column;184 series.SetCustomProperty("PointWidth", "1");185 if (!series.Color.IsEmpty && series.Color.GetBrightness() < 0.25)186 series.BorderColor = Color.White;187 else series.BorderColor = Color.Black;188 break;189 case DataRowVisualProperties.DataRowChartType.StepLine:190 series.ChartType = SeriesChartType.StepLine;191 series.BorderWidth = row.VisualProperties.LineWidth;192 series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);193 break;194 default:195 series.ChartType = SeriesChartType.FastPoint;196 break;197 }198 series.YAxisType = row.VisualProperties.SecondYAxis ? AxisType.Secondary : AxisType.Primary;199 series.XAxisType = row.VisualProperties.SecondXAxis ? AxisType.Secondary : AxisType.Primary;200 if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;201 else series.LegendText = row.Name;202 203 string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)204 ? "X"205 : Content.VisualProperties.XAxisTitle;206 string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)207 ? "Y"208 : Content.VisualProperties.YAxisTitle;209 series.ToolTip =210 series.LegendText + Environment.NewLine +211 xAxisTitle + " = " + "#INDEX," + Environment.NewLine +212 yAxisTitle + " = " + "#VAL";213 }214 215 private void ConfigureChartArea(ChartArea area) {216 if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;217 if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;218 chart.Titles[0].Text = Content.VisualProperties.Title;219 chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.VisualProperties.Title);220 221 if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;222 if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;223 area.AxisX.Title = Content.VisualProperties.XAxisTitle;224 225 if (Content.VisualProperties.AxisTitleFont != null) area.AxisX2.TitleFont = Content.VisualProperties.AxisTitleFont;226 if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX2.TitleForeColor = Content.VisualProperties.AxisTitleColor;227 area.AxisX2.Title = Content.VisualProperties.SecondXAxisTitle;228 229 if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;230 if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;231 area.AxisY.Title = Content.VisualProperties.YAxisTitle;232 233 if (Content.VisualProperties.AxisTitleFont != null) area.AxisY2.TitleFont = Content.VisualProperties.AxisTitleFont;234 if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY2.TitleForeColor = Content.VisualProperties.AxisTitleColor;235 area.AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;236 237 area.AxisX.IsLogarithmic = Content.VisualProperties.XAxisLogScale;238 area.AxisX2.IsLogarithmic = Content.VisualProperties.SecondXAxisLogScale;239 area.AxisY.IsLogarithmic = Content.VisualProperties.YAxisLogScale;240 area.AxisY2.IsLogarithmic = Content.VisualProperties.SecondYAxisLogScale;241 }242 243 private void RecalculateAxesScale(ChartArea area) {244 // Reset the axes bounds so that RecalculateAxesScale() will assign new bounds245 foreach (Axis a in area.Axes) {246 a.Minimum = double.NaN;247 a.Maximum = double.NaN;248 }249 area.RecalculateAxesScale();250 area.AxisX.IsMarginVisible = false;251 area.AxisX2.IsMarginVisible = false;252 253 if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;254 if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;255 if (!Content.VisualProperties.SecondXAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMinimumFixedValue)) area.AxisX2.Minimum = Content.VisualProperties.SecondXAxisMinimumFixedValue;256 if (!Content.VisualProperties.SecondXAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMaximumFixedValue)) area.AxisX2.Maximum = Content.VisualProperties.SecondXAxisMaximumFixedValue;257 if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;258 if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;259 if (!Content.VisualProperties.SecondYAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMinimumFixedValue)) area.AxisY2.Minimum = Content.VisualProperties.SecondYAxisMinimumFixedValue;260 if (!Content.VisualProperties.SecondYAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMaximumFixedValue)) area.AxisY2.Maximum = Content.VisualProperties.SecondYAxisMaximumFixedValue;261 if (area.AxisX.Minimum >= area.AxisX.Maximum) area.AxisX.Maximum = area.AxisX.Minimum + 1;262 if (area.AxisX2.Minimum >= area.AxisX2.Maximum) area.AxisX2.Maximum = area.AxisX2.Minimum + 1;263 if (area.AxisY.Minimum >= area.AxisY.Maximum) area.AxisY.Maximum = area.AxisY.Minimum + 1;264 if (area.AxisY2.Minimum >= area.AxisY2.Maximum) area.AxisY2.Maximum = area.AxisY2.Minimum + 1;265 }266 267 protected virtual void UpdateYCursorInterval() {268 double interestingValuesRange = (269 from series in chart.Series270 where series.Enabled271 let values = (from point in series.Points272 where !point.IsEmpty273 select point.YValues[0]).DefaultIfEmpty(1.0)274 let range = values.Max() - values.Min()275 where range > 0.0276 select range277 ).DefaultIfEmpty(1.0).Min();278 279 double digits = (int)Math.Log10(interestingValuesRange) - 3;280 double yZoomInterval = Math.Pow(10, digits);281 this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;282 }283 284 #region Event Handlers285 50 #region Content Event Handlers 286 51 protected override void Content_NameChanged(object sender, EventArgs e) { … … 288 53 Invoke(new EventHandler(Content_NameChanged), sender, e); 289 54 else { 290 chart.Titles[0].Text = Content.Name; 291 chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.Name); 55 Content.VisualProperties.Title = Content.Name; 292 56 base.Content_NameChanged(sender, e); 293 }294 }295 private void Content_VisualPropertiesChanged(object sender, EventArgs e) {296 if (InvokeRequired)297 Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);298 else {299 ConfigureChartArea(chart.ChartAreas[0]);300 RecalculateAxesScale(chart.ChartAreas[0]); // axes min/max could have changed301 }302 }303 #endregion304 #region Rows Event Handlers305 private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {306 if (InvokeRequired)307 Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);308 else {309 AddDataRows(e.Items);310 }311 }312 private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {313 if (InvokeRequired)314 Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);315 else {316 RemoveDataRows(e.Items);317 }318 }319 private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {320 if (InvokeRequired)321 Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);322 else {323 RemoveDataRows(e.OldItems);324 AddDataRows(e.Items);325 }326 }327 private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {328 if (InvokeRequired)329 Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);330 else {331 RemoveDataRows(e.OldItems);332 AddDataRows(e.Items);333 }334 }335 #endregion336 #region Row Event Handlers337 private void Row_VisualPropertiesChanged(object sender, EventArgs e) {338 if (InvokeRequired)339 Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);340 else {341 DataRow row = (DataRow)sender;342 Series series = chart.Series[row.Name];343 series.Points.Clear();344 ConfigureSeries(series, row);345 FillSeriesWithRowValues(series, row);346 RecalculateAxesScale(chart.ChartAreas[0]);347 }348 }349 private void Row_NameChanged(object sender, EventArgs e) {350 if (InvokeRequired)351 Invoke(new EventHandler(Row_NameChanged), sender, e);352 else {353 DataRow row = (DataRow)sender;354 chart.Series[row.Name].Name = row.Name;355 }356 }357 #endregion358 #region Values Event Handlers359 private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {360 if (InvokeRequired)361 Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);362 else {363 DataRow row = null;364 valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);365 if (row != null) {366 Series rowSeries = chart.Series[row.Name];367 if (!invisibleSeries.Contains(rowSeries)) {368 rowSeries.Points.Clear();369 FillSeriesWithRowValues(rowSeries, row);370 RecalculateAxesScale(chart.ChartAreas[0]);371 UpdateYCursorInterval();372 }373 }374 }375 }376 private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {377 if (InvokeRequired)378 Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);379 else {380 DataRow row = null;381 valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);382 if (row != null) {383 Series rowSeries = chart.Series[row.Name];384 if (!invisibleSeries.Contains(rowSeries)) {385 rowSeries.Points.Clear();386 FillSeriesWithRowValues(rowSeries, row);387 RecalculateAxesScale(chart.ChartAreas[0]);388 UpdateYCursorInterval();389 }390 }391 }392 }393 private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {394 if (InvokeRequired)395 Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);396 else {397 DataRow row = null;398 valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);399 if (row != null) {400 Series rowSeries = chart.Series[row.Name];401 if (!invisibleSeries.Contains(rowSeries)) {402 if (row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram) {403 rowSeries.Points.Clear();404 FillSeriesWithRowValues(rowSeries, row);405 } else {406 foreach (IndexedItem<double> item in e.Items) {407 if (IsInvalidValue(item.Value))408 rowSeries.Points[item.Index].IsEmpty = true;409 else {410 rowSeries.Points[item.Index].YValues = new double[] { item.Value };411 rowSeries.Points[item.Index].IsEmpty = false;412 }413 }414 }415 RecalculateAxesScale(chart.ChartAreas[0]);416 UpdateYCursorInterval();417 }418 }419 }420 }421 private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {422 if (InvokeRequired)423 Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);424 else {425 DataRow row = null;426 valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);427 if (row != null) {428 Series rowSeries = chart.Series[row.Name];429 if (!invisibleSeries.Contains(rowSeries)) {430 rowSeries.Points.Clear();431 FillSeriesWithRowValues(rowSeries, row);432 RecalculateAxesScale(chart.ChartAreas[0]);433 UpdateYCursorInterval();434 }435 }436 }437 }438 439 private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {440 if (InvokeRequired)441 Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);442 else {443 DataRow row = null;444 valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);445 if (row != null) {446 Series rowSeries = chart.Series[row.Name];447 if (!invisibleSeries.Contains(rowSeries)) {448 rowSeries.Points.Clear();449 FillSeriesWithRowValues(rowSeries, row);450 RecalculateAxesScale(chart.ChartAreas[0]);451 UpdateYCursorInterval();452 }453 }454 }455 }456 #endregion457 private void configureToolStripMenuItem_Click(object sender, EventArgs e) {458 ShowConfiguration();459 }460 #endregion461 462 #region Chart Event Handlers463 private void chart_MouseDown(object sender, MouseEventArgs e) {464 HitTestResult result = chart.HitTest(e.X, e.Y);465 if (result.ChartElementType == ChartElementType.LegendItem) {466 ToggleSeriesVisible(result.Series);467 }468 }469 private void chart_MouseMove(object sender, MouseEventArgs e) {470 HitTestResult result = chart.HitTest(e.X, e.Y);471 if (result.ChartElementType == ChartElementType.LegendItem)472 this.Cursor = Cursors.Hand;473 else474 this.Cursor = Cursors.Default;475 }476 private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {477 foreach (LegendItem legendItem in e.LegendItems) {478 var series = chart.Series[legendItem.SeriesName];479 if (series != null) {480 bool seriesIsInvisible = invisibleSeries.Contains(series);481 foreach (LegendCell cell in legendItem.Cells) {482 cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;483 }484 }485 57 } 486 58 } 487 59 #endregion 488 60 489 private void ToggleSeriesVisible(Series series) { 490 if (!invisibleSeries.Contains(series)) { 491 series.Points.Clear(); 492 invisibleSeries.Add(series); 493 } else { 494 invisibleSeries.Remove(series); 495 if (Content != null) { 496 497 var row = (from r in Content.Rows 498 where r.Name == series.Name 499 select r).Single(); 500 FillSeriesWithRowValues(series, row); 501 this.chart.Legends[series.Legend].ForeColor = Color.Black; 502 RecalculateAxesScale(chart.ChartAreas[0]); 503 UpdateYCursorInterval(); 504 } 505 } 61 public void ShowConfiguration() { 62 chart.ShowConfiguration(); 506 63 } 507 508 private void FillSeriesWithRowValues(Series series, DataRow row) {509 switch (row.VisualProperties.ChartType) {510 case DataRowVisualProperties.DataRowChartType.Histogram:511 CalculateHistogram(series, row);512 break;513 default: {514 bool yLogarithmic = series.YAxisType == AxisType.Primary515 ? Content.VisualProperties.YAxisLogScale516 : Content.VisualProperties.SecondYAxisLogScale;517 bool xLogarithmic = series.XAxisType == AxisType.Primary518 ? Content.VisualProperties.XAxisLogScale519 : Content.VisualProperties.SecondXAxisLogScale;520 for (int i = 0; i < row.Values.Count; i++) {521 var value = row.Values[i];522 var point = new DataPoint();523 point.XValue = row.VisualProperties.StartIndexZero && !xLogarithmic ? i : i + 1;524 if (IsInvalidValue(value) || (yLogarithmic && value <= 0))525 point.IsEmpty = true;526 else527 point.YValues = new double[] { value };528 series.Points.Add(point);529 }530 }531 break;532 }533 }534 535 protected virtual void CalculateHistogram(Series series, DataRow row) {536 series.Points.Clear();537 if (!row.Values.Any()) return;538 int bins = row.VisualProperties.Bins;539 540 double minValue = row.Values.Min();541 double maxValue = row.Values.Max();542 double intervalWidth = (maxValue - minValue) / bins;543 if (intervalWidth < 0) return;544 if (intervalWidth == 0) {545 series.Points.AddXY(minValue, row.Values.Count);546 return;547 }548 549 if (!row.VisualProperties.ExactBins) {550 intervalWidth = HumanRoundRange(intervalWidth);551 minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;552 maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;553 }554 555 double intervalCenter = intervalWidth / 2;556 557 double min = 0.0, max = 0.0;558 if (!Double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue) && !Content.VisualProperties.XAxisMinimumAuto)559 min = Content.VisualProperties.XAxisMinimumFixedValue;560 else min = minValue;561 if (!Double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue) && !Content.VisualProperties.XAxisMaximumAuto)562 max = Content.VisualProperties.XAxisMaximumFixedValue;563 else max = maxValue + intervalWidth;564 565 double axisInterval = intervalWidth / row.VisualProperties.ScaleFactor;566 567 var area = chart.ChartAreas[0];568 area.AxisX.Interval = axisInterval;569 570 series.SetCustomProperty("PointWidth", "1"); // 0.8 is the default value571 572 // get the range or intervals which define the grouping of the frequency values573 var doubleRange = DoubleRange(min, max, intervalWidth).Skip(1).ToList();574 575 // aggregate the row values by unique key and frequency value576 var valueFrequencies = (from v in row.Values577 where !IsInvalidValue(v)578 orderby v579 group v by v into g580 select new Tuple<double, double>(g.First(), g.Count())).ToList();581 582 // shift the chart to the left so the bars are placed on the intervals583 if (valueFrequencies.First().Item1 < doubleRange.First())584 series.Points.Add(new DataPoint(min - intervalWidth, 0));585 586 // add data points587 int j = 0;588 foreach (var d in doubleRange) {589 double sum = 0.0;590 // sum the frequency values that fall within the same interval591 while (j < valueFrequencies.Count && valueFrequencies[j].Item1 < d) {592 sum += valueFrequencies[j].Item2;593 ++j;594 }595 string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)596 ? "X"597 : Content.VisualProperties.XAxisTitle;598 string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)599 ? "Y"600 : Content.VisualProperties.YAxisTitle;601 series.Points.Add(new DataPoint(d - intervalCenter, sum) {602 ToolTip =603 xAxisTitle + ": [" + (d - intervalWidth) + "-" + d + ")" + Environment.NewLine +604 yAxisTitle + ": " + sum605 });606 }607 }608 609 #region Helpers610 public static IEnumerable<double> DoubleRange(double min, double max, double step) {611 double i;612 for (i = min; i <= max; i += step)613 yield return i;614 615 if (i != max + step)616 yield return i;617 }618 619 protected void RemoveCustomPropertyIfExists(Series series, string property) {620 if (series.IsCustomPropertySet(property)) series.DeleteCustomProperty(property);621 }622 623 private double HumanRoundRange(double range) {624 double base10 = Math.Pow(10.0, Math.Floor(Math.Log10(range)));625 double rounding = range / base10;626 if (rounding <= 1.5) rounding = 1;627 else if (rounding <= 2.25) rounding = 2;628 else if (rounding <= 3.75) rounding = 2.5;629 else if (rounding <= 7.5) rounding = 5;630 else rounding = 10;631 return rounding * base10;632 }633 634 private double HumanRoundMax(double max) {635 double base10;636 if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));637 else base10 = Math.Pow(10.0, Math.Ceiling(Math.Log10(-max)));638 double rounding = (max > 0) ? base10 : -base10;639 while (rounding < max) rounding += base10;640 return rounding;641 }642 643 private ChartDashStyle ConvertLineStyle(DataRowVisualProperties.DataRowLineStyle dataRowLineStyle) {644 switch (dataRowLineStyle) {645 case DataRowVisualProperties.DataRowLineStyle.Dash:646 return ChartDashStyle.Dash;647 case DataRowVisualProperties.DataRowLineStyle.DashDot:648 return ChartDashStyle.DashDot;649 case DataRowVisualProperties.DataRowLineStyle.DashDotDot:650 return ChartDashStyle.DashDotDot;651 case DataRowVisualProperties.DataRowLineStyle.Dot:652 return ChartDashStyle.Dot;653 case DataRowVisualProperties.DataRowLineStyle.NotSet:654 return ChartDashStyle.NotSet;655 case DataRowVisualProperties.DataRowLineStyle.Solid:656 return ChartDashStyle.Solid;657 default:658 return ChartDashStyle.NotSet;659 }660 }661 662 protected static bool IsInvalidValue(double x) {663 return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;664 }665 #endregion666 64 } 667 65 } -
trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj
r14208 r14439 122 122 </ItemGroup> 123 123 <ItemGroup> 124 <Compile Include="DataTableControl.cs"> 125 <SubType>UserControl</SubType> 126 </Compile> 127 <Compile Include="DataTableControl.Designer.cs"> 128 <DependentUpon>DataTableControl.cs</DependentUpon> 129 </Compile> 124 130 <Compile Include="IndexedDataTableView.cs"> 125 131 <SubType>UserControl</SubType> … … 127 133 <Compile Include="IndexedDataTableView.Designer.cs"> 128 134 <DependentUpon>IndexedDataTableView.cs</DependentUpon> 135 </Compile> 136 <Compile Include="ScatterPlotControl.cs"> 137 <SubType>UserControl</SubType> 138 </Compile> 139 <Compile Include="ScatterPlotControl.Designer.cs"> 140 <DependentUpon>ScatterPlotControl.cs</DependentUpon> 129 141 </Compile> 130 142 <Compile Include="ScatterPlotVisualPropertiesDialog.cs"> -
trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotControl.Designer.cs
r14435 r14439 21 21 22 22 namespace HeuristicLab.Analysis.Views { 23 partial class ScatterPlot View{23 partial class ScatterPlotControl { 24 24 /// <summary> 25 25 /// Required designer variable. … … 45 45 /// </summary> 46 46 private void InitializeComponent() { 47 this.components = new System.ComponentModel.Container(); 47 48 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); 48 49 System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); … … 51 52 this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart(); 52 53 this.configureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 53 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();54 54 ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit(); 55 55 this.SuspendLayout(); 56 56 // 57 // nameTextBox58 //59 this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);60 this.errorProvider.SetIconPadding(this.nameTextBox, 2);61 this.nameTextBox.Location = new System.Drawing.Point(55, 0);62 this.nameTextBox.Size = new System.Drawing.Size(279, 20);63 //64 // infoLabel65 //66 this.infoLabel.Location = new System.Drawing.Point(340, 3);67 //68 57 // chart 69 58 // 70 this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 71 | System.Windows.Forms.AnchorStyles.Left)72 59 this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 60 | System.Windows.Forms.AnchorStyles.Left) 61 | System.Windows.Forms.AnchorStyles.Right))); 73 62 this.chart.BorderlineColor = System.Drawing.Color.Black; 74 63 this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid; … … 84 73 legend1.Name = "Default"; 85 74 this.chart.Legends.Add(legend1); 86 this.chart.Location = new System.Drawing.Point(0, 26);75 this.chart.Location = new System.Drawing.Point(0, 0); 87 76 this.chart.Name = "chart"; 88 77 series1.ChartArea = "Default"; … … 90 79 series1.Name = "Default"; 91 80 this.chart.Series.Add(series1); 92 this.chart.Size = new System.Drawing.Size(359, 2 48);81 this.chart.Size = new System.Drawing.Size(359, 274); 93 82 this.chart.TabIndex = 3; 94 83 this.chart.Text = "chart"; … … 106 95 this.configureToolStripMenuItem.Size = new System.Drawing.Size(256, 22); 107 96 this.configureToolStripMenuItem.Text = "Configure Chart"; 108 this.configureToolStripMenuItem.Click += new System.EventHandler( configureToolStripMenuItem_Click);97 this.configureToolStripMenuItem.Click += new System.EventHandler(this.configureToolStripMenuItem_Click); 109 98 // 110 // ScatterPlot View99 // ScatterPlotControl 111 100 // 112 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);113 101 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; 114 102 this.Controls.Add(this.chart); 115 this.Name = "ScatterPlot View";103 this.Name = "ScatterPlotControl"; 116 104 this.Size = new System.Drawing.Size(359, 274); 117 this.Controls.SetChildIndex(this.infoLabel, 0);118 this.Controls.SetChildIndex(this.chart, 0);119 this.Controls.SetChildIndex(this.nameLabel, 0);120 this.Controls.SetChildIndex(this.nameTextBox, 0);121 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();122 105 ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit(); 123 106 this.ResumeLayout(false); 124 this.PerformLayout();125 107 126 108 } -
trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotControl.cs
r14438 r14439 28 28 using HeuristicLab.Collections; 29 29 using HeuristicLab.Common; 30 using HeuristicLab.Core.Views;31 using HeuristicLab.MainForm;32 30 33 31 namespace HeuristicLab.Analysis.Views { 34 [View("ScatterPlot View")] 35 [Content(typeof(ScatterPlot), true)] 36 public partial class ScatterPlotView : NamedItemView, IConfigureableView { 32 public partial class ScatterPlotControl : UserControl { 37 33 protected List<Series> invisibleSeries; 38 34 protected Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow> pointsRowsTable; 39 35 private double xMin, xMax, yMin, yMax; 40 36 41 public new ScatterPlot Content { 42 get { return (ScatterPlot)base.Content; } 43 set { base.Content = value; } 44 } 45 46 public ScatterPlotView() { 37 private ScatterPlot content; 38 public ScatterPlot Content { 39 get { return content; } 40 set { 41 if (value == content) return; 42 if (content != null) DeregisterContentEvents(); 43 content = value; 44 if (content != null) RegisterContentEvents(); 45 OnContentChanged(); 46 SetEnabledStateOfControls(); 47 } 48 } 49 50 public ScatterPlotControl() { 47 51 InitializeComponent(); 48 52 pointsRowsTable = new Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow>(); … … 54 58 55 59 #region Event Handler Registration 56 protected overridevoid DeregisterContentEvents() {60 protected virtual void DeregisterContentEvents() { 57 61 foreach (ScatterPlotDataRow row in Content.Rows) 58 62 DeregisterScatterPlotDataRowEvents(row); … … 62 66 Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced); 63 67 Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset); 64 base.DeregisterContentEvents(); 65 } 66 protected override void RegisterContentEvents() { 67 base.RegisterContentEvents(); 68 } 69 protected virtual void RegisterContentEvents() { 68 70 Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged); 69 71 Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded); … … 93 95 #endregion 94 96 95 protected override void OnContentChanged() { 96 base.OnContentChanged(); 97 protected virtual void OnContentChanged() { 97 98 invisibleSeries.Clear(); 98 99 chart.Titles[0].Text = string.Empty; … … 110 111 } 111 112 112 protected override void SetEnabledStateOfControls() { 113 base.SetEnabledStateOfControls(); 113 protected virtual void SetEnabledStateOfControls() { 114 114 chart.Enabled = Content != null; 115 115 } … … 252 252 #region Event Handlers 253 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 254 private void Content_VisualPropertiesChanged(object sender, EventArgs e) { 264 255 if (InvokeRequired) -
trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.Designer.cs
r14435 r14439 45 45 /// </summary> 46 46 private void InitializeComponent() { 47 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(); 49 System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); 50 System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title(); 51 this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart(); 52 this.configureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 this.chart = new HeuristicLab.Analysis.Views.ScatterPlotControl(); 53 48 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); 54 ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();55 49 this.SuspendLayout(); 56 50 // … … 71 65 | System.Windows.Forms.AnchorStyles.Left) 72 66 | System.Windows.Forms.AnchorStyles.Right))); 73 this.chart.BorderlineColor = System.Drawing.Color.Black;74 this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;75 chartArea1.AxisX.Minimum = 0D;76 chartArea1.CursorX.IsUserEnabled = true;77 chartArea1.CursorX.IsUserSelectionEnabled = true;78 chartArea1.CursorY.IsUserEnabled = true;79 chartArea1.CursorY.IsUserSelectionEnabled = true;80 chartArea1.Name = "Default";81 this.chart.ChartAreas.Add(chartArea1);82 legend1.Alignment = System.Drawing.StringAlignment.Center;83 legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;84 legend1.Name = "Default";85 this.chart.Legends.Add(legend1);86 67 this.chart.Location = new System.Drawing.Point(0, 26); 87 68 this.chart.Name = "chart"; 88 series1.ChartArea = "Default";89 series1.Legend = "Default";90 series1.Name = "Default";91 this.chart.Series.Add(series1);92 69 this.chart.Size = new System.Drawing.Size(359, 248); 93 70 this.chart.TabIndex = 3; 94 71 this.chart.Text = "chart"; 95 title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));96 title1.Name = "Default";97 title1.Text = "Title";98 this.chart.Titles.Add(title1);99 this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);100 this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);101 this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);102 //103 // configureToolStripMenuItem104 //105 this.configureToolStripMenuItem.Name = "configureToolStripMenuItem";106 this.configureToolStripMenuItem.Size = new System.Drawing.Size(256, 22);107 this.configureToolStripMenuItem.Text = "Configure Chart";108 this.configureToolStripMenuItem.Click += new System.EventHandler(configureToolStripMenuItem_Click);109 72 // 110 73 // ScatterPlotView … … 120 83 this.Controls.SetChildIndex(this.nameTextBox, 0); 121 84 ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit(); 122 ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();123 85 this.ResumeLayout(false); 124 86 this.PerformLayout(); … … 127 89 #endregion 128 90 129 protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart; 130 private System.Windows.Forms.ToolStripMenuItem configureToolStripMenuItem; 91 protected HeuristicLab.Analysis.Views.ScatterPlotControl chart; 131 92 } 132 93 } -
trunk/sources/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs
r14438 r14439 21 21 22 22 using System; 23 using System.Collections.Generic;24 using System.Drawing;25 using System.Linq;26 23 using System.Windows.Forms; 27 using System.Windows.Forms.DataVisualization.Charting;28 using HeuristicLab.Collections;29 using HeuristicLab.Common;30 24 using HeuristicLab.Core.Views; 31 25 using HeuristicLab.MainForm; … … 35 29 [Content(typeof(ScatterPlot), true)] 36 30 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 31 41 32 public new ScatterPlot Content { … … 46 37 public ScatterPlotView() { 47 38 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 39 } 54 55 #region Event Handler Registration56 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 #endregion94 40 95 41 protected override void OnContentChanged() { 96 42 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 } 43 chart.Content = Content; 110 44 } 111 45 … … 116 50 117 51 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."); 52 chart.ShowConfiguration(); 123 53 } 124 54 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.Series238 where series.Enabled239 let values = (from point in series.Points240 where !point.IsEmpty241 select point.YValues[0]).DefaultIfEmpty(1.0)242 let range = values.Max() - values.Min()243 where range > 0.0244 select range245 ).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 Handlers253 55 #region Content Event Handlers 254 56 protected override void Content_NameChanged(object sender, EventArgs e) { … … 256 58 Invoke(new EventHandler(Content_NameChanged), sender, e); 257 59 else { 258 chart.Titles[0].Text = Content.Name; 259 chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.Name); 60 Content.VisualProperties.Title = Content.Name; 260 61 base.Content_NameChanged(sender, e); 261 62 } 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 changed269 }270 }271 #endregion272 #region Rows Event Handlers273 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 #endregion304 #region Row Event Handlers305 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 #endregion327 #region Points Event Handlers328 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 #endregion401 private void configureToolStripMenuItem_Click(object sender, System.EventArgs e) {402 ShowConfiguration();403 }404 #endregion405 406 #region Chart Event Handlers407 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 else418 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 #endregion432 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.Rows443 where r.Name == series.Name444 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 Helpers483 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 63 } 511 64 #endregion
Note: See TracChangeset
for help on using the changeset viewer.