Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 4870)
@@ -67,4 +67,5 @@
       foreach (DataRow row in Content.Rows)
         DeregisterDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
       Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
       Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
@@ -80,4 +81,5 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
       Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
       Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
@@ -92,4 +94,7 @@
       invisibleSeries.Clear();
       chart.Titles[0].Text = string.Empty;
+      chart.ChartAreas[0].AxisX.Title = string.Empty;
+      chart.ChartAreas[0].AxisY.Title = string.Empty;
+      chart.ChartAreas[0].AxisY2.Title = string.Empty;
       chart.Series.Clear();
       if (Content != null) {
@@ -97,4 +102,7 @@
         foreach (DataRow row in Content.Rows)
           AddDataRow(row);
+        chart.ChartAreas[0].AxisX.Title = Content.VisualProperties.XAxisTitle;
+        chart.ChartAreas[0].AxisY.Title = Content.VisualProperties.YAxisTitle;
+        chart.ChartAreas[0].AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;
       }
     }
@@ -188,4 +196,13 @@
       }
     }
+    private void Content_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);
+      else {
+        chart.ChartAreas[0].AxisX.Title = Content.VisualProperties.XAxisTitle;
+        chart.ChartAreas[0].AxisY.Title = Content.VisualProperties.YAxisTitle;
+        chart.ChartAreas[0].AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;
+      }
+    }
     private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
       if (InvokeRequired)
Index: /trunk/sources/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalyzer.cs	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalyzer.cs	(revision 4870)
@@ -172,5 +172,7 @@
         if (!results.ContainsKey("Alleles")) {
           allelesTable = new DataTable("Alleles");
-          results.Add(new Result("Alleles", allelesTable));
+          allelesTable.VisualProperties.XAxisTitle = "Iteration";
+          allelesTable.VisualProperties.YAxisTitle = "Number of Alleles";
+          allelesTable.VisualProperties.SecondYAxisTitle = "Number of Alleles";
 
           allelesTable.Rows.Add(new DataRow("Unique Alleles"));
@@ -192,4 +194,6 @@
           allelesTable.Rows["Lost Alleles of Best Known Solution"].VisualProperties.SecondYAxis = true;
           allelesTable.Rows["Lost Alleles of Best Known Solution"].VisualProperties.StartIndexZero = true;
+
+          results.Add(new Result("Alleles", allelesTable));
         } else {
           allelesTable = (DataTable)results["Alleles"].Value;
Index: /trunk/sources/HeuristicLab.Analysis/3.3/DataRowVisualProperties.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/DataRowVisualProperties.cs	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/DataRowVisualProperties.cs	(revision 4870)
@@ -119,10 +119,4 @@
       startIndexZero = false;
     }
-    public DataRowVisualProperties(DataRowChartType chartType, bool secondYAxis, Color color, bool startIndexZero) {
-      this.chartType = chartType;
-      this.secondYAxis = secondYAxis;
-      this.color = color;
-      this.startIndexZero = startIndexZero;
-    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs	(revision 4870)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Drawing;
 using System.Linq;
@@ -41,5 +42,18 @@
     }
 
-    [Storable]
+    private DataTableVisualProperties visualProperties;
+    public DataTableVisualProperties VisualProperties {
+      get { return visualProperties; }
+      set {
+        if (visualProperties != value) {
+          if (value == null) throw new ArgumentNullException("VisualProperties");
+          if (visualProperties != null) visualProperties.PropertyChanged -= new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          visualProperties = value;
+          visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          OnVisualPropertiesChanged();
+        }
+      }
+    }
+
     private NamedItemCollection<DataRow> rows;
     public NamedItemCollection<DataRow> Rows {
@@ -47,30 +61,64 @@
     }
 
-    #region Storing & Cloning
+    #region Persistence Properties
+    [Storable(Name = "VisualProperties")]
+    private DataTableVisualProperties StorableVisualProperties {
+      get { return VisualProperties; }
+      set { VisualProperties = value; }
+    }
+    [Storable(Name = "rows")]
+    private IEnumerable<DataRow> StorableRows {
+      get { return rows; }
+      set { rows = new NamedItemCollection<DataRow>(value); }
+    }
+    #endregion
+
     [StorableConstructor]
     private DataTable(bool deserializing) : base(deserializing) { }
     private DataTable(DataTable original, Cloner cloner)
       : base(original, cloner) {
+      this.VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
       this.rows = cloner.Clone(original.rows);
       this.RegisterRowsEvents();
     }
+    public DataTable()
+      : base() {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<DataRow>();
+      this.RegisterRowsEvents();
+    }
+    public DataTable(string name)
+      : base(name) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<DataRow>();
+      this.RegisterRowsEvents();
+    }
+    public DataTable(string name, string description)
+      : base(name, description) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<DataRow>();
+      this.RegisterRowsEvents();
+    }
+
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (VisualProperties == null) VisualProperties = new DataTableVisualProperties();
+    }
+    #endregion
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new DataTable(this, cloner);
     }
-    #endregion
-    public DataTable()
-      : base() {
-      rows = new NamedItemCollection<DataRow>();
-      this.RegisterRowsEvents();
-    }
-    public DataTable(string name)
-      : base(name) {
-      rows = new NamedItemCollection<DataRow>();
-      this.RegisterRowsEvents();
-    }
-    public DataTable(string name, string description)
-      : base(name, description) {
-      rows = new NamedItemCollection<DataRow>();
-      this.RegisterRowsEvents();
+
+    public event EventHandler VisualPropertiesChanged;
+    private void OnVisualPropertiesChanged() {
+      EventHandler handler = VisualPropertiesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      OnVisualPropertiesChanged();
     }
 
Index: /trunk/sources/HeuristicLab.Analysis/3.3/DataTableVisualProperties.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/DataTableVisualProperties.cs	(revision 4870)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/DataTableVisualProperties.cs	(revision 4870)
@@ -0,0 +1,110 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.ComponentModel;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Visual properties of a DataTable.
+  /// </summary>
+  [StorableClass]
+  public class DataTableVisualProperties : DeepCloneable, INotifyPropertyChanged {
+    private string xAxisTitle;
+    public string XAxisTitle {
+      get { return xAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (xAxisTitle != value) {
+          xAxisTitle = value;
+          OnPropertyChanged("XAxisTitle");
+        }
+      }
+    }
+
+    private string yAxisTitle;
+    public string YAxisTitle {
+      get { return yAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (yAxisTitle != value) {
+          yAxisTitle = value;
+          OnPropertyChanged("YAxisTitle");
+        }
+      }
+    }
+
+    private string secondYAxisTitle;
+    public string SecondYAxisTitle {
+      get { return secondYAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (secondYAxisTitle != value) {
+          secondYAxisTitle = value;
+          OnPropertyChanged("SecondYAxisTitle");
+        }
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "XAxisTitle")]
+    private string StorableXAxisTitle {
+      get { return xAxisTitle; }
+      set { xAxisTitle = value; }
+    }
+    [Storable(Name = "YAxisTitle")]
+    private string StorableYAxisTitle {
+      get { return yAxisTitle; }
+      set { yAxisTitle = value; }
+    }
+    [Storable(Name = "SecondYAxisTitle")]
+    private string StorableSecondYAxisTitle {
+      get { return secondYAxisTitle; }
+      set { secondYAxisTitle = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataTableVisualProperties(bool deserializing) : base() { }
+    protected DataTableVisualProperties(DataTableVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      this.xAxisTitle = original.xAxisTitle;
+      this.yAxisTitle = original.yAxisTitle;
+      this.secondYAxisTitle = original.secondYAxisTitle;
+    }
+    public DataTableVisualProperties() {
+      this.xAxisTitle = string.Empty;
+      this.yAxisTitle = string.Empty;
+      this.secondYAxisTitle = string.Empty;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataTableVisualProperties(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      PropertyChangedEventHandler handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 4870)
@@ -118,4 +118,5 @@
     <Compile Include="Allele.cs" />
     <Compile Include="AlleleFrequency.cs" />
+    <Compile Include="DataTableVisualProperties.cs" />
     <Compile Include="DataTableHistory.cs" />
     <Compile Include="HeatMapHistory.cs" />
Index: /trunk/sources/HeuristicLab.Analysis/3.3/PopulationDiversityAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/PopulationDiversityAnalyzer.cs	(revision 4869)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/PopulationDiversityAnalyzer.cs	(revision 4870)
@@ -186,5 +186,6 @@
           if (!results.ContainsKey("Average Minimum/Average/Maximum Solution Similarity")) {
             minAvgMaxSimilarityDataTable = new DataTable("Average Minimum/Average/Maximum Solution Similarity");
-            results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
+            minAvgMaxSimilarityDataTable.VisualProperties.XAxisTitle = "Iteration";
+            minAvgMaxSimilarityDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
             minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Minimum Solution Similarity", null));
             minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].VisualProperties.StartIndexZero = true;
@@ -193,4 +194,5 @@
             minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Maximum Solution Similarity", null));
             minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].VisualProperties.StartIndexZero = true;
+            results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
           } else {
             minAvgMaxSimilarityDataTable = (DataTable)results["Average Minimum/Average/Maximum Solution Similarity"].Value;
@@ -202,4 +204,6 @@
           // store minimum, average, maximum similarities data table
           DataTable minAvgMaxSimilaritiesDataTable = new DataTable("Minimum/Average/Maximum Solution Similarities");
+          minAvgMaxSimilaritiesDataTable.VisualProperties.XAxisTitle = "Solution Index";
+          minAvgMaxSimilaritiesDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
           minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Minimum Solution Similarity", null, minSimilarities));
           minAvgMaxSimilaritiesDataTable.Rows["Minimum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
