{
const height = 400
const svg = d3.select(DOM.svg(width, height))
const margin = { left: 70, top: 10, right: 30, bottom: 50 }
const rankingOnDate = (date) => {
const dateString = moment(date).format('YYYY-MM-DD')
const data = spotifyDailyGlobalRanking.filter(d => d.date === dateString)
return spotifySongs.map(song => {
const ranking = _.find(data, { trackId: song.trackId })
return ranking || { trackId: song.trackId, streams: 0 }
})
}
const xScale = d3.scaleBand()
.padding(0.1)
.range([margin.left, width - margin.right])
.domain(spotifySongs.map(song => song.trackId))
svg.append('g')
.call(d3.axisBottom(xScale)
.tickFormat(v => _.find(spotifySongs, { trackId: v }).trackName.substr(0, 15)))
.attr('transform', `translate(0,${height - margin.bottom})`)
const yScale = d3.scaleLinear()
.range([height - margin.bottom, margin.top])
.domain([0, maxDailyStreams])
svg.append('g')
.call(d3.axisLeft(yScale).tickFormat(d3.format('.2s')))
.attr('transform', `translate(${margin.left},0)`)
const dateText = svg.append('text')
.text(`Spotify Streams on ${moment([2017, 0, 1]).format('YYYY-MM-DD')}`)
.attr('transform', `translate(${width - 300}, 20)`)
const bars = svg.selectAll('rect')
.data(rankingOnDate('2017-01-01'))
.enter()
.append('rect')
.attr('x', d => xScale(d.trackId))
.attr('y', d => yScale(d.streams))
.attr('height', d => yScale(0) - yScale(d.streams))
.attr('width', xScale.bandwidth())
.attr('fill', 'SteelBlue')
let date = moment([2017, 0, 1])
while (true) {
yield svg.node();
date = date.add(1, 'd')
if (date.isAfter([2017, 11, 31])) break
dateText.text(`Spotify Streams on ${date.format('YYYY-MM-DD')}`)
await bars
.data(rankingOnDate(date))
.transition()
.duration(500)
.ease(d3.easeCubic)
.attr('y', d => yScale(d.streams))
.attr('height', d => yScale(0) - yScale(d.streams))
.end()
}
}