Published
Edited
Feb 1, 2021
18 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let svgNode = DOM.svg(width*1, height*1);
let svg = d3.select(svgNode).style("background","#011a2a").attr("viewBox", [0, 0, width, height]);
for(var ii=0; ii<=300; ii++){
sim.tick();
}
var myline = d3.line()
.curve(d3.curveCardinalClosed.tension(0.1))
.x(d => d.x)
.y(d => d.y);
sim.on('end', function() {
let g = svg.selectAll('.group')
.data(dataset).enter()
.append('g')
.attr("class","group")
.attr("transform",d => "translate("+((d.y-height/2)*7.3+height/2)+","+(d.x*1.01+10)+")");
const discs = g.selectAll('.discs')
.data((d)=> {return d.r_vec
.map(rr => {
let ppp = d3.randomUniform(0,Math.PI*2)();
return (
{Voice: d.Voice,
PitchClass: d.PitchClass,
poly: d3.range(9)
.map(x => {
let pp = d3.randomUniform(0,0.05)();
return ({x: rr*Math.cos(2*Math.PI/9*x+pp+ppp),
y: rr*Math.sin(2*Math.PI/9*x+pp+ppp)})}),
r: rr})})})
.enter()
.append('path')
.attr("stroke","#011a2a")
.attr("stroke-opacity",0.993)
.attr("stroke-width",2.0)
.attr("fill",d => d3.scalePow()
.domain([0,90])
.range(["#012a4a",colorScale(d.PitchClass)])(d.r))
.attr("d",d => myline(d.poly))
.attr("class","discs")
.append("title").text(d=>d.Voice);

});

return svgNode;
}
Insert cell
d3.range(7).map(x => {return ({x: Math.cos(2*Math.PI/7*x),
y: Math.sin(2*Math.PI/7*x)
})})
Insert cell
rScale = d3.scaleLinear()
.domain(d3.extent(dataset.map(x=>Math.sqrt(x.dur))))
.range([4, 16]);
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function pitch2freq(pitchClass, octave){
// i do this kinda like a 2 digit number in base 12
// where "pitchClass" is the LSB and "octave" is the MSB
// kinda...
return(C0 * Math.pow(2, (octave + pitchClass/12)))
}
Insert cell
md` Test A4. According to my code it has a f = ${pitch2freq(9,4)} Hz. Dope, it works 🎉`
Insert cell
Insert cell
Insert cell
dataset = d3.csvParse(await FileAttachment("moon@1.csv").text(), function(d){
var pn = +Number(d["Pitch Num"]);
var o = +Number(d.Octave);
var f = pitch2freq(pn, o);
return {ID : d.ID,
Voice: d.Voice,
PitchClass: d["Pitch Class"],
PitchNum: pn,
Octave: o,
Start: +d.Start,
Stop: +d.Stop,
dur: d.Stop - d.Start,
freq: f,
lambda: 331/f,
r_vec: d3.range(90,1,-1*331/f-4)
//r_vec: d3.range(70,1,-6)
}
})
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more