Published
Edited
Feb 17, 2021
3 stars
Insert cell
Insert cell
Insert cell
sample_data = [
{ name: "group 1", values: [{ x: 100, y: 100 }, { x: 200, y: 250 }] },
{ name: "group 2", values: [{ x: 250, y: 150 }, { x: 150, y: 200 }] },
{ name: "group 3", values: [{ x: 300, y: 150 }, { x: 200, y: 100 }] },
{ name: "group 4", values: [{ x: 200, y: 250 }, { x: 250, y: 100 }] }
]
Insert cell
Insert cell
small_multiples = {
// Create a div in which to put the svgs
const div = d3
.create("div")
.style("width", width)
.style("height", height);

// Use a data join to create the svgs
const svgs = div
.selectAll("svg")
.data(sample_data)
.join("svg")
.style("border", "1px solid black")
.attr("width", width / 2 - 5)
.attr("height", height / 2 - 5);

// Double data join to create circles!
const points = svgs
.selectAll("circle")
.data(d => d.values) // pass down the values from each element in your array!
.join("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 5);

return div.node();
}
Insert cell
md`Below is an example of creating a set of lists using an actual dataset`
Insert cell
data = await d3.csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-04-14/rankings.csv")
Insert cell
render_data_table(data.slice(0, 10))
Insert cell
// Group data by artist
by_artist = d3.group(data, d => d.artist)
Insert cell
by_artist.get("Public Enemy")
Insert cell
// Let's create a list of Public Enemy songs
pe_songs = {
const div = d3.create("div")
const songs = by_artist.get("Public Enemy")
div.append("text")
.text("Public Enemy")
.style("font-weight", "bold")
// Let's create a list of songs
const lis = div.selectAll("li")
.data(songs)
.join("li")
.text(d => d.title)
return div.node()
}
Insert cell
// Create a list for all artists and songs
all_songs = {
const div = d3
.create("div")
.style("height", "400px")
.style("overflow", "scroll");

const artists = div
.selectAll("p")
.data(by_artist)
.join("p")
.text(d => d[0] + ": " + d[1].length)
.style("font-weight", "bold")
.selectAll("li") // select all li elements *in* the paragraph
.data(d => d[1]) // do the double data join with the array of songs for each artist
.join("li")
.text(d => d.title)
.style("font-weight", "normal");
return div.node();
}
Insert cell
by_artist_groups = d3
.groups(data, d => d.artist)
.sort((a, b) => b[1].length - a[1].length)
// Alphabetical
// by_artist_groups = d3
// .groups(data, d => d.artist)
// .sort((a, b) => {
// if (a[0] < b[0]) {
// return -1;
// }
// if (a[0] > b[0]) {
// return 1;
// }
// return 0;
// })
Insert cell
// Create a list for all artists and songs
all_songs_groups = {
const div = d3
.create("div")
.style("height", "400px")
.style("overflow", "scroll");

const artists = div
.selectAll("p")
.data(by_artist_groups)
.join("p")
.text(d => d[0] + ": " + d[1].length)
.style("font-weight", "bold")
.selectAll("li") // select all li elements *in* the paragraph
.data(d => d[1]) // do the double data join with the array of songs for each artist
.join("li")
.text(d => d.title)
.style("font-weight", "normal");
return div.node();
}
Insert cell
md`## Appendix`
Insert cell
d3 = require("d3")
Insert cell
height = 600
Insert cell
_ = require("lodash")
Insert cell
import {render_data_table, table_styles} from "@uw-info474/utilities"
Insert cell
table_styles
Insert cell
diagram = await FileAttachment("double_data_join@1.png")
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