console.clear()
var sel = d3.select('body').html('')
var c = d3.conventions({sel, layers: 'csd', margin: {left: 30, bottom: 40}})
var xMax = Math.floor(c.width/2)
c.x.domain([0, xMax])
c.y.domain([0, 100])
d3.drawAxis(c)
var [ctx, svg, div] = c.layers
svg.select('.y').append('text')
.text('ms per frame')
.at({textAnchor: 'start', x: -25, y: 15, fill: '#000'})
var points = d3.range(150)
.map(d => [Math.random()*c.width, Math.random()*c.height])
points.forEach(d => {d.vx = 0, d.vy = 0})
var r = 6
var svgCircles = svg.appendMany('circle', points)
.translate(d => d)
.at({r, fill: '#0ff', stroke: '#0ff', fillOpacity: .2})
var divCircles = div.appendMany('div', points)
.translate(d => d)
.st({
position: 'absolute',
width: r*2,
height: r*2,
left: -r,
top: -r,
borderRadius: r*2 + 'px',
background: 'rgba(255, 0, 255, .2)',
backgroundOpacity: .2,
border: '1px solid #f0f'
})
var i = 0
var prevT = 0
if (window.timer) timer.stop()
timer = d3.timer(t => {
i++
var dt = t - prevT
prevT = t
var color = ['#0ff', '#f0f', '#ff0'][i % 3]
var x = c.x(i)
var y = c.y(dt)
if (i > xMax){
i = i - xMax
c.sel.selectAll('.time-bar').remove()
}
points.forEach(d => {
d.vx = d3.clamp(-3, d.vx + Math.random()*.6 - .6*.5, 3)
d.vy = d3.clamp(-3, d.vy + Math.random()*.6 - .6*.5, 3)
d[0] += d.vx
d[1] += d.vy
if (d[0] < 0 || d[0] > c.width) d.vx = -d.vx
if (d[1] < 0 || d[1] > c.height) d.vy = -d.vy
})
if (i % 3 == 0){
svgCircles.translate(d => d)
svg.append('path.time-bar')
.at({d: `M ${x} ${c.height} V ${y}`, stroke: color})
} else if (i % 3 == 1){
divCircles.translate(d => d)
div.append('div.time-bar')
.st({left: x, top: y, height: c.height - y})
.st({width: 1, background: color, position: 'absolute'})
} else if (i % 3 == 2){
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'
ctx.fillRect(-c.margin.left, -c.margin.top, c.totalWidth, c.totalHeight)
ctx.beginPath()
ctx.fillStyle = 'rgba(255, 255, 0, .2)'
ctx.strokeStyle = '#ff0'
points.forEach(([x, y]) => {
ctx.moveTo(x + r, y)
ctx.arc(x, y, r, 0, 2 * Math.PI)
})
ctx.stroke()
ctx.fill()
ctx.strokeStyle = color
ctx.beginPath()
ctx.moveTo(x, y)
ctx.lineTo(x, c.height)
ctx.stroke()
}
})