From: Robert Konigsberg Date: Sun, 25 Nov 2012 04:11:14 +0000 (-0500) Subject: Merge branch 'remove-old-options' into new-series-option, make new style axis specifi... X-Git-Tag: v1.0.0~157^2~3 X-Git-Url: https://adrianiainlam.tk/git/?a=commitdiff_plain;h=6ad8b6a444ae32d026264409698f496506b3d33b;hp=632bd78ca394e97157f2e09e0f10a05f813a810b;p=dygraphs.git Merge branch 'remove-old-options' into new-series-option, make new style axis specification work. Conflicts: dygraph-options.js --- diff --git a/Makefile b/Makefile index 6a645a5..a307c72 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # # Dean Wampler March 22, 2010 -all: generate-combined +all: test generate-combined generate-combined: @echo Generating dygraph-combined.js @@ -18,3 +18,6 @@ generate-gwt: test: @./test.sh + +lint: + @./lint.sh diff --git a/auto_tests/tests/per_series.js b/auto_tests/tests/per_series.js index bba18ad..8d81c7b 100644 --- a/auto_tests/tests/per_series.js +++ b/auto_tests/tests/per_series.js @@ -100,9 +100,9 @@ perSeriesTestCase.prototype.testNewStyleSeriesTrumpsOldStyle = function() { assertEquals(5, g.getOption("pointSize", "Y")); }; +// TODO(konigsberg): move to multiple_axes.js perSeriesTestCase.prototype.testAxisInNewSeries = function() { var opts = { - logscale: true, series : { D : { axis : 'y2' }, C : { axis : 1 }, @@ -114,11 +114,11 @@ perSeriesTestCase.prototype.testAxisInNewSeries = function() { var data = "X,A,B,C,D,E\n0,1,2,3,4,5\n"; g = new Dygraph(graph, data, opts); - assertEquals(5, g.getOption("pointSize")); - assertEquals(4, g.getOption("pointSize", "Y")); - assertEquals(5, g.getOption("pointSize", "Z")); + assertEquals(["A", "B", "E"], g.attributes_.seriesForAxis(0)); + assertEquals(["C", "D"], g.attributes_.seriesForAxis(1)); }; +// TODO(konigsberg): move to multiple_axes.js perSeriesTestCase.prototype.testAxisInNewSeries_withAxes = function() { var opts = { series : { @@ -128,15 +128,21 @@ perSeriesTestCase.prototype.testAxisInNewSeries_withAxes = function() { E : { axis : 'y' } }, axes : { - y : {}, - y2 : {} + y : { pointSize : 7 }, + y2 : { pointSize : 6 } } }; var graph = document.getElementById("graph"); var data = "X,A,B,C,D,E\n0,1,2,3,4,5\n"; g = new Dygraph(graph, data, opts); - assertEquals(5, g.getOption("pointSize")); - assertEquals(4, g.getOption("pointSize", "Y")); - assertEquals(5, g.getOption("pointSize", "Z")); + assertEquals(["A", "B", "E"], g.attributes_.seriesForAxis(0)); + assertEquals(["C", "D"], g.attributes_.seriesForAxis(1)); + + assertEquals(1.5, g.getOption("pointSize")); + assertEquals(7, g.getOption("pointSize", "A")); + assertEquals(7, g.getOption("pointSize", "B")); + assertEquals(6, g.getOption("pointSize", "C")); + assertEquals(6, g.getOption("pointSize", "D")); + assertEquals(7, g.getOption("pointSize", "E")); }; diff --git a/dygraph-options.js b/dygraph-options.js index 82daff6..f734c5d 100644 --- a/dygraph-options.js +++ b/dygraph-options.js @@ -9,11 +9,11 @@ /* * Interesting member variables: * dygraph_ - the graph. - * global - global attributes (common among all graphs, AIUI) + * global_ - global attributes (common among all graphs, AIUI) * user - attributes set by the user - * axes - map of options specific to the axis. - * series - { seriesName -> { idx, yAxis, options } - * labels - used as mapping from index to series name. + * axes_ - array of axis index to { series : [ series names ] , options : { axis-specific options. } + * series_ - { seriesName -> { idx, yAxis, options }} + * labels_ - used as mapping from index to series name. */ /** @@ -88,7 +88,7 @@ DygraphOptions.axisToIndex_ = function(axis) { DygraphOptions.prototype.reparseSeries = function() { this.labels = this.get("labels").slice(1); - this.axes_ = [ {} ]; // Always one axis at least. + this.axes_ = [ { series : [], options : {}} ]; // Always one axis at least. this.series_ = {}; // Traditionally, per-series options were specified right up there with the options. For instance @@ -127,8 +127,14 @@ DygraphOptions.prototype.reparseSeries = function() { var axis = optionsForSeries["axis"]; if (typeof(axis) == 'object') { yAxis = ++axisId; - this.axes_[yAxis] = axis; + this.axes_[yAxis] = { series : [ seriesName ], options : axis }; } + + // Associate series without axis options with axis 0. + if (!axis) { // undefined + this.axes_[0].series.push(seriesName); + } + this.series_[seriesName] = { idx: idx, yAxis: yAxis, options : optionsForSeries }; } @@ -145,7 +151,9 @@ DygraphOptions.prototype.reparseSeries = function() { "series " + axis + ", which does not define its own axis."); return null; } - this.series_[seriesName].yAxis = this.series_[axis].yAxis; + var yAxis = this.series_[axis].yAxis; + this.series_[seriesName].yAxis = yAxis; + this.axes_[yAxis].series.push(seriesName); } } } else { @@ -162,25 +170,20 @@ DygraphOptions.prototype.reparseSeries = function() { idx: idx, yAxis: yAxis, options : optionsForSeries }; - } - for (; maxYAxis >= 0; maxYAxis--) { - this.axes_[maxYAxis] = {}; + if (!this.axes_[yAxis]) { + this.axes_[yAxis] = { series : [ seriesName ], options : {} }; + } else { + this.axes_[yAxis].series.push(seriesName); + } } } // This doesn't support reading from the 'x' axis, only 'y' and 'y2. - if (this.user_["axes"]) { - var axis_opts = this.user_.axes; - - if (axis_opts.hasOwnProperty("y")) { - Dygraph.update(this.axes_[0], axis_opts.y); - } - - if (axis_opts.hasOwnProperty("y2")) { - this.axes_[1] = this.axes_[1] || {}; - Dygraph.update(this.axes_[1], 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"] || {}); } }; @@ -216,7 +219,7 @@ DygraphOptions.prototype.getForAxis = function(name, axis) { axisIdx = (axis == "y2") ? 1 : 0; } - var axisOptions = this.axes_[axisIdx]; + var axisOptions = this.axes_[axisIdx].options; if (axisOptions.hasOwnProperty(name)) { return axisOptions[name]; } @@ -253,3 +256,48 @@ DygraphOptions.prototype.getForSeries = function(name, series) { return this.getForAxis(name, seriesObj["yAxis"]); }; + +/** + * Returns the number of y-axes on the chart. + * @return {Number} the number of axes. + */ +DygraphOptions.prototype.numAxes = function() { + return this.axes_.length; +} + +/** + * Return the y-axis for a given series, specified by name. + */ +DygraphOptions.prototype.axisForSeries = function(seriesName) { + return this.series_[seriesName].yAxis; +} + +/** + * Returns the options for the specified axis. + */ +DygraphOptions.prototype.axisOptions = function(yAxis) { + return this.axes_[yAxis].options; +} + +/** + * Return the series associated with an axis. + */ +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; +} diff --git a/dygraph.js b/dygraph.js index 720443a..1193e74 100644 --- a/dygraph.js +++ b/dygraph.js @@ -573,7 +573,6 @@ Dygraph.prototype.attr_ = function(name, seriesName) { Dygraph.OPTIONS_REFERENCE[name] = true; } // - return seriesName ? this.attributes_.getForSeries(name, seriesName) : this.attributes_.get(name); }; @@ -1137,7 +1136,7 @@ Dygraph.prototype.getPropertiesForSeries = function(series_name) { column: idx, visible: this.visibility()[idx - 1], color: this.colorsMap_[series_name], - axis: 1 + this.seriesToAxisMap_[series_name] + axis: 1 + this.attributes_.axisForSeries(series_name) }; }; @@ -2420,9 +2419,8 @@ Dygraph.prototype.renderGraph_ = function(is_initial_draw) { * currently being displayed. This includes things like the number of axes and * the style of the axes. It does not include the range of each axis and its * tick marks. - * This fills in this.axes_ and this.seriesToAxisMap_. + * This fills in this.axes_. * axes_ = [ { options } ] - * seriesToAxisMap_ = { seriesName: 0, seriesName2: 1, ... } * indices are into the axes_ array. */ Dygraph.prototype.computeYAxes_ = function() { @@ -2436,16 +2434,16 @@ Dygraph.prototype.computeYAxes_ = function() { } } - this.axes_ = [{ yAxisId : 0, g : this }]; // always have at least one y-axis. - this.seriesToAxisMap_ = {}; - - // Get a list of series names. - var labels = this.attr_("labels"); - var series = {}; - for (i = 1; i < labels.length; i++) series[labels[i]] = (i - 1); + // this.axes_ doesn't match this.attributes_.axes_.options. It's used for + // data computation as well as options storage. + this.axes_ = []; + for (axis = 0; axis < this.attributes_.numAxes(); axis++) { + this.axes_.push({ yAxisId : i, g : this }); + } // all options which could be applied per-axis: - var axisOptions = [ + // TODO(konigsberg) + var globalAxisOptions = [ 'includeZero', 'valueRange', 'labelsKMB', @@ -2458,48 +2456,22 @@ Dygraph.prototype.computeYAxes_ = function() { ]; // Copy global axis options over to the first axis. - for (i = 0; i < axisOptions.length; i++) { - var k = axisOptions[i]; + for (i = 0; i < globalAxisOptions.length; i++) { + var k = globalAxisOptions[i]; v = this.attr_(k); if (v) this.axes_[0][k] = v; } // Go through once and add all the axes. - for (seriesName in series) { - if (!series.hasOwnProperty(seriesName)) continue; - axis = this.attr_("axis", seriesName); - if (axis === null) { - this.seriesToAxisMap_[seriesName] = 0; - continue; - } - if (typeof(axis) == 'object') { - // Add a new axis, making a copy of its per-axis options. - opts = {}; - Dygraph.update(opts, this.axes_[0]); - Dygraph.update(opts, { valueRange: null }); // shouldn't inherit this. - var yAxisId = this.axes_.length; - opts.yAxisId = yAxisId; - opts.g = this; - Dygraph.update(opts, axis); - this.axes_.push(opts); - this.seriesToAxisMap_[seriesName] = yAxisId; - } - } - - // Go through one more time and assign series to an axis defined by another - // series, e.g. { 'Y1: { axis: {} }, 'Y2': { axis: 'Y1' } } - for (seriesName in series) { - if (!series.hasOwnProperty(seriesName)) continue; - axis = this.attr_("axis", seriesName); - if (typeof(axis) == 'string') { - if (!this.seriesToAxisMap_.hasOwnProperty(axis)) { - this.error("Series " + seriesName + " wants to share a y-axis with " + - "series " + axis + ", which does not define its own axis."); - return null; - } - var idx = this.seriesToAxisMap_[axis]; - this.seriesToAxisMap_[seriesName] = idx; - } + + // This seems to be right - starting at 1. I think this gets simpler now. + for (axis = 1; axis < this.attributes_.numAxes(); axis++) { + // Add a new axis, making a copy of its per-axis options. + opts = {}; + Dygraph.update(opts, this.axes_[0]); + Dygraph.update(opts, { valueRange: null }); // shouldn't inherit this. + Dygraph.update(opts, this.attributes_.axisOptions(axis)); + this.axes_[axis] = opts; } if (valueWindows !== undefined) { @@ -2523,7 +2495,6 @@ Dygraph.prototype.computeYAxes_ = function() { } } } - }; /** @@ -2531,13 +2502,7 @@ Dygraph.prototype.computeYAxes_ = function() { * @return {Number} the number of axes. */ Dygraph.prototype.numAxes = function() { - var last_axis = 0; - for (var series in this.seriesToAxisMap_) { - if (!this.seriesToAxisMap_.hasOwnProperty(series)) continue; - var idx = this.seriesToAxisMap_[series]; - if (idx > last_axis) last_axis = idx; - } - return 1 + last_axis; + return this.attributes_.numAxes(); }; /** @@ -2549,7 +2514,7 @@ Dygraph.prototype.numAxes = function() { */ Dygraph.prototype.axisPropertiesForSeries = function(series) { // TODO(danvk): handle errors. - return this.axes_[this.seriesToAxisMap_[series]]; + return this.axes_[this.attributes_.axisForSeries(series)]; }; /** @@ -2559,25 +2524,20 @@ Dygraph.prototype.axisPropertiesForSeries = function(series) { * This fills in the valueRange and ticks fields in each entry of this.axes_. */ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { - // Build a map from axis number -> [list of series names] - var seriesForAxis = [], series; - for (series in this.seriesToAxisMap_) { - if (!this.seriesToAxisMap_.hasOwnProperty(series)) continue; - var idx = this.seriesToAxisMap_[series]; - while (seriesForAxis.length <= idx) seriesForAxis.push([]); - seriesForAxis[idx].push(series); - } + var series; + var numAxes = this.attributes_.numAxes(); // Compute extreme values, a span and tick marks for each axis. - for (var i = 0; i < this.axes_.length; i++) { + for (var i = 0; i < numAxes; i++) { var axis = this.axes_[i]; - if (!seriesForAxis[i]) { + series = this.attributes_.seriesForAxis(i); + + if (series.length == 0) { // If no series are defined or visible then use a reasonable default axis.extremeRange = [0, 1]; } else { // Calculate the extremes of extremes. - series = seriesForAxis[i]; var minY = Infinity; // extremes[series[0]][0]; var maxY = -Infinity; // extremes[series[0]][1]; var extremeMinY, extremeMaxY;