Index: /trunk/sources/HeuristicLab.Visualization.Test/LineChartTestForm.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization.Test/LineChartTestForm.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization.Test/LineChartTestForm.cs	(revision 1350)
@@ -4,4 +4,6 @@
 
 namespace HeuristicLab.Visualization.Test {
+  public delegate void AddValueHandler();
+
   public partial class LineChartTestForm : Form {
     private readonly IView view;
@@ -29,9 +31,15 @@
     }
 
+    public event AddValueHandler AddValue;
+
     private void btnAddRandomValue_Click(object sender, EventArgs e) {
-      Random rand = new Random();
+      if (AddValue != null) {
+        AddValue();
+      } else {
+        Random rand = new Random();
 
-      foreach (IDataRow row in model.Rows)
-        row.AddValue(rand.NextDouble()*100);
+        foreach (IDataRow row in model.Rows)
+          row.AddValue(rand.NextDouble() * 100);
+      }
     }
   }
Index: /trunk/sources/HeuristicLab.Visualization.Test/LineChartTests.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization.Test/LineChartTests.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization.Test/LineChartTests.cs	(revision 1350)
@@ -77,4 +77,5 @@
       IDataRow row1 = new DataRow();
       IDataRow row2 = new DataRow();
+      IDataRow row3 = new DataRow();
 
       row1.Color = Color.Red;
@@ -88,13 +89,27 @@
       row2.Label = "Die Grüne";
 
+      row3.Color = Color.Blue;
+      row3.Thickness = 3;
+      row3.Style = DrawingStyle.Solid;
+      row3.Label = "Die Blaue";
+      row3.YAxis = new YAxisDescriptor();
+
       model.AddDataRow(row1);
       model.AddDataRow(row2);
+      model.AddDataRow(row3);
 
       Random rand = new Random(42);
-      
+
       for (int i = 0; i < 10; i++) {
         row1.AddValue(rand.NextDouble()*10);
         row2.AddValue(rand.NextDouble()*10);
+        row3.AddValue(rand.NextDouble()*1);
       }
+
+      f.AddValue += delegate {
+        row1.AddValue(rand.NextDouble()*10);
+        row2.AddValue(rand.NextDouble()*10);
+        row3.AddValue(rand.NextDouble()*1);
+      };
 
       f.ShowDialog();
@@ -114,5 +129,5 @@
 
 
-      IAggregator aggregator = new MinAggregator();
+      MinAggregator aggregator = new MinAggregator();
       aggregator.Label = "MinAggregator";
       aggregator.Color = Color.Pink;
@@ -173,5 +188,5 @@
 
 
-        IAggregator aggregator = new MinAggregator();
+        MinAggregator aggregator = new MinAggregator();
         aggregator.Label = "MinAggregator";
         aggregator.Color = Color.Pink;
@@ -182,5 +197,5 @@
         model.AddDataRow(aggregator);
 
-        IAggregator maxAggregator = new MaxAggregator();
+        MaxAggregator maxAggregator = new MaxAggregator();
         maxAggregator.Label = "MaxAggregator";
         maxAggregator.Color = Color.DeepSkyBlue;
@@ -192,5 +207,5 @@
         
         
-        IAggregator avgAggregator = new AvgAggregator();
+        AvgAggregator avgAggregator = new AvgAggregator();
         avgAggregator.Label = "AvgAggregator";
         avgAggregator.Color = Color.Violet;
@@ -201,5 +216,5 @@
         model.AddDataRow(avgAggregator);
 
-        IAggregator multiAvgAggregator = new AvgAggregator();
+        AvgAggregator multiAvgAggregator = new AvgAggregator();
         multiAvgAggregator.Label = "MultiAvgAggregator";
         multiAvgAggregator.Color = Color.DarkOliveGreen;
@@ -211,5 +226,5 @@
         model.AddDataRow(multiAvgAggregator);
 
-        IAggregator multiMaxAggregator = new MaxAggregator();
+        MaxAggregator multiMaxAggregator = new MaxAggregator();
         multiMaxAggregator.Label = "MultiMaxAggregator";
         multiMaxAggregator.Color = Color.DarkKhaki;
@@ -221,5 +236,5 @@
         model.AddDataRow(multiMaxAggregator);
 
-        IAggregator multiMinAggregator = new MinAggregator();
+        MinAggregator multiMinAggregator = new MinAggregator();
         multiMinAggregator.Label = "MultiMinAggregator";
         multiMinAggregator.Color = Color.DarkRed;
@@ -231,5 +246,5 @@
         model.AddDataRow(multiMinAggregator);
 
-        IAggregator multiLineAvgAggregator = new AvgLineAggregator();
+        AvgLineAggregator multiLineAvgAggregator = new AvgLineAggregator();
         multiLineAvgAggregator.Label = "MultiLineAvgAggregator";
         multiLineAvgAggregator.Color = Color.Red;
Index: /trunk/sources/HeuristicLab.Visualization/AvgAggregator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/AvgAggregator.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/AvgAggregator.cs	(revision 1350)
@@ -1,10 +1,7 @@
 ﻿using System;
 using System.Collections.Generic;
-using System.Drawing;
 
 namespace HeuristicLab.Visualization {
-  public class AvgAggregator : IAggregator {
-
-
+  public class AvgAggregator : DataRowBase {
     #region IAggregator Members
 
@@ -17,5 +14,4 @@
 
     public void RemoveWatch(IDataRow dataRow) {
-
       dataRowWatches.Remove(dataRow);
       dataRow.DataRowChanged -= dataRow_DataRowChanged;
@@ -24,15 +20,14 @@
     }
 
-
     #endregion
 
-    List<IDataRow> dataRowWatches = new List<IDataRow>();
-    double curAvgValue;
+    private List<IDataRow> dataRowWatches = new List<IDataRow>();
+    private double curAvgValue;
 
-    void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
+    private void dataRow_ValueChanged(IDataRow row, double value, int index, Action action) {
       refreshValue(value);
     }
 
-    void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
+    private void dataRow_ValuesChanged(IDataRow row, double[] values, int index, Action action) {
       for (int i = 0; i < values.Length; i++) {
         refreshValue(values[i]);
@@ -40,5 +35,5 @@
     }
 
-    void dataRow_DataRowChanged(IDataRow row) {
+    private void dataRow_DataRowChanged(IDataRow row) {
       refreshValue(double.MinValue);
     }
@@ -50,5 +45,5 @@
       double tmpSum = 0;
       int count = 0;
-      foreach (var rows in dataRowWatches) {
+      foreach (IDataRow rows in dataRowWatches) {
         for (int i = 0; i < rows.Count; i++) {
           tmpSum += rows[i];
@@ -63,145 +58,51 @@
     #region IDataRow Members
 
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
-
-
-    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);
-      }
-    }
-
-    private bool showYAxis = false;
-
-    public bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public LabelProvider.ILabelProvider YAxisLabelProvider {
-      get {
-        throw new NotImplementedException();
-      }
-      set {
-        throw new NotImplementedException();
-      }
-    }
-
-    public void AddValue(double value) {
+    public override void AddValue(double value) {
       throw new NotSupportedException();
     }
 
-    public void AddValue(double value, int index) {
+    public override void AddValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values) {
+    public override void AddValues(double[] values) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values, int index) {
+    public override void AddValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValue(double value, int index) {
+    public override void ModifyValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValues(double[] values, int index) {
+    public override void ModifyValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValue(int index) {
+    public override void RemoveValue(int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValues(int index, int count) {
+    public override void RemoveValues(int index, int count) {
       throw new NotSupportedException();
     }
 
-    public int Count {
+    public override int Count {
       get { return 1; }
     }
 
-    public double this[int index] {
-      get {
-        return curAvgValue;
-      }
-      set {
-        throw new NotSupportedException();
-      }
+    public override double this[int index] {
+      get { return curAvgValue; }
+      set { throw new NotSupportedException(); }
     }
 
-    public double MinValue {
-      get { throw new System.NotImplementedException(); }
+    public override double MinValue {
+      get { return curAvgValue; }
     }
 
-    public double MaxValue {
-      get { throw new System.NotImplementedException(); }
-    }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    public event ValueChangedHandler ValueChanged;
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-
-    public event DataRowChangedHandler DataRowChanged;
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
+    public override double MaxValue {
+      get { return curAvgValue; }
     }
 
Index: /trunk/sources/HeuristicLab.Visualization/AvgLineAggregator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/AvgLineAggregator.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/AvgLineAggregator.cs	(revision 1350)
@@ -1,8 +1,7 @@
 ﻿using System;
 using System.Collections.Generic;
-using System.Drawing;
 
 namespace HeuristicLab.Visualization {
-  public class AvgLineAggregator : IAggregator {
+  public class AvgLineAggregator : DataRowBase {
 
     private readonly List<double> dataRow = new List<double>();
@@ -77,109 +76,42 @@
     #region IDataRow Members
 
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
-
-
-    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);
-      }
-    }
-
-
-    private bool showYAxis = false;
-
-    public bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public LabelProvider.ILabelProvider YAxisLabelProvider {
-      get {
-        throw new NotImplementedException();
-      }
-      set {
-        throw new NotImplementedException();
-      }
-    }
-
-    public void AddValue(double value) {
+    public override void AddValue(double value) {
       dataRow.Add(value);
       OnValueChanged(value, dataRow.Count - 1, Action.Added);
     }
 
-    public void AddValue(double value, int index) {
-      throw new System.NotImplementedException();
+    public override void AddValue(double value, int index) {
+      throw new NotImplementedException();
     }
 
-    public void AddValues(double[] values) {
+    public override void AddValues(double[] values) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values, int index) {
+    public override void AddValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValue(double value, int index) {
+    public override void ModifyValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValues(double[] values, int index) {
+    public override void ModifyValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValue(int index) {
+    public override void RemoveValue(int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValues(int index, int count) {
+    public override void RemoveValues(int index, int count) {
       throw new NotSupportedException();
     }
 
-    public int Count {
+    public override int Count {
       get { return dataRowWatches.Count; }
     }
 
-    public double this[int index] {
+    public override double this[int index] {
       get { return dataRow[index]; }
       set {
@@ -189,34 +121,12 @@
     }
 
-    public double MinValue {
-      get { throw new System.NotImplementedException(); }
+    // TODO calculate min value
+    public override double MinValue {
+      get { return 0; }
     }
 
-    public double MaxValue {
-      get { throw new System.NotImplementedException(); }
-    }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    public event ValueChangedHandler ValueChanged;
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-
-    public event DataRowChangedHandler DataRowChanged;
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
+    // TODO calculate max value
+    public override double MaxValue {
+      get { return 0; }
     }
 
Index: /trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs	(revision 1350)
@@ -28,4 +28,16 @@
     }
 
+    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>();
@@ -111,5 +123,10 @@
     //}
 
+    private readonly YAxisDescriptor defaultYAxisDescriptor = new YAxisDescriptor();
+
     public void AddDataRow(IDataRow row) {
+      if (row.YAxis == null) {
+        row.YAxis = defaultYAxisDescriptor;
+      }
       rows.Add(row);
       OnDataRowAdded(row);
Index: /trunk/sources/HeuristicLab.Visualization/DataRow.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/DataRow.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/DataRow.cs	(revision 1350)
@@ -15,33 +15,10 @@
   public delegate void ValueChangedHandler(IDataRow row, double value, int index, Action action);
 
-  public class DataRow : IDataRow {
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
+  public class DataRow : DataRowBase {
     private readonly List<double> dataRow = new List<double>();
-
-    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.##");
 
     // TODO implement calculation of min and max values
     private double minValue = double.MaxValue;
     private double maxValue = double.MinValue;
-
-    public DataRowType LineType{
-      get { return lineType; }
-      set { 
-        lineType = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public ILabelProvider YAxisLabelProvider {
-      get { return labelProvider; }
-      set {
-        this.labelProvider = value;
-        OnDataRowChanged(this);
-      }
-    }
 
     public DataRow() {
@@ -60,72 +37,5 @@
     }
 
-    public event DataRowChangedHandler DataRowChanged;
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
-    }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    public event ValueChangedHandler ValueChanged;
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-  
-    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);
-      }
-    }
-
-    private bool showYAxis = true;
-
-    public virtual bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public void AddValue(double value) {
+    public override void AddValue(double value) {
       UpdateMinMaxValue(value);
 
@@ -134,5 +44,5 @@
     }
 
-    public void AddValue(double value, int index) {
+    public override void AddValue(double value, int index) {
       //check if index is valid
       if (index >= 0 && index < dataRow.Count) {
@@ -144,5 +54,5 @@
     }
 
-    public void AddValues(double[] values) {
+    public override void AddValues(double[] values) {
       int startInd = dataRow.Count;
 
@@ -153,5 +63,5 @@
     }
 
-    public void AddValues(double[] values, int index) {
+    public override void AddValues(double[] values, int index) {
       int j = index;
 
@@ -168,5 +78,5 @@
     }
 
-    public void ModifyValue(double value, int index) {
+    public override void ModifyValue(double value, int index) {
       //check if index is valid
       if (index >= 0 && index < dataRow.Count) {
@@ -178,5 +88,5 @@
     }
 
-    public void ModifyValues(double[] values, int index) {
+    public override void ModifyValues(double[] values, int index) {
       int startInd = index;
       int modInd = index;
@@ -194,5 +104,5 @@
     }
 
-    public void RemoveValue(int index) {
+    public override void RemoveValue(int index) {
       double remVal = dataRow[index];
       //check if index is valid
@@ -205,5 +115,5 @@
     }
 
-    public void RemoveValues(int index, int count) {
+    public override void RemoveValues(int index, int count) {
       double[] remValues = new double[count]; //removed values
       int j = 0;
@@ -227,9 +137,9 @@
     }
 
-    public int Count {
+    public override int Count {
       get { return dataRow.Count; }
     }
 
-    public double this[int index] {
+    public override double this[int index] {
       get { return dataRow[index]; }
       set {
@@ -239,9 +149,9 @@
     }
 
-    public double MinValue {
+    public override double MinValue {
       get { return minValue; }
     }
 
-    public double MaxValue {
+    public override double MaxValue {
       get { return maxValue; }
     }
Index: /trunk/sources/HeuristicLab.Visualization/DataRowBase.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/DataRowBase.cs	(revision 1350)
+++ /trunk/sources/HeuristicLab.Visualization/DataRowBase.cs	(revision 1350)
@@ -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/HeuristicLab.Visualization.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/HeuristicLab.Visualization.csproj	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/HeuristicLab.Visualization.csproj	(revision 1350)
@@ -4,5 +4,5 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{E392A1E2-DC95-4E33-B82E-8ED690EDA1AB}</ProjectGuid>
@@ -84,5 +84,5 @@
     <Compile Include="CompositeShape.cs" />
     <Compile Include="ChartDataRowsModelDataCollector.cs" />
-    <Compile Include="IAggregator.cs" />
+    <Compile Include="DataRowBase.cs" />
     <Compile Include="LabelProvider\ContinuousLabelProvider.cs" />
     <Compile Include="LabelProvider\DiscreteLabelProvider.cs" />
@@ -130,4 +130,5 @@
     <Compile Include="XAxis.cs" />
     <Compile Include="YAxis.cs" />
+    <Compile Include="YAxisDescriptor.cs" />
     <Compile Include="ZoomListener.cs" />
   </ItemGroup>
Index: unk/sources/HeuristicLab.Visualization/IAggregator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/IAggregator.cs	(revision 1349)
+++ 	(revision )
@@ -1,11 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace HeuristicLab.Visualization {
-  public interface IAggregator : IDataRow {
-    void AddWatch(IDataRow dataRow);
-    void RemoveWatch(IDataRow dataRow);
-  }
-}
Index: /trunk/sources/HeuristicLab.Visualization/IChartDataRowsModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/IChartDataRowsModel.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/IChartDataRowsModel.cs	(revision 1350)
@@ -7,20 +7,11 @@
   public interface IChartDataRowsModel : IItem {
     string Title { get; set; }
-    //string XAxisLabel { get; set; }
-    //List<string> XLabels { get; }
     List<IDataRow> Rows { get; }
     ILabelProvider XAxisLabelProvider { get; set; }
 
+    List<YAxisDescriptor> YAxes { get; }
+
     void AddDataRow(IDataRow row);
     void RemoveDataRow(IDataRow row);
-
-    //void AddLabel(string label);
-    //void AddLabel(string label, int index);
-    //void AddLabels(string[] labels);
-    //void AddLabels(string[] labels, int index);
-    //void ModifyLabel(string label, int index);
-    //void ModifyLabels(string[] labels, int index);
-    //void RemoveLabel(int index);
-    //void RemoveLabels(int index, int count);
 
     int MaxDataRowValues { get; }
Index: /trunk/sources/HeuristicLab.Visualization/IDataRow.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/IDataRow.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/IDataRow.cs	(revision 1350)
@@ -1,7 +1,5 @@
 using System.Drawing;
-using HeuristicLab.Visualization.LabelProvider;
 
 namespace HeuristicLab.Visualization {
-
   public enum DataRowType {
     Normal, SingleValue
@@ -15,10 +13,5 @@
     DataRowType LineType { get; set; }
  
-    bool ShowYAxis { get; set; }
-    ILabelProvider YAxisLabelProvider { get; set; }
-
-    /// <summary>
-    /// Raised when data row data changed. Should cause redraw in the view.
-    /// </summary>
+    YAxisDescriptor YAxis { get; set; }
 
     void AddValue(double value);
Index: /trunk/sources/HeuristicLab.Visualization/LineChart.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/LineChart.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/LineChart.cs	(revision 1350)
@@ -29,7 +29,4 @@
     private const int XAxisHeight = 20;
 
-    private bool zoomToFullView;
-
-
     /// <summary>
     /// This constructor shouldn't be called. Only required for the designer.
@@ -86,6 +83,7 @@
       canvas.ClearShapes();
 
-      foreach (RowEntry rowEntry in rowEntries) {
-        canvas.AddShape(rowEntry.Grid);
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        canvas.AddShape(info.Grid);
       }
 
@@ -98,7 +96,8 @@
       int yAxesWidth = 0;
 
-      foreach (RowEntry rowEntry in rowEntries) {
-        if (rowEntry.DataRow.ShowYAxis) {
-          canvas.AddShape(rowEntry.YAxis);
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        if (yAxisDescriptor.ShowYAxis) {
+          canvas.AddShape(info.YAxis);
           yAxesWidth += YAxisWidth;
         }
@@ -120,14 +119,19 @@
       foreach (RowEntry rowEntry in rowEntries) {
         rowEntry.LinesShape.BoundingBox = linesAreaBoundingBox;
-        rowEntry.Grid.BoundingBox = linesAreaBoundingBox;
+      }
+
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        info.Grid.BoundingBox = linesAreaBoundingBox;
       }
 
       int yAxisLeft = 0;
-      foreach (RowEntry rowEntry in rowEntries) {
-        if (rowEntry.DataRow.ShowYAxis) {
-          rowEntry.YAxis.BoundingBox = new RectangleD(yAxisLeft,
-                                                      linesAreaBoundingBox.Y1,
-                                                      yAxisLeft + YAxisWidth,
-                                                      linesAreaBoundingBox.Y2);
+      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
+        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
+        if (yAxisDescriptor.ShowYAxis) {
+          info.YAxis.BoundingBox = new RectangleD(yAxisLeft,
+                                                 linesAreaBoundingBox.Y1,
+                                                 yAxisLeft + YAxisWidth,
+                                                 linesAreaBoundingBox.Y2);
           yAxisLeft += YAxisWidth;
         }
@@ -143,4 +147,23 @@
 
       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;
+    }
+
+    private void UpdateYAxisInfo(YAxisDescriptor yAxisDescriptor) {
+//      if (yAxisInfos.ContainsKey(yAxisDescriptor)) {
+//        yAxisInfos.Remove(yAxisDescriptor);
+//      }
     }
 
@@ -206,5 +229,4 @@
     private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
       OptionsDialog optionsdlg = new OptionsDialog(model);
-      //var optionsdlg = new OptionsDialog(model, this);
       optionsdlg.ShowDialog(this);
       Invalidate();
@@ -212,4 +234,6 @@
 
     public void OnDataRowChanged(IDataRow row) {
+      UpdateYAxisInfo(row.YAxis);
+
       RowEntry rowEntry = rowToRowEntry[row];
 
@@ -273,12 +297,10 @@
 
       foreach (RowEntry rowEntry in rowEntries) {
-        IDataRow row = rowEntry.DataRow;
+        YAxisDescriptor yAxisDescriptor = rowEntry.DataRow.YAxis;
 
         SetClipY(rowEntry,
-                 row.MinValue - ((row.MaxValue - row.MinValue)*0.05),
-                 row.MaxValue + ((row.MaxValue - row.MinValue)*0.05));
-      }
-
-      zoomToFullView = true;
+                 yAxisDescriptor.MinValue - ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05),
+                 yAxisDescriptor.MaxValue + ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05));
+      }
 
       canvasUI.Invalidate();
@@ -296,28 +318,35 @@
                                                           x2,
                                                           rowEntry.LinesShape.ClippingArea.Y2);
-        rowEntry.Grid.ClippingArea = new RectangleD(x1,
-                                                    rowEntry.Grid.ClippingArea.Y1,
-                                                    x2,
-                                                    rowEntry.Grid.ClippingArea.Y2);
-        rowEntry.YAxis.ClippingArea = new RectangleD(0,
-                                                     rowEntry.YAxis.ClippingArea.Y1,
-                                                     YAxisWidth,
-                                                     rowEntry.YAxis.ClippingArea.Y2);
-      }
-    }
-
-    private static void SetClipY(RowEntry rowEntry, double y1, double 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);
-      rowEntry.Grid.ClippingArea = new RectangleD(rowEntry.Grid.ClippingArea.X1,
-                                                  y1,
-                                                  rowEntry.Grid.ClippingArea.X2,
-                                                  y2);
-      rowEntry.YAxis.ClippingArea = new RectangleD(rowEntry.YAxis.ClippingArea.X1,
-                                                   y1,
-                                                   rowEntry.YAxis.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);
     }
 
@@ -418,6 +447,4 @@
 
     private void Pan(Point startPoint, Point endPoint) {
-      zoomToFullView = false;
-
       foreach (RowEntry rowEntry in rowEntries) {
         RectangleD clippingArea = CalcPanClippingArea(startPoint, endPoint, rowEntry.LinesShape);
@@ -431,6 +458,4 @@
 
     private void PanEnd(Point startPoint, Point endPoint) {
-      zoomToFullView = false;
-
       foreach (RowEntry rowEntry in rowEntries) {
         RectangleD clippingArea = CalcPanClippingArea(startPoint, endPoint, rowEntry.LinesShape);
@@ -552,15 +577,22 @@
       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();
-      private readonly LinesShape linesShape = new LinesShape();
-
-      public RowEntry(IDataRow dataRow) {
-        this.dataRow = dataRow;
-      }
-
-      public IDataRow DataRow {
-        get { return dataRow; }
-      }
 
       public Grid Grid {
@@ -571,8 +603,4 @@
         get { return yAxis; }
       }
-
-      public LinesShape LinesShape {
-        get { return linesShape; }
-      }
     }
   }
Index: /trunk/sources/HeuristicLab.Visualization/MaxAggregator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/MaxAggregator.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/MaxAggregator.cs	(revision 1350)
@@ -4,7 +4,5 @@
 
 namespace HeuristicLab.Visualization {
-  public class MaxAggregator : IAggregator {
-    
-    
+  public class MaxAggregator : DataRowBase {
     #region IAggregator Members
 
@@ -51,5 +49,5 @@
       } else {
         curMaxValue = double.MinValue;
-        foreach (var rows in dataRowWatches) {
+        foreach (IDataRow rows in dataRowWatches) {
           for (int i = 0; i < rows.Count; i++) {
             if (rows[i] > curMaxValue) {
@@ -65,108 +63,41 @@
 
     #region IDataRow Members
-
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
-
-
-    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);
-      }
-    }
-
-    private bool showYAxis = false;
-
-    public bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public LabelProvider.ILabelProvider YAxisLabelProvider {
-      get {
-        throw new NotImplementedException();
-      }
-      set {
-        throw new NotImplementedException();
-      }
-    }
-
-    public void AddValue(double value) {
+    public override void AddValue(double value) {
       OnValueChanged(2, 0, Action.Added);
     }
 
-    public void AddValue(double value, int index) {
+    public override void AddValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values) {
+    public override void AddValues(double[] values) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values, int index) {
+    public override void AddValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValue(double value, int index) {
+    public override void ModifyValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValues(double[] values, int index) {
+    public override void ModifyValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValue(int index) {
+    public override void RemoveValue(int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValues(int index, int count) {
+    public override void RemoveValues(int index, int count) {
       throw new NotSupportedException();
     }
 
-    public int Count {
+    public override int Count {
       get { return 1; }
     }
 
-    public double this[int index] {
+    public override double this[int index] {
       get {
         return curMaxValue;
@@ -177,34 +108,10 @@
     }
 
-    public double MinValue {
-      get { throw new System.NotImplementedException(); }
+    public override double MinValue {
+      get { return curMaxValue; }
     }
 
-    public double MaxValue {
-      get { throw new System.NotImplementedException(); }
-    }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    public event ValueChangedHandler ValueChanged;
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-
-    public event DataRowChangedHandler DataRowChanged;
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
+    public override double MaxValue {
+      get { return curMaxValue; }
     }
 
Index: /trunk/sources/HeuristicLab.Visualization/MinAggregator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/MinAggregator.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/MinAggregator.cs	(revision 1350)
@@ -1,9 +1,7 @@
 ﻿using System;
 using System.Collections.Generic;
-using System.Drawing;
-using HeuristicLab.Visualization.LabelProvider;
 
 namespace HeuristicLab.Visualization {
-  public class MinAggregator : IAggregator {
+  public class MinAggregator : DataRowBase {
     #region IAggregator Members
 
@@ -50,5 +48,5 @@
       } else {
         curMinValue = double.MaxValue;
-        foreach (var rows in dataRowWatches) {
+        foreach (IDataRow rows in dataRowWatches) {
           for (int i = 0; i < rows.Count; i++) {
             if (rows[i] < curMinValue) {
@@ -65,108 +63,41 @@
     #region IDataRow Members
 
-    private string label = "";
-    private Color color = Color.Black;
-    private int thickness = 2;
-    private DrawingStyle style = DrawingStyle.Solid;
-    private DataRowType lineType = DataRowType.Normal;
-
-
-    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);
-      }
-    }
-
-
-    private bool showYAxis = false;
-
-    public bool ShowYAxis {
-      get { return showYAxis; }
-      set {
-        showYAxis = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    private ILabelProvider labelProvider = new ContinuousLabelProvider("0.##");
-    public ILabelProvider YAxisLabelProvider {
-      get { return labelProvider; }
-      set {
-        this.labelProvider = value;
-        OnDataRowChanged(this);
-      }
-    }
-
-    public void AddValue(double value) {
+    public override void AddValue(double value) {
       OnValueChanged(2, 0, Action.Added);
     }
 
-    public void AddValue(double value, int index) {
+    public override void AddValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values) {
+    public override void AddValues(double[] values) {
       throw new NotSupportedException();
     }
 
-    public void AddValues(double[] values, int index) {
+    public override void AddValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValue(double value, int index) {
+    public override void ModifyValue(double value, int index) {
       throw new NotSupportedException();
     }
 
-    public void ModifyValues(double[] values, int index) {
+    public override void ModifyValues(double[] values, int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValue(int index) {
+    public override void RemoveValue(int index) {
       throw new NotSupportedException();
     }
 
-    public void RemoveValues(int index, int count) {
+    public override void RemoveValues(int index, int count) {
       throw new NotSupportedException();
     }
 
-    public int Count {
+    public override int Count {
       get { return 1; }
     }
 
-    public double this[int index] {
+    public override double this[int index] {
       get {
         return curMinValue;
@@ -177,34 +108,10 @@
     }
 
-    public double MinValue {
-      get { throw new System.NotImplementedException(); }
+    public override double MinValue {
+      get { return curMinValue; }
     }
 
-    public double MaxValue {
-      get { throw new System.NotImplementedException(); }
-    }
-
-    public event ValuesChangedHandler ValuesChanged;
-
-    protected void OnValuesChanged(double[] values, int index, Action action) {
-      if (ValuesChanged != null) {
-        ValuesChanged(this, values, index, action);
-      }
-    }
-
-    public event ValueChangedHandler ValueChanged;
-
-    protected void OnValueChanged(double value, int index, Action action) {
-      if (ValueChanged != null) {
-        ValueChanged(this, value, index, action);
-      }
-    }
-
-    public event DataRowChangedHandler DataRowChanged;
-
-    protected void OnDataRowChanged(IDataRow row) {
-      if (DataRowChanged != null) {
-        DataRowChanged(this);
-      }
+    public override double MaxValue {
+      get { return curMinValue; }
     }
 
Index: /trunk/sources/HeuristicLab.Visualization/Options/OptionsDialog.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/Options/OptionsDialog.cs	(revision 1349)
+++ /trunk/sources/HeuristicLab.Visualization/Options/OptionsDialog.cs	(revision 1350)
@@ -52,11 +52,11 @@
 
     private void InitTabPageYAxes() {
-      for (int i = 0; i < model.Rows.Count; i++) {
-        IDataRow row = model.Rows[i];
+      for (int i = 0; i < model.YAxes.Count; i++) {
+        YAxisDescriptor yAxisDescriptor = model.YAxes[i];
 
         CheckBox chkbox = new CheckBox();
-        chkbox.Text = row.Label;
-        chkbox.Checked = row.ShowYAxis;
-        chkbox.CheckedChanged += delegate { row.ShowYAxis = chkbox.Checked; };
+        chkbox.Text = yAxisDescriptor.Label;
+        chkbox.Checked = yAxisDescriptor.ShowYAxis;
+        chkbox.CheckedChanged += delegate { yAxisDescriptor.ShowYAxis = chkbox.Checked; };
         
         dataRowsFlowLayout.Controls.Add(chkbox);
Index: /trunk/sources/HeuristicLab.Visualization/YAxisDescriptor.cs
===================================================================
--- /trunk/sources/HeuristicLab.Visualization/YAxisDescriptor.cs	(revision 1350)
+++ /trunk/sources/HeuristicLab.Visualization/YAxisDescriptor.cs	(revision 1350)
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Visualization.LabelProvider;
+
+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 string label = "";
+
+    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 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 void AddDataRow(IDataRow row) {
+      if (row.YAxis != null) {
+        row.YAxis.DataRows.Remove(row);
+      }
+      this.DataRows.Add(row);
+      OnYAxisDescriptorChanged();
+    }
+  }
+}
