3 Things I learned
Generating a scatter plot
Scales and Axes
Transitions of lines,objects
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>D3 scatterplot and transition</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style type="text/css"> | |
body{margin:10px;} | |
circle { | |
fill:#ccc; | |
stroke:#000; | |
pointer-events:none; | |
} | |
#button {position:absolute;top:10px;left:400px;} | |
#title {position:absolute;top:12px;left:0px;width:500px;text-align:center;} | |
.btn { display:inline-block;*display:inline;/* IE7 inline-block hack */ *zoom:1;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#ffffff,#e6e6e6);background-image:-ms-linear-gradient(top,#ffffff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#ffffff,#e6e6e6);background-image:-o-linear-gradient(top,#ffffff,#e6e6e6);background-image:linear-gradient(top,#ffffff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);border:1px solid #cccccc;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);cursor:pointer;*margin-left:.3em;} .btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled] { background-color:#e6e6e6;} .btn:active,.btn.active { background-color:#cccccc \9;} .btn:first-child { *margin-left:0;} .btn:hover { color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} .btn:focus { outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} .btn.active,.btn:active { background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;outline:0;} .btn.disabled,.btn[disabled] { cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .btn-mini { padding:2px 6px;font-size:11px;line-height:14px;} | |
} | |
svg {border:1px solid black;} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 17px; | |
} | |
</style> | |
<script src="http://d3js.org/d3.v2.min.js?2.8.1"></script> | |
<div id="chart" style="width:500px;height:250px"> | |
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="200"> | |
</svg> | |
<div id="title">Movement</div> | |
<button class="btn btn-mini" id="button">Transition</button> | |
</div> | |
</head> | |
<body> | |
<script> | |
var w = 500; | |
var h = 300; | |
var padding = 40; | |
var dataset = []; | |
var numDataPoints = 50; | |
var xRange = Math.random() * 1000; | |
var yRange = Math.random() * 1000; | |
for (var i = 0; i < numDataPoints; i++) { | |
var newNumber1 = Math.round(Math.random() * xRange); | |
var newNumber2 = Math.round(Math.random() * yRange); | |
dataset.push([newNumber1, newNumber2]); | |
} | |
var xScale = d3.scale.linear() | |
.domain([0, d3.max(dataset, function(d) { return d[0]; })]) | |
.range([padding, w - padding * 2]); | |
var yScale = d3.scale.linear() | |
.domain([0, d3.max(dataset, function(d) { return d[1]; })]) | |
.range([h - padding, padding]); | |
var rScale = d3.scale.linear() | |
.domain([0, d3.max(dataset, function(d) { return d[1]; })]) | |
.range([2, 5]); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(5); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.ticks(5); | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
svg.selectAll("circle") | |
.data(dataset) | |
.enter() | |
.append("circle") | |
.attr("cx", function(d) { | |
return xScale(d[0]); | |
}) | |
.attr("cy", function(d) { | |
return yScale(d[1]); | |
}) | |
svg.selectAll("text") | |
.data(dataset) | |
.enter() | |
.append("text") | |
.text(function(d) { | |
return d[0] + "," + d[1]; | |
}) | |
.attr("x", function(d) { | |
return xScale(d[0]); | |
}) | |
.attr("y", function(d) { | |
return yScale(d[1]); | |
}) | |
.attr("font-family", "sans-serif") | |
.attr("font-size", "9px") | |
.attr("fill", "blue"); | |
svg.append("g") | |
.attr("class", "axis") | |
.attr("transform", "translate(0," + (h - padding) + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "axis") | |
.attr("transform", "translate(" + padding + ",0)") | |
.call(yAxis); | |
</script> | |
<script> | |
data={ | |
title:"Line chart (unrolling)", | |
shapes:[ | |
{ | |
type:"path", | |
init:{ | |
attr:{ | |
"d":"m0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120L0,120" | |
}, | |
style:{stroke:"blue","stroke-width":2,fill:"none"} | |
}, | |
transition:{duration:50,delay:50,ease:"linear",attr:{"d":"m0,120L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110L20,110"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170L40,170"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190L60,190"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180L80,180"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160L100,160"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165L120,165"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140L140,140"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120L160,120"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130L180,130"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150L200,150"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130L220,130"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120L240,120"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110L260,110"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L280,90L280,90L280,90L280,90L280,90L280,90L280,90L280,90L280,90L280,90L280,90"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L300,80L300,80L300,80L300,80L300,80L300,80L300,80L300,80L300,80L300,80"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L320,85L320,85L320,85L320,85L320,85L320,85L320,85L320,85L320,85"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L340,100L340,100L340,100L340,100L340,100L340,100L340,100L340,100"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L360,90L360,90L360,90L360,90L360,90L360,90L360,90"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L380,80L380,80L380,80L380,80L380,80L380,80"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L400,70L400,70L400,70L400,70L400,70L400,70"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L400,70L420,50L420,50L420,50L420,50L420,50"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L400,70L420,50L440,45L440,45L440,45L440,45"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L400,70L420,50L440,45L460,50L460,50L460,50"}, | |
next:{duration:25,ease:"linear",attr:{"d":"m0,120L20,110L40,170L60,190L80,180L100,160L120,165L140,140L160,120L180,130L200,150L220,130L240,120L260,110L280,90L300,80L320,85L340,100L360,90L380,80L400,70L420,50L440,45L460,50L500,40L500,40"}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
} | |
}} | |
] | |
}; | |
var svg=d3.select("svg"); | |
svg.selectAll(".vline").data(d3.range(26)).enter() | |
.append("line") | |
.attr("x1",function(d){return d*20;}) | |
.attr("x2",function(d){return d*20;}) | |
.attr("y1",function(d){return 40;}) | |
.attr("y2",function(d){return 250;}) | |
.style("stroke","#eee"); | |
svg.selectAll(".vline").data(d3.range(2,13)).enter() | |
.append("line") | |
.attr("y1",function(d){return d*20;}) | |
.attr("y2",function(d){return d*20;}) | |
.attr("x1",function(d){return 0;}) | |
.attr("x2",function(d){return 500;}) | |
.style("stroke","#eee"); | |
var button=d3.select("#button"); | |
if (data.button==="none") {button.remove();} | |
var mode=0; | |
var modes=[{state:"init",title:"Transition"},{state:"transition",title:"Reset"}]; | |
d3.select("#title").html(data.title); | |
data.shapes.forEach(function(d,i) { | |
var myshape=svg.append(d.type).attr("id","s"+i); | |
var state=d.init; | |
set(myshape,state); | |
}) | |
button.on("click",function() { | |
mode=1-mode; | |
button.html(modes[mode].title); | |
data.shapes.forEach(change) | |
}); | |
function change(d,i){ | |
var state=d[modes[mode].state]; | |
var myshape=svg.select("#s"+i).transition().duration(state.duration||1000).delay(state.delay||0).ease(state.ease||"cubic-in-out"); | |
set(myshape,state); | |
} | |
function set(selection,state,createTransition) { | |
if(state.remove) { | |
selection.remove();return; | |
} | |
d3.keys(state.attr).forEach(function(a) { | |
selection.attr(a, state.attr[a]); | |
}); | |
if (state.text) { | |
selection.text(state.text); | |
}; | |
d3.keys(state.style).forEach(function(s) { | |
selection.style(s, state.style[s]); | |
}); | |
if(state.next) { | |
var next=state.next; | |
if (next.type) { | |
selection.each("end",function() { | |
set(svg.append(next.type),next,true); | |
}) | |
} | |
else { | |
if(createTransition) { | |
selection=selection.transition().duration(0); | |
} | |
selection.each("end",function() { | |
set(d3.select(this).transition().duration(next.duration||1000).delay(next.delay||0).ease(state.ease||"cubic-in-out"),next); | |
}); | |
} | |
} | |
} | |
</script> | |
</body> | |
</html> |