Skip to content

Instantly share code, notes, and snippets.

@micahstubbs
Created April 23, 2017 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micahstubbs/4de7f2d492518a4a2ae0e2c65bde8e74 to your computer and use it in GitHub Desktop.
Save micahstubbs/4de7f2d492518a4a2ae0e2c65bde8e74 to your computer and use it in GitHub Desktop.
zoom & drag event filtering
border: no
height: 500
license: Apache-2.0

an es2015 iteration on the block D3 event filtering from @pkerpedjiev

this iteration also makes sure the title text is not accidentally selected when attemption to drag over an un-draggable red circle:

  svg.selectAll('text')
    .style('-webkit-user-select', 'none') /* Chrome/Safari */
    .style('-moz-user-select', 'none') /* Firefox */
    .style('-ms-user-select', 'none') /* IE10+ */

credit to this stackoverflow answer for the styles to make text un-selectable in most browsers

<!DOCTYPE html>
<meta charset='utf-8'>
<body>
<div id='zoom-filtering-div'>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js'></script>
<script src='vis.js'></script>
<script>
zoomFiltering('#zoom-filtering-div');
</script>
</body>
# safe
lebab --replace vis.js --transform arrow
lebab --replace vis.js --transform for-of
lebab --replace vis.js --transform for-each
lebab --replace vis.js --transform arg-rest
lebab --replace vis.js --transform arg-spread
lebab --replace vis.js --transform obj-method
lebab --replace vis.js --transform obj-shorthand
lebab --replace vis.js --transform multi-var
# unsafe
lebab --replace vis.js --transform let
lebab --replace vis.js --transform template
/* global d3 */
function zoomFiltering(divId) {
const width = 960;
const height = 500;
const maxR = 60;
const svg = d3.select(divId)
.append('svg')
.attr('width', width)
.attr('height', height);
// style svg
svg
// .style('border', '1px solid')
.style('font', '20px sans-serif')
.style('text-anchor', 'start');
const g = svg.append('g');
// create 15 circles
const numCircles = 55;
const circles = [];
for (let i = 0; i < numCircles; i += 1) {
circles.push({ x: 1 + Math.floor(Math.random() * width),
y: 1 + Math.floor(Math.random() * height),
r: 1 + Math.floor(Math.random() * maxR) });
}
g.selectAll('circle')
.data(circles)
.enter()
.append('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', d => d.r)
.style('fill', 'red')
.style('opacity', 0.2)
.style('stroke', 'black')
.style('stroke-width', '1px')
.classed('no-zoom', true);
const zoom = d3.zoom()
.filter(() => !d3.event.path[0].classList.contains('no-zoom'))
.on('zoom', (d) => { g.attr('transform', d3.event.transform); });
const texts = [
"The red circles don't allow",
'scroll-wheel zooming or',
'drag-based panning'
];
svg.selectAll('text')
.data(texts)
.enter()
.append('text')
.attr('x', 22)
.attr('y', (d, i) => 40 + (i * 26))
.style('-webkit-user-select', 'none') /* Chrome/Safari */
.style('-moz-user-select', 'none') /* Firefox */
.style('-ms-user-select', 'none') /* IE10+ */
.text(d => d);
svg.call(zoom);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment