Last active
November 29, 2016 05:28
-
-
Save queuebit/99f55f57624b6db17ad7367d776700a3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
*.json |
This file contains hidden or 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> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font: 10px sans-serif; | |
} | |
.dot { | |
stroke: #000; | |
} | |
.overlay { | |
fill: none; | |
pointer-events: all; | |
} | |
.tracking line { | |
stroke-dasharray: 5,5; | |
stroke: red; | |
} | |
.tooltip { | |
position: absolute; | |
width: 200px; | |
height: 28px; | |
pointer-events: none; | |
} | |
</style> | |
<body> | |
<!-- #hattip - http://bl.ocks.org/mbostock/3902569 --> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="//d3js.org/d3-timer.v1.min.js"></script> | |
<script> | |
d3.select("body") | |
.on("keydown", function () { | |
if (d3.event.keyCode === 74) { | |
updatePlayback(-5); | |
console.log('j - back 5 frames'); | |
} else if (d3.event.keyCode === 75) { | |
updatePlayback(0); | |
console.log('k - play/pause'); | |
} else if (d3.event.keyCode === 76) { | |
updatePlayback(5); | |
console.log('l - fwd 5 frames'); | |
} else if (d3.event.keyCode === 188) { | |
updatePlayback(-1); | |
console.log('< - back 1 frame'); | |
} else if (d3.event.keyCode === 190) { | |
updatePlayback(1); | |
console.log('> - fwd 1 frames'); | |
} else if (d3.event.keyCode === 82) { | |
updatePlayback(-fs.length); | |
console.log('r - restart'); | |
} else if (d3.event.keyCode === 72) { | |
console.log('j - back 5 frames'); | |
console.log('l - fwd 5 frames'); | |
console.log('k - play/pause'); | |
console.log('< - back 1 frame'); | |
console.log('> - fwd 1 frames'); | |
console.log('r - restart'); | |
} else { | |
console.log(d3.event.keyCode); | |
} | |
}); | |
var tooltip = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
var margin = {top: 20, right: 20, bottom: 30, left: 40}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var x = d3.scale.linear() | |
.range([0, width]); | |
var y = d3.scale.linear() | |
.range([height, 0]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left"); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var tracking = svg.append("g") | |
.attr("class", "tracking"); | |
var pX = tracking.append("line") | |
.attr("x1", 0).attr("x2", 0) | |
.attr("y1", 0).attr("y2", height) | |
var pY = tracking.append("line") | |
.attr("x1", 0).attr("x2", width) | |
.attr("y1", 0).attr("y2", 0) | |
svg.append("g") | |
.append("rect") | |
.attr("class", "overlay") | |
.attr("width", width) | |
.attr("height", height) | |
.on("mouseover", function() { tracking.style("display", null); }) | |
.on("mouseout", function() { | |
tracking.style("display", "none"); | |
updateCoords(0,0); | |
}) | |
.on("mousemove", function() { | |
var [mx, my] = d3.mouse(this); | |
updateCoords(mx, my); | |
}) | |
var data; | |
var frames; | |
var fs; | |
var fi; | |
var f; | |
var t; | |
var dot; | |
var paused = false; | |
d3.json("frames.json", function(error, json) { | |
if (error) return console.warn(error); | |
frames = json; | |
fs = Object.keys(frames).sort(); | |
fi = 0; | |
f = fs[fi]; | |
data = frames[f]; | |
data.forEach(function(d) { | |
d.x = +d.x; | |
d.y = +d.y; | |
}); | |
//x.domain(d3.extent(data, function(d) { return d.x; })).nice(); | |
//y.domain(d3.extent(data, function(d) { return d.y; })).nice(); | |
x.domain([0,300]) | |
y.domain([350,600]) | |
svg.append("text") | |
.attr("class", "frame") | |
.attr("x", width - 50) | |
.attr("y", 40) | |
.text(f); | |
svg.append("text") | |
.attr("class", "coords") | |
.attr("x", 30) | |
.attr("y", height - 10) | |
.text("0, 0"); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis) | |
.append("text") | |
.attr("class", "label") | |
.attr("x", width) | |
.attr("y", -6) | |
.style("text-anchor", "end") | |
.text("x"); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("class", "label") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("y") | |
t = d3.interval(updateFrame, 10); | |
}); | |
function updateFrame(elapsed) { | |
var svg = d3.select("body > svg"); | |
if (!paused) fi++; | |
if (fi < 0) { | |
fi = 0; | |
} else if (fi >= fs.length) { | |
t.stop(); | |
return; | |
} | |
f = fs[fi]; | |
data = frames[f]; | |
svg.select('text.frame') | |
.text(f); | |
dot = svg.selectAll(".dot") | |
.data(data, function (d) { return d.eid; }); | |
dot.exit().remove(); | |
dot.enter().append("circle") | |
.attr("class", "dot") | |
.attr("r", 2) | |
.attr("cx", function(d) { return x(d.x); }) | |
.attr("cy", function(d) { return y(d.y); }) | |
.on("mouseover", function(d) { | |
tooltip.transition() | |
.duration(100) | |
.style("opacity", .9); | |
tooltip.html(d.eid) | |
.style("left", (d3.event.pageX + 5) + "px") | |
.style("top", (d3.event.pageY - 10) + "px"); | |
}) | |
.on("mouseout", function(d) { | |
tooltip.transition() | |
.duration(200) | |
.style("opacity", 0); | |
}); | |
dot.attr("cx", function(d) { return x(d.x); }) | |
.attr("cy", function(d) { return y(d.y); }); | |
} | |
function updateCoords(mx, my) { | |
var svg = d3.select("body > svg"); | |
pX.transition() | |
.duration(10) | |
.attr("x1", mx).attr("x2", mx) | |
pY.transition() | |
.duration(10) | |
.attr("y1", my).attr("y2", my) | |
svg.select('text.coords') | |
.text(x.invert(mx).toFixed(0) + ", " + y.invert(my).toFixed(0)); | |
} | |
function updatePlayback(frameDelta) { | |
if (frameDelta === 0) { | |
paused = !paused; | |
} else { | |
paused = true; | |
fi += frameDelta; | |
} | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment