Public
Edited
May 25, 2023
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

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