source and
target only record the pair.id, station_name, and the three node
variables: district (Central, North, South, East and
West, 10 stations each), daily_passengers
(1,373–9,850) and station_type (Terminal 17,
Transfer 17, Local 16).source, target, and the two link
variables: travel_time_min (2–16 minutes) and
route_type (Express 17, Shuttle 17, Metro 16).Both views on this page are built from these two files with D3 data binding, so they always show the same 50 stations and the same 50 connections.
Every station is one symbol and every direct connection one line. Drag a station to pull it out of the tangle and the simulation re-settles around it. Hover a station to fade everything it does not touch, or hover a line for its travel time. Click a legend entry to isolate one district or one route type. Under Grouped by district the same simulation adds a pull toward five compass anchors, so district membership is carried by position as well as by colour.
The three station variables go onto three channels so that none has to share. District is colour, the channel that lets a reader pick one category out of a layout it is scattered across. Daily passengers is symbol area on a square-root scale, since it is the only real quantity and size reads as magnitude unaided. Station type is symbol shape — triangle Terminal, square Transfer, circle Local — keeping a station's function separate from where it sits.
District spends the colour budget, so route type is line pattern (solid Metro, dashed Express, dotted Shuttle) and links stay grey and recessive. Travel time is line width and the simulation's link distance: more minutes, more ink and more space. Drawing fast links heavier would make width and length disagree.
Interaction covers what a static layout cannot: dragging pulls overlapping symbols apart, hover fades everything a station does not touch — the only reliable way to trace one neighbourhood among 50 crossing lines — and tooltips carry exact values. The legend doubles as a filter, and the layout toggle trades topology for geography.
The same 50 stations on both axes. A filled square means those two stations are directly connected; the matrix is symmetric, so every connection appears twice, once on each side of the grey diagonal. Hover anywhere in the grid for a crosshair and the pair's details, including empty cells, which report that no direct connection exists. Changing the ordering re-sorts both axes together and is the main way this view is made to reveal structure.
Rows and columns are both stations; a filled cell means they are directly connected. With no layout to read, the real design decision is ordering. The default sorts by district, then station type, then passengers, turning district membership into five labelled blocks, so whether two districts connect becomes whether the block where their rows and columns cross has anything in it. Three further orderings are offered because each exposes something different; Network position walks outward from one end and collapses the connections onto a diagonal stripe.
Inside the grid, cell colour is route type and cell size is travel time, so both link variables survive and travel time keeps its direction from the node-link view. Colour is free for route type because district has moved onto position, which keeps the matrix to one colour scale. The margins carry what ordering cannot: each row's station-type glyph, in the same three shapes, and a grey passenger bar. District keeps its colour only in the block labels, tying the two figures together.
Six questions, each answered from the views above rather than from the CSV. For each one: how well the design answers it, which view does the work, the encoding or interaction that carries the answer, and what I actually see.
Two things stayed hard. Exact passenger volumes are not readable from either view: symbol area and a 30-pixel margin bar both give a ranking rather than a number, which is why the tooltip carries the figure and the table view is there as a fallback. And path length — how many hops separate two stations — is not encoded anywhere. The node-link view hints at it through layout distance, but a force layout's geometry is not a metric, and the matrix cannot show it. Answering that properly would need a third view.
It is also worth being clear that this dataset is synthetic in a way the visualizations expose rather than hide. Passenger volume rises in an exact arithmetic step from Station 1 to Station 50, district cycles every fifth station and station type every third, and 40 of the 50 links simply join consecutively numbered stations. Several of the patterns reported above are therefore properties of how the file was generated rather than facts about a city, and saying so is part of reading the picture honestly.