(Automatic Visualization of the Frontend)
Based on the cover graphic from Edward Tufte's Visual Display of Quantitative Information
git blame / CODEOWNERS
...graphical representations that facilitate spatial understanding of things...
- Harley & Woodward, History of Cartography
"Not only is it easy to lie with maps, it's essential...
To avoid hiding critical information in a fog of detail, the map must offer a selective, incomplete view of reality"
- Mark Monmonier, "How to Lie With Maps"
the ideal
abstraction level
is
situation specific.
Marine Map of Scandinavia: 1539
How can we keep the plan and the implementation in sync?
Data API
Container
View
Imported by
// data-service.js export const fetchItems = async () => fetch('/api/items'); // List.jsx import { formatItems } from './data-service'; const formatItems = (items) = items.map(formatItem); export const List = (props) => { return ( <div> {formatItems(props.items)} </div> ) } // ListContainer.jsx import { fetchItems } from './data-service'; export const ListContainer = (props) => { // pseudocode for data fetching const items = await fetchItems(); return <List items={items}/> }
// data-service.js export const fetchItems = async () => fetch('/api/items'); // List.jsx import { formatItems } from './data-service'; const formatItems = (items) = items.map(formatItem); export const List = (props) => { return ( <div> {formatItems(props.items)} </div> ) } // ListContainer.jsx import { fetchItems } from './data-service'; export const ListContainer = (props) => { // pseudocode for data fetching const items = await fetchItems(); return <List items={items}/> }
// data-service.js export const fetchItems = async () => fetch('/api/items'); // List.jsx import { formatItems } from './data-service'; const formatItems = (items) = items.map(formatItem); export const List = (props) => { return ( <div> {formatItems(props.items)} </div> ) } // ListContainer.jsx import { fetchItems } from './data-service'; export const ListContainer = (props) => { // pseudocode for data fetching const items = await fetchItems(); return <List items={items}/> }
// data-service.js export const fetchItems = async () => fetch('/api/items'); // List.jsx import { formatItems } from './data-service'; const formatItems = (items) = items.map(formatItem); export const List = (props) => { return ( <div> {formatItems(props.items)} </div> ) } // ListContainer.jsx import { fetchItems } from './data-service'; export const ListContainer = (props) => { // pseudocode for data fetching const items = await fetchItems(); return <List items={items}/> }
data-api: *-service.js container: *Container.jsx view: *.jsx
Data API
Container
View
Matching
Missing
Unexpected
Added /people API
// data-service.js export const fetchItems = async () => fetch('/api/items'); export const formatItems = (items) => items.map(item => processItem(item)); // Someone unfamiliar with project structure proposes a new change export const fetchPeople = async () => fetch('/api/people'); // List.jsx import { formatItems, fetchItems, fetchPeople } from './data-service'; export const List = (props) => { const items = await fetchItems(); const people = await fetchPeople(); return ( <div> {formatItems(items)} {people} </div> ) } // ListContainer.jsx export const ListContainer = (props) => { // some other code for logging, routing etc return <List /> }
Data API
Container
View
Matching
Missing
Unexpected
Refactored
New import
How can we keep the plan and implementation in sync?
*without extra manual steps
github.com/ivanreese/visual-programming-codex
We don't have this for JS
(and this won't help our existing applications)
(Directed Acyclic Graphs)
A B
B "uses" A
Continent (Eurasia)
Country
Subnational (State, Province, County)
City
Neighborhood
Specific
Broader
UK (country) projected onto Texas (US State)
Imports (module/file)
Call graphs (function)
Dataflow (variable)
Specific
Abstract
const node = "file" `Which ${node} might be affected by changes to other ${node}s?`
npx arkit
See Github for Client/Server example
const node = "function" `Which ${node} might be affected by changes to other ${node}s?`
*Not necessarily DAG (Recursion / Loops)
Record of actual run (single path though tree)
(Python Pyan: Flask Example)
Have data, seeking visualization
const node = "variable" `Which ${node} might be affected by changes to other ${node}s?`
- Reposition/Highlight upstream / downstream
- Inspect runtime values
- Count recomputations (hotspots)
Automatic visual documentation
const pedestrianStates = { initial: 'walk', states: { walk: { on: { PED_TIMER: 'wait' } }, wait: { on: { PED_TIMER: 'stop' } }, stop: {} } }; const lightMachine = Machine({ id: 'light', initial: 'green', states: { green: { on: { TIMER: 'yellow' } }, yellow: { on: { TIMER: 'red' } }, red: { on: { TIMER: 'green' }, ...pedestrianStates } } }); // via xstate docs page
See @DavidKPiano's XState Talks
light green timer -> yellow yellow timer -> red red walk ped_timer -> wait wait ped_timer -> stop stop timer -> green
- Generate XState Code from YAML-like markup
- Auto-generated clickable diagram
1. Hairball -> Visual Search Mantra
2. Wayfinding -> Adding Data
Future: Biofabric / Hive Plots / Hyperbolic Tree / other non-mainstream layouts
Source: EagerEyes / It's Always Sunny in Philadelphia
- not a real Yoda quote
Source: AxisMaps
Source: Mapbox / Nathaniel Slaughter on Medium
Ben "Hyperlink" Schneiderman (The Eyes Have It, 1996)
Examining JSNetworkX + nteract
- information systems from architecture (signage)
- Help people to orient themselves
- Enhance understanding + experience of complex spaces
Weather
Flight Coverage
Reselect, Python Call Craph, FlameGraphs all do this
1. Pick a search tool
(grep, Sourcegraph, etc)
2. Pick a map
3. Combine them
JSNetworkx/src/algorithms
- Attributed to Marshall McLuhan
Looking forward to seeing pictures of your maps 🗺
(code related or otherwise)
Thank you!
Twitter: @hydrosquall
Pronouns: he/him
Demos/Resources: github.com/hydrosquall/code-maps-frontend
Datadog: We're hiring! (React/Typescript/WebGL/Go/Etc)
This page intentionally left blank. Please do not write on it.