Public
Edited
Jan 8, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ual student count - data.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
data = _.sortBy( // order the data by student population
ualStudentCountData.filter(d => d.category !== 'all students').filter(d => d.category !== 'Postgraduate Teaching'),
[d => d.student_count_22]
).map(d => d)
Insert cell
Insert cell
Plot.plot({
marginLeft: 300,
marginRight: 50,
width: 800,
color: {
type: "diverging",
scheme: "BrBG"
},
marks: [
Plot.barX(data, {x: "student_count_22", y: "category", fill: "#f27291", sort: {y: "x"},}),
Plot.ruleX([-100, 0, 2500])
]
})
Insert cell
Insert cell
Insert cell
Plot.plot({
marginLeft: 300,
marginRight: 50,
width: 800,
marks: [
Plot.barX(changeData, {
x: "value",
y: "label",
fill: "#fbe6a0",
sort: {
y: "-data",
}
}),
Plot.ruleX([-100, 0, 2500]),
Plot.text(changeData, {x: "value", y: "label", text: d => d.value, dx: 15, dy: 0}),
],
x: {
// axis: null
},
y: {
domain: changeData.map(d => d.label) // keep the order the same as
}
})
Insert cell
pct = data.map(d => (d.pct_22 * 100).toFixed(0))
Insert cell
people = data.map((d, i) => {
const change = Math.abs(+d.diff_2022_2001);
return {
value: +d.student_count_22,
valueMinusChange: +d.student_count_22 - change,
label: d.category,
postiveChange: change, // values above zero
change: +d.diff_2022_2001,
pct: +(+d.pct_22 * 100).toFixed(0),
index: i // use for the letter to be applied
}
})
Insert cell
lettersString = 'UniversityArtsLon'.toUpperCase().split('')
Insert cell
Insert cell
barPipes(people, {
letters: lettersString,
valueKey: 'pct',
changeKey: null,
color: 'black'
})
Insert cell
barPipes(people, {
letters: lettersString,
valueKey: 'pct',
color: 'black',
showLabel: false,
})
Insert cell
barPipes(people, {
letters: lettersString,
changeKey: 'postiveChange'
})
Insert cell
staff = [
{
value: 1582,
label: "Support staff",
index: 0
},
{
value: 3081,
label: "Associate lecturers",
index: 1
},
{
value: 1568,
label: "Academic, research and technical staff",
index: 2
}
]
Insert cell
staffTotal = staff.map(d => d.value).reduce((partialSum, a) => partialSum + a, 0);
Insert cell
barPipes(staff, {
letters: 'NDO'.toUpperCase().split(''),
color: 'black'
})
Insert cell
function barPipes(data, {
valueKey = 'value',
indexKey = 'index',
labelKey = 'label',
changeKey = null,
letters = alphabet.map(d => d.letter),
padding = 20,
showLabel = true,
color = 'tomato'
} = {}) {
const sel = d3.create('div')
.attr('class', 'bar-pipe');
sel.append('div')
// .style('min-width', width + 'px')
.selectAll('div')
.data(data)
.join('div')
.style('color', color)
.html(d => {
const pipes = repeatStringNumTimes(`${letters[d[indexKey]]} ` , d[valueKey]);
const change = repeatStringNumTimes(`${letters[d[indexKey]]} ` , d[changeKey]);
console.warn('d', d)
console.warn('change', change)
const labelYes = `${d.label} : <span class='pipe'>${pipes} ------ ${change}</span> ------ :${d[valueKey]}`;
const labelNo = `<span class='pipe'>${pipes}</span>`;
const output = (showLabel) ? labelYes : labelNo;
return output;
});

function repeatStringNumTimes (string, times) {
return times > 0 ? string.repeat(times) : '';
};

return sel.node();
}
Insert cell
<hr>
<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>
.label {
font-family:'Space Mono',monospace;
color: #008cbc;
font-size: 13px;
padding-left: 5px;
}
text {
font-family:'Space Mono',monospace;
fill: #130C0E;
font-size: 11px;
}
.bar-pipe {
font-size: 14px;
font-family: 'Space Mono', monospace;
font-weight: 400;
color: #454545;
padding-bottom: 20px
}
.pipe {
font-weight: bold;
letter-spacing: -5px;
font-size: 18px;
</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