Published
Edited
Oct 13, 2021
4 forks
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof dashboard = {
const brush = vl.selectInterval().encodings('x').init({x: [0, 40]});
const hover = vl.selectSingle('hover').on('mouseover').encodings("x").nearest(true).clear("mouseout");
const proteinList = Array.from(new Set(data_viz.heatmap.map(d => d.n)));

const scale = {
domain: Array.from(new Set(data_viz.heatmap.map(d => d.v))),
range: d3.schemeSet3.concat(d3.schemeSet2).concat(['#ddd'])
}
const heatmap = vl
.data(data_viz.heatmap)
.layer(
vl.markRect()
.params(hover)
.encode(
vl.y().fieldN('n').axis({title:null}),
vl.x().fieldN('k').axis({domain: false, title: null, values: d3.range(0, data.total_len, 20), labelAngle: 0, orient: 'top'}),
vl.color().fieldN('v').scale(scale).legend(null),
),
vl.markText({align: 'center'})
.encode(
vl.y().fieldN('n'),
vl.x().fieldN('k'),
vl.text().fieldN('v'),
vl.tooltip([ {field:'n', title: 'Protein'}, {field: 'k', title: 'Position'},
{field: 'v', title: 'Sequence'}, {field: 'mode', title: 'Mode'}])
),
)
.width(810)
.height(600)
.transform(vl.filter(brush))

const miniMap = vl.markTick()
.data(data_viz.heatmap)
.encode(
vl.x().fieldQ('k').axis(false),
vl.y().fieldN('n').axis(false),
vl.color().fieldN('v').legend(null),
vl.color().value('lightgray')
.if(brush, vl.color().fieldN('v').scale(scale).legend(null)),
)
.height(150)
.params(brush)
.width(250)

const barChart = vl.markBar()
.data(data_viz.bar)
.encode(
vl.x().fieldO('k').axis({ title: null, values: d3.range(0, data.total_len, 20), labelAngle: 0}),
vl.y().fieldQ('Conversion Rate'),
vl.color().fieldQ('Conversion Rate').scale({scheme: 'yellowgreenblue'}).legend(null),
vl.tooltip([ {field: 'Conversion Rate', format: '.2f'}, {field: 'k', title: 'Position'}])
)
.height(150)
.width(500)
.transform(vl.filter(brush))

return vl.vconcat(vl.hconcat(miniMap, barChart), heatmap)
.config({view:{stroke:'transparent'}})
.render();
}
Insert cell
data = {
const url = 'https://raw.githubusercontent.com/plotly/dash-bio-docs-files/master/alignment_viewer_p53.fasta'
const raw = (
file === null
? a.fastaParser(await d3.text(url))
: a.fastaParser(await file.text())
)
.map(d => ({...d,
'seq_len': d.seq.length,
'seq_name': d.header.split('|')[2].split(' ')[0]
}));
const max_len = d3.max(raw, d => d.seq_len);
const raw1 = raw.map(d => ({...d,
'seq_full_str': d.seq + '-'.repeat(max_len - d.seq_len),
'seq_full': [...(d.seq + '-'.repeat(max_len - d.seq_len))].map((n,i) => ({'k': i, 'v': n, 'n': d.seq_name}))
}));

const derive = raw1.map(k => k.seq_full.map(j => ({'n': j.n, 'k': j.k, 'v': j.v }))).flat()

return {'raw': raw1, 'derive': derive, 'total_len': max_len}
}
Insert cell
data_viz = {
const raw_len = data.raw.length
const countCol = d3.flatRollup(data.derive, v => v.length, d => d.k, d => d.v)
.map(([k, v, cnt]) => ({k, v, cnt}))

const conversion = d3.groups(countCol, d=>d.k)
.map(n => d3.greatest(n[1], a=>a.cnt))
.map(d => ({...d, 'Conversion Rate': d.cnt / raw_len}))

const derive2 = data.derive.map(d => ({...d, 'mode': conversion.filter(j => j.k === d.k )[0].v}))

const data_viz = derive2.concat(conversion.map(d => ({'n': 'Concensus', 'k': d.k, 'v': d.v, 'mode': d.v})))

return {'heatmap': data_viz, 'bar' : conversion}
}
Insert cell
Insert cell
Insert cell
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