Skip to content

Instantly share code, notes, and snippets.

@ErikOnBike
Last active September 30, 2018 14:01
Show Gist options
  • Save ErikOnBike/6a6ff9e033cd883e31e631f8f2ebfbbe to your computer and use it in GitHub Desktop.
Save ErikOnBike/6a6ff9e033cd883e31e631f8f2ebfbbe to your computer and use it in GitHub Desktop.
Render simple transition on multiple SVG paths
license: gpl-3.0
height: 540
scrolling: yes

This example demonstrates using a transition on a (collection of) SVG path in d3-template.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
}
svg {
border: 1px solid #aaaaaa;
}
path {
fill: none;
}
.button {
display: inline-block;
border: 1px solid #aaaaaa;
border-radius: .4em;
width: 4em;
height: 2em;
line-height: 2em;
text-align: center;
cursor: pointer;
/* Prevent selection when clicking repeatedly */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/d3-template-plugin/build/d3-template.min.js"></script>
<svg width="500" height="500">
<g data-repeat="{{d}}">
<path d="M250,250 250,250 250,250 250,250 250,250 250,250 250,250 250,250 Z" data-attr-d="{{coordinatesToPath(d.coords)}}" data-style-stroke="{{d.color}}"></path>
</g>
</svg>
<div>
<span class="button minus">-</span> <span class="button plus">+</span>
</div>
<script>
function coordinatesToPath(d) {
return "M" + d.map(function(coord) { return coord.x + "," + coord.y; }) .join(" ") + "Z";
}
var count = 3;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var repeat = function() {
// Create new data collection
var data = [];
for(var i = 0; i < count; i++) {
// Create 4 corners (in 4 quadrants) randomly
var coords = [
{ x: 200 - (Math.random() * 200 | 0), y: 200 - (Math.random() * 200 | 0) },
{ x: 300 + (Math.random() * 200 | 0), y: 200 - (Math.random() * 200 | 0) },
{ x: 300 + (Math.random() * 200 | 0), y: 300 + (Math.random() * 200 | 0) },
{ x: 200 - (Math.random() * 200 | 0), y: 300 + (Math.random() * 200 | 0) }
];
// Add 4 'middle' points with some randomness
for(var j = 0; j < 8; j += 2) {
coords.splice(j + 1, 0, {
x: (coords[j].x + coords[(j + 1) % coords.length].x) / 2 + (Math.random() * 100 | 0) - 50,
y: (coords[j].y + coords[(j + 1) % coords.length].y) / 2 + (Math.random() * 100 | 0) - 50
});
}
// Add coordinates and color to data collection
data.push({
coords: coords,
color: color(i)
});
}
// Select template and render data on transition
d3.select("svg")
.transition()
.duration(750)
.render(data)
.on("end", function() {
repeat();
})
;
};
// Add event handlers to buttons
d3.select(".button.minus").on("click", function() {
if(count > 1) {
count--;
}
});
d3.select(".button.plus").on("click", function() {
count++;
});
// Create template and start drawing
d3.select("svg").template();
repeat();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment