Index: /branches/BubbleChart/HeuristicLab.Optimization.BubbleChart/3.3/BubbleChartView.cs
===================================================================
--- /branches/BubbleChart/HeuristicLab.Optimization.BubbleChart/3.3/BubbleChartView.cs	(revision 12646)
+++ /branches/BubbleChart/HeuristicLab.Optimization.BubbleChart/3.3/BubbleChartView.cs	(revision 12647)
@@ -187,24 +187,80 @@
       RebuildInverseIndex();
 
-      chart.ChartAreas[0].AxisX.IsMarginVisible = XAxisValue != AxisDimension.Index.ToString();
-      chart.ChartAreas[0].AxisY.IsMarginVisible = YAxisValue != AxisDimension.Index.ToString();
+      chart.ChartAreas[0].AxisX.IsMarginVisible = !(XAxisValue != null && XAxisValue.Contains(AxisDimension.Index.ToString()));
+      chart.ChartAreas[0].AxisY.IsMarginVisible = !(YAxisValue != null && YAxisValue.Contains(AxisDimension.Index.ToString()));
 
       if (Content != null) {
-        var items = GetAvailableItems();
-        foreach (var item in items) {
-          var xs = GetValues(item, XAxisValue).ToList();
-          var ys = GetValues(item, YAxisValue).ToList();
-          var ss = GetValues(item, SizeAxisValue).ToList();
-          if (xs.Count > 0 && ys.Count > 0 && (ss.Count == 1 || ss.Count == xs.Count || ss.Count == ys.Count)) {
-            var sEnum = ss.Count > 1 ? ss.GetEnumerator() : Enumerable.Repeat(ss[0], xs.Count * ys.Count).GetEnumerator();
-            sEnum.MoveNext();
-            if (xs.Count > 1 && ys.Count > 1) { // index matching
-              for (int i = 0; i < Math.Min(xs.Count, ys.Count); i++)
-                series.Points.Add(new DataPoint(xs[i], new[] { ys[i], sEnum.Current }));
-            } else {
-              foreach (var x in xs) {
-                foreach (var y in ys) {
-                  series.Points.Add(new DataPoint(x, new[] { y, sEnum.Current }));
-                  sEnum.MoveNext();
+        var items = GetAvailableItems().ToList();
+        var xss = GetValues(items, XAxisValue).Select(x => x.ToList()).ToList();
+        var yss = GetValues(items, YAxisValue).Select(x => x.ToList()).ToList();
+        var sss = GetValues(items, SizeAxisValue).Select(x => x.ToList()).ToList();
+
+        if (xss.Any(xs => xs.Any()) && yss.Any(ys => ys.Any()) && sss.Any(ss => ss.Any())) {
+          var xDim = Tuple.Create(xss.Count, xss.Max(xs => xs.Count));
+          var yDim = Tuple.Create(yss.Count, yss.Max(ys => ys.Count));
+          var sDim = Tuple.Create(sss.Count, sss.Max(ss => ss.Count));
+
+          var isSimple = new Func<Tuple<int, int>, bool>(dim => dim.Item1 == 1 && dim.Item2 > 1 || dim.Item1 > 1 && dim.Item2 == 1);
+          var flatten = new Func<List<List<double>>, List<double>>(ss => ss.SelectMany(s => s).ToList());
+
+          if (isSimple(xDim) && isSimple(yDim)) {
+            var xs = flatten(xss);
+            var ys = flatten(yss);
+            if (xs.Count == ys.Count) {
+              var xsEnum = xs.GetEnumerator();
+              var ysEnum = ys.GetEnumerator();
+              while (xsEnum.MoveNext() & ysEnum.MoveNext())
+                series.Points.Add(new DataPoint(xsEnum.Current, new[] { ysEnum.Current, sss[0][0] }));
+            } /*else {
+              foreach (var x in xs)
+                foreach (var y in ys)
+                  series.Points.Add(new DataPoint(x, new[] { y, sss[0][0] }));
+            }*/
+          } else if (isSimple(xDim)) {
+            var xs = flatten(xss);
+            if (xs.Count == yss.Count) {
+              var xsEnum = xs.GetEnumerator();
+              var yssEnum = yss.GetEnumerator();
+              while (xsEnum.MoveNext() & yssEnum.MoveNext()) {
+                var x = xsEnum.Current;
+                var ys = yssEnum.Current;
+                foreach (var y in ys)
+                  series.Points.Add(new DataPoint(x, new[] { y, sss[0][0] }));
+              }
+            }
+          } else if (isSimple(yDim)) {
+            var ys = flatten(yss);
+            if (xss.Count == ys.Count) {
+              var xssEnum = xss.GetEnumerator();
+              var ysEnum = ys.GetEnumerator();
+              while (xssEnum.MoveNext() & ysEnum.MoveNext()) {
+                var xs = xssEnum.Current;
+                var y = ysEnum.Current;
+                foreach (var x in xs)
+                  series.Points.Add(new DataPoint(x, new[] { y, sss[0][0] }));
+              }
+            }
+          } else {
+            if (xss.Count == yss.Count) {
+              var xssEnum = xss.GetEnumerator();
+              var yssEnum = yss.GetEnumerator();
+              while (xssEnum.MoveNext() & yssEnum.MoveNext()) {
+                var xs = xssEnum.Current;
+                var ys = yssEnum.Current;
+                if (xs.Count == ys.Count) {
+                  var xsEnum = xs.GetEnumerator();
+                  var ysEnum = ys.GetEnumerator();
+                  while (xsEnum.MoveNext() & ysEnum.MoveNext())
+                    series.Points.Add(new DataPoint(xsEnum.Current, new[] { ysEnum.Current, sss[0][0] }));
+                }
+              }
+            } else if (xDim.Item2 == yDim.Item2) {
+              foreach (var xs in xss) {
+                foreach (var ys in yss) {
+                  var xsEnum = xs.GetEnumerator();
+                  var ysEnum = ys.GetEnumerator();
+                  while (xsEnum.MoveNext() & ysEnum.MoveNext()) {
+                    series.Points.Add(new DataPoint(xsEnum.Current, new[] { ysEnum.Current, sss[0][0] }));
+                  }
                 }
               }
@@ -214,4 +270,54 @@
         UpdateMarkerSizes();
       }
+    }
+
+    /*var items = GetAvailableItems();
+          foreach (var item in items) {
+            var xs = GetValues(item, XAxisValue).ToList();
+            var ys = GetValues(item, YAxisValue).ToList();
+            var ss = GetValues(item, SizeAxisValue).ToList();
+            if (xs.Count > 0 && ys.Count > 0 && (ss.Count == 1 || ss.Count == xs.Count || ss.Count == ys.Count)) {
+              var sEnum = ss.Count > 1 ? ss.GetEnumerator() : Enumerable.Repeat(ss[0], xs.Count * ys.Count).GetEnumerator();
+              sEnum.MoveNext();
+              if (xs.Count > 1 && ys.Count > 1) { // index matching
+                for (int i = 0; i < Math.Min(xs.Count, ys.Count); i++)
+                  series.Points.Add(new DataPoint(xs[i], new[] { ys[i], sEnum.Current }));
+              } else {
+                foreach (var x in xs) {
+                  foreach (var y in ys) {
+                    series.Points.Add(new DataPoint(x, new[] { y, sEnum.Current }));
+                    sEnum.MoveNext();
+                  }
+                }
+              }
+            }
+          }*/
+
+    private IEnumerable<IEnumerable<double>> GetValues(IEnumerable<RecursiveDataItem> items, string key) {
+      if (key == null) yield break;
+      var keyTokens = key.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries);
+      if (keyTokens.Length == 1) {
+        if (Enum.IsDefined(typeof(SizeDimension), key)) {
+          var sizeDimension = (SizeDimension)Enum.Parse(typeof(SizeDimension), key);
+          yield return GetValue(null, sizeDimension).ToEnumerable();
+        } else
+          foreach (var item in items) {
+            if (Enum.IsDefined(typeof(AxisDimension), key)) {
+              var axisDimension = (AxisDimension)Enum.Parse(typeof(AxisDimension), key);
+              yield return GetValue(item, axisDimension).ToEnumerable();
+            } else if (item.Data.ContainsKey(key)) {
+              yield return item.Data[key] as IEnumerable<double> ?? ConvertToDouble(item, key).ToEnumerable();
+            }
+          }
+      } else if (keyTokens.Length == 2) {
+        string parentName = keyTokens[0];
+        key = keyTokens[1];
+        foreach (var item in items.Where(item => item.Name == parentName)) {
+          foreach (var child in item.Children.Where(child => child.Data.ContainsKey(key))) {
+            yield return child.Data[key] as IEnumerable<double> ?? ConvertToDouble(child, key).ToEnumerable();
+          }
+        }
+      } else throw new InvalidOperationException("key either contains a single key or a child/data key");
+
     }
 
@@ -370,5 +476,5 @@
       double sizeRange = maxSizeValue - minSizeValue;
 
-      const int smallestBubbleSize = 7;
+      const int smallestBubbleSize = 5;
 
       foreach (DataPoint point in series.Points) {
