Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.Designer.cs	(revision 14734)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.Designer.cs	(revision 14734)
@@ -0,0 +1,75 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class GanttDataView {
+    /// <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.ganttChart = new HeuristicLab.Visualization.ChartControlsExtensions.GanttChart();
+      this.SuspendLayout();
+      // 
+      // ganttChart
+      // 
+      this.ganttChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.ganttChart.Location = new System.Drawing.Point(0, 0);
+      this.ganttChart.Name = "ganttChart";
+      this.ganttChart.Size = new System.Drawing.Size(367, 249);
+      this.ganttChart.TabIndex = 0;
+      // 
+      // GanttDataView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.ganttChart);
+      this.Name = "GanttDataView";
+      this.Size = new System.Drawing.Size(367, 249);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Visualization.ChartControlsExtensions.GanttChart ganttChart;
+  }
+}
Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.cs	(revision 14734)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/GanttDataView.cs	(revision 14734)
@@ -0,0 +1,166 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("Gantt Data View")]
+  [Content(typeof(GanttData), IsDefaultView = true)]
+  public partial class GanttDataView : ItemView {
+
+    public new GanttData Content {
+      get { return (GanttData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public GanttDataView() {
+      InitializeComponent();
+    }
+
+    #region De/Register Content Events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Rows.ItemsAdded += GanttRowsOnChanged;
+      Content.Rows.ItemsRemoved += GanttRowsOnRemoved;
+      Content.Rows.ItemsReplaced += GanttRowsOnChanged;
+      Content.Rows.CollectionReset += GanttRowsOnChanged;
+      foreach (var row in Content.Rows)
+        RegisterGanttRowEvents(row);
+    }
+
+    private void RegisterGanttRowEvents(GanttRow row) {
+      row.Items.ItemsAdded += GanttRowItemsOnChanged;
+      row.Items.ItemsReplaced += GanttRowItemsOnChanged;
+      row.Items.ItemsRemoved += GanttRowItemsOnRemoved;
+      row.Items.CollectionReset += GanttRowItemsOnChanged;
+      foreach (var item in row.Items)
+        RegisterGanttRowItemEvents(item);
+    }
+
+    private void RegisterGanttRowItemEvents(GanttItem item) {
+      item.PropertyChanged += GanttRowItemsItemOnChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.Rows.ItemsAdded -= GanttRowsOnChanged;
+      Content.Rows.ItemsRemoved -= GanttRowsOnRemoved;
+      Content.Rows.ItemsReplaced -= GanttRowsOnChanged;
+      Content.Rows.CollectionReset -= GanttRowsOnChanged;
+      foreach (var row in Content.Rows)
+        DeregisterGanttRowEvents(row);
+    }
+
+    private void DeregisterGanttRowEvents(GanttRow row) {
+      row.Items.ItemsAdded -= GanttRowItemsOnChanged;
+      row.Items.ItemsReplaced -= GanttRowItemsOnChanged;
+      row.Items.ItemsRemoved -= GanttRowItemsOnRemoved;
+      row.Items.CollectionReset -= GanttRowItemsOnChanged;
+      foreach (var item in row.Items)
+        DeregisterGanttRowItemEvents(item);
+    }
+
+    private void DeregisterGanttRowItemEvents(GanttItem item) {
+      item.PropertyChanged -= GanttRowItemsItemOnChanged;
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      UpdateVisualization();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      ganttChart.Enabled = !Locked && !ReadOnly && Content != null;
+    }
+
+    private void UpdateVisualization() {
+      ganttChart.Reset();
+
+      if (Content == null) return;
+
+      var colors = (KnownColor[])Enum.GetValues(typeof(KnownColor));
+
+      var categories = Content.Rows.SelectMany(x => x.Items.Select(y => y.Category ?? string.Empty)).Distinct();
+      foreach (var cat in categories) {
+        Color color;
+        if (!Content.CategoryColors.TryGetValue(cat, out color)) {
+          // if no color is defined, a random color is chosen for each category
+          var rand = new Random(cat.GetHashCode());
+          color = Color.FromKnownColor(colors[rand.Next(colors.Length)]);
+        }
+        ganttChart.AddCategory(cat, color);
+      }
+      
+      ganttChart.Hide();
+      foreach (var row in Content.Rows) {
+        foreach (var item in row.Items) {
+          ganttChart.AddData(row.Name, item.Category ?? string.Empty, item.StartDate, item.EndDate, item.ToolTip, item.ShowLabel);
+        }
+      }
+      ganttChart.Show();
+    }
+
+    #region Content Event Handlers
+    private void GanttRowsOnChanged(object sender, CollectionItemsChangedEventArgs<GanttRow> e) {
+      foreach (var row in e.Items)
+        RegisterGanttRowEvents(row);
+      foreach (var row in e.OldItems)
+        DeregisterGanttRowEvents(row);
+
+      UpdateVisualization();
+    }
+
+    private void GanttRowsOnRemoved(object sender, CollectionItemsChangedEventArgs<GanttRow> e) {
+      foreach (var row in e.Items)
+        DeregisterGanttRowEvents(row);
+
+      UpdateVisualization();
+    }
+    private void GanttRowItemsOnChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<GanttItem>> e) {
+      foreach (var item in e.Items)
+        RegisterGanttRowItemEvents(item.Value);
+      foreach (var item in e.OldItems)
+        DeregisterGanttRowItemEvents(item.Value);
+
+      UpdateVisualization();
+    }
+    private void GanttRowItemsOnRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<GanttItem>> e) {
+      foreach (var item in e.Items)
+        DeregisterGanttRowItemEvents(item.Value);
+
+      UpdateVisualization();
+    }
+    private void GanttRowItemsItemOnChanged(object sender, EventArgs e) {
+      UpdateVisualization();
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 14733)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 14734)
@@ -132,4 +132,10 @@
       <DependentUpon>DataTableControl.cs</DependentUpon>
     </Compile>
