Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:14
Show Gist options
  • Save nitaku/a916fb443e71f593ca16 to your computer and use it in GitHub Desktop.
Save nitaku/a916fb443e71f593ca16 to your computer and use it in GitHub Desktop.
Interactive rota II
svg = d3.select('svg')
zoom_group = svg.select('#zoom_group')
# define a zoom behavior
zoom = d3.behavior.zoom()
.scaleExtent([1,4]) # min-max zoom
.on 'zoom', () ->
# GEOMETRIC ZOOM
zoom_group
.attr
transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})"
# bind the zoom behavior to the main SVG
svg.call(zoom)
rota_1 = svg.select('#rota_1')
.datum({
offset: 6,
pinch_offset: null
})
rota_1
.transition().duration(1200)
.attr('transform', 'rotate('+rota_1.datum().offset+')')
# define a drag behavior to let the user rotate the arcs
dragging = false
drag = d3.behavior.drag()
.on 'dragstart', () ->
# silence other listeners (disable pan when dragging)
# see https://github.com/mbostock/d3/wiki/Drag-Behavior
d3.event.sourceEvent.stopPropagation()
dragging = true
# highlight
d3.select(this).classed('highlighted', true)
.on 'drag', () ->
rota = d3.select(this)
d = rota.datum()
if not d.pinch_offset?
d.pinch_offset = 180/Math.PI*Math.atan2(d3.event.y,d3.event.x)+180-d.offset
# current angle in positive degrees
angle = 180/Math.PI*Math.atan2(d3.event.y, d3.event.x)+180
d.offset = angle-d.pinch_offset
rota
.attr('transform', 'rotate('+d.offset+')')
.on 'dragend', () ->
d3.select(this).datum().pinch_offset = null
dragging = false
# highlight
d3.select(this).classed('highlighted', false)
highlight = (rota) ->
rota
.on 'mousemove', () ->
# highlight
if not dragging
d3.select(this).classed('highlighted', true)
.on 'mouseout', () ->
# highlight
if not dragging
d3.select(this).classed('highlighted', false)
rota_1
.call(drag)
.call(highlight)
d3.select(self.frameElement).style('height', '800px')
svg {
background: #0C0C0C;
}
.rota {
cursor: move;
}
.rota .highlight {
display: none;
fill: yellow;
opacity: 0.06;
}
.rota.highlighted .highlight {
display: inline;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Interactive rota"/>
<title>Interactive rota</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<svg height="800" width="960">
<defs>
<pattern id="rota_img"
patternUnits="userSpaceOnUse"
x="-491"
y="-427"
width="800"
height="800"
viewBox="0 0 800 800">
<image
xlink:href="http://wafi.iit.cnr.it/webvis/tmp/clavius/rota_2.jpg"
x="80"
y="0"
height="800"
width="800"
/>
</pattern>
</defs>
<g id="zoom_group">
<g transform="translate(491,427)">
<rect
fill="url(#rota_img)"
x="-491"
y="-427"
width="800"
height="800"
/>
<g id="rota_1" class="rota">
<circle
fill="url(#rota_img)"
cx="0"
cy="0"
r="117"
/>
<circle
class="highlight"
cx="0"
cy="0"
r="117"
/>
</g>
<circle
fill="url(#rota_img)"
cx="0"
cy="0"
r="17"
/>
</g>
</g>
</svg>
<script src="index.js"></script>
</body>
</html>
(function() {
var drag, dragging, highlight, rota_1, svg, zoom, zoom_group;
svg = d3.select('svg');
zoom_group = svg.select('#zoom_group');
zoom = d3.behavior.zoom().scaleExtent([1, 4]).on('zoom', function() {
return zoom_group.attr({
transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"
});
});
svg.call(zoom);
rota_1 = svg.select('#rota_1').datum({
offset: 6,
pinch_offset: null
});
rota_1.transition().duration(1200).attr('transform', 'rotate(' + rota_1.datum().offset + ')');
dragging = false;
drag = d3.behavior.drag().on('dragstart', function() {
d3.event.sourceEvent.stopPropagation();
dragging = true;
return d3.select(this).classed('highlighted', true);
}).on('drag', function() {
var angle, d, rota;
rota = d3.select(this);
d = rota.datum();
if (d.pinch_offset == null) {
d.pinch_offset = 180 / Math.PI * Math.atan2(d3.event.y, d3.event.x) + 180 - d.offset;
}
angle = 180 / Math.PI * Math.atan2(d3.event.y, d3.event.x) + 180;
d.offset = angle - d.pinch_offset;
return rota.attr('transform', 'rotate(' + d.offset + ')');
}).on('dragend', function() {
d3.select(this).datum().pinch_offset = null;
dragging = false;
return d3.select(this).classed('highlighted', false);
});
highlight = function(rota) {
return rota.on('mousemove', function() {
if (!dragging) {
return d3.select(this).classed('highlighted', true);
}
}).on('mouseout', function() {
if (!dragging) {
return d3.select(this).classed('highlighted', false);
}
});
};
rota_1.call(drag).call(highlight);
d3.select(self.frameElement).style('height', '800px');
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment