Changeset 13894 for branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Views/MOFrontScatterPlotView.cs
- Timestamp:
- 06/15/16 09:04:09 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Views/MOFrontScatterPlotView.cs
r13771 r13894 28 28 using HeuristicLab.Core.Views; 29 29 using HeuristicLab.MainForm; 30 31 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { 32 [View("Scatter Plot")] 33 [Content(typeof(IMOFrontModel))] 34 public partial class MOQualitiesScatterPlotView : ItemView { 35 private const string QUALITIES = "Qualities"; 36 private const string PARETO_FRONT = "Best Known Pareto Front"; 37 private Series qualitySeries; 38 private Series paretoSeries; 39 private int xDim = 0; 40 private int yDim = 1; 41 int objectives = -1; 42 43 public new IMOFrontModel Content { 44 get { return (IMOFrontModel)base.Content; } 45 set { base.Content = value; } 30 using System.Drawing.Imaging; 31 32 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions 33 { 34 [View("Scatter Plot")] 35 [Content(typeof(IMOFrontModel))] 36 public partial class MOQualitiesScatterPlotView : ItemView 37 { 38 private const string QUALITIES = "Qualities"; 39 private const string PARETO_FRONT = "Best Known Pareto Front"; 40 private Series qualitySeries; 41 private Series paretoSeries; 42 private int xDim = 0; 43 private int yDim = 1; 44 int objectives = -1; 45 46 public new IMOFrontModel Content 47 { 48 get { return (IMOFrontModel)base.Content; } 49 set { base.Content = value; } 50 } 51 52 public MOQualitiesScatterPlotView() 53 : base() 54 { 55 InitializeComponent(); 56 57 BuildEmptySeries(); 58 59 //start with qualities toggled ON 60 qualitySeries.Points.AddXY(0, 0); 61 62 this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High; 63 this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged); 64 65 //configure axis 66 this.chart.CustomizeAllChartAreas(); 67 this.chart.ChartAreas[0].AxisX.Title = "Objective " + xDim; 68 this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; 69 this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true; 70 this.chart.ChartAreas[0].CursorX.Interval = 1; 71 this.chart.ChartAreas[0].CursorY.Interval = 1; 72 73 this.chart.ChartAreas[0].AxisY.Title = "Objective " + yDim; 74 this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true; 75 this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true; 76 this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true; 77 } 78 79 protected override void RegisterContentEvents() 80 { 81 base.RegisterContentEvents(); 82 this.chart.GetToolTipText += new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText); 83 } 84 85 protected override void DeregisterContentEvents() 86 { 87 base.DeregisterContentEvents(); 88 this.chart.GetToolTipText -= new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText); 89 } 90 91 private void Chart_GetToolTipText(object sender, ToolTipEventArgs e) 92 { 93 if (e.HitTestResult.ChartElementType == ChartElementType.LegendItem) 94 { 95 if (e.HitTestResult.Series == paretoSeries && (Content.ParetoFront == null || Content.ParetoFront.Length == 0)) 96 { 97 e.Text = "No optimal pareto front is available for this problem with this number of objectives"; 98 } 99 if (e.HitTestResult.Series == paretoSeries && (xDim >= Content.Objectives || yDim >= Content.Objectives)) 100 { 101 e.Text = "The optimal pareto front can only be displayed in Objective Space"; 102 } 103 } 104 105 // Check selected chart element and set tooltip text 106 if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) 107 { 108 int i = e.HitTestResult.PointIndex; 109 StringBuilder toolTippText = new StringBuilder(); 110 DataPoint qp = e.HitTestResult.Series.Points[i]; 111 toolTippText.Append("Objective " + xDim + " = " + qp.XValue + "\n"); 112 toolTippText.Append("Objective " + yDim + " = " + qp.YValues[0]); 113 114 Series s = e.HitTestResult.Series; 115 if (s.Equals(this.chart.Series[QUALITIES])) 116 { 117 double[] dp = Content.Solutions[i]; 118 toolTippText.Append("\nSolution: {"); 119 for (int j = 0; j < dp.Length; j++) 120 { 121 toolTippText.Append(dp[j]); 122 toolTippText.Append(";"); 123 } 124 toolTippText.Remove(toolTippText.Length - 1, 1); 125 toolTippText.Append("}"); 126 e.Text = toolTippText.ToString(); 127 } 128 129 130 } 131 } 132 133 protected override void OnContentChanged() 134 { 135 base.OnContentChanged(); 136 if (Content == null) return; 137 if (objectives != Content.Objectives) 138 { 139 AddMenuItems(); 140 objectives = Content.Objectives; 141 } 142 if (Content.ParetoFront == null && chart.Series.Contains(paretoSeries)) 143 { 144 Series s = this.chart.Series[PARETO_FRONT]; 145 paretoSeries = null; 146 this.chart.Series.Remove(s); 147 148 } 149 else if (Content.ParetoFront != null && !chart.Series.Contains(paretoSeries)) 150 { 151 this.chart.Series.Add(PARETO_FRONT); 152 paretoSeries = this.chart.Series[PARETO_FRONT]; 153 this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT; 154 this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint; 155 } 156 UpdateChart(); 157 } 158 159 private void UpdateChart() 160 { 161 if (InvokeRequired) Invoke((Action)UpdateChart); 162 else 163 { 164 if (Content != null) 165 { 166 this.UpdateSeries(); 167 if (!this.chart.Series.Any(s => s.Points.Count > 0)) 168 this.ClearChart(); 169 } 170 } 171 } 172 173 private void UpdateCursorInterval() 174 { 175 var estimatedValues = this.chart.Series[QUALITIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0); 176 var targetValues = this.chart.Series[QUALITIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0); 177 double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min(); 178 double targetValuesRange = targetValues.Max() - targetValues.Min(); 179 double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0)); 180 double digits = (int)Math.Log10(interestingValuesRange) - 3; 181 double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5); 182 this.chart.ChartAreas[0].CursorX.Interval = zoomInterval; 183 this.chart.ChartAreas[0].CursorY.Interval = zoomInterval; 184 185 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval; 186 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval; 187 188 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number; 189 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval; 190 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number; 191 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval; 192 193 if (digits < 0) 194 { 195 this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits); 196 this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits); 197 } 198 else 199 { 200 this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0"; 201 this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0"; 202 } 203 } 204 205 private void UpdateSeries() 206 { 207 if (InvokeRequired) Invoke((Action)UpdateSeries); 208 else 209 { 210 211 if (this.chart.Series.Contains(qualitySeries) && qualitySeries.Points.Count() != 0) 212 { 213 fillSeries(Content.Qualities, Content.Solutions, qualitySeries); 214 } 215 if (this.chart.Series.Contains(paretoSeries) && paretoSeries.Points.Count() != 0) 216 { 217 fillSeries(Content.ParetoFront, null, paretoSeries); 218 } 219 220 221 double minX = Double.MaxValue; 222 double maxX = Double.MinValue; 223 double minY = Double.MaxValue; 224 double maxY = Double.MinValue; 225 foreach (Series s in this.chart.Series) 226 { 227 if (s.Points.Count == 0) continue; 228 minX = Math.Min(minX, s.Points.Select(p => p.XValue).Min()); 229 maxX = Math.Max(maxX, s.Points.Select(p => p.XValue).Max()); 230 minY = Math.Min(minY, s.Points.Select(p => p.YValues.Min()).Min()); 231 maxY = Math.Max(maxY, s.Points.Select(p => p.YValues.Max()).Max()); 232 } 233 234 maxX = maxX + 0.2 * Math.Abs(maxX); 235 minX = minX - 0.2 * Math.Abs(minX); 236 maxY = maxY + 0.2 * Math.Abs(maxY); 237 minY = minY - 0.2 * Math.Abs(minY); 238 239 double interestingValuesRangeX = maxX - minX; 240 double interestingValuesRangeY = maxY - minY; 241 242 int digitsX = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeX)); 243 int digitsY = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeY)); 244 245 246 maxX = Math.Round(maxX, digitsX); 247 minX = Math.Round(minX, digitsX); 248 maxY = Math.Round(maxY, digitsY); 249 minY = Math.Round(minY, digitsY); 250 if (minX > maxX) 251 { 252 minX = 0; 253 maxX = 1; 254 } 255 if (minY > maxY) 256 { 257 minY = 0; 258 maxY = 1; 259 } 260 261 262 this.chart.ChartAreas[0].AxisX.Maximum = maxX; 263 this.chart.ChartAreas[0].AxisX.Minimum = minX; 264 this.chart.ChartAreas[0].AxisY.Maximum = maxY; 265 this.chart.ChartAreas[0].AxisY.Minimum = minY; 266 UpdateCursorInterval(); 267 } 268 } 269 270 private void ClearChart() 271 { 272 if (chart.Series.Contains(qualitySeries)) chart.Series.Remove(qualitySeries); 273 if (chart.Series.Contains(paretoSeries)) chart.Series.Remove(paretoSeries); 274 BuildEmptySeries(); 275 } 276 277 private void ToggleSeriesData(Series series) 278 { 279 if (series.Points.Count > 0) 280 { //checks if series is shown 281 series.Points.Clear(); 282 } 283 else if (Content != null) 284 { 285 switch (series.Name) 286 { 287 case PARETO_FRONT: 288 fillSeries(Content.ParetoFront, null, this.chart.Series[PARETO_FRONT]); 289 break; 290 case QUALITIES: 291 fillSeries(Content.Qualities, Content.Solutions, this.chart.Series[QUALITIES]); 292 break; 293 } 294 } 295 } 296 297 private void chart_MouseDown(object sender, MouseEventArgs e) 298 { 299 HitTestResult result = chart.HitTest(e.X, e.Y); 300 if (result.ChartElementType == ChartElementType.LegendItem) 301 { 302 this.ToggleSeriesData(result.Series); 303 } 304 305 } 306 307 private void chart_MouseMove(object sender, MouseEventArgs e) 308 { 309 HitTestResult result = chart.HitTest(e.X, e.Y); 310 if (result.ChartElementType == ChartElementType.LegendItem) 311 this.Cursor = Cursors.Hand; 312 else 313 this.Cursor = Cursors.Default; 314 } 315 316 private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) 317 { 318 this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize; 319 this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize; 320 } 321 322 private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) 323 { 324 if (this.chart.Series.Contains(qualitySeries)) e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[QUALITIES].Points.Count == 0 ? Color.Gray : Color.Black; 325 if (this.chart.Series.Contains(paretoSeries)) e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[PARETO_FRONT].Points.Count == 0 ? Color.Gray : Color.Black; 326 } 327 328 private void AddMenuItems() 329 { 330 chooseDimensionToolStripMenuItem.DropDownItems.Clear(); 331 chooseYDimensionToolStripMenuItem.DropDownItems.Clear(); 332 if (Content == null) { return; } 333 int i = 0; 334 for (; i < Content.Objectives; i++) 335 { 336 //add Menu Points 337 ToolStripMenuItem xItem = makeMenuItem("X", "Objective " + i, i); 338 ToolStripMenuItem yItem = makeMenuItem("Y", "Objective " + i, i); 339 xItem.Click += new System.EventHandler(this.XMenu_Click); 340 yItem.Click += new System.EventHandler(this.YMenu_Click); 341 chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem); 342 chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem); 343 } 344 345 for (; i < Content.Solutions[0].Length + Content.Objectives; i++) 346 { 347 ToolStripMenuItem xItem = makeMenuItem("X", "ProblemDimension " + (i - Content.Objectives), i); 348 ToolStripMenuItem yItem = makeMenuItem("Y", "ProblemDimension " + (i - Content.Objectives), i); ; 349 xItem.Click += new System.EventHandler(this.XMenu_Click); 350 yItem.Click += new System.EventHandler(this.YMenu_Click); 351 chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem); 352 chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem); 353 } 354 } 355 356 private ToolStripMenuItem makeMenuItem(String axis, String label, int i) 357 { 358 ToolStripMenuItem xItem = new ToolStripMenuItem(); 359 xItem.Name = "obj" + i; 360 xItem.Size = new System.Drawing.Size(269, 38); 361 xItem.Text = label; 362 return xItem; 363 } 364 365 private void YMenu_Click(object sender, EventArgs e) 366 { 367 ToolStripMenuItem item = (ToolStripMenuItem)sender; 368 yDim = Int32.Parse(item.Name.Remove(0, 3)); 369 String label = item.Text; 370 this.chooseYDimensionToolStripMenuItem.Text = label; 371 this.chart.ChartAreas[0].AxisY.Title = label; 372 UpdateChart(); 373 } 374 375 private void XMenu_Click(object sender, EventArgs e) 376 { 377 ToolStripMenuItem item = (ToolStripMenuItem)sender; 378 xDim = Int32.Parse(item.Name.Remove(0, 3)); 379 String label = item.Text; 380 this.chooseDimensionToolStripMenuItem.Text = label; 381 this.chart.ChartAreas[0].AxisX.Title = label; 382 UpdateChart(); 383 } 384 385 private void fillSeries(double[][] qualities, double[][] solutions, Series series) 386 { 387 series.Points.Clear(); 388 if (qualities == null || qualities.Length == 0) return; 389 int jx = xDim - qualities[0].Length; 390 int jy = yDim - qualities[0].Length; 391 if ((jx >= 0 || jy >= 0) && solutions == null) 392 { 393 return; 394 } 395 for (int i = 0; i < qualities.Length; i++) 396 { //Assumtion: Columnwise 397 double[] d = qualities[i]; 398 double[] q = null; 399 if (jx >= 0 || jy >= 0) { q = solutions[i]; } 400 series.Points.AddXY(jx < 0 ? d[xDim] : q[jx], jy < 0 ? d[yDim] : q[jy]); 401 } 402 } 403 404 private void BuildEmptySeries() 405 { 406 407 this.chart.Series.Add(QUALITIES); 408 qualitySeries = this.chart.Series[QUALITIES]; 409 410 this.chart.Series[QUALITIES].LegendText = QUALITIES; 411 this.chart.Series[QUALITIES].ChartType = SeriesChartType.FastPoint; 412 413 this.chart.Series.Add(PARETO_FRONT); 414 paretoSeries = this.chart.Series[PARETO_FRONT]; 415 paretoSeries.Color = Color.FromArgb(100, Color.Orange); 416 this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT; 417 this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint; 418 } 46 419 } 47 48 public MOQualitiesScatterPlotView()49 : base() {50 InitializeComponent();51 52 BuildEmptySeries();53 54 //start with qualities toggled ON55 qualitySeries.Points.AddXY(0, 0);56 57 this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;58 this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged);59 60 //configure axis61 this.chart.CustomizeAllChartAreas();62 this.chart.ChartAreas[0].AxisX.Title = "Objective " + xDim;63 this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;64 this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;65 this.chart.ChartAreas[0].CursorX.Interval = 1;66 this.chart.ChartAreas[0].CursorY.Interval = 1;67 68 this.chart.ChartAreas[0].AxisY.Title = "Objective " + yDim;69 this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;70 this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;71 this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;72 }73 74 protected override void RegisterContentEvents() {75 base.RegisterContentEvents();76 this.chart.GetToolTipText += new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText);77 }78 79 protected override void DeregisterContentEvents() {80 base.DeregisterContentEvents();81 this.chart.GetToolTipText -= new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText);82 }83 84 private void Chart_GetToolTipText(object sender, ToolTipEventArgs e) {85 if (e.HitTestResult.ChartElementType == ChartElementType.LegendItem) {86 if (e.HitTestResult.Series == paretoSeries && (Content.ParetoFront == null || Content.ParetoFront.Length == 0)) {87 e.Text = "No optimal pareto front is available for this problem with this number of objectives";88 }89 if (e.HitTestResult.Series == paretoSeries && (xDim >= Content.Objectives || yDim >= Content.Objectives)) {90 e.Text = "The optimal pareto front can only be displayed in Objective Space";91 }92 }93 94 // Check selected chart element and set tooltip text95 if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) {96 int i = e.HitTestResult.PointIndex;97 StringBuilder toolTippText = new StringBuilder();98 DataPoint qp = e.HitTestResult.Series.Points[i];99 toolTippText.Append("Objective " + xDim + " = " + qp.XValue + "\n");100 toolTippText.Append("Objective " + yDim + " = " + qp.YValues[0]);101 102 Series s = e.HitTestResult.Series;103 if (s.Equals(this.chart.Series[QUALITIES])) {104 double[] dp = Content.Solutions[i];105 toolTippText.Append("\nSolution: {");106 for (int j = 0; j < dp.Length; j++) {107 toolTippText.Append(dp[j]);108 toolTippText.Append(";");109 }110 toolTippText.Remove(toolTippText.Length - 1, 1);111 toolTippText.Append("}");112 e.Text = toolTippText.ToString();113 }114 115 116 }117 }118 119 protected override void OnContentChanged() {120 base.OnContentChanged();121 if (Content == null) return;122 if (objectives != Content.Objectives) {123 AddMenuItems();124 objectives = Content.Objectives;125 }126 if (Content.ParetoFront == null && chart.Series.Contains(paretoSeries)) {127 Series s = this.chart.Series[PARETO_FRONT];128 paretoSeries = null;129 this.chart.Series.Remove(s);130 131 } else if (Content.ParetoFront != null && !chart.Series.Contains(paretoSeries)) {132 this.chart.Series.Add(PARETO_FRONT);133 paretoSeries = this.chart.Series[PARETO_FRONT];134 this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;135 this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;136 }137 UpdateChart();138 }139 140 private void UpdateChart() {141 if (InvokeRequired) Invoke((Action)UpdateChart);142 else {143 if (Content != null) {144 this.UpdateSeries();145 if (!this.chart.Series.Any(s => s.Points.Count > 0))146 this.ClearChart();147 }148 }149 }150 151 private void UpdateCursorInterval() {152 var estimatedValues = this.chart.Series[QUALITIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);153 var targetValues = this.chart.Series[QUALITIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);154 double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();155 double targetValuesRange = targetValues.Max() - targetValues.Min();156 double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));157 double digits = (int)Math.Log10(interestingValuesRange) - 3;158 double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);159 this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;160 this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;161 162 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval;163 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval;164 165 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;166 this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval;167 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;168 this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval;169 170 if (digits < 0) {171 this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits);172 this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits);173 } else {174 this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0";175 this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";176 }177 }178 179 private void UpdateSeries() {180 if (InvokeRequired) Invoke((Action)UpdateSeries);181 else {182 183 if (this.chart.Series.Contains(qualitySeries) && qualitySeries.Points.Count() != 0) {184 fillSeries(Content.Qualities, Content.Solutions, qualitySeries);185 }186 if (this.chart.Series.Contains(paretoSeries) && paretoSeries.Points.Count() != 0) {187 fillSeries(Content.ParetoFront, null, paretoSeries);188 }189 190 191 double minX = Double.MaxValue;192 double maxX = Double.MinValue;193 double minY = Double.MaxValue;194 double maxY = Double.MinValue;195 foreach (Series s in this.chart.Series) {196 if (s.Points.Count == 0) continue;197 minX = Math.Min(minX, s.Points.Select(p => p.XValue).Min());198 maxX = Math.Max(maxX, s.Points.Select(p => p.XValue).Max());199 minY = Math.Min(minY, s.Points.Select(p => p.YValues.Min()).Min());200 maxY = Math.Max(maxY, s.Points.Select(p => p.YValues.Max()).Max());201 }202 203 maxX = maxX + 0.2 * Math.Abs(maxX);204 minX = minX - 0.2 * Math.Abs(minX);205 maxY = maxY + 0.2 * Math.Abs(maxY);206 minY = minY - 0.2 * Math.Abs(minY);207 208 double interestingValuesRangeX = maxX - minX;209 double interestingValuesRangeY = maxY - minY;210 211 int digitsX = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeX));212 int digitsY = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeY));213 214 215 maxX = Math.Round(maxX, digitsX);216 minX = Math.Round(minX, digitsX);217 maxY = Math.Round(maxY, digitsY);218 minY = Math.Round(minY, digitsY);219 if (minX > maxX) {220 minX = 0;221 maxX = 1;222 }223 if (minY > maxY) {224 minY = 0;225 maxY = 1;226 }227 228 229 this.chart.ChartAreas[0].AxisX.Maximum = maxX;230 this.chart.ChartAreas[0].AxisX.Minimum = minX;231 this.chart.ChartAreas[0].AxisY.Maximum = maxY;232 this.chart.ChartAreas[0].AxisY.Minimum = minY;233 UpdateCursorInterval();234 }235 }236 237 private void ClearChart() {238 if (chart.Series.Contains(qualitySeries)) chart.Series.Remove(qualitySeries);239 if (chart.Series.Contains(paretoSeries)) chart.Series.Remove(paretoSeries);240 BuildEmptySeries();241 }242 243 private void ToggleSeriesData(Series series) {244 if (series.Points.Count > 0) { //checks if series is shown245 series.Points.Clear();246 } else if (Content != null) {247 switch (series.Name) {248 case PARETO_FRONT:249 fillSeries(Content.ParetoFront, null, this.chart.Series[PARETO_FRONT]);250 break;251 case QUALITIES:252 fillSeries(Content.Qualities, Content.Solutions, this.chart.Series[QUALITIES]);253 break;254 }255 }256 }257 258 private void chart_MouseDown(object sender, MouseEventArgs e) {259 HitTestResult result = chart.HitTest(e.X, e.Y);260 if (result.ChartElementType == ChartElementType.LegendItem) {261 this.ToggleSeriesData(result.Series);262 }263 264 }265 266 private void chart_MouseMove(object sender, MouseEventArgs e) {267 HitTestResult result = chart.HitTest(e.X, e.Y);268 if (result.ChartElementType == ChartElementType.LegendItem)269 this.Cursor = Cursors.Hand;270 else271 this.Cursor = Cursors.Default;272 }273 274 private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {275 this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;276 this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;277 }278 279 private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {280 if (this.chart.Series.Contains(qualitySeries)) e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[QUALITIES].Points.Count == 0 ? Color.Gray : Color.Black;281 if (this.chart.Series.Contains(paretoSeries)) e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[PARETO_FRONT].Points.Count == 0 ? Color.Gray : Color.Black;282 }283 284 private void AddMenuItems() {285 chooseDimensionToolStripMenuItem.DropDownItems.Clear();286 chooseYDimensionToolStripMenuItem.DropDownItems.Clear();287 if (Content == null) { return; }288 int i = 0;289 for (; i < Content.Objectives; i++) {290 //add Menu Points291 ToolStripMenuItem xItem = makeMenuItem("X", "Objective " + i, i);292 ToolStripMenuItem yItem = makeMenuItem("Y", "Objective " + i, i);293 xItem.Click += new System.EventHandler(this.XMenu_Click);294 yItem.Click += new System.EventHandler(this.YMenu_Click);295 chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);296 chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);297 }298 299 for (; i < Content.Solutions[0].Length + Content.Objectives; i++) {300 ToolStripMenuItem xItem = makeMenuItem("X", "ProblemDimension " + (i - Content.Objectives), i);301 ToolStripMenuItem yItem = makeMenuItem("Y", "ProblemDimension " + (i - Content.Objectives), i); ;302 xItem.Click += new System.EventHandler(this.XMenu_Click);303 yItem.Click += new System.EventHandler(this.YMenu_Click);304 chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);305 chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);306 }307 }308 309 private ToolStripMenuItem makeMenuItem(String axis, String label, int i) {310 ToolStripMenuItem xItem = new ToolStripMenuItem();311 xItem.Name = "obj" + i;312 xItem.Size = new System.Drawing.Size(269, 38);313 xItem.Text = label;314 return xItem;315 }316 317 private void YMenu_Click(object sender, EventArgs e) {318 ToolStripMenuItem item = (ToolStripMenuItem)sender;319 yDim = Int32.Parse(item.Name.Remove(0, 3));320 String label = item.Text;321 this.chooseYDimensionToolStripMenuItem.Text = label;322 this.chart.ChartAreas[0].AxisY.Title = label;323 UpdateChart();324 }325 326 private void XMenu_Click(object sender, EventArgs e) {327 ToolStripMenuItem item = (ToolStripMenuItem)sender;328 xDim = Int32.Parse(item.Name.Remove(0, 3));329 String label = item.Text;330 this.chooseDimensionToolStripMenuItem.Text = label;331 this.chart.ChartAreas[0].AxisX.Title = label;332 UpdateChart();333 }334 335 private void fillSeries(double[][] qualities, double[][] solutions, Series series) {336 series.Points.Clear();337 if (qualities == null || qualities.Length == 0) return;338 int jx = xDim - qualities[0].Length;339 int jy = yDim - qualities[0].Length;340 if ((jx >= 0 || jy >= 0) && solutions == null) {341 return;342 }343 for (int i = 0; i < qualities.Length; i++) { //Assumtion: Columnwise344 double[] d = qualities[i];345 double[] q = null;346 if (jx >= 0 || jy >= 0) { q = solutions[i]; }347 series.Points.AddXY(jx < 0 ? d[xDim] : q[jx], jy < 0 ? d[yDim] : q[jy]);348 }349 }350 351 private void BuildEmptySeries() {352 this.chart.Series.Add(QUALITIES);353 qualitySeries = this.chart.Series[QUALITIES];354 this.chart.Series[QUALITIES].LegendText = QUALITIES;355 this.chart.Series[QUALITIES].ChartType = SeriesChartType.FastPoint;356 357 this.chart.Series.Add(PARETO_FRONT);358 paretoSeries = this.chart.Series[PARETO_FRONT];359 this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;360 this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;361 }362 }363 420 } 364 421
Note: See TracChangeset
for help on using the changeset viewer.