Skip to content

Zoom Behaviors Combined with Brush and Range Chart

Gordon Woodhull edited this page Jun 15, 2014 · 6 revisions

Currently zooming exhibits some strange behavior, especially when coupled with brush and range chart. This page provides an overview of current state and proposed solutions.

Zoom Only

Current: By default, user can zoom out indefinitely, eventually getting to domain [NaN, NaN]. zoomOutRestrict() setting exists, but is ignored unless range chart is configured.

Analysis: Zoom can be limited when configuring a chart by setting chart.x().clamp(true). mbostock/d3#1299 also provides relevant functionality, but maybe is redundant since clamp() solution seems pretty good. Perhaps this is why mbostock/d3#1299 was not yet merged? If clamp is used, may need a way to make sure it is only called once - haven't tested what happens if you call clamp during render while chart is zoomed in.

Proposed: When zoomOutRestrict is true, limit zooming to chart's original x extent. Continue to set zoomOutRestrict to true by default.

Zoom + Box Plot

Current: Zoom is broken for box plot (possibly for all ordinal charts.) This can be reproduced simply by enabling mouse zoom on the box plot example.

Analysis: Have only investigated superficially so far; d3 rescale is throwing the exception, doesn't seem to like the domain.

Proposed: After fixing current error, need to test and see if ordinal charts need any custom zoom behavior due to relatively small domain extents.

Zoom + Line Chart Series Mouseover

Current: If brush is disabled, when mousing over the series of a line chart, a dot appears highlighting the data point under the mouse. If you zoom while the dot is visible, the dot will seem to 'wander.' After zoom, the dot is still visible, even though it is no longer under the mouse.

Analysis: Looks like the dot is moving to its new position before the line is redrawn, getting to its new position before the line.

Proposed: Since the function of the dot is to highlight user selection, seems like it should disappear during zoom as the series repositions. Ideally, mouse position should be re-evaluated after zoom, and the dot long with associated data label should appear under the current mouse position if appropriate.

Zoom + Range Chart + Custom Zoom Listener

Current: A custom zoom listener is only invoked when chart is zoomed due to user interaction. It is not invoked when chart is re-focused programatically, such as when range chart is manipulated.

Analysis: _invokeZoomListener is only called during in the zoom handler, which is not invoked by the focus() method.

Proposed: When focus() is invoked, the same behaviors should occur as when zoom happens due to user interaction, since focus() is basically a synonym for zoom in context of dc.js.

Zoom + Range Chart

Current: According to coordinate grid API doc, zoomOutRestrict(true) should limit zooming on focus chart based on initial extent of range chart. But on stock example page, you can easily zoom out to infinity on the monthly move chart, even though it has a range chart and its zoomOutRestrict is defaulted to true.

Analysis: Currently updateRangeSelChart is the only place where zoomOutRestrict(true) triggers any behavior, so it seems like the documented behavior was never implemented.

Proposed: When no range chart exists, zoomOutRestrict should limit zooming to original extent. If range chart is defined, zoomOutRestrict should behave as currently documented.

Zoom + Brush

Current: When zoom and brush are both enabled, manipulating the brush causes chart to pan from side to side. Exacerbated by unlimited zoom issue, but even with limited zoom still causes weird behavior. See: #347.

Analysis: Caused by interaction between d3 brush and zoom. Zoom listens for drag events and responds by panning, and brush listens for drag events as well. This is normal behavior for both zoom and brush, but when combined seems strange to the user.

Proposed: When brush and zoom are both enabled, only brush should respond to dragging.

Zoom + Brush + Range Chart

Current: When a range is selected on range chart, then you scroll or drag on focus chart, focus chart exhibits strange behavior such as snapping to original x extent. Documented in #253.

Analysis: When you manipulate brush on the range chart it is directly manipulating x() of focus chart. d3.behavior.zoom.x() of focus chart is not being updated, so when zoom is invoked it is zooming relative to whatever x() it remembers (in the simple case, the original chart.x()). d3.behavior.zoom.x() needs to be updated every time a chart.x() gets manipulated by dc.js, which right now is mainly in the .focus() method.

Proposed: Zooming on focus chart should behave identically whether or not range on range chart was chosen. One working fix is to call zoom.x(chart.x()) in the .focus() method.