Index: trunk/sources/HeuristicLab.Visualization/3.2/AvgAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/AvgAggregator.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/AvgAggregator.cs	(revision 1530)
@@ -0,0 +1,111 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Visualization {
+  public class AvgAggregator : DataRowBase {
+    #region IAggregator Members
+
+    public void AddWatch(IDataRow dataRow) {
+      dataRowWatches.Add(dataRow);
+      dataRow.ValueChanged += dataRow_ValueChanged;
+      dataRow.ValuesChanged += dataRow_ValuesChanged;
+      dataRow.DataRowChanged += dataRow_DataRowChanged;
+    }
+
+    public void RemoveWatch(IDataRow dataRow) {
+      dataRowWatches.Remove(dataRow);
+      dataRow.DataRowChanged -= dataRow_DataRowChanged;
+      dataRow.ValuesChanged -= dataRow_ValuesChanged;
+      dataRow.ValueChanged -= dataRow_ValueChanged;
+    }
+
+    #endregion
+
+    private List<IDataRow> dataRowWatches = new List<IDataRow>();
+    private double curAvgValue;
+
+    private void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
+      refreshValue(value);
+    }
+
+    private void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
+      for (int i = 0; i < values.Length; i++) {
+        refreshValue(values[i]);
+      }
+    }
+
+    private void dataRow_DataRowChanged(IDataRow row) {
+      refreshValue(double.MinValue);
+    }
+
+    private void refreshValue(double newVal) {
+      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
+
+      curAvgValue = double.MinValue;
+      double tmpSum = 0;
+      int count = 0;
+      foreach (IDataRow rows in dataRowWatches) {
+        for (int i = 0; i < rows.Count; i++) {
+          tmpSum += rows[i];
+          count++;
+        }
+      }
+      curAvgValue = tmpSum/count;
+      // evtl nur feuern wenn sich geändert hat (jedes mal?)
+      OnValueChanged(curAvgValue, 0, Action.Modified);
+    }
+
+    #region IDataRow Members
+
+    public override void AddValue(double value) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValue(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValues(int index, int count) {
+      throw new NotSupportedException();
+    }
+
+    public override int Count {
+      get { return 1; }
+    }
+
+    public override double this[int index] {
+      get { return curAvgValue; }
+      set { throw new NotSupportedException(); }
+    }
+
+    public override double MinValue {
+      get { return curAvgValue; }
+    }
+
+    public override double MaxValue {
+      get { return curAvgValue; }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/AvgLineAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/AvgLineAggregator.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/AvgLineAggregator.cs	(revision 1530)
@@ -0,0 +1,135 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Visualization {
+  public class AvgLineAggregator : DataRowBase {
+
+    private readonly List<double> dataRow = new List<double>();
+
+    #region IAggregator Members
+
+    public void AddWatch(IDataRow dataRow) {
+      dataRowWatches.Add(dataRow);
+      dataRow.ValueChanged += dataRow_ValueChanged;
+      dataRow.ValuesChanged += dataRow_ValuesChanged;
+      dataRow.DataRowChanged += dataRow_DataRowChanged;
+    }
+
+    public void RemoveWatch(IDataRow dataRow) {
+
+      dataRowWatches.Remove(dataRow);
+      dataRow.DataRowChanged -= dataRow_DataRowChanged;
+      dataRow.ValuesChanged -= dataRow_ValuesChanged;
+      dataRow.ValueChanged -= dataRow_ValueChanged;
+    }
+
+
+    #endregion
+
+    List<IDataRow> dataRowWatches = new List<IDataRow>();
+    
+    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
+      refreshValue(value);
+    }
+
+    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
+      for (int i = 0; i < values.Length; i++) {
+        refreshValue(values[i]);
+      }
+    }
+
+    void dataRow_DataRowChanged(IDataRow row) {
+      refreshValue(double.MinValue);
+    }
+
+    private void refreshValue(double newVal) {
+      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
+
+      //curAvgValue = double.MinValue;
+      double tmpSum = 0;
+      int count = dataRowWatches.Count;
+
+      IDataRow firstRow = dataRowWatches[0];
+      int count1 = firstRow.Count;
+      System.Console.WriteLine("count: " + count1);
+
+      dataRow.Clear();
+
+      if (dataRowWatches.Count >= 2) {
+        for (int i = 0; i < count1; i++) {
+          tmpSum = 0;
+          for (int j = 0; j < count; j++) {
+            if (dataRowWatches[j].Count > i) {
+              tmpSum += dataRowWatches[j][i];
+            }
+          }
+
+          this.dataRow.Add(tmpSum/count);
+          OnValueChanged(tmpSum / count, dataRow.Count - 1, Action.Added);
+        }
+      }
+
+      // evtl nur feuern wenn sich geändert hat (jedes mal?)
+      //OnDataRowChanged(this);
+    }
+
+    #region IDataRow Members
+
+    public override void AddValue(double value) {
+      dataRow.Add(value);
+      OnValueChanged(value, dataRow.Count - 1, Action.Added);
+    }
+
+    public override void AddValue(double value, int index) {
+      throw new NotImplementedException();
+    }
+
+    public override void AddValues(double[] values) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValue(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValues(int index, int count) {
+      throw new NotSupportedException();
+    }
+
+    public override int Count {
+      get { return dataRow.Count; } //return dataRowWatches.Count; }
+    }
+
+    public override double this[int index] {
+      get { return dataRow[index]; }
+      set {
+        dataRow[index] = value;
+        OnValueChanged(value, index, Action.Modified);
+      }
+    }
+
+    // TODO calculate min value
+    public override double MinValue {
+      get { return 0; }
+    }
+
+    // TODO calculate max value
+    public override double MaxValue {
+      get { return 0; }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/AxisPosition.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/AxisPosition.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/AxisPosition.cs	(revision 1530)
@@ -0,0 +1,6 @@
+namespace HeuristicLab.Visualization.Test {
+  public enum AxisPosition {
+    Left,
+    Right
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/AxisTicks.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/AxisTicks.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/AxisTicks.cs	(revision 1530)
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Visualization {
+  public static class AxisTicks {
+    public static IEnumerable<double> GetTicks(int pixelsPerInterval, int screenSize, double worldSize, double worldStart) {
+      int intervals = screenSize/pixelsPerInterval;
+
+      if (intervals > 0) {
+        double step = worldSize/intervals;
+        step = Math.Pow(10, Math.Floor(Math.Log10(step)));
+        if (worldSize/(step*5) > intervals)
+          step = step*5;
+        else if (worldSize/(step*2) > intervals)
+          step = step*2;
+
+        for (double x = Math.Floor(worldStart/step)*step;
+             x <= worldStart + worldSize;
+             x += step)
+          yield return x;
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Canvas.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Canvas.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Canvas.cs	(revision 1530)
@@ -0,0 +1,66 @@
+using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Visualization {
+  public class Canvas : IShape {
+    private readonly WorldShape worldShape;
+
+    private Rectangle viewport;
+
+    public Canvas() {
+      worldShape = new WorldShape();
+      worldShape.Parent = this;
+    }
+
+    public void AddShape(IShape shape) {
+      worldShape.AddShape(shape);
+    }
+
+    public void RemoveShape(IShape shape) {
+      worldShape.RemoveShape(shape);
+    }
+
+    public void ClearShapes() {
+      worldShape.ClearShapes();
+    }
+
+    public Rectangle Viewport {
+      get { return viewport; }
+      set {
+        viewport = value;
+        worldShape.ClippingArea = new RectangleD(0, 0, viewport.Width, viewport.Height);
+        worldShape.BoundingBox = worldShape.ClippingArea;
+      }
+    }
+
+    public RectangleD ClippingArea {
+      get { return worldShape.ClippingArea; }
+    }
+
+    public RectangleD BoundingBox {
+      get { throw new InvalidOperationException(); }
+    }
+
+    public IShape Parent {
+      get { throw new InvalidOperationException(); }
+      set { throw new InvalidOperationException(); }
+    }
+
+    public void Draw(Graphics graphics) {
+      Stopwatch sw = new Stopwatch();
+      sw.Start();
+
+      graphics.SmoothingMode = SmoothingMode.AntiAlias;
+      graphics.FillRectangle(Brushes.White, Viewport);
+
+      worldShape.Draw(graphics);
+
+      graphics.DrawRectangle(Pens.Black, 0, 0, Viewport.Width - 1, Viewport.Height - 1);
+
+      sw.Stop();
+      Trace.WriteLine(string.Format("Drawing time: {0:0.0}ms", sw.Elapsed.TotalMilliseconds));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.Designer.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.Designer.cs	(revision 1530)
@@ -0,0 +1,41 @@
+﻿namespace HeuristicLab.Visualization
+{
+    partial class CanvasUI
+    {
+        /// <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.SuspendLayout();
+          // 
+          // CanvasUI
+          // 
+          this.ResumeLayout(false);
+
+        }
+
+        #endregion
+    }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/CanvasUI.cs	(revision 1530)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Visualization {
+  public partial class CanvasUI : Control {
+    private readonly Canvas canvas = new Canvas();
+
+    public CanvasUI() {
+      InitializeComponent();
+
+      DoubleBuffered = true;
+    }
+
+    public Canvas Canvas {
+      get { return canvas; }
+    }
+
+    protected override void OnPaint(PaintEventArgs pe) {
+      try {
+        Graphics g = pe.Graphics;
+
+        canvas.Viewport = ClientRectangle;
+        canvas.Draw(g);
+
+        base.OnPaint(pe);
+      } catch (Exception e) {
+       Trace.WriteLine(e);
+      }
+    }
+
+    protected override void OnResize(EventArgs e) {
+      Invalidate();
+
+      canvas.Viewport = ClientRectangle;
+
+      base.OnResize(e);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ChangeType.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ChangeType.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ChangeType.cs	(revision 1530)
@@ -0,0 +1,7 @@
+namespace HeuristicLab.Visualization {
+  public enum ChangeType {
+    Add,
+    Modify,
+    Remove
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ChartDataModelBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ChartDataModelBase.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ChartDataModelBase.cs	(revision 1530)
@@ -0,0 +1,10 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Visualization {
+  public abstract class ChartDataModelBase : ItemBase, IChartDataModel{
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModel.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModel.cs	(revision 1530)
@@ -0,0 +1,257 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Xml;
+using HeuristicLab.Core;
+using System.Text;
+using HeuristicLab.Visualization.LabelProvider;
+using HeuristicLab.Visualization.Options;
+
+namespace HeuristicLab.Visualization{
+  public delegate void DataRowAddedHandler(IDataRow row);
+  public delegate void DataRowRemovedHandler(IDataRow row);
+  public delegate void ModelChangedHandler();
+
+  public class ChartDataRowsModel : ChartDataModelBase, IChartDataRowsModel{
+    private string title = "Title";
+    private string xAxisLabel = "";
+    private bool showXAxisLabel = true;
+    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.##");
+
+    private ViewSettings viewSettings = new ViewSettings();
+
+    public ILabelProvider XAxisLabelProvider {
+      get { return labelProvider; }
+      set{
+        this.labelProvider = value;
+        OnModelChanged();
+      }
+    }
+
+    public List<YAxisDescriptor> YAxes {
+      get {
+        Dictionary<YAxisDescriptor, object> yaxes = new Dictionary<YAxisDescriptor, object>();
+
+        foreach (IDataRow row in rows) {
+          yaxes[row.YAxis] = null;
+        }
+
+        return new List<YAxisDescriptor>(yaxes.Keys);
+      }
+    }
+
+
+    private readonly List<IDataRow> rows = new List<IDataRow>();
+    //private readonly List<string> xLabels = new List<string>();
+
+    //public List<string> XLabels{
+    //  get { return xLabels; }
+    //}
+
+    public List<IDataRow> Rows{
+      get { return rows; }
+    }
+
+    public string Title {
+      get { return title; }
+      set {
+        title = value;
+        OnModelChanged();
+      }
+    }
+
+    public string XAxisLabel {
+      get { return xAxisLabel; }
+      set {
+        xAxisLabel = value;
+        OnModelChanged();
+      }
+    }
+
+    public bool ShowXAxisLabel {
+      get { return showXAxisLabel; }
+      set {
+        showXAxisLabel = value;
+        OnModelChanged();
+      }
+    }
+
+    public override IView CreateView() {
+      return new LineChart(this);
+    }
+
+    //public void AddLabel(string label) {
+    //  xLabels.Add(label);
+    //  OnModelChanged();
+    //}
+
+    //public void AddLabel(string label, int index) {
+    //  xLabels[index] = label;
+    //  OnModelChanged();
+    //}
+
+    //public void AddLabels(string[] labels) {
+    //  foreach (var s in labels){
+    //    AddLabel(s);
+    //  }
+    //  //OnModelChanged();
+    //}
+
+    //public void AddLabels(string[] labels, int index) {
+    //  int i = 0;
+    //  foreach (var s in labels){
+    //    AddLabel(s, index + i);
+    //    i++;
+    //  }
+    //  //OnModelChanged();
+    //}
+
+    //public void ModifyLabel(string label, int index) {
+    //  xLabels[index] = label;
+    //  OnModelChanged();
+    //}
+
+    //public void ModifyLabels(string[] labels, int index) {
+    //  int i = 0;
+    //  foreach (var s in labels){
+    //    ModifyLabel(s, index + i);
+    //    i++;
+    //  }
+    //  //OnModelChanged();
+    //}
+
+    //public void RemoveLabel(int index) {
+    //  xLabels.RemoveAt(index);
+    //  OnModelChanged();
+    //}
+
+    //public void RemoveLabels(int index, int count) {
+    //  for (int i = index; i < index + count; i++ ){
+    //    RemoveLabel(i);
+    //  }
+    //  //OnModelChanged();
+    //}
+
+    private readonly YAxisDescriptor defaultYAxisDescriptor = new YAxisDescriptor();
+
+    public void AddDataRow(IDataRow row) {
+      if (row.YAxis == null) {
+        row.YAxis = defaultYAxisDescriptor;
+      }
+      rows.Add(row);
+      OnDataRowAdded(row);
+    }
+
+    public void RemoveDataRow(IDataRow row) {
+      rows.Remove(row);
+      OnDataRowRemoved(row);
+    }
+
+    public YAxisDescriptor DefaultYAxis {
+      get { return defaultYAxisDescriptor; }
+    }
+
+    // TODO implement calculation of max data row values
+    public int MaxDataRowValues {
+      get {
+        int max = 0;
+
+        foreach (IDataRow row in rows) {
+          max = Math.Max(max, row.Count);
+        }
+
+        return max;
+      }
+    }
+
+    public ViewSettings ViewSettings {
+      get { return viewSettings; }
+      set { viewSettings = value; }
+    }
+
+    public event ModelChangedHandler ModelChanged;
+
+    protected void OnModelChanged() {
+      if (ModelChanged != null) {
+        ModelChanged();
+      }
+    }
+
+    public event DataRowAddedHandler DataRowAdded;
+
+    protected void OnDataRowAdded(IDataRow row) {
+      if (DataRowAdded != null) {
+        DataRowAdded(row);
+      }
+    }
+
+    public event DataRowRemovedHandler DataRowRemoved;
+
+    protected void OnDataRowRemoved(IDataRow row) {
+      if (DataRowRemoved != null) {
+        DataRowRemoved(row);
+      }
+    }
+
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+
+      foreach (IDataRow row in rows) {
+        XmlNode columnElement = document.CreateNode(XmlNodeType.Element, "row", null);
+
+        XmlAttribute idAttr = document.CreateAttribute("label");
+        idAttr.Value = row.Label;
+        columnElement.Attributes.Append(idAttr);
+
+        StringBuilder builder = new StringBuilder();
+
+        for (int i = 0; i < row.Count; i++) {
+          if (i == 0) {
+            builder.Append(row[i].ToString(CultureInfo.InvariantCulture.NumberFormat));
+            //columnElement.InnerText += row[i].ToString(CultureInfo.InvariantCulture.NumberFormat);
+          } else {
+            builder.Append(";" + row[i].ToString(CultureInfo.InvariantCulture.NumberFormat));
+            //columnElement.InnerText += ";" + row[i].ToString(CultureInfo.InvariantCulture.NumberFormat);
+          }
+        }
+        columnElement.InnerText += builder.ToString();
+        node.AppendChild(columnElement);
+      }
+
+      XmlNode labelProviderNode = document.ImportNode(labelProvider.GetLabelProviderXmlNode(), true);
+      node.AppendChild(labelProviderNode);
+
+      return node;    
+    }
+
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+
+      foreach (XmlNode dataRow in node.ChildNodes) {
+        if (dataRow.Name.Equals("LabelProvider")) {
+          labelProvider = labelProvider.PopulateLabelProviderXmlNode(dataRow);
+        } else {
+          XmlAttributeCollection attrs = dataRow.Attributes;
+          XmlAttribute rowIdAttr = (XmlAttribute)attrs.GetNamedItem("label");
+          string rowLabel = rowIdAttr.Value;
+          DataRow row = new DataRow();
+          row.Label = rowLabel;
+
+          string[] tokens = dataRow.InnerText.Split(';');
+          double[] data = new double[tokens.Length];
+          for (int i = 0; i < data.Length; i++) {
+            if (tokens[i].Length != 0) {
+              if (
+                double.TryParse(tokens[i], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out data[i]) ==
+                false) {
+                throw new FormatException("Can't parse " + tokens[i] + " as double value.");
+              }
+            }
+          }
+          row.AddValues(data);
+          AddDataRow(row);
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDataCollector.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDataCollector.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDataCollector.cs	(revision 1530)
@@ -0,0 +1,83 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Visualization {
+  /// <summary>
+  /// Collects values of specific variable names in a given scope and feeds them into a ChartDataRowsModel.
+  /// </summary>
+  public class ChartDataRowsModelDataCollector : OperatorBase {
+    /// <inheritdoc select="summary"/>
+    public override string Description {
+      get { return @"Collects values of specific variable names in a given scope and feeds them into a ChartDataRowsModel."; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ChartDataRowsModelDataCollector"/> with two variable infos 
+    /// (<c>VariableNames</c> and <c>Values</c>).
+    /// </summary>
+    public ChartDataRowsModelDataCollector() {
+      IVariableInfo variableNamesVariableInfo = new VariableInfo("VariableNames", "Names of variables whose values should be collected", typeof(ItemList<StringData>), VariableKind.In);
+      variableNamesVariableInfo.Local = true;
+      AddVariableInfo(variableNamesVariableInfo);
+      ItemList<StringData> variableNames = new ItemList<StringData>();
+      AddVariable(new Variable("VariableNames", variableNames));
+      AddVariableInfo(new VariableInfo("Model", "Data model in which the collected values should be fed.", typeof(IChartDataRowsModel), VariableKind.New | VariableKind.In | VariableKind.Out));
+    }
+
+    /// <summary>
+    /// Collects the values of a specified list of variable names in the given <paramref name="scope"/>.
+    /// </summary>
+    /// <param name="scope">The scope where to collect the values from.</param>
+    /// <returns><c>null</c>.</returns>
+    public override IOperation Apply(IScope scope) {
+      ItemList<StringData> names = GetVariableValue<ItemList<StringData>>("VariableNames", scope, false);
+      IChartDataRowsModel model = GetVariableValue<IChartDataRowsModel>("Model", scope, true, false);
+
+      // if necessary, add a new model
+      if (model == null) {
+        model = new ChartDataRowsModel();
+        for (int i = 0; i < names.Count; i++)
+          model.AddDataRow(new DataRow(names[i].Data));  // create new data row for each variable name to collect
+
+        IVariableInfo info = GetVariableInfo("Model");
+        if (info.Local)
+          AddVariable(new Variable(info.ActualName, model));
+        else
+          scope.AddVariable(new Variable(scope.TranslateName(info.FormalName), model));
+      }
+
+      // collect data values and feed them into the model
+      for (int i = 0; i < names.Count; i++) {
+        DoubleData data = scope.GetVariableValue(names[i].Data, true) as DoubleData;
+        if (data != null)
+          model.Rows[i].AddValue(data.Data);
+      }
+      return null;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDummy.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDummy.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ChartDataRowsModelDummy.cs	(revision 1530)
@@ -0,0 +1,42 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.Visualization{
+  public class ChartDataRowsModelDummy : ChartDataRowsModel  {
+    
+    public ChartDataRowsModelDummy(){
+      Random rand = new Random();
+
+      // test rows
+
+      // TODO change to call new DataRow("Datarow 1");
+      DataRow row1 = new DataRow();
+      row1.Label = "Datarow 1";
+      row1.Color = Color.Red;
+      DataRow row2 = new DataRow();
+      row2.Label = "Datarow 2";
+      row2.Color = Color.Blue;
+      DataRow row3 = new DataRow();
+      row3.Label = "Datarow 3";
+      row3.Color = Color.DeepPink;
+
+      AddDataRow(row1);
+      AddDataRow(row2);
+      AddDataRow(row3);
+      
+      for (int i = 0; i < 10; i++){
+
+        // TODO Test AddDataRow mit bereits befüllter Row
+
+        row1.AddValue(rand.NextDouble() * 100);
+        row2.AddValues(new double[] { rand.NextDouble() * 100,  
+          rand.NextDouble() * 100 });
+        row3.AddValue(11.0);
+        // TODO after implemention of modifyValue: row1.ModifyValue(row1.getval[i]+100, i);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/CompositeShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/CompositeShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/CompositeShape.cs	(revision 1530)
@@ -0,0 +1,60 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public class CompositeShape : IShape {
+    private IShape parent;
+
+    protected readonly List<IShape> shapes = new List<IShape>();
+    protected RectangleD boundingBox = RectangleD.Empty;
+
+    public virtual void Draw(Graphics graphics) {
+      foreach (IShape shape in shapes) {
+        shape.Draw(graphics);
+      }
+    }
+
+    public RectangleD BoundingBox {
+      get {
+        if (shapes.Count == 0) {
+          throw new InvalidOperationException("No shapes, no bounding box.");
+        }
+
+        return boundingBox;
+      }
+    }
+
+    public RectangleD ClippingArea {
+      get { return Parent.ClippingArea; }
+    }
+
+    public Rectangle Viewport {
+      get { return Parent.Viewport; }
+    }
+
+    public IShape Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    public void ClearShapes() {
+      shapes.Clear();
+      boundingBox = RectangleD.Empty;
+    }
+
+    public void AddShape(IShape shape) {
+      shape.Parent = this;
+
+      if (shapes.Count == 0) {
+        boundingBox = shape.BoundingBox;
+      } else {
+        boundingBox = new RectangleD(Math.Min(boundingBox.X1, shape.BoundingBox.X1),
+                                     Math.Min(boundingBox.Y1, shape.BoundingBox.Y1),
+                                     Math.Max(boundingBox.X2, shape.BoundingBox.X2),
+                                     Math.Max(boundingBox.Y2, shape.BoundingBox.Y2));
+      }
+      shapes.Add(shape);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/DataRow.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/DataRow.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/DataRow.cs	(revision 1530)
@@ -0,0 +1,164 @@
+using System;
+using System.Drawing;
+using System.Collections.Generic;
+using HeuristicLab.Visualization.LabelProvider;
+
+namespace HeuristicLab.Visualization {
+  public enum Action {
+    Added,
+    Modified,
+    Deleted
+  }
+
+  public delegate void DataRowChangedHandler(IDataRow row);
+  public delegate void ValuesChangedHandler(IDataRow row, double[] values, int index, Action action);
+  public delegate void ValueChangedHandler(IDataRow row, double value, int index, Action action);
+
+  public class DataRow : DataRowBase {
+    private readonly List<double> dataRow = new List<double>();
+
+    // TODO implement calculation of min and max values
+    private double minValue = double.MaxValue;
+    private double maxValue = double.MinValue;
+
+    public DataRow() {
+    }
+    
+    public DataRow(string label) {
+      this.Label = label;
+    }
+
+    public DataRow(string label, Color color, int thickness, DrawingStyle style, List<double> dataRow) {
+     this.Label = label;
+      this.Color = color;
+      this.Thickness = thickness;
+      this.Style = style;
+      this.dataRow = dataRow;
+    }
+
+    public override void AddValue(double value) {
+      UpdateMinMaxValue(value);
+
+      dataRow.Add(value);
+      OnValueChanged(value, dataRow.Count - 1, Action.Added);
+    }
+
+    public override void AddValue(double value, int index) {
+      //check if index is valid
+      if (index >= 0 && index < dataRow.Count) {
+        dataRow.Insert(index, value);
+        OnValueChanged(value, index, Action.Added);
+      } else {
+        throw new IndexOutOfRangeException();
+      }   
+    }
+
+    public override void AddValues(double[] values) {
+      int startInd = dataRow.Count;
+
+      foreach (double d in values) {
+        dataRow.Add(d);
+      }
+      OnValuesChanged(values, startInd, Action.Added); 
+    }
+
+    public override void AddValues(double[] values, int index) {
+      int j = index;
+
+      //check if index to start changes is valid
+      if (index >=0 && (index + values.Length) < dataRow.Count) {
+        foreach (double d in values) {
+          dataRow.Insert(j, d);
+          j++;
+        }
+        OnValuesChanged(values, index, Action.Added);
+      } else {
+        throw new IndexOutOfRangeException();
+      }
+    }
+
+    public override void ModifyValue(double value, int index) {
+      //check if index is valid
+      if (index >= 0 && index < dataRow.Count) {
+        dataRow[index] = value;
+        OnValueChanged(value, index, Action.Modified);
+      } else {
+        throw new IndexOutOfRangeException();
+      }
+    }
+
+    public override void ModifyValues(double[] values, int index) {
+      int startInd = index;
+      int modInd = index;
+
+      //check if index to start modification is valid
+      if (startInd >=0 && startInd + values.Length < dataRow.Count) {
+        foreach (double d in values) {
+          dataRow[modInd] = d;
+          modInd++;
+        }
+        OnValuesChanged(values, startInd, Action.Modified);
+      } else {
+        throw new IndexOutOfRangeException();
+      }
+    }
+
+    public override void RemoveValue(int index) {
+      double remVal = dataRow[index];
+      //check if index is valid
+      if (index >= 0 && index < dataRow.Count) {
+        dataRow.RemoveAt(index);
+        OnValueChanged(remVal, index, Action.Deleted);
+      } else {
+        throw new IndexOutOfRangeException();
+      }
+    }
+
+    public override void RemoveValues(int index, int count) {
+      double[] remValues = new double[count]; //removed values
+      int j = 0;
+
+      //check if count is valid
+      if (count > 0) {
+        //check if index is valid
+        if ((index >= 0) && (index + count <= dataRow.Count)) {
+          for (int i = index; i < (index + count); i++) {
+            remValues.SetValue(i, j);
+            dataRow.RemoveAt(i);
+            j++;
+          }
+          OnValuesChanged(remValues, index, Action.Deleted);
+        } else {
+          throw new IndexOutOfRangeException();
+        }
+      } else {
+        throw new Exception("parameter count must be > 0!");
+      }
+    }
+
+    public override int Count {
+      get { return dataRow.Count; }
+    }
+
+    public override double this[int index] {
+      get { return dataRow[index]; }
+      set {
+        dataRow[index] = value;
+        OnValueChanged(value, index, Action.Modified);
+      }
+    }
+
+    public override double MinValue {
+      get { return minValue; }
+    }
+
+    public override double MaxValue {
+      get { return maxValue; }
+    }
+
+    private void UpdateMinMaxValue(double value) {
+      maxValue = Math.Max(value, maxValue);
+      minValue = Math.Min(value, minValue);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/DataRowBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/DataRowBase.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/DataRowBase.cs	(revision 1530)
@@ -0,0 +1,110 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public abstract class DataRowBase : IDataRow {
+    private string label = "";
+    private Color color = Color.Black;
+    private int thickness = 2;
+    private DrawingStyle style = DrawingStyle.Solid;
+    private DataRowType lineType = DataRowType.Normal;
+    private YAxisDescriptor yAxis;
+
+    public string Label {
+      get { return label; }
+      set {
+        label = value;
+        OnDataRowChanged(this);
+      }
+    }
+
+    public Color Color {
+      get { return color; }
+      set {
+        color = value;
+        OnDataRowChanged(this);
+      }
+    }
+
+    public int Thickness {
+      get { return thickness; }
+      set {
+        thickness = value;
+        OnDataRowChanged(this);
+      }
+    }
+
+    public DrawingStyle Style {
+      get { return style; }
+      set {
+        style = value;
+        OnDataRowChanged(this);
+      }
+    }
+
+    public DataRowType LineType {
+      get { return lineType; }
+      set {
+        lineType = value;
+        OnDataRowChanged(this);
+      }
+    }
+
+    public YAxisDescriptor YAxis {
+      get { return yAxis; }
+      set {
+        yAxis = value;
+        yAxis.AddDataRow(this);
+        yAxis.YAxisDescriptorChanged += delegate { OnDataRowChanged(this); };
+        OnDataRowChanged(this);
+      }
+    }
+
+    protected void OnDataRowChanged(IDataRow row) {
+      if (DataRowChanged != null) {
+        DataRowChanged(this);
+      }
+    }
+
+    protected void OnValuesChanged(double[] values, int index, Action action) {
+      if (ValuesChanged != null) {
+        ValuesChanged(this, values, index, action);
+      }
+    }
+
+    protected void OnValueChanged(double value, int index, Action action) {
+      if (ValueChanged != null) {
+        ValueChanged(this, value, index, action);
+      }
+    }
+
+    public abstract void AddValue(double value);
+
+    public abstract void AddValue(double value, int index);
+
+    public abstract void AddValues(double[] values);
+
+    public abstract void AddValues(double[] values, int index);
+
+    public abstract void ModifyValue(double value, int index);
+
+    public abstract void ModifyValues(double[] values, int index);
+
+    public abstract void RemoveValue(int index);
+
+    public abstract void RemoveValues(int index, int count);
+
+    public abstract int Count { get; }
+
+    public abstract double this[int index] { get; set; }
+
+    public abstract double MinValue { get; }
+
+    public abstract double MaxValue { get; }
+
+    public event ValuesChangedHandler ValuesChanged;
+
+    public event ValueChangedHandler ValueChanged;
+
+    public event DataRowChangedHandler DataRowChanged;
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/DrawingStyle.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/DrawingStyle.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/DrawingStyle.cs	(revision 1530)
@@ -0,0 +1,5 @@
+namespace HeuristicLab.Visualization {
+  public enum DrawingStyle {
+    Solid, Dashed
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Grid.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Grid.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Grid.cs	(revision 1530)
@@ -0,0 +1,53 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public class Grid : WorldShape {
+    private Color color = Color.LightBlue;
+
+    public override void Draw(Graphics graphics) {
+      ClearShapes();
+
+      foreach (double y in AxisTicks.GetTicks(YAxis.PixelsPerInterval,
+                                              Parent.Viewport.Height,
+                                              ClippingArea.Height,
+                                              ClippingArea.Y1)) {
+        LineShape line = new LineShape(ClippingArea.X1, y,
+                                       ClippingArea.X2, y,
+                                       color, 1,
+                                       DrawingStyle.Dashed);
+        AddShape(line);
+      }
+
+      foreach (double x in AxisTicks.GetTicks(XAxis.PixelsPerInterval,
+                                              Parent.Viewport.Width,
+                                              ClippingArea.Width,
+                                              ClippingArea.X1)) {
+        LineShape line = new LineShape(x, ClippingArea.Y1,
+                                       x, ClippingArea.Y2,
+                                       color, 1,
+                                       DrawingStyle.Dashed);
+        AddShape(line);
+      }
+
+      LineShape lineZeroX = new LineShape(0, ClippingArea.Y1,
+                                          0, ClippingArea.Y2,
+                                          color, 3,
+                                          DrawingStyle.Dashed);
+
+      LineShape lineZeroY = new LineShape(ClippingArea.X1, 0,
+                                          ClippingArea.X2, 0,
+                                          color, 3,
+                                          DrawingStyle.Dashed);
+
+      AddShape(lineZeroX);
+      AddShape(lineZeroY);
+
+      base.Draw(graphics);
+    }
+
+    public Color Color {
+      get { return color; }
+      set { color = value; }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLab.Visualization.csproj
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLab.Visualization.csproj	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLab.Visualization.csproj	(revision 1530)
@@ -0,0 +1,196 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E392A1E2-DC95-4E33-B82E-8ED690EDA1AB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Visualization</RootNamespace>
+    <AssemblyName>HeuristicLab.Visualization-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <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="AvgAggregator.cs" />
+    <Compile Include="AvgLineAggregator.cs" />
+    <Compile Include="AxisPosition.cs" />
+    <Compile Include="AxisTicks.cs" />
+    <Compile Include="Canvas.cs" />
+    <Compile Include="CanvasUI.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="CanvasUI.Designer.cs">
+      <DependentUpon>CanvasUI.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ChangeType.cs" />
+    <Compile Include="ChartDataModelBase.cs" />
+    <Compile Include="ChartDataRowsModel.cs" />
+    <Compile Include="ChartDataRowsModelDummy.cs" />
+    <Compile Include="CompositeShape.cs" />
+    <Compile Include="ChartDataRowsModelDataCollector.cs" />
+    <Compile Include="DataRowBase.cs" />
+    <Compile Include="LabelProvider\ContinuousLabelProvider.cs" />
+    <Compile Include="LabelProvider\DiscreteLabelProvider.cs" />
+    <Compile Include="Grid.cs" />
+    <Compile Include="HorizontalLineShape.cs" />
+    <Compile Include="LabelProvider\ILabelProvider.cs" />
+    <Compile Include="IMouseEventListener.cs" />
+    <Compile Include="Legend\LegendItem.cs" />
+    <Compile Include="MaxAggregator.cs" />
+    <Compile Include="MinAggregator.cs" />
+    <Compile Include="Options\OptionsDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Options\OptionsDialog.Designer.cs">
+      <DependentUpon>OptionsDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Options\ViewSettings.cs" />
+    <Compile Include="PanListener.cs" />
+    <Compile Include="LabelProvider\StringLabelProvider.cs" />
+    <Compile Include="TextShape.cs" />
+    <Compile Include="Legend\LegendShape.cs" />
+    <Compile Include="DataRow.cs" />
+    <Compile Include="DrawingStyle.cs" />
+    <Compile Include="HeuristicLabVisualizationPlugin.cs" />
+    <Compile Include="IChartDataModel.cs" />
+    <Compile Include="IChartDataRowsModel.cs" />
+    <Compile Include="IDataRow.cs" />
+    <Compile Include="IShape.cs" />
+    <Compile Include="LineChart.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="LineChart.Designer.cs">
+      <DependentUpon>LineChart.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LineShape.cs" />
+    <Compile Include="Offset.cs" />
+    <Compile Include="PointD.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RectangleD.cs" />
+    <Compile Include="RectangleShape.cs" />
+    <Compile Include="SizeD.cs" />
+    <Compile Include="Transform.cs" />
+    <Compile Include="Translate.cs" />
+    <Compile Include="WorldShape.cs" />
+    <Compile Include="XAxis.cs" />
+    <Compile Include="YAxis.cs" />
+    <Compile Include="YAxisDescriptor.cs" />
+    <Compile Include="ZoomListener.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="LineChart.resx">
+      <DependentUpon>LineChart.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Options\OptionsDialog.resx">
+      <DependentUpon>OptionsDialog.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLabVisualizationPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLabVisualizationPlugin.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/HeuristicLabVisualizationPlugin.cs	(revision 1530)
@@ -0,0 +1,30 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Visualization {
+  [ClassInfo(Name = "HeuristicLab.Visualization-3.2")]
+  [PluginFile(Filename = "HeuristicLab.Visualization-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  public class HeuristicLabVisualizationPlugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/HorizontalLineShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/HorizontalLineShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/HorizontalLineShape.cs	(revision 1530)
@@ -0,0 +1,25 @@
+﻿using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public class HorizontalLineShape : LineShape {
+    /// <summary>
+    /// Initializes the LineShape.
+    /// </summary>
+    /// <param name="x1">x coordinate of left lineEndPoind</param>
+    /// <param name="y1">y coordinate of left lineEndPoind</param>
+    /// <param name="x2">x coordinate of right lineEndPoind</param>
+    /// <param name="y2">y coordinate of right lineEndPoind</param>
+    /// <param name="color">color for the LineShape</param>
+    /// <param name="thickness">tickness of the line in pixels</param>
+    /// <param name="drawingStyle">drawing style of the line (solid, dashed, dotted,...)</param>
+    public HorizontalLineShape(double x1, double y1, double x2, double y2, Color color, int thickness,
+                               DrawingStyle drawingStyle) : base(x1, y1, x2, y2, color, thickness, drawingStyle) {}
+
+    public override void Draw(Graphics graphics) {
+      X1 = Parent.ClippingArea.X1;
+      X2 = Parent.ClippingArea.X2;
+      Y2 = Y1;
+      base.Draw(graphics);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/IChartDataModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/IChartDataModel.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/IChartDataModel.cs	(revision 1530)
@@ -0,0 +1,10 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Visualization {
+  interface IChartDataModel : IItem {
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/IChartDataRowsModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/IChartDataRowsModel.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/IChartDataRowsModel.cs	(revision 1530)
@@ -0,0 +1,28 @@
+﻿using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Visualization.LabelProvider;
+using HeuristicLab.Visualization.Options;
+
+namespace HeuristicLab.Visualization {
+  public interface IChartDataRowsModel : IItem {
+    string Title { get; set; }
+    List<IDataRow> Rows { get; }
+    ILabelProvider XAxisLabelProvider { get; set; }
+
+    List<YAxisDescriptor> YAxes { get; }
+
+    void AddDataRow(IDataRow row);
+    void RemoveDataRow(IDataRow row);
+
+    int MaxDataRowValues { get; }
+
+    ViewSettings ViewSettings { get; set; }
+
+    string XAxisLabel { get; set; }
+    bool ShowXAxisLabel { get; set; }
+
+    event ModelChangedHandler ModelChanged;
+    event DataRowAddedHandler DataRowAdded;
+    event DataRowRemovedHandler DataRowRemoved;
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/IDataRow.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/IDataRow.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/IDataRow.cs	(revision 1530)
@@ -0,0 +1,38 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public enum DataRowType {
+    Normal, SingleValue
+  }
+
+  public interface IDataRow {
+    string Label { get; set; }
+    Color Color { get; set; }
+    int Thickness { get; set; }
+    DrawingStyle Style { get; set; }
+    DataRowType LineType { get; set; }
+ 
+    YAxisDescriptor YAxis { get; set; }
+
+    void AddValue(double value);
+    void AddValue(double value, int index);
+    void AddValues(double[] values);
+    void AddValues(double[] values, int index);
+
+    void ModifyValue(double value, int index);
+    void ModifyValues(double[] values, int index);
+
+    void RemoveValue(int index);
+    void RemoveValues(int index, int count);
+
+    int Count { get; }
+    double this[int index] { get; set; }
+
+    double MinValue { get; }
+    double MaxValue { get; }
+
+    event ValuesChangedHandler ValuesChanged;
+    event ValueChangedHandler ValueChanged;
+    event DataRowChangedHandler DataRowChanged;
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/IMouseEventListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/IMouseEventListener.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/IMouseEventListener.cs	(revision 1530)
@@ -0,0 +1,12 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Visualization {
+  public interface IMouseEventListener {
+    void MouseMove(object sender, MouseEventArgs e);
+    void MouseUp(object sender, MouseEventArgs e);
+  }
+
+  public delegate void MoveHandler(Point startPoint, Point endPoint);
+  public delegate void RectangleHandler(Rectangle rectangle);
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/IShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/IShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/IShape.cs	(revision 1530)
@@ -0,0 +1,39 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  /// <summary>
+  /// This is the base interface that has to be implemented by all shapes.
+  /// 
+  /// View port
+  ///   The view port is the available drawing area on the screen.
+  ///   It is specified in the GDI coordinate system.
+  /// 
+  /// Clipping area
+  ///   The clipping area is the range of values visible on the view port.
+  ///   Values outside this area will not be visible (they "get clipped").
+  ///   It can either be inherited from the parent, or it can be overriden
+  ///   to create distorted realities (see world shapes).
+  ///   It is specified in a world coordinate system.
+  /// 
+  /// Bounding box
+  ///   The bounding box is the location and the size of a shape on its parent.
+  ///   It is specified in the parent's world coordinate system.
+  /// </summary>
+  public interface IShape {
+    /// <summary>
+    /// Draws the shape
+    /// </summary>
+    /// <param name="graphics">The Graphics object used to draw the shape</param>
+    void Draw(Graphics graphics);
+
+    /// <summary>
+    /// The shape's bounding box
+    /// </summary>
+    RectangleD BoundingBox { get; }
+
+    RectangleD ClippingArea { get; }
+    Rectangle Viewport { get; }
+
+    IShape Parent { get; set; }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ContinuousLabelProvider.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ContinuousLabelProvider.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ContinuousLabelProvider.cs	(revision 1530)
@@ -0,0 +1,38 @@
+using System.Globalization;
+using System.Xml;
+
+namespace HeuristicLab.Visualization.LabelProvider {
+  public class ContinuousLabelProvider : ILabelProvider {
+    private readonly string format;
+
+    public ContinuousLabelProvider() {}
+
+    public ContinuousLabelProvider(string format) {
+      this.format = format;
+    }
+
+    public string GetLabel(double value) {
+      return value.ToString(format, CultureInfo.InvariantCulture);
+    }
+
+    public XmlNode GetLabelProviderXmlNode()
+    {
+      XmlDocument Xdoc = new XmlDocument();
+
+      XmlNode lblProvInfo = Xdoc.CreateNode(XmlNodeType.Element, "LabelProvider", null);
+      lblProvInfo.InnerText = "ContinuousLabelProvider";
+
+      XmlAttribute idFormat = Xdoc.CreateAttribute("format");
+      idFormat.Value = this.format;
+
+      lblProvInfo.Attributes.Append(idFormat);
+
+      return lblProvInfo;
+    }
+
+    public ILabelProvider PopulateLabelProviderXmlNode(XmlNode node) {
+      var labelProvider = new ContinuousLabelProvider(node.SelectSingleNode("//LabelProvider").Attributes[0].Value);
+      return labelProvider;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/DiscreteLabelProvider.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/DiscreteLabelProvider.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/DiscreteLabelProvider.cs	(revision 1530)
@@ -0,0 +1,31 @@
+using System;
+using System.Xml;
+
+namespace HeuristicLab.Visualization.LabelProvider {
+  public class DiscreteLabelProvider : ILabelProvider {
+    public string GetLabel(double value) {
+      int index = (int)Math.Round(value);
+      double delta = Math.Abs(index - value);
+
+      if (delta < 1e-10)
+        return index.ToString();
+      else
+        return string.Empty;
+    }
+
+    public XmlNode GetLabelProviderXmlNode()
+    {
+      XmlDocument Xdoc = new XmlDocument();
+
+      XmlNode lblProvInfo = Xdoc.CreateNode(XmlNodeType.Element, "LabelProvider", null);
+      lblProvInfo.InnerText = "DiscreteLabelProvider";
+
+      return lblProvInfo;
+    }
+
+    public ILabelProvider PopulateLabelProviderXmlNode(XmlNode node) {
+      var labelProvider = new DiscreteLabelProvider();
+      return labelProvider;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ILabelProvider.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ILabelProvider.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/ILabelProvider.cs	(revision 1530)
@@ -0,0 +1,9 @@
+using System.Xml;
+
+namespace HeuristicLab.Visualization.LabelProvider {
+  public interface ILabelProvider {
+    string GetLabel(double value);
+    XmlNode GetLabelProviderXmlNode();
+    ILabelProvider PopulateLabelProviderXmlNode(XmlNode node);
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/StringLabelProvider.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/StringLabelProvider.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LabelProvider/StringLabelProvider.cs	(revision 1530)
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Visualization.LabelProvider;
+using System.Xml;
+
+namespace HeuristicLab.Visualization.LabelProvider {
+  public class StringLabelProvider : ILabelProvider {
+    private readonly Dictionary<int, string> labels = new Dictionary<int, string>();
+
+    public void ClearLabels() {
+      labels.Clear();
+    }
+
+    public void SetLabel(int index, string label) {
+      labels[index] = label;
+    }
+
+    public string GetLabel(double value) {
+      int index = (int)Math.Round(value);
+      double delta = Math.Abs(index - value);
+
+      string label;
+
+      if (delta < 1e-10 && labels.TryGetValue(index, out label))
+        return label;
+      else
+        return string.Empty;
+    }
+
+    public XmlNode GetLabelProviderXmlNode() {
+      XmlDocument Xdoc = new XmlDocument();
+
+      XmlNode lblProvInfo = Xdoc.CreateNode(XmlNodeType.Element, "LabelProvider", null);
+      lblProvInfo.InnerText = "StringLabelProvider";
+
+      foreach (KeyValuePair<int, string> pair in labels)
+      {
+        XmlNode strLbl = Xdoc.CreateNode(XmlNodeType.Element, "String", null);
+
+        XmlAttribute idStrLbl = Xdoc.CreateAttribute("id");
+        idStrLbl.Value = pair.Key.ToString();
+        strLbl.Attributes.Append(idStrLbl);
+
+        strLbl.InnerText = pair.Value;
+        lblProvInfo.AppendChild(strLbl);
+      }
+      return lblProvInfo;
+    }
+
+    public ILabelProvider PopulateLabelProviderXmlNode(XmlNode node) {
+      var labelProvider = new StringLabelProvider();
+
+      foreach (XmlNode strLbl in node.SelectNodes("//String"))
+      {
+        labelProvider.SetLabel(int.Parse(strLbl.Attributes[0].Value), strLbl.InnerText);
+      }
+      return labelProvider;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendItem.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendItem.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendItem.cs	(revision 1530)
@@ -0,0 +1,18 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization.Legend {
+  public class LegendItem {
+
+    public static readonly int WIDTH = 100;
+
+    public LegendItem(string label, Color color, int thickness) {
+      Label = label;
+      Color = color;
+      Thickness = thickness;
+    }
+
+    public string Label { get; set; }
+    public Color Color { get; set; }
+    public int Thickness { get; set; }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendShape.cs	(revision 1530)
@@ -0,0 +1,212 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace HeuristicLab.Visualization.Legend {
+  public enum LegendPosition {
+    Top,
+    Bottom,
+    Left,
+    Right
+  }
+
+  public class LegendShape : WorldShape {
+    private readonly IList<LegendItem> legendItems = new List<LegendItem>();
+    // legend draw default value: column
+    private bool row;
+    private bool top;
+
+    private Color color = Color.Blue;
+    private Font font = new Font("Arial", 8);
+
+    public LegendShape() {
+      CreateLegend();
+    }
+
+    public bool Row {
+      set { row = value; }
+      get { return row; }
+    }
+
+    public bool Top {
+      set { top = value; }
+      get { return top; }
+    }
+
+    private bool ExistsLegendItems() {
+      return legendItems.Count > 0;
+    }
+    
+    /// <summary>
+    /// paints the legend on the canvas
+    /// </summary>
+    public void CreateLegend() {
+      if (ExistsLegendItems()) {
+        ClearShapes();
+        double x = ClippingArea.X1;
+        double y = ClippingArea.Y2;
+
+        int numberOfItemsPerRow = 1;
+        if (row) {
+          numberOfItemsPerRow = GetNrOfItemsPerRow();
+          if (!top) {
+            y = GetHeight4Rows();
+          }
+        }
+        int rowCounter = 0;
+        foreach (LegendItem item in legendItems) {
+          if (!row) {
+            CreateColumn(item, y);
+            y -= Font.Height;
+          } else {
+            if (rowCounter >= numberOfItemsPerRow) {
+              x = ClippingArea.X1;
+              y -= Font.Height+15;
+              rowCounter = 0;
+            }
+            CreateRow(item, x, y);
+            x += GetLabelLengthInPixel(item);
+            rowCounter++;
+          }
+        }
+      }
+    }
+
+    /// <summary>
+    /// returns die optimal height for the top or bottom legend
+    /// </summary>
+    /// <returns></returns>
+    private int GetHeight4Rows() {
+      int numberOfItemsPerRow = GetNrOfItemsPerRow();
+      int nrOfItems = legendItems.Count;
+      int rowsToDraw = 1;
+      if (nrOfItems > numberOfItemsPerRow) {
+        int rest;
+        int value = Math.DivRem(nrOfItems, numberOfItemsPerRow, out rest);
+        if (rest > 1) {
+          rowsToDraw = rest;
+        } else {
+          rowsToDraw = value + rest;
+        }
+      }
+      return (Font.Height+12)*rowsToDraw;
+    }
+
+    /// <summary>
+    /// returns the maximum number of items per row to paint
+    /// </summary>
+    /// <returns></returns>
+    private int GetNrOfItemsPerRow() {
+      int numberOfItemsPerRow = (int)ClippingArea.Width / GetMaxLabelLength();
+      // if the width of the clippingarea < maxLabelLength
+      if (numberOfItemsPerRow == 0) numberOfItemsPerRow = 1;
+      return numberOfItemsPerRow;
+    }
+
+    /// <summary>
+    /// returns the length of the current legenditem in pixel
+    /// </summary>
+    /// <param name="item"></param>
+    /// <returns></returns>
+    private int GetLabelLengthInPixel(LegendItem item) {
+      int dummy = (int)(item.Label.Length*Font.Size + 20);
+      if (dummy < LegendItem.WIDTH) {
+        return LegendItem.WIDTH;
+      }
+      return dummy;
+    }
+
+    /// <summary>
+    /// draws the legend as a row at the top or bottom of the WorldShape
+    /// </summary>
+    /// <param name="item">the legenditem to draw</param>
+    /// <param name="x">x axis to draw the item</param>
+    /// <param name="y">y axis to draw the item</param>
+    private void CreateRow(LegendItem item, double x, double y) {
+      AddShape(new LineShape(x, y - (Font.Height / 2), x + 20, y - (Font.Height / 2), item.Color, item.Thickness, DrawingStyle.Solid));
+      AddShape(new TextShape(x + 25, y, item.Label, Font, Color));
+    }
+
+    /// <summary>
+    /// draws the legend as a column on the right or left side of the WorldShape
+    /// </summary>
+    /// <param name="item">the legenditem to draw</param>
+    /// <param name="y">y axis to draw the item</param>
+    private void CreateColumn(LegendItem item, double y) {
+      AddShape(new LineShape(10, y - (Font.Height / 2), 30, y - (Font.Height / 2), item.Color, item.Thickness, DrawingStyle.Solid));
+      AddShape(new TextShape(Font.Height+12, y, item.Label, Font, Color));
+    }
+
+    /// <summary>
+    /// adds a legenditem to the items list
+    /// </summary>
+    /// <param name="item">legenditem to add</param>
+    public void AddLegendItem(LegendItem item) {
+      legendItems.Add(item);
+    }
+
+    /// <summary>
+    /// searches the longest label and returns it with factor of the the current font size
+    /// useful to set the width of the legend
+    /// </summary>
+    /// <returns>max label length with factor of the current font size</returns>
+    public int GetMaxLabelLength() {
+      int maxLabelLength = 0;
+      if (ExistsLegendItems()) {
+        maxLabelLength = legendItems[0].Label.Length;
+        foreach (var item in legendItems) {
+          if (item.Label.Length > maxLabelLength) {
+            maxLabelLength = item.Label.Length;
+          }
+        }
+        maxLabelLength = (int)(maxLabelLength*Font.Size);
+      }
+      return maxLabelLength < LegendItem.WIDTH ? LegendItem.WIDTH : maxLabelLength;
+    }
+
+    /// <summary>
+    /// removes a legenditem from the items list
+    /// </summary>
+    /// <param name="item">legenditem to remove</param>
+    public void RemoveLegendItem(LegendItem item) {
+      legendItems.Remove(item);
+    }
+
+    /// <summary>
+    /// deletes the legenditem list
+    /// </summary>
+    public void ClearLegendItems() {
+      legendItems.Clear();
+    }
+
+    public Color Color {
+      get { return color; }
+      set {
+        color = value;
+        UpdateTextShapes();
+      }
+    }
+
+    public Font Font {
+      get { return font; }
+      set {
+        font = value;
+        UpdateTextShapes();
+      }
+    }
+
+    /// <summary>
+    /// updates the font settings of the legend
+    /// </summary>
+    private void UpdateTextShapes() {
+      foreach (IShape shape in shapes) {
+        TextShape textShape = shape as TextShape;
+
+        if (textShape != null) {
+          textShape.Font = font;
+          textShape.Color = color;
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LineChart.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LineChart.Designer.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LineChart.Designer.cs	(revision 1530)
@@ -0,0 +1,87 @@
+﻿using System.Windows.Forms;
+
+namespace HeuristicLab.Visualization
+{
+    partial class LineChart
+    {
+        /// <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();
+          this.canvasUI = new HeuristicLab.Visualization.CanvasUI();
+          this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
+          this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+          this.contextMenuStrip1.SuspendLayout();
+          this.SuspendLayout();
+          // 
+          // canvasUI
+          // 
+          this.canvasUI.Dock = System.Windows.Forms.DockStyle.Fill;
+          this.canvasUI.Location = new System.Drawing.Point(0, 0);
+          this.canvasUI.Name = "canvasUI";
+          this.canvasUI.Size = new System.Drawing.Size(551, 373);
+          this.canvasUI.TabIndex = 0;
+          this.canvasUI.Text = "canvas";
+          this.canvasUI.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.canvasUI1_MouseWheel);
+          this.canvasUI.MouseMove += new System.Windows.Forms.MouseEventHandler(this.canvasUI_MouseMove);
+          this.canvasUI.ContextMenuStripChanged += new System.EventHandler(this.optionsToolStripMenuItem_Click);
+          this.canvasUI.MouseDown += new System.Windows.Forms.MouseEventHandler(this.canvasUI1_MouseDown);
+          this.canvasUI.MouseUp += new System.Windows.Forms.MouseEventHandler(this.canvasUI_MouseUp);
+          this.canvasUI.KeyDown += new System.Windows.Forms.KeyEventHandler(this.canvasUI1_KeyDown);
+          // 
+          // contextMenuStrip1
+          // 
+          this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.optionsToolStripMenuItem});
+          this.contextMenuStrip1.Name = "contextMenuStrip1";
+          this.contextMenuStrip1.Size = new System.Drawing.Size(123, 26);
+          // 
+          // optionsToolStripMenuItem
+          // 
+          this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
+          this.optionsToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
+          this.optionsToolStripMenuItem.Text = "Options";
+          this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
+          // 
+          // LineChart
+          // 
+          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+          this.Controls.Add(this.canvasUI);
+          this.Name = "LineChart";
+          this.Size = new System.Drawing.Size(551, 373);
+          this.contextMenuStrip1.ResumeLayout(false);
+          this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private CanvasUI canvasUI;
+        private ContextMenuStrip contextMenuStrip1;
+        private ToolStripMenuItem optionsToolStripMenuItem;
+    }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LineChart.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LineChart.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LineChart.cs	(revision 1530)
@@ -0,0 +1,636 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Visualization.Legend;
+using HeuristicLab.Visualization.Options;
+using HeuristicLab.Visualization.Test;
+
+namespace HeuristicLab.Visualization {
+  public partial class LineChart : ViewBase {
+    private readonly IChartDataRowsModel model;
+    private readonly Canvas canvas;
+
+    private readonly TextShape titleShape = new TextShape("Title");
+    private readonly LegendShape legendShape = new LegendShape();
+    private readonly XAxis xAxis = new XAxis();
+    private readonly List<RowEntry> rowEntries = new List<RowEntry>();
+
+    private readonly Dictionary<IDataRow, RowEntry> rowToRowEntry = new Dictionary<IDataRow, RowEntry>();
+
+    private readonly ViewSettings viewSettings;
+
+    private readonly WorldShape userInteractionShape = new WorldShape();
+    private readonly RectangleShape rectangleShape = new RectangleShape(0, 0, 0, 0, Color.FromArgb(50, 0, 0, 255));
+    private IMouseEventListener mouseEventListener;
+
+    private const int YAxisWidth = 100;
+    private const int XAxisHeight = 40;
+
+    /// <summary>
+    /// This constructor shouldn't be called. Only required for the designer.
+    /// </summary>
+    public LineChart() {
+      InitializeComponent();
+    }
+
+    /// <summary>
+    /// Initializes the chart.
+    /// </summary>
+    /// <param name="model">Referenz to the model, for data</param>
+    public LineChart(IChartDataRowsModel model) : this() {
+      if (model == null) {
+        throw new NullReferenceException("Model cannot be null.");
+      }
+
+      canvas = canvasUI.Canvas;
+
+      this.model = model;
+      viewSettings = model.ViewSettings;
+      viewSettings.OnUpdateSettings += UpdateViewSettings;
+
+      Item = model;
+
+      UpdateLayout();
+      canvasUI.Resize += delegate { UpdateLayout(); };
+
+      ZoomToFullView();
+    }
+
+    /// <summary>
+    /// updates the view settings
+    /// </summary>
+    private void UpdateViewSettings() {
+      titleShape.Font = viewSettings.TitleFont;
+      titleShape.Color = viewSettings.TitleColor;
+
+      legendShape.Font = viewSettings.LegendFont;
+      legendShape.Color = viewSettings.LegendColor;
+
+      xAxis.Font = viewSettings.XAxisFont;
+      xAxis.Color = viewSettings.XAxisColor;
+
+      SetLegendPosition();
+
+      canvasUI.Invalidate();
+    }
+
+    /// <summary>
+    /// Layout management - arranges the inner shapes.
+    /// </summary>
+    private void UpdateLayout() {
+      canvas.ClearShapes();
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        if (yAxisDescriptor.ShowGrid) {
+          info.Grid.Color = yAxisDescriptor.GridColor;
+          canvas.AddShape(info.Grid);
+        }
+      }
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        canvas.AddShape(rowEntry.LinesShape);
+      }
+
+      xAxis.ShowLabel = model.ShowXAxisLabel;
+      xAxis.Label = model.XAxisLabel;
+
+      canvas.AddShape(xAxis);
+
+      int yAxesWidthLeft = 0;
+      int yAxesWidthRight = 0;
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        if (yAxisDescriptor.ShowYAxis) {
+          canvas.AddShape(info.YAxis);
+          info.YAxis.ShowLabel = yAxisDescriptor.ShowYAxisLabel;
+          info.YAxis.Label = yAxisDescriptor.Label;
+          info.YAxis.Position = yAxisDescriptor.Position;
+          switch (yAxisDescriptor.Position) {
+            case AxisPosition.Left:
+              yAxesWidthLeft += YAxisWidth;
+              break;
+            case AxisPosition.Right:
+              yAxesWidthRight += YAxisWidth;
+              break;
+            default:
+              throw new NotImplementedException();
+          }
+        }
+      }
+
+      canvas.AddShape(titleShape);
+      canvas.AddShape(legendShape);
+
+      canvas.AddShape(userInteractionShape);
+
+      titleShape.X = 10;
+      titleShape.Y = canvasUI.Height - 10;
+
+      RectangleD linesAreaBoundingBox = new RectangleD(yAxesWidthLeft,
+                                                       XAxisHeight,
+                                                       canvasUI.Width - yAxesWidthRight,
+                                                       canvasUI.Height);
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        rowEntry.LinesShape.BoundingBox = linesAreaBoundingBox;
+      }
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        info.Grid.BoundingBox = linesAreaBoundingBox;
+      }
+
+      int yAxisLeft = 0;
+      int yAxisRight = (int)linesAreaBoundingBox.X2;
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        if (yAxisDescriptor.ShowYAxis) {
+          switch (yAxisDescriptor.Position) {
+            case AxisPosition.Left:
+              info.YAxis.BoundingBox = new RectangleD(yAxisLeft,
+                                                      linesAreaBoundingBox.Y1,
+                                                      yAxisLeft + YAxisWidth,
+                                                      linesAreaBoundingBox.Y2);
+              yAxisLeft += YAxisWidth;
+              break;
+            case AxisPosition.Right:
+              info.YAxis.BoundingBox = new RectangleD(yAxisRight,
+                                                      linesAreaBoundingBox.Y1,
+                                                      yAxisRight + YAxisWidth,
+                                                      linesAreaBoundingBox.Y2);
+              yAxisRight += YAxisWidth;
+              break;
+            default:
+              throw new NotImplementedException();
+          }
+        }
+      }
+
+      userInteractionShape.BoundingBox = linesAreaBoundingBox;
+      userInteractionShape.ClippingArea = new RectangleD(0, 0, userInteractionShape.BoundingBox.Width, userInteractionShape.BoundingBox.Height);
+
+      xAxis.BoundingBox = new RectangleD(linesAreaBoundingBox.X1,
+                                         0,
+                                         linesAreaBoundingBox.X2,
+                                         linesAreaBoundingBox.Y1);
+
+      SetLegendPosition();
+    }
+
+    private readonly Dictionary<YAxisDescriptor, YAxisInfo> yAxisInfos = new Dictionary<YAxisDescriptor, YAxisInfo>();
+
+    private YAxisInfo GetYAxisInfo(YAxisDescriptor yAxisDescriptor) {
+      YAxisInfo info;
+
+      if (!yAxisInfos.TryGetValue(yAxisDescriptor, out info)) {
+        info = new YAxisInfo();
+        yAxisInfos[yAxisDescriptor] = info;
+      }
+
+      return info;
+    }
+
+    /// <summary>
+    /// sets the legend position
+    /// </summary>
+    private void SetLegendPosition() {
+      switch (viewSettings.LegendPosition) {
+        case LegendPosition.Bottom:
+          setLegendBottom();
+          break;
+
+        case LegendPosition.Top:
+          setLegendTop();
+          break;
+
+        case LegendPosition.Left:
+          setLegendLeft();
+          break;
+
+        case LegendPosition.Right:
+          setLegendRight();
+          break;
+      }
+    }
+
+    public void setLegendRight() {
+      // legend right
+      legendShape.BoundingBox = new RectangleD(canvasUI.Width - legendShape.GetMaxLabelLength(), 10, canvasUI.Width, canvasUI.Height - 50);
+      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
+      legendShape.Row = false;
+      legendShape.CreateLegend();
+    }
+
+    public void setLegendLeft() {
+      // legend left
+      legendShape.BoundingBox = new RectangleD(10, 10, canvasUI.Width, canvasUI.Height - 50);
+      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
+      legendShape.Row = false;
+      legendShape.CreateLegend();
+
+      canvasUI.Invalidate();
+    }
+
+    public void setLegendTop() {
+      // legend top
+      legendShape.BoundingBox = new RectangleD(100, canvasUI.Height - canvasUI.Height, canvasUI.Width, canvasUI.Height - 10);
+      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
+      legendShape.Row = true;
+      legendShape.Top = true;
+      legendShape.CreateLegend();
+    }
+
+    public void setLegendBottom() {
+      // legend bottom
+      legendShape.BoundingBox = new RectangleD(100, 10, canvasUI.Width, canvasUI.Height/*legendShape.GetHeight4Rows()*/);
+      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
+      legendShape.Row = true;
+      legendShape.Top = false;
+      legendShape.CreateLegend();
+    }
+
+    private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
+      OptionsDialog optionsdlg = new OptionsDialog(model);
+      optionsdlg.Show();
+    }
+
+    public void OnDataRowChanged(IDataRow row) {
+      RowEntry rowEntry = rowToRowEntry[row];
+
+      rowEntry.LinesShape.UpdateStyle(row);
+
+      UpdateLayout();
+
+      canvasUI.Invalidate();
+    }
+
+    #region Add-/RemoveItemEvents
+
+    protected override void AddItemEvents() {
+      base.AddItemEvents();
+
+      model.DataRowAdded += OnDataRowAdded;
+      model.DataRowRemoved += OnDataRowRemoved;
+      model.ModelChanged += OnModelChanged;
+
+      foreach (IDataRow row in model.Rows) {
+        OnDataRowAdded(row);
+      }
+    }
+
+    protected override void RemoveItemEvents() {
+      base.RemoveItemEvents();
+
+      model.DataRowAdded -= OnDataRowAdded;
+      model.DataRowRemoved -= OnDataRowRemoved;
+      model.ModelChanged -= OnModelChanged;
+    }
+
+    private void OnDataRowAdded(IDataRow row) {
+      row.ValueChanged += OnRowValueChanged;
+      row.ValuesChanged += OnRowValuesChanged;
+      row.DataRowChanged += OnDataRowChanged;
+
+      legendShape.AddLegendItem(new LegendItem(row.Label, row.Color, row.Thickness));
+      legendShape.CreateLegend();
+
+      InitLineShapes(row);
+
+      UpdateLayout();
+    }
+
+    private void OnDataRowRemoved(IDataRow row) {
+      row.ValueChanged -= OnRowValueChanged;
+      row.ValuesChanged -= OnRowValuesChanged;
+      row.DataRowChanged -= OnDataRowChanged;
+
+      rowToRowEntry.Remove(row);
+      rowEntries.RemoveAll(delegate(RowEntry rowEntry) { return rowEntry.DataRow == row; });
+
+      UpdateLayout();
+    }
+
+    #endregion
+
+    public void ZoomToFullView() {
+      SetClipX(-0.1, model.MaxDataRowValues - 0.9);
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        YAxisDescriptor yAxisDescriptor = rowEntry.DataRow.YAxis;
+
+        SetClipY(rowEntry,
+                 yAxisDescriptor.MinValue - ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05),
+                 yAxisDescriptor.MaxValue + ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05));
+      }
+
+      canvasUI.Invalidate();
+    }
+
+    private void SetClipX(double x1, double x2) {
+      xAxis.ClippingArea = new RectangleD(x1,
+                                          0,
+                                          x2,
+                                          XAxisHeight);
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        rowEntry.LinesShape.ClippingArea = new RectangleD(x1,
+                                                          rowEntry.LinesShape.ClippingArea.Y1,
+                                                          x2,
+                                                          rowEntry.LinesShape.ClippingArea.Y2);
+      }
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        info.Grid.ClippingArea = new RectangleD(x1,
+                                                info.Grid.ClippingArea.Y1,
+                                                x2,
+                                                info.Grid.ClippingArea.Y2);
+        info.YAxis.ClippingArea = new RectangleD(0,
+                                                 info.YAxis.ClippingArea.Y1,
+                                                 YAxisWidth,
+                                                 info.YAxis.ClippingArea.Y2);
+      }
+    }
+
+    private void SetClipY(RowEntry rowEntry, double y1, double y2) {
+      rowEntry.LinesShape.ClippingArea = new RectangleD(rowEntry.LinesShape.ClippingArea.X1,
+                                                        y1,
+                                                        rowEntry.LinesShape.ClippingArea.X2,
+                                                        y2);
+
+      YAxisInfo info = GetYAxisInfo(rowEntry.DataRow.YAxis);
+
+      info.Grid.ClippingArea = new RectangleD(info.Grid.ClippingArea.X1,
+                                              y1,
+                                              info.Grid.ClippingArea.X2,
+                                              y2);
+      info.YAxis.ClippingArea = new RectangleD(info.YAxis.ClippingArea.X1,
+                                               y1,
+                                               info.YAxis.ClippingArea.X2,
+                                               y2);
+    }
+
+    private void InitLineShapes(IDataRow row) {
+      RowEntry rowEntry = new RowEntry(row);
+      rowEntries.Add(rowEntry);
+      rowToRowEntry[row] = rowEntry;
+
+      if ((row.LineType == DataRowType.SingleValue)) {
+        if (row.Count > 0) {
+          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
+                                                        row.Style);
+          rowEntry.LinesShape.AddShape(lineShape);
+        }
+      } else {
+        for (int i = 1; i < row.Count; i++) {
+          LineShape lineShape = new LineShape(i - 1, row[i - 1], i, row[i], row.Color, row.Thickness, row.Style);
+          rowEntry.LinesShape.AddShape(lineShape);
+        }
+      }
+
+      ZoomToFullView();
+    }
+
+    private void OnRowValueChanged(IDataRow row, double value, int index, Action action) {
+      RowEntry rowEntry = rowToRowEntry[row];
+
+      if (row.LineType == DataRowType.SingleValue) {
+        if (action == Action.Added) {
+          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
+                                                        row.Style);
+          rowEntry.LinesShape.AddShape(lineShape);
+        } else {
+          LineShape lineShape = rowEntry.LinesShape.GetShape(0);
+          lineShape.Y1 = value;
+          lineShape.Y2 = value;
+        }
+      } else {
+        if (index > rowEntry.LinesShape.Count + 1) {
+          throw new NotImplementedException();
+        }
+
+        // new value was added
+        if (index > 0 && index == rowEntry.LinesShape.Count + 1) {
+          LineShape lineShape = new LineShape(index - 1, row[index - 1], index, row[index], row.Color, row.Thickness, row.Style);
+          rowEntry.LinesShape.AddShape(lineShape);
+        }
+
+        // not the first value
+        if (index > 0) {
+          rowEntry.LinesShape.GetShape(index - 1).Y2 = value;
+        }
+
+        // not the last value
+        if (index > 0 && index < row.Count - 1) {
+          rowEntry.LinesShape.GetShape(index).Y1 = value;
+        }
+      }
+
+      ZoomToFullView();
+    }
+
+    private void OnRowValuesChanged(IDataRow row, double[] values, int index, Action action) {
+      foreach (double value in values) {
+        OnRowValueChanged(row, value, index++, action);
+      }
+    }
+
+    private void OnModelChanged() {
+      titleShape.Text = model.Title;
+
+      canvasUI.Invalidate();
+    }
+
+    #region Begin-/EndUpdate
+
+    private int beginUpdateCount;
+
+    public void BeginUpdate() {
+      beginUpdateCount++;
+    }
+
+    public void EndUpdate() {
+      if (beginUpdateCount == 0) {
+        throw new InvalidOperationException("Too many EndUpdates.");
+      }
+
+      beginUpdateCount--;
+
+      if (beginUpdateCount == 0) {
+        canvasUI.Invalidate();
+      }
+    }
+
+    #endregion
+
+    #region Zooming / Panning
+
+    private void Pan(Point startPoint, Point endPoint) {
+      RectangleD clippingArea = Translate.ClippingArea(startPoint, endPoint, xAxis.ClippingArea, xAxis.Viewport);
+
+      SetClipX(clippingArea.X1, clippingArea.X2);
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        if (rowEntry.DataRow.YAxis.ClipChangeable) {
+          clippingArea = Translate.ClippingArea(startPoint, endPoint, rowEntry.LinesShape.ClippingArea, rowEntry.LinesShape.Viewport);
+          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
+        }
+      }
+
+      canvasUI.Invalidate();
+    }
+
+    private void PanEnd(Point startPoint, Point endPoint) {
+      Pan(startPoint, endPoint);
+    }
+
+    private void SetClippingArea(Rectangle rectangle) {
+      RectangleD clippingArea = Transform.ToWorld(rectangle, xAxis.Viewport, xAxis.ClippingArea);
+
+      SetClipX(clippingArea.X1, clippingArea.X2);
+
+      foreach (RowEntry rowEntry in rowEntries) {
+        if (rowEntry.DataRow.YAxis.ClipChangeable) {
+          clippingArea = Transform.ToWorld(rectangle, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
+
+          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
+        }
+      }
+
+      userInteractionShape.RemoveShape(rectangleShape);
+      canvasUI.Invalidate();
+    }
+
+    private void DrawRectangle(Rectangle rectangle) {
+      rectangleShape.Rectangle = Transform.ToWorld(rectangle, userInteractionShape.Viewport, userInteractionShape.ClippingArea);
+      canvasUI.Invalidate();
+    }
+
+    private void canvasUI1_KeyDown(object sender, KeyEventArgs e) {
+    }
+
+    private void canvasUI1_MouseDown(object sender, MouseEventArgs e) {
+      Focus();
+
+      if (e.Button == MouseButtons.Right) {
+        contextMenuStrip1.Show(PointToScreen(e.Location));
+      } else if (e.Button == MouseButtons.Left) {
+        if (ModifierKeys == Keys.None) {
+          PanListener panListener = new PanListener(e.Location);
+          panListener.Pan += Pan;
+          panListener.PanEnd += PanEnd;
+
+          mouseEventListener = panListener;
+        } else if (ModifierKeys == Keys.Control) {
+          ZoomListener zoomListener = new ZoomListener(e.Location);
+          zoomListener.DrawRectangle += DrawRectangle;
+          zoomListener.SetClippingArea += SetClippingArea;
+
+          rectangleShape.Rectangle = RectangleD.Empty;
+          userInteractionShape.AddShape(rectangleShape);
+
+          mouseEventListener = zoomListener;
+        }
+      }
+    }
+
+    private void canvasUI_MouseMove(object sender, MouseEventArgs e) {
+      if (mouseEventListener != null) {
+        mouseEventListener.MouseMove(sender, e);
+      }
+    }
+
+    private void canvasUI_MouseUp(object sender, MouseEventArgs e) {
+      if (mouseEventListener != null) {
+        mouseEventListener.MouseUp(sender, e);
+      }
+
+      mouseEventListener = null;
+    }
+
+    private void canvasUI1_MouseWheel(object sender, MouseEventArgs e) {
+      if (ModifierKeys == Keys.Control) {
+        double zoomFactor = (e.Delta > 0) ? 0.7 : 1.3;
+
+        PointD world;
+
+        world = Transform.ToWorld(e.Location, xAxis.Viewport, xAxis.ClippingArea);
+
+        double x1 = world.X - (world.X - xAxis.ClippingArea.X1)*zoomFactor;
+        double x2 = world.X + (xAxis.ClippingArea.X2 - world.X)*zoomFactor;
+
+        SetClipX(x1, x2);
+
+        foreach (RowEntry rowEntry in rowEntries) {
+          world = Transform.ToWorld(e.Location, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
+
+          double y1 = world.Y - (world.Y - rowEntry.LinesShape.ClippingArea.Y1) * zoomFactor;
+          double y2 = world.Y + (rowEntry.LinesShape.ClippingArea.Y2 - world.Y)*zoomFactor;
+
+          SetClipY(rowEntry, y1, y2);
+        }
+
+        canvasUI.Invalidate();
+      }
+    }
+
+    #endregion
+
+    private class LinesShape : WorldShape {
+      public void UpdateStyle(IDataRow row) {
+        foreach (IShape shape in shapes) {
+          LineShape lineShape = shape as LineShape;
+          if (lineShape != null) {
+            lineShape.LSColor = row.Color;
+            lineShape.LSDrawingStyle = row.Style;
+            lineShape.LSThickness = row.Thickness;
+          }
+        }
+      }
+
+      public int Count {
+        get { return shapes.Count; }
+      }
+
+      public LineShape GetShape(int index) {
+        return (LineShape)shapes[index];
+      }
+    }
+
+    private class RowEntry {
+      private readonly IDataRow dataRow;
+
+      private readonly LinesShape linesShape = new LinesShape();
+
+      public RowEntry(IDataRow dataRow) {
+        this.dataRow = dataRow;
+      }
+
+      public IDataRow DataRow {
+        get { return dataRow; }
+      }
+
+      public LinesShape LinesShape {
+        get { return linesShape; }
+      }
+    }
+
+    private class YAxisInfo {
+      private readonly Grid grid = new Grid();
+      private readonly YAxis yAxis = new YAxis();
+
+      public Grid Grid {
+        get { return grid; }
+      }
+
+      public YAxis YAxis {
+        get { return yAxis; }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/LineChart.resx
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LineChart.resx	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LineChart.resx	(revision 1530)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: trunk/sources/HeuristicLab.Visualization/3.2/LineShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/LineShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/LineShape.cs	(revision 1530)
@@ -0,0 +1,128 @@
+﻿using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Visualization {
+  public class LineShape : IShape {
+    private IShape parent;
+    private RectangleD boundingBox;
+
+    private Color color;
+    private int thickness;
+    private DrawingStyle drawingStyle;
+
+    private Pen pen;
+
+    /// <summary>
+    /// Initializes the LineShape.
+    /// </summary>
+    /// <param name="x1">x coordinate of left lineEndPoind</param>
+    /// <param name="y1">y coordinate of left lineEndPoind</param>
+    /// <param name="x2">x coordinate of right lineEndPoind</param>
+    /// <param name="y2">y coordinate of right lineEndPoind</param>
+    /// <param name="color">color for the LineShape</param>
+    /// <param name="thickness">tickness of the line in pixels</param>
+    /// <param name="drawingStyle">drawing style of the line (solid, dashed, dotted,...)</param>
+    public LineShape(double x1, double y1, double x2, double y2, Color color, int thickness, DrawingStyle drawingStyle) {
+      this.boundingBox = new RectangleD(x1, y1, x2, y2);
+      this.LSColor = color;
+      this.LSThickness = thickness;
+      this.LSDrawingStyle = drawingStyle;
+    }
+
+    public RectangleD BoundingBox {
+      get { return boundingBox; }
+      set { boundingBox = value; }
+    }
+
+    public RectangleD ClippingArea {
+      get { return Parent.ClippingArea; }
+    }
+
+    public Rectangle Viewport {
+      get { return Parent.Viewport; }
+    }
+
+    public IShape Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    public double Y1 {
+      get { return boundingBox.Y1; }
+      set { boundingBox.Y1 = value; }
+    }
+
+    public double Y2 {
+      get { return boundingBox.Y2; }
+      set { boundingBox.Y2 = value; }
+    }
+
+    public double X1 {
+      get { return boundingBox.X1; }
+      set { boundingBox.X1 = value; }
+    }
+
+    public double X2 {
+      get { return boundingBox.X2; }
+      set { boundingBox.X2 = value; }
+    }
+
+    /// <summary>
+    /// Draws the LineShape.
+    /// </summary>
+    /// <param name="graphics">graphics handle to draw to</param>
+    public virtual void Draw(Graphics graphics) {
+      Rectangle screenRect = Transform.ToScreen(boundingBox, Parent.Viewport, Parent.ClippingArea);
+
+      graphics.DrawLine(GetPen(), screenRect.Left, screenRect.Bottom, screenRect.Right, screenRect.Top);
+    }
+
+    private Pen GetPen() {
+      if (pen == null) {
+        pen = new Pen(LSColor, LSThickness);
+
+        switch (LSDrawingStyle) {
+          case DrawingStyle.Dashed:
+            pen.DashStyle = DashStyle.Dash;
+            break;
+          default:
+            pen.DashStyle = DashStyle.Solid;
+            break;
+        }
+      }
+
+      return pen;
+    }
+
+    private void DisposePen() {
+      if (pen != null) {
+        pen.Dispose();
+        pen = null;
+      }
+    }
+
+    public Color LSColor {
+      get { return color; }
+      set {
+        color = value;
+        DisposePen();
+      }
+    }
+
+    public int LSThickness {
+      get { return thickness; }
+      set {
+        thickness = value;
+        DisposePen();
+      }
+    }
+
+    public DrawingStyle LSDrawingStyle {
+      get { return drawingStyle; }
+      set {
+        drawingStyle = value;
+        DisposePen();
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/MaxAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/MaxAggregator.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/MaxAggregator.cs	(revision 1530)
@@ -0,0 +1,120 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public class MaxAggregator : DataRowBase {
+    #region IAggregator Members
+
+    public void AddWatch(IDataRow dataRow) {
+      dataRowWatches.Add(dataRow);
+      dataRow.ValueChanged += dataRow_ValueChanged;
+      dataRow.ValuesChanged += dataRow_ValuesChanged;
+      dataRow.DataRowChanged += dataRow_DataRowChanged;
+    }
+
+    public void RemoveWatch(IDataRow dataRow) {
+
+      dataRowWatches.Remove(dataRow);
+      dataRow.DataRowChanged -= dataRow_DataRowChanged;
+      dataRow.ValuesChanged -= dataRow_ValuesChanged;
+      dataRow.ValueChanged -= dataRow_ValueChanged;
+    }
+
+
+    #endregion
+
+    List<IDataRow> dataRowWatches = new List<IDataRow>();
+    double curMaxValue;
+
+    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
+      refreshValue(value);
+    }
+
+    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
+      for (int i = 0; i < values.Length; i++) {
+        refreshValue(values[i]);
+      }
+    }
+
+    void dataRow_DataRowChanged(IDataRow row) {
+      refreshValue(double.MinValue);
+    }
+
+    private void refreshValue(double newVal) {
+      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
+      if (curMaxValue < newVal) {
+        curMaxValue = newVal;
+        OnValueChanged(newVal, 0, Action.Modified);
+      } else {
+        curMaxValue = double.MinValue;
+        foreach (IDataRow rows in dataRowWatches) {
+          for (int i = 0; i < rows.Count; i++) {
+            if (rows[i] > curMaxValue) {
+              curMaxValue = rows[i];
+            }
+          }
+        }
+
+      }
+      // evtl nur feuern wenn sich geändert hat (jedes mal?)
+      OnValueChanged(curMaxValue, 0, Action.Modified);
+    }
+
+    #region IDataRow Members
+    public override void AddValue(double value) {
+      OnValueChanged(2, 0, Action.Added);
+    }
+
+    public override void AddValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValue(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValues(int index, int count) {
+      throw new NotSupportedException();
+    }
+
+    public override int Count {
+      get { return 1; }
+    }
+
+    public override double this[int index] {
+      get {
+        return curMaxValue;
+      }
+      set {
+        throw new NotSupportedException();
+      }
+    }
+
+    public override double MinValue {
+      get { return curMaxValue; }
+    }
+
+    public override double MaxValue {
+      get { return curMaxValue; }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/MinAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/MinAggregator.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/MinAggregator.cs	(revision 1530)
@@ -0,0 +1,120 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Visualization {
+  public class MinAggregator : DataRowBase {
+    #region IAggregator Members
+
+    public void AddWatch(IDataRow dataRow) {
+      dataRowWatches.Add(dataRow);
+      dataRow.ValueChanged += dataRow_ValueChanged;
+      dataRow.ValuesChanged += dataRow_ValuesChanged;
+      dataRow.DataRowChanged += dataRow_DataRowChanged;
+    }
+
+    public void RemoveWatch(IDataRow dataRow) {
+
+      dataRowWatches.Remove(dataRow);
+      dataRow.DataRowChanged -= dataRow_DataRowChanged;
+      dataRow.ValuesChanged -= dataRow_ValuesChanged;
+      dataRow.ValueChanged -= dataRow_ValueChanged;
+    }
+
+
+    #endregion
+
+    readonly List<IDataRow> dataRowWatches = new List<IDataRow>();
+    double curMinValue;
+
+    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
+      refreshValue(value);
+    }
+
+    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
+      for (int i = 0; i < values.Length; i++) {
+        refreshValue(values[i]);
+      }
+    }
+
+    void dataRow_DataRowChanged(IDataRow row) {
+      refreshValue(double.MaxValue);
+    }
+
+    private void refreshValue(double newVal) {
+      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
+      if (curMinValue > newVal) {
+        curMinValue = newVal;
+        OnValueChanged(newVal, 0, Action.Modified);
+      } else {
+        curMinValue = double.MaxValue;
+        foreach (IDataRow rows in dataRowWatches) {
+          for (int i = 0; i < rows.Count; i++) {
+            if (rows[i] < curMinValue) {
+              curMinValue = rows[i];
+            }
+          }
+        }
+
+      }
+      // evtl nur feuern wenn sich geändert hat (jedes mal?)
+      OnValueChanged(curMinValue, 0, Action.Modified);
+    }
+
+    #region IDataRow Members
+
+    public override void AddValue(double value) {
+      OnValueChanged(2, 0, Action.Added);
+    }
+
+    public override void AddValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValue(double value, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void ModifyValues(double[] values, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValue(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveValues(int index, int count) {
+      throw new NotSupportedException();
+    }
+
+    public override int Count {
+      get { return 1; }
+    }
+
+    public override double this[int index] {
+      get {
+        return curMinValue;
+      }
+      set {
+        throw new NotSupportedException();
+      }
+    }
+
+    public override double MinValue {
+      get { return curMinValue; }
+    }
+
+    public override double MaxValue {
+      get { return curMinValue; }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Offset.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Offset.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Offset.cs	(revision 1530)
@@ -0,0 +1,115 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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;
+
+namespace HeuristicLab.Visualization {
+  public struct Offset {
+    public static readonly Offset Empty = new Offset();
+
+    private double myDX;
+
+    public double DX {
+      get { return myDX; }
+      set { myDX = value; }
+    }
+
+    private double myDY;
+
+    public double DY {
+      get { return myDY; }
+      set { myDY = value; }
+    }
+
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+
+    public double Length {
+      get { return Math.Sqrt(DX*DX + DY*DY); }
+    }
+
+    public Offset(double dx, double dy) {
+      myDX = dx;
+      myDY = dy;
+    }
+
+    public Offset(PointD point) {
+      myDX = point.X;
+      myDY = point.Y;
+    }
+
+    public Offset(SizeD size) {
+      myDX = size.Width;
+      myDY = size.Height;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is Offset) {
+        return ((Offset)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+
+    public override int GetHashCode() {
+      return (int)Math.Pow(DX, DY);
+    }
+
+    public override string ToString() {
+      return string.Format("({0};{1})", DX, DY);
+    }
+
+    public static Offset operator +(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
+    }
+
+    public static Offset operator -(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
+    }
+
+    public static bool operator ==(Offset offset1, Offset offset2) {
+      return (offset1.DX == offset2.DX) && (offset1.DY == offset2.DY);
+    }
+
+    public static bool operator !=(Offset offset1, Offset offset2) {
+      return (offset1.DX != offset2.DX) && (offset1.DY != offset2.DY);
+    }
+
+    public static explicit operator PointD(Offset offset) {
+      return new PointD(offset.DX, offset.DY);
+    }
+
+    public static explicit operator SizeD(Offset offset) {
+      return new SizeD(offset.DX, offset.DY);
+    }
+
+    public static Offset Add(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
+    }
+
+    public static Offset Subtract(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.Designer.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.Designer.cs	(revision 1530)
@@ -0,0 +1,414 @@
+﻿namespace HeuristicLab.Visualization.Options {
+  partial class OptionsDialog {
+    /// <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 Windows Form 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.OptionsDialogCancelButton = new System.Windows.Forms.Button();
+      this.OptionsDialogOkButton = new System.Windows.Forms.Button();
+      this.fdFont = new System.Windows.Forms.FontDialog();
+      this.tpTitle = new System.Windows.Forms.TabPage();
+      this.btnChangeTitleFont = new System.Windows.Forms.Button();
+      this.tabPage2 = new System.Windows.Forms.TabPage();
+      this.btnChangeLegendFont = new System.Windows.Forms.Button();
+      this.legendposition = new System.Windows.Forms.Label();
+      this.cbLegendPosition = new System.Windows.Forms.ComboBox();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.OptionsDialogSelectColorBt = new System.Windows.Forms.Button();
+      this.ColorPreviewTB = new System.Windows.Forms.TextBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.LinestyleCB = new System.Windows.Forms.ComboBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.LineSelectCB = new System.Windows.Forms.ComboBox();
+      this.groupBox1 = new System.Windows.Forms.GroupBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.LineThicknessCB = new System.Windows.Forms.ComboBox();
+      this.label3 = new System.Windows.Forms.Label();
+      this.Optionstabs = new System.Windows.Forms.TabControl();
+      this.tpXAxis = new System.Windows.Forms.TabPage();
+      this.btnChangeXAxisFont = new System.Windows.Forms.Button();
+      this.tpYAxes = new System.Windows.Forms.TabPage();
+      this.gbxShowYAxis = new System.Windows.Forms.GroupBox();
+      this.gbxYAxisClipChangeable = new System.Windows.Forms.GroupBox();
+      this.flpShowYAxis = new System.Windows.Forms.FlowLayoutPanel();
+      this.flpYAxisClipChangeable = new System.Windows.Forms.FlowLayoutPanel();
+      this.tpTitle.SuspendLayout();
+      this.tabPage2.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      this.groupBox1.SuspendLayout();
+      this.Optionstabs.SuspendLayout();
+      this.tpXAxis.SuspendLayout();
+      this.tpYAxes.SuspendLayout();
+      this.gbxShowYAxis.SuspendLayout();
+      this.gbxYAxisClipChangeable.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // OptionsDialogCancelButton
+      // 
+      this.OptionsDialogCancelButton.Location = new System.Drawing.Point(213, 232);
+      this.OptionsDialogCancelButton.Name = "OptionsDialogCancelButton";
+      this.OptionsDialogCancelButton.Size = new System.Drawing.Size(75, 23);
+      this.OptionsDialogCancelButton.TabIndex = 1;
+      this.OptionsDialogCancelButton.Text = "Reset";
+      this.OptionsDialogCancelButton.UseVisualStyleBackColor = true;
+      this.OptionsDialogCancelButton.Click += new System.EventHandler(this.OptionsDialogResetButton_Click);
+      // 
+      // OptionsDialogOkButton
+      // 
+      this.OptionsDialogOkButton.Location = new System.Drawing.Point(132, 232);
+      this.OptionsDialogOkButton.Name = "OptionsDialogOkButton";
+      this.OptionsDialogOkButton.Size = new System.Drawing.Size(75, 23);
+      this.OptionsDialogOkButton.TabIndex = 2;
+      this.OptionsDialogOkButton.Text = "OK";
+      this.OptionsDialogOkButton.UseVisualStyleBackColor = true;
+      this.OptionsDialogOkButton.Click += new System.EventHandler(this.OptionsDialogOkButton_Click);
+      // 
+      // fdFont
+      // 
+      this.fdFont.ShowColor = true;
+      // 
+      // tpTitle
+      // 
+      this.tpTitle.Controls.Add(this.btnChangeTitleFont);
+      this.tpTitle.Location = new System.Drawing.Point(4, 22);
+      this.tpTitle.Name = "tpTitle";
+      this.tpTitle.Size = new System.Drawing.Size(284, 199);
+      this.tpTitle.TabIndex = 2;
+      this.tpTitle.Text = "Title";
+      this.tpTitle.UseVisualStyleBackColor = true;
+      // 
+      // btnChangeTitleFont
+      // 
+      this.btnChangeTitleFont.Location = new System.Drawing.Point(3, 3);
+      this.btnChangeTitleFont.Name = "btnChangeTitleFont";
+      this.btnChangeTitleFont.Size = new System.Drawing.Size(94, 23);
+      this.btnChangeTitleFont.TabIndex = 1;
+      this.btnChangeTitleFont.Text = "Change Font";
+      this.btnChangeTitleFont.UseVisualStyleBackColor = true;
+      this.btnChangeTitleFont.Click += new System.EventHandler(this.btnChangeTitleFont_Click);
+      // 
+      // tabPage2
+      // 
+      this.tabPage2.Controls.Add(this.btnChangeLegendFont);
+      this.tabPage2.Controls.Add(this.legendposition);
+      this.tabPage2.Controls.Add(this.cbLegendPosition);
+      this.tabPage2.Location = new System.Drawing.Point(4, 22);
+      this.tabPage2.Name = "tabPage2";
+      this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage2.Size = new System.Drawing.Size(284, 199);
+      this.tabPage2.TabIndex = 1;
+      this.tabPage2.Text = "Legend";
+      this.tabPage2.UseVisualStyleBackColor = true;
+      // 
+      // btnChangeLegendFont
+      // 
+      this.btnChangeLegendFont.Location = new System.Drawing.Point(3, 6);
+      this.btnChangeLegendFont.Name = "btnChangeLegendFont";
+      this.btnChangeLegendFont.Size = new System.Drawing.Size(94, 23);
+      this.btnChangeLegendFont.TabIndex = 2;
+      this.btnChangeLegendFont.Text = "Change Font";
+      this.btnChangeLegendFont.UseVisualStyleBackColor = true;
+      this.btnChangeLegendFont.Click += new System.EventHandler(this.btnChangeLegendFont_Click);
+      // 
+      // legendposition
+      // 
+      this.legendposition.AutoSize = true;
+      this.legendposition.Location = new System.Drawing.Point(8, 38);
+      this.legendposition.Name = "legendposition";
+      this.legendposition.Size = new System.Drawing.Size(82, 13);
+      this.legendposition.TabIndex = 1;
+      this.legendposition.Text = "Legendposition:";
+      // 
+      // cbLegendPosition
+      // 
+      this.cbLegendPosition.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cbLegendPosition.FormattingEnabled = true;
+      this.cbLegendPosition.Location = new System.Drawing.Point(96, 35);
+      this.cbLegendPosition.Name = "cbLegendPosition";
+      this.cbLegendPosition.Size = new System.Drawing.Size(121, 21);
+      this.cbLegendPosition.TabIndex = 0;
+      this.cbLegendPosition.SelectedIndexChanged += new System.EventHandler(this.cbLegendPosition_SelectedIndexChanged);
+      // 
+      // tabPage1
+      // 
+      this.tabPage1.Controls.Add(this.OptionsDialogSelectColorBt);
+      this.tabPage1.Controls.Add(this.ColorPreviewTB);
+      this.tabPage1.Controls.Add(this.label2);
+      this.tabPage1.Controls.Add(this.LinestyleCB);
+      this.tabPage1.Controls.Add(this.label1);
+      this.tabPage1.Controls.Add(this.LineSelectCB);
+      this.tabPage1.Controls.Add(this.groupBox1);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(284, 199);
+      this.tabPage1.TabIndex = 0;
+      this.tabPage1.Text = "Linestyle";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      // 
+      // OptionsDialogSelectColorBt
+      // 
+      this.OptionsDialogSelectColorBt.Location = new System.Drawing.Point(217, 126);
+      this.OptionsDialogSelectColorBt.Name = "OptionsDialogSelectColorBt";
+      this.OptionsDialogSelectColorBt.Size = new System.Drawing.Size(50, 23);
+      this.OptionsDialogSelectColorBt.TabIndex = 7;
+      this.OptionsDialogSelectColorBt.Text = "Select";
+      this.OptionsDialogSelectColorBt.UseVisualStyleBackColor = true;
+      this.OptionsDialogSelectColorBt.Click += new System.EventHandler(this.OptionsDialogSelectColorBtn_Click);
+      // 
+      // ColorPreviewTB
+      // 
+      this.ColorPreviewTB.Location = new System.Drawing.Point(146, 127);
+      this.ColorPreviewTB.Name = "ColorPreviewTB";
+      this.ColorPreviewTB.ReadOnly = true;
+      this.ColorPreviewTB.Size = new System.Drawing.Size(64, 20);
+      this.ColorPreviewTB.TabIndex = 6;
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(36, 80);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(30, 13);
+      this.label2.TabIndex = 3;
+      this.label2.Text = "Style";
+      // 
+      // LinestyleCB
+      // 
+      this.LinestyleCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.LinestyleCB.FormattingEnabled = true;
+      this.LinestyleCB.Location = new System.Drawing.Point(146, 73);
+      this.LinestyleCB.Name = "LinestyleCB";
+      this.LinestyleCB.Size = new System.Drawing.Size(121, 21);
+      this.LinestyleCB.TabIndex = 2;
+      this.LinestyleCB.SelectedIndexChanged += new System.EventHandler(this.LinestyleCB_SelectedIndexChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(7, 37);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(72, 13);
+      this.label1.TabIndex = 1;
+      this.label1.Text = "Selected Line";
+      // 
+      // LineSelectCB
+      // 
+      this.LineSelectCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.LineSelectCB.FormattingEnabled = true;
+      this.LineSelectCB.Location = new System.Drawing.Point(146, 30);
+      this.LineSelectCB.Name = "LineSelectCB";
+      this.LineSelectCB.Size = new System.Drawing.Size(121, 21);
+      this.LineSelectCB.TabIndex = 0;
+      this.LineSelectCB.SelectedIndexChanged += new System.EventHandler(this.LineSelectCB_SelectedIndexChanged);
+      // 
+      // groupBox1
+      // 
+      this.groupBox1.Controls.Add(this.label4);
+      this.groupBox1.Controls.Add(this.LineThicknessCB);
+      this.groupBox1.Controls.Add(this.label3);
+      this.groupBox1.Location = new System.Drawing.Point(4, 54);
+      this.groupBox1.Name = "groupBox1";
+      this.groupBox1.Size = new System.Drawing.Size(274, 129);
+      this.groupBox1.TabIndex = 9;
+      this.groupBox1.TabStop = false;
+      this.groupBox1.Text = "Details";
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(33, 77);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(31, 13);
+      this.label4.TabIndex = 8;
+      this.label4.Text = "Color";
+      // 
+      // LineThicknessCB
+      // 
+      this.LineThicknessCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.LineThicknessCB.FormattingEnabled = true;
+      this.LineThicknessCB.Location = new System.Drawing.Point(142, 46);
+      this.LineThicknessCB.Name = "LineThicknessCB";
+      this.LineThicknessCB.Size = new System.Drawing.Size(121, 21);
+      this.LineThicknessCB.TabIndex = 4;
+      this.LineThicknessCB.SelectedIndexChanged += new System.EventHandler(this.LineThicknessCB_SelectedIndexChanged);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(32, 52);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(56, 13);
+      this.label3.TabIndex = 5;
+      this.label3.Text = "Thickness";
+      // 
+      // Optionstabs
+      // 
+      this.Optionstabs.Controls.Add(this.tabPage1);
+      this.Optionstabs.Controls.Add(this.tabPage2);
+      this.Optionstabs.Controls.Add(this.tpTitle);
+      this.Optionstabs.Controls.Add(this.tpXAxis);
+      this.Optionstabs.Controls.Add(this.tpYAxes);
+      this.Optionstabs.Location = new System.Drawing.Point(0, 1);
+      this.Optionstabs.Name = "Optionstabs";
+      this.Optionstabs.SelectedIndex = 0;
+      this.Optionstabs.Size = new System.Drawing.Size(292, 225);
+      this.Optionstabs.TabIndex = 0;
+      // 
+      // tpXAxis
+      // 
+      this.tpXAxis.Controls.Add(this.btnChangeXAxisFont);
+      this.tpXAxis.Location = new System.Drawing.Point(4, 22);
+      this.tpXAxis.Name = "tpXAxis";
+      this.tpXAxis.Size = new System.Drawing.Size(284, 199);
+      this.tpXAxis.TabIndex = 3;
+      this.tpXAxis.Text = "X-Axis";
+      this.tpXAxis.UseVisualStyleBackColor = true;
+      // 
+      // btnChangeXAxisFont
+      // 
+      this.btnChangeXAxisFont.Location = new System.Drawing.Point(3, 3);
+      this.btnChangeXAxisFont.Name = "btnChangeXAxisFont";
+      this.btnChangeXAxisFont.Size = new System.Drawing.Size(94, 23);
+      this.btnChangeXAxisFont.TabIndex = 2;
+      this.btnChangeXAxisFont.Text = "Change Font";
+      this.btnChangeXAxisFont.UseVisualStyleBackColor = true;
+      this.btnChangeXAxisFont.Click += new System.EventHandler(this.btnChangeXAxisFont_Click);
+      // 
+      // tpYAxes
+      // 
+      this.tpYAxes.Controls.Add(this.gbxYAxisClipChangeable);
+      this.tpYAxes.Controls.Add(this.gbxShowYAxis);
+      this.tpYAxes.Location = new System.Drawing.Point(4, 22);
+      this.tpYAxes.Name = "tpYAxes";
+      this.tpYAxes.Padding = new System.Windows.Forms.Padding(3);
+      this.tpYAxes.Size = new System.Drawing.Size(284, 199);
+      this.tpYAxes.TabIndex = 4;
+      this.tpYAxes.Text = "Y-Axes";
+      this.tpYAxes.UseVisualStyleBackColor = true;
+      // 
+      // gbxShowYAxis
+      // 
+      this.gbxShowYAxis.AutoSize = true;
+      this.gbxShowYAxis.Controls.Add(this.flpShowYAxis);
+      this.gbxShowYAxis.Location = new System.Drawing.Point(0, 0);
+      this.gbxShowYAxis.Name = "gbxShowYAxis";
+      this.gbxShowYAxis.Size = new System.Drawing.Size(281, 76);
+      this.gbxShowYAxis.TabIndex = 0;
+      this.gbxShowYAxis.TabStop = false;
+      this.gbxShowYAxis.Text = "Show Y-Axis";
+      // 
+      // gbxYAxisClipChangeable
+      // 
+      this.gbxYAxisClipChangeable.AutoSize = true;
+      this.gbxYAxisClipChangeable.Controls.Add(this.flpYAxisClipChangeable);
+      this.gbxYAxisClipChangeable.Location = new System.Drawing.Point(0, 82);
+      this.gbxYAxisClipChangeable.Name = "gbxYAxisClipChangeable";
+      this.gbxYAxisClipChangeable.Size = new System.Drawing.Size(281, 76);
+      this.gbxYAxisClipChangeable.TabIndex = 1;
+      this.gbxYAxisClipChangeable.TabStop = false;
+      this.gbxYAxisClipChangeable.Text = "Y-Axis-Clip changeable";
+      // 
+      // flpShowYAxis
+      // 
+      this.flpShowYAxis.AutoSize = true;
+      this.flpShowYAxis.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.flpShowYAxis.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
+      this.flpShowYAxis.Location = new System.Drawing.Point(3, 16);
+      this.flpShowYAxis.Name = "flpShowYAxis";
+      this.flpShowYAxis.Size = new System.Drawing.Size(275, 57);
+      this.flpShowYAxis.TabIndex = 0;
+      // 
+      // flpYAxisClipChangeable
+      // 
+      this.flpYAxisClipChangeable.AutoSize = true;
+      this.flpYAxisClipChangeable.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.flpYAxisClipChangeable.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
+      this.flpYAxisClipChangeable.Location = new System.Drawing.Point(3, 16);
+      this.flpYAxisClipChangeable.Name = "flpYAxisClipChangeable";
+      this.flpYAxisClipChangeable.Size = new System.Drawing.Size(275, 57);
+      this.flpYAxisClipChangeable.TabIndex = 0;
+      // 
+      // OptionsDialog
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(292, 266);
+      this.Controls.Add(this.OptionsDialogOkButton);
+      this.Controls.Add(this.OptionsDialogCancelButton);
+      this.Controls.Add(this.Optionstabs);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.MaximizeBox = false;
+      this.Name = "OptionsDialog";
+      this.Text = "OptionsDialog";
+      this.Load += new System.EventHandler(this.OptionsDialog_Load);
+      this.tpTitle.ResumeLayout(false);
+      this.tabPage2.ResumeLayout(false);
+      this.tabPage2.PerformLayout();
+      this.tabPage1.ResumeLayout(false);
+      this.tabPage1.PerformLayout();
+      this.groupBox1.ResumeLayout(false);
+      this.groupBox1.PerformLayout();
+      this.Optionstabs.ResumeLayout(false);
+      this.tpXAxis.ResumeLayout(false);
+      this.tpYAxes.ResumeLayout(false);
+      this.tpYAxes.PerformLayout();
+      this.gbxShowYAxis.ResumeLayout(false);
+      this.gbxShowYAxis.PerformLayout();
+      this.gbxYAxisClipChangeable.ResumeLayout(false);
+      this.gbxYAxisClipChangeable.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button OptionsDialogCancelButton;
+    private System.Windows.Forms.Button OptionsDialogOkButton;
+    private System.Windows.Forms.FontDialog fdFont;
+    private System.Windows.Forms.TabPage tpTitle;
+    private System.Windows.Forms.Button btnChangeTitleFont;
+    private System.Windows.Forms.TabPage tabPage2;
+    private System.Windows.Forms.TabPage tabPage1;
+    private System.Windows.Forms.Button OptionsDialogSelectColorBt;
+    private System.Windows.Forms.TextBox ColorPreviewTB;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.ComboBox LinestyleCB;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox LineSelectCB;
+    private System.Windows.Forms.GroupBox groupBox1;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.ComboBox cbLegendPosition;
+    private System.Windows.Forms.Label legendposition;
+    private System.Windows.Forms.ComboBox LineThicknessCB;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.TabControl Optionstabs;
+    private System.Windows.Forms.Button btnChangeLegendFont;
+    private System.Windows.Forms.TabPage tpXAxis;
+    private System.Windows.Forms.Button btnChangeXAxisFont;
+    private System.Windows.Forms.TabPage tpYAxes;
+    private System.Windows.Forms.GroupBox gbxShowYAxis;
+    private System.Windows.Forms.GroupBox gbxYAxisClipChangeable;
+    private System.Windows.Forms.FlowLayoutPanel flpYAxisClipChangeable;
+    private System.Windows.Forms.FlowLayoutPanel flpShowYAxis;
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.cs	(revision 1530)
@@ -0,0 +1,221 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.Visualization.Legend;
+
+namespace HeuristicLab.Visualization.Options {
+  public partial class OptionsDialog : Form {
+    private readonly IChartDataRowsModel model;
+    private readonly ViewSettings viewSettings;
+    private readonly ViewSettings oldViewSettings;
+    private LineParams[] oldLineParams;
+    private Dictionary<CheckBox,bool> ShowYAxisBoxes;
+    private Dictionary<CheckBox,bool> yAxisClipChangeableBoxes;
+
+    internal class LineParams {
+      string Label { get; set; }
+      Color Color { get; set; }
+      int Thickness { get; set; }
+      DrawingStyle Style { get; set; }
+      private readonly IDataRow row;
+
+      public LineParams(IDataRow row) {
+        Label = row.Label;
+        Color = row.Color;
+        Thickness = row.Thickness;
+        Style = row.Style;
+        this.row = row;
+      }
+
+      public void applySettings() {
+        row.Label = Label;
+        row.Color = Color;
+        row.Thickness = Thickness;
+        row.Style = Style;
+      }
+    }
+
+    public OptionsDialog(IChartDataRowsModel model) {
+      InitializeComponent();
+
+      this.model = model;
+      viewSettings = model.ViewSettings;
+      oldViewSettings = new ViewSettings(model.ViewSettings);
+
+      cbLegendPosition.Items.Add(LegendPosition.Top);
+      cbLegendPosition.Items.Add(LegendPosition.Bottom);
+      cbLegendPosition.Items.Add(LegendPosition.Left);
+      cbLegendPosition.Items.Add(LegendPosition.Right);
+
+      cbLegendPosition.SelectedItem = viewSettings.LegendPosition;
+    }
+
+    private void OptionsDialogSelectColorBtn_Click(object sender, EventArgs e) {
+      ColorDialog dlg = new ColorDialog();
+      dlg.ShowDialog();
+      ColorPreviewTB.BackColor = dlg.Color;
+      ((IDataRow)LineSelectCB.SelectedValue).Color = dlg.Color;
+    }
+
+    public IList<int> GetThicknesses() {
+      return new List<int>(new int[] {1, 2, 3, 4, 5, 6, 7, 8});
+    }
+
+    public IList<DrawingStyle> GetStyles() {
+      return new List<DrawingStyle>(new DrawingStyle[] {DrawingStyle.Solid, DrawingStyle.Dashed});
+    }
+
+    private void OptionsDialog_Load(object sender, EventArgs e) {
+      InitTabPageLines();
+      InitTabPageYAxes();
+    }
+
+    private void InitTabPageLines() {
+      if (model.Rows.Count != 0) {
+        int index = 0;
+        oldLineParams = new LineParams[model.Rows.Count];
+        foreach (var row in model.Rows) {
+          oldLineParams[index++]= new LineParams(row);
+        }
+        LineThicknessCB.DataSource = GetThicknesses();
+        LinestyleCB.DataSource = GetStyles();
+        LinestyleCB.SelectedItem = model.Rows[0].Style;
+        LineThicknessCB.SelectedItem = model.Rows[0].Thickness;
+
+        LineSelectCB.DataSource = model.Rows;
+        LineSelectCB.DisplayMember = "Label";
+
+        
+        LineSelectCB.SelectedIndex = 0;
+        LineSelectCB_SelectedIndexChanged(this, null);
+        
+      }
+    }
+
+    private void InitTabPageYAxes() {
+      ShowYAxisBoxes = new Dictionary<CheckBox, bool>();
+      yAxisClipChangeableBoxes = new Dictionary<CheckBox, bool>();
+
+      for (int i = 0; i < model.YAxes.Count; i++) {
+        YAxisDescriptor yAxisDescriptor = model.YAxes[i];
+
+        CheckBox cbxShowYAxis = new CheckBox();
+        cbxShowYAxis.Text = yAxisDescriptor.Label;
+        cbxShowYAxis.Checked = yAxisDescriptor.ShowYAxis;
+        ShowYAxisBoxes[cbxShowYAxis] = yAxisDescriptor.ShowYAxis;
+        cbxShowYAxis.CheckedChanged += delegate { yAxisDescriptor.ShowYAxis = cbxShowYAxis.Checked; };
+        
+        flpShowYAxis.Controls.Add(cbxShowYAxis);
+
+        CheckBox cbxClipChangeable = new CheckBox();
+        cbxClipChangeable.Text = yAxisDescriptor.Label;
+        cbxClipChangeable.Checked = yAxisDescriptor.ClipChangeable;
+        yAxisClipChangeableBoxes[cbxClipChangeable] = yAxisDescriptor.ClipChangeable; 
+        cbxClipChangeable.CheckedChanged += delegate { yAxisDescriptor.ClipChangeable = cbxClipChangeable.Checked; };
+
+        flpYAxisClipChangeable.Controls.Add(cbxClipChangeable);
+      }
+    }
+
+    private void LineSelectCB_SelectedIndexChanged(object sender, EventArgs e) {
+      if (LineSelectCB.SelectedValue != null) {
+      /*  int index =
+          LineThicknessCB.FindStringExact(((IDataRow)LineSelectCB.SelectedValue).Thickness.ToString());
+        LineThicknessCB.SelectedIndex = index;
+        index = LinestyleCB.FindStringExact(((IDataRow)LineSelectCB.SelectedValue).Style.ToString());
+        LinestyleCB.SelectedIndex = index;  */
+        LineThicknessCB.SelectedItem = ((IDataRow) LineSelectCB.SelectedValue).Thickness;
+        LinestyleCB.SelectedItem = ((IDataRow)LineSelectCB.SelectedValue).Style;
+        ColorPreviewTB.BackColor = ((IDataRow)LineSelectCB.SelectedValue).Color;   
+      }
+    }
+
+    
+    private void OptionsDialogOkButton_Click(object sender, EventArgs e) {
+      Close();
+    }
+    
+    private void cbLegendPosition_SelectedIndexChanged(object sender, EventArgs e) {
+      viewSettings.LegendPosition = (LegendPosition)cbLegendPosition.SelectedItem;
+      viewSettings.UpdateView();
+    }
+
+    private void btnChangeTitleFont_Click(object sender, EventArgs e) {
+      fdFont.Font = viewSettings.TitleFont;
+      fdFont.Color = viewSettings.TitleColor;
+
+      DialogResult dr = fdFont.ShowDialog();
+
+      if(dr == DialogResult.OK) {
+        viewSettings.TitleFont = fdFont.Font;
+        viewSettings.TitleColor = fdFont.Color;
+
+        viewSettings.UpdateView();
+      }
+    }
+
+    private void btnChangeLegendFont_Click(object sender, EventArgs e) {
+      fdFont.Font = viewSettings.LegendFont;
+      fdFont.Color = viewSettings.LegendColor;
+
+      DialogResult dr = fdFont.ShowDialog();
+
+      if (dr == DialogResult.OK) {
+        viewSettings.LegendFont = fdFont.Font;
+        viewSettings.LegendColor = fdFont.Color;
+
+        viewSettings.UpdateView();
+      }
+    }
+
+    private void btnChangeXAxisFont_Click(object sender, EventArgs e) {
+      fdFont.Font = viewSettings.XAxisFont;
+      fdFont.Color = viewSettings.XAxisColor;
+
+      DialogResult dr = fdFont.ShowDialog();
+
+      if (dr == DialogResult.OK) {
+        viewSettings.XAxisFont = fdFont.Font;
+        viewSettings.XAxisColor = fdFont.Color;
+
+        viewSettings.UpdateView();
+      }
+    }
+
+    private void OptionsDialogResetButton_Click(object sender, EventArgs e) {
+      foreach (var param in oldLineParams) {
+        param.applySettings();
+      }
+
+      foreach (var box in ShowYAxisBoxes) {
+        box.Key.Checked = box.Value;
+      }
+
+      foreach (KeyValuePair<CheckBox, bool> box in yAxisClipChangeableBoxes) {
+        box.Key.Checked = box.Value;
+      }
+
+      viewSettings.LegendColor = oldViewSettings.LegendColor;
+      viewSettings.LegendPosition = oldViewSettings.LegendPosition;
+      viewSettings.LegendFont = oldViewSettings.LegendFont;
+      viewSettings.TitleColor = oldViewSettings.TitleColor;
+      viewSettings.TitleFont = oldViewSettings.TitleFont;
+      viewSettings.XAxisColor = oldViewSettings.LegendColor;
+      viewSettings.XAxisFont = oldViewSettings.XAxisFont;
+      viewSettings.UpdateView();
+      cbLegendPosition.SelectedItem = viewSettings.LegendPosition;
+      this.LineSelectCB_SelectedIndexChanged(this,null);
+    }
+
+    private void LinestyleCB_SelectedIndexChanged(object sender, EventArgs e) {
+      if (LineSelectCB.SelectedValue != null)
+        ((IDataRow)LineSelectCB.SelectedValue).Style = (DrawingStyle)LinestyleCB.SelectedItem;
+    }
+
+    private void LineThicknessCB_SelectedIndexChanged(object sender, EventArgs e) {
+      if (LineSelectCB.SelectedValue != null)
+        ((IDataRow)LineSelectCB.SelectedValue).Thickness = (int)LineThicknessCB.SelectedItem;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.resx
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.resx	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Options/OptionsDialog.resx	(revision 1530)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="fdFont.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: trunk/sources/HeuristicLab.Visualization/3.2/Options/ViewSettings.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Options/ViewSettings.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Options/ViewSettings.cs	(revision 1530)
@@ -0,0 +1,86 @@
+using System.Drawing;
+using HeuristicLab.Visualization.Legend;
+
+namespace HeuristicLab.Visualization.Options {
+  public class ViewSettings {
+    public event UpdateViewSettingsHandler OnUpdateSettings;
+
+    private Font titleFont;
+    private Color titleColor;
+    private Font legendFont;
+    private Color legendColor;
+    private Font xAxisFont;
+    private Color xAxisColor;
+    private LegendPosition legendPosition;
+
+    public ViewSettings() {
+      titleFont = new Font("Arial", 8);
+      titleColor = Color.Blue;
+
+      legendFont = new Font("Arial", 8);
+      legendColor = Color.Blue;
+
+      xAxisFont = new Font("Arial", 8);
+      xAxisColor = Color.Blue;
+
+      legendPosition = LegendPosition.Bottom;
+    }
+
+    public ViewSettings(ViewSettings src) {
+      
+      titleFont = (Font)(src.titleFont.Clone());
+      titleColor = src.TitleColor;
+
+      legendFont = (Font)(src.legendFont.Clone());
+      legendColor = src.LegendColor;
+
+      xAxisFont = (Font) (src.xAxisFont.Clone());
+      xAxisColor = src.XAxisColor;
+
+      legendPosition = src.LegendPosition;
+    }
+
+    public void UpdateView() {
+      if (OnUpdateSettings != null) {
+        OnUpdateSettings();
+      }
+    }
+
+    public Font TitleFont {
+      get { return titleFont; }
+      set { titleFont = value; }
+    }
+
+    public Color TitleColor {
+      get { return titleColor; }
+      set { titleColor = value; }
+    }
+
+    public Font LegendFont {
+      get { return legendFont; }
+      set { legendFont = value; }
+    }
+
+    public Color LegendColor {
+      get { return legendColor; }
+      set { legendColor = value; }
+    }
+
+    public Font XAxisFont {
+      get { return xAxisFont; }
+      set { xAxisFont = value; }
+    }
+
+    public Color XAxisColor {
+      get { return xAxisColor; }
+      set { xAxisColor = value; }
+    }
+
+    public LegendPosition LegendPosition {
+      get { return legendPosition; }
+      set { legendPosition = value; }
+    }
+  }
+
+  public delegate void UpdateViewSettingsHandler();
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/PanListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/PanListener.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/PanListener.cs	(revision 1530)
@@ -0,0 +1,33 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Visualization {
+  public class PanListener : IMouseEventListener {
+    private Point startPoint;
+
+    public event MoveHandler Pan;
+    public event MoveHandler PanEnd;
+
+    public PanListener(Point startPoint) {
+      this.startPoint = startPoint;
+    }
+
+    #region IMouseEventListener Members
+
+    public void MouseMove(object sender, MouseEventArgs e) {
+      if (Pan != null) {
+        Pan(startPoint, e.Location);
+      }
+
+      startPoint = e.Location;  
+    }
+
+    public void MouseUp(object sender, MouseEventArgs e) {
+      if(PanEnd != null) {
+        PanEnd(startPoint, e.Location);
+      }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/PointD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/PointD.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/PointD.cs	(revision 1530)
@@ -0,0 +1,128 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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;
+
+namespace HeuristicLab.Visualization {
+  public struct PointD {
+    public static readonly PointD Empty = new PointD();
+
+    private double myX;
+
+    public double X {
+      get { return myX; }
+      set { myX = value; }
+    }
+
+    private double myY;
+
+    public double Y {
+      get { return myY; }
+      set { myY = value; }
+    }
+
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+
+    public PointD(double x, double y) {
+      myX = x;
+      myY = y;
+    }
+
+    public PointD(SizeD size) {
+      myX = size.Width;
+      myY = size.Height;
+    }
+
+    public PointD(Offset offset) {
+      myX = offset.DX;
+      myY = offset.DY;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is PointD) {
+        return ((PointD)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+
+    public override int GetHashCode() {
+      return (int)Math.Pow(X, Y);
+    }
+
+    public override string ToString() {
+      return string.Format("({0};{1})", X, Y);
+    }
+
+    public static PointD operator +(PointD point, Offset offset) {
+      return new PointD(point.X + offset.DX, point.Y + offset.DY);
+    }
+
+    public static PointD operator -(PointD point, Offset offset) {
+      return new PointD(point.X - offset.DX, point.Y - offset.DY);
+    }
+
+    public static Offset operator +(PointD point1, PointD point2) {
+      return new Offset(point1.X + point2.X, point1.Y + point2.Y);
+    }
+
+    public static Offset operator -(PointD point1, PointD point2) {
+      return new Offset(point1.X - point2.X, point1.Y - point2.Y);
+    }
+
+    public static bool operator ==(PointD point1, PointD point2) {
+      return (point1.X == point2.X) && (point1.Y == point2.Y);
+    }
+
+    public static bool operator !=(PointD point1, PointD point2) {
+      return (point1.X != point2.X) && (point1.Y != point2.Y);
+    }
+
+    public static explicit operator SizeD(PointD point) {
+      return new SizeD(point.X, point.Y);
+    }
+
+    public static explicit operator Offset(PointD point) {
+      return new Offset(point.X, point.Y);
+    }
+
+    public static implicit operator PointD(Point point) {
+      return new PointD(point.X, point.Y);
+    }
+
+    public static implicit operator PointD(PointF point) {
+      return new PointD(point.X, point.Y);
+    }
+
+    public static PointD Add(PointD point, Offset offset) {
+      return new PointD(point.X + offset.DX, point.Y + offset.DY);
+    }
+
+    public static PointD Subtract(PointD point, Offset offset) {
+      return new PointD(point.X - offset.DX, point.Y - offset.DY);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Properties/AssemblyInfo.frame	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Properties/AssemblyInfo.frame	(revision 1530)
@@ -0,0 +1,59 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Visualization")]
+[assembly: AssemblyDescription("HeuristicLab data visualization framework")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2008 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f7c10f77-1067-4b4c-876a-92fe49b4f228")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: trunk/sources/HeuristicLab.Visualization/3.2/RectangleD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/RectangleD.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/RectangleD.cs	(revision 1530)
@@ -0,0 +1,95 @@
+namespace HeuristicLab.Visualization {
+  public struct RectangleD {
+    public static readonly RectangleD Empty = new RectangleD();
+
+    private PointD bottomLeft;
+    private PointD topRight;
+
+    private double width;
+    private double height;
+
+    public RectangleD(double x1, double y1, double x2, double y2) {
+      bottomLeft = PointD.Empty;
+      topRight = PointD.Empty;
+
+      bottomLeft.X = x1;
+      bottomLeft.Y = y1;
+
+      topRight.X = x2;
+      topRight.Y = y2;
+
+      width = x2 - x1;
+      height = y2 - y1;
+    }
+
+    public PointD BottomLeft {
+      get { return bottomLeft; }
+      set {
+        bottomLeft = value;
+        width = topRight.X - bottomLeft.X;
+        height = topRight.Y - bottomLeft.Y;
+      }
+    }
+
+    public PointD TopRight {
+      get { return topRight; }
+      set {
+        topRight = value;
+        width = topRight.X - bottomLeft.X;
+        height = topRight.Y - bottomLeft.Y;
+      }
+    }
+
+    public double X1 {
+      get { return bottomLeft.X; }
+      set {
+        bottomLeft.X = value;
+        width = topRight.X - bottomLeft.X;
+      }
+    }
+
+    public double X2 {
+      get { return topRight.X; }
+      set {
+        topRight.X = value;
+        width = topRight.X - bottomLeft.X;
+      }
+    }
+
+    public double Y1 {
+      get { return bottomLeft.Y; }
+      set {
+        bottomLeft.Y = value;
+        height = topRight.Y - bottomLeft.Y;
+      }
+    }
+
+    public double Y2 {
+      get { return topRight.Y; }
+      set {
+        topRight.Y = value;
+        height = topRight.Y - bottomLeft.Y;
+      }
+    }
+
+    public double Width {
+      get { return width; }
+      set {
+        width = value;
+        topRight.X = bottomLeft.X + width;
+      }
+    }
+
+    public double Height {
+      get { return height; }
+      set {
+        height = value;
+        topRight.Y = bottomLeft.Y + height;
+      }
+    }
+
+    public override string ToString() {
+      return (string.Format("{{X1={0},Y1={1},Width={2},Height={3}}}", X1, Y1, Width, Height));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/RectangleShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/RectangleShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/RectangleShape.cs	(revision 1530)
@@ -0,0 +1,79 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public class RectangleShape : IShape {
+    private IShape parent;
+    private RectangleD rectangle;
+
+    private Color color;
+
+    private Pen pen;
+    private Brush brush;
+
+    public RectangleShape(double x1, double y1, double x2, double y2, Color color) {
+      rectangle = new RectangleD(x1, y1, x2, y2);
+      this.color = color;
+    }
+
+    public RectangleD BoundingBox {
+      get { return rectangle; }
+    }
+
+    public RectangleD ClippingArea {
+      get { return Parent.ClippingArea; }
+    }
+
+    public Rectangle Viewport {
+      get { return Parent.Viewport; }
+    }
+
+    public IShape Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    public RectangleD Rectangle {
+      get { return rectangle; }
+      set { rectangle = value; }
+    }
+
+    public void Draw(Graphics graphics) {
+      Rectangle screenRect = Transform.ToScreen(rectangle, Parent.Viewport, Parent.ClippingArea);
+
+      graphics.DrawRectangle(GetPen(), screenRect);
+      graphics.FillRectangle(GetBrush(), screenRect);
+    }
+
+    private Pen GetPen() {
+      if (pen == null)
+        pen = new Pen(color, 1);
+      return pen;
+    }
+
+    private Brush GetBrush() {
+      if (brush == null)
+        brush = new SolidBrush(color);
+      return brush;
+    }
+
+    public Color Color {
+      get { return color; }
+      set {
+        color = value;
+        DisposeDrawingTools();
+      }
+    }
+
+    private void DisposeDrawingTools() {
+      if (pen != null) {
+        pen.Dispose();
+        pen = null;
+      }
+
+      if (brush != null) {
+        brush.Dispose();
+        brush = null;
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/SizeD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/SizeD.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/SizeD.cs	(revision 1530)
@@ -0,0 +1,120 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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;
+
+namespace HeuristicLab.Visualization {
+  public struct SizeD {
+    public static readonly SizeD Empty = new SizeD();
+
+    private double myWidth;
+
+    public double Width {
+      get { return myWidth; }
+      set { myWidth = value; }
+    }
+
+    private double myHeight;
+
+    public double Height {
+      get { return myHeight; }
+      set { myHeight = value; }
+    }
+
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+
+    public SizeD(double width, double height) {
+      myWidth = width;
+      myHeight = height;
+    }
+
+    public SizeD(PointD point) {
+      myWidth = point.X;
+      myHeight = point.Y;
+    }
+
+    public SizeD(Offset offset) {
+      myWidth = offset.DX;
+      myHeight = offset.DY;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is SizeD) {
+        return ((SizeD)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+
+    public override int GetHashCode() {
+      return (int)Math.Pow(Width, Height);
+    }
+
+    public override string ToString() {
+      return string.Format("({0};{1})", Width, Height);
+    }
+
+    public static SizeD operator +(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
+    }
+
+    public static SizeD operator -(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
+    }
+
+    public static bool operator ==(SizeD size1, SizeD size2) {
+      return (size1.Width == size2.Width) && (size1.Height == size2.Height);
+    }
+
+    public static bool operator !=(SizeD size1, SizeD size2) {
+      return (size1.Width != size2.Width) && (size1.Height != size2.Height);
+    }
+
+    public static explicit operator PointD(SizeD size) {
+      return new PointD(size.Width, size.Height);
+    }
+
+    public static explicit operator Offset(SizeD size) {
+      return new Offset(size.Width, size.Height);
+    }
+
+    public static implicit operator SizeD(Size size) {
+      return new SizeD(size.Width, size.Height);
+    }
+
+    public static implicit operator SizeD(SizeF size) {
+      return new SizeD(size.Width, size.Height);
+    }
+
+    public static SizeD Add(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
+    }
+
+    public static SizeD Subtract(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/TextShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/TextShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/TextShape.cs	(revision 1530)
@@ -0,0 +1,154 @@
+﻿using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Visualization {
+  public enum AnchorPositionX {
+    Left, Middle, Right
+  }
+
+  public enum AnchorPositionY {
+    Bottom, Middle, Top
+  }
+
+  public class TextShape : IShape {
+    private IShape parent;
+    private Font font;
+    private Brush brush;
+    private Color color;
+    private string text;
+    private double x;
+    private double y;
+    private float rotation = 0;
+
+    private AnchorPositionX anchorPositionX = AnchorPositionX.Left;
+    private AnchorPositionY anchorPositionY = AnchorPositionY.Top;
+
+    public TextShape(string text) : this(0, 0, text, 14) {}
+
+    public TextShape(double x, double y, string text) : this(x, y, text, 8) {}
+
+    public TextShape(double x, double y, string text, int fontSize) {
+      this.x = x;
+      this.y = y;
+      this.text = text;
+      font = new Font("Arial", fontSize);
+
+      Color = Color.Blue;
+    }
+
+    public TextShape(double x, double y, string text, Font font, Color color) {
+      this.x = x;
+      this.y = y;
+      this.text = text;
+      Font = font;
+      Color = color;
+    }
+
+    public string Text {
+      get { return text; }
+      set { text = value; }
+    }
+
+    public double X {
+      get { return x; }
+      set { x = value; }
+    }
+
+    public double Y {
+      get { return y; }
+      set { y = value; }
+    }
+
+    public float Rotation {
+      get { return rotation; }
+      set { rotation = value; }
+    }
+
+    public Color Color {
+      get { return color; }
+      set {
+        color = value;
+        brush = new SolidBrush(color);
+      }
+    }
+
+    public Font Font {
+      get { return font; }
+      set { font = value; }
+    }
+
+    public AnchorPositionX AnchorPositionX {
+      get { return anchorPositionX; }
+      set { anchorPositionX = value; }
+    }
+
+    public AnchorPositionY AnchorPositionY {
+      get { return anchorPositionY; }
+      set { anchorPositionY = value; }
+    }
+
+    #region IShape Members
+
+    public void Draw(Graphics graphics) {
+      int screenX = Transform.ToScreenX(x, Parent.Viewport, Parent.ClippingArea);
+      int screenY = Transform.ToScreenY(y, Parent.Viewport, Parent.ClippingArea);
+      int offsetX, offsetY;
+
+      SizeF size = graphics.MeasureString(text, font);
+
+      switch (AnchorPositionX) {
+        case AnchorPositionX.Left:
+          offsetX = 0;
+          break;
+        case AnchorPositionX.Middle:
+          offsetX = -(int)(size.Width/2);
+          break;
+        case AnchorPositionX.Right:
+          offsetX = -(int)size.Width;
+          break;
+        default:
+          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
+      }
+
+      switch (AnchorPositionY) {
+        case AnchorPositionY.Top:
+          offsetY = 0;
+          break;
+        case AnchorPositionY.Middle:
+          offsetY = -(int)(size.Height/2);
+          break;
+        case AnchorPositionY.Bottom:
+          offsetY = -(int)size.Height;
+          break;
+        default:
+          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
+      }
+
+      GraphicsState gstate = graphics.Save();
+      graphics.TranslateTransform(screenX, screenY, MatrixOrder.Append);
+      graphics.RotateTransform(rotation, MatrixOrder.Prepend);
+      graphics.DrawString(text, font, brush, offsetX, offsetY);
+      graphics.Restore(gstate);
+    }
+
+    public RectangleD BoundingBox {
+      get { return RectangleD.Empty; }
+    }
+
+    public RectangleD ClippingArea {
+      get { return Parent.ClippingArea; }
+    }
+
+    public Rectangle Viewport {
+      get { return Parent.Viewport; }
+    }
+
+    public IShape Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Transform.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Transform.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Transform.cs	(revision 1530)
@@ -0,0 +1,117 @@
+﻿using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  /// <summary>
+  /// GDI (or screen) coordinate system
+  ///   The GDI coordinate system is specified in pixels. X goes from left to right
+  ///   and Y goes from top to bottom.
+  /// 
+  /// World coordinate system
+  ///   A world coordinate system can be freely specified. X goes from left to
+  ///   right and Y goes from bottom to top.
+  /// 
+  /// The transformation between world- and screen-coordinate systems is done using
+  /// a view port and a clipping area.
+  /// </summary>
+  public static class Transform {
+    /// <summary>
+    /// Transforms a rectangle in screen coordinates to world coordinates
+    /// </summary>
+    /// <param name="rect">The rectangle in screen coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The rectangle rect transformed to world coordinates</returns>
+    public static RectangleD ToWorld(Rectangle rect, Rectangle viewport, RectangleD clippingArea) {
+      double x1 = ToWorldX(rect.Left, viewport, clippingArea);
+      double y1 = ToWorldY(rect.Bottom, viewport, clippingArea);
+      double x2 = ToWorldX(rect.Right, viewport, clippingArea);
+      double y2 = ToWorldY(rect.Top, viewport, clippingArea);
+      return new RectangleD(x1, y1, x2, y2);
+    }
+
+    /// <summary>
+    /// Transforms a 2d point in screen coordinates to world coordinates
+    /// </summary>
+    /// <param name="point">The point in screen coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to world coordinates</returns>
+    public static PointD ToWorld(Point point, Rectangle viewport, RectangleD clippingArea) {
+      double x = ToWorldX(point.X, viewport, clippingArea);
+      double y = ToWorldY(point.Y, viewport, clippingArea);
+      return new PointD(x, y);
+    }
+
+    /// <summary>
+    /// Transforms a point on the X-axis in screen coordinates to world coordinates
+    /// </summary>
+    /// <param name="x">The point on the X-axis in screen coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to world coordinates</returns>
+    public static double ToWorldX(int x, Rectangle viewport, RectangleD clippingArea) {
+      return clippingArea.X1 + clippingArea.Width/viewport.Width*(x - viewport.Left);
+    }
+
+    /// <summary>
+    /// Transforms a point on the Y-axis in screen coordinates to world coordinates
+    /// </summary>
+    /// <param name="y">The point on the Y-axis in screen coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to world coordinates</returns>
+    public static double ToWorldY(int y, Rectangle viewport, RectangleD clippingArea) {
+      return clippingArea.Y1 - clippingArea.Height/viewport.Height*(y - viewport.Bottom);
+    }
+
+    /// <summary>
+    /// Transforms a rectangle in world coordinates to screen coordinates
+    /// </summary>
+    /// <param name="rect">The rectangle in world coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The rectangle rect transformed to screen coordinates</returns>
+    public static Rectangle ToScreen(RectangleD rect, Rectangle viewport, RectangleD clippingArea) {
+      int left = ToScreenX(rect.X1, viewport, clippingArea);
+      int bottom = ToScreenY(rect.Y1, viewport, clippingArea);
+      int right = ToScreenX(rect.X2, viewport, clippingArea);
+      int top = ToScreenY(rect.Y2, viewport, clippingArea);
+      return new Rectangle(left, top, right - left , bottom - top );
+    }
+
+    /// <summary>
+    /// Transforms a 2d point in world coordinates to screen coordinates
+    /// </summary>
+    /// <param name="point">The point in world coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to screen coordinates</returns>
+    public static Point ToScreen(PointD point, Rectangle viewport, RectangleD clippingArea) {
+      int x = ToScreenX(point.X, viewport, clippingArea);
+      int y = ToScreenY(point.Y, viewport, clippingArea);
+      return new Point(x, y);
+    }
+
+    /// <summary>
+    /// Transforms a point on the X-axis in world coordinates to screen coordinates
+    /// </summary>
+    /// <param name="x">The point on the X-axis in world coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to screen coordinates</returns>
+    public static int ToScreenX(double x, Rectangle viewport, RectangleD clippingArea) {
+      return (int)(viewport.Left + viewport.Width/clippingArea.Width*(x - clippingArea.X1));
+    }
+
+    /// <summary>
+    /// Transforms a point on the Y-axis in world coordinates to screen coordinates
+    /// </summary>
+    /// <param name="y">The point on the Y-axis in world coordinates that should be transformed</param>
+    /// <param name="viewport">The target view port</param>
+    /// <param name="clippingArea">The target clipping area</param>
+    /// <returns>The point transformed to screen coordinates</returns>
+    public static int ToScreenY(double y, Rectangle viewport, RectangleD clippingArea) {
+      return (int)(viewport.Bottom - viewport.Height/clippingArea.Height*(y - clippingArea.Y1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/Translate.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/Translate.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/Translate.cs	(revision 1530)
@@ -0,0 +1,26 @@
+using System.Drawing;
+
+namespace HeuristicLab.Visualization {
+  public static class Translate {
+    public static RectangleD ClippingArea(Point startPoint, Point endPoint, RectangleD clippingArea, Rectangle viewPort) {
+      PointD worldStartPoint = Transform.ToWorld(startPoint, viewPort, clippingArea);
+      PointD worldEndPoint = Transform.ToWorld(endPoint, viewPort, clippingArea);
+
+      double xDiff = worldEndPoint.X - worldStartPoint.X;
+      double yDiff = worldEndPoint.Y - worldStartPoint.Y;
+
+      return RectangleD(xDiff, yDiff, clippingArea);
+    }
+
+    public static RectangleD RectangleD(double x, double y, RectangleD rectangle) {
+      RectangleD rect = new RectangleD();
+
+      rect.X1 = rectangle.X1 - x;
+      rect.X2 = rectangle.X2 - x;
+      rect.Y1 = rectangle.Y1 - y;
+      rect.Y2 = rectangle.Y2 - y;
+
+      return rect;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/WorldShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/WorldShape.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/WorldShape.cs	(revision 1530)
@@ -0,0 +1,77 @@
+﻿using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Visualization {
+  /// <summary>
+  /// World shapes are composite shapes that have their own coordinate system
+  /// which is independent from their parent's coordinate system.
+  /// </summary>
+  public class WorldShape : IShape {
+    private RectangleD clippingArea; // own clipping area
+    private RectangleD boundingBox;
+    private IShape parent;
+
+    protected readonly List<IShape> shapes = new List<IShape>();
+
+    public WorldShape() {
+      this.clippingArea = new RectangleD(0, 0, 1, 1);
+      this.boundingBox = new RectangleD(0, 0, 1, 1);
+    }
+
+    public virtual void Draw(Graphics graphics) {
+      GraphicsState gstate = graphics.Save();
+
+      graphics.SetClip(Viewport);
+
+      foreach (IShape shape in shapes) {
+        // draw child shapes using our own clipping area
+        shape.Draw(graphics);
+      }
+
+      graphics.Restore(gstate);
+    }
+
+    public RectangleD BoundingBox {
+      get { return boundingBox; }
+      set { boundingBox = value; }
+    }
+
+    /// <summary>
+    /// The world shape's own clipping area.
+    /// This overrides the clipping area of the parent shape.
+    /// </summary>
+    public RectangleD ClippingArea {
+      get { return clippingArea; }
+      set { clippingArea = value; }
+    }
+
+    public Rectangle Viewport {
+      get {
+        // calculate our drawing area on the screen using our location and
+        // size in the parent (boundingBox), the parent's viewport and the
+        // parent's clipping area
+        Rectangle viewport = Transform.ToScreen(boundingBox, Parent.Viewport, Parent.ClippingArea);
+        return viewport;
+      }
+    }
+
+    public IShape Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    public void ClearShapes() {
+      shapes.Clear();
+    }
+
+    public void AddShape(IShape shape) {
+      shape.Parent = this;
+      shapes.Add(shape);
+    }
+
+    public bool RemoveShape(IShape shape) {
+      return shapes.Remove(shape);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/XAxis.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/XAxis.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/XAxis.cs	(revision 1530)
@@ -0,0 +1,66 @@
+using System.Drawing;
+using HeuristicLab.Visualization.LabelProvider;
+
+namespace HeuristicLab.Visualization {
+  public class XAxis : WorldShape {
+    public const int PixelsPerInterval = 100;
+    
+    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.####");
+
+    private Color color = Color.Blue;
+    private Font font = new Font("Arial", 8);
+    private bool showLabel = true;
+    private string label = "";
+
+    public ILabelProvider LabelProvider {
+      get { return labelProvider; }
+      set { labelProvider = value; }
+    }
+
+    public override void Draw(Graphics graphics) {
+      ClearShapes();
+
+      foreach (double x in AxisTicks.GetTicks(PixelsPerInterval, Parent.Viewport.Width,
+                                              ClippingArea.Width,
+                                              ClippingArea.X1)) {
+        TextShape tickLabel = new TextShape(x, ClippingArea.Height - 3,
+                                        labelProvider.GetLabel(x), Font, Color);
+        tickLabel.AnchorPositionX = AnchorPositionX.Middle;
+        tickLabel.AnchorPositionY = AnchorPositionY.Top;
+        AddShape(tickLabel);
+      }
+
+      if (showLabel) {
+        TextShape label = new TextShape(ClippingArea.X1 + ClippingArea.Width/2,
+                                        ClippingArea.Y1 + 3,
+                                        this.label);
+        label.AnchorPositionX = AnchorPositionX.Middle;
+        label.AnchorPositionY = AnchorPositionY.Bottom;
+
+        AddShape(label);
+      }
+
+      base.Draw(graphics);
+    }
+
+    public Color Color {
+      get { return color; }
+      set { color = value; }
+    }
+
+    public Font Font {
+      get { return font; }
+      set { font = value; }
+    }
+
+    public bool ShowLabel {
+      get { return showLabel; }
+      set { showLabel = value; }
+    }
+
+    public string Label {
+      get { return label; }
+      set { label = value; }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/YAxis.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/YAxis.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/YAxis.cs	(revision 1530)
@@ -0,0 +1,92 @@
+using System;
+using System.Drawing;
+using HeuristicLab.Visualization.LabelProvider;
+using HeuristicLab.Visualization.Test;
+
+namespace HeuristicLab.Visualization {
+  public class YAxis : WorldShape {
+    public const int PixelsPerInterval = 75;
+
+    private ILabelProvider labelProvider = new ContinuousLabelProvider("e4");
+    private AxisPosition position = AxisPosition.Left;
+    private bool showLabel = true;
+    private string label = "";
+
+    public ILabelProvider LabelProvider {
+      get { return labelProvider; }
+      set { labelProvider = value; }
+    }
+
+    public AxisPosition Position {
+      get { return position; }
+      set { position = value; }
+    }
+
+    public bool ShowLabel {
+      get { return showLabel; }
+      set { showLabel = value; }
+    }
+
+    public string Label {
+      get { return label; }
+      set { label = value; }
+    }
+
+    public override void Draw(Graphics graphics) {
+      ClearShapes();
+
+      foreach (double y in AxisTicks.GetTicks(PixelsPerInterval, Parent.Viewport.Height,
+                                              ClippingArea.Height,
+                                              ClippingArea.Y1)) {
+        double x;
+        AnchorPositionX anchorPositionX;
+
+        switch (position) {
+          case AxisPosition.Left:
+            x = ClippingArea.X2 - 3;
+            anchorPositionX = AnchorPositionX.Right;
+            break;
+          case AxisPosition.Right:
+            x = ClippingArea.X1 + 3;
+            anchorPositionX = AnchorPositionX.Left;
+            break;
+          default:
+            throw new NotImplementedException();
+        }
+        
+        TextShape tickLabel = new TextShape(x, y, labelProvider.GetLabel(y));
+        tickLabel.AnchorPositionX = anchorPositionX;
+        tickLabel.AnchorPositionY = AnchorPositionY.Middle;
+        AddShape(tickLabel);
+      }
+
+      if (showLabel) {
+        double x;
+        AnchorPositionY anchorPositionY;
+
+        switch (position) {
+          case AxisPosition.Left:
+            x = ClippingArea.X1 + 3;
+            anchorPositionY = AnchorPositionY.Top;
+            break;
+          case AxisPosition.Right:
+            x = ClippingArea.X2 - 3;
+            anchorPositionY = AnchorPositionY.Bottom;
+            break;
+          default:
+            throw new NotImplementedException();
+        }
+
+        TextShape label = new TextShape(x,
+                                        ClippingArea.Y1 + ClippingArea.Height/2,
+                                        this.label);
+        label.AnchorPositionX = AnchorPositionX.Middle;
+        label.AnchorPositionY = anchorPositionY;
+        label.Rotation = -90;
+        AddShape(label);
+      }
+
+      base.Draw(graphics);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/YAxisDescriptor.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/YAxisDescriptor.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/YAxisDescriptor.cs	(revision 1530)
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Visualization.LabelProvider;
+using HeuristicLab.Visualization.Test;
+
+namespace HeuristicLab.Visualization {
+  public delegate void YAxisDescriptorChangedHandler(YAxisDescriptor sender);
+
+  public class YAxisDescriptor {
+    private ILabelProvider yAxisLabelProvider = new ContinuousLabelProvider("0.##");
+    private readonly List<IDataRow> dataRows = new List<IDataRow>();
+    private bool showYAxis = true;
+    private bool showYAxisLabel = true;
+    private string label = "";
+    public bool clipChangeable = true;
+    private AxisPosition position = AxisPosition.Left;
+
+    private bool showGrid = true;
+    private Color gridColor = Color.LightBlue;
+
+    public event YAxisDescriptorChangedHandler YAxisDescriptorChanged;
+
+    private void OnYAxisDescriptorChanged() {
+      if (YAxisDescriptorChanged != null) {
+        YAxisDescriptorChanged(this);
+      }
+    }
+
+    public List<IDataRow> DataRows {
+      get { return dataRows; }
+    }
+
+    public bool ShowYAxis {
+      get { return showYAxis; }
+      set {
+        showYAxis = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public bool ShowYAxisLabel {
+      get { return showYAxisLabel; }
+      set {
+        showYAxisLabel = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public ILabelProvider YAxisLabelProvider {
+      get { return yAxisLabelProvider; }
+      set {
+        yAxisLabelProvider = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public double MinValue {
+      get {
+        double min = double.MaxValue;
+
+        foreach (IDataRow row in dataRows) {
+          min = Math.Min(min, row.MinValue);
+        }
+
+        return min;
+      }
+    }
+
+    public double MaxValue {
+      get {
+        double max = double.MinValue;
+
+        foreach (IDataRow row in dataRows) {
+          max = Math.Max(max, row.MaxValue);
+        }
+
+        return max;
+      }
+    }
+
+    public string Label {
+      get { return label; }
+      set {
+        label = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public bool ClipChangeable {
+      get { return clipChangeable; }
+      set { clipChangeable = value; }
+    }
+
+    public AxisPosition Position {
+      get { return position; }
+      set {
+        position = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public bool ShowGrid {
+      get { return showGrid; }
+      set {
+        showGrid = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public Color GridColor {
+      get { return gridColor; }
+      set {
+        gridColor = value;
+        OnYAxisDescriptorChanged();
+      }
+    }
+
+    public void AddDataRow(IDataRow row) {
+      if (row.YAxis != null) {
+        row.YAxis.DataRows.Remove(row);
+      }
+      this.DataRows.Add(row);
+      OnYAxisDescriptorChanged();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/3.2/ZoomListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/3.2/ZoomListener.cs	(revision 1530)
+++ trunk/sources/HeuristicLab.Visualization/3.2/ZoomListener.cs	(revision 1530)
@@ -0,0 +1,67 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Visualization {
+  public class ZoomListener : IMouseEventListener {
+    private readonly Point startPoint;
+
+    public event RectangleHandler DrawRectangle;
+    public event RectangleHandler SetClippingArea;
+
+    public ZoomListener(Point startPoint) {
+      this.startPoint = startPoint;
+    }
+
+    #region IMouseEventListener Members
+
+    public void MouseMove(object sender, MouseEventArgs e) {
+      if(DrawRectangle != null) {
+        DrawRectangle(CalcRectangle(e.Location));
+      }
+    }
+
+    public void MouseUp(object sender, MouseEventArgs e) {
+     if(SetClippingArea != null) {
+       SetClippingArea(CalcRectangle(e.Location));
+     }
+    }
+
+    #endregion
+
+    private Rectangle CalcRectangle(Point actualPoint) {
+      Rectangle rectangle = new Rectangle();
+
+      if (startPoint.X < actualPoint.X) {
+        rectangle.X = startPoint.X;
+        rectangle.Width = actualPoint.X - startPoint.X;
+      } else {
+        rectangle.X = actualPoint.X;
+        rectangle.Width = startPoint.X - actualPoint.X;
+      }
+
+      if (startPoint.Y < actualPoint.Y) {
+        rectangle.Y = startPoint.Y;
+        rectangle.Height = actualPoint.Y - startPoint.Y;
+      } else {
+        rectangle.Y = actualPoint.Y;
+        rectangle.Height = startPoint.Y - actualPoint.Y;
+      }
+
+      return rectangle;
+    }
+
+    public static RectangleD ZoomClippingArea(RectangleD clippingArea, double zoomFactor) {
+      double x1, x2, y1, y2, width, height;
+
+      width = clippingArea.Width * zoomFactor;
+      height = clippingArea.Height * zoomFactor;
+
+      x1 = clippingArea.X1 - (width - clippingArea.Width) / 2;
+      y1 = clippingArea.Y1 - (height - clippingArea.Height) / 2;
+      x2 = width + x1;
+      y2 = height + y1;
+
+      return new RectangleD(x1, y1, x2, y2);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Visualization/AvgAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/AvgAggregator.cs	(revision 1528)
+++ 	(revision )
@@ -1,111 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-
-namespace HeuristicLab.Visualization {
-  public class AvgAggregator : DataRowBase {
-    #region IAggregator Members
-
-    public void AddWatch(IDataRow dataRow) {
-      dataRowWatches.Add(dataRow);
-      dataRow.ValueChanged += dataRow_ValueChanged;
-      dataRow.ValuesChanged += dataRow_ValuesChanged;
-      dataRow.DataRowChanged += dataRow_DataRowChanged;
-    }
-
-    public void RemoveWatch(IDataRow dataRow) {
-      dataRowWatches.Remove(dataRow);
-      dataRow.DataRowChanged -= dataRow_DataRowChanged;
-      dataRow.ValuesChanged -= dataRow_ValuesChanged;
-      dataRow.ValueChanged -= dataRow_ValueChanged;
-    }
-
-    #endregion
-
-    private List<IDataRow> dataRowWatches = new List<IDataRow>();
-    private double curAvgValue;
-
-    private void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
-      refreshValue(value);
-    }
-
-    private void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      for (int i = 0; i < values.Length; i++) {
-        refreshValue(values[i]);
-      }
-    }
-
-    private void dataRow_DataRowChanged(IDataRow row) {
-      refreshValue(double.MinValue);
-    }
-
-    private void refreshValue(double newVal) {
-      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
-
-      curAvgValue = double.MinValue;
-      double tmpSum = 0;
-      int count = 0;
-      foreach (IDataRow rows in dataRowWatches) {
-        for (int i = 0; i < rows.Count; i++) {
-          tmpSum += rows[i];
-          count++;
-        }
-      }
-      curAvgValue = tmpSum/count;
-      // evtl nur feuern wenn sich geändert hat (jedes mal?)
-      OnValueChanged(curAvgValue, 0, Action.Modified);
-    }
-
-    #region IDataRow Members
-
-    public override void AddValue(double value) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValue(int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValues(int index, int count) {
-      throw new NotSupportedException();
-    }
-
-    public override int Count {
-      get { return 1; }
-    }
-
-    public override double this[int index] {
-      get { return curAvgValue; }
-      set { throw new NotSupportedException(); }
-    }
-
-    public override double MinValue {
-      get { return curAvgValue; }
-    }
-
-    public override double MaxValue {
-      get { return curAvgValue; }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/AvgLineAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/AvgLineAggregator.cs	(revision 1528)
+++ 	(revision )
@@ -1,135 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-
-namespace HeuristicLab.Visualization {
-  public class AvgLineAggregator : DataRowBase {
-
-    private readonly List<double> dataRow = new List<double>();
-
-    #region IAggregator Members
-
-    public void AddWatch(IDataRow dataRow) {
-      dataRowWatches.Add(dataRow);
-      dataRow.ValueChanged += dataRow_ValueChanged;
-      dataRow.ValuesChanged += dataRow_ValuesChanged;
-      dataRow.DataRowChanged += dataRow_DataRowChanged;
-    }
-
-    public void RemoveWatch(IDataRow dataRow) {
-
-      dataRowWatches.Remove(dataRow);
-      dataRow.DataRowChanged -= dataRow_DataRowChanged;
-      dataRow.ValuesChanged -= dataRow_ValuesChanged;
-      dataRow.ValueChanged -= dataRow_ValueChanged;
-    }
-
-
-    #endregion
-
-    List<IDataRow> dataRowWatches = new List<IDataRow>();
-    
-    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
-      refreshValue(value);
-    }
-
-    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      for (int i = 0; i < values.Length; i++) {
-        refreshValue(values[i]);
-      }
-    }
-
-    void dataRow_DataRowChanged(IDataRow row) {
-      refreshValue(double.MinValue);
-    }
-
-    private void refreshValue(double newVal) {
-      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
-
-      //curAvgValue = double.MinValue;
-      double tmpSum = 0;
-      int count = dataRowWatches.Count;
-
-      IDataRow firstRow = dataRowWatches[0];
-      int count1 = firstRow.Count;
-      System.Console.WriteLine("count: " + count1);
-
-      dataRow.Clear();
-
-      if (dataRowWatches.Count >= 2) {
-        for (int i = 0; i < count1; i++) {
-          tmpSum = 0;
-          for (int j = 0; j < count; j++) {
-            if (dataRowWatches[j].Count > i) {
-              tmpSum += dataRowWatches[j][i];
-            }
-          }
-
-          this.dataRow.Add(tmpSum/count);
-          OnValueChanged(tmpSum / count, dataRow.Count - 1, Action.Added);
-        }
-      }
-
-      // evtl nur feuern wenn sich geändert hat (jedes mal?)
-      //OnDataRowChanged(this);
-    }
-
-    #region IDataRow Members
-
-    public override void AddValue(double value) {
-      dataRow.Add(value);
-      OnValueChanged(value, dataRow.Count - 1, Action.Added);
-    }
-
-    public override void AddValue(double value, int index) {
-      throw new NotImplementedException();
-    }
-
-    public override void AddValues(double[] values) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValue(int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValues(int index, int count) {
-      throw new NotSupportedException();
-    }
-
-    public override int Count {
-      get { return dataRow.Count; } //return dataRowWatches.Count; }
-    }
-
-    public override double this[int index] {
-      get { return dataRow[index]; }
-      set {
-        dataRow[index] = value;
-        OnValueChanged(value, index, Action.Modified);
-      }
-    }
-
-    // TODO calculate min value
-    public override double MinValue {
-      get { return 0; }
-    }
-
-    // TODO calculate max value
-    public override double MaxValue {
-      get { return 0; }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/AxisPosition.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/AxisPosition.cs	(revision 1528)
+++ 	(revision )
@@ -1,6 +1,0 @@
-namespace HeuristicLab.Visualization.Test {
-  public enum AxisPosition {
-    Left,
-    Right
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/AxisTicks.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/AxisTicks.cs	(revision 1528)
+++ 	(revision )
@@ -1,24 +1,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace HeuristicLab.Visualization {
-  public static class AxisTicks {
-    public static IEnumerable<double> GetTicks(int pixelsPerInterval, int screenSize, double worldSize, double worldStart) {
-      int intervals = screenSize/pixelsPerInterval;
-
-      if (intervals > 0) {
-        double step = worldSize/intervals;
-        step = Math.Pow(10, Math.Floor(Math.Log10(step)));
-        if (worldSize/(step*5) > intervals)
-          step = step*5;
-        else if (worldSize/(step*2) > intervals)
-          step = step*2;
-
-        for (double x = Math.Floor(worldStart/step)*step;
-             x <= worldStart + worldSize;
-             x += step)
-          yield return x;
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/Canvas.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/Canvas.cs	(revision 1528)
+++ 	(revision )
@@ -1,66 +1,0 @@
-using System;
-using System.Diagnostics;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-
-namespace HeuristicLab.Visualization {
-  public class Canvas : IShape {
-    private readonly WorldShape worldShape;
-
-    private Rectangle viewport;
-
-    public Canvas() {
-      worldShape = new WorldShape();
-      worldShape.Parent = this;
-    }
-
-    public void AddShape(IShape shape) {
-      worldShape.AddShape(shape);
-    }
-
-    public void RemoveShape(IShape shape) {
-      worldShape.RemoveShape(shape);
-    }
-
-    public void ClearShapes() {
-      worldShape.ClearShapes();
-    }
-
-    public Rectangle Viewport {
-      get { return viewport; }
-      set {
-        viewport = value;
-        worldShape.ClippingArea = new RectangleD(0, 0, viewport.Width, viewport.Height);
-        worldShape.BoundingBox = worldShape.ClippingArea;
-      }
-    }
-
-    public RectangleD ClippingArea {
-      get { return worldShape.ClippingArea; }
-    }
-
-    public RectangleD BoundingBox {
-      get { throw new InvalidOperationException(); }
-    }
-
-    public IShape Parent {
-      get { throw new InvalidOperationException(); }
-      set { throw new InvalidOperationException(); }
-    }
-
-    public void Draw(Graphics graphics) {
-      Stopwatch sw = new Stopwatch();
-      sw.Start();
-
-      graphics.SmoothingMode = SmoothingMode.AntiAlias;
-      graphics.FillRectangle(Brushes.White, Viewport);
-
-      worldShape.Draw(graphics);
-
-      graphics.DrawRectangle(Pens.Black, 0, 0, Viewport.Width - 1, Viewport.Height - 1);
-
-      sw.Stop();
-      Trace.WriteLine(string.Format("Drawing time: {0:0.0}ms", sw.Elapsed.TotalMilliseconds));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/CanvasUI.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/CanvasUI.Designer.cs	(revision 1528)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿namespace HeuristicLab.Visualization
-{
-    partial class CanvasUI
-    {
-        /// <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.SuspendLayout();
-          // 
-          // CanvasUI
-          // 
-          this.ResumeLayout(false);
-
-        }
-
-        #endregion
-    }
-}
Index: trunk/sources/HeuristicLab.Visualization/CanvasUI.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/CanvasUI.cs	(revision 1528)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿using System;
-using System.Diagnostics;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace HeuristicLab.Visualization {
-  public partial class CanvasUI : Control {
-    private readonly Canvas canvas = new Canvas();
-
-    public CanvasUI() {
-      InitializeComponent();
-
-      DoubleBuffered = true;
-    }
-
-    public Canvas Canvas {
-      get { return canvas; }
-    }
-
-    protected override void OnPaint(PaintEventArgs pe) {
-      try {
-        Graphics g = pe.Graphics;
-
-        canvas.Viewport = ClientRectangle;
-        canvas.Draw(g);
-
-        base.OnPaint(pe);
-      } catch (Exception e) {
-       Trace.WriteLine(e);
-      }
-    }
-
-    protected override void OnResize(EventArgs e) {
-      Invalidate();
-
-      canvas.Viewport = ClientRectangle;
-
-      base.OnResize(e);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ChangeType.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ChangeType.cs	(revision 1528)
+++ 	(revision )
@@ -1,7 +1,0 @@
-namespace HeuristicLab.Visualization {
-  public enum ChangeType {
-    Add,
-    Modify,
-    Remove
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ChartDataModelBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ChartDataModelBase.cs	(revision 1528)
+++ 	(revision )
@@ -1,10 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.Visualization {
-  public abstract class ChartDataModelBase : ItemBase, IChartDataModel{
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs	(revision 1528)
+++ 	(revision )
@@ -1,257 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Xml;
-using HeuristicLab.Core;
-using System.Text;
-using HeuristicLab.Visualization.LabelProvider;
-using HeuristicLab.Visualization.Options;
-
-namespace HeuristicLab.Visualization{
-  public delegate void DataRowAddedHandler(IDataRow row);
-  public delegate void DataRowRemovedHandler(IDataRow row);
-  public delegate void ModelChangedHandler();
-
-  public class ChartDataRowsModel : ChartDataModelBase, IChartDataRowsModel{
-    private string title = "Title";
-    private string xAxisLabel = "";
-    private bool showXAxisLabel = true;
-    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.##");
-
-    private ViewSettings viewSettings = new ViewSettings();
-
-    public ILabelProvider XAxisLabelProvider {
-      get { return labelProvider; }
-      set{
-        this.labelProvider = value;
-        OnModelChanged();
-      }
-    }
-
-    public List<YAxisDescriptor> YAxes {
-      get {
-        Dictionary<YAxisDescriptor, object> yaxes = new Dictionary<YAxisDescriptor, object>();
-
-        foreach (IDataRow row in rows) {
-          yaxes[row.YAxis] = null;
-        }
-
-        return new List<YAxisDescriptor>(yaxes.Keys);
-      }
-    }
-
-
-    private readonly List<IDataRow> rows = new List<IDataRow>();
-    //private readonly List<string> xLabels = new List<string>();
-
-    //public List<string> XLabels{
-    //  get { return xLabels; }
-    //}
-
-    public List<IDataRow> Rows{
-      get { return rows; }
-    }
-
-    public string Title {
-      get { return title; }
-      set {
-        title = value;
-        OnModelChanged();
-      }
-    }
-
-    public string XAxisLabel {
-      get { return xAxisLabel; }
-      set {
-        xAxisLabel = value;
-        OnModelChanged();
-      }
-    }
-
-    public bool ShowXAxisLabel {
-      get { return showXAxisLabel; }
-      set {
-        showXAxisLabel = value;
-        OnModelChanged();
-      }
-    }
-
-    public override IView CreateView() {
-      return new LineChart(this);
-    }
-
-    //public void AddLabel(string label) {
-    //  xLabels.Add(label);
-    //  OnModelChanged();
-    //}
-
-    //public void AddLabel(string label, int index) {
-    //  xLabels[index] = label;
-    //  OnModelChanged();
-    //}
-
-    //public void AddLabels(string[] labels) {
-    //  foreach (var s in labels){
-    //    AddLabel(s);
-    //  }
-    //  //OnModelChanged();
-    //}
-
-    //public void AddLabels(string[] labels, int index) {
-    //  int i = 0;
-    //  foreach (var s in labels){
-    //    AddLabel(s, index + i);
-    //    i++;
-    //  }
-    //  //OnModelChanged();
-    //}
-
-    //public void ModifyLabel(string label, int index) {
-    //  xLabels[index] = label;
-    //  OnModelChanged();
-    //}
-
-    //public void ModifyLabels(string[] labels, int index) {
-    //  int i = 0;
-    //  foreach (var s in labels){
-    //    ModifyLabel(s, index + i);
-    //    i++;
-    //  }
-    //  //OnModelChanged();
-    //}
-
-    //public void RemoveLabel(int index) {
-    //  xLabels.RemoveAt(index);
-    //  OnModelChanged();
-    //}
-
-    //public void RemoveLabels(int index, int count) {
-    //  for (int i = index; i < index + count; i++ ){
-    //    RemoveLabel(i);
-    //  }
-    //  //OnModelChanged();
-    //}
-
-    private readonly YAxisDescriptor defaultYAxisDescriptor = new YAxisDescriptor();
-
-    public void AddDataRow(IDataRow row) {
-      if (row.YAxis == null) {
-        row.YAxis = defaultYAxisDescriptor;
-      }
-      rows.Add(row);
-      OnDataRowAdded(row);
-    }
-
-    public void RemoveDataRow(IDataRow row) {
-      rows.Remove(row);
-      OnDataRowRemoved(row);
-    }
-
-    public YAxisDescriptor DefaultYAxis {
-      get { return defaultYAxisDescriptor; }
-    }
-
-    // TODO implement calculation of max data row values
-    public int MaxDataRowValues {
-      get {
-        int max = 0;
-
-        foreach (IDataRow row in rows) {
-          max = Math.Max(max, row.Count);
-        }
-
-        return max;
-      }
-    }
-
-    public ViewSettings ViewSettings {
-      get { return viewSettings; }
-      set { viewSettings = value; }
-    }
-
-    public event ModelChangedHandler ModelChanged;
-
-    protected void OnModelChanged() {
-      if (ModelChanged != null) {
-        ModelChanged();
-      }
-    }
-
-    public event DataRowAddedHandler DataRowAdded;
-
-    protected void OnDataRowAdded(IDataRow row) {
-      if (DataRowAdded != null) {
-        DataRowAdded(row);
-      }
-    }
-
-    public event DataRowRemovedHandler DataRowRemoved;
-
-    protected void OnDataRowRemoved(IDataRow row) {
-      if (DataRowRemoved != null) {
-        DataRowRemoved(row);
-      }
-    }
-
-    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
-      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
-
-      foreach (IDataRow row in rows) {
-        XmlNode columnElement = document.CreateNode(XmlNodeType.Element, "row", null);
-
-        XmlAttribute idAttr = document.CreateAttribute("label");
-        idAttr.Value = row.Label;
-        columnElement.Attributes.Append(idAttr);
-
-        StringBuilder builder = new StringBuilder();
-
-        for (int i = 0; i < row.Count; i++) {
-          if (i == 0) {
-            builder.Append(row[i].ToString(CultureInfo.InvariantCulture.NumberFormat));
-            //columnElement.InnerText += row[i].ToString(CultureInfo.InvariantCulture.NumberFormat);
-          } else {
-            builder.Append(";" + row[i].ToString(CultureInfo.InvariantCulture.NumberFormat));
-            //columnElement.InnerText += ";" + row[i].ToString(CultureInfo.InvariantCulture.NumberFormat);
-          }
-        }
-        columnElement.InnerText += builder.ToString();
-        node.AppendChild(columnElement);
-      }
-
-      XmlNode labelProviderNode = document.ImportNode(labelProvider.GetLabelProviderXmlNode(), true);
-      node.AppendChild(labelProviderNode);
-
-      return node;    
-    }
-
-    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-
-      foreach (XmlNode dataRow in node.ChildNodes) {
-        if (dataRow.Name.Equals("LabelProvider")) {
-          labelProvider = labelProvider.PopulateLabelProviderXmlNode(dataRow);
-        } else {
-          XmlAttributeCollection attrs = dataRow.Attributes;
-          XmlAttribute rowIdAttr = (XmlAttribute)attrs.GetNamedItem("label");
-          string rowLabel = rowIdAttr.Value;
-          DataRow row = new DataRow();
-          row.Label = rowLabel;
-
-          string[] tokens = dataRow.InnerText.Split(';');
-          double[] data = new double[tokens.Length];
-          for (int i = 0; i < data.Length; i++) {
-            if (tokens[i].Length != 0) {
-              if (
-                double.TryParse(tokens[i], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out data[i]) ==
-                false) {
-                throw new FormatException("Can't parse " + tokens[i] + " as double value.");
-              }
-            }
-          }
-          row.AddValues(data);
-          AddDataRow(row);
-        }
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ChartDataRowsModelDataCollector.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ChartDataRowsModelDataCollector.cs	(revision 1528)
+++ 	(revision )
@@ -1,83 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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.Collections.Generic;
-using System.Text;
-using System.Drawing;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-
-namespace HeuristicLab.Visualization {
-  /// <summary>
-  /// Collects values of specific variable names in a given scope and feeds them into a ChartDataRowsModel.
-  /// </summary>
-  public class ChartDataRowsModelDataCollector : OperatorBase {
-    /// <inheritdoc select="summary"/>
-    public override string Description {
-      get { return @"Collects values of specific variable names in a given scope and feeds them into a ChartDataRowsModel."; }
-    }
-
-    /// <summary>
-    /// Initializes a new instance of <see cref="ChartDataRowsModelDataCollector"/> with two variable infos 
-    /// (<c>VariableNames</c> and <c>Values</c>).
-    /// </summary>
-    public ChartDataRowsModelDataCollector() {
-      IVariableInfo variableNamesVariableInfo = new VariableInfo("VariableNames", "Names of variables whose values should be collected", typeof(ItemList<StringData>), VariableKind.In);
-      variableNamesVariableInfo.Local = true;
-      AddVariableInfo(variableNamesVariableInfo);
-      ItemList<StringData> variableNames = new ItemList<StringData>();
-      AddVariable(new Variable("VariableNames", variableNames));
-      AddVariableInfo(new VariableInfo("Model", "Data model in which the collected values should be fed.", typeof(IChartDataRowsModel), VariableKind.New | VariableKind.In | VariableKind.Out));
-    }
-
-    /// <summary>
-    /// Collects the values of a specified list of variable names in the given <paramref name="scope"/>.
-    /// </summary>
-    /// <param name="scope">The scope where to collect the values from.</param>
-    /// <returns><c>null</c>.</returns>
-    public override IOperation Apply(IScope scope) {
-      ItemList<StringData> names = GetVariableValue<ItemList<StringData>>("VariableNames", scope, false);
-      IChartDataRowsModel model = GetVariableValue<IChartDataRowsModel>("Model", scope, true, false);
-
-      // if necessary, add a new model
-      if (model == null) {
-        model = new ChartDataRowsModel();
-        for (int i = 0; i < names.Count; i++)
-          model.AddDataRow(new DataRow(names[i].Data));  // create new data row for each variable name to collect
-
-        IVariableInfo info = GetVariableInfo("Model");
-        if (info.Local)
-          AddVariable(new Variable(info.ActualName, model));
-        else
-          scope.AddVariable(new Variable(scope.TranslateName(info.FormalName), model));
-      }
-
-      // collect data values and feed them into the model
-      for (int i = 0; i < names.Count; i++) {
-        DoubleData data = scope.GetVariableValue(names[i].Data, true) as DoubleData;
-        if (data != null)
-          model.Rows[i].AddValue(data.Data);
-      }
-      return null;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ChartDataRowsModelDummy.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ChartDataRowsModelDummy.cs	(revision 1528)
+++ 	(revision )
@@ -1,42 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-
-namespace HeuristicLab.Visualization{
-  public class ChartDataRowsModelDummy : ChartDataRowsModel  {
-    
-    public ChartDataRowsModelDummy(){
-      Random rand = new Random();
-
-      // test rows
-
-      // TODO change to call new DataRow("Datarow 1");
-      DataRow row1 = new DataRow();
-      row1.Label = "Datarow 1";
-      row1.Color = Color.Red;
-      DataRow row2 = new DataRow();
-      row2.Label = "Datarow 2";
-      row2.Color = Color.Blue;
-      DataRow row3 = new DataRow();
-      row3.Label = "Datarow 3";
-      row3.Color = Color.DeepPink;
-
-      AddDataRow(row1);
-      AddDataRow(row2);
-      AddDataRow(row3);
-      
-      for (int i = 0; i < 10; i++){
-
-        // TODO Test AddDataRow mit bereits befüllter Row
-
-        row1.AddValue(rand.NextDouble() * 100);
-        row2.AddValues(new double[] { rand.NextDouble() * 100,  
-          rand.NextDouble() * 100 });
-        row3.AddValue(11.0);
-        // TODO after implemention of modifyValue: row1.ModifyValue(row1.getval[i]+100, i);
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/CompositeShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/CompositeShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,60 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public class CompositeShape : IShape {
-    private IShape parent;
-
-    protected readonly List<IShape> shapes = new List<IShape>();
-    protected RectangleD boundingBox = RectangleD.Empty;
-
-    public virtual void Draw(Graphics graphics) {
-      foreach (IShape shape in shapes) {
-        shape.Draw(graphics);
-      }
-    }
-
-    public RectangleD BoundingBox {
-      get {
-        if (shapes.Count == 0) {
-          throw new InvalidOperationException("No shapes, no bounding box.");
-        }
-
-        return boundingBox;
-      }
-    }
-
-    public RectangleD ClippingArea {
-      get { return Parent.ClippingArea; }
-    }
-
-    public Rectangle Viewport {
-      get { return Parent.Viewport; }
-    }
-
-    public IShape Parent {
-      get { return parent; }
-      set { parent = value; }
-    }
-
-    public void ClearShapes() {
-      shapes.Clear();
-      boundingBox = RectangleD.Empty;
-    }
-
-    public void AddShape(IShape shape) {
-      shape.Parent = this;
-
-      if (shapes.Count == 0) {
-        boundingBox = shape.BoundingBox;
-      } else {
-        boundingBox = new RectangleD(Math.Min(boundingBox.X1, shape.BoundingBox.X1),
-                                     Math.Min(boundingBox.Y1, shape.BoundingBox.Y1),
-                                     Math.Max(boundingBox.X2, shape.BoundingBox.X2),
-                                     Math.Max(boundingBox.Y2, shape.BoundingBox.Y2));
-      }
-      shapes.Add(shape);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/DataRow.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/DataRow.cs	(revision 1528)
+++ 	(revision )
@@ -1,164 +1,0 @@
-using System;
-using System.Drawing;
-using System.Collections.Generic;
-using HeuristicLab.Visualization.LabelProvider;
-
-namespace HeuristicLab.Visualization {
-  public enum Action {
-    Added,
-    Modified,
-    Deleted
-  }
-
-  public delegate void DataRowChangedHandler(IDataRow row);
-  public delegate void ValuesChangedHandler(IDataRow row, double[] values, int index, Action action);
-  public delegate void ValueChangedHandler(IDataRow row, double value, int index, Action action);
-
-  public class DataRow : DataRowBase {
-    private readonly List<double> dataRow = new List<double>();
-
-    // TODO implement calculation of min and max values
-    private double minValue = double.MaxValue;
-    private double maxValue = double.MinValue;
-
-    public DataRow() {
-    }
-    
-    public DataRow(string label) {
-      this.Label = label;
-    }
-
-    public DataRow(string label, Color color, int thickness, DrawingStyle style, List<double> dataRow) {
-     this.Label = label;
-      this.Color = color;
-      this.Thickness = thickness;
-      this.Style = style;
-      this.dataRow = dataRow;
-    }
-
-    public override void AddValue(double value) {
-      UpdateMinMaxValue(value);
-
-      dataRow.Add(value);
-      OnValueChanged(value, dataRow.Count - 1, Action.Added);
-    }
-
-    public override void AddValue(double value, int index) {
-      //check if index is valid
-      if (index >= 0 && index < dataRow.Count) {
-        dataRow.Insert(index, value);
-        OnValueChanged(value, index, Action.Added);
-      } else {
-        throw new IndexOutOfRangeException();
-      }   
-    }
-
-    public override void AddValues(double[] values) {
-      int startInd = dataRow.Count;
-
-      foreach (double d in values) {
-        dataRow.Add(d);
-      }
-      OnValuesChanged(values, startInd, Action.Added); 
-    }
-
-    public override void AddValues(double[] values, int index) {
-      int j = index;
-
-      //check if index to start changes is valid
-      if (index >=0 && (index + values.Length) < dataRow.Count) {
-        foreach (double d in values) {
-          dataRow.Insert(j, d);
-          j++;
-        }
-        OnValuesChanged(values, index, Action.Added);
-      } else {
-        throw new IndexOutOfRangeException();
-      }
-    }
-
-    public override void ModifyValue(double value, int index) {
-      //check if index is valid
-      if (index >= 0 && index < dataRow.Count) {
-        dataRow[index] = value;
-        OnValueChanged(value, index, Action.Modified);
-      } else {
-        throw new IndexOutOfRangeException();
-      }
-    }
-
-    public override void ModifyValues(double[] values, int index) {
-      int startInd = index;
-      int modInd = index;
-
-      //check if index to start modification is valid
-      if (startInd >=0 && startInd + values.Length < dataRow.Count) {
-        foreach (double d in values) {
-          dataRow[modInd] = d;
-          modInd++;
-        }
-        OnValuesChanged(values, startInd, Action.Modified);
-      } else {
-        throw new IndexOutOfRangeException();
-      }
-    }
-
-    public override void RemoveValue(int index) {
-      double remVal = dataRow[index];
-      //check if index is valid
-      if (index >= 0 && index < dataRow.Count) {
-        dataRow.RemoveAt(index);
-        OnValueChanged(remVal, index, Action.Deleted);
-      } else {
-        throw new IndexOutOfRangeException();
-      }
-    }
-
-    public override void RemoveValues(int index, int count) {
-      double[] remValues = new double[count]; //removed values
-      int j = 0;
-
-      //check if count is valid
-      if (count > 0) {
-        //check if index is valid
-        if ((index >= 0) && (index + count <= dataRow.Count)) {
-          for (int i = index; i < (index + count); i++) {
-            remValues.SetValue(i, j);
-            dataRow.RemoveAt(i);
-            j++;
-          }
-          OnValuesChanged(remValues, index, Action.Deleted);
-        } else {
-          throw new IndexOutOfRangeException();
-        }
-      } else {
-        throw new Exception("parameter count must be > 0!");
-      }
-    }
-
-    public override int Count {
-      get { return dataRow.Count; }
-    }
-
-    public override double this[int index] {
-      get { return dataRow[index]; }
-      set {
-        dataRow[index] = value;
-        OnValueChanged(value, index, Action.Modified);
-      }
-    }
-
-    public override double MinValue {
-      get { return minValue; }
-    }
-
-    public override double MaxValue {
-      get { return maxValue; }
-    }
-
-    private void UpdateMinMaxValue(double value) {
-      maxValue = Math.Max(value, maxValue);
-      minValue = Math.Min(value, minValue);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/DataRowBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/DataRowBase.cs	(revision 1528)
+++ 	(revision )
@@ -1,110 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public abstract class DataRowBase : IDataRow {
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
-    private YAxisDescriptor yAxis;
-
-    public string Label {
-      get { return label; }
-      set {
-        label = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public Color Color {
-      get { return color; }
-      set {
-        color = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public int Thickness {
-      get { return thickness; }
-      set {
-        thickness = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public DrawingStyle Style {
-      get { return style; }
-      set {
-        style = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public DataRowType LineType {
-      get { return lineType; }
-      set {
-        lineType = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public YAxisDescriptor YAxis {
-      get { return yAxis; }
-      set {
-        yAxis = value;
-        yAxis.AddDataRow(this);
-        yAxis.YAxisDescriptorChanged += delegate { OnDataRowChanged(this); };
-        OnDataRowChanged(this);
-      }
-    }
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
-    }
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-
-    public abstract void AddValue(double value);
-
-    public abstract void AddValue(double value, int index);
-
-    public abstract void AddValues(double[] values);
-
-    public abstract void AddValues(double[] values, int index);
-
-    public abstract void ModifyValue(double value, int index);
-
-    public abstract void ModifyValues(double[] values, int index);
-
-    public abstract void RemoveValue(int index);
-
-    public abstract void RemoveValues(int index, int count);
-
-    public abstract int Count { get; }
-
-    public abstract double this[int index] { get; set; }
-
-    public abstract double MinValue { get; }
-
-    public abstract double MaxValue { get; }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    public event ValueChangedHandler ValueChanged;
-
-    public event DataRowChangedHandler DataRowChanged;
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/DrawingStyle.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/DrawingStyle.cs	(revision 1528)
+++ 	(revision )
@@ -1,5 +1,0 @@
-namespace HeuristicLab.Visualization {
-  public enum DrawingStyle {
-    Solid, Dashed
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/Grid.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/Grid.cs	(revision 1528)
+++ 	(revision )
@@ -1,53 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public class Grid : WorldShape {
-    private Color color = Color.LightBlue;
-
-    public override void Draw(Graphics graphics) {
-      ClearShapes();
-
-      foreach (double y in AxisTicks.GetTicks(YAxis.PixelsPerInterval,
-                                              Parent.Viewport.Height,
-                                              ClippingArea.Height,
-                                              ClippingArea.Y1)) {
-        LineShape line = new LineShape(ClippingArea.X1, y,
-                                       ClippingArea.X2, y,
-                                       color, 1,
-                                       DrawingStyle.Dashed);
-        AddShape(line);
-      }
-
-      foreach (double x in AxisTicks.GetTicks(XAxis.PixelsPerInterval,
-                                              Parent.Viewport.Width,
-                                              ClippingArea.Width,
-                                              ClippingArea.X1)) {
-        LineShape line = new LineShape(x, ClippingArea.Y1,
-                                       x, ClippingArea.Y2,
-                                       color, 1,
-                                       DrawingStyle.Dashed);
-        AddShape(line);
-      }
-
-      LineShape lineZeroX = new LineShape(0, ClippingArea.Y1,
-                                          0, ClippingArea.Y2,
-                                          color, 3,
-                                          DrawingStyle.Dashed);
-
-      LineShape lineZeroY = new LineShape(ClippingArea.X1, 0,
-                                          ClippingArea.X2, 0,
-                                          color, 3,
-                                          DrawingStyle.Dashed);
-
-      AddShape(lineZeroX);
-      AddShape(lineZeroY);
-
-      base.Draw(graphics);
-    }
-
-    public Color Color {
-      get { return color; }
-      set { color = value; }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/HeuristicLab.Visualization.csproj
===================================================================
--- trunk/sources/HeuristicLab.Visualization/HeuristicLab.Visualization.csproj	(revision 1528)
+++ 	(revision )
@@ -1,196 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{E392A1E2-DC95-4E33-B82E-8ED690EDA1AB}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>HeuristicLab.Visualization</RootNamespace>
-    <AssemblyName>HeuristicLab.Visualization-3.2</AssemblyName>
-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <SignAssembly>true</SignAssembly>
-    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>bin\x86\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <OutputPath>bin\x86\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>bin\x64\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <OutputPath>bin\x64\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <DocumentationFile>bin\Release\HeuristicLab.Visualization-3.2.XML</DocumentationFile>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Windows.Forms" />
-    <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="AvgAggregator.cs" />
-    <Compile Include="AvgLineAggregator.cs" />
-    <Compile Include="AxisPosition.cs" />
-    <Compile Include="AxisTicks.cs" />
-    <Compile Include="Canvas.cs" />
-    <Compile Include="CanvasUI.cs">
-      <SubType>Component</SubType>
-    </Compile>
-    <Compile Include="CanvasUI.Designer.cs">
-      <DependentUpon>CanvasUI.cs</DependentUpon>
-    </Compile>
-    <Compile Include="ChangeType.cs" />
-    <Compile Include="ChartDataModelBase.cs" />
-    <Compile Include="ChartDataRowsModel.cs" />
-    <Compile Include="ChartDataRowsModelDummy.cs" />
-    <Compile Include="CompositeShape.cs" />
-    <Compile Include="ChartDataRowsModelDataCollector.cs" />
-    <Compile Include="DataRowBase.cs" />
-    <Compile Include="LabelProvider\ContinuousLabelProvider.cs" />
-    <Compile Include="LabelProvider\DiscreteLabelProvider.cs" />
-    <Compile Include="Grid.cs" />
-    <Compile Include="HorizontalLineShape.cs" />
-    <Compile Include="LabelProvider\ILabelProvider.cs" />
-    <Compile Include="IMouseEventListener.cs" />
-    <Compile Include="Legend\LegendItem.cs" />
-    <Compile Include="MaxAggregator.cs" />
-    <Compile Include="MinAggregator.cs" />
-    <Compile Include="Options\OptionsDialog.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="Options\OptionsDialog.Designer.cs">
-      <DependentUpon>OptionsDialog.cs</DependentUpon>
-    </Compile>
-    <Compile Include="Options\ViewSettings.cs" />
-    <Compile Include="PanListener.cs" />
-    <Compile Include="LabelProvider\StringLabelProvider.cs" />
-    <Compile Include="TextShape.cs" />
-    <Compile Include="Legend\LegendShape.cs" />
-    <Compile Include="DataRow.cs" />
-    <Compile Include="DrawingStyle.cs" />
-    <Compile Include="HeuristicLabVisualizationPlugin.cs" />
-    <Compile Include="IChartDataModel.cs" />
-    <Compile Include="IChartDataRowsModel.cs" />
-    <Compile Include="IDataRow.cs" />
-    <Compile Include="IShape.cs" />
-    <Compile Include="LineChart.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="LineChart.Designer.cs">
-      <DependentUpon>LineChart.cs</DependentUpon>
-    </Compile>
-    <Compile Include="LineShape.cs" />
-    <Compile Include="Offset.cs" />
-    <Compile Include="PointD.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="RectangleD.cs" />
-    <Compile Include="RectangleShape.cs" />
-    <Compile Include="SizeD.cs" />
-    <Compile Include="Transform.cs" />
-    <Compile Include="Translate.cs" />
-    <Compile Include="WorldShape.cs" />
-    <Compile Include="XAxis.cs" />
-    <Compile Include="YAxis.cs" />
-    <Compile Include="YAxisDescriptor.cs" />
-    <Compile Include="ZoomListener.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="HeuristicLab.snk" />
-    <None Include="Properties\AssemblyInfo.frame" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
-      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
-      <Name>HeuristicLab.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
-      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
-      <Name>HeuristicLab.Data</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
-      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
-      <Name>HeuristicLab.PluginInfrastructure</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="LineChart.resx">
-      <DependentUpon>LineChart.cs</DependentUpon>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Options\OptionsDialog.resx">
-      <DependentUpon>OptionsDialog.cs</DependentUpon>
-    </EmbeddedResource>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-  <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
-set ProjectDir=$(ProjectDir)
-set SolutionDir=$(SolutionDir)
-set Outdir=$(Outdir)
-
-call PreBuildEvent.cmd</PreBuildEvent>
-  </PropertyGroup>
-</Project>
Index: trunk/sources/HeuristicLab.Visualization/HeuristicLabVisualizationPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/HeuristicLabVisualizationPlugin.cs	(revision 1528)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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 HeuristicLab.PluginInfrastructure;
-
-namespace HeuristicLab.Visualization {
-  [ClassInfo(Name = "HeuristicLab.Visualization-3.2")]
-  [PluginFile(Filename = "HeuristicLab.Visualization-3.2.dll", Filetype = PluginFileType.Assembly)]
-  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
-  public class HeuristicLabVisualizationPlugin : PluginBase {
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/HorizontalLineShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/HorizontalLineShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,25 +1,0 @@
-﻿using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public class HorizontalLineShape : LineShape {
-    /// <summary>
-    /// Initializes the LineShape.
-    /// </summary>
-    /// <param name="x1">x coordinate of left lineEndPoind</param>
-    /// <param name="y1">y coordinate of left lineEndPoind</param>
-    /// <param name="x2">x coordinate of right lineEndPoind</param>
-    /// <param name="y2">y coordinate of right lineEndPoind</param>
-    /// <param name="color">color for the LineShape</param>
-    /// <param name="thickness">tickness of the line in pixels</param>
-    /// <param name="drawingStyle">drawing style of the line (solid, dashed, dotted,...)</param>
-    public HorizontalLineShape(double x1, double y1, double x2, double y2, Color color, int thickness,
-                               DrawingStyle drawingStyle) : base(x1, y1, x2, y2, color, thickness, drawingStyle) {}
-
-    public override void Draw(Graphics graphics) {
-      X1 = Parent.ClippingArea.X1;
-      X2 = Parent.ClippingArea.X2;
-      Y2 = Y1;
-      base.Draw(graphics);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/IChartDataModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/IChartDataModel.cs	(revision 1528)
+++ 	(revision )
@@ -1,10 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.Visualization {
-  interface IChartDataModel : IItem {
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/IChartDataRowsModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/IChartDataRowsModel.cs	(revision 1528)
+++ 	(revision )
@@ -1,28 +1,0 @@
-﻿using System.Collections.Generic;
-using HeuristicLab.Core;
-using HeuristicLab.Visualization.LabelProvider;
-using HeuristicLab.Visualization.Options;
-
-namespace HeuristicLab.Visualization {
-  public interface IChartDataRowsModel : IItem {
-    string Title { get; set; }
-    List<IDataRow> Rows { get; }
-    ILabelProvider XAxisLabelProvider { get; set; }
-
-    List<YAxisDescriptor> YAxes { get; }
-
-    void AddDataRow(IDataRow row);
-    void RemoveDataRow(IDataRow row);
-
-    int MaxDataRowValues { get; }
-
-    ViewSettings ViewSettings { get; set; }
-
-    string XAxisLabel { get; set; }
-    bool ShowXAxisLabel { get; set; }
-
-    event ModelChangedHandler ModelChanged;
-    event DataRowAddedHandler DataRowAdded;
-    event DataRowRemovedHandler DataRowRemoved;
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/IDataRow.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/IDataRow.cs	(revision 1528)
+++ 	(revision )
@@ -1,38 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public enum DataRowType {
-    Normal, SingleValue
-  }
-
-  public interface IDataRow {
-    string Label { get; set; }
-    Color Color { get; set; }
-    int Thickness { get; set; }
-    DrawingStyle Style { get; set; }
-    DataRowType LineType { get; set; }
- 
-    YAxisDescriptor YAxis { get; set; }
-
-    void AddValue(double value);
-    void AddValue(double value, int index);
-    void AddValues(double[] values);
-    void AddValues(double[] values, int index);
-
-    void ModifyValue(double value, int index);
-    void ModifyValues(double[] values, int index);
-
-    void RemoveValue(int index);
-    void RemoveValues(int index, int count);
-
-    int Count { get; }
-    double this[int index] { get; set; }
-
-    double MinValue { get; }
-    double MaxValue { get; }
-
-    event ValuesChangedHandler ValuesChanged;
-    event ValueChangedHandler ValueChanged;
-    event DataRowChangedHandler DataRowChanged;
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/IMouseEventListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/IMouseEventListener.cs	(revision 1528)
+++ 	(revision )
@@ -1,12 +1,0 @@
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace HeuristicLab.Visualization {
-  public interface IMouseEventListener {
-    void MouseMove(object sender, MouseEventArgs e);
-    void MouseUp(object sender, MouseEventArgs e);
-  }
-
-  public delegate void MoveHandler(Point startPoint, Point endPoint);
-  public delegate void RectangleHandler(Rectangle rectangle);
-}
Index: trunk/sources/HeuristicLab.Visualization/IShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/IShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,39 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  /// <summary>
-  /// This is the base interface that has to be implemented by all shapes.
-  /// 
-  /// View port
-  ///   The view port is the available drawing area on the screen.
-  ///   It is specified in the GDI coordinate system.
-  /// 
-  /// Clipping area
-  ///   The clipping area is the range of values visible on the view port.
-  ///   Values outside this area will not be visible (they "get clipped").
-  ///   It can either be inherited from the parent, or it can be overriden
-  ///   to create distorted realities (see world shapes).
-  ///   It is specified in a world coordinate system.
-  /// 
-  /// Bounding box
-  ///   The bounding box is the location and the size of a shape on its parent.
-  ///   It is specified in the parent's world coordinate system.
-  /// </summary>
-  public interface IShape {
-    /// <summary>
-    /// Draws the shape
-    /// </summary>
-    /// <param name="graphics">The Graphics object used to draw the shape</param>
-    void Draw(Graphics graphics);
-
-    /// <summary>
-    /// The shape's bounding box
-    /// </summary>
-    RectangleD BoundingBox { get; }
-
-    RectangleD ClippingArea { get; }
-    Rectangle Viewport { get; }
-
-    IShape Parent { get; set; }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/LineChart.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/LineChart.Designer.cs	(revision 1528)
+++ 	(revision )
@@ -1,87 +1,0 @@
-﻿using System.Windows.Forms;
-
-namespace HeuristicLab.Visualization
-{
-    partial class LineChart
-    {
-        /// <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();
-          this.canvasUI = new HeuristicLab.Visualization.CanvasUI();
-          this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
-          this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-          this.contextMenuStrip1.SuspendLayout();
-          this.SuspendLayout();
-          // 
-          // canvasUI
-          // 
-          this.canvasUI.Dock = System.Windows.Forms.DockStyle.Fill;
-          this.canvasUI.Location = new System.Drawing.Point(0, 0);
-          this.canvasUI.Name = "canvasUI";
-          this.canvasUI.Size = new System.Drawing.Size(551, 373);
-          this.canvasUI.TabIndex = 0;
-          this.canvasUI.Text = "canvas";
-          this.canvasUI.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.canvasUI1_MouseWheel);
-          this.canvasUI.MouseMove += new System.Windows.Forms.MouseEventHandler(this.canvasUI_MouseMove);
-          this.canvasUI.ContextMenuStripChanged += new System.EventHandler(this.optionsToolStripMenuItem_Click);
-          this.canvasUI.MouseDown += new System.Windows.Forms.MouseEventHandler(this.canvasUI1_MouseDown);
-          this.canvasUI.MouseUp += new System.Windows.Forms.MouseEventHandler(this.canvasUI_MouseUp);
-          this.canvasUI.KeyDown += new System.Windows.Forms.KeyEventHandler(this.canvasUI1_KeyDown);
-          // 
-          // contextMenuStrip1
-          // 
-          this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.optionsToolStripMenuItem});
-          this.contextMenuStrip1.Name = "contextMenuStrip1";
-          this.contextMenuStrip1.Size = new System.Drawing.Size(123, 26);
-          // 
-          // optionsToolStripMenuItem
-          // 
-          this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
-          this.optionsToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
-          this.optionsToolStripMenuItem.Text = "Options";
-          this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
-          // 
-          // LineChart
-          // 
-          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-          this.Controls.Add(this.canvasUI);
-          this.Name = "LineChart";
-          this.Size = new System.Drawing.Size(551, 373);
-          this.contextMenuStrip1.ResumeLayout(false);
-          this.ResumeLayout(false);
-
-        }
-
-        #endregion
-
-        private CanvasUI canvasUI;
-        private ContextMenuStrip contextMenuStrip1;
-        private ToolStripMenuItem optionsToolStripMenuItem;
-    }
-}
Index: trunk/sources/HeuristicLab.Visualization/LineChart.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/LineChart.cs	(revision 1528)
+++ 	(revision )
@@ -1,636 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Windows.Forms;
-using HeuristicLab.Core;
-using HeuristicLab.Visualization.Legend;
-using HeuristicLab.Visualization.Options;
-using HeuristicLab.Visualization.Test;
-
-namespace HeuristicLab.Visualization {
-  public partial class LineChart : ViewBase {
-    private readonly IChartDataRowsModel model;
-    private readonly Canvas canvas;
-
-    private readonly TextShape titleShape = new TextShape("Title");
-    private readonly LegendShape legendShape = new LegendShape();
-    private readonly XAxis xAxis = new XAxis();
-    private readonly List<RowEntry> rowEntries = new List<RowEntry>();
-
-    private readonly Dictionary<IDataRow, RowEntry> rowToRowEntry = new Dictionary<IDataRow, RowEntry>();
-
-    private readonly ViewSettings viewSettings;
-
-    private readonly WorldShape userInteractionShape = new WorldShape();
-    private readonly RectangleShape rectangleShape = new RectangleShape(0, 0, 0, 0, Color.FromArgb(50, 0, 0, 255));
-    private IMouseEventListener mouseEventListener;
-
-    private const int YAxisWidth = 100;
-    private const int XAxisHeight = 40;
-
-    /// <summary>
-    /// This constructor shouldn't be called. Only required for the designer.
-    /// </summary>
-    public LineChart() {
-      InitializeComponent();
-    }
-
-    /// <summary>
-    /// Initializes the chart.
-    /// </summary>
-    /// <param name="model">Referenz to the model, for data</param>
-    public LineChart(IChartDataRowsModel model) : this() {
-      if (model == null) {
-        throw new NullReferenceException("Model cannot be null.");
-      }
-
-      canvas = canvasUI.Canvas;
-
-      this.model = model;
-      viewSettings = model.ViewSettings;
-      viewSettings.OnUpdateSettings += UpdateViewSettings;
-
-      Item = model;
-
-      UpdateLayout();
-      canvasUI.Resize += delegate { UpdateLayout(); };
-
-      ZoomToFullView();
-    }
-
-    /// <summary>
-    /// updates the view settings
-    /// </summary>
-    private void UpdateViewSettings() {
-      titleShape.Font = viewSettings.TitleFont;
-      titleShape.Color = viewSettings.TitleColor;
-
-      legendShape.Font = viewSettings.LegendFont;
-      legendShape.Color = viewSettings.LegendColor;
-
-      xAxis.Font = viewSettings.XAxisFont;
-      xAxis.Color = viewSettings.XAxisColor;
-
-      SetLegendPosition();
-
-      canvasUI.Invalidate();
-    }
-
-    /// <summary>
-    /// Layout management - arranges the inner shapes.
-    /// </summary>
-    private void UpdateLayout() {
-      canvas.ClearShapes();
-
-      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
-        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
-        if (yAxisDescriptor.ShowGrid) {
-          info.Grid.Color = yAxisDescriptor.GridColor;
-          canvas.AddShape(info.Grid);
-        }
-      }
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        canvas.AddShape(rowEntry.LinesShape);
-      }
-
-      xAxis.ShowLabel = model.ShowXAxisLabel;
-      xAxis.Label = model.XAxisLabel;
-
-      canvas.AddShape(xAxis);
-
-      int yAxesWidthLeft = 0;
-      int yAxesWidthRight = 0;
-
-      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
-        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
-        if (yAxisDescriptor.ShowYAxis) {
-          canvas.AddShape(info.YAxis);
-          info.YAxis.ShowLabel = yAxisDescriptor.ShowYAxisLabel;
-          info.YAxis.Label = yAxisDescriptor.Label;
-          info.YAxis.Position = yAxisDescriptor.Position;
-          switch (yAxisDescriptor.Position) {
-            case AxisPosition.Left:
-              yAxesWidthLeft += YAxisWidth;
-              break;
-            case AxisPosition.Right:
-              yAxesWidthRight += YAxisWidth;
-              break;
-            default:
-              throw new NotImplementedException();
-          }
-        }
-      }
-
-      canvas.AddShape(titleShape);
-      canvas.AddShape(legendShape);
-
-      canvas.AddShape(userInteractionShape);
-
-      titleShape.X = 10;
-      titleShape.Y = canvasUI.Height - 10;
-
-      RectangleD linesAreaBoundingBox = new RectangleD(yAxesWidthLeft,
-                                                       XAxisHeight,
-                                                       canvasUI.Width - yAxesWidthRight,
-                                                       canvasUI.Height);
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        rowEntry.LinesShape.BoundingBox = linesAreaBoundingBox;
-      }
-
-      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
-        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
-        info.Grid.BoundingBox = linesAreaBoundingBox;
-      }
-
-      int yAxisLeft = 0;
-      int yAxisRight = (int)linesAreaBoundingBox.X2;
-
-      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
-        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
-        if (yAxisDescriptor.ShowYAxis) {
-          switch (yAxisDescriptor.Position) {
-            case AxisPosition.Left:
-              info.YAxis.BoundingBox = new RectangleD(yAxisLeft,
-                                                      linesAreaBoundingBox.Y1,
-                                                      yAxisLeft + YAxisWidth,
-                                                      linesAreaBoundingBox.Y2);
-              yAxisLeft += YAxisWidth;
-              break;
-            case AxisPosition.Right:
-              info.YAxis.BoundingBox = new RectangleD(yAxisRight,
-                                                      linesAreaBoundingBox.Y1,
-                                                      yAxisRight + YAxisWidth,
-                                                      linesAreaBoundingBox.Y2);
-              yAxisRight += YAxisWidth;
-              break;
-            default:
-              throw new NotImplementedException();
-          }
-        }
-      }
-
-      userInteractionShape.BoundingBox = linesAreaBoundingBox;
-      userInteractionShape.ClippingArea = new RectangleD(0, 0, userInteractionShape.BoundingBox.Width, userInteractionShape.BoundingBox.Height);
-
-      xAxis.BoundingBox = new RectangleD(linesAreaBoundingBox.X1,
-                                         0,
-                                         linesAreaBoundingBox.X2,
-                                         linesAreaBoundingBox.Y1);
-
-      SetLegendPosition();
-    }
-
-    private readonly Dictionary<YAxisDescriptor, YAxisInfo> yAxisInfos = new Dictionary<YAxisDescriptor, YAxisInfo>();
-
-    private YAxisInfo GetYAxisInfo(YAxisDescriptor yAxisDescriptor) {
-      YAxisInfo info;
-
-      if (!yAxisInfos.TryGetValue(yAxisDescriptor, out info)) {
-        info = new YAxisInfo();
-        yAxisInfos[yAxisDescriptor] = info;
-      }
-
-      return info;
-    }
-
-    /// <summary>
-    /// sets the legend position
-    /// </summary>
-    private void SetLegendPosition() {
-      switch (viewSettings.LegendPosition) {
-        case LegendPosition.Bottom:
-          setLegendBottom();
-          break;
-
-        case LegendPosition.Top:
-          setLegendTop();
-          break;
-
-        case LegendPosition.Left:
-          setLegendLeft();
-          break;
-
-        case LegendPosition.Right:
-          setLegendRight();
-          break;
-      }
-    }
-
-    public void setLegendRight() {
-      // legend right
-      legendShape.BoundingBox = new RectangleD(canvasUI.Width - legendShape.GetMaxLabelLength(), 10, canvasUI.Width, canvasUI.Height - 50);
-      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
-      legendShape.Row = false;
-      legendShape.CreateLegend();
-    }
-
-    public void setLegendLeft() {
-      // legend left
-      legendShape.BoundingBox = new RectangleD(10, 10, canvasUI.Width, canvasUI.Height - 50);
-      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
-      legendShape.Row = false;
-      legendShape.CreateLegend();
-
-      canvasUI.Invalidate();
-    }
-
-    public void setLegendTop() {
-      // legend top
-      legendShape.BoundingBox = new RectangleD(100, canvasUI.Height - canvasUI.Height, canvasUI.Width, canvasUI.Height - 10);
-      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
-      legendShape.Row = true;
-      legendShape.Top = true;
-      legendShape.CreateLegend();
-    }
-
-    public void setLegendBottom() {
-      // legend bottom
-      legendShape.BoundingBox = new RectangleD(100, 10, canvasUI.Width, canvasUI.Height/*legendShape.GetHeight4Rows()*/);
-      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
-      legendShape.Row = true;
-      legendShape.Top = false;
-      legendShape.CreateLegend();
-    }
-
-    private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
-      OptionsDialog optionsdlg = new OptionsDialog(model);
-      optionsdlg.Show();
-    }
-
-    public void OnDataRowChanged(IDataRow row) {
-      RowEntry rowEntry = rowToRowEntry[row];
-
-      rowEntry.LinesShape.UpdateStyle(row);
-
-      UpdateLayout();
-
-      canvasUI.Invalidate();
-    }
-
-    #region Add-/RemoveItemEvents
-
-    protected override void AddItemEvents() {
-      base.AddItemEvents();
-
-      model.DataRowAdded += OnDataRowAdded;
-      model.DataRowRemoved += OnDataRowRemoved;
-      model.ModelChanged += OnModelChanged;
-
-      foreach (IDataRow row in model.Rows) {
-        OnDataRowAdded(row);
-      }
-    }
-
-    protected override void RemoveItemEvents() {
-      base.RemoveItemEvents();
-
-      model.DataRowAdded -= OnDataRowAdded;
-      model.DataRowRemoved -= OnDataRowRemoved;
-      model.ModelChanged -= OnModelChanged;
-    }
-
-    private void OnDataRowAdded(IDataRow row) {
-      row.ValueChanged += OnRowValueChanged;
-      row.ValuesChanged += OnRowValuesChanged;
-      row.DataRowChanged += OnDataRowChanged;
-
-      legendShape.AddLegendItem(new LegendItem(row.Label, row.Color, row.Thickness));
-      legendShape.CreateLegend();
-
-      InitLineShapes(row);
-
-      UpdateLayout();
-    }
-
-    private void OnDataRowRemoved(IDataRow row) {
-      row.ValueChanged -= OnRowValueChanged;
-      row.ValuesChanged -= OnRowValuesChanged;
-      row.DataRowChanged -= OnDataRowChanged;
-
-      rowToRowEntry.Remove(row);
-      rowEntries.RemoveAll(delegate(RowEntry rowEntry) { return rowEntry.DataRow == row; });
-
-      UpdateLayout();
-    }
-
-    #endregion
-
-    public void ZoomToFullView() {
-      SetClipX(-0.1, model.MaxDataRowValues - 0.9);
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        YAxisDescriptor yAxisDescriptor = rowEntry.DataRow.YAxis;
-
-        SetClipY(rowEntry,
-                 yAxisDescriptor.MinValue - ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05),
-                 yAxisDescriptor.MaxValue + ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05));
-      }
-
-      canvasUI.Invalidate();
-    }
-
-    private void SetClipX(double x1, double x2) {
-      xAxis.ClippingArea = new RectangleD(x1,
-                                          0,
-                                          x2,
-                                          XAxisHeight);
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        rowEntry.LinesShape.ClippingArea = new RectangleD(x1,
-                                                          rowEntry.LinesShape.ClippingArea.Y1,
-                                                          x2,
-                                                          rowEntry.LinesShape.ClippingArea.Y2);
-      }
-
-      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
-        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
-        info.Grid.ClippingArea = new RectangleD(x1,
-                                                info.Grid.ClippingArea.Y1,
-                                                x2,
-                                                info.Grid.ClippingArea.Y2);
-        info.YAxis.ClippingArea = new RectangleD(0,
-                                                 info.YAxis.ClippingArea.Y1,
-                                                 YAxisWidth,
-                                                 info.YAxis.ClippingArea.Y2);
-      }
-    }
-
-    private void SetClipY(RowEntry rowEntry, double y1, double y2) {
-      rowEntry.LinesShape.ClippingArea = new RectangleD(rowEntry.LinesShape.ClippingArea.X1,
-                                                        y1,
-                                                        rowEntry.LinesShape.ClippingArea.X2,
-                                                        y2);
-
-      YAxisInfo info = GetYAxisInfo(rowEntry.DataRow.YAxis);
-
-      info.Grid.ClippingArea = new RectangleD(info.Grid.ClippingArea.X1,
-                                              y1,
-                                              info.Grid.ClippingArea.X2,
-                                              y2);
-      info.YAxis.ClippingArea = new RectangleD(info.YAxis.ClippingArea.X1,
-                                               y1,
-                                               info.YAxis.ClippingArea.X2,
-                                               y2);
-    }
-
-    private void InitLineShapes(IDataRow row) {
-      RowEntry rowEntry = new RowEntry(row);
-      rowEntries.Add(rowEntry);
-      rowToRowEntry[row] = rowEntry;
-
-      if ((row.LineType == DataRowType.SingleValue)) {
-        if (row.Count > 0) {
-          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
-                                                        row.Style);
-          rowEntry.LinesShape.AddShape(lineShape);
-        }
-      } else {
-        for (int i = 1; i < row.Count; i++) {
-          LineShape lineShape = new LineShape(i - 1, row[i - 1], i, row[i], row.Color, row.Thickness, row.Style);
-          rowEntry.LinesShape.AddShape(lineShape);
-        }
-      }
-
-      ZoomToFullView();
-    }
-
-    private void OnRowValueChanged(IDataRow row, double value, int index, Action action) {
-      RowEntry rowEntry = rowToRowEntry[row];
-
-      if (row.LineType == DataRowType.SingleValue) {
-        if (action == Action.Added) {
-          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
-                                                        row.Style);
-          rowEntry.LinesShape.AddShape(lineShape);
-        } else {
-          LineShape lineShape = rowEntry.LinesShape.GetShape(0);
-          lineShape.Y1 = value;
-          lineShape.Y2 = value;
-        }
-      } else {
-        if (index > rowEntry.LinesShape.Count + 1) {
-          throw new NotImplementedException();
-        }
-
-        // new value was added
-        if (index > 0 && index == rowEntry.LinesShape.Count + 1) {
-          LineShape lineShape = new LineShape(index - 1, row[index - 1], index, row[index], row.Color, row.Thickness, row.Style);
-          rowEntry.LinesShape.AddShape(lineShape);
-        }
-
-        // not the first value
-        if (index > 0) {
-          rowEntry.LinesShape.GetShape(index - 1).Y2 = value;
-        }
-
-        // not the last value
-        if (index > 0 && index < row.Count - 1) {
-          rowEntry.LinesShape.GetShape(index).Y1 = value;
-        }
-      }
-
-      ZoomToFullView();
-    }
-
-    private void OnRowValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      foreach (double value in values) {
-        OnRowValueChanged(row, value, index++, action);
-      }
-    }
-
-    private void OnModelChanged() {
-      titleShape.Text = model.Title;
-
-      canvasUI.Invalidate();
-    }
-
-    #region Begin-/EndUpdate
-
-    private int beginUpdateCount;
-
-    public void BeginUpdate() {
-      beginUpdateCount++;
-    }
-
-    public void EndUpdate() {
-      if (beginUpdateCount == 0) {
-        throw new InvalidOperationException("Too many EndUpdates.");
-      }
-
-      beginUpdateCount--;
-
-      if (beginUpdateCount == 0) {
-        canvasUI.Invalidate();
-      }
-    }
-
-    #endregion
-
-    #region Zooming / Panning
-
-    private void Pan(Point startPoint, Point endPoint) {
-      RectangleD clippingArea = Translate.ClippingArea(startPoint, endPoint, xAxis.ClippingArea, xAxis.Viewport);
-
-      SetClipX(clippingArea.X1, clippingArea.X2);
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        if (rowEntry.DataRow.YAxis.ClipChangeable) {
-          clippingArea = Translate.ClippingArea(startPoint, endPoint, rowEntry.LinesShape.ClippingArea, rowEntry.LinesShape.Viewport);
-          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
-        }
-      }
-
-      canvasUI.Invalidate();
-    }
-
-    private void PanEnd(Point startPoint, Point endPoint) {
-      Pan(startPoint, endPoint);
-    }
-
-    private void SetClippingArea(Rectangle rectangle) {
-      RectangleD clippingArea = Transform.ToWorld(rectangle, xAxis.Viewport, xAxis.ClippingArea);
-
-      SetClipX(clippingArea.X1, clippingArea.X2);
-
-      foreach (RowEntry rowEntry in rowEntries) {
-        if (rowEntry.DataRow.YAxis.ClipChangeable) {
-          clippingArea = Transform.ToWorld(rectangle, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
-
-          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
-        }
-      }
-
-      userInteractionShape.RemoveShape(rectangleShape);
-      canvasUI.Invalidate();
-    }
-
-    private void DrawRectangle(Rectangle rectangle) {
-      rectangleShape.Rectangle = Transform.ToWorld(rectangle, userInteractionShape.Viewport, userInteractionShape.ClippingArea);
-      canvasUI.Invalidate();
-    }
-
-    private void canvasUI1_KeyDown(object sender, KeyEventArgs e) {
-    }
-
-    private void canvasUI1_MouseDown(object sender, MouseEventArgs e) {
-      Focus();
-
-      if (e.Button == MouseButtons.Right) {
-        contextMenuStrip1.Show(PointToScreen(e.Location));
-      } else if (e.Button == MouseButtons.Left) {
-        if (ModifierKeys == Keys.None) {
-          PanListener panListener = new PanListener(e.Location);
-          panListener.Pan += Pan;
-          panListener.PanEnd += PanEnd;
-
-          mouseEventListener = panListener;
-        } else if (ModifierKeys == Keys.Control) {
-          ZoomListener zoomListener = new ZoomListener(e.Location);
-          zoomListener.DrawRectangle += DrawRectangle;
-          zoomListener.SetClippingArea += SetClippingArea;
-
-          rectangleShape.Rectangle = RectangleD.Empty;
-          userInteractionShape.AddShape(rectangleShape);
-
-          mouseEventListener = zoomListener;
-        }
-      }
-    }
-
-    private void canvasUI_MouseMove(object sender, MouseEventArgs e) {
-      if (mouseEventListener != null) {
-        mouseEventListener.MouseMove(sender, e);
-      }
-    }
-
-    private void canvasUI_MouseUp(object sender, MouseEventArgs e) {
-      if (mouseEventListener != null) {
-        mouseEventListener.MouseUp(sender, e);
-      }
-
-      mouseEventListener = null;
-    }
-
-    private void canvasUI1_MouseWheel(object sender, MouseEventArgs e) {
-      if (ModifierKeys == Keys.Control) {
-        double zoomFactor = (e.Delta > 0) ? 0.7 : 1.3;
-
-        PointD world;
-
-        world = Transform.ToWorld(e.Location, xAxis.Viewport, xAxis.ClippingArea);
-
-        double x1 = world.X - (world.X - xAxis.ClippingArea.X1)*zoomFactor;
-        double x2 = world.X + (xAxis.ClippingArea.X2 - world.X)*zoomFactor;
-
-        SetClipX(x1, x2);
-
-        foreach (RowEntry rowEntry in rowEntries) {
-          world = Transform.ToWorld(e.Location, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
-
-          double y1 = world.Y - (world.Y - rowEntry.LinesShape.ClippingArea.Y1) * zoomFactor;
-          double y2 = world.Y + (rowEntry.LinesShape.ClippingArea.Y2 - world.Y)*zoomFactor;
-
-          SetClipY(rowEntry, y1, y2);
-        }
-
-        canvasUI.Invalidate();
-      }
-    }
-
-    #endregion
-
-    private class LinesShape : WorldShape {
-      public void UpdateStyle(IDataRow row) {
-        foreach (IShape shape in shapes) {
-          LineShape lineShape = shape as LineShape;
-          if (lineShape != null) {
-            lineShape.LSColor = row.Color;
-            lineShape.LSDrawingStyle = row.Style;
-            lineShape.LSThickness = row.Thickness;
-          }
-        }
-      }
-
-      public int Count {
-        get { return shapes.Count; }
-      }
-
-      public LineShape GetShape(int index) {
-        return (LineShape)shapes[index];
-      }
-    }
-
-    private class RowEntry {
-      private readonly IDataRow dataRow;
-
-      private readonly LinesShape linesShape = new LinesShape();
-
-      public RowEntry(IDataRow dataRow) {
-        this.dataRow = dataRow;
-      }
-
-      public IDataRow DataRow {
-        get { return dataRow; }
-      }
-
-      public LinesShape LinesShape {
-        get { return linesShape; }
-      }
-    }
-
-    private class YAxisInfo {
-      private readonly Grid grid = new Grid();
-      private readonly YAxis yAxis = new YAxis();
-
-      public Grid Grid {
-        get { return grid; }
-      }
-
-      public YAxis YAxis {
-        get { return yAxis; }
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/LineChart.resx
===================================================================
--- trunk/sources/HeuristicLab.Visualization/LineChart.resx	(revision 1528)
+++ 	(revision )
@@ -1,123 +1,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 17</value>
-  </metadata>
-</root>
Index: trunk/sources/HeuristicLab.Visualization/LineShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/LineShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,128 +1,0 @@
-﻿using System.Drawing;
-using System.Drawing.Drawing2D;
-
-namespace HeuristicLab.Visualization {
-  public class LineShape : IShape {
-    private IShape parent;
-    private RectangleD boundingBox;
-
-    private Color color;
-    private int thickness;
-    private DrawingStyle drawingStyle;
-
-    private Pen pen;
-
-    /// <summary>
-    /// Initializes the LineShape.
-    /// </summary>
-    /// <param name="x1">x coordinate of left lineEndPoind</param>
-    /// <param name="y1">y coordinate of left lineEndPoind</param>
-    /// <param name="x2">x coordinate of right lineEndPoind</param>
-    /// <param name="y2">y coordinate of right lineEndPoind</param>
-    /// <param name="color">color for the LineShape</param>
-    /// <param name="thickness">tickness of the line in pixels</param>
-    /// <param name="drawingStyle">drawing style of the line (solid, dashed, dotted,...)</param>
-    public LineShape(double x1, double y1, double x2, double y2, Color color, int thickness, DrawingStyle drawingStyle) {
-      this.boundingBox = new RectangleD(x1, y1, x2, y2);
-      this.LSColor = color;
-      this.LSThickness = thickness;
-      this.LSDrawingStyle = drawingStyle;
-    }
-
-    public RectangleD BoundingBox {
-      get { return boundingBox; }
-      set { boundingBox = value; }
-    }
-
-    public RectangleD ClippingArea {
-      get { return Parent.ClippingArea; }
-    }
-
-    public Rectangle Viewport {
-      get { return Parent.Viewport; }
-    }
-
-    public IShape Parent {
-      get { return parent; }
-      set { parent = value; }
-    }
-
-    public double Y1 {
-      get { return boundingBox.Y1; }
-      set { boundingBox.Y1 = value; }
-    }
-
-    public double Y2 {
-      get { return boundingBox.Y2; }
-      set { boundingBox.Y2 = value; }
-    }
-
-    public double X1 {
-      get { return boundingBox.X1; }
-      set { boundingBox.X1 = value; }
-    }
-
-    public double X2 {
-      get { return boundingBox.X2; }
-      set { boundingBox.X2 = value; }
-    }
-
-    /// <summary>
-    /// Draws the LineShape.
-    /// </summary>
-    /// <param name="graphics">graphics handle to draw to</param>
-    public virtual void Draw(Graphics graphics) {
-      Rectangle screenRect = Transform.ToScreen(boundingBox, Parent.Viewport, Parent.ClippingArea);
-
-      graphics.DrawLine(GetPen(), screenRect.Left, screenRect.Bottom, screenRect.Right, screenRect.Top);
-    }
-
-    private Pen GetPen() {
-      if (pen == null) {
-        pen = new Pen(LSColor, LSThickness);
-
-        switch (LSDrawingStyle) {
-          case DrawingStyle.Dashed:
-            pen.DashStyle = DashStyle.Dash;
-            break;
-          default:
-            pen.DashStyle = DashStyle.Solid;
-            break;
-        }
-      }
-
-      return pen;
-    }
-
-    private void DisposePen() {
-      if (pen != null) {
-        pen.Dispose();
-        pen = null;
-      }
-    }
-
-    public Color LSColor {
-      get { return color; }
-      set {
-        color = value;
-        DisposePen();
-      }
-    }
-
-    public int LSThickness {
-      get { return thickness; }
-      set {
-        thickness = value;
-        DisposePen();
-      }
-    }
-
-    public DrawingStyle LSDrawingStyle {
-      get { return drawingStyle; }
-      set {
-        drawingStyle = value;
-        DisposePen();
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/MaxAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/MaxAggregator.cs	(revision 1528)
+++ 	(revision )
@@ -1,120 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public class MaxAggregator : DataRowBase {
-    #region IAggregator Members
-
-    public void AddWatch(IDataRow dataRow) {
-      dataRowWatches.Add(dataRow);
-      dataRow.ValueChanged += dataRow_ValueChanged;
-      dataRow.ValuesChanged += dataRow_ValuesChanged;
-      dataRow.DataRowChanged += dataRow_DataRowChanged;
-    }
-
-    public void RemoveWatch(IDataRow dataRow) {
-
-      dataRowWatches.Remove(dataRow);
-      dataRow.DataRowChanged -= dataRow_DataRowChanged;
-      dataRow.ValuesChanged -= dataRow_ValuesChanged;
-      dataRow.ValueChanged -= dataRow_ValueChanged;
-    }
-
-
-    #endregion
-
-    List<IDataRow> dataRowWatches = new List<IDataRow>();
-    double curMaxValue;
-
-    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
-      refreshValue(value);
-    }
-
-    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      for (int i = 0; i < values.Length; i++) {
-        refreshValue(values[i]);
-      }
-    }
-
-    void dataRow_DataRowChanged(IDataRow row) {
-      refreshValue(double.MinValue);
-    }
-
-    private void refreshValue(double newVal) {
-      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
-      if (curMaxValue < newVal) {
-        curMaxValue = newVal;
-        OnValueChanged(newVal, 0, Action.Modified);
-      } else {
-        curMaxValue = double.MinValue;
-        foreach (IDataRow rows in dataRowWatches) {
-          for (int i = 0; i < rows.Count; i++) {
-            if (rows[i] > curMaxValue) {
-              curMaxValue = rows[i];
-            }
-          }
-        }
-
-      }
-      // evtl nur feuern wenn sich geändert hat (jedes mal?)
-      OnValueChanged(curMaxValue, 0, Action.Modified);
-    }
-
-    #region IDataRow Members
-    public override void AddValue(double value) {
-      OnValueChanged(2, 0, Action.Added);
-    }
-
-    public override void AddValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValue(int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValues(int index, int count) {
-      throw new NotSupportedException();
-    }
-
-    public override int Count {
-      get { return 1; }
-    }
-
-    public override double this[int index] {
-      get {
-        return curMaxValue;
-      }
-      set {
-        throw new NotSupportedException();
-      }
-    }
-
-    public override double MinValue {
-      get { return curMaxValue; }
-    }
-
-    public override double MaxValue {
-      get { return curMaxValue; }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/MinAggregator.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/MinAggregator.cs	(revision 1528)
+++ 	(revision )
@@ -1,120 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-
-namespace HeuristicLab.Visualization {
-  public class MinAggregator : DataRowBase {
-    #region IAggregator Members
-
-    public void AddWatch(IDataRow dataRow) {
-      dataRowWatches.Add(dataRow);
-      dataRow.ValueChanged += dataRow_ValueChanged;
-      dataRow.ValuesChanged += dataRow_ValuesChanged;
-      dataRow.DataRowChanged += dataRow_DataRowChanged;
-    }
-
-    public void RemoveWatch(IDataRow dataRow) {
-
-      dataRowWatches.Remove(dataRow);
-      dataRow.DataRowChanged -= dataRow_DataRowChanged;
-      dataRow.ValuesChanged -= dataRow_ValuesChanged;
-      dataRow.ValueChanged -= dataRow_ValueChanged;
-    }
-
-
-    #endregion
-
-    readonly List<IDataRow> dataRowWatches = new List<IDataRow>();
-    double curMinValue;
-
-    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
-      refreshValue(value);
-    }
-
-    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
-      for (int i = 0; i < values.Length; i++) {
-        refreshValue(values[i]);
-      }
-    }
-
-    void dataRow_DataRowChanged(IDataRow row) {
-      refreshValue(double.MaxValue);
-    }
-
-    private void refreshValue(double newVal) {
-      //alle durchlaufen und neues min berechnen; verbesserung: merken in welcher row lowest wert steckt
-      if (curMinValue > newVal) {
-        curMinValue = newVal;
-        OnValueChanged(newVal, 0, Action.Modified);
-      } else {
-        curMinValue = double.MaxValue;
-        foreach (IDataRow rows in dataRowWatches) {
-          for (int i = 0; i < rows.Count; i++) {
-            if (rows[i] < curMinValue) {
-              curMinValue = rows[i];
-            }
-          }
-        }
-
-      }
-      // evtl nur feuern wenn sich geändert hat (jedes mal?)
-      OnValueChanged(curMinValue, 0, Action.Modified);
-    }
-
-    #region IDataRow Members
-
-    public override void AddValue(double value) {
-      OnValueChanged(2, 0, Action.Added);
-    }
-
-    public override void AddValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values) {
-      throw new NotSupportedException();
-    }
-
-    public override void AddValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValue(double value, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void ModifyValues(double[] values, int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValue(int index) {
-      throw new NotSupportedException();
-    }
-
-    public override void RemoveValues(int index, int count) {
-      throw new NotSupportedException();
-    }
-
-    public override int Count {
-      get { return 1; }
-    }
-
-    public override double this[int index] {
-      get {
-        return curMinValue;
-      }
-      set {
-        throw new NotSupportedException();
-      }
-    }
-
-    public override double MinValue {
-      get { return curMinValue; }
-    }
-
-    public override double MaxValue {
-      get { return curMinValue; }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/Offset.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/Offset.cs	(revision 1528)
+++ 	(revision )
@@ -1,115 +1,0 @@
-﻿#region License Information
-
-/* HeuristicLab
- * Copyright (C) 2002-2008 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;
-
-namespace HeuristicLab.Visualization {
-  public struct Offset {
-    public static readonly Offset Empty = new Offset();
-
-    private double myDX;
-
-    public double DX {
-      get { return myDX; }
-      set { myDX = value; }
-    }
-
-    private double myDY;
-
-    public double DY {
-      get { return myDY; }
-      set { myDY = value; }
-    }
-
-    public bool IsEmpty {
-      get { return this == Empty; }
-    }
-
-    public double Length {
-      get { return Math.Sqrt(DX*DX + DY*DY); }
-    }
-
-    public Offset(double dx, double dy) {
-      myDX = dx;
-      myDY = dy;
-    }
-
-    public Offset(PointD point) {
-      myDX = point.X;
-      myDY = point.Y;
-    }
-
-    public Offset(SizeD size) {
-      myDX = size.Width;
-      myDY = size.Height;
-    }
-
-    public override bool Equals(object obj) {
-      if (obj is Offset) {
-        return ((Offset)obj) == this;
-      } else {
-        return base.Equals(obj);
-      }
-    }
-
-    public override int GetHashCode() {
-      return (int)Math.Pow(DX, DY);
-    }
-
-    public override string ToString() {
-      return string.Format("({0};{1})", DX, DY);
-    }
-
-    public static Offset operator +(Offset offset1, Offset offset2) {
-      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
-    }
-
-    public static Offset operator -(Offset offset1, Offset offset2) {
-      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
-    }
-
-    public static bool operator ==(Offset offset1, Offset offset2) {
-      return (offset1.DX == offset2.DX) && (offset1.DY == offset2.DY);
-    }
-
-    public static bool operator !=(Offset offset1, Offset offset2) {
-      return (offset1.DX != offset2.DX) && (offset1.DY != offset2.DY);
-    }
-
-    public static explicit operator PointD(Offset offset) {
-      return new PointD(offset.DX, offset.DY);
-    }
-
-    public static explicit operator SizeD(Offset offset) {
-      return new SizeD(offset.DX, offset.DY);
-    }
-
-    public static Offset Add(Offset offset1, Offset offset2) {
-      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
-    }
-
-    public static Offset Subtract(Offset offset1, Offset offset2) {
-      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/PanListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/PanListener.cs	(revision 1528)
+++ 	(revision )
@@ -1,33 +1,0 @@
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace HeuristicLab.Visualization {
-  public class PanListener : IMouseEventListener {
-    private Point startPoint;
-
-    public event MoveHandler Pan;
-    public event MoveHandler PanEnd;
-
-    public PanListener(Point startPoint) {
-      this.startPoint = startPoint;
-    }
-
-    #region IMouseEventListener Members
-
-    public void MouseMove(object sender, MouseEventArgs e) {
-      if (Pan != null) {
-        Pan(startPoint, e.Location);
-      }
-
-      startPoint = e.Location;  
-    }
-
-    public void MouseUp(object sender, MouseEventArgs e) {
-      if(PanEnd != null) {
-        PanEnd(startPoint, e.Location);
-      }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/PointD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/PointD.cs	(revision 1528)
+++ 	(revision )
@@ -1,128 +1,0 @@
-﻿#region License Information
-
-/* HeuristicLab
- * Copyright (C) 2002-2008 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;
-
-namespace HeuristicLab.Visualization {
-  public struct PointD {
-    public static readonly PointD Empty = new PointD();
-
-    private double myX;
-
-    public double X {
-      get { return myX; }
-      set { myX = value; }
-    }
-
-    private double myY;
-
-    public double Y {
-      get { return myY; }
-      set { myY = value; }
-    }
-
-    public bool IsEmpty {
-      get { return this == Empty; }
-    }
-
-    public PointD(double x, double y) {
-      myX = x;
-      myY = y;
-    }
-
-    public PointD(SizeD size) {
-      myX = size.Width;
-      myY = size.Height;
-    }
-
-    public PointD(Offset offset) {
-      myX = offset.DX;
-      myY = offset.DY;
-    }
-
-    public override bool Equals(object obj) {
-      if (obj is PointD) {
-        return ((PointD)obj) == this;
-      } else {
-        return base.Equals(obj);
-      }
-    }
-
-    public override int GetHashCode() {
-      return (int)Math.Pow(X, Y);
-    }
-
-    public override string ToString() {
-      return string.Format("({0};{1})", X, Y);
-    }
-
-    public static PointD operator +(PointD point, Offset offset) {
-      return new PointD(point.X + offset.DX, point.Y + offset.DY);
-    }
-
-    public static PointD operator -(PointD point, Offset offset) {
-      return new PointD(point.X - offset.DX, point.Y - offset.DY);
-    }
-
-    public static Offset operator +(PointD point1, PointD point2) {
-      return new Offset(point1.X + point2.X, point1.Y + point2.Y);
-    }
-
-    public static Offset operator -(PointD point1, PointD point2) {
-      return new Offset(point1.X - point2.X, point1.Y - point2.Y);
-    }
-
-    public static bool operator ==(PointD point1, PointD point2) {
-      return (point1.X == point2.X) && (point1.Y == point2.Y);
-    }
-
-    public static bool operator !=(PointD point1, PointD point2) {
-      return (point1.X != point2.X) && (point1.Y != point2.Y);
-    }
-
-    public static explicit operator SizeD(PointD point) {
-      return new SizeD(point.X, point.Y);
-    }
-
-    public static explicit operator Offset(PointD point) {
-      return new Offset(point.X, point.Y);
-    }
-
-    public static implicit operator PointD(Point point) {
-      return new PointD(point.X, point.Y);
-    }
-
-    public static implicit operator PointD(PointF point) {
-      return new PointD(point.X, point.Y);
-    }
-
-    public static PointD Add(PointD point, Offset offset) {
-      return new PointD(point.X + offset.DX, point.Y + offset.DY);
-    }
-
-    public static PointD Subtract(PointD point, Offset offset) {
-      return new PointD(point.X - offset.DX, point.Y - offset.DY);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/RectangleD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/RectangleD.cs	(revision 1528)
+++ 	(revision )
@@ -1,95 +1,0 @@
-namespace HeuristicLab.Visualization {
-  public struct RectangleD {
-    public static readonly RectangleD Empty = new RectangleD();
-
-    private PointD bottomLeft;
-    private PointD topRight;
-
-    private double width;
-    private double height;
-
-    public RectangleD(double x1, double y1, double x2, double y2) {
-      bottomLeft = PointD.Empty;
-      topRight = PointD.Empty;
-
-      bottomLeft.X = x1;
-      bottomLeft.Y = y1;
-
-      topRight.X = x2;
-      topRight.Y = y2;
-
-      width = x2 - x1;
-      height = y2 - y1;
-    }
-
-    public PointD BottomLeft {
-      get { return bottomLeft; }
-      set {
-        bottomLeft = value;
-        width = topRight.X - bottomLeft.X;
-        height = topRight.Y - bottomLeft.Y;
-      }
-    }
-
-    public PointD TopRight {
-      get { return topRight; }
-      set {
-        topRight = value;
-        width = topRight.X - bottomLeft.X;
-        height = topRight.Y - bottomLeft.Y;
-      }
-    }
-
-    public double X1 {
-      get { return bottomLeft.X; }
-      set {
-        bottomLeft.X = value;
-        width = topRight.X - bottomLeft.X;
-      }
-    }
-
-    public double X2 {
-      get { return topRight.X; }
-      set {
-        topRight.X = value;
-        width = topRight.X - bottomLeft.X;
-      }
-    }
-
-    public double Y1 {
-      get { return bottomLeft.Y; }
-      set {
-        bottomLeft.Y = value;
-        height = topRight.Y - bottomLeft.Y;
-      }
-    }
-
-    public double Y2 {
-      get { return topRight.Y; }
-      set {
-        topRight.Y = value;
-        height = topRight.Y - bottomLeft.Y;
-      }
-    }
-
-    public double Width {
-      get { return width; }
-      set {
-        width = value;
-        topRight.X = bottomLeft.X + width;
-      }
-    }
-
-    public double Height {
-      get { return height; }
-      set {
-        height = value;
-        topRight.Y = bottomLeft.Y + height;
-      }
-    }
-
-    public override string ToString() {
-      return (string.Format("{{X1={0},Y1={1},Width={2},Height={3}}}", X1, Y1, Width, Height));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/RectangleShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/RectangleShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,79 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public class RectangleShape : IShape {
-    private IShape parent;
-    private RectangleD rectangle;
-
-    private Color color;
-
-    private Pen pen;
-    private Brush brush;
-
-    public RectangleShape(double x1, double y1, double x2, double y2, Color color) {
-      rectangle = new RectangleD(x1, y1, x2, y2);
-      this.color = color;
-    }
-
-    public RectangleD BoundingBox {
-      get { return rectangle; }
-    }
-
-    public RectangleD ClippingArea {
-      get { return Parent.ClippingArea; }
-    }
-
-    public Rectangle Viewport {
-      get { return Parent.Viewport; }
-    }
-
-    public IShape Parent {
-      get { return parent; }
-      set { parent = value; }
-    }
-
-    public RectangleD Rectangle {
-      get { return rectangle; }
-      set { rectangle = value; }
-    }
-
-    public void Draw(Graphics graphics) {
-      Rectangle screenRect = Transform.ToScreen(rectangle, Parent.Viewport, Parent.ClippingArea);
-
-      graphics.DrawRectangle(GetPen(), screenRect);
-      graphics.FillRectangle(GetBrush(), screenRect);
-    }
-
-    private Pen GetPen() {
-      if (pen == null)
-        pen = new Pen(color, 1);
-      return pen;
-    }
-
-    private Brush GetBrush() {
-      if (brush == null)
-        brush = new SolidBrush(color);
-      return brush;
-    }
-
-    public Color Color {
-      get { return color; }
-      set {
-        color = value;
-        DisposeDrawingTools();
-      }
-    }
-
-    private void DisposeDrawingTools() {
-      if (pen != null) {
-        pen.Dispose();
-        pen = null;
-      }
-
-      if (brush != null) {
-        brush.Dispose();
-        brush = null;
-      }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/SizeD.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/SizeD.cs	(revision 1528)
+++ 	(revision )
@@ -1,120 +1,0 @@
-﻿#region License Information
-
-/* HeuristicLab
- * Copyright (C) 2002-2008 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;
-
-namespace HeuristicLab.Visualization {
-  public struct SizeD {
-    public static readonly SizeD Empty = new SizeD();
-
-    private double myWidth;
-
-    public double Width {
-      get { return myWidth; }
-      set { myWidth = value; }
-    }
-
-    private double myHeight;
-
-    public double Height {
-      get { return myHeight; }
-      set { myHeight = value; }
-    }
-
-    public bool IsEmpty {
-      get { return this == Empty; }
-    }
-
-    public SizeD(double width, double height) {
-      myWidth = width;
-      myHeight = height;
-    }
-
-    public SizeD(PointD point) {
-      myWidth = point.X;
-      myHeight = point.Y;
-    }
-
-    public SizeD(Offset offset) {
-      myWidth = offset.DX;
-      myHeight = offset.DY;
-    }
-
-    public override bool Equals(object obj) {
-      if (obj is SizeD) {
-        return ((SizeD)obj) == this;
-      } else {
-        return base.Equals(obj);
-      }
-    }
-
-    public override int GetHashCode() {
-      return (int)Math.Pow(Width, Height);
-    }
-
-    public override string ToString() {
-      return string.Format("({0};{1})", Width, Height);
-    }
-
-    public static SizeD operator +(SizeD size1, SizeD size2) {
-      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
-    }
-
-    public static SizeD operator -(SizeD size1, SizeD size2) {
-      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
-    }
-
-    public static bool operator ==(SizeD size1, SizeD size2) {
-      return (size1.Width == size2.Width) && (size1.Height == size2.Height);
-    }
-
-    public static bool operator !=(SizeD size1, SizeD size2) {
-      return (size1.Width != size2.Width) && (size1.Height != size2.Height);
-    }
-
-    public static explicit operator PointD(SizeD size) {
-      return new PointD(size.Width, size.Height);
-    }
-
-    public static explicit operator Offset(SizeD size) {
-      return new Offset(size.Width, size.Height);
-    }
-
-    public static implicit operator SizeD(Size size) {
-      return new SizeD(size.Width, size.Height);
-    }
-
-    public static implicit operator SizeD(SizeF size) {
-      return new SizeD(size.Width, size.Height);
-    }
-
-    public static SizeD Add(SizeD size1, SizeD size2) {
-      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
-    }
-
-    public static SizeD Subtract(SizeD size1, SizeD size2) {
-      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/TextShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/TextShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,154 +1,0 @@
-﻿using System;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-
-namespace HeuristicLab.Visualization {
-  public enum AnchorPositionX {
-    Left, Middle, Right
-  }
-
-  public enum AnchorPositionY {
-    Bottom, Middle, Top
-  }
-
-  public class TextShape : IShape {
-    private IShape parent;
-    private Font font;
-    private Brush brush;
-    private Color color;
-    private string text;
-    private double x;
-    private double y;
-    private float rotation = 0;
-
-    private AnchorPositionX anchorPositionX = AnchorPositionX.Left;
-    private AnchorPositionY anchorPositionY = AnchorPositionY.Top;
-
-    public TextShape(string text) : this(0, 0, text, 14) {}
-
-    public TextShape(double x, double y, string text) : this(x, y, text, 8) {}
-
-    public TextShape(double x, double y, string text, int fontSize) {
-      this.x = x;
-      this.y = y;
-      this.text = text;
-      font = new Font("Arial", fontSize);
-
-      Color = Color.Blue;
-    }
-
-    public TextShape(double x, double y, string text, Font font, Color color) {
-      this.x = x;
-      this.y = y;
-      this.text = text;
-      Font = font;
-      Color = color;
-    }
-
-    public string Text {
-      get { return text; }
-      set { text = value; }
-    }
-
-    public double X {
-      get { return x; }
-      set { x = value; }
-    }
-
-    public double Y {
-      get { return y; }
-      set { y = value; }
-    }
-
-    public float Rotation {
-      get { return rotation; }
-      set { rotation = value; }
-    }
-
-    public Color Color {
-      get { return color; }
-      set {
-        color = value;
-        brush = new SolidBrush(color);
-      }
-    }
-
-    public Font Font {
-      get { return font; }
-      set { font = value; }
-    }
-
-    public AnchorPositionX AnchorPositionX {
-      get { return anchorPositionX; }
-      set { anchorPositionX = value; }
-    }
-
-    public AnchorPositionY AnchorPositionY {
-      get { return anchorPositionY; }
-      set { anchorPositionY = value; }
-    }
-
-    #region IShape Members
-
-    public void Draw(Graphics graphics) {
-      int screenX = Transform.ToScreenX(x, Parent.Viewport, Parent.ClippingArea);
-      int screenY = Transform.ToScreenY(y, Parent.Viewport, Parent.ClippingArea);
-      int offsetX, offsetY;
-
-      SizeF size = graphics.MeasureString(text, font);
-
-      switch (AnchorPositionX) {
-        case AnchorPositionX.Left:
-          offsetX = 0;
-          break;
-        case AnchorPositionX.Middle:
-          offsetX = -(int)(size.Width/2);
-          break;
-        case AnchorPositionX.Right:
-          offsetX = -(int)size.Width;
-          break;
-        default:
-          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
-      }
-
-      switch (AnchorPositionY) {
-        case AnchorPositionY.Top:
-          offsetY = 0;
-          break;
-        case AnchorPositionY.Middle:
-          offsetY = -(int)(size.Height/2);
-          break;
-        case AnchorPositionY.Bottom:
-          offsetY = -(int)size.Height;
-          break;
-        default:
-          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
-      }
-
-      GraphicsState gstate = graphics.Save();
-      graphics.TranslateTransform(screenX, screenY, MatrixOrder.Append);
-      graphics.RotateTransform(rotation, MatrixOrder.Prepend);
-      graphics.DrawString(text, font, brush, offsetX, offsetY);
-      graphics.Restore(gstate);
-    }
-
-    public RectangleD BoundingBox {
-      get { return RectangleD.Empty; }
-    }
-
-    public RectangleD ClippingArea {
-      get { return Parent.ClippingArea; }
-    }
-
-    public Rectangle Viewport {
-      get { return Parent.Viewport; }
-    }
-
-    public IShape Parent {
-      get { return parent; }
-      set { parent = value; }
-    }
-
-    #endregion
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/Transform.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/Transform.cs	(revision 1528)
+++ 	(revision )
@@ -1,117 +1,0 @@
-﻿using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  /// <summary>
-  /// GDI (or screen) coordinate system
-  ///   The GDI coordinate system is specified in pixels. X goes from left to right
-  ///   and Y goes from top to bottom.
-  /// 
-  /// World coordinate system
-  ///   A world coordinate system can be freely specified. X goes from left to
-  ///   right and Y goes from bottom to top.
-  /// 
-  /// The transformation between world- and screen-coordinate systems is done using
-  /// a view port and a clipping area.
-  /// </summary>
-  public static class Transform {
-    /// <summary>
-    /// Transforms a rectangle in screen coordinates to world coordinates
-    /// </summary>
-    /// <param name="rect">The rectangle in screen coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The rectangle rect transformed to world coordinates</returns>
-    public static RectangleD ToWorld(Rectangle rect, Rectangle viewport, RectangleD clippingArea) {
-      double x1 = ToWorldX(rect.Left, viewport, clippingArea);
-      double y1 = ToWorldY(rect.Bottom, viewport, clippingArea);
-      double x2 = ToWorldX(rect.Right, viewport, clippingArea);
-      double y2 = ToWorldY(rect.Top, viewport, clippingArea);
-      return new RectangleD(x1, y1, x2, y2);
-    }
-
-    /// <summary>
-    /// Transforms a 2d point in screen coordinates to world coordinates
-    /// </summary>
-    /// <param name="point">The point in screen coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to world coordinates</returns>
-    public static PointD ToWorld(Point point, Rectangle viewport, RectangleD clippingArea) {
-      double x = ToWorldX(point.X, viewport, clippingArea);
-      double y = ToWorldY(point.Y, viewport, clippingArea);
-      return new PointD(x, y);
-    }
-
-    /// <summary>
-    /// Transforms a point on the X-axis in screen coordinates to world coordinates
-    /// </summary>
-    /// <param name="x">The point on the X-axis in screen coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to world coordinates</returns>
-    public static double ToWorldX(int x, Rectangle viewport, RectangleD clippingArea) {
-      return clippingArea.X1 + clippingArea.Width/viewport.Width*(x - viewport.Left);
-    }
-
-    /// <summary>
-    /// Transforms a point on the Y-axis in screen coordinates to world coordinates
-    /// </summary>
-    /// <param name="y">The point on the Y-axis in screen coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to world coordinates</returns>
-    public static double ToWorldY(int y, Rectangle viewport, RectangleD clippingArea) {
-      return clippingArea.Y1 - clippingArea.Height/viewport.Height*(y - viewport.Bottom);
-    }
-
-    /// <summary>
-    /// Transforms a rectangle in world coordinates to screen coordinates
-    /// </summary>
-    /// <param name="rect">The rectangle in world coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The rectangle rect transformed to screen coordinates</returns>
-    public static Rectangle ToScreen(RectangleD rect, Rectangle viewport, RectangleD clippingArea) {
-      int left = ToScreenX(rect.X1, viewport, clippingArea);
-      int bottom = ToScreenY(rect.Y1, viewport, clippingArea);
-      int right = ToScreenX(rect.X2, viewport, clippingArea);
-      int top = ToScreenY(rect.Y2, viewport, clippingArea);
-      return new Rectangle(left, top, right - left , bottom - top );
-    }
-
-    /// <summary>
-    /// Transforms a 2d point in world coordinates to screen coordinates
-    /// </summary>
-    /// <param name="point">The point in world coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to screen coordinates</returns>
-    public static Point ToScreen(PointD point, Rectangle viewport, RectangleD clippingArea) {
-      int x = ToScreenX(point.X, viewport, clippingArea);
-      int y = ToScreenY(point.Y, viewport, clippingArea);
-      return new Point(x, y);
-    }
-
-    /// <summary>
-    /// Transforms a point on the X-axis in world coordinates to screen coordinates
-    /// </summary>
-    /// <param name="x">The point on the X-axis in world coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to screen coordinates</returns>
-    public static int ToScreenX(double x, Rectangle viewport, RectangleD clippingArea) {
-      return (int)(viewport.Left + viewport.Width/clippingArea.Width*(x - clippingArea.X1));
-    }
-
-    /// <summary>
-    /// Transforms a point on the Y-axis in world coordinates to screen coordinates
-    /// </summary>
-    /// <param name="y">The point on the Y-axis in world coordinates that should be transformed</param>
-    /// <param name="viewport">The target view port</param>
-    /// <param name="clippingArea">The target clipping area</param>
-    /// <returns>The point transformed to screen coordinates</returns>
-    public static int ToScreenY(double y, Rectangle viewport, RectangleD clippingArea) {
-      return (int)(viewport.Bottom - viewport.Height/clippingArea.Height*(y - clippingArea.Y1));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/Translate.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/Translate.cs	(revision 1528)
+++ 	(revision )
@@ -1,26 +1,0 @@
-using System.Drawing;
-
-namespace HeuristicLab.Visualization {
-  public static class Translate {
-    public static RectangleD ClippingArea(Point startPoint, Point endPoint, RectangleD clippingArea, Rectangle viewPort) {
-      PointD worldStartPoint = Transform.ToWorld(startPoint, viewPort, clippingArea);
-      PointD worldEndPoint = Transform.ToWorld(endPoint, viewPort, clippingArea);
-
-      double xDiff = worldEndPoint.X - worldStartPoint.X;
-      double yDiff = worldEndPoint.Y - worldStartPoint.Y;
-
-      return RectangleD(xDiff, yDiff, clippingArea);
-    }
-
-    public static RectangleD RectangleD(double x, double y, RectangleD rectangle) {
-      RectangleD rect = new RectangleD();
-
-      rect.X1 = rectangle.X1 - x;
-      rect.X2 = rectangle.X2 - x;
-      rect.Y1 = rectangle.Y1 - y;
-      rect.Y2 = rectangle.Y2 - y;
-
-      return rect;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/WorldShape.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/WorldShape.cs	(revision 1528)
+++ 	(revision )
@@ -1,77 +1,0 @@
-﻿using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-
-namespace HeuristicLab.Visualization {
-  /// <summary>
-  /// World shapes are composite shapes that have their own coordinate system
-  /// which is independent from their parent's coordinate system.
-  /// </summary>
-  public class WorldShape : IShape {
-    private RectangleD clippingArea; // own clipping area
-    private RectangleD boundingBox;
-    private IShape parent;
-
-    protected readonly List<IShape> shapes = new List<IShape>();
-
-    public WorldShape() {
-      this.clippingArea = new RectangleD(0, 0, 1, 1);
-      this.boundingBox = new RectangleD(0, 0, 1, 1);
-    }
-
-    public virtual void Draw(Graphics graphics) {
-      GraphicsState gstate = graphics.Save();
-
-      graphics.SetClip(Viewport);
-
-      foreach (IShape shape in shapes) {
-        // draw child shapes using our own clipping area
-        shape.Draw(graphics);
-      }
-
-      graphics.Restore(gstate);
-    }
-
-    public RectangleD BoundingBox {
-      get { return boundingBox; }
-      set { boundingBox = value; }
-    }
-
-    /// <summary>
-    /// The world shape's own clipping area.
-    /// This overrides the clipping area of the parent shape.
-    /// </summary>
-    public RectangleD ClippingArea {
-      get { return clippingArea; }
-      set { clippingArea = value; }
-    }
-
-    public Rectangle Viewport {
-      get {
-        // calculate our drawing area on the screen using our location and
-        // size in the parent (boundingBox), the parent's viewport and the
-        // parent's clipping area
-        Rectangle viewport = Transform.ToScreen(boundingBox, Parent.Viewport, Parent.ClippingArea);
-        return viewport;
-      }
-    }
-
-    public IShape Parent {
-      get { return parent; }
-      set { parent = value; }
-    }
-
-    public void ClearShapes() {
-      shapes.Clear();
-    }
-
-    public void AddShape(IShape shape) {
-      shape.Parent = this;
-      shapes.Add(shape);
-    }
-
-    public bool RemoveShape(IShape shape) {
-      return shapes.Remove(shape);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/XAxis.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/XAxis.cs	(revision 1528)
+++ 	(revision )
@@ -1,66 +1,0 @@
-using System.Drawing;
-using HeuristicLab.Visualization.LabelProvider;
-
-namespace HeuristicLab.Visualization {
-  public class XAxis : WorldShape {
-    public const int PixelsPerInterval = 100;
-    
-    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.####");
-
-    private Color color = Color.Blue;
-    private Font font = new Font("Arial", 8);
-    private bool showLabel = true;
-    private string label = "";
-
-    public ILabelProvider LabelProvider {
-      get { return labelProvider; }
-      set { labelProvider = value; }
-    }
-
-    public override void Draw(Graphics graphics) {
-      ClearShapes();
-
-      foreach (double x in AxisTicks.GetTicks(PixelsPerInterval, Parent.Viewport.Width,
-                                              ClippingArea.Width,
-                                              ClippingArea.X1)) {
-        TextShape tickLabel = new TextShape(x, ClippingArea.Height - 3,
-                                        labelProvider.GetLabel(x), Font, Color);
-        tickLabel.AnchorPositionX = AnchorPositionX.Middle;
-        tickLabel.AnchorPositionY = AnchorPositionY.Top;
-        AddShape(tickLabel);
-      }
-
-      if (showLabel) {
-        TextShape label = new TextShape(ClippingArea.X1 + ClippingArea.Width/2,
-                                        ClippingArea.Y1 + 3,
-                                        this.label);
-        label.AnchorPositionX = AnchorPositionX.Middle;
-        label.AnchorPositionY = AnchorPositionY.Bottom;
-
-        AddShape(label);
-      }
-
-      base.Draw(graphics);
-    }
-
-    public Color Color {
-      get { return color; }
-      set { color = value; }
-    }
-
-    public Font Font {
-      get { return font; }
-      set { font = value; }
-    }
-
-    public bool ShowLabel {
-      get { return showLabel; }
-      set { showLabel = value; }
-    }
-
-    public string Label {
-      get { return label; }
-      set { label = value; }
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/YAxis.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/YAxis.cs	(revision 1528)
+++ 	(revision )
@@ -1,92 +1,0 @@
-using System;
-using System.Drawing;
-using HeuristicLab.Visualization.LabelProvider;
-using HeuristicLab.Visualization.Test;
-
-namespace HeuristicLab.Visualization {
-  public class YAxis : WorldShape {
-    public const int PixelsPerInterval = 75;
-
-    private ILabelProvider labelProvider = new ContinuousLabelProvider("e4");
-    private AxisPosition position = AxisPosition.Left;
-    private bool showLabel = true;
-    private string label = "";
-
-    public ILabelProvider LabelProvider {
-      get { return labelProvider; }
-      set { labelProvider = value; }
-    }
-
-    public AxisPosition Position {
-      get { return position; }
-      set { position = value; }
-    }
-
-    public bool ShowLabel {
-      get { return showLabel; }
-      set { showLabel = value; }
-    }
-
-    public string Label {
-      get { return label; }
-      set { label = value; }
-    }
-
-    public override void Draw(Graphics graphics) {
-      ClearShapes();
-
-      foreach (double y in AxisTicks.GetTicks(PixelsPerInterval, Parent.Viewport.Height,
-                                              ClippingArea.Height,
-                                              ClippingArea.Y1)) {
-        double x;
-        AnchorPositionX anchorPositionX;
-
-        switch (position) {
-          case AxisPosition.Left:
-            x = ClippingArea.X2 - 3;
-            anchorPositionX = AnchorPositionX.Right;
-            break;
-          case AxisPosition.Right:
-            x = ClippingArea.X1 + 3;
-            anchorPositionX = AnchorPositionX.Left;
-            break;
-          default:
-            throw new NotImplementedException();
-        }
-        
-        TextShape tickLabel = new TextShape(x, y, labelProvider.GetLabel(y));
-        tickLabel.AnchorPositionX = anchorPositionX;
-        tickLabel.AnchorPositionY = AnchorPositionY.Middle;
-        AddShape(tickLabel);
-      }
-
-      if (showLabel) {
-        double x;
-        AnchorPositionY anchorPositionY;
-
-        switch (position) {
-          case AxisPosition.Left:
-            x = ClippingArea.X1 + 3;
-            anchorPositionY = AnchorPositionY.Top;
-            break;
-          case AxisPosition.Right:
-            x = ClippingArea.X2 - 3;
-            anchorPositionY = AnchorPositionY.Bottom;
-            break;
-          default:
-            throw new NotImplementedException();
-        }
-
-        TextShape label = new TextShape(x,
-                                        ClippingArea.Y1 + ClippingArea.Height/2,
-                                        this.label);
-        label.AnchorPositionX = AnchorPositionX.Middle;
-        label.AnchorPositionY = anchorPositionY;
-        label.Rotation = -90;
-        AddShape(label);
-      }
-
-      base.Draw(graphics);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/YAxisDescriptor.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/YAxisDescriptor.cs	(revision 1528)
+++ 	(revision )
@@ -1,127 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using HeuristicLab.Visualization.LabelProvider;
-using HeuristicLab.Visualization.Test;
-
-namespace HeuristicLab.Visualization {
-  public delegate void YAxisDescriptorChangedHandler(YAxisDescriptor sender);
-
-  public class YAxisDescriptor {
-    private ILabelProvider yAxisLabelProvider = new ContinuousLabelProvider("0.##");
-    private readonly List<IDataRow> dataRows = new List<IDataRow>();
-    private bool showYAxis = true;
-    private bool showYAxisLabel = true;
-    private string label = "";
-    public bool clipChangeable = true;
-    private AxisPosition position = AxisPosition.Left;
-
-    private bool showGrid = true;
-    private Color gridColor = Color.LightBlue;
-
-    public event YAxisDescriptorChangedHandler YAxisDescriptorChanged;
-
-    private void OnYAxisDescriptorChanged() {
-      if (YAxisDescriptorChanged != null) {
-        YAxisDescriptorChanged(this);
-      }
-    }
-
-    public List<IDataRow> DataRows {
-      get { return dataRows; }
-    }
-
-    public bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public bool ShowYAxisLabel {
-      get { return showYAxisLabel; }
-      set {
-        showYAxisLabel = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public ILabelProvider YAxisLabelProvider {
-      get { return yAxisLabelProvider; }
-      set {
-        yAxisLabelProvider = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public double MinValue {
-      get {
-        double min = double.MaxValue;
-
-        foreach (IDataRow row in dataRows) {
-          min = Math.Min(min, row.MinValue);
-        }
-
-        return min;
-      }
-    }
-
-    public double MaxValue {
-      get {
-        double max = double.MinValue;
-
-        foreach (IDataRow row in dataRows) {
-          max = Math.Max(max, row.MaxValue);
-        }
-
-        return max;
-      }
-    }
-
-    public string Label {
-      get { return label; }
-      set {
-        label = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public bool ClipChangeable {
-      get { return clipChangeable; }
-      set { clipChangeable = value; }
-    }
-
-    public AxisPosition Position {
-      get { return position; }
-      set {
-        position = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public bool ShowGrid {
-      get { return showGrid; }
-      set {
-        showGrid = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public Color GridColor {
-      get { return gridColor; }
-      set {
-        gridColor = value;
-        OnYAxisDescriptorChanged();
-      }
-    }
-
-    public void AddDataRow(IDataRow row) {
-      if (row.YAxis != null) {
-        row.YAxis.DataRows.Remove(row);
-      }
-      this.DataRows.Add(row);
-      OnYAxisDescriptorChanged();
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Visualization/ZoomListener.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization/ZoomListener.cs	(revision 1528)
+++ 	(revision )
@@ -1,67 +1,0 @@
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace HeuristicLab.Visualization {
-  public class ZoomListener : IMouseEventListener {
-    private readonly Point startPoint;
-
-    public event RectangleHandler DrawRectangle;
-    public event RectangleHandler SetClippingArea;
-
-    public ZoomListener(Point startPoint) {
-      this.startPoint = startPoint;
-    }
-
-    #region IMouseEventListener Members
-
-    public void MouseMove(object sender, MouseEventArgs e) {
-      if(DrawRectangle != null) {
-        DrawRectangle(CalcRectangle(e.Location));
-      }
-    }
-
-    public void MouseUp(object sender, MouseEventArgs e) {
-     if(SetClippingArea != null) {
-       SetClippingArea(CalcRectangle(e.Location));
-     }
-    }
-
-    #endregion
-
-    private Rectangle CalcRectangle(Point actualPoint) {
-      Rectangle rectangle = new Rectangle();
-
-      if (startPoint.X < actualPoint.X) {
-        rectangle.X = startPoint.X;
-        rectangle.Width = actualPoint.X - startPoint.X;
-      } else {
-        rectangle.X = actualPoint.X;
-        rectangle.Width = startPoint.X - actualPoint.X;
-      }
-
-      if (startPoint.Y < actualPoint.Y) {
-        rectangle.Y = startPoint.Y;
-        rectangle.Height = actualPoint.Y - startPoint.Y;
-      } else {
-        rectangle.Y = actualPoint.Y;
-        rectangle.Height = startPoint.Y - actualPoint.Y;
-      }
-
-      return rectangle;
-    }
-
-    public static RectangleD ZoomClippingArea(RectangleD clippingArea, double zoomFactor) {
-      double x1, x2, y1, y2, width, height;
-
-      width = clippingArea.Width * zoomFactor;
-      height = clippingArea.Height * zoomFactor;
-
-      x1 = clippingArea.X1 - (width - clippingArea.Width) / 2;
-      y1 = clippingArea.Y1 - (height - clippingArea.Height) / 2;
-      x2 = width + x1;
-      y2 = height + y1;
-
-      return new RectangleD(x1, y1, x2, y2);
-    }
-  }
-}
