viewof coeffs = {
let node = DOM.svg(w, h),
svg = d3.select(node)
svg.style('overflow', 'visible')
let ret = dft(samples.map(d => d.v))
ret.forEach((c,k) => c.index = k)
let y = yFreq, x = xFreq
let bind = function(d,i) {
let [xIn,yIn] = d3.mouse(this)
let j = ret.length - i
if (i != 0 && i != j) {
ret[i].re = x.invert(xIn)
ret[i].im = y.invert(yIn)
ret[j].re = ret[i].re
ret[j].im = -ret[i].im
}
else {
ret[i].re = x.invert(xIn)
}
svg.selectAll('circle.coeff')
.attr('cx', (d) => x(d.re))
.attr('cy', (d) => y(d.im))
node.dispatchEvent(new CustomEvent('input'))
}
let r = (mag) => xFreq(mag - .5)
svg.selectAll('circle')
.data([ .5, .3, .2, .1 ]).join('circle')
.attr('cx', x(0)).attr('cy', y(0))
.attr('r', d => r(d) )
.style('fill', 'none').style('stroke', 'lightgray')
svg.selectAll('circle.coeff')
.data(ret).join('circle')
.attr('class', 'coeff')
.attr('cx', (d) => x(d.re))
.attr('cy', (d) => y(d.im))
.attr('r', 5)
.style('fill', 'white')
.style('stroke', (_,i) => blues[i])
.style('stroke-width', 3)
.call(d3.drag().on('drag', bind))
node.value = ret
return node
}