META-INF.resources.scripts.d3-battement.js Maven / Gradle / Ivy
The newest version!
export default function() {
var svg = null;
var circle = null;
var circleTransition = null;
var latestBeat = null;
var insideBeat = false;
var data = [];
var SECONDS_SAMPLE = 5;
var BEAT_TIME = 400;
var TICK_FREQUENCY = SECONDS_SAMPLE * 1000 / BEAT_TIME;
var BEAT_VALUES = [0, 0, 3, -4, 10, -7, 3, 0, 0];
var CIRCLE_FULL_RADIUS = 40;
var MAX_LATENCY = 5000;
var colorScale = d3.scaleLinear()
.domain([BEAT_TIME, (MAX_LATENCY - BEAT_TIME) / 2, MAX_LATENCY])
.range(["#6D9521", "#D77900", "#CD3333"]);
var radiusScale = d3.scaleLinear()
.range([5, CIRCLE_FULL_RADIUS])
.domain([MAX_LATENCY, BEAT_TIME]);
function beat() {
if (insideBeat) return;
insideBeat = true;
var now = new Date();
var nowTime = now.getTime();
if (data.length > 0 && data[data.length - 1].date > now) {
data.splice(data.length - 1, 1);
}
data.push({
date: now,
value: 0
});
var step = BEAT_TIME / BEAT_VALUES.length - 2;
for (var i = 1; i < BEAT_VALUES.length; i++) {
data.push({
date: new Date(nowTime + i * step),
value: BEAT_VALUES[i]
});
}
latestBeat = now;
circleTransition = circle.transition()
.duration(BEAT_TIME)
.attr("r", CIRCLE_FULL_RADIUS)
.attr("fill", "#6D9521");
setTimeout(function() {
insideBeat = false;
}, BEAT_TIME);
}
var svgWrapper = document.getElementById("svg-wrapper");
var margin = {left: 10, top: 10, right: CIRCLE_FULL_RADIUS * 3, bottom: 10},
width = svgWrapper.offsetWidth - margin.left - margin.right,
height = svgWrapper.offsetHeight - margin.top - margin.bottom;
// create SVG
svg = d3.select('#svg-wrapper').append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
circle = svg
.append("circle")
.attr("fill", "#6D9521")
.attr("cx", width + margin.right / 2)
.attr("cy", height / 2)
.attr("r", CIRCLE_FULL_RADIUS);
// init scales
var now = new Date(),
fromDate = new Date(now.getTime() - SECONDS_SAMPLE * 1000);
// create initial set of data
data.push({
date: now,
value: 0
});
var x = d3.scaleTime()
.domain([fromDate, new Date(now.getTime())])
.range([0, width]),
y = d3.scaleLinear()
.domain([-10, 10])
.range([height, 0]);
var line = d3.line()
.curve(d3.curveBasis)
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.value);
});
/*
var xAxis = d3.axisBottom()
.scale(x)
.ticks(d3.timeSeconds, 1)
.tickFormat(function(d) {
var seconds = d.getSeconds() === 0 ? "00" : d.getSeconds();
return seconds % 10 === 0 ? d.getMinutes() + ":" + seconds : ":" + seconds;
});
*/
// add clipPath
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
/*
var axis = d3.select("svg").append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
*/
var path = svg.append("g")
.attr("clip-path", "url(#clip)")
.append("path")
.attr("class", "line");
svg.select(".line")
.attr("d", line(data));
var transition = d3.select("path").transition()
.duration(100)
.ease(d3.easeLinear);
(function tick() {
transition = transition.each(function() {
// update the domains
now = new Date();
fromDate = new Date(now.getTime() - SECONDS_SAMPLE * 1000);
x.domain([fromDate, new Date(now.getTime() - 100)]);
var translateTo = x(new Date(fromDate.getTime()) - 100);
// redraw the line
svg.select(".line")
.attr("d", line(data))
.attr("transform", null)
.transition()
.attr("transform", "translate(" + translateTo + ")");
// slide the x-axis left
// axis.call(xAxis);
}).transition().on("start", tick);
})();
setInterval(function() {
now = new Date();
fromDate = new Date(now.getTime() - SECONDS_SAMPLE * 1000);
for (var i = 0; i < data.length; i++) {
if (data[i].date < fromDate) {
data.shift();
} else {
break;
}
}
if (insideBeat) return;
data.push({
date: now,
value: 0
});
if (circleTransition != null) {
var diff = now.getTime() - latestBeat.getTime();
if (diff < MAX_LATENCY) {
circleTransition = circle.transition()
.duration(TICK_FREQUENCY)
.attr("r", radiusScale(diff))
.attr("fill", colorScale(diff));
}
}
}, TICK_FREQUENCY);
setInterval(function() {
beat();
}, 2000);
beat();
}