Index: /trunk/sources/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 15202)
+++ /trunk/sources/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 15203)
@@ -245,6 +245,6 @@
       set { Results[CurrentFrontResultName].Value = value; }
     }
-    private ScatterPlotContent ResultsScatterPlot {
-      get { return (ScatterPlotContent)Results[ScatterPlotResultName].Value; }
+    private ParetoFrontScatterPlot ResultsScatterPlot {
+      get { return (ParetoFrontScatterPlot)Results[ScatterPlotResultName].Value; }
       set { Results[ScatterPlotResultName].Value = value; }
     }
@@ -353,5 +353,5 @@
       Results.Add(new Result(TimetableResultName, "Different quality meassures in a timeseries", table));
       Results.Add(new Result(CurrentFrontResultName, "The current front", new DoubleMatrix()));
-      Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ScatterPlotContent(null, null, null, 2)));
+      Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
 
       var problem = Problem as MultiObjectiveTestFunctionProblem;
@@ -361,5 +361,5 @@
         ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
       }
-      ResultsScatterPlot = new ScatterPlotContent(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), problem.Objectives);
+      ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), problem.Objectives, problem.ProblemSize);
     }
     #endregion
@@ -470,5 +470,5 @@
 
     private void Analyze() {
-      ResultsScatterPlot = new ScatterPlotContent(solutions.Select(x => x.Fitness).ToArray(), solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives);
+      ResultsScatterPlot = new ParetoFrontScatterPlot(solutions.Select(x => x.Fitness).ToArray(), solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
       ResultsSolutions = solutions.Select(x => x.Mean.ToArray()).ToMatrix();
 
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 15202)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 15203)
@@ -37,6 +37,6 @@
     }
 
-    public IResultParameter<ScatterPlotContent> ScatterPlotResultParameter {
-      get { return (IResultParameter<ScatterPlotContent>)Parameters["Scatterplot"]; }
+    public IResultParameter<ParetoFrontScatterPlot> ScatterPlotResultParameter {
+      get { return (IResultParameter<ParetoFrontScatterPlot>)Parameters["Scatterplot"]; }
     }
 
@@ -51,5 +51,5 @@
     public ScatterPlotAnalyzer() {
       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("Individuals", "The individual solutions to the problem"));
-      Parameters.Add(new ResultParameter<ScatterPlotContent>("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
+      Parameters.Add(new ResultParameter<ParetoFrontScatterPlot>("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
 
     }
@@ -57,7 +57,8 @@
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
+      var individuals = IndividualsParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
       int objectives = qualities[0].Length;
-      var individuals = IndividualsParameter.ActualValue;
+      int problemSize = individuals[0].Length;
 
       double[][] optimalFront = new double[0][];
@@ -68,5 +69,5 @@
       var solutionClones = individuals.Select(s => s.ToArray()).ToArray();
 
-      ScatterPlotResultParameter.ActualValue = new ScatterPlotContent(qualityClones, solutionClones, optimalFront, objectives);
+      ScatterPlotResultParameter.ActualValue = new ParetoFrontScatterPlot(qualityClones, solutionClones, optimalFront, objectives, problemSize);
 
       return base.Apply();
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 15202)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 15203)
@@ -111,5 +111,5 @@
     <Compile Include="Calculators\InvertedGenerationalDistance.cs" />
     <Compile Include="Calculators\GenerationalDistance.cs" />
-    <Compile Include="ScatterPlotContent.cs" />
+    <Compile Include="ParetoFrontScatterPlot.cs" />
     <Compile Include="Utilities.cs" />
     <Compile Include="Instances\MISCInstanceProvider.cs" />
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs	(revision 15203)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs	(revision 15203)
@@ -0,0 +1,89 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
+  [StorableClass]
+  [Item("Pareto Front Scatter Plot", "The optimal front, current front and its associated Points in the searchspace")]
+  public class ParetoFrontScatterPlot : Item {
+
+    [Storable]
+    private int objectives;
+    public int Objectives {
+      get { return objectives; }
+    }
+
+    [Storable]
+    private int problemSize;
+    public int ProblemSize {
+      get { return problemSize; }
+    }
+
+    [Storable]
+    private double[][] qualities;
+    public double[][] Qualities {
+      get { return qualities; }
+    }
+
+    [Storable]
+    private double[][] solutions;
+    public double[][] Solutions {
+      get { return solutions; }
+    }
+
+    [Storable]
+    private double[][] paretoFront;
+    public double[][] ParetoFront {
+      get { return paretoFront; }
+    }
+
+    #region Constructor, Cloning & Persistance
+    public ParetoFrontScatterPlot(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives, int problemSize) {
+      this.qualities = qualities;
+      this.solutions = solutions;
+      this.paretoFront = paretoFront;
+      this.objectives = objectives;
+      this.problemSize = problemSize;
+    }
+    public ParetoFrontScatterPlot() { }
+
+    protected ParetoFrontScatterPlot(ParetoFrontScatterPlot original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.qualities != null) qualities = original.qualities.Select(s => s.ToArray()).ToArray();
+      if (original.solutions != null) solutions = original.solutions.Select(s => s.ToArray()).ToArray();
+      if (original.paretoFront != null) paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
+      objectives = original.objectives;
+      problemSize = original.problemSize;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParetoFrontScatterPlot(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ParetoFrontScatterPlot(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+  }
+}
Index: unk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs	(revision 15202)
+++ 	(revision )
@@ -1,101 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
-  [StorableClass]
-  [Item("ScatterPlot", "The optimal front, current front and its associated Points in the searchspace")]
-  public class ScatterPlotContent : Item {
-
-    [Storable]
-    private double[][] qualities;
-    public double[][] Qualities {
-      get {
-        return qualities;
-      }
-
-      private set {
-        qualities = value;
-      }
-    }
-
-    [Storable]
-    private int objectives;
-    public int Objectives {
-      get {
-        return objectives;
-      }
-
-      private set {
-        objectives = value;
-      }
-    }
-
-    [Storable]
-    private double[][] solutions;
-    public double[][] Solutions {
-      get {
-        return solutions;
-      }
-
-      private set {
-        solutions = value;
-      }
-    }
-
-    [Storable]
-    private double[][] paretoFront;
-    public double[][] ParetoFront {
-      get {
-        return paretoFront;
-      }
-
-      private set {
-        paretoFront = value;
-      }
-    }
-
-    [StorableConstructor]
-    protected ScatterPlotContent(bool deserializing) : base() { }
-
-    protected ScatterPlotContent(ScatterPlotContent original, Cloner cloner)
-      : this() {
-      this.qualities = original.qualities.Select(s => s.ToArray()).ToArray();
-      this.solutions = original.solutions.Select(s => s.ToArray()).ToArray();
-      this.paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
-      this.objectives = original.objectives;
-    }
-    protected ScatterPlotContent() : base() { }
-    public ScatterPlotContent(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives) {
-      this.qualities = qualities;
-      this.solutions = solutions;
-      this.paretoFront = paretoFront;
-      this.objectives = objectives;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ScatterPlotContent(this, cloner);
-    }
-  }
-}
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj	(revision 15202)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj	(revision 15203)
@@ -105,20 +105,11 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Windows.Forms.DataVisualization" />
-    <Reference Include="System.Xml.Linq">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data.DataSetExtensions">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs">
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ParetoFrontScatterPlotView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs">
-      <DependentUpon>MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs</DependentUpon>
+    <Compile Include="ParetoFrontScatterPlotView.Designer.cs">
+      <DependentUpon>ParetoFrontScatterPlotView.cs</DependentUpon>
     </Compile>
     <Compile Include="Plugin.cs" />
@@ -143,4 +134,14 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
+      <Project>{76945d76-ca61-4147-9dc2-0acdcddf87f9}</Project>
+      <Name>HeuristicLab.Analysis.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
@@ -211,9 +212,4 @@
       <Project>{88B9B0E3-344E-4196-82A3-0F9732506FE8}</Project>
       <Name>HeuristicLab.Problems.TestFunctions-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
-      <Project>{315bda09-3f4f-49b3-9790-b37cfc1c5750}</Project>
-      <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: unk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs	(revision 15202)
+++ 	(revision )
@@ -1,137 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-namespace HeuristicLab.Problems.TestFunctions.Views {
-  partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      this.components = new System.ComponentModel.Container();
-      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
-      this.menuStrip1 = new System.Windows.Forms.MenuStrip();
-      this.chooseDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      this.chooseYDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      this.testToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
-      this.menuStrip1.SuspendLayout();
-      this.SuspendLayout();
-      // 
-      // chart
-      // 
-      chartArea2.Name = "ChartArea";
-      this.chart.ChartAreas.Add(chartArea2);
-      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
-      legend2.Alignment = System.Drawing.StringAlignment.Center;
-      legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend2.Name = "Default";
-      this.chart.Legends.Add(legend2);
-      this.chart.Location = new System.Drawing.Point(0, 42);
-      this.chart.Margin = new System.Windows.Forms.Padding(6);
-      this.chart.Name = "chart";
-      this.chart.Size = new System.Drawing.Size(1054, 712);
-      this.chart.TabIndex = 1;
-      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
-      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
-      // 
-      // menuStrip1
-      // 
-      this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
-      this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.chooseDimensionToolStripMenuItem,
-            this.chooseYDimensionToolStripMenuItem});
-      this.menuStrip1.Location = new System.Drawing.Point(0, 0);
-      this.menuStrip1.Name = "menuStrip1";
-      this.menuStrip1.Size = new System.Drawing.Size(1054, 42);
-      this.menuStrip1.TabIndex = 2;
-      this.menuStrip1.Text = "menuStrip1";
-      this.menuStrip1.ShowItemToolTips = true;
-      // 
-      // chooseDimensionToolStripMenuItem
-      // 
-      this.chooseDimensionToolStripMenuItem.Name = "chooseDimensionToolStripMenuItem";
-      this.chooseDimensionToolStripMenuItem.Size = new System.Drawing.Size(253, 38);
-      this.chooseDimensionToolStripMenuItem.Text = "Objective 0";
-      this.chooseDimensionToolStripMenuItem.ToolTipText = "Choose X-Dimension";
-      // 
-      // chooseYDimensionToolStripMenuItem
-      // 
-      this.chooseYDimensionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.testToolStripMenuItem});
-      this.chooseYDimensionToolStripMenuItem.Name = "chooseYDimensionToolStripMenuItem";
-      this.chooseYDimensionToolStripMenuItem.Size = new System.Drawing.Size(252, 38);
-      this.chooseYDimensionToolStripMenuItem.Text = "Objective 1";
-      this.chooseYDimensionToolStripMenuItem.ToolTipText = "Choose Y-Dimension";
-      // 
-      // testToolStripMenuItem
-      // 
-      this.testToolStripMenuItem.Name = "testToolStripMenuItem";
-      this.testToolStripMenuItem.Size = new System.Drawing.Size(269, 38);
-      this.testToolStripMenuItem.Text = "Test";
-      // 
-      // MOQualitiesScatterPlotView
-      // 
-      this.AllowDrop = true;
-      this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
-      this.Controls.Add(this.chart);
-      this.Controls.Add(this.menuStrip1);
-      this.Margin = new System.Windows.Forms.Padding(6);
-      this.Name = "MOQualitiesScatterPlotView";
-      this.Size = new System.Drawing.Size(1054, 754);
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
-      this.menuStrip1.ResumeLayout(false);
-      this.menuStrip1.PerformLayout();
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-
-    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
-    private System.Windows.Forms.MenuStrip menuStrip1;
-    private System.Windows.Forms.ToolStripMenuItem chooseDimensionToolStripMenuItem;
-    private System.Windows.Forms.ToolStripMenuItem chooseYDimensionToolStripMenuItem;
-    private System.Windows.Forms.ToolStripMenuItem testToolStripMenuItem;
-  }
-}
Index: unk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs	(revision 15202)
+++ 	(revision )
@@ -1,359 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-using System;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
-using HeuristicLab.MainForm;
-using HeuristicLab.Problems.TestFunctions.MultiObjective;
-
-namespace HeuristicLab.Problems.TestFunctions.Views {
-  [View("Scatter Plot")]
-  [Content(typeof(ScatterPlotContent))]
-  public partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView : ItemView {
-    private const string QUALITIES = "Qualities";
-    private const string PARETO_FRONT = "Best Known Pareto Front";
-    private Series qualitySeries;
-    private Series paretoSeries;
-    private int xDim = 0;
-    private int yDim = 1;
-    int objectives = -1;
-
-    public new ScatterPlotContent Content {
-      get { return (ScatterPlotContent)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public MultiObjectiveTestFunctionParetoFrontScatterPlotView()
-      : base() {
-      InitializeComponent();
-
-      BuildEmptySeries();
-
-      //start with qualities toggled ON
-      qualitySeries.Points.AddXY(0, 0);
-
-      this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
-      this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged);
-      this.chart.GetToolTipText += new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText);
-
-      //configure axis 
-      this.chart.CustomizeAllChartAreas();
-      this.chart.ChartAreas[0].AxisX.Title = "Objective " + xDim;
-      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].CursorX.Interval = 1;
-      this.chart.ChartAreas[0].CursorY.Interval = 1;
-
-      this.chart.ChartAreas[0].AxisY.Title = "Objective " + yDim;
-      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
-    }
-
-
-    private void Chart_GetToolTipText(object sender, ToolTipEventArgs e) {
-      if (e.HitTestResult.ChartElementType == ChartElementType.LegendItem) {
-        if (e.HitTestResult.Series == paretoSeries && (Content.ParetoFront == null || Content.ParetoFront.Length == 0)) {
-          e.Text = "No optimal pareto front is available for this problem with this number of objectives";
-        }
-        if (e.HitTestResult.Series == paretoSeries && (xDim >= Content.Objectives || yDim >= Content.Objectives)) {
-          e.Text = "The optimal pareto front can only be displayed in  Objective Space";
-        }
-      }
-
-      // Check selected chart element and set tooltip text
-      if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) {
-        int i = e.HitTestResult.PointIndex;
-        StringBuilder toolTippText = new StringBuilder();
-        DataPoint qp = e.HitTestResult.Series.Points[i];
-        toolTippText.Append("Objective " + xDim + " = " + qp.XValue + "\n");
-        toolTippText.Append("Objective " + yDim + " = " + qp.YValues[0]);
-
-        Series s = e.HitTestResult.Series;
-        if (s.Equals(this.chart.Series[QUALITIES])) {
-          double[] dp = Content.Solutions[i];
-          toolTippText.Append("\nSolution: {");
-          for (int j = 0; j < dp.Length; j++) {
-            toolTippText.Append(dp[j]);
-            toolTippText.Append(";");
-          }
-          toolTippText.Remove(toolTippText.Length - 1, 1);
-          toolTippText.Append("}");
-          e.Text = toolTippText.ToString();
-        }
-
-
-      }
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content == null) return;
-      if (objectives != Content.Objectives) {
-        AddMenuItems();
-        objectives = Content.Objectives;
-      }
-      if (Content.ParetoFront == null && chart.Series.Contains(paretoSeries)) {
-        Series s = this.chart.Series[PARETO_FRONT];
-        paretoSeries = null;
-        this.chart.Series.Remove(s);
-
-      } else if (Content.ParetoFront != null && !chart.Series.Contains(paretoSeries)) {
-        this.chart.Series.Add(PARETO_FRONT);
-        paretoSeries = this.chart.Series[PARETO_FRONT];
-        this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
-        this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
-      }
-      UpdateChart();
-    }
-
-    private void UpdateChart() {
-      if (InvokeRequired) Invoke((Action)UpdateChart);
-      else {
-        if (Content != null) {
-          this.UpdateSeries();
-          if (!this.chart.Series.Any(s => s.Points.Count > 0))
-            this.ClearChart();
-        }
-      }
-    }
-
-    private void UpdateCursorInterval() {
-      var estimatedValues = this.chart.Series[QUALITIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);
-      var targetValues = this.chart.Series[QUALITIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
-      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
-      double targetValuesRange = targetValues.Max() - targetValues.Min();
-      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
-      double digits = (int)Math.Log10(interestingValuesRange) - 3;
-      double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
-      this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;
-      this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;
-
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval;
-
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval;
-
-      if (digits < 0) {
-        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits);
-        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits);
-      } else {
-        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0";
-        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";
-      }
-    }
-
-    private void UpdateSeries() {
-      if (InvokeRequired) Invoke((Action)UpdateSeries);
-      else {
-
-        if (this.chart.Series.Contains(qualitySeries) && qualitySeries.Points.Count() != 0) {
-          FillSeries(Content.Qualities, Content.Solutions, qualitySeries);
-        }
-        if (this.chart.Series.Contains(paretoSeries) && paretoSeries.Points.Count() != 0) {
-          FillSeries(Content.ParetoFront, null, paretoSeries);
-        }
-
-
-        double minX = Double.MaxValue;
-        double maxX = Double.MinValue;
-        double minY = Double.MaxValue;
-        double maxY = Double.MinValue;
-        foreach (Series s in this.chart.Series) {
-          if (s.Points.Count == 0) continue;
-          minX = Math.Min(minX, s.Points.Select(p => p.XValue).Min());
-          maxX = Math.Max(maxX, s.Points.Select(p => p.XValue).Max());
-          minY = Math.Min(minY, s.Points.Select(p => p.YValues.Min()).Min());
-          maxY = Math.Max(maxY, s.Points.Select(p => p.YValues.Max()).Max());
-        }
-
-        maxX = maxX + 0.2 * Math.Abs(maxX);
-        minX = minX - 0.2 * Math.Abs(minX);
-        maxY = maxY + 0.2 * Math.Abs(maxY);
-        minY = minY - 0.2 * Math.Abs(minY);
-
-        double interestingValuesRangeX = maxX - minX;
-        double interestingValuesRangeY = maxY - minY;
-
-        int digitsX = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeX));
-        int digitsY = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeY));
-
-
-        maxX = Math.Round(maxX, digitsX);
-        minX = Math.Round(minX, digitsX);
-        maxY = Math.Round(maxY, digitsY);
-        minY = Math.Round(minY, digitsY);
-        if (minX > maxX) {
-          minX = 0;
-          maxX = 1;
-        }
-        if (minY > maxY) {
-          minY = 0;
-          maxY = 1;
-        }
-
-
-        this.chart.ChartAreas[0].AxisX.Maximum = maxX;
-        this.chart.ChartAreas[0].AxisX.Minimum = minX;
-        this.chart.ChartAreas[0].AxisY.Maximum = maxY;
-        this.chart.ChartAreas[0].AxisY.Minimum = minY;
-        UpdateCursorInterval();
-      }
-    }
-
-    private void ClearChart() {
-      if (chart.Series.Contains(qualitySeries)) chart.Series.Remove(qualitySeries);
-      if (chart.Series.Contains(paretoSeries)) chart.Series.Remove(paretoSeries);
-      BuildEmptySeries();
-    }
-
-    private void ToggleSeriesData(Series series) {
-      if (series.Points.Count > 0) {  //checks if series is shown
-        series.Points.Clear();
-      } else if (Content != null) {
-        switch (series.Name) {
-          case PARETO_FRONT:
-            FillSeries(Content.ParetoFront, null, this.chart.Series[PARETO_FRONT]);
-            break;
-          case QUALITIES:
-            FillSeries(Content.Qualities, Content.Solutions, this.chart.Series[QUALITIES]);
-            break;
-        }
-      }
-    }
-
-    private void chart_MouseDown(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem) {
-        this.ToggleSeriesData(result.Series);
-      }
-
-    }
-
-    private void chart_MouseMove(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem)
-        this.Cursor = Cursors.Hand;
-      else
-        this.Cursor = Cursors.Default;
-    }
-
-    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
-      this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;
-    }
-
-    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
-      if (this.chart.Series.Contains(qualitySeries)) e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[QUALITIES].Points.Count == 0 ? Color.Gray : Color.Black;
-      if (this.chart.Series.Contains(paretoSeries)) e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[PARETO_FRONT].Points.Count == 0 ? Color.Gray : Color.Black;
-    }
-
-    private void AddMenuItems() {
-      chooseDimensionToolStripMenuItem.DropDownItems.Clear();
-      chooseYDimensionToolStripMenuItem.DropDownItems.Clear();
-      if (Content == null) { return; }
-      int i = 0;
-      for (; i < Content.Objectives; i++) {
-        //add Menu Points
-        ToolStripMenuItem xItem = MakeMenuItem("X", "Objective " + i, i);
-        ToolStripMenuItem yItem = MakeMenuItem("Y", "Objective " + i, i);
-        xItem.Click += new System.EventHandler(this.XMenu_Click);
-        yItem.Click += new System.EventHandler(this.YMenu_Click);
-        chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
-        chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
-      }
-
-      for (; i < Content.Solutions[0].Length + Content.Objectives; i++) {
-        ToolStripMenuItem xItem = MakeMenuItem("X", "ProblemDimension " + (i - Content.Objectives), i);
-        ToolStripMenuItem yItem = MakeMenuItem("Y", "ProblemDimension " + (i - Content.Objectives), i); ;
-        xItem.Click += new System.EventHandler(this.XMenu_Click);
-        yItem.Click += new System.EventHandler(this.YMenu_Click);
-        chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
-        chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
-      }
-    }
-
-    private ToolStripMenuItem MakeMenuItem(String axis, String label, int i) {
-      ToolStripMenuItem xItem = new ToolStripMenuItem();
-      xItem.Name = "obj" + i;
-      xItem.Size = new System.Drawing.Size(269, 38);
-      xItem.Text = label;
-      return xItem;
-    }
-
-    private void YMenu_Click(object sender, EventArgs e) {
-      ToolStripMenuItem item = (ToolStripMenuItem)sender;
-      yDim = Int32.Parse(item.Name.Remove(0, 3));
-      String label = item.Text;
-      this.chooseYDimensionToolStripMenuItem.Text = label;
-      this.chart.ChartAreas[0].AxisY.Title = label;
-      UpdateChart();
-    }
-
-    private void XMenu_Click(object sender, EventArgs e) {
-      ToolStripMenuItem item = (ToolStripMenuItem)sender;
-      xDim = Int32.Parse(item.Name.Remove(0, 3));
-      String label = item.Text;
-      this.chooseDimensionToolStripMenuItem.Text = label;
-      this.chart.ChartAreas[0].AxisX.Title = label;
-      UpdateChart();
-    }
-
-    private void FillSeries(double[][] qualities, double[][] solutions, Series series) {
-      series.Points.Clear();
-      if (qualities == null || qualities.Length == 0) return;
-      int jx = xDim - qualities[0].Length;
-      int jy = yDim - qualities[0].Length;
-      if ((jx >= 0 || jy >= 0) && solutions == null) {
-        return;
-      }
-      for (int i = 0; i < qualities.Length; i++) {   //Assumtion: Columnwise
-        double[] d = qualities[i];
-        double[] q = null;
-        if (jx >= 0 || jy >= 0) { q = solutions[i]; }
-        series.Points.AddXY(jx < 0 ? d[xDim] : q[jx], jy < 0 ? d[yDim] : q[jy]);
-      }
-    }
-
-    private void BuildEmptySeries() {
-
-      this.chart.Series.Add(QUALITIES);
-      qualitySeries = this.chart.Series[QUALITIES];
-
-      this.chart.Series[QUALITIES].LegendText = QUALITIES;
-      this.chart.Series[QUALITIES].ChartType = SeriesChartType.FastPoint;
-
-      this.chart.Series.Add(PARETO_FRONT);
-      paretoSeries = this.chart.Series[PARETO_FRONT];
-      paretoSeries.Color = Color.FromArgb(100, Color.Orange);
-      this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
-      this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
-    }
-  }
-}
-
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs	(revision 15203)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs	(revision 15203)
@@ -0,0 +1,129 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.TestFunctions.Views {
+  partial class ParetoFrontScatterPlotView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.scatterPlotView = new HeuristicLab.Analysis.Views.ScatterPlotView();
+      this.xAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.yAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.xLabel = new System.Windows.Forms.Label();
+      this.yLabel = new System.Windows.Forms.Label();
+      this.SuspendLayout();
+      // 
+      // scatterPlotView
+      // 
+      this.scatterPlotView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.scatterPlotView.Caption = "ScatterPlot View";
+      this.scatterPlotView.Content = null;
+      this.scatterPlotView.Location = new System.Drawing.Point(3, 37);
+      this.scatterPlotView.Name = "scatterPlotView";
+      this.scatterPlotView.ReadOnly = false;
+      this.scatterPlotView.ShowName = false;
+      this.scatterPlotView.Size = new System.Drawing.Size(615, 342);
+      this.scatterPlotView.TabIndex = 3;
+      // 
+      // xAxisComboBox
+      // 
+      this.xAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.xAxisComboBox.FormattingEnabled = true;
+      this.xAxisComboBox.Location = new System.Drawing.Point(29, 3);
+      this.xAxisComboBox.Name = "xAxisComboBox";
+      this.xAxisComboBox.Size = new System.Drawing.Size(135, 28);
+      this.xAxisComboBox.TabIndex = 4;
+      this.xAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+      // 
+      // yAxisComboBox
+      // 
+      this.yAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.yAxisComboBox.FormattingEnabled = true;
+      this.yAxisComboBox.Location = new System.Drawing.Point(240, 3);
+      this.yAxisComboBox.Name = "yAxisComboBox";
+      this.yAxisComboBox.Size = new System.Drawing.Size(135, 28);
+      this.yAxisComboBox.TabIndex = 5;
+      this.yAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+      // 
+      // xLabel
+      // 
+      this.xLabel.AutoSize = true;
+      this.xLabel.Location = new System.Drawing.Point(3, 6);
+      this.xLabel.Name = "xLabel";
+      this.xLabel.Size = new System.Drawing.Size(20, 20);
+      this.xLabel.TabIndex = 6;
+      this.xLabel.Text = "x:";
+      // 
+      // yLabel
+      // 
+      this.yLabel.AutoSize = true;
+      this.yLabel.Location = new System.Drawing.Point(214, 6);
+      this.yLabel.Name = "yLabel";
+      this.yLabel.Size = new System.Drawing.Size(20, 20);
+      this.yLabel.TabIndex = 7;
+      this.yLabel.Text = "y:";
+      // 
+      // ParetoFrontScatterPlotView
+      // 
+      this.AllowDrop = true;
+      this.Controls.Add(this.yLabel);
+      this.Controls.Add(this.xLabel);
+      this.Controls.Add(this.yAxisComboBox);
+      this.Controls.Add(this.xAxisComboBox);
+      this.Controls.Add(this.scatterPlotView);
+      this.Margin = new System.Windows.Forms.Padding(6);
+      this.Name = "ParetoFrontScatterPlotView";
+      this.Size = new System.Drawing.Size(621, 382);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+    private HeuristicLab.Analysis.Views.ScatterPlotView scatterPlotView;
+    private System.Windows.Forms.ComboBox xAxisComboBox;
+    private System.Windows.Forms.ComboBox yAxisComboBox;
+    private System.Windows.Forms.Label xLabel;
+    private System.Windows.Forms.Label yLabel;
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs	(revision 15203)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs	(revision 15203)
@@ -0,0 +1,187 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+
+namespace HeuristicLab.Problems.TestFunctions.Views {
+  [View("Scatter Plot")]
+  [Content(typeof(ParetoFrontScatterPlot))]
+  public partial class ParetoFrontScatterPlotView : ItemView {
+
+    private readonly ScatterPlot scatterPlot;
+    private readonly ScatterPlotDataRow qualitiesRow;
+    private readonly ScatterPlotDataRow paretoFrontRow;
+
+    private int oldObjectives = -1;
+    private int oldProblemSize = -1;
+
+    private bool suppressEvents;
+
+    public new ParetoFrontScatterPlot Content {
+      get { return (ParetoFrontScatterPlot)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ParetoFrontScatterPlotView() {
+      InitializeComponent();
+
+      scatterPlot = new ScatterPlot();
+
+      qualitiesRow = new ScatterPlotDataRow("Qualities", string.Empty, Enumerable.Empty<Point2D<double>>()) {
+        VisualProperties = {
+          PointSize = 8 ,
+          PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle
+        }
+      };
+      scatterPlot.Rows.Add(qualitiesRow);
+
+      paretoFrontRow = new ScatterPlotDataRow("Best Known Pareto Front", string.Empty, Enumerable.Empty<Point2D<double>>()) {
+        VisualProperties = {
+            PointSize = 4,
+            PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square
+          }
+      };
+      scatterPlot.Rows.Add(paretoFrontRow);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      if (Content == null) {
+        scatterPlotView.Content = null;
+        xAxisComboBox.Items.Clear();
+        xAxisComboBox.SelectedIndex = -1;
+        yAxisComboBox.Items.Clear();
+        yAxisComboBox.SelectedIndex = -1;
+        return;
+      }
+
+      scatterPlotView.Content = scatterPlot;
+
+      if (oldObjectives != Content.Objectives || oldProblemSize != Content.ProblemSize)
+        UpdateAxisComboBoxes();
+
+      UpdateChartData();
+
+      oldObjectives = Content.Objectives;
+      oldProblemSize = Content.ProblemSize;
+    }
+
+    private void UpdateChartData() {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateChartData);
+        return;
+      }
+
+      int xDimGlobal = xAxisComboBox.SelectedIndex;
+      int yDimGlobal = yAxisComboBox.SelectedIndex;
+
+      qualitiesRow.Points.Replace(CreatePoints(Content.Qualities, Content.Solutions, xDimGlobal, yDimGlobal));
+
+      paretoFrontRow.Points.Replace(CreatePoints(Content.ParetoFront, null, xDimGlobal, yDimGlobal));
+      paretoFrontRow.VisualProperties.IsVisibleInLegend = paretoFrontRow.Points.Count > 0; // hide if empty
+    }
+
+    private void UpdateAxisComboBoxes() {
+      try {
+        suppressEvents = true;
+
+        string prevSelectedX = (string)xAxisComboBox.SelectedItem;
+        string prevSelectedY = (string)yAxisComboBox.SelectedItem;
+
+        xAxisComboBox.Items.Clear();
+        yAxisComboBox.Items.Clear();
+
+        // Add Objectives first
+        for (int i = 0; i < Content.Objectives; i++) {
+          xAxisComboBox.Items.Add("Objective " + i);
+          yAxisComboBox.Items.Add("Objective " + i);
+        }
+
+        // Add Problem Dimension
+        for (int i = 0; i < Content.ProblemSize; i++) {
+          xAxisComboBox.Items.Add("Problem Dimension " + i);
+          yAxisComboBox.Items.Add("Problem Dimension " + i);
+        }
+
+        // Selection
+        int count = xAxisComboBox.Items.Count;
+        if (count > 0) {
+          if (prevSelectedX != null && xAxisComboBox.Items.Contains(prevSelectedX))
+            xAxisComboBox.SelectedItem = prevSelectedX;
+          else xAxisComboBox.SelectedIndex = 0;
+
+          if (prevSelectedY != null && yAxisComboBox.Items.Contains(prevSelectedY))
+            yAxisComboBox.SelectedItem = prevSelectedY;
+          else yAxisComboBox.SelectedIndex = Math.Min(1, count - 1);
+        } else {
+          xAxisComboBox.SelectedIndex = -1;
+          yAxisComboBox.SelectedIndex = -1;
+        }
+
+        UpdateAxisDescription();
+      } finally {
+        suppressEvents = false;
+      }
+    }
+
+    private void UpdateAxisDescription() {
+      scatterPlot.VisualProperties.XAxisTitle = (string)xAxisComboBox.SelectedItem;
+      scatterPlot.VisualProperties.YAxisTitle = (string)yAxisComboBox.SelectedItem;
+    }
+
+    private static Point2D<double>[] CreatePoints(double[][] qualities, double[][] solutions, int xDimGlobal, int yDimGlobal) {
+      if (qualities == null || qualities.Length == 0) return new Point2D<double>[0];
+
+      int objectives = qualities[0].Length;
+
+      // "Global" dimension index describes the index as if the qualities and solutions would be in a single array
+      // If the global dimension index is too long for the qualities, use solutions
+      var xDimArray = xDimGlobal < objectives ? qualities : solutions;
+      var yDimArray = yDimGlobal < objectives ? qualities : solutions;
+      var xDimIndex = xDimGlobal < objectives ? xDimGlobal : xDimGlobal - objectives;
+      var yDimIndex = yDimGlobal < objectives ? yDimGlobal : yDimGlobal - objectives;
+
+      if (xDimArray == null || yDimArray == null)
+        return new Point2D<double>[0];
+
+      var points = new Point2D<double>[xDimArray.Length];
+      for (int i = 0; i < xDimArray.Length; i++) {
+        points[i] = new Point2D<double>(xDimArray[i][xDimIndex], yDimArray[i][yDimIndex]);
+      }
+      return points;
+    }
+
+    #region Event Handler
+    private void axisComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (suppressEvents) return;
+      UpdateAxisDescription();
+      UpdateChartData();
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame	(revision 15202)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame	(revision 15203)
@@ -28,4 +28,6 @@
   [Plugin("HeuristicLab.Problems.TestFunctions.Views", "3.3.14.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.TestFunctions.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Analysis.Views", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
@@ -40,5 +42,4 @@
   [PluginDependency("HeuristicLab.Problems.TestFunctions", "3.3")]
   [PluginDependency("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3")]
-  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
   public class HeuristicLabProblemsTestFunctionsViewsPlugin : PluginBase {
   }
