var plugins = Dygraph.PLUGINS.concat(this.getOption('plugins'));
for (var i = 0; i < plugins.length; i++) {
var Plugin = plugins[i];
- var pluginInstance = new Plugin();
+
+ // the plugins option may contain either plugin classes or instances.
+ var pluginInstance;
+ if (typeof(Plugin.activate) !== 'undefined') {
+ pluginInstance = Plugin;
+ } else {
+ pluginInstance = new Plugin();
+ }
+
var pluginDict = {
plugin: pluginInstance,
events: {},
/**
* Triggers a cascade of events to the various plugins which are interested in them.
- * Returns true if the "default behavior" should be performed, i.e. if none of
- * the event listeners called event.preventDefault().
+ * Returns true if the "default behavior" should be prevented, i.e. if one
+ * of the event listeners called event.preventDefault().
* @private
*/
Dygraph.prototype.cascadeEvents_ = function(name, extra_props) {
- if (!(name in this.eventListeners_)) return true;
+ if (!(name in this.eventListeners_)) return false;
// QUESTION: can we use objects & prototypes to speed this up?
var e = {
*/
Dygraph.prototype.loadedEvent_ = function(data) {
this.rawData_ = this.parseCSV_(data);
+ this.cascadeDataDidUpdateEvent_();
this.predraw_();
};
};
/**
+ * Signals to plugins that the chart data has updated.
+ * This happens after the data has updated but before the chart has redrawn.
+ */
+Dygraph.prototype.cascadeDataDidUpdateEvent_ = function() {
+ // TODO(danvk): there are some issues checking xAxisRange() and using
+ // toDomCoords from handlers of this event. The visible range should be set
+ // when the chart is drawn, not derived from the data.
+ this.cascadeEvents_('dataDidUpdate', {});
+};
+
+/**
* Get the CSV data. If it's in a function, call that function. If it's in a
* file, do an XMLHttpRequest to get it.
* @private
if (Dygraph.isArrayLike(data)) {
this.rawData_ = this.parseArray_(data);
+ this.cascadeDataDidUpdateEvent_();
this.predraw_();
} else if (typeof data == 'object' &&
typeof data.getColumnRange == 'function') {
// must be a DataTable from gviz.
this.parseDataTable_(data);
+ this.cascadeDataDidUpdateEvent_();
this.predraw_();
} else if (typeof data == 'string') {
// Heuristic: a newline means it's CSV data. Otherwise it's an URL.
this.attributes_.reparseSeries();
if (file) {
+ // This event indicates that the data is about to change, but hasn't yet.
+ // TODO(danvk): support cancelation of the update via this event.
+ this.cascadeEvents_('dataWillUpdate', {});
+
this.file_ = file;
if (!block_redraw) this.start_();
} else {