From 822016c14e3b767586e4f2b15ed11b104a5823bc Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 4 Dec 2015 20:21:34 +0000 Subject: [PATCH] Added support to zoom types (scroll and drag) with option to disable default zoom behavior. Added uncorrect removed files. Fixed build files permissions. Fixed visibility property spelling. Fixed bug on returned zoom domain in 'onzoomend' event. Prevent a drag from a single click. removed fix for false click. Fixed bug in update zoom when zoom type is drag. --- .gitignore | 7 +++ htdocs/index.html | 3 ++ htdocs/samples/zoom_type.html | 62 +++++++++++++++++++++++++++ src/class.js | 1 + src/config.js | 2 + src/core.js | 3 ++ src/scss/main.scss | 4 ++ src/scss/zoom.scss | 13 ++++++ src/zoom.js | 80 +++++++++++++++++++++++++++++++++++ 9 files changed, 175 insertions(+) create mode 100644 htdocs/samples/zoom_type.html create mode 100644 src/scss/zoom.scss diff --git a/.gitignore b/.gitignore index dfafee4..ffc6074 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,10 @@ components # coverage report /coverage + +# OS related +.DS_Store + +# IDE related +.idea + diff --git a/htdocs/index.html b/htdocs/index.html index fcddafb..33ddd2a 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -371,6 +371,9 @@ Enable zoom + + Change Zoom Type + Zoom on category axis diff --git a/htdocs/samples/zoom_type.html b/htdocs/samples/zoom_type.html new file mode 100644 index 0000000..042cf1c --- /dev/null +++ b/htdocs/samples/zoom_type.html @@ -0,0 +1,62 @@ + + + + + +

Zoom Type Scroll with Default Zoom Behavior

+
+ +

Zoom Type Drag with Default Zoom Behavior

