Created
November 17, 2014 20:27
-
-
Save WilliamQLiu/faaac1a0ecbc124171cf to your computer and use it in GitHub Desktop.
D3 Transitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- Load D3 from site --> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<!-- CSS (Styling) --> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; /* Round any decimal pixels so it'll render nicely */ | |
} | |
/* | |
//Can use CSS3 Transitions, but not for everything (e.g. change radius size) | |
circle:hover{ | |
fill: green; | |
} | |
*/ | |
</style> | |
</head> | |
<body> | |
<!-- Begin Javascript --> | |
<script type="text/javascript"> | |
var w = window.innerWidth, | |
h = window.innerHeight, | |
margin = { top: 40, right: 20, bottom: 20, left: 40 }, | |
radius = 6; | |
var svg = d3.select("body").append("svg").attr({ | |
width: w, | |
height: h | |
}); | |
var dataset = [ | |
{ x: 100, y: 110 }, | |
{ x: 83, y: 43 }, | |
{ x: 92, y: 28 }, | |
{ x: 49, y: 74 }, | |
{ x: 51, y: 10 }, | |
{ x: 25, y: 98 }, | |
{ x: 77, y: 30 }, | |
{ x: 20, y: 83 }, | |
{ x: 11, y: 63 }, | |
{ x: 4, y: 55 }, | |
{ x: 0, y: 0 }, | |
{ x: 85, y: 100 }, | |
{ x: 60, y: 40 }, | |
{ x: 70, y: 80 }, | |
{ x: 10, y: 20 }, | |
{ x: 40, y: 50 }, | |
{ x: 25, y: 31 } | |
]; | |
// We're passing in a function in d3.max to tell it what we're maxing (x value) | |
var xScale = d3.scale.linear() | |
.domain([0, d3.max(dataset, function (d) { return d.x + 10; })]) | |
.range([margin.left, w - margin.right]); // Set margins for x specific | |
// We're passing in a function in d3.max to tell it what we're maxing (y value) | |
var yScale = d3.scale.linear() | |
.domain([0, d3.max(dataset, function (d) { return d.y + 10; })]) | |
.range([margin.top, h - margin.bottom]); // Set margins for y specific | |
// Add a X and Y Axis (Note: orient means the direction that ticks go, not position) | |
var xAxis = d3.svg.axis().scale(xScale).orient("top"); | |
var yAxis = d3.svg.axis().scale(yScale).orient("left"); | |
// New circles will start at 0,0 | |
var circleInitialAttrs = { | |
cx: xScale(0), | |
cy: yScale(0), | |
r: 1 | |
}; | |
// Sets circles attributes | |
var circleAttrs = { | |
cx: function(d) { return xScale(d.x); }, | |
cy: function(d) { return yScale(d.y); }, | |
r: radius | |
}; | |
// Adds X-Axis as a 'g' element | |
svg.append("g").attr({ | |
"class": "axis", // Give class so we can style it | |
transform: "translate(" + [0, margin.top] + ")" // Translate just moves it down into position (or will be on top) | |
}).call(xAxis); // Call the xAxis function on the group | |
// Adds Y-Axis as a 'g' element | |
svg.append("g").attr({ | |
"class": "axis", | |
transform: "translate(" + [margin.left, 0] + ")" | |
}).call(yAxis); // Call the yAxis function on the group | |
var circles = svg.selectAll("circle") | |
.data(dataset) | |
.enter() | |
.append("circle") | |
.attr(circleInitialAttrs) // Get attributes from circleInitialAttrs var | |
.on("mouseover", handleMouseOver) | |
.on("mouseout", handleMouseOut); | |
circles.transition() // Gives the fly out from the center effect | |
.delay(function (d, i){ | |
return i * 100; // Gives a slight delay with 100 ms spacing | |
}) | |
.duration(1000) | |
.ease("elastic") | |
.attr(circleAttrs); | |
// On Click, we want to add data to the array and chart | |
svg.on("click", function() { | |
var coords = d3.mouse(this); | |
// Normally we go from data to pixels, but here we're doing pixels to data | |
var newData= { | |
x: Math.round( xScale.invert(coords[0])), // Takes the pixel number to convert to number | |
y: Math.round( yScale.invert(coords[1])) | |
}; | |
dataset.push(newData); // Push data to our array | |
// When adding new items, goes from 0,0 and transition to place | |
var c = svg.selectAll("circle") // For new circle, go through the update process | |
.data(dataset) | |
.enter() | |
.append("circle") | |
.attr(circleInitialAttrs) | |
.on("mouseover", handleMouseOver) | |
.on("mouseout", handleMouseOut); | |
c.transition() | |
.duration(1000) // Set how long it takes | |
.ease("elastic") // Bounces a bit | |
.attr(circleAttrs); | |
}) | |
// Create Event Handlers for mouse | |
function handleMouseOver(d, i) { // Add interactivity | |
// Use D3 to select element, change color and size | |
d3.select(this).attr({ | |
fill: "orange", | |
r: radius * 2 | |
}); | |
// Specify where to put label of text | |
svg.append("text").attr({ | |
id: "t" + d.x + "-" + d.y + "-" + i, // Create an id for text so we can select it later for removing on mouseout | |
x: function() { return xScale(d.x) - 30; }, | |
y: function() { return yScale(d.y) - 15; } | |
}) | |
.text(function() { | |
return [d.x, d.y]; // Value of the text | |
}); | |
} | |
function handleMouseOut(d, i) { | |
// Use D3 to select element, change color back to normal | |
d3.select(this).attr({ | |
fill: "black", | |
r: radius | |
}); | |
// Select text by id and then remove | |
d3.select("#t" + d.x + "-" + d.y + "-" + i).remove(); // Remove text location | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment