|
function melodyChart() { |
|
var settings = { |
|
chartContainerClass: ".g-chart-container-melody-chart" |
|
}; |
|
|
|
var chartContainer = d3.select(settings.chartContainerClass).html(''); |
|
|
|
var margin = { |
|
top:40, |
|
left:100, |
|
right:140, |
|
bottom:40 |
|
}; |
|
|
|
var w = chartContainer.node().clientWidth - margin.left - margin.right, |
|
h = 600 - margin.top - margin.bottom; |
|
|
|
d3.queue() |
|
.defer(d3.csv, "note-frequency.csv") |
|
.defer(d3.csv, "melody.csv") |
|
.await(ready); |
|
|
|
function ready(error, freqD, melodyD) { |
|
if (error) throw "error: not loading data, bro"; |
|
|
|
melodyD.forEach(function(d){ |
|
d.beats = +d.beats; |
|
}); |
|
|
|
var freqRange = freqD.map(function(d){ |
|
return d.freq; |
|
}); |
|
|
|
var freqByNote = {}; |
|
freqD.forEach(function(d){ |
|
freqByNote[d.note] = +d.freq; |
|
}); |
|
|
|
melodyD.forEach(function(d,i){ |
|
var indexM = melodyD[i]; |
|
var sliced = melodyD.slice(0,i); |
|
var total = 1; |
|
sliced.forEach(function(d){ |
|
total += d.beats; |
|
return total; |
|
}); |
|
d.songPos = total; |
|
}); |
|
|
|
function axisSum(input, pos){ |
|
if (pos !== undefined) { |
|
} |
|
var total = 0; |
|
for(var i=0;i<input.length;i++) { |
|
total += Number(input[i].beats); |
|
} |
|
return total; |
|
} |
|
|
|
var totalBeats = axisSum(melodyD); |
|
|
|
var yscale = d3.scaleLinear() |
|
.domain([0,200]) |
|
.range([h,0]); |
|
|
|
var yaxis = d3.axisRight() |
|
.scale(yscale) |
|
.tickFormat(d3.format(".4r")) |
|
.tickSize(w); |
|
|
|
var xscale = d3.scaleLinear() |
|
.domain([1,totalBeats+1]) |
|
.range([0, w]); |
|
|
|
var xaxis = d3.axisBottom(xscale) |
|
.ticks(totalBeats) |
|
.tickSize(-h); |
|
|
|
var svg = chartContainer |
|
.append("svg") |
|
.attr("width", w + margin.left + margin.right) |
|
.attr("height", h + margin.top + margin.bottom) |
|
.append("g.wrap") |
|
.translate([margin.left,margin.top]); |
|
|
|
svg |
|
.append("text.x-axis-label") |
|
.translate([w/2,h+margin.bottom]) |
|
.attr("text-anchor","middle") |
|
.text("Beats"); |
|
|
|
svg |
|
.append("text.y-axis-label") |
|
.attr("transform","translate("+ (w+70) + "," + h/2 +"), rotate(90)") |
|
.attr("text-anchor","middle") |
|
.text("Note Frequency"); |
|
|
|
svg.append("g.y-axis") |
|
.call(yaxis); |
|
|
|
svg.append("g.x-axis") |
|
.translate([0,h]) |
|
.call(xaxis); |
|
|
|
var ticks = d3.selectAll(".x-axis .tick"); |
|
ticks.attr("class", function(d,i){ |
|
var self = d3.select(this); |
|
if(i%4 != 0) { |
|
self.select("text").text(""); |
|
return "up-beat"; |
|
} else { |
|
self.select("text").text("1"); |
|
return "down-beat"; |
|
} |
|
}); |
|
|
|
var lineGen2 = d3.line() |
|
.x( function(d){ return xscale(d.songPos); }) |
|
.y( function(d){ return yscale(freqByNote[d.note]); }); |
|
|
|
svg.append("path.path") |
|
.attr("d", lineGen2(melodyD)); |
|
|
|
var dots = svg |
|
.selectAll("g.dot-note") |
|
.data(melodyD) |
|
.enter() |
|
.append("g.cov-dot") |
|
.attr("transform", function(d){ return "translate(" + xscale(d.songPos) +","+ yscale(freqByNote[d.note]) +")" ; }); |
|
|
|
dots |
|
.append("circle") |
|
.attr("r", 3); |
|
|
|
dots |
|
.append("text") |
|
.text(function(d){ |
|
var note = d.note; |
|
note = note.replace(/[0-9]/g, ''); |
|
note = note.toUpperCase(); |
|
return note; |
|
}) |
|
.attr("dy",-10) |
|
.attr("text-anchor","middle"); |
|
} |
|
} |
|
|
|
$( window ).resize(fireAll); |
|
function fireAll() { |
|
melodyChart(); |
|
} |
|
// pageload fire |
|
;(function(){ |
|
melodyChart(); |
|
})(); |