+
+ + + + + + diff --git a/src/class.js b/src/class.js index 7cc0b61..695c1f3 100644 --- a/src/class.js +++ b/src/class.js @@ -22,6 +22,7 @@ export default { eventRectsMultiple: 'c3-event-rects-multiple', zoomRect: 'c3-zoom-rect', brush: 'c3-brush', + dragZoom: 'c3-drag-zoom', focused: 'c3-focused', defocused: 'c3-defocused', region: 'c3-region', diff --git a/src/config.js b/src/config.js index 7ea0bb8..693cd3e 100644 --- a/src/config.js +++ b/src/config.js @@ -14,6 +14,8 @@ ChartInternal.prototype.getDefaultConfig = function () { resize_auto: true, zoom_enabled: false, zoom_initialRange: undefined, + zoom_type: 'scroll', + zoom_disableDefaultBehavior: false, zoom_privileged: false, zoom_rescale: false, zoom_onzoom: function () {}, diff --git a/src/core.js b/src/core.js index a69efe0..6a3bea4 100644 --- a/src/core.js +++ b/src/core.js @@ -257,6 +257,9 @@ ChartInternal.prototype.initWithData = function(data) { if ($$.initPie) { $$.initPie(); } + if ($$.initDragZoom) { + $$.initDragZoom(); + } if ($$.initSubchart) { $$.initSubchart(); } diff --git a/src/scss/main.scss b/src/scss/main.scss index fecfcfe..0b34feb 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -61,3 +61,7 @@ /*-- Arc --*/ @import 'arc'; + +/*-- Zoom --*/ + +@import 'zoom'; diff --git a/src/scss/zoom.scss b/src/scss/zoom.scss new file mode 100644 index 0000000..1e0c6fe --- /dev/null +++ b/src/scss/zoom.scss @@ -0,0 +1,13 @@ +.c3-drag-zoom.enabled{ + pointer-events: all!important; + visibility: visible; +} + +.c3-drag-zoom.disabled{ + pointer-events: none!important; + visibility: hidden; +} + +.c3-drag-zoom .extent { + fill-opacity: .1; +} diff --git a/src/zoom.js b/src/zoom.js index b7dd217..ebdf98f 100644 --- a/src/zoom.js +++ b/src/zoom.js @@ -5,17 +5,29 @@ ChartInternal.prototype.initZoom = function () { $$.zoom = d3.zoom() .on("start", function () { + if (config.zoom_type !== 'scroll') { + return; + } + var e = d3.event.sourceEvent; if (e && e.type === "brush") { return; } startEvent = e; config.zoom_onzoomstart.call($$.api, e); }) .on("zoom", function () { + if (config.zoom_type !== 'scroll') { + return; + } + var e = d3.event.sourceEvent; if (e && e.type === "brush") { return; } $$.redrawForZoom.call($$); }) .on('end', function () { + if (config.zoom_type !== 'scroll') { + return; + } + var e = d3.event.sourceEvent; if (e && e.type === "brush") { return; } // if click, do nothing. otherwise, click interaction will be canceled. @@ -48,6 +60,74 @@ ChartInternal.prototype.zoomTransform = function (range) { return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0); }; +ChartInternal.prototype.initDragZoom = function () { + if (this.config.zoom_type === 'drag' && this.config.zoom_enabled) { + var $$ = this, d3 = $$.d3, config = $$.config, + context = $$.context = $$.svg, + brushXPos, brushYPos; + + $$.dragZoomBrush = d3.svg.brush() + .x($$.x) + .y($$.y) + .on("brushstart", function () { + config.zoom_onzoomstart.call($$.api, $$.x.orgDomain()); + }) + .on("brush", function () { + var extent = $$.dragZoomBrush.extent(), + ar1 = [extent[0][0], $$.y.domain()[0]], + ar2 = [extent[1][0], $$.y.domain()[1]]; + + $$.dragZoomBrush.extent([ar1, ar2]); + $$.svg.select("." + CLASS.dragZoom).call($$.dragZoomBrush); + + + config.zoom_onzoom.call($$.api, $$.x.orgDomain()); + }) + .on("brushend", function () { + var extent = $$.dragZoomBrush.extent(); + + if (!config.zoom_disableDefaultBehavior) { + $$.api.zoom([extent[0][0], extent[1][0]]); + } + else { + var ar1 = [$$.x.domain()[0], $$.y.domain()[0]], + ar2 = [$$.x.domain()[1], $$.y.domain()[1]]; + $$.dragZoomBrush.extent([ar1, ar2]); + $$.api.zoom([$$.x.domain()[0], $$.x.domain()[1]]); + } + + d3.selectAll("." + CLASS.dragZoom) + .attr("class", CLASS.dragZoom + " disabled"); + + $$.dragZoomBrush.clear(); + $$.svg.select("." + CLASS.dragZoom).call($$.dragZoomBrush); + + config.zoom_onzoomend.call($$.api, [extent[0][0], extent[1][0]]); + }); + + brushXPos = $$.margin.left + 20.5; + brushYPos = $$.margin.top + 0.5; + context.append("g") + .attr("clip-path", $$.clipPath) + .attr("class", CLASS.dragZoom + " disabled") + .attr("transform", "translate(" + brushXPos + "," + brushYPos + ")") + .call($$.dragZoomBrush); + + $$.svg.on("mousedown", function () { + d3.selectAll("." + CLASS.dragZoom) + .attr("class", CLASS.dragZoom + " enabled"); + + var brush_elm = $$.svg.select("." + CLASS.dragZoom).node(); + var new_click_event = new Event('mousedown'); + new_click_event.pageX = d3.event.pageX; + new_click_event.clientX = d3.event.clientX; + new_click_event.pageY = d3.event.pageY; + new_click_event.clientY = d3.event.clientY; + brush_elm.dispatchEvent(new_click_event); + }); + } +}; + ChartInternal.prototype.getZoomDomain = function () { var $$ = this, config = $$.config, d3 = $$.d3, min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),