Merge branch 'remove-old-options' into new-series-option, make new style axis specifi...
[dygraphs.git] / dygraph-options.js
index dd7bb6b..f734c5d 100644 (file)
@@ -46,6 +46,39 @@ var DygraphOptions = function(dygraph) {
   this.reparseSeries();
 };
 
+/*
+ * Not optimal, but does the trick when you're only using two axes.
+ * If we move to more axes, this can just become a function.
+ */
+DygraphOptions.AXIS_STRING_MAPPINGS_ = {
+  'y' : 0,
+  'Y' : 0,
+  'y1' : 0,
+  'Y1' : 0,
+  'y2' : 1,
+  'Y2' : 1
+}
+
+DygraphOptions.axisToIndex_ = function(axis) {
+  if (typeof(axis) == "string") {
+    if (DygraphOptions.AXIS_STRING_MAPPINGS_.hasOwnProperty(axis)) {
+      return DygraphOptions.AXIS_STRING_MAPPINGS_[axis];
+    }
+    throw "Unknown axis : " + text;
+  }
+  if (typeof(axis) == "number") {
+    if (axis == 0 || axis == 1) {
+      return axis;
+    }
+    throw "Dygraphs only supports two y-axes, indexed from 0-1."
+  }
+  if (axis) {
+    throw "Unknown axis : " + axis;
+  }
+  // No axis specification means axis 0.
+  return 0;
+};
+
 /**
  * Reparses options that are all related to series. This typically occurs when
  * options are either updated, or source data has been made avaialble.
@@ -58,60 +91,99 @@ DygraphOptions.prototype.reparseSeries = function() {
   this.axes_ = [ { series : [], options : {}} ]; // Always one axis at least.
   this.series_ = {};
 
-  var axisId = 0; // 0-offset; there's always one.
-  // Go through once, add all the series, and for those with {} axis options, add a new axis.
-  for (var idx = 0; idx < this.labels.length; idx++) {
-    var seriesName = this.labels[idx];
+  // Traditionally, per-series options were specified right up there with the options. For instance
+  // {
+  //   labels: [ "X", "foo", "bar" ],
+  //   pointSize: 3,
+  //   foo : {}, // options for foo
+  //   bar : {} // options for bar
+  // }
+  //
+  // Moving forward, series really should be specified in the series element, separating them.
+  // like so:
+  //
+  // {
+  //   labels: [ "X", "foo", "bar" ],
+  //   pointSize: 3,
+  //   series : {
+  //     foo : {}, // options for foo
+  //     bar : {} // options for bar
+  //   }
+  // }
+  //
+  // So, if series is found, it's expected to contain per-series data, otherwise we fall
+  // back.
+  var oldStyleSeries = !this.user_["series"];
+  
+  if (oldStyleSeries) {
+    var axisId = 0; // 0-offset; there's always one.
+    // Go through once, add all the series, and for those with {} axis options, add a new axis.
+    for (var idx = 0; idx < this.labels.length; idx++) {
+      var seriesName = this.labels[idx];
+  
+      var optionsForSeries = this.user_[seriesName] || {};
+  
+      var yAxis = 0;
+      var axis = optionsForSeries["axis"];
+      if (typeof(axis) == 'object') {
+        yAxis = ++axisId;
+        this.axes_[yAxis] = { series : [ seriesName ], options : axis };
+      }
 
-    var optionsForSeries = this.user_[seriesName] || {};
-    var yAxis = 0;
+      // Associate series without axis options with axis 0.
+      if (!axis) { // undefined
+        this.axes_[0].series.push(seriesName);
+      }
 
-    var axis = optionsForSeries["axis"];
-    if (typeof(axis) == 'object') {
-      yAxis = ++axisId;
-      this.axes_[yAxis] = { series : [ seriesName ], options : axis };
+      this.series_[seriesName] = { idx: idx, yAxis: yAxis, options : optionsForSeries };
     }
-
-    // Associate series without axis options with axis 0.
-    if (!axis) { // undefined
-      this.axes_[0].series.push(seriesName);
+  
+    // Go through one more time and assign series to an axis defined by another
+    // series, e.g. { 'Y1: { axis: {} }, 'Y2': { axis: 'Y1' } }
+    for (var idx = 0; idx < this.labels.length; idx++) {
+      var seriesName = this.labels[idx];
+      var optionsForSeries = this.series_[seriesName]["options"]; 
+      var axis = optionsForSeries["axis"];
+  
+      if (typeof(axis) == 'string') {
+        if (!this.series_.hasOwnProperty(axis)) {
+          this.dygraph_.error("Series " + seriesName + " wants to share a y-axis with " +
+                     "series " + axis + ", which does not define its own axis.");
+          return null;
+        }
+        var yAxis = this.series_[axis].yAxis;
+        this.series_[seriesName].yAxis = yAxis;
+        this.axes_[yAxis].series.push(seriesName);
+      }
     }
+  } else {
+    var maxYAxis = 0;
 
-    this.series_[seriesName] = { idx: idx, yAxis: yAxis, options : optionsForSeries };
-  }
+    for (var idx = 0; idx < this.labels.length; idx++) {
+      var seriesName = this.labels[idx];
+      var optionsForSeries = this.user_.series[seriesName] || {};
+      var yAxis = DygraphOptions.axisToIndex_(optionsForSeries["axis"]);
+
+      maxYAxis = Math.max(yAxis, maxYAxis);
 
-  // Go through one more time and assign series to an axis defined by another
-  // series, e.g. { 'Y1: { axis: {} }, 'Y2': { axis: 'Y1' } }
-  for (var idx = 0; idx < this.labels.length; idx++) {
-    var seriesName = this.labels[idx];
-    var optionsForSeries = this.series_[seriesName]["options"]; 
-    var axis = optionsForSeries["axis"];
-
-    if (typeof(axis) == 'string') {
-      if (!this.series_.hasOwnProperty(axis)) {
-        this.dygraph_.error("Series " + seriesName + " wants to share a y-axis with " +
-                   "series " + axis + ", which does not define its own axis.");
-        return null;
+      this.series_[seriesName] = {
+        idx: idx,
+        yAxis: yAxis,
+        options : optionsForSeries };
+
+      if (!this.axes_[yAxis]) {
+        this.axes_[yAxis] =  { series : [ seriesName ], options : {} };
+      } else {
+        this.axes_[yAxis].series.push(seriesName);
       }
-      var yAxis = this.series_[axis].yAxis;
-      this.series_[seriesName].yAxis = yAxis;
-      this.axes_[yAxis].series.push(seriesName);
     }
   }
 
   // This doesn't support reading from the 'x' axis, only 'y' and 'y2.
-  // Read from the global "axes" option.
-  if (this.user_.hasOwnProperty("axes")) {
-    var axis_opts = this.user_.axes;
-
-    if (axis_opts.hasOwnProperty("y")) {
-      Dygraph.update(this.axes_[0].options, axis_opts.y);
-    }
-
-    if (axis_opts.hasOwnProperty("y2")) {
-      this.axes_[1] = this.axes_[1] || {}; // FIX
-      Dygraph.update(this.axes_[1].options, axis_opts.y2);
-    }
+  var axis_opts = this.user_["axes"] || {};
+  Dygraph.update(this.axes_[0].options, axis_opts["y"] || {});
+  if (this.axes_.length > 1) {
+    Dygraph.update(this.axes_[1].options, axis_opts["y2"] || {});   
   }
 };
 
@@ -213,3 +285,19 @@ DygraphOptions.prototype.axisOptions = function(yAxis) {
 DygraphOptions.prototype.seriesForAxis = function(yAxis) {
   return this.axes_[yAxis].series;
 }
+
+/**
+ * Return the list of all series, in their columnar order.
+ */
+DygraphOptions.prototype.seriesNames = function() {
+  return this.labels_;
+}
+
+/* Are we using this? */ 
+/**
+ * Return the index of the specified series.
+ * @param {string} series the series name.
+ */
+DygraphOptions.prototype.indexOfSeries = function(series) {
+  return this.series_[series].idx;
+}