X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=extras%2Fsynchronizer.js;h=16e4d96bc36926a8a0a502bc7d20c294c705a3a5;hb=8db6393ec8cac592f323724e43a2a7122a84614f;hp=ca05a2bf25425e8de3ab8e3793dd49f3089c83ef;hpb=b94ba4b52e227816448775cce9687f33a80cfe9a;p=dygraphs.git diff --git a/extras/synchronizer.js b/extras/synchronizer.js index ca05a2b..16e4d96 100644 --- a/extras/synchronizer.js +++ b/extras/synchronizer.js @@ -48,6 +48,12 @@ Dygraph.synchronize = function(/* dygraphs..., opts */) { }; var dygraphs = []; + var prevCallbacks = { + draw: null, + highlight: null, + unhighlight: null + }; + var parseOpts = function(obj) { if (!(obj instanceof Object)) { throw 'Last argument must be either Dygraph or Object.'; @@ -94,44 +100,54 @@ Dygraph.synchronize = function(/* dygraphs..., opts */) { throw 'Invalid invocation of Dygraph.synchronize(). ' + 'Need two or more dygraphs to synchronize.'; } + + var readycount = dygraphs.length; + for (var i = 0; i < dygraphs.length; i++) { + var g = dygraphs[i]; + g.ready( function() { + if (--readycount == 0) { + // Listen for draw, highlight, unhighlight callbacks. + if (opts.zoom) { + attachZoomHandlers(dygraphs, opts, prevCallbacks); + } - // Listen for draw, highlight, unhighlight callbacks. - if (opts.zoom) { - attachZoomHandlers(dygraphs, opts); - } - - if (opts.selection) { - attachSelectionHandlers(dygraphs); + if (opts.selection) { + attachSelectionHandlers(dygraphs, prevCallbacks); + } + } + }); } - + return { detach: function() { for (var i = 0; i < dygraphs.length; i++) { var g = dygraphs[i]; if (opts.zoom) { - g.updateOptions({drawCallback: null}); + g.updateOptions({drawCallback: prevCallbacks.draw}); } if (opts.selection) { g.updateOptions({ - highlightCallback: null, - unhighlightCallback: null + highlightCallback: prevCallbacks.highlight, + unhighlightCallback: prevCallbacks.unhighlight }); } } // release references & make subsequent calls throw. dygraphs = null; opts = null; + prevCallbacks = null; } }; }; -// TODO: call any `drawCallback`s that were set before this. -function attachZoomHandlers(gs, syncOpts) { +function attachZoomHandlers(gs, syncOpts, prevCallbacks) { var block = false; for (var i = 0; i < gs.length; i++) { var g = gs[i]; + prevCallbacks.draw = g.getFunctionOption('drawCallback'); g.updateOptions({ drawCallback: function(me, initial) { + if (prevCallbacks.draw) prevCallbacks.draw(me, initial); if (block || initial) return; block = true; var opts = { @@ -149,18 +165,23 @@ function attachZoomHandlers(gs, syncOpts) { } } -function attachSelectionHandlers(gs) { +function attachSelectionHandlers(gs, prevCallbacks) { var block = false; for (var i = 0; i < gs.length; i++) { var g = gs[i]; + prevCallbacks.highlight = g.getFunctionOption('highlightCallback'); + prevCallbacks.unhighlight = g.getFunctionOption('unhighlightCallback'); g.updateOptions({ highlightCallback: function(event, x, points, row, seriesName) { + if (prevCallbacks.highlight) { + prevCallbacks.highlight(event, x, points, row, seriesName); + } if (block) return; block = true; var me = this; for (var i = 0; i < gs.length; i++) { if (me == gs[i]) continue; - var idx = dygraphsBinarySearch(gs[i], x); + var idx = gs[i].getRowForX(x); if (idx !== null) { gs[i].setSelection(idx, seriesName); } @@ -168,6 +189,7 @@ function attachSelectionHandlers(gs) { block = false; }, unhighlightCallback: function(event) { + if (prevCallbacks.unhighlight) prevCallbacks.unhighlight(event); if (block) return; block = true; var me = this; @@ -181,25 +203,4 @@ function attachSelectionHandlers(gs) { } } -// Returns the index corresponding to xVal, or null if there is none. -function dygraphsBinarySearch(g, xVal) { - var low = 0, - high = g.numRows() - 1; - - while (low < high) { - var idx = (high + low) >> 1; - var x = g.getValue(idx, 0); - if (x < xVal) { - low = idx + 1; - } else if (x > xVal) { - high = idx - 1; - } else { - return idx; - } - } - - // TODO: give an option to find the closest point, i.e. not demand an exact match. - return null; -} - })();