chart = {
const data = streams
.filter(x=> x.msPlayed >= 1000*30)
.map(x=> ({...x, hrsPlayed: x.msPlayed/(60*60*1000) }))
const brush = vl.selectInterval().encodings('x');
const top = vl.markBar()
.data(data)
.encode(vl.x().fieldT('endTime').timeUnit('yearmonthdate'),
vl.y().sum('hrsPlayed'))
.select(brush)
.width(width * .83)
.height(125)
.title("Hours Streaming by Day (click and drag to filter top lists by date)")
const bar = (str) => {
const marks =
vl.markBar()
.data(data)
.transform(
vl.filter(brush),
vl.aggregate(vl.count().as('streams')).groupby(str, 'artistName'),
vl.window(vl.row_number().as('Rank')).sort(vl.field('streams').order('descending')),
vl.filter('datum["Rank"]<=15')
)
.encode(vl.y().fieldN(str).sort('-x'),
vl.x().fieldQ('streams'),
vl.text().fieldN('streams'))
.title(str)
.width(width/3)
return vl.layer(marks, marks.markText({align : "right", color: "white", dx: -5}))
}
const artists = bar('artistName').title("Top Artists")
const songs = bar('trackName').title("Top Songs")
return vl.vconcat(top, vl.hconcat(artists, songs))
.render()
}