NOTE: Always take the strong axis motion using the .v2 extension. All units in ‘cm/sec2’ with a 0.2 second interval from the uncorrected data
Built with blockbuilder.org
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
const width = 960;
const height = 500;
const margin = {top: 0, right: 0, bottom: 0, left: 0};
const interval = 0.2; // second per point
const svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
const gLine = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const gBar = svg.append('g');
const xScale = d3.scaleLinear()
.rangeRound([0, width]);
const yScale = d3.scaleLinear()
.rangeRound([height, 0]);
const colorScale = d3.scaleSequential(d3.interpolateReds)
const line = d3.line()
.x(function(d, i) { return xScale(i); })
.y(function(d) { return yScale(d); });
d3.json('data.json', function(err, data){
const pixelsPerBar = 2;
const rawDataPoints = data.acceleration.length;
const totalResponseTime = rawDataPoints * interval;
const barCount = width / pixelsPerBar;
const pointsPerBin = rawDataPoints / barCount;
// Hack: just take averages in the meantime
const binnedAcceleration = data.acceleration
.reduce(createBins, [[]])
.map((bin) => d3.mean(bin));
const max = d3.max(binnedAcceleration);
const min = d3.min(binnedAcceleration);
const greatest = Math.max(max, Math.abs(min));
xScale.domain([0, barCount]);
yScale.domain([min, max]);
colorScale.domain([0, greatest]);
gBar.selectAll('.bars')
.data(binnedAcceleration).enter()
.append('rect')
.attr('class', 'bars')
.attr('width', pixelsPerBar)
.attr('height', height)
.attr('x', (d, i) => i * pixelsPerBar)
.attr('y', 0)
.attr('fill', (d) => colorScale(Math.abs(d)))
gLine.append('g')
.attr('transform', `translate(0,${height})`)
.attr('opacity', 0)
.attr('class', 'line-graph')
.call(d3.axisBottom(xScale))
.select('.domain')
.remove();
// gLine.append('g')
// .call(d3.axisLeft(yScale))
// .append('text')
// .attr('fill', '#000')
// .attr('transform', 'rotate(-90)')
// .attr('y', 6)
// .attr('dy', '0.71em')
// .attr('text-anchor', 'end')
// .text('Acceleration');
gLine.append('path')
.datum(binnedAcceleration)
.attr('fill', 'none')
.attr('stroke', colorScale(max / 4))
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1)
.attr('d', line);
gLine.append('g')
.append('text')
.attr('fill', '#000')
.attr('transform', `translate(${width}, 0)`)
//.attr('y', 6)
//.attr('dy', '0.71em')
//.attr('text-anchor', 'end')
.text(`${totalResponseTime}s`);
let toggle = true;
setInterval(() => {
d3.selectAll('.bars')
.transition().duration(2000)
.attr('fill', toggle ? colorScale(max / 4) : (d) => colorScale(Math.abs(d)))
.attr('height', toggle ? 0 : height)
.attr('y', toggle ? yScale : 0);
d3.selectAll('.line-graph')
.transition().delay(1000).duration(1000)
.attr('opacity', toggle ? 1 : 0)
d3.selectAll('.line-graph')
.transition().delay(1000).duration(1000)
.attr('opacity', toggle ? 1 : 0)
toggle = !toggle;
}, 2000)
function createBins(bins, currentValue, currentIndex) {
const lastBin = bins[bins.length - 1];
const binFilledUp = lastBin.length >= pointsPerBin;
binFilledUp ? bins.push([currentValue]) : lastBin.push(currentValue);
return bins;
}
})
</script>
</body>