Public
Edited
Feb 28, 2023
2 stars
Insert cell
Insert cell
vis = html`<div class="vis-rb"></div>`
Insert cell
ratioBar(value, {
bind: d3.select(vis), // pass in the selection
margin: {top: 10, right: 10, bottom: 30, left: 0}
})
Insert cell
Insert cell
Insert cell
function ratioBar (value, {
bind = null, // pass in a d3 selection i.e d3.select('class/div')
barFill = ['#0d75ff', '#b875eb'], // left, right
textFill = '#fff', // text colour
margin = {top: 10, right: 10, bottom: 10, left: 10}, // padding around bar
width = 300, // width of bar
height = 50, // height of bar
} = {}) {

const data = [value, 100 - value]

// set the dimensions and margins of the graph
const w = width + margin.left + margin.right
const h = height + margin.top + margin.bottom

bind.selectAll('svg').remove();
const svg = bind.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);

const xScale = d3.scaleLinear()
.domain([0, 100])
.range([margin.left, width])

// append wrap
const wrap = svg.append('g')
.attr('class', 'ratio-wrap')

// append first rect
const firstRect = wrap.append('rect')
.attr('height', height)
.attr('width', xScale(data[0]))
.attr('y', margin.top)
.style('fill', barFill[0])

// append second rect
const scndRect = wrap.append('rect')
.attr('height', height)
.attr('x', xScale(data[0])) // start the first rect after the first ends
.attr('y', margin.top)
.attr('width', xScale(data[1]))
.style('fill',barFill[1])

// append values
const label = svg.append('text')
.attr('class', 'ratio-label')
.attr('y', height / 2 + margin.top)
.attr('dy', 5)
.style('text-anchor', 'middle')
// .style('dominant-baseline', 'central')
.style('fill', textFill)
.attr('x', function () {
// ensure there is enough space to display numbers
console.log('xScale(data[0])', xScale(data[0]))
if (xScale(data[0]) < 25 || xScale(data[0]) > (w - 35)) {
console.log('ratio returning width')
return width / 2
} else {
return xScale(data[0])
}
})
.text(data[0] + ' : ' + data[1])

return svg;

}
Insert cell
Insert cell
visWrap = html`<div class="vis-1 flex flex-wrap "></div>`
Insert cell
viewof barLeft = Inputs.color({label: "Bar left:", value: "#0d75ff"})
Insert cell
viewof barRight = Inputs.color({label: "Bar right:", value: "##681916"})
Insert cell
{ // have a way of updating the cell put not creating extra dom elements
if (d3.select(visWrap).empty()) { // don't reload on any cell refreshes
testMultipleRender(visWrap, [barLeft, barRight]);
} else {
d3.select(visWrap).selectAll('div').remove();
testMultipleRender(visWrap, [barLeft, barRight]);
}
}
Insert cell
function testMultipleRender(sel, colArray) { // render dom and bind svg visual to it
return [30, 45, 25, 80, 60, 5, 20, 25, 15, 10, 90, 50].forEach((d, i) => {
const div = d3.select(sel).append('div').attr('class', 'ref-' + i)
d3.select('.ref-' + i).append('h3').attr('class', 'ml2 normal label mb0 pb0').text('group: ' + i)
ratioBar(d, {
bind: d3.select('.ref-' + i),
width: 150,
barFill: [colArray[0], colArray[1]],
margin: {top: 5, right: 10, bottom: 30, left: 0}
})
})
}
Insert cell
Insert cell
<link href="https://fonts.googleapis.com/css?family=Space+Mono" rel="stylesheet">
<link href="https://unpkg.com/basscss@8.0.2/css/basscss.min.css" rel="stylesheet">
<style>
.ratio-label, .label {
font-family:'Space Mono',monospace;
color: #008cbc;
font-size: 13px;
}
</style>
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