Public
Edited
Dec 31
Public Housing in Canberra
Timeline in OfficeAge in Office
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
draw = function(g, data) {
draw_column(g, housing_allocated, 0, "Public Housing Allocated", "in 2022-23", "#377eb8");
draw_column(g, wait_list_priority, 1, "Wait List", "Priority", "#6e016b");
draw_column(g, wait_list_high_needs, 2, "Wait List", "High Needs", "#88419d");
draw_column(g, wait_list_standard, 3, "Wait List", "Standard", "#8c6bb1");
}
Insert cell
draw_column = function(g, square_num, col_num, label_1, label_2, fill) {
let delay_offset = 15;
let row_item_width = 25;
let edge_offset = 10;
let spacing_offset = 1.5;
let side_length = 7;

let column_width = side_length * row_item_width + spacing_offset * (row_item_width - 1);

let row_correction = ((square_num % row_item_width < row_item_width / 2) ? 1 : 0);
let num_rows = Math.floor(square_num / row_item_width) - row_correction;
let column_height = side_length * num_rows + spacing_offset * (num_rows - 1);
// add a new g that we'll placing all of the drawing within
let shift_correction = col_num > 0 ? 2*edge_offset : 0;
let x_shift = edge_offset*(col_num + 1) + column_width * col_num + shift_correction;
let y_shift = height - 6*edge_offset;
let target_g = g.append("g")
.attr("transform", "translate(" + x_shift + "," + y_shift + ")");

// place the main labels
target_g.append("g")
.append("text")
.text(label_1)
.attr("x", column_width / 2)
.attr("y", 3*edge_offset)
.attr("fill", "#000")
.attr("font-family", "sans-serif")
.attr("font-size", 1.4*edge_offset + "px")
.attr("text-anchor", "middle")
.attr("opacity", 0)
.transition()
.duration(duration)
.attr("opacity", 1);

target_g.append("g")
.append("text")
.text(label_2)
.attr("x", column_width / 2)
.attr("y", 5*edge_offset)
.attr("fill", "#000")
.attr("font-family", "sans-serif")
.attr("font-size", 1.5*edge_offset + "px")
.attr("text-anchor", "middle")
.attr("opacity", 0)
.transition()
.duration(duration)
.attr("opacity", 1);
// place the squares
target_g.append("g")
.selectAll("rect")
.data(Array.from({length: square_num}, (x, i) => i))
.enter()
.append("rect")
.attr("x", d => (side_length + spacing_offset) * (d % row_item_width))
.attr("y", d => -1 * (side_length + spacing_offset) * (Math.floor(d / row_item_width)))
.attr("width", side_length)
.attr("height", side_length)
.attr("rx", 2)
.attr("ry", 2)
.attr("fill", fill)
.attr("opacity", 0)
.transition()
.delay(d => delay_offset * d)
.duration(duration)
.attr("opacity", 1);

// place the count label
target_g.append("g")
.append("text")
.text(square_num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","))
.attr("x", column_width / 2)
.attr("y", -1 * column_height - edge_offset)
.attr("fill", "#000")
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle")
.attr("opacity", 0)
.transition()
.delay(d => delay + delay_offset * square_num)
.duration(duration)
.attr("opacity", 1);
}
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