+    <Compile Include="GanttDataView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="GanttDataView.Designer.cs">
+      <DependentUpon>GanttDataView.cs</DependentUpon>
+    </Compile>
     <Compile Include="IndexedDataTableView.cs">
       <SubType>UserControl</SubType>
Index: /trunk/sources/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 14734)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 14734)
@@ -0,0 +1,180 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("Gantt Data", "Data of a Gantt visualization")]
+  [StorableClass]
+  public class GanttData : Item {
+
+    [Storable]
+    private NamedItemCollection<GanttRow> rows;
+    public NamedItemCollection<GanttRow> Rows { get { return rows; } }
+
+    [Storable]
+    private ObservableDictionary<string, Color> categoryColors;
+    public ObservableDictionary<string, Color> CategoryColors { get { return categoryColors; } }
+
+    [StorableConstructor]
+    protected GanttData(bool deserializing) : base(deserializing) {}
+    protected GanttData(GanttData original, Cloner cloner)
+      : base(original, cloner) {
+      rows = cloner.Clone(original.rows);
+      categoryColors = new ObservableDictionary<string, Color>(original.categoryColors);
+    }
+    public GanttData() {
+      rows = new NamedItemCollection<GanttRow>();
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+    public GanttData(IEnumerable<GanttRow> rows) {
+      this.rows = new NamedItemCollection<GanttRow>(rows);
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttData(this, cloner);
+    }
+  }
+
+  [Item("Gantt Row", "Row of a Gantt chart")]
+  [StorableClass]
+  public class GanttRow : NamedItem {
+    [Storable]
+    private ItemList<GanttItem> items;
+    public ItemList<GanttItem> Items { get { return items; } }
+
+    [StorableConstructor]
+    protected GanttRow(bool deserializing) : base(deserializing) {}
+    protected GanttRow(GanttRow original, Cloner cloner)
+      : base(original, cloner) {
+      items = cloner.Clone(original.items);
+    }
+    public GanttRow() {
+      items = new ItemList<GanttItem>();
+    }
+    public GanttRow(IEnumerable<GanttItem> items) {
+      this.items = new ItemList<GanttItem>(items);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttRow(this, cloner);
+    }
+  }
+
+  [Item("Gantt Item", "Item of a Gantt chart row")]
+  [StorableClass]
+  public class GanttItem : Item, INotifyPropertyChanged {
+
+    [Storable]
+    private DateTime startDate;
+    public DateTime StartDate {
+      get { return startDate; }
+      set {
+        if (startDate == value) return;
+        startDate = value;
+        OnPropertyChanged("StartDate");
+      }
+    }
+
+    [Storable]
+    private DateTime endDate;
+    public DateTime EndDate {
+      get { return endDate; }
+      set {
+        if (endDate == value) return;
+        endDate = value;
+        OnPropertyChanged("EndDate");
+      }
+    }
+
+    [Storable]
+    private string toolTip;
+    public string ToolTip {
+      get { return toolTip; }
+      set {
+        if (toolTip == value) return;
+        toolTip = value;
+        OnPropertyChanged("ToolTip");
+      }
+    }
+
+    [Storable]
+    private string category;
+    public string Category {
+      get { return category; }
+      set {
+        if (category == value) return;
+        category = value;
+        OnPropertyChanged("Category");
+      }
+    }
+
+    [Storable]
+    private bool showLabel;
+    public bool ShowLabel {
+      get { return showLabel; }
+      set {
+        if (showLabel == value) return;
+        showLabel = value;
+        OnPropertyChanged("ShowLabel");
+      }
+    }
+
+    [StorableConstructor]
+    protected GanttItem(bool deserializing) : base(deserializing) { }
+    protected GanttItem(GanttItem original, Cloner cloner)
+      : base(original, cloner) {
+      startDate = original.startDate;
+      endDate = original.endDate;
+      toolTip = original.toolTip;
+      category = original.category;
+      showLabel = original.showLabel;
+    }
+    public GanttItem() : this(DateTime.Now, DateTime.Now) { }
+    public GanttItem(DateTime start, DateTime end) {
+      startDate = start;
+      endDate = end;
+      toolTip = string.Empty;
+      category = string.Empty;
+      showLabel = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttItem(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      var 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 14733)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 14734)
@@ -131,4 +131,5 @@
     <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyCollectionHistory.cs" />
     <Compile Include="BestScopeSolutionAnalyzer.cs" />
+    <Compile Include="DataVisualization\GanttData.cs" />
     <Compile Include="DataVisualization\IndexedDataRow.cs" />
     <Compile Include="DataVisualization\IndexedDataTable.cs" />
