Public
Edited
1 fork
Insert cell
Insert cell
margin = ({left: 50, right: 100, bottom: 10, top: 10 })
Insert cell
bar_height = 40
Insert cell
//todo make dynamic based on x-axis
xScale = d3.scaleLinear()
.domain([0,50])
.range([0 + margin.left , width - margin.right])
Insert cell
//TODO make dynamic based on amount
cScale = d3.scaleSequential([300, 900], d3.interpolateBlues)
Insert cell
// type == blip of width == 1
// bar == duration more than one

// for blips, you count how many bars it overlaps, then use that count as the index to append to that level of the list.
// for example - blip 2 covers both the first and second so it's going in the second array

// x: STDY
// width: CMDUR or you're on your own calculating this
// amount: DOSE
// type:

// what about a medication thats ongoing?
// ongoing - flag if its ongoing lulz

data3 = [[
{stdy: 0, width: 12, dose: 300, type: 'bar', endday: 50, ongoing: false}, // bar one goes 0 to 12
{stdy: 12, width: 30-12, dose: 700, type: 'bar', endday: 50, ongoing: false}, // bar two goes 12 to 30,
{stdy: 32, width: 50-32, dose: 300, type: 'bar', endday: 50, ongoing: false}, // bar three goes 32 to 50,
{stdy: 9, width: 0, dose: 900, y: 0, type: 'blip', endday: 50, ongoing: false},
],
[
{stdy: 32, width: 10, dose: 900, type: 'bar', endday: 50, ongoing: false}, // bar four goes 32 to 42 but bumped up 1
],
[
// TODO
// if width spills over, make it just go to the end of the plot
// and then put a cute little arrow at the end
// if ongoing true width: max x-axis - stdy
// add a little arrow
/*{stdy: -1, width: 10, dose: 300, type: 'bar', endday: 10, ongoing: false}*/
{stdy: 33, width: 200, dose: 300, type: 'bar', endday: null, ongoing: true},
{stdy: 36, width: 0, dose: 900, type: 'blip', endday: 50, ongoing: false},
]
]
Insert cell
swimmerplot3 = {

let bar_height = 20
let plot_height = data3.length*bar_height + margin.bottom + margin.top
// calculate height based on the max y (we can leverage data2.bars.length to get the height
var svg = d3.select(DOM.svg(width, plot_height))

let gradient = svg.selectAll("gradient")
.data(data3)
.enter()
.append("g")
.attr('class', 'gradient')
.attr('transform', function(d, i) { return `translate(0,${ plot_height - (i+1)*bar_height - margin.bottom} )` })

let bars = gradient.selectAll('gradient')
.data(d => d)
.enter()
.append('rect')
.attr('class', 'bar')
// plot the study day or the min that we set somehow TODO
.attr('x', d => d.stdy < 0 ? xScale(0) : xScale(d.stdy))
.attr('y', d => d.type === 'bar' ? 0 : -5)
.attr('width', function(d) {
if (d.type == 'bar') {
return (d.ongoing ? xScale(50 - d.stdy) : xScale(d.width))
} else {
return 2
}
})
// the height of blips is the y... maybe this is bad idea
.attr('height', d => d.type === 'bar' ? bar_height : ((bar_height+5)*data3.length))
.attr('stroke', 'black')
.attr('stroke-width', 2)
.attr('fill', d => cScale(d.dose))

// if its ongoing add a little triangle
let triangles = gradient.selectAll('triangle')
.data(d => d)
.enter()
.append("path")
.attr("d", d => d.ongoing ? d3.symbol().type(d3.symbolTriangle).size(200)() : null)
.attr("stroke", 'black')
.attr("fill", 'black')
.attr("transform", function(d) {
return `translate(${width - margin.right + margin.left + 5},10)rotate(90)`;
});

return svg.node()
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more