Published
Edited
Jan 29, 2021
5 forks
Importers
8 stars
Insert cell
Insert cell
chart = {
const nameRe = /%(\d+)/
const container = d3.select(DOM.element("div"))
.classed("container", true)
const signs = container.selectAll(".subway-sign")
.data([...stations.keys()])
.enter()
.append("div")
.classed("subway-sign", true);
signs.append("div")
.classed("rule", true);
const inner = signs
.append("div")
.classed("inner", true);
inner.append("p")
.classed("name", true)
.text(d => d % nameRe.test(d) ? d : d.replace(nameRe, ""));
inner.selectAll(".line")
.data(d => [...stations.get(d)])
.enter()
.append("div")
.classed("line", true)
.style("background-color", d => palette.get(color(d)))
.append("p")
.style("color", d => color(d) === "yellow" ? "#000" : "#fff")
.text(d => d);
return container.node();
}
Insert cell
color = d3.scaleOrdinal()
.domain([
...["B", "D", "F", "M"],
...["A", "C", "E"],
"G",
...["J", "Z"],
"L",
...["N", "Q", "R", "W"],
"S",
...["1", "2", "3"],
...["4", "5", "6"],
"7"
])
.range([
...Array(4).fill("orange"),
...Array(3).fill("blue"),
"lime",
...Array(2).fill("brown"),
"light-grey",
...Array(4).fill("yellow"),
"medium-grey",
...Array(3).fill("red"),
...Array(3).fill("green"),
"purple"
])
Insert cell
palette = {
// http://web.mta.info/developers/resources/line_colors.htm
const p = new Map();
p.set("blue", "#0039A6"); // A,C,E
p.set("orange", "#FF6319") // B,D,F,M
p.set("lime", "#6CBE45"); // G
p.set("brown", "#996633"); // J,Z
p.set("light-grey", "#A7A9AC"); // L
p.set("yellow", "#FCCC0A"); // N,Q,R,W
p.set("medium-grey", "#808183"); // S
p.set("red", "#EE352E"); // 1,2,3
p.set("green", "#00933C"); // 4,5,6
p.set("purple", "#B933AD"); // 7
return p;
}
Insert cell
stations = {
const data = await d3.csv("https://gist.githubusercontent.com/clhenrick/a585388c95c14074ebe512458e359197/raw/189cfaa73aa6dc0676e33fed17c22158b40394fe/nyc_subway_names_lines.csv")
console.log(data);
return data
.sort((a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
return nameA.localeCompare(nameB, "en", {numeric: true, sensitivity: 'base'});
})
.reduce((acc, cur, i) => {
const re = RegExp("Express")
const name = cur.name;
let line = cur.line
.split("-")
.sort()
.filter(d => d.indexOf("Express") === -1);
if (acc.get(name)) {
acc.set(`${name}%${i}`, new Set([...line]))
} else {
acc.set(name, new Set(line));
}
return acc;
}, new Map());
}
Insert cell
styles = {
const fontFamily = "Helvetica, sans-serif";
const bgColor = "#e2e2e2";
const black = "#000";
const white = "#FFF";
const minWidth = "125px";
return html`<style>
.container {
width: ${width};
height: auto;
background: ${bgColor};
}

.subway-sign {
display: inline-block;
min-width: ${minWidth};
height: auto;
margin: 6px;
background: ${black};
}

.subway-sign .rule {
padding-top: 6px;
border-bottom: 1px solid ${white};
}

.subway-sign p {
padding: 0;
margin: 0;
font-family: ${fontFamily};
font-weight: bold;
line-height: 12px;
}

.subway-sign .inner {
padding: 6px;
padding-right: 12px;
padding-bottom: 18px;
}

.subway-sign .name {
font-size: 16px;
color: ${white};
}

.subway-sign .line {
display: inline-flex;
align-items: center;
align-content: space-around;
justify-content: center;
width: 20px;
height: 20px;
margin-left: 2px;
margin-right: 2px;
border-radius: 50%;
}

.subway-sign .line p {
display: inline;
margin: auto;
font-size: 14px;
text-align: center;
line-height: 22px;
}
</style>`
}
Insert cell
Insert cell
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