Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Analysis.Views/3.3/ParetoFrontScatterPlotView.cs @ 17229

Last change on this file since 17229 was 17229, checked in by abeham, 4 years ago

#2521: Refactored ParetoFrontScatterPlot (moved from TestFunctions.MultiObjective to Analysis)

  • Introduced generic type that may work with all solution encodings
File size: 6.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Linq;
24using HeuristicLab.Common;
25using HeuristicLab.Core.Views;
26using HeuristicLab.MainForm;
27
28namespace HeuristicLab.Analysis.Views {
29  [View("Scatter Plot")]
30#pragma warning disable CS0618 // Type or member is obsolete
31  [Content(typeof(ParetoFrontScatterPlot))]
32#pragma warning restore CS0618 // Type or member is obsolete
33  public partial class ParetoFrontScatterPlotView : ItemView {
34
35    private readonly ScatterPlot scatterPlot;
36    private readonly ScatterPlotDataRow qualitiesRow;
37    private readonly ScatterPlotDataRow paretoFrontRow;
38
39    private int oldObjectives = -1;
40    private int oldProblemSize = -1;
41
42    private bool suppressEvents;
43
44#pragma warning disable CS0618 // Type or member is obsolete
45    public new ParetoFrontScatterPlot Content {
46      get { return (ParetoFrontScatterPlot)base.Content; }
47      set { base.Content = value; }
48    }
49#pragma warning restore CS0618 // Type or member is obsolete
50
51    public ParetoFrontScatterPlotView() {
52      InitializeComponent();
53
54      scatterPlot = new ScatterPlot();
55
56      qualitiesRow = new ScatterPlotDataRow("Qualities", string.Empty, Enumerable.Empty<Point2D<double>>()) {
57        VisualProperties = {
58          PointSize = 8 ,
59          PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle
60        }
61      };
62      scatterPlot.Rows.Add(qualitiesRow);
63
64      paretoFrontRow = new ScatterPlotDataRow("Best Known Pareto Front", string.Empty, Enumerable.Empty<Point2D<double>>()) {
65        VisualProperties = {
66            PointSize = 4,
67            PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square
68          }
69      };
70      scatterPlot.Rows.Add(paretoFrontRow);
71    }
72
73    protected override void OnContentChanged() {
74      base.OnContentChanged();
75
76      if (Content == null) {
77        scatterPlotView.Content = null;
78        xAxisComboBox.Items.Clear();
79        xAxisComboBox.SelectedIndex = -1;
80        yAxisComboBox.Items.Clear();
81        yAxisComboBox.SelectedIndex = -1;
82        return;
83      }
84
85      scatterPlotView.Content = scatterPlot;
86
87      if (oldObjectives != Content.Objectives || oldProblemSize != Content.ProblemSize)
88        UpdateAxisComboBoxes();
89
90      UpdateChartData();
91
92      oldObjectives = Content.Objectives;
93      oldProblemSize = Content.ProblemSize;
94    }
95
96    private void UpdateChartData() {
97      if (InvokeRequired) {
98        Invoke((Action)UpdateChartData);
99        return;
100      }
101
102      int xDimGlobal = xAxisComboBox.SelectedIndex;
103      int yDimGlobal = yAxisComboBox.SelectedIndex;
104
105      qualitiesRow.Points.Replace(CreatePoints(Content.Qualities, Content.Solutions, xDimGlobal, yDimGlobal));
106
107      paretoFrontRow.Points.Replace(CreatePoints(Content.ParetoFront, null, xDimGlobal, yDimGlobal));
108      paretoFrontRow.VisualProperties.IsVisibleInLegend = paretoFrontRow.Points.Count > 0; // hide if empty
109    }
110
111    private void UpdateAxisComboBoxes() {
112      try {
113        suppressEvents = true;
114
115        string prevSelectedX = (string)xAxisComboBox.SelectedItem;
116        string prevSelectedY = (string)yAxisComboBox.SelectedItem;
117
118        xAxisComboBox.Items.Clear();
119        yAxisComboBox.Items.Clear();
120
121        // Add Objectives first
122        for (int i = 0; i < Content.Objectives; i++) {
123          xAxisComboBox.Items.Add("Objective " + i);
124          yAxisComboBox.Items.Add("Objective " + i);
125        }
126
127        // Add Problem Dimension
128        for (int i = 0; i < Content.ProblemSize; i++) {
129          xAxisComboBox.Items.Add("Problem Dimension " + i);
130          yAxisComboBox.Items.Add("Problem Dimension " + i);
131        }
132
133        // Selection
134        int count = xAxisComboBox.Items.Count;
135        if (count > 0) {
136          if (prevSelectedX != null && xAxisComboBox.Items.Contains(prevSelectedX))
137            xAxisComboBox.SelectedItem = prevSelectedX;
138          else xAxisComboBox.SelectedIndex = 0;
139
140          if (prevSelectedY != null && yAxisComboBox.Items.Contains(prevSelectedY))
141            yAxisComboBox.SelectedItem = prevSelectedY;
142          else yAxisComboBox.SelectedIndex = Math.Min(1, count - 1);
143        } else {
144          xAxisComboBox.SelectedIndex = -1;
145          yAxisComboBox.SelectedIndex = -1;
146        }
147
148        UpdateAxisDescription();
149      } finally {
150        suppressEvents = false;
151      }
152    }
153
154    private void UpdateAxisDescription() {
155      scatterPlot.VisualProperties.XAxisTitle = (string)xAxisComboBox.SelectedItem;
156      scatterPlot.VisualProperties.YAxisTitle = (string)yAxisComboBox.SelectedItem;
157    }
158
159    private static Point2D<double>[] CreatePoints(double[][] qualities, double[][] solutions, int xDimGlobal, int yDimGlobal) {
160      if (qualities == null || qualities.Length == 0) return new Point2D<double>[0];
161
162      int objectives = qualities[0].Length;
163
164      // "Global" dimension index describes the index as if the qualities and solutions would be in a single array
165      // If the global dimension index is too long for the qualities, use solutions
166      var xDimArray = xDimGlobal < objectives ? qualities : solutions;
167      var yDimArray = yDimGlobal < objectives ? qualities : solutions;
168      var xDimIndex = xDimGlobal < objectives ? xDimGlobal : xDimGlobal - objectives;
169      var yDimIndex = yDimGlobal < objectives ? yDimGlobal : yDimGlobal - objectives;
170
171      if (xDimArray == null || yDimArray == null)
172        return new Point2D<double>[0];
173
174      var points = new Point2D<double>[xDimArray.Length];
175      for (int i = 0; i < xDimArray.Length; i++) {
176        points[i] = new Point2D<double>(xDimArray[i][xDimIndex], yDimArray[i][yDimIndex]);
177      }
178      return points;
179    }
180
181    #region Event Handler
182    private void axisComboBox_SelectedIndexChanged(object sender, EventArgs e) {
183      if (suppressEvents) return;
184      UpdateAxisDescription();
185      UpdateChartData();
186    }
187    #endregion
188  }
189}
Note: See TracBrowser for help on using the repository browser.