Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 9420)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 9421)
@@ -41,5 +41,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\..\..\..\Trunk\sources\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -60,5 +60,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -80,5 +80,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -102,64 +102,80 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Analysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="Microsoft.CSharp" />
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 9420)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 9421)
@@ -124,4 +124,5 @@
         this.categoricalMapping.Clear();
         UpdateDataPoints();
+        UpdateAxisLabels();
       }
     }
@@ -137,5 +138,4 @@
         this.Invoke(new EventHandler(run_Changed), sender, e);
       else if (!suppressUpdates) {
-        IRun run = (IRun)sender;
         UpdateDataPoints();
       }
@@ -326,11 +326,14 @@
     }
     private double GetCategoricalValue(int dimension, string value) {
-      if (!this.categoricalMapping.ContainsKey(dimension))
+      if (!this.categoricalMapping.ContainsKey(dimension)) {
         this.categoricalMapping[dimension] = new Dictionary<object, double>();
-      if (!this.categoricalMapping[dimension].ContainsKey(value)) {
-        if (this.categoricalMapping[dimension].Values.Count == 0)
-          this.categoricalMapping[dimension][value] = 1.0;
-        else
-          this.categoricalMapping[dimension][value] = this.categoricalMapping[dimension].Values.Max() + 1.0;
+        var orderedCategories = Content.Where(r=> r.Visible).Select(r => Content.GetValue(r, dimension).ToString())
+                                .Distinct()
+                                .OrderBy(x => x, new NaturalStringComparer());
+        int count = 1;
+        foreach (var category in orderedCategories) {
+          this.categoricalMapping[dimension].Add(category, count);
+          count++;
+        }
       }
       return this.categoricalMapping[dimension][value];
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 9420)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 9421)
@@ -65,5 +65,5 @@
       this.selectButton = new System.Windows.Forms.RadioButton();
       this.radioButtonGroup = new System.Windows.Forms.GroupBox();
-      this.colorButton = new System.Windows.Forms.Button();
+      this.colorDialogButton = new System.Windows.Forms.Button();
       this.colorDialog = new System.Windows.Forms.ColorDialog();
       this.tooltip = new System.Windows.Forms.ToolTip(this.components);
@@ -73,4 +73,8 @@
       this.sizeTrackBar = new System.Windows.Forms.TrackBar();
       this.getDataAsMatrixToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.transparencyTrackBar = new System.Windows.Forms.TrackBar();
+      this.transparencyLabel = new System.Windows.Forms.Label();
+      this.colorRunsButton = new System.Windows.Forms.Button();
+      this.hideRunsButton = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.xTrackBar)).BeginInit();
       ((System.ComponentModel.ISupportInitialize)(this.yTrackBar)).BeginInit();
@@ -78,4 +82,5 @@
       this.radioButtonGroup.SuspendLayout();
       ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).BeginInit();
       this.SuspendLayout();
       // 
@@ -254,23 +259,23 @@
       this.radioButtonGroup.Controls.Add(this.zoomButton);
       this.radioButtonGroup.Controls.Add(this.selectButton);
-      this.radioButtonGroup.Location = new System.Drawing.Point(3, 461);
+      this.radioButtonGroup.Location = new System.Drawing.Point(2, 461);
       this.radioButtonGroup.Name = "radioButtonGroup";
-      this.radioButtonGroup.Size = new System.Drawing.Size(135, 32);
+      this.radioButtonGroup.Size = new System.Drawing.Size(122, 32);
       this.radioButtonGroup.TabIndex = 19;
       this.radioButtonGroup.TabStop = false;
       // 
-      // colorButton
-      // 
-      this.colorButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.colorButton.Enabled = false;
-      this.colorButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.colorButton.Location = new System.Drawing.Point(144, 469);
-      this.colorButton.Name = "colorButton";
-      this.colorButton.Size = new System.Drawing.Size(64, 21);
-      this.colorButton.TabIndex = 20;
-      this.colorButton.Text = "Color";
-      this.colorButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
-      this.colorButton.UseVisualStyleBackColor = true;
-      this.colorButton.Click += new System.EventHandler(this.colorButton_Click);
+      // colorDialogButton
+      // 
+      this.colorDialogButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.colorDialogButton.Enabled = false;
+      this.colorDialogButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.colorDialogButton.Location = new System.Drawing.Point(130, 469);
+      this.colorDialogButton.Name = "colorDialogButton";
+      this.colorDialogButton.Size = new System.Drawing.Size(21, 21);
+      this.colorDialogButton.TabIndex = 20;
+      this.colorDialogButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.tooltip.SetToolTip(this.colorDialogButton, "Choose color");
+      this.colorDialogButton.UseVisualStyleBackColor = true;
+      this.colorDialogButton.Click += new System.EventHandler(this.colorDialogButton_Click);
       // 
       // colorDialog
@@ -318,14 +323,14 @@
       this.sizeTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
       this.sizeTrackBar.Location = new System.Drawing.Point(787, 3);
-      this.sizeTrackBar.Maximum = 50;
-      this.sizeTrackBar.Minimum = 5;
+      this.sizeTrackBar.Maximum = 20;
+      this.sizeTrackBar.Minimum = -20;
       this.sizeTrackBar.Name = "sizeTrackBar";
       this.sizeTrackBar.Size = new System.Drawing.Size(64, 45);
       this.sizeTrackBar.TabIndex = 24;
-      this.sizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
-      this.sizeTrackBar.Value = 10;
+      this.sizeTrackBar.TickFrequency = 20;
+      this.sizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
       this.sizeTrackBar.ValueChanged += new System.EventHandler(this.sizeTrackBar_ValueChanged);
       // 
-      // ToolStripMenuItem
+      // getDataAsMatrixToolStripMenuItem
       // 
       this.getDataAsMatrixToolStripMenuItem.Name = "getDataAsMatrixToolStripMenuItem";
@@ -334,15 +339,70 @@
       this.getDataAsMatrixToolStripMenuItem.Click += new System.EventHandler(this.getDataAsMatrixToolStripMenuItem_Click);
       // 
+      // transparencyTrackBar
+      // 
+      this.transparencyTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.transparencyTrackBar.LargeChange = 16;
+      this.transparencyTrackBar.Location = new System.Drawing.Point(359, 470);
+      this.transparencyTrackBar.Maximum = 254;
+      this.transparencyTrackBar.Name = "transparencyTrackBar";
+      this.transparencyTrackBar.Size = new System.Drawing.Size(64, 45);
+      this.transparencyTrackBar.TabIndex = 24;
+      this.transparencyTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
+      this.tooltip.SetToolTip(this.transparencyTrackBar, "Sets the transparency of the colors");
+      this.transparencyTrackBar.ValueChanged += new System.EventHandler(this.transparencyTrackBar_ValueChanged);
+      // 
+      // transparencyLabel
+      // 
+      this.transparencyLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.transparencyLabel.AutoSize = true;
+      this.transparencyLabel.Location = new System.Drawing.Point(278, 475);
+      this.transparencyLabel.Name = "transparencyLabel";
+      this.transparencyLabel.Size = new System.Drawing.Size(75, 13);
+      this.transparencyLabel.TabIndex = 12;
+      this.transparencyLabel.Text = "Transparency:";
+      // 
+      // colorRunsButton
+      // 
+      this.colorRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.colorRunsButton.Enabled = false;
+      this.colorRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.colorRunsButton.Location = new System.Drawing.Point(151, 469);
+      this.colorRunsButton.Name = "colorRunsButton";
+      this.colorRunsButton.Size = new System.Drawing.Size(43, 21);
+      this.colorRunsButton.TabIndex = 25;
+      this.colorRunsButton.Text = "Color";
+      this.colorRunsButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      this.tooltip.SetToolTip(this.colorRunsButton, "Color all selected runs");
+      this.colorRunsButton.UseVisualStyleBackColor = true;
+      this.colorRunsButton.Click += new System.EventHandler(this.colorRunsButton_Click);
+      // 
+      // hideRunsButton
+      // 
+      this.hideRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.hideRunsButton.Enabled = false;
+      this.hideRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.hideRunsButton.Location = new System.Drawing.Point(194, 469);
+      this.hideRunsButton.Name = "hideRunsButton";
+      this.hideRunsButton.Size = new System.Drawing.Size(43, 21);
+      this.hideRunsButton.TabIndex = 26;
+      this.hideRunsButton.Text = "Hide";
+      this.hideRunsButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      this.tooltip.SetToolTip(this.hideRunsButton, "Hides all selected runs");
+      this.hideRunsButton.UseVisualStyleBackColor = true;
+      this.hideRunsButton.Click += new System.EventHandler(this.hideRunsButton_Click);
+      // 
       // RunCollectionBubbleChartView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.BackColor = System.Drawing.SystemColors.Window;
       this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.Controls.Add(this.hideRunsButton);
+      this.Controls.Add(this.colorRunsButton);
+      this.Controls.Add(this.transparencyTrackBar);
       this.Controls.Add(this.sizeTrackBar);
       this.Controls.Add(this.colorYAxisButton);
       this.Controls.Add(this.colorXAxisButton);
       this.Controls.Add(this.noRunsLabel);
-      this.Controls.Add(this.colorButton);
+      this.Controls.Add(this.colorDialogButton);
       this.Controls.Add(this.radioButtonGroup);
       this.Controls.Add(this.chart);
@@ -350,4 +410,5 @@
       this.Controls.Add(this.sizeComboBox);
       this.Controls.Add(this.yJitterLabel);
+      this.Controls.Add(this.transparencyLabel);
       this.Controls.Add(this.xJitterlabel);
       this.Controls.Add(this.xTrackBar);
@@ -365,4 +426,5 @@
       this.radioButtonGroup.PerformLayout();
       ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).EndInit();
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -385,5 +447,5 @@
     private System.Windows.Forms.RadioButton selectButton;
     private System.Windows.Forms.GroupBox radioButtonGroup;
-    private System.Windows.Forms.Button colorButton;
+    private System.Windows.Forms.Button colorDialogButton;
     private System.Windows.Forms.ColorDialog colorDialog;
     private System.Windows.Forms.ToolTip tooltip;
@@ -395,4 +457,8 @@
     private System.Windows.Forms.TrackBar sizeTrackBar;
     private System.Windows.Forms.ToolStripMenuItem getDataAsMatrixToolStripMenuItem;
+    private System.Windows.Forms.TrackBar transparencyTrackBar;
+    private System.Windows.Forms.Label transparencyLabel;
+    private System.Windows.Forms.Button colorRunsButton;
+    private System.Windows.Forms.Button hideRunsButton;
   }
 }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 9420)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 9421)
@@ -20,9 +20,4 @@
 #endregion
 
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 using System;
 using System.Collections.Generic;
@@ -31,4 +26,9 @@
 using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Optimization.Views {
@@ -43,13 +43,17 @@
     private string sizeAxisValue;
 
-    private Dictionary<IRun, List<DataPoint>> runToDataPointMapping;
-    private Dictionary<int, Dictionary<object, double>> categoricalMapping;
-    private Dictionary<IRun, double> xJitter;
-    private Dictionary<IRun, double> yJitter;
+    private readonly Dictionary<IRun, List<DataPoint>> runToDataPointMapping = new Dictionary<IRun, List<DataPoint>>();
+    private readonly Dictionary<IRun, int> runToIndexMapping = new Dictionary<IRun, int>();
+    private readonly Dictionary<int, Dictionary<object, double>> categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
+    private readonly Dictionary<IRun, double> xJitter = new Dictionary<IRun, double>();
+    private readonly Dictionary<IRun, double> yJitter = new Dictionary<IRun, double>();
+
+    private readonly HashSet<IRun> selectedRuns = new HashSet<IRun>();
+    private readonly Random random = new Random();
     private double xJitterFactor = 0.0;
     private double yJitterFactor = 0.0;
-    private Random random;
     private bool isSelecting = false;
     private bool suppressUpdates = false;
+
 
     public RunCollectionBubbleChartView() {
@@ -61,12 +65,6 @@
       chart.ContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(ContextMenuStrip_Opening);
 
-      runToDataPointMapping = new Dictionary<IRun, List<DataPoint>>();
-      categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
-      xJitter = new Dictionary<IRun, double>();
-      yJitter = new Dictionary<IRun, double>();
-      random = new Random();
-
       colorDialog.Color = Color.Black;
-      colorButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
+      colorDialogButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
       isSelecting = false;
 
@@ -84,4 +82,7 @@
     public IStringConvertibleMatrix Matrix {
       get { return this.Content; }
+    }
+    public IEnumerable<IRun> SelectedRuns {
+      get { return selectedRuns; }
     }
 
@@ -93,6 +94,6 @@
       Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
       Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
       Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
-      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
       RegisterRunEvents(Content);
     }
@@ -104,6 +105,6 @@
       Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
       Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
       Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
-      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
       DeregisterRunEvents(Content);
     }
@@ -128,4 +129,5 @@
     }
     private void run_Changed(object sender, EventArgs e) {
+      if (suppressUpdates) return;
       if (InvokeRequired)
         this.Invoke(new EventHandler(run_Changed), sender, e);
@@ -133,30 +135,50 @@
         IRun run = (IRun)sender;
         UpdateRun(run);
+        UpdateCursorInterval();
+        chart.ChartAreas[0].RecalculateAxesScale();
+        UpdateAxisLabels();
+      }
+    }
+
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        this.Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+      else {
+        suppressUpdates = Content.UpdateOfRunsInProgress;
+        if (suppressUpdates) return;
+
+        foreach (var run in Content) UpdateRun(run);
+        UpdateMarkerSizes();
+        UpdateCursorInterval();
+        chart.ChartAreas[0].RecalculateAxesScale();
+        UpdateAxisLabels();
       }
     }
 
     private void UpdateRun(IRun run) {
-      if (!suppressUpdates) {
-        if (runToDataPointMapping.ContainsKey(run)) {
-          foreach (DataPoint point in runToDataPointMapping[run]) {
-            point.Color = run.Color;
-            if (!run.Visible) {
-              this.chart.Series[0].Points.Remove(point);
-              UpdateCursorInterval();
-              chart.ChartAreas[0].RecalculateAxesScale();
-            }
+      if (runToDataPointMapping.ContainsKey(run)) {
+        foreach (DataPoint point in runToDataPointMapping[run]) {
+          if (!run.Visible) {
+            this.chart.Series[0].Points.Remove(point);
+            continue;
           }
-          if (!run.Visible) runToDataPointMapping.Remove(run);
-        } else {
-          AddDataPoint(run);
-          UpdateCursorInterval();
-          chart.ChartAreas[0].RecalculateAxesScale();
-        }
-
-        if (this.chart.Series[0].Points.Count == 0)
-          noRunsLabel.Visible = true;
-        else
-          noRunsLabel.Visible = false;
-      }
+          if (selectedRuns.Contains(run)) {
+            point.Color = Color.Red;
+            point.MarkerStyle = MarkerStyle.Cross;
+          } else {
+            point.Color = Color.FromArgb(255 - transparencyTrackBar.Value, ((IRun)point.Tag).Color);
+            point.MarkerStyle = MarkerStyle.Circle;
+          }
+
+        }
+        if (!run.Visible) runToDataPointMapping.Remove(run);
+      } else {
+        AddDataPoint(run);
+      }
+
+      if (this.chart.Series[0].Points.Count == 0)
+        noRunsLabel.Visible = true;
+      else
+        noRunsLabel.Visible = false;
     }
 
@@ -167,5 +189,18 @@
       UpdateDataPoints();
       UpdateCaption();
-    }
+      RebuildInverseIndex();
+    }
+
+    private void RebuildInverseIndex() {
+      if (Content != null) {
+        runToIndexMapping.Clear();
+        int i = 0;
+        foreach (var run in Content) {
+          runToIndexMapping.Add(run, i);
+          i++;
+        }
+      }
+    }
+
     private void Content_ColumnNamesChanged(object sender, EventArgs e) {
       if (InvokeRequired)
@@ -210,16 +245,8 @@
           changed = true;
         }
-        if (changed)
+        if (changed) {
           UpdateDataPoints();
-      }
-    }
-
-
-    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
-      if (InvokeRequired)
-        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
-      else {
-        suppressUpdates = Content.UpdateOfRunsInProgress;
-        if (!suppressUpdates) UpdateDataPoints();
+          UpdateAxisLabels();
+        }
       }
     }
@@ -236,5 +263,7 @@
       else {
         this.categoricalMapping.Clear();
+        RebuildInverseIndex();
         UpdateDataPoints();
+        UpdateAxisLabels();
       }
     }
@@ -244,4 +273,5 @@
       series.Points.Clear();
       runToDataPointMapping.Clear();
+      selectedRuns.Clear();
 
       chart.ChartAreas[0].AxisX.IsMarginVisible = xAxisValue != AxisDimension.Index.ToString();
@@ -272,17 +302,26 @@
 
     private void UpdateMarkerSizes() {
-      double[] sizeValues = this.chart.Series[0].Points.Select(p => p.YValues[1]).ToArray();
+      var series = chart.Series[0];
+      if (series.Points.Count <= 0) return;
+
+      var sizeValues = series.Points.Select(p => p.YValues[1]);
       double minSizeValue = sizeValues.Min();
       double maxSizeValue = sizeValues.Max();
-
-      for (int i = 0; i < sizeValues.Length; i++) {
-        DataPoint point = this.chart.Series[0].Points[i];
-        double sizeRange = maxSizeValue - minSizeValue;
+      double sizeRange = maxSizeValue - minSizeValue;
+
+      const int smallestBubbleSize = 5;
+
+      foreach (DataPoint point in series.Points) {
+        //calculates the relative size of the data point  0 <= relativeSize <= 1
         double relativeSize = (point.YValues[1] - minSizeValue);
-
-        if (sizeRange > double.Epsilon) relativeSize /= sizeRange;
-        else relativeSize = 1;
-
-        point.MarkerSize = (int)Math.Round((sizeTrackBar.Value - sizeTrackBar.Minimum) * relativeSize + sizeTrackBar.Minimum);
+        if (sizeRange > double.Epsilon) {
+          relativeSize /= sizeRange;
+
+          //invert bubble sizes if the value of the trackbar is negative
+          if (sizeTrackBar.Value < 0) relativeSize = Math.Abs(relativeSize - 1);
+        } else relativeSize = 1;
+
+        double sizeChange = Math.Abs(sizeTrackBar.Value) * relativeSize;
+        point.MarkerSize = (int)Math.Round(sizeChange + smallestBubbleSize);
       }
     }
@@ -344,5 +383,4 @@
       if (xValue.HasValue && yValue.HasValue && sizeValue.HasValue) {
         xValue = xValue.Value;
-
         yValue = yValue.Value;
 
@@ -350,8 +388,8 @@
           DataPoint point = new DataPoint(xValue.Value, new double[] { yValue.Value, sizeValue.Value });
           point.Tag = run;
-          point.Color = run.Color;
           series.Points.Add(point);
           if (!runToDataPointMapping.ContainsKey(run)) runToDataPointMapping.Add(run, new List<DataPoint>());
           runToDataPointMapping[run].Add(point);
+          UpdateRun(run);
         }
       }
@@ -391,19 +429,23 @@
     }
     private double GetCategoricalValue(int dimension, string value) {
-      if (!this.categoricalMapping.ContainsKey(dimension))
+      if (!this.categoricalMapping.ContainsKey(dimension)) {
         this.categoricalMapping[dimension] = new Dictionary<object, double>();
-      if (!this.categoricalMapping[dimension].ContainsKey(value)) {
-        if (this.categoricalMapping[dimension].Values.Count == 0)
-          this.categoricalMapping[dimension][value] = 1.0;
-        else
-          this.categoricalMapping[dimension][value] = this.categoricalMapping[dimension].Values.Max() + 1.0;
+        var orderedCategories = Content.Where(r => r.Visible).Select(r => Content.GetValue(r, dimension).ToString())
+                                    .Distinct()
+                                    .OrderBy(x => x, new NaturalStringComparer());
+        int count = 1;
+        foreach (var category in orderedCategories) {
+          this.categoricalMapping[dimension].Add(category, count);
+          count++;
+        }
       }
       return this.categoricalMapping[dimension][value];
     }
+
     private double GetValue(IRun run, AxisDimension axisDimension) {
       double value = double.NaN;
       switch (axisDimension) {
         case AxisDimension.Index: {
-            value = Content.ToList().IndexOf(run);
+            value = runToIndexMapping[run];
             break;
           }
@@ -428,18 +470,22 @@
     }
     private void UpdateCursorInterval() {
-      Series series = chart.Series[0];
-      double[] xValues = (from point in series.Points
-                          where !point.IsEmpty
-                          select point.XValue)
-                    .DefaultIfEmpty(1.0)
-                    .ToArray();
-      double[] yValues = (from point in series.Points
-                          where !point.IsEmpty
-                          select point.YValues[0])
-                    .DefaultIfEmpty(1.0)
-                    .ToArray();
-
-      double xRange = xValues.Max() - xValues.Min();
-      double yRange = yValues.Max() - yValues.Min();
+      double xMin = double.MaxValue;
+      double xMax = double.MinValue;
+      double yMin = double.MaxValue;
+      double yMax = double.MinValue;
+
+      foreach (var point in chart.Series[0].Points) {
+        if (point.IsEmpty) continue;
+        if (point.XValue < xMin) xMin = point.XValue;
+        if (point.XValue > xMax) xMax = point.XValue;
+        if (point.YValues[0] < yMin) yMin = point.YValues[0];
+        if (point.YValues[0] > yMax) yMax = point.YValues[0];
+      }
+
+      double xRange = 0.0;
+      double yRange = 0.0;
+      if (xMin != double.MaxValue && xMax != double.MinValue) xRange = xMax - xMin;
+      if (yMin != double.MaxValue && yMax != double.MinValue) yRange = yMax - yMin;
+
       if (xRange.IsAlmost(0.0)) xRange = 1.0;
       if (yRange.IsAlmost(0.0)) yRange = 1.0;
@@ -479,40 +525,44 @@
 
     private void chart_MouseUp(object sender, MouseEventArgs e) {
-      if (isSelecting) {
-        System.Windows.Forms.DataVisualization.Charting.Cursor xCursor = chart.ChartAreas[0].CursorX;
-        System.Windows.Forms.DataVisualization.Charting.Cursor yCursor = chart.ChartAreas[0].CursorY;
-
-        double minX = Math.Min(xCursor.SelectionStart, xCursor.SelectionEnd);
-        double maxX = Math.Max(xCursor.SelectionStart, xCursor.SelectionEnd);
-        double minY = Math.Min(yCursor.SelectionStart, yCursor.SelectionEnd);
-        double maxY = Math.Max(yCursor.SelectionStart, yCursor.SelectionEnd);
-
-        //check for click to select model
-        if (minX == maxX && minY == maxY) {
-          HitTestResult hitTest = chart.HitTest(e.X, e.Y);
-          if (hitTest.ChartElementType == ChartElementType.DataPoint) {
-            int pointIndex = hitTest.PointIndex;
-            IRun run = (IRun)this.chart.Series[0].Points[pointIndex].Tag;
-            run.Color = colorDialog.Color;
-          }
-        } else {
-          List<DataPoint> selectedPoints = new List<DataPoint>();
-          foreach (DataPoint p in this.chart.Series[0].Points) {
-            if (p.XValue >= minX && p.XValue < maxX &&
-              p.YValues[0] >= minY && p.YValues[0] < maxY) {
-              selectedPoints.Add(p);
-            }
-          }
-          foreach (DataPoint p in selectedPoints) {
-            IRun run = (IRun)p.Tag;
-            run.Color = colorDialog.Color;
-          }
-        }
-        this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
-        this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
-      }
+      if (!isSelecting) return;
+
+      System.Windows.Forms.DataVisualization.Charting.Cursor xCursor = chart.ChartAreas[0].CursorX;
+      System.Windows.Forms.DataVisualization.Charting.Cursor yCursor = chart.ChartAreas[0].CursorY;
+
+      double minX = Math.Min(xCursor.SelectionStart, xCursor.SelectionEnd);
+      double maxX = Math.Max(xCursor.SelectionStart, xCursor.SelectionEnd);
+      double minY = Math.Min(yCursor.SelectionStart, yCursor.SelectionEnd);
+      double maxY = Math.Max(yCursor.SelectionStart, yCursor.SelectionEnd);
+
+      //check for click to select a single model
+      if (minX == maxX && minY == maxY) {
+        HitTestResult hitTest = chart.HitTest(e.X, e.Y, ChartElementType.DataPoint);
+        if (hitTest.ChartElementType == ChartElementType.DataPoint) {
+          int pointIndex = hitTest.PointIndex;
+          var point = chart.Series[0].Points[pointIndex];
+          IRun run = (IRun)point.Tag;
+          point.Color = Color.Red;
+          point.MarkerStyle = MarkerStyle.Cross;
+          selectedRuns.Add(run);
+
+        } else ClearSelectedRuns();
+      } else {
+        foreach (DataPoint point in this.chart.Series[0].Points) {
+          if (point.XValue < minX || point.XValue >= maxX) continue;
+          if (point.YValues[0] < minY || point.YValues[0] >= maxY) continue;
+          point.MarkerStyle = MarkerStyle.Cross;
+          point.Color = Color.Red;
+          IRun run = (IRun)point.Tag;
+          selectedRuns.Add(run);
+        }
+      }
+
+      this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
+      this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
+      this.OnChanged();
     }
 
     private void chart_MouseMove(object sender, MouseEventArgs e) {
+      if (Control.MouseButtons != MouseButtons.None) return;
       HitTestResult h = this.chart.HitTest(e.X, e.Y);
       string newTooltipText = string.Empty;
@@ -638,21 +688,10 @@
     private void zoomButton_CheckedChanged(object sender, EventArgs e) {
       this.isSelecting = selectButton.Checked;
-      this.colorButton.Enabled = this.isSelecting;
+      this.colorDialogButton.Enabled = this.isSelecting;
+      this.colorRunsButton.Enabled = this.isSelecting;
+      this.hideRunsButton.Enabled = this.isSelecting;
       this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = !isSelecting;
       this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = !isSelecting;
-    }
-    private void colorButton_Click(object sender, EventArgs e) {
-      if (colorDialog.ShowDialog(this) == DialogResult.OK) {
-        this.colorButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
-      }
-    }
-    private Image GenerateImage(int width, int height, Color fillColor) {
-      Image colorImage = new Bitmap(width, height);
-      using (Graphics gfx = Graphics.FromImage(colorImage)) {
-        using (SolidBrush brush = new SolidBrush(fillColor)) {
-          gfx.FillRectangle(brush, 0, 0, width, height);
-        }
-      }
-      return colorImage;
+      ClearSelectedRuns();
     }
 
@@ -673,5 +712,5 @@
     }
     private void hideRunToolStripMenuItem_Click(object sender, EventArgs e) {
-      var constraint = Content.Constraints.OfType<RunCollectionContentConstraint>().Where(c => c.Active).FirstOrDefault();
+      var constraint = Content.Constraints.OfType<RunCollectionContentConstraint>().FirstOrDefault(c => c.Active);
       if (constraint == null) {
         constraint = new RunCollectionContentConstraint();
@@ -680,4 +719,31 @@
       }
       constraint.ConstraintData.Add(runToHide);
+    }
+    private void hideRunsButton_Click(object sender, EventArgs e) {
+      if (!selectedRuns.Any()) return;
+      var constraint = new RunCollectionContentConstraint();
+      constraint.ConstraintData = new ItemSet<IRun>(selectedRuns);
+      Content.Constraints.Add(constraint);
+      ClearSelectedRuns();
+      constraint.Active = true;
+    }
+
+    private void ClearSelectedRuns() {
+      foreach (var run in selectedRuns) {
+        foreach (var point in runToDataPointMapping[run]) {
+          point.MarkerStyle = MarkerStyle.Circle;
+          point.Color = Color.FromArgb(255 - LogTransform(transparencyTrackBar.Value), run.Color);
+        }
+      }
+      selectedRuns.Clear();
+    }
+
+    // returns a value in [0..255]
+    private int LogTransform(int x) {
+      double min = transparencyTrackBar.Minimum;
+      double max = transparencyTrackBar.Maximum;
+      double r = (x - min) / (max - min);  // r \in [0..1]
+      double l = Math.Log(r + 1) / Math.Log(2.0); // l \in [0..1]
+      return (int)Math.Round(255.0 * l);
     }
 
@@ -692,4 +758,6 @@
     private void getDataAsMatrixToolStripMenuItem_Click(object sender, EventArgs e) {
       int xCol = Matrix.ColumnNames.ToList().IndexOf(xAxisValue);
+      int yCol = Matrix.ColumnNames.ToList().IndexOf(yAxisValue);
+
       var grouped = new Dictionary<string, List<string>>();
       Dictionary<double, string> reverseMapping = null;
@@ -698,10 +766,13 @@
       foreach (var run in Content.Where(r => r.Visible)) {
         var x = GetValue(run, xAxisValue);
-        var y = GetValue(run, yAxisValue);
-        if (!(x.HasValue && y.HasValue)) continue;
+        object y;
+        if (categoricalMapping.ContainsKey(yCol))
+          y = Content.GetValue(run, yAxisValue);
+        else y = GetValue(run, yAxisValue);
+        if (!(x.HasValue && y != null)) continue;
 
         var category = reverseMapping == null ? x.Value.ToString() : reverseMapping[x.Value];
         if (!grouped.ContainsKey(category)) grouped[category] = new List<string>();
-        grouped[category].Add(y.Value.ToString());
+        grouped[category].Add(y.ToString());
       }
 
@@ -717,29 +788,65 @@
         i++;
       }
-
-      MainFormManager.MainForm.ShowContent(matrix);
+      matrix.SortableView = false;
+      var view = MainFormManager.MainForm.ShowContent(matrix);
+      view.ReadOnly = true;
+    }
+
+    private void transparencyTrackBar_ValueChanged(object sender, EventArgs e) {
+      foreach (var run in Content)
+        UpdateRun(run);
     }
     #endregion
 
-    #region Automatic coloring
+    #region coloring
+    private void colorDialogButton_Click(object sender, EventArgs e) {
+      if (colorDialog.ShowDialog(this) == DialogResult.OK) {
+        this.colorDialogButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
+      }
+    }
+    private Image GenerateImage(int width, int height, Color fillColor) {
+      Image colorImage = new Bitmap(width, height);
+      using (Graphics gfx = Graphics.FromImage(colorImage)) {
+        using (SolidBrush brush = new SolidBrush(fillColor)) {
+          gfx.FillRectangle(brush, 0, 0, width, height);
+        }
+      }
+      return colorImage;
+    }
+
+    private void colorRunsButton_Click(object sender, EventArgs e) {
+      if (!selectedRuns.Any()) return;
+      Content.UpdateOfRunsInProgress = true;
+      foreach (var run in selectedRuns)
+        run.Color = colorDialog.Color;
+
+      ClearSelectedRuns();
+      Content.UpdateOfRunsInProgress = false;
+    }
+
     private void colorXAxisButton_Click(object sender, EventArgs e) {
       ColorRuns(xAxisValue);
     }
-
     private void colorYAxisButton_Click(object sender, EventArgs e) {
       ColorRuns(yAxisValue);
     }
-
     private void ColorRuns(string axisValue) {
-      var runs = Content.Where(r => r.Visible).Select(r => new { Run = r, Value = GetValue(r, axisValue) }).Where(r => r.Value.HasValue);
+      var runs = Content.Where(r => r.Visible).Select(r => new { Run = r, Value = GetValue(r, axisValue) }).Where(r => r.Value.HasValue).ToList();
       double minValue = runs.Min(r => r.Value.Value);
       double maxValue = runs.Max(r => r.Value.Value);
       double range = maxValue - minValue;
-
-      foreach (var r in runs) {
-        int colorIndex = 0;
-        if (!range.IsAlmost(0)) colorIndex = (int)((ColorGradient.Colors.Count - 1) * (r.Value.Value - minValue) / (range));
-        r.Run.Color = ColorGradient.Colors[colorIndex];
-      }
+      // UpdateOfRunsInProgress has to be set to true, otherwise run_Changed is called all the time (also in other views)
+      Content.UpdateOfRunsInProgress = true;
+      if (range.IsAlmost(0)) {
+        Color c = ColorGradient.Colors[0];
+        runs.ForEach(r => r.Run.Color = c);
+      } else {
+        int maxColorIndex = ColorGradient.Colors.Count - 1;
+        foreach (var r in runs) {
+          int colorIndex = (int)(maxColorIndex * (r.Value - minValue) / (range));
+          r.Run.Color = ColorGradient.Colors[colorIndex];
+        }
+      }
+      Content.UpdateOfRunsInProgress = false;
     }
     #endregion
