|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title>D3 SVG Tiger</title> |
|
</head> |
|
<body> |
|
|
|
<button id="update">Update</button> |
|
<div id="placeholder"></div> |
|
|
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script> |
|
|
|
var WIDTH = 640; |
|
var HEIGHT = 480; |
|
var SVG_URL = 'http://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg'; |
|
var svg = null; |
|
var importedNode = null; |
|
var buttonToggle = true; |
|
|
|
var init = function(callback) { |
|
// Create the SVG container. |
|
svg = d3.select('#placeholder') |
|
.append('svg') |
|
.attr('width', WIDTH) |
|
.attr('height', HEIGHT) |
|
.style('background', 'white'); |
|
|
|
// Import the tiger. |
|
d3.xml(SVG_URL, 'image/svg+xml', function(xmlDoc) { |
|
importedNode = document.importNode(xmlDoc.documentElement, true); |
|
callback(); |
|
}); |
|
}; |
|
|
|
var createTransformation = function(translateX, translateY, scale) { |
|
return 'translate(' + translateX + ',' + translateY + ')scale(' + scale + ')'; |
|
}; |
|
|
|
var positionAndSizeTiger = function(tiger) { |
|
tiger |
|
.attr('transform', function(d) { |
|
return createTransformation( |
|
// translateX: 100 years old * 6 ~= 640 |
|
(d.age * 6), |
|
// translateY: 200 cm high * 2 ~= 480 |
|
(HEIGHT - d.height * 2), |
|
// scale |
|
(d.weight * 0.0035) |
|
); |
|
}); |
|
}; |
|
|
|
var update = function(error, dataset) { |
|
// Stuff happens. |
|
if (error) { |
|
console.log(error); |
|
window.alert('Oops, looks like we can\'t retreive data properly!'); |
|
return; |
|
} |
|
|
|
// BINDING |
|
var tigers = svg |
|
.selectAll('g.tiger') |
|
// The unique key is the name. |
|
.data(dataset.people, function(d) { return d.name; }); |
|
|
|
// UPDATE |
|
tigers |
|
.transition() |
|
.duration(750) |
|
.call(positionAndSizeTiger) |
|
// Necessary in case we switch quickly between data, and some tigers started |
|
// fading out but are not deleted yet. Then, during the update of the tigers, |
|
// we set it back to the correct opacity. This is because setting a new |
|
// transition on an element is cancelling the previous transition. |
|
.style('opacity', 0.75); |
|
|
|
// ENTER |
|
tigers |
|
.enter() |
|
.append('g') |
|
.attr('class', 'tiger') |
|
.each(function() { |
|
// Append the imported SVG to the group element. |
|
this.appendChild(importedNode.cloneNode(true)); |
|
}) |
|
.style('opacity', 0) |
|
.call(positionAndSizeTiger) |
|
.transition() |
|
.duration(750) |
|
.style('opacity', 0.75); |
|
|
|
// ENTER + UPDATE |
|
// Nothing here... |
|
|
|
// EXIT |
|
tigers |
|
.exit() |
|
.transition() |
|
.duration(750) |
|
.style('opacity', 0) |
|
.remove(); |
|
}; |
|
|
|
var loadDataAndUpdate = function() { |
|
d3.json(buttonToggle ? 'example-2000.json' : 'example-2005.json', update); |
|
buttonToggle = !buttonToggle; |
|
}; |
|
|
|
init(loadDataAndUpdate); |
|
d3.select('#update').on('click', loadDataAndUpdate); |
|
|
|
</script> |
|
</body> |
|
</html> |