Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.Designer.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.Designer.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.Designer.cs	(revision 13831)
@@ -24,33 +24,60 @@
     /// </summary>
     private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
       System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation();
       System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
-      ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine1 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine2 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
       this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.AllowDrop = true;
+      verticalLineAnnotation1.AllowMoving = true;
+      verticalLineAnnotation1.AxisXName = "ChartArea\\rX";
+      verticalLineAnnotation1.ClipToChartArea = "ChartArea";
+      verticalLineAnnotation1.IsInfinitive = true;
+      verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
+      verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      verticalLineAnnotation1.Name = "VerticalLineAnnotation";
+      verticalLineAnnotation1.YAxisName = "ChartArea1\\rY";
+      this.chart.Annotations.Add(verticalLineAnnotation1);
+      stripLine1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      stripLine2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      chartArea1.AxisX.StripLines.Add(stripLine1);
+      chartArea1.AxisX.StripLines.Add(stripLine2);
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.LegendItemOrder = System.Windows.Forms.DataVisualization.Charting.LegendItemOrder.SameAsSeriesOrder;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.PaletteCustomColors = new System.Drawing.Color[] {
+        System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(180)))), ((int)(((byte)(65))))),
+        System.Drawing.Color.FromArgb(((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))))};
+      this.chart.Size = new System.Drawing.Size(453, 308);
+      this.chart.TabIndex = 0;
+      this.chart.AnnotationPositionChanged += new System.EventHandler(this.chart_AnnotationPositionChanged);
+      this.chart.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
+      this.chart.FormatNumber += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.FormatNumberEventArgs>(this.chart_FormatNumber);
+      this.chart.DragDrop += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragDrop);
+      this.chart.DragEnter += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragEnter);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
       // 
       // GradientChart
       // 
-      this.AllowDrop = true;
-      verticalLineAnnotation1.AllowMoving = true;
-      verticalLineAnnotation1.AxisXName = "ChartArea1\\rX";
-      verticalLineAnnotation1.ClipToChartArea = "ChartArea1";
-      verticalLineAnnotation1.IsInfinitive = true;
-      verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
-      verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
-      verticalLineAnnotation1.Name = "VerticalLineAnnotation1";
-      verticalLineAnnotation1.YAxisName = "ChartArea1\\rY";
-      this.Annotations.Add(verticalLineAnnotation1);
-      chartArea1.Name = "ChartArea1";
-      this.ChartAreas.Add(chartArea1);
-      series1.ChartArea = "ChartArea1";
-      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
-      series1.Name = "Series1";
-      this.Series.Add(series1);
-      this.AnnotationPositionChanged += new System.EventHandler(this.chart_AnnotationPositionChanged);
-      this.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
-      this.DragDrop += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragDrop);
-      this.DragEnter += new System.Windows.Forms.DragEventHandler(this.GradientChart_DragEnter);
-      ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.chart);
+      this.Name = "GradientChart";
+      this.Size = new System.Drawing.Size(453, 308);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
       this.ResumeLayout(false);
 
@@ -58,4 +85,6 @@
 
     #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/GradientChart.cs	(revision 13831)
@@ -22,5 +22,4 @@
 using System;
 using System.Collections.Generic;
-using System.Drawing;
 using System.Globalization;
 using System.Linq;
@@ -31,290 +30,255 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  public partial class GradientChart : EnhancedChart {
-    private ModifiableDataset sharedDataset; // used for syncronising variable values between charts
+  public partial class GradientChart : UserControl {
+    private ModifiableDataset sharedFixedVariables; // used for syncronising variable values between charts
     private ModifiableDataset internalDataset; // used to cache values and speed up calculations
 
-    public bool ShowLegend { get; set; }
-    public bool ShowXAxisLabel { get; set; }
-    public bool ShowYAxisLabel { get; set; }
-    public bool ShowCursor { get; set; }
-
-    private bool useMedianValues;
-    public bool UseMedianValues {
-      get { return useMedianValues; }
+    public bool ShowLegend {
+      get { return chart.Legends[0].Enabled; }
+      set { chart.Legends[0].Enabled = value; }
+    }
+    public bool ShowXAxisLabel {
+      get { return chart.ChartAreas[0].AxisX.Enabled == AxisEnabled.True; }
+      set { chart.ChartAreas[0].AxisX.Enabled = value ? AxisEnabled.True : AxisEnabled.False; }
+    }
+    public bool ShowYAxisLabel {
+      get { return chart.ChartAreas[0].AxisY.Enabled == AxisEnabled.True; }
+      set { chart.ChartAreas[0].AxisY.Enabled = value ? AxisEnabled.True : AxisEnabled.False; }
+    }
+    public bool ShowCursor {
+      get { return chart.Annotations[0].Visible; }
+      set { chart.Annotations[0].Visible = value; }
+    }
+
+    private int xAxisTicks = 5;
+    public int XAxisTicks {
+      get { return xAxisTicks; }
+      set { if (xAxisTicks != value) { xAxisTicks = value; UpdateChart(); } }
+    }
+    private int yAxisTicks = 5;
+    public int YXAxisTicks {
+      get { return yAxisTicks; }
+      set { if (yAxisTicks != value) { yAxisTicks = value; UpdateChart(); } }
+    }
+
+    private double trainingMin = double.MinValue;
+    public double TrainingMin {
+      get { return trainingMin; }
+      set { if (!value.IsAlmost(trainingMin)) { trainingMin = value; UpdateChart(); } }
+    }
+    private double trainingMax = double.MaxValue;
+    public double TrainingMax {
+      get { return trainingMax; }
+      set { if (!value.IsAlmost(trainingMax)) { trainingMax = value; UpdateChart(); } }
+    }
+
+    private int drawingSteps = 1000;
+    public int DrawingSteps {
+      get { return drawingSteps; }
+      set { if (value != drawingSteps) { drawingSteps = value; UpdateChart(); } }
+    }
+
+    private string freeVariable;
+    public string FreeVariable {
+      get { return freeVariable; }
       set {
-        if (value == useMedianValues) return;
-        useMedianValues = value;
-        OnChartPropertyChanged(this, EventArgs.Empty);
+        if (value == freeVariable) return;
+        if (solutions.Any(s => !s.ProblemData.Dataset.DoubleVariables.Contains(value))) {
+          throw new ArgumentException("Variable does not exist in the ProblemData of the Solutions.");
+        }
+        freeVariable = value;
+        RecalculateInternalDataset();
         UpdateChart();
       }
     }
 
-    private int row;
-    public int Row {
-      get { return row; }
-      set {
-        if (row == value) return;
-        row = value;
-        OnChartPropertyChanged(this, EventArgs.Empty);
-        UpdateChart();
-      }
-    }
-
-    private double min;
-    public double Min {
-      get { return min; }
-      set {
-        if (value.IsAlmost(min)) return;
-        min = value;
-        OnChartPropertyChanged(this, EventArgs.Empty);
-        UpdateChart();
-      }
-    }
-
-    private double max;
-    public double Max {
-      get { return max; }
-      set {
-        if (value.IsAlmost(max)) return;
-        max = value;
-        OnChartPropertyChanged(this, EventArgs.Empty);
-        UpdateChart();
-      }
-    }
-
-    private int points;
-    public int Points {
-      get { return points; }
-      set {
-        if (value == points) return;
-        points = value;
-        OnChartPropertyChanged(this, EventArgs.Empty);
-        UpdateChart();
-      }
-    }
-
-    private IRegressionProblemData problemData;
-    public IRegressionProblemData ProblemData {
-      get { return problemData; }
-      set {
-        if (!SolutionsCompatibleWithProblemData(value, solutionList))
-          throw new ArgumentException("The problem data provided does not contain all the variables required by the solutions.");
-        problemData = value;
-        UpdateDataset();
-        UpdateChart();
-      }
-    }
-
-    public string Target {
-      get { return Solutions.First().ProblemData.TargetVariable; }
-    }
-
-    private string variable;
-    public string Variable {
-      get { return variable; }
-      set {
-        if (variable == value) return;
-        if (!ProblemData.Dataset.DoubleVariables.Contains(value))
-          throw new ArgumentException("The variable must be present in the problem dataset.");
-        OnChartPropertyChanged(this, EventArgs.Empty);
-        variable = value;
-        var values = ProblemData.Dataset.GetReadOnlyDoubleValues(variable);
-        min = values.Min();
-        max = values.Max();
-        UpdateChart();
-      }
-    }
-
-    private List<IRegressionSolution> solutionList;
+    private bool updateChartAutomatically = false;
+    public bool UpdateChartAutomatically {
+      get { return updateChartAutomatically; }
+      set { updateChartAutomatically = value; if (updateChartAutomatically) UpdateChart(); }
+    }
+
+    private readonly List<IRegressionSolution> solutions = new List<IRegressionSolution>();
     public IEnumerable<IRegressionSolution> Solutions {
-      get { return solutionList; }
-      set {
-        if (!value.Any())
-          throw new ArgumentException("At least one solution must be provided.");
-        if (SolutionsCompatibleWithProblemData(problemData, value))
-          solutionList = new List<IRegressionSolution>(value);
-        else
-          throw new ArgumentException("The provided solution collection is not compatible with the existing problem data.");
-        UpdateChart();
-      }
-    }
-
-    public VerticalLineAnnotation VerticalLineAnnotation {
-      get { return (VerticalLineAnnotation)Annotations.SingleOrDefault(x => x is VerticalLineAnnotation); }
+      get { return solutions; }
+    }
+
+    private VerticalLineAnnotation VerticalLineAnnotation {
+      get { return (VerticalLineAnnotation)chart.Annotations.SingleOrDefault(x => x is VerticalLineAnnotation); }
     }
 
     public GradientChart() {
       InitializeComponent();
-      RegisterEvents();
-    }
-
-    public void AddSolution(IRegressionSolution solution) {
-      if (!SolutionsCompatibleWithProblemData(problemData, new[] { solution })) {
-        throw new ArgumentException("The solution is not compatible with the problem data.");
-      }
-      solutionList.Add(solution);
-      UpdateChart();
-    }
-
-    public void RemoveSolution(IRegressionSolution solution) {
-      var removed = solutionList.RemoveAll(x => x == solution);
-      if (removed > 0)
-        UpdateChart();
-    }
-
-    private static bool SolutionsCompatibleWithProblemData(IRegressionProblemData pd, IEnumerable<IRegressionSolution> solutions) {
-      if (pd == null || !solutions.Any()) return true;
-      if (solutions.Any(x => x.ProblemData.TargetVariable != pd.TargetVariable)) return false;
-      var variables = new HashSet<string>(pd.Dataset.DoubleVariables);
-      return solutions.SelectMany(x => x.ProblemData.Dataset.DoubleVariables).All(variables.Contains);
-    }
-
-    public void Configure(IEnumerable<IRegressionSolution> solutions, IRegressionProblemData pd, ModifiableDataset dataset, string variable, double min, double max, int points) {
-      if (!SolutionsCompatibleWithProblemData(pd, solutions))
+    }
+
+    public void Configure(IEnumerable<IRegressionSolution> solutions, ModifiableDataset sharedFixedVariables, string freeVariable, int drawingSteps) {
+      if (!SolutionsCompatible(solutions))
         throw new ArgumentException("Solutions are not compatible with the problem data.");
-      this.solutionList = new List<IRegressionSolution>(solutions);
-      this.problemData = pd;
-      this.variable = variable;
-      this.sharedDataset = dataset;
-      this.min = min;
-      this.max = max;
-      this.points = points;
+      this.solutions.Clear();
+      this.solutions.AddRange(solutions);
+      this.freeVariable = freeVariable;
+      this.drawingSteps = drawingSteps;
 
       // add an event such that whenever a value is changed in the shared dataset, 
       // this change is reflected in the internal dataset (where the value becomes a whole column)
-      var variables = sharedDataset.DoubleVariables.ToList();
-      sharedDataset.ItemChanged += (o, e) => {
-        var rowIndex = e.Value;
-        var columnIndex = e.Value2;
-        var ds = (ModifiableDataset)o;
-        var variableName = variables[columnIndex];
-        if (variableName == Variable) return;
-        var v = ds.GetDoubleValue(variableName, rowIndex);
-        var values = new List<double>(Enumerable.Repeat(v, Points));
-        internalDataset.ReplaceVariable(variableName, values);
-      };
-
-      // configure internal dataset. we also expand the range in order to get nice tick intervals on the x axis
-      const int tics = 5;
+      if (this.sharedFixedVariables != null)
+        this.sharedFixedVariables.ItemChanged -= sharedFixedVariables_ItemChanged;
+      this.sharedFixedVariables = sharedFixedVariables;
+      this.sharedFixedVariables.ItemChanged += sharedFixedVariables_ItemChanged;
+
+      trainingMin = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Min()).Max();
+      trainingMax = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Max()).Min();
+
+      RecalculateInternalDataset();
+    }
+
+    private void sharedFixedVariables_ItemChanged(object o, EventArgs<int, int> e) {
+      var sender = (ModifiableDataset)o;
+      var variables = sharedFixedVariables.DoubleVariables.ToList();
+      var rowIndex = e.Value;
+      var columnIndex = e.Value2;
+
+      var variableName = variables[columnIndex];
+      if (variableName == FreeVariable) return;
+      var v = sender.GetDoubleValue(variableName, rowIndex);
+      var values = new List<double>(Enumerable.Repeat(v, DrawingSteps));
+      internalDataset.ReplaceVariable(variableName, values);
+
+      if (UpdateChartAutomatically)
+        UpdateChart();
+    }
+
+    private void RecalculateInternalDataset() {
+      // we expand the range in order to get nice tick intervals on the x axis
       double xmin, xmax, xinterval;
-      ChartUtil.CalculateAxisInterval(min, max, tics, out xmin, out xmax, out xinterval);
-      var step = (xmax - xmin) / points;
+      ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out xmin, out xmax, out xinterval);
+      double step = (xmax - xmin) / drawingSteps;
+
       var xvalues = new List<double>();
-      for (int i = 0; i < points; ++i) { xvalues.Add(xmin + i * step); }
-      internalDataset = new ModifiableDataset(variables, variables.Select(x => x == Variable ? xvalues : new List<double>(Enumerable.Repeat(sharedDataset.GetDoubleValue(x, 0), xvalues.Count))));
+      for (int i = 0; i < drawingSteps; i++)
+        xvalues.Add(xmin + i * step);
+
+      var variables = sharedFixedVariables.DoubleVariables.ToList();
+      internalDataset = new ModifiableDataset(variables,
+        variables.Select(x => x == FreeVariable
+          ? xvalues
+          : Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(x, 0), xvalues.Count).ToList()
+        )
+      );
     }
 
     public void UpdateChart() {
       // throw exceptions?
-      if (sharedDataset == null || solutionList == null || !solutionList.Any())
+      if (sharedFixedVariables == null || solutions == null || !solutions.Any())
         return;
-      if (min.IsAlmost(max) || min > max || points == 0)
+      if (trainingMin.IsAlmost(trainingMax) || trainingMin > trainingMax || drawingSteps == 0)
         return;
-      Series.Clear();
-      var vla = VerticalLineAnnotation;
-      Annotations.Clear();
-      var defaultValue = sharedDataset.GetDoubleValue(variable, 0);
-      vla.Visible = ShowCursor;
-      Annotations.Add(vla);
-      vla.X = defaultValue;
-
+
+      // Set cursor
+      var defaultValue = sharedFixedVariables.GetDoubleValue(freeVariable, 0);
+      VerticalLineAnnotation.X = defaultValue;
+
+      // Calculate X-axis interval
       double axisMin, axisMax, axisInterval;
-      // calculate X-axis interval
-      ChartUtil.CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval);
-      var axis = ChartAreas[0].AxisX;
+      ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out axisMin, out axisMax, out axisInterval);
+      var axis = chart.ChartAreas[0].AxisX;
       axis.Minimum = axisMin;
       axis.Maximum = axisMax;
       axis.Interval = axisInterval;
 
-      for (int i = 0; i < solutionList.Count; ++i) {
-        var solution = solutionList[i];
-        var series = PlotSeries(solution);
-        series.Name = Target + " " + i;
-        Series.Add(series);
-      }
-      // calculate Y-axis interval
-      double ymin = 0, ymax = 0;
-      foreach (var v in Series[0].Points.Select(x => x.YValues[0])) {
-        if (ymin > v) ymin = v;
-        if (ymax < v) ymax = v;
-      }
-      ChartUtil.CalculateAxisInterval(ymin, ymax, 5, out axisMin, out axisMax, out axisInterval);
-      axis = ChartAreas[0].AxisY;
-      axis.Minimum = axisMin;
-      axis.Maximum = axisMax;
-      axis.Interval = axisInterval;
-
-      if (ShowXAxisLabel) {
-        ChartAreas[0].AxisX.Title = Variable + " : " + defaultValue.ToString("N3", CultureInfo.CurrentCulture); // set axis title
-      }
-
-      AddStripLines(); // add strip lines
-      if (ShowLegend)
-        AddLegends();
-    }
-
-    private void UpdateDataset() {
-      var variables = ProblemData.Dataset.DoubleVariables.ToList();
-      var variableValues = new List<double>[variables.Count];
-
-      if (UseMedianValues) {
-        for (int i = 0; i < variables.Count; ++i) {
-          var median = ProblemData.Dataset.GetDoubleValues(variables[i], ProblemData.TrainingIndices).Median();
-          variableValues[i] = new List<double> { median };
+      // Create series
+      chart.Series.Clear();
+      for (int i = 0; i < solutions.Count; ++i) {
+        var solution = solutions[i];
+        Series confidenceIntervalPlotSeries;
+        var series = CreateSeries(solution, out confidenceIntervalPlotSeries);
+        series.Name = Solutions.First().ProblemData.TargetVariable + " " + i;
+        if (confidenceIntervalPlotSeries != null)
+          chart.Series.Add(confidenceIntervalPlotSeries);
+        chart.Series.Add(series);
+      }
+      //// calculate Y-axis interval
+      //double ymin = 0, ymax = 0;
+      //foreach (var v in chart.Series[0].Points.Select(x => x.YValues[0])) {
+      //  if (ymin > v) ymin = v;
+      //  if (ymax < v) ymax = v;
+      //}
+      //ChartUtil.CalculateAxisInterval(ymin, ymax, YXAxisTicks, out axisMin, out axisMax, out axisInterval);
+      //axis = chart.ChartAreas[0].AxisY;
+      //axis.Minimum = axisMin;
+      //axis.Maximum = axisMax;
+      //axis.Interval = axisInterval;
+
+      // set axis title
+      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + defaultValue.ToString("N3", CultureInfo.CurrentCulture);
+
+      UpdateStripLines();
+    }
+
+    private Series CreateSeries(IRegressionSolution solution, out Series confidenceIntervalPlotSeries) {
+      var series = new Series {
+        ChartType = SeriesChartType.Line
+      };
+
+      var xvalues = internalDataset.GetDoubleValues(FreeVariable).ToList();
+      var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+      series.Points.DataBindXY(xvalues, yvalues);
+
+      var confidenceBoundSolution = solution as IConfidenceBoundRegressionSolution;
+      if (confidenceBoundSolution != null) {
+        var variances = confidenceBoundSolution.Model.GetEstimatedVariances(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+
+        var lower = yvalues.Zip(variances, (m, s2) => m - 1.96 * Math.Sqrt(s2)).ToList();
+        var upper = yvalues.Zip(variances, (m, s2) => m + 1.96 * Math.Sqrt(s2)).ToList();
+
+        confidenceIntervalPlotSeries = new Series {
+          ChartType = SeriesChartType.Range,
+          YValuesPerPoint = 2
+        };
+        confidenceIntervalPlotSeries.Points.DataBindXY(xvalues, lower, upper);
+      } else {
+        confidenceIntervalPlotSeries = null;
+      }
+
+      return series;
+    }
+
+    public void AddSolution(IRegressionSolution solution) {
+      if (!SolutionsCompatible(solutions.Concat(new[] { solution })))
+        throw new ArgumentException("The solution is not compatible with the problem data.");
+      if (solutions.Contains(solution)) return;
+      solutions.Add(solution);
+      UpdateChart();
+    }
+    public void RemoveSolution(IRegressionSolution solution) {
+      bool removed = solutions.Remove(solution);
+      if (removed)
+        UpdateChart();
+    }
+
+    private static bool SolutionsCompatible(IEnumerable<IRegressionSolution> solutions) {
+      foreach (var solution1 in solutions) {
+        var variables1 = solution1.ProblemData.Dataset.DoubleVariables;
+        foreach (var solution2 in solutions) {
+          if (solution1 == solution2)
+            continue;
+          var variables2 = solution2.ProblemData.Dataset.DoubleVariables;
+          if (!variables1.All(variables2.Contains))
+            return false;
         }
-      } else {
-        for (int i = 0; i < variables.Count; ++i) {
-          var variableValue = ProblemData.Dataset.GetDoubleValue(variables[i], Row);
-          variableValues[i] = new List<double> { variableValue };
-        }
-      }
-      sharedDataset = new ModifiableDataset(variables, variableValues);
-    }
-
-    private Series PlotSeries(IRegressionSolution solution) {
-      var v = sharedDataset.GetDoubleValue(variable, 0);
-      var series = new Series { ChartType = SeriesChartType.Point };
-      // get values from series
-      var xvalues = internalDataset.GetReadOnlyDoubleValues(Variable);
-      var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows));
-      int i = 0;
-      foreach (var y in yvalues) {
-        var x = xvalues[i++];
-        series.Points.Add(new DataPoint(x, y) { MarkerSize = 2, MarkerColor = Color.DodgerBlue });
-      }
-      if (ShowCursor) {
-        var y = solution.Model.GetEstimatedValues(sharedDataset, new[] { 0 }).Single();
-        series.Points.Add(new DataPoint(v, y) { MarkerSize = 5, MarkerColor = Color.Red });
-      }
-      if (ShowLegend) {
-        series.IsVisibleInLegend = true;
-      }
-      return series;
-    }
-
-    private void AddLegends() {
-      Legends.Clear();
-      var legend = new Legend();
-      legend.Alignment = StringAlignment.Center;
-      legend.LegendStyle = LegendStyle.Row;
-      legend.Docking = Docking.Top;
-      Legends.Add(legend);
-      foreach (var s in Series) {
-        s.Legend = legend.Name;
-      }
-    }
-
-    private void AddStripLines() {
-      var axisX = ChartAreas[0].AxisX;
-      axisX.StripLines.Clear();
-      axisX.StripLines.Add(new StripLine { BackColor = Color.FromArgb(30, Color.Green), IntervalOffset = axisX.Minimum, StripWidth = min - axisX.Minimum });
-      axisX.StripLines.Add(new StripLine { BackColor = Color.FromArgb(30, Color.Green), IntervalOffset = max, StripWidth = axisX.Maximum - max });
-    }
-
-    private void RegisterEvents() {
-      AnnotationPositionChanging += chart_AnnotationPositionChanging;
-      MouseMove += chart_MouseMove;
-      FormatNumber += chart_FormatNumber;
+      }
+      return true;
+    }
+
+    private void UpdateStripLines() {
+      var axisX = chart.ChartAreas[0].AxisX;
+      var lowerStripLine = axisX.StripLines[0];
+      var upperStripLine = axisX.StripLines[1];
+
+      lowerStripLine.IntervalOffset = axisX.Minimum;
+      lowerStripLine.StripWidth = trainingMin - axisX.Minimum;
+
+      upperStripLine.IntervalOffset = trainingMax;
+      upperStripLine.StripWidth = axisX.Maximum - trainingMax;
     }
 
@@ -327,40 +291,36 @@
     }
 
-    public event EventHandler ChartPropertyChanged;
-    public void OnChartPropertyChanged(object sender, EventArgs args) {
-      var changed = ChartPropertyChanged;
-      if (changed == null) return;
-      changed(sender, args);
-    }
-
     private void chart_AnnotationPositionChanged(object sender, EventArgs e) {
       var annotation = VerticalLineAnnotation;
       var x = annotation.X;
-      sharedDataset.SetVariableValue(x, Variable, 0);
-      for (int i = 0; i < solutionList.Count; ++i) {
-        var y = solutionList[i].Model.GetEstimatedValues(sharedDataset, new[] { 0 }).Single();
-        var s = Series[i];
-        var n = s.Points.Count;
-        s.Points[n - 1] = new DataPoint(x, y) { MarkerColor = Color.Red, MarkerSize = 5 };
-      }
-      if (ShowXAxisLabel) {
-        ChartAreas[0].AxisX.Title = Variable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
-      }
-      Update();
+      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
+
+      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
+      chart.Update();
+
       OnVariableValueChanged(this, EventArgs.Empty);
     }
 
     private void chart_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e) {
-      var step = (max - min) / points;
-      e.NewLocationX = step * (long)Math.Round(e.NewLocationX / step);
-      var axisX = ChartAreas[0].AxisX;
-      if (e.NewLocationX > axisX.Maximum)
-        e.NewLocationX = axisX.Maximum;
-      if (e.NewLocationX < axisX.Minimum)
-        e.NewLocationX = axisX.Minimum;
+      //var step = (trainingMax - trainingMin) / drawingSteps;
+      //e.NewLocationX = step * (long)Math.Round(e.NewLocationX / step);
+      //var axisX = chart.ChartAreas[0].AxisX;
+      //if (e.NewLocationX > axisX.Maximum)
+      //  e.NewLocationX = axisX.Maximum;
+      //if (e.NewLocationX < axisX.Minimum)
+      //  e.NewLocationX = axisX.Minimum;
+
+      var annotation = VerticalLineAnnotation;
+      var x = annotation.X;
+      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
+
+      chart.ChartAreas[0].AxisX.Title = FreeVariable + " : " + x.ToString("N3", CultureInfo.CurrentCulture);
+      chart.Update();
+
+      OnVariableValueChanged(this, EventArgs.Empty);
     }
 
     private void chart_MouseMove(object sender, MouseEventArgs e) {
-      this.Cursor = HitTest(e.X, e.Y).ChartElementType == ChartElementType.Annotation ? Cursors.VSplit : Cursors.Default;
+      chart.Cursor = chart.HitTest(e.X, e.Y).ChartElementType == ChartElementType.Annotation ? Cursors.VSplit : Cursors.Default;
     }
 
@@ -388,5 +348,4 @@
       }
     }
-
     private void GradientChart_DragEnter(object sender, DragEventArgs e) {
       if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) return;
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 13831)
@@ -271,4 +271,10 @@
       <DependentUpon>FeatureCorrelationView.cs</DependentUpon>
     </Compile>
+    <Compile Include="GradientChart.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="GradientChart.Designer.cs">
+      <DependentUpon>GradientChart.cs</DependentUpon>
+    </Compile>
     <Compile Include="RegressionSolutionGradientView.cs">
       <SubType>UserControl</SubType>
@@ -467,10 +473,4 @@
     <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
       <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
-    </Compile>
-    <Compile Include="GradientChart.cs">
-      <SubType>Component</SubType>
-    </Compile>
-    <Compile Include="GradientChart.Designer.cs">
-      <DependentUpon>GradientChart.cs</DependentUpon>
     </Compile>
     <None Include="HeuristicLab.snk" />
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.Designer.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.Designer.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.Designer.cs	(revision 13831)
@@ -23,5 +23,5 @@
   partial class RegressionSolutionGradientView {
     /// <summary> 
-    /// Required designer variable.
+    /// Required designer variableNames.
     /// </summary>
     private System.ComponentModel.IContainer components = null;
@@ -45,12 +45,8 @@
     /// </summary>
     private void InitializeComponent() {
-      this.components = new System.ComponentModel.Container();
-      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
       this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.gradientChart = new HeuristicLab.Problems.DataAnalysis.Views.GradientChart();
       this.configurationGroupBox = new System.Windows.Forms.GroupBox();
       this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
@@ -59,27 +55,4 @@
       this.configurationGroupBox.SuspendLayout();
       this.SuspendLayout();
-      // 
-      // chart
-      // 
-      chartArea1.Name = "ChartArea";
-      this.chart.ChartAreas.Add(chartArea1);
-      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
-      legend1.Alignment = System.Drawing.StringAlignment.Center;
-      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend1.Name = "Default";
-      this.chart.Legends.Add(legend1);
-      this.chart.Location = new System.Drawing.Point(0, 0);
-      this.chart.Name = "chart";
-      this.chart.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.None;
-      this.chart.PaletteCustomColors = new System.Drawing.Color[] {
-        System.Drawing.Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(180)))), ((int)(((byte)(65))))),
-        System.Drawing.Color.FromArgb(((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240))))),
-        System.Drawing.Color.FromArgb(((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))))};
-      this.chart.Size = new System.Drawing.Size(715, 376);
-      this.chart.TabIndex = 0;
-      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
-      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
-      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
       // 
       // splitContainer
@@ -92,5 +65,5 @@
       // splitContainer.Panel1
       // 
-      this.splitContainer.Panel1.Controls.Add(this.chart);
+      this.splitContainer.Panel1.Controls.Add(this.gradientChart);
       // 
       // splitContainer.Panel2
@@ -100,4 +73,22 @@
       this.splitContainer.SplitterDistance = 376;
       this.splitContainer.TabIndex = 1;
+      // 
+      // gradientChart
+      // 
+      this.gradientChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.gradientChart.DrawingSteps = 1000;
+      this.gradientChart.UpdateChartAutomatically = true;
+      this.gradientChart.Location = new System.Drawing.Point(0, 0);
+      this.gradientChart.Name = "gradientChart";
+      this.gradientChart.ShowCursor = false;
+      this.gradientChart.ShowLegend = true;
+      this.gradientChart.ShowXAxisLabel = true;
+      this.gradientChart.ShowYAxisLabel = true;
+      this.gradientChart.Size = new System.Drawing.Size(715, 376);
+      this.gradientChart.TabIndex = 0;
+      this.gradientChart.TrainingMax = 1.7976931348623157E+308D;
+      this.gradientChart.TrainingMin = -1.7976931348623157E+308D;
+      this.gradientChart.XAxisTicks = 10;
+      this.gradientChart.YXAxisTicks = 5;
       // 
       // configurationGroupBox
@@ -132,5 +123,4 @@
       this.Name = "RegressionSolutionGradientView";
       this.Size = new System.Drawing.Size(715, 591);
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
       this.splitContainer.Panel1.ResumeLayout(false);
       this.splitContainer.Panel2.ResumeLayout(false);
@@ -143,9 +133,8 @@
 
     #endregion
-
-    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
     private System.Windows.Forms.SplitContainer splitContainer;
     private System.Windows.Forms.GroupBox configurationGroupBox;
     private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+    private Problems.DataAnalysis.Views.GradientChart gradientChart;
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionGradientView.cs	(revision 13831)
@@ -22,12 +22,8 @@
 using System;
 using System.Collections.Generic;
-using System.Drawing;
 using System.Linq;
 using System.Windows.Forms;
-using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.Collections;
-using HeuristicLab.Data;
 using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 using HeuristicLab.Problems.DataAnalysis;
 using HeuristicLab.Problems.DataAnalysis.Views;
@@ -45,9 +41,10 @@
     private const string EstimatedVarianceSeriesName = "95% Conficence Interval";
 
-    private readonly List<string> dimensionNames;
-    private readonly ObservableList<DensityTrackbar> dimensionTrackbars;
+    private readonly List<string> variableNames;
+    private readonly ObservableList<DensityTrackbar> trackbars;
+    private ModifiableDataset sharedFixedVariables;
 
     private int ActiveDimension {
-      get { return dimensionTrackbars.FindIndex(tb => tb.Checked); }
+      get { return trackbars.FindIndex(tb => tb.Checked); }
     }
 
@@ -59,18 +56,17 @@
     public RegressionSolutionGradientView()
       : base() {
-      dimensionNames = new List<string>();
+      variableNames = new List<string>();
 
-      dimensionTrackbars = new ObservableList<DensityTrackbar>();
-      dimensionTrackbars.ItemsAdded += (sender, args) => {
+      trackbars = new ObservableList<DensityTrackbar>();
+      trackbars.ItemsAdded += (sender, args) => {
         ForEach(args.Items.Select(i => i.Value), RegisterEvents);
       };
-      dimensionTrackbars.ItemsRemoved += (sender, args) => {
+      trackbars.ItemsRemoved += (sender, args) => {
         ForEach(args.Items.Select(i => i.Value), DeregisterEvents);
       };
-      dimensionTrackbars.CollectionReset += (sender, args) => {
+      trackbars.CollectionReset += (sender, args) => {
         ForEach(args.OldItems.Select(i => i.Value), DeregisterEvents);
         ForEach(args.Items.Select(i => i.Value), RegisterEvents);
       };
-
 
       InitializeComponent();
@@ -79,105 +75,40 @@
       var vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
       tableLayoutPanel.Padding = new Padding(0, 0, vertScrollWidth, 0);
-
-      // Configure axis
-      chart.CustomizeAllChartAreas();
-      chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
-      chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
-      chart.ChartAreas[0].CursorX.Interval = 1;
-
-      chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
-      chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-      chart.ChartAreas[0].CursorY.Interval = 0;
-    }
-
-    private void RedrawChart() {
-      chart.Series.Clear();
-      chart.ChartAreas[0].AxisX.StripLines.Clear();
-      if (Content == null || ActiveDimension < 0) return;
-
-      double minX = dimensionTrackbars[ActiveDimension].Limits.Lower;
-      double maxX = dimensionTrackbars[ActiveDimension].Limits.Upper;
-      decimal stepSize = (decimal)((maxX - minX) / DrawingSteps);
-
-      // Build dataset
-      var activeXs = Enumerable.Range(0, DrawingSteps).Select(i => (decimal)minX + i * stepSize).ToList();
-      var fixedXs = dimensionTrackbars.Select(tb => tb.Value).ToList();
-      var values = new double[DrawingSteps, dimensionNames.Count];
-      for (int r = 0; r < DrawingSteps; r++) {
-        for (int c = 0; c < dimensionNames.Count; c++) {
-          values[r, c] = (double)(c == ActiveDimension ? activeXs[r] : fixedXs[c]);
-        }
-      }
-      var dataset = new Dataset(dimensionNames, values);
-
-      // Estimations
-      var model = Content.Model;
-      var means = model.GetEstimatedValues(dataset, Enumerable.Range(0, DrawingSteps)).ToList();
-      var variances = model.GetEstimatedVariances(dataset, Enumerable.Range(0, DrawingSteps)).ToList();
-
-      // Charting config
-      chart.ChartAreas[0].AxisX.Minimum = minX;
-      chart.ChartAreas[0].AxisX.Maximum = maxX;
-      chart.ChartAreas[0].AxisX.Interval = (maxX - minX) / 10;
-
-      // ToDo only databind and put config in codebehind
-      chart.Series.Add(EstimatedVarianceSeriesName);
-      chart.Series[EstimatedVarianceSeriesName].LegendText = EstimatedVarianceSeriesName;
-      chart.Series[EstimatedVarianceSeriesName].ChartType = SeriesChartType.Range;
-      chart.Series[EstimatedVarianceSeriesName].EmptyPointStyle.Color = chart.Series[EstimatedVarianceSeriesName].Color;
-
-      chart.Series.Add(EstimatedMeanSeriesName);
-      chart.Series[EstimatedMeanSeriesName].LegendText = EstimatedMeanSeriesName;
-      chart.Series[EstimatedMeanSeriesName].ChartType = SeriesChartType.FastLine;
-
-      // Charting databind
-      var lower = means.Zip(variances, GetLowerConfBound).ToList();
-      var upper = means.Zip(variances, GetUpperConfBound).ToList();
-      chart.Series[EstimatedVarianceSeriesName].Points.DataBindXY(activeXs, lower, upper);
-      chart.Series[EstimatedMeanSeriesName].Points.DataBindXY(activeXs, means);
-
-      // Update StripLines
-      var trainingValues = Content.ProblemData.Dataset.GetDoubleValues(dimensionNames[ActiveDimension],
-        Content.ProblemData.TrainingIndices);
-      var trainingRange = new DoubleRange(trainingValues.Min(), trainingValues.Max());
-      if (minX < trainingRange.Start)
-        CreateAndAddStripLine(minX, trainingRange.Start, Color.FromArgb(40, 223, 58, 2), Color.Transparent);
-      if (maxX > trainingRange.End)
-        CreateAndAddStripLine(trainingRange.End, maxX, Color.FromArgb(40, 223, 58, 2), Color.Transparent);
-
-      // Update axis description
-      chart.ChartAreas[0].AxisX.Title = dimensionNames[ActiveDimension];
-    }
-
-    private void CreateAndAddStripLine(double start, double end, Color color, Color secondColor) {
-      StripLine stripLine = new StripLine {
-        BackColor = color,
-        BackSecondaryColor = secondColor,
-        StripWidth = end - start,
-        IntervalOffset = start
-      };
-      chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
     }
 
     private void UpdateConfigurationControls() {
-      tableLayoutPanel.SuspendRepaint();
-      tableLayoutPanel.SuspendLayout();
+      variableNames.Clear();
+      trackbars.Clear();
 
       tableLayoutPanel.RowCount = 0;
       tableLayoutPanel.Controls.Clear();
 
-      dimensionNames.Clear();
-      dimensionTrackbars.Clear();
+      if (Content == null) return;
 
-      if (Content == null) {
-        tableLayoutPanel.ResumeLayout(true);
-        tableLayoutPanel.ResumeRepaint(true);
-        return;
+      variableNames.AddRange(Content.ProblemData.AllowedInputVariables);
+
+      var newTrackbars = CreateConfiguration();
+
+      sharedFixedVariables = new ModifiableDataset(variableNames, newTrackbars.Select(tb => new List<double>(1) { (double)tb.Value }));
+      gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableNames.First(), DrawingSteps);
+      gradientChart.UpdateChart();
+
+      // Add to table and observable lists     
+      tableLayoutPanel.RowCount = variableNames.Count;
+      while (tableLayoutPanel.RowStyles.Count < variableNames.Count)
+        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+      for (int i = 0; i < newTrackbars.Count; i++) {
+        // events registered automatically
+        trackbars.Add(newTrackbars[i]);
+        tableLayoutPanel.Controls.Add(newTrackbars[i], 0, i);
       }
 
-      dimensionNames.AddRange(Content.ProblemData.AllowedInputVariables);
+      trackbars.First().Checked = true;
+    }
+
+    private IList<DensityTrackbar> CreateConfiguration() {
       var ranges = new List<DoubleLimit>();
-      for (int i = 0; i < dimensionNames.Count; i++) {
-        var values = Content.ProblemData.Dataset.GetDoubleValues(dimensionNames[i], Content.ProblemData.AllIndices);
+      foreach (string variableName in variableNames) {
+        var values = Content.ProblemData.Dataset.GetDoubleValues(variableName, Content.ProblemData.AllIndices);
         double min, max, interval;
         ChartUtil.CalculateAxisInterval(values.Min(), values.Max(), 10, out min, out max, out interval);
@@ -185,60 +116,50 @@
       }
 
-      tableLayoutPanel.RowCount = dimensionNames.Count;
-      while (tableLayoutPanel.RowStyles.Count < dimensionNames.Count)
-        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+      var newTrackbars = new List<DensityTrackbar>();
+      for (int i = 0; i < variableNames.Count; i++) {
+        var name = variableNames[i];
+        var trainingData = Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
 
-      for (int i = 0; i < dimensionNames.Count; i++) {
-        var name = dimensionNames[i];
-        var trainingData =
-          Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
-
-        var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData);
-
-        // events registered automatically
-        dimensionTrackbars.Add(dimensionTrackbar);
-
-        dimensionTrackbar.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
-        tableLayoutPanel.Controls.Add(dimensionTrackbar, 0, i);
+        var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData) {
+          Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+        };
+        newTrackbars.Add(dimensionTrackbar);
       }
 
-      if (dimensionTrackbars.Any())
-        dimensionTrackbars.First().Checked = true;
-
-      tableLayoutPanel.ResumeLayout(true);
-      tableLayoutPanel.ResumeRepaint(true);
+      return newTrackbars;
     }
 
     private void RegisterEvents(DensityTrackbar trackbar) {
-      trackbar.CheckedChanged += DimensionTrackbar_CheckedChanged;
-      trackbar.ValueChanged += DimensionTrackbar_ValueChanged;
-      trackbar.LimitsChanged += DimensionTrackbar_LimitsChanged;
+      trackbar.CheckedChanged += trackbar_CheckedChanged;
+      trackbar.ValueChanged += trackbar_ValueChanged;
+      trackbar.LimitsChanged += trackbar_LimitsChanged;
+    }
+    private void DeregisterEvents(DensityTrackbar trackbar) {
+      trackbar.CheckedChanged -= trackbar_CheckedChanged;
+      trackbar.ValueChanged -= trackbar_ValueChanged;
+      trackbar.LimitsChanged -= trackbar_LimitsChanged;
     }
 
-    private void DeregisterEvents(DensityTrackbar trackbar) {
-      trackbar.CheckedChanged -= DimensionTrackbar_CheckedChanged;
-      trackbar.ValueChanged -= DimensionTrackbar_ValueChanged;
-      trackbar.LimitsChanged -= DimensionTrackbar_LimitsChanged;
+    private void trackbar_CheckedChanged(object sender, EventArgs e) {
+      var trackBar = sender as DensityTrackbar;
+      if (trackBar == null || !trackBar.Checked) return;
+      // Uncheck all others
+      foreach (var tb in trackbars.Except(new[] { trackBar }))
+        tb.Checked = false;
+      gradientChart.FreeVariable = variableNames[trackbars.IndexOf(trackBar)];
     }
 
-    private void DimensionTrackbar_CheckedChanged(object sender, EventArgs e) {
-      var trackBarSender = sender as DensityTrackbar;
-      if (trackBarSender == null || !trackBarSender.Checked) return;
-      // Uncheck all others
-      foreach (var tb in dimensionTrackbars.Except(new[] { trackBarSender }))
-        tb.Checked = false;
-      RedrawChart();
+    private void trackbar_LimitsChanged(object sender, EventArgs e) {
+      // Todo adapt bounds
     }
 
-    private void DimensionTrackbar_LimitsChanged(object sender, EventArgs e) {
-      RedrawChart();
-    }
-
-    private void DimensionTrackbar_ValueChanged(object sender, EventArgs e) {
-      RedrawChart();
+    private void trackbar_ValueChanged(object sender, EventArgs e) {
+      var trackBar = sender as DensityTrackbar;
+      if (trackBar == null) return;
+      sharedFixedVariables.SetVariableValue((double)trackBar.Value, variableNames[trackbars.IndexOf(trackBar)], 0);
+      gradientChart.UpdateChart();
     }
 
     #region Events
-
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
@@ -256,60 +177,14 @@
       base.OnContentChanged();
       UpdateConfigurationControls();
-      RedrawChart();
     }
 
     private void Content_ModelChanged(object sender, EventArgs e) {
-      RedrawChart();
+      UpdateConfigurationControls();
     }
 
     private void Content_ProblemDataChanged(object sender, EventArgs e) {
       UpdateConfigurationControls();
-      RedrawChart();
     }
-
-    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
-      var result = chart.HitTest(e.X, e.Y);
-      if (true || result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
-                                               result.ChartElementType == ChartElementType.Gridlines) ||
-          result.ChartElementType == ChartElementType.StripLines) {
-        foreach (var axis in result.ChartArea.Axes)
-          axis.ScaleView.ZoomReset(int.MaxValue);
-      }
-    }
-
-    private void chart_MouseMove(object sender, MouseEventArgs e) {
-      //HitTestResult result = chart.HitTest(e.X, e.Y);
-      //if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
-      //  Cursor = Cursors.Hand;
-      //else
-      //  Cursor = Cursors.Default;
-    }
-
-    private void chart_MouseDown(object sender, MouseEventArgs e) {
-      //HitTestResult result = chart.HitTest(e.X, e.Y);
-      //if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
-      //  ToggleSeriesData(result.Series);
-      //}
-    }
-
-    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
-      //if (chart.Series.Count != 4) return;
-      //e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[EstimatedMeanSeriesName].Points.Count == 0 ? Color.Gray : Color.Black;
-      //e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      //e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      //e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-    }
-
     #endregion
-
-    #region Helper
-
-    private double GetLowerConfBound(double m, double s2) {
-      return m - 1.96 * Math.Sqrt(s2);
-    }
-
-    private double GetUpperConfBound(double m, double s2) {
-      return m + 1.96 * Math.Sqrt(s2);
-    }
 
     public static void ForEach<T>(IEnumerable<T> source, Action<T> action) {
@@ -317,6 +192,4 @@
         action(item);
     }
-
-    #endregion
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionTargetResponseGradientView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionTargetResponseGradientView.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionTargetResponseGradientView.cs	(revision 13831)
@@ -26,5 +26,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -32,17 +31,15 @@
   [Content(typeof(IRegressionSolution))]
   public partial class RegressionSolutionTargetResponseGradientView : DataAnalysisSolutionEvaluationView {
-    private Dictionary<string, GradientChart> charts;
-    private const int Points = 1000;
+    private readonly Dictionary<string, GradientChart> charts;
+    private const int Points = 200;
 
     public RegressionSolutionTargetResponseGradientView() {
       InitializeComponent();
+      charts = new Dictionary<string, GradientChart>();
     }
 
     public new IRegressionSolution Content {
       get { return (IRegressionSolution)base.Content; }
-      set {
-        if (value == null || value == Content) return;
-        base.Content = value;
-      }
+      set { base.Content = value; }
     }
 
@@ -60,18 +57,12 @@
       base.OnContentChanged();
       if (Content == null) return;
-      var pd = Content.ProblemData;
-      var ds = pd.Dataset;
+      var problemData = Content.ProblemData;
       // create dataset
       var variableNames = Content.GetUsedVariablesForPrediction().ToList();
-      var variableValues = variableNames.Select(x => new List<double> { pd.Dataset.GetDoubleValues(x, pd.TrainingIndices).Median() });
-      var dataset = new ModifiableDataset(variableNames, variableValues);
+      var variableValues = variableNames.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
+      var sharedFixedVariables = new ModifiableDataset(variableNames, variableValues);
       // create charts
-      charts = new Dictionary<string, GradientChart>();
-      foreach (var x in variableNames) {
-        double min = 0, max = 0;
-        foreach (var v in ds.GetDoubleValues(x, pd.TrainingIndices)) {
-          if (v > max) max = v;
-          if (v < min) min = v;
-        }
+      charts.Clear();
+      foreach (var variableName in variableNames) {
         var gradientChart = new GradientChart {
           Dock = DockStyle.Fill,
@@ -80,5 +71,5 @@
           ShowCursor = true,
           ShowXAxisLabel = true,
-          ShowYAxisLabel = true
+          ShowYAxisLabel = true,
         };
         gradientChart.VariableValueChanged += (o, e) => {
@@ -88,6 +79,6 @@
           }
         };
-        gradientChart.Configure(new[] { Content }, pd, dataset, x, min, max, Points);
-        charts[x] = gradientChart;
+        gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, Points);
+        charts[variableName] = gradientChart;
       }
       // update variable list
@@ -101,9 +92,9 @@
       var indices = variableListView.CheckedItems.Cast<ListViewItem>().ToDictionary(checkedItem => checkedItem.Text, checkedItem => checkedItem.Index);
       var count = tl.Controls.Count;
-      var controls = new GradientChart[count];
-      for (int i = 0; i < count; ++i) controls[i] = (GradientChart)tl.Controls[i];
-      Array.Sort(controls, (a, b) => indices[a.Variable].CompareTo(indices[b.Variable]));
+      var charts = new GradientChart[count];
+      for (int i = 0; i < count; ++i) charts[i] = (GradientChart)tl.Controls[i];
+      Array.Sort(charts, (a, b) => indices[a.FreeVariable].CompareTo(indices[b.FreeVariable]));
       tl.Controls.Clear();
-      tl.Controls.AddRange(controls);
+      tl.Controls.AddRange(charts);
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 13831)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -111,4 +111,8 @@
     protected override void DeregisterItemEvents(IEnumerable<IResult> items) { }
 
+    public virtual IEnumerable<string> GetUsedVariablesForPrediction() {
+      return this.ProblemData.AllowedInputVariables;
+    }
+
     #region INamedItem Members
     [Storable]
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 13830)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 13831)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -28,4 +29,5 @@
     IDataAnalysisModel Model { get; }
     IDataAnalysisProblemData ProblemData { get; set; }
+    IEnumerable<string> GetUsedVariablesForPrediction();
 
     event EventHandler ModelChanged;
