|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<style> |
|
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } |
|
|
|
.line { |
|
fill: none; |
|
opacity: 0.9; |
|
stroke-width: 1.5px; |
|
} |
|
|
|
.line--x { |
|
stroke: steelblue; |
|
} |
|
|
|
.line--y { |
|
stroke: coral; |
|
} |
|
|
|
.line--z { |
|
stroke: purple; |
|
} |
|
|
|
.line--fade { |
|
stroke-width: 1.4px; |
|
opacity: 0.5; |
|
} |
|
|
|
.line--hover { |
|
stroke-width: 2px; |
|
opacity: 1.0; |
|
} |
|
|
|
div.tooltip { |
|
position: absolute; |
|
text-align: center; |
|
pointer-events: none; |
|
|
|
line-height: 1; |
|
font-weight: bold; |
|
padding: 8px; |
|
background: rgba(0, 0, 0, 0.6); |
|
color: #fff; |
|
border-radius: 2px; |
|
} |
|
|
|
/* Creates a small triangle extender for the tooltip */ |
|
div.tooltip:after { |
|
clear; |
|
box-sizing: border-box; |
|
display: inline; |
|
font-size: 11px; |
|
top: 95%; |
|
left: 50%; |
|
line-height: 1; |
|
color: rgba(0, 0, 0, 0.6); |
|
content: "\25BC"; |
|
position: absolute; |
|
text-align: center; |
|
} |
|
|
|
</style> |
|
</head> |
|
|
|
<body> |
|
<script> |
|
// set the dimensions and margins of the graph |
|
var margin = {top: 20, right: 40, bottom: 30, left: 50}, |
|
width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom; |
|
|
|
// the different dimensions in the data |
|
var dims = ['x', 'y', 'z']; |
|
|
|
// set x-range |
|
var x = d3.scaleLinear().range([0, width]); |
|
|
|
// set the y-ranges |
|
var Y = {} |
|
dims.forEach(dim => { |
|
Y[dim] = d3.scaleLinear().range([height, 0]); |
|
}); |
|
|
|
// define the line functions for each dimension |
|
var lines = {} |
|
dims.forEach(dim => { |
|
lines[dim] = d3.line() |
|
.x(d => x(d.tick)) |
|
.y(d => Y[dim](d[dim])); |
|
}); |
|
|
|
// tooltip |
|
var div = d3.select("body").append("div") |
|
.attr("class", "tooltip") |
|
.style("opacity", 0); |
|
|
|
// create the svg object |
|
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 + ")"); |
|
|
|
// process the data |
|
d3.csv("accel-data.csv",(error, data) => { |
|
if (error) throw error; |
|
|
|
// Parse the data |
|
data.forEach(d => { |
|
d.tick = +d.tick; |
|
d.x = +d.x; |
|
d.y = +d.y; |
|
d.z = +d.z; |
|
}); |
|
// Set domain scales |
|
x.domain(d3.extent(data, d => d.tick)); |
|
for(var dim of dims) { |
|
Y[dim].domain(d3.extent(data, d => d[dim])); |
|
} |
|
|
|
// Draw Paths |
|
for (var dim of dims) { |
|
svg.append("path") |
|
.data([data]) |
|
.attr("class", "line line--"+dim) |
|
.attr("name", dim) |
|
.attr("d", d => lines[dim](d)) |
|
.on("mouseover", mouseover) |
|
.on("mouseout", mouseout) |
|
} |
|
|
|
// Add the X Axis |
|
svg.append("g") |
|
.attr("transform", "translate(0," + height + ")") |
|
.call(d3.axisBottom(x)); |
|
|
|
// Add the Y Axis (Note how we only need one axis) |
|
svg.append("g") |
|
.attr("class", "axisSteelBlue") |
|
.call(d3.axisLeft(Y['x'])); |
|
|
|
// mouseover function |
|
function mouseover(d) { |
|
var name = d3.select(this).attr("name"); |
|
|
|
// highlight this line, fade other lines |
|
d3.selectAll(".line").classed("line--hover", (d, i) => { |
|
return (name === dims[i]); |
|
}).classed("line--fade", (d, i) => { |
|
return (name !== dims[i]); |
|
}); |
|
|
|
// display tooltip |
|
div.transition() |
|
.duration(200) |
|
.style("opacity", 1); |
|
div.html("accelerometer - " + name) |
|
.style("left", (d3.event.pageX - 70) + "px") |
|
.style("top", (d3.event.pageY - 40) + "px"); |
|
} |
|
|
|
// mouseout function |
|
function mouseout(d) { |
|
// turn off hover and fade effects |
|
d3.selectAll(".line") |
|
.classed("line--hover", false) |
|
.classed("line--fade", false); |
|
|
|
// hide tooltip |
|
div.transition() |
|
.duration(500) |
|
.style("opacity", 0); |
|
} |
|
}); |
|
|
|
</script> |
|
</body> |