*/
var DygraphOptions = (function() {
+/*jshint strict:false */
+// For "production" code, this gets set to false by uglifyjs.
+// Need to define it outside of "use strict", hence the nested IIFEs.
+if (typeof(DEBUG) === 'undefined') DEBUG=true;
+
+return (function() {
+
+// TODO: remove this jshint directive & fix the warnings.
/*jshint sub:true */
/*global Dygraph:false */
"use strict";
var DygraphOptions = function(dygraph) {
/**
* The dygraph.
- * @type {Dygraph}
+ * @type {!Dygraph}
*/
this.dygraph_ = dygraph;
/**
* Array of axis index to { series : [ series names ] , options : { axis-specific options. }
- * @type {Array.<{series : Array.<string>, options : Object}>}
+ * @type {Array.<{series : Array.<string>, options : Object}>} @private
*/
this.yAxes_ = [];
/**
- * { options : { axis-specific options. }
- * @type {Object}
+ * Contains x-axis specific options, which are stored in the options key.
+ * This matches the yAxes_ object structure (by being a dictionary with an
+ * options element) allowing for shared code.
+ * @type {options: Object} @private
*/
this.xAxis_ = {};
this.series_ = {};
* 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.
*
- * @type {Object.<string, number>}
+ * @type {Object.<number>}
* @private
*/
DygraphOptions.AXIS_STRING_MAPPINGS_ = {
'Y2' : 1
};
+/**
+ * @param {string|number} axis
+ * @private
+ */
DygraphOptions.axisToIndex_ = function(axis) {
if (typeof(axis) == "string") {
if (DygraphOptions.AXIS_STRING_MAPPINGS_.hasOwnProperty(axis)) {
}
throw "Dygraphs only supports two y-axes, indexed from 0-1.";
}
- if (typeof(axis) == "object") {
- throw "Using objects for axis specification " +
- "is not supported inside the 'series' option.";
- }
if (axis) {
throw "Unknown axis : " + axis;
}
if (typeof(axis) == 'string') {
if (!this.series_.hasOwnProperty(axis)) {
- this.dygraph_.error("Series " + seriesName + " wants to share a y-axis with " +
+ console.error("Series " + seriesName + " wants to share a y-axis with " +
"series " + axis + ", which does not define its own axis.");
- return null;
+ return;
}
var yAxis = this.series_[axis].yAxis;
this.series_[seriesName].yAxis = yAxis;
Dygraph.update(this.yAxes_[1].options, axis_opts["y2"] || {});
}
Dygraph.update(this.xAxis_.options, axis_opts["x"] || {});
+
+ if (DEBUG) this.validateOptions_();
};
/**
}
// User-specified global options second.
- var result = this.getGlobalUser_(name);
- if (result !== null) {
- return result;
+ // But, hack, ignore globally-specified 'logscale' for 'x' axis declaration.
+ if (!(axis === 'x' && name === 'logscale')) {
+ var result = this.getGlobalUser_(name);
+ if (result !== null) {
+ return result;
+ }
}
-
// Default axis options third.
var defaultAxisOptions = Dygraph.DEFAULT_ATTRS.axes[axisString];
if (defaultAxisOptions.hasOwnProperty(name)) {
*/
DygraphOptions.prototype.getForSeries = function(name, series) {
// Honors indexes as series.
- if (series === this.dygraph_.highlightSet_) {
+ if (series === this.dygraph_.getHighlightSeries()) {
if (this.highlightSeries_.hasOwnProperty(name)) {
return this.highlightSeries_[name];
}
return this.labels_;
};
-/* Are we using this? */
+if (DEBUG) {
+
/**
- * Return the index of the specified series.
- * @param {string} series the series name.
+ * Validate all options.
+ * This requires Dygraph.OPTIONS_REFERENCE, which is only available in debug builds.
+ * @private
*/
-DygraphOptions.prototype.indexOfSeries = function(series) {
- return this.series_[series].idx;
+DygraphOptions.prototype.validateOptions_ = function() {
+ if (typeof Dygraph.OPTIONS_REFERENCE === 'undefined') {
+ throw 'Called validateOptions_ in prod build.';
+ }
+
+ var that = this;
+ var validateOption = function(optionName) {
+ if (!Dygraph.OPTIONS_REFERENCE[optionName]) {
+ that.warnInvalidOption_(optionName);
+ }
+ };
+
+ var optionsDicts = [this.xAxis_.options,
+ this.yAxes_[0].options,
+ this.yAxes_[1] && this.yAxes_[1].options,
+ this.global_,
+ this.user_,
+ this.highlightSeries_];
+ var names = this.seriesNames();
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ if (this.series_.hasOwnProperty(name)) {
+ optionsDicts.push(this.series_[name].options);
+ }
+ }
+ for (var i = 0; i < optionsDicts.length; i++) {
+ var dict = optionsDicts[i];
+ if (!dict) continue;
+ for (var optionName in dict) {
+ if (dict.hasOwnProperty(optionName)) {
+ validateOption(optionName);
+ }
+ }
+ }
};
+var WARNINGS = {}; // Only show any particular warning once.
+
+/**
+ * Logs a warning about invalid options.
+ * TODO: make this throw for testing
+ * @private
+ */
+DygraphOptions.prototype.warnInvalidOption_ = function(optionName) {
+ if (!WARNINGS[optionName]) {
+ WARNINGS[optionName] = true;
+ var isSeries = (this.labels_.indexOf(optionName) >= 0);
+ if (isSeries) {
+ console.warn('Use new-style per-series options (saw ' + optionName + ' as top-level options key). See http://bit.ly/1tceaJs');
+ } else {
+ console.warn('Unknown option ' + optionName + ' (full list of options at dygraphs.com/options.html');
+ throw "invalid option " + optionName;
+ }
+ }
+};
+
+// Reset list of previously-shown warnings. Used for testing.
+DygraphOptions.resetWarnings_ = function() {
+ WARNINGS = {};
+};
+
+}
+
return DygraphOptions;
})();
+})();