diff --git a/.gitignore b/.gitignore index 6fecae67..5b4779cf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,11 @@ npm-debug.log yarn.lock package.lock -source/msi-4096/scenarios.tsv \ No newline at end of file +source/dvs-privacy/membership.json +explorable-ml + +source/forecast-correlation/data/ +source/forecast-correlation/node_modules/ + + + diff --git a/README.md b/README.md index 031ec93f..7c041473 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [roadtolarissa.com](http://roadtolarissa.com/) ``` -yarn run start +yarn start ``` -Changes to JS/CSS in `source/` are injected without a reload. Edits to `source/_posts/*.md` trigger an incremental rebuild and hard reload client side. +Changes to JS/CSS in `source/` are [injected without a reload](http://roadtolarissa.com/hot-reload). Edits to `source/_posts/*.md` trigger [an incremental rebuild](https://roadtolarissa.com/literate-blogging/) and hard client side reload. diff --git a/package.json b/package.json index 0db82dd4..0e7baf14 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,15 @@ { - "name": "static-site", + "license": "MIT", "dependencies": { "chokidar": "^1.7.0", - "highlight.js": "^9.12.0", + "highlight.js": "11", "hot-server": "^0.0.16", "lit-node": "^0.0.1", "marked": "^0.3.6" }, "scripts": { - "start": "lit-node source/_posts/2017-11-12-literate-blogging.md --watch & cd public/ && hot-server", - "publish": "lit-node source/_posts/2017-11-12-literate-blogging.md index.js && rsync -a --omit-dir-times --no-perms public/ demo@roadtolarissa.com:../../usr/share/nginx/html/" + "start": "mkdir -p public && yarn lit-node source/_posts/2018-05-24-literate-blogging.md --watch & cd public/ && hot-server", + "pub": "mkdir -p public && yarn lit-node source/_posts/2018-05-24-literate-blogging.md && rsync -a --omit-dir-times --no-perms public/ demo@roadtolarissa.com:../../usr/share/nginx/html/", + "homepage": "source/homepage/update.sh" } } diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/source/_posts/2012-09-27-first-post.md b/source/_posts/2012-09-27-first-post.md index cf7b71de..c4622e83 100644 --- a/source/_posts/2012-09-27-first-post.md +++ b/source/_posts/2012-09-27-first-post.md @@ -1,6 +1,7 @@ --- title: First Post template: post.html +date: 2012-09-27 permalink: /first-post --- I've found that writing todo lists enormously increases my productivity while programming. Programming is all about breaking larger problems into smaller problems over and over until the problems are small enough to solve easily. Lists provide a map of the problems that need solving and make it possible to work on a smaller subset of them without having to simultaneously worry about the global structure of the program. @@ -107,7 +108,7 @@ https://news.ycombinator.com/item?id=9177469 ### Difference between playoff and regular season win rates - Cubs got swept in playoffs after sweeping during season -### [Remake trib baseball chart](https://bl.ocks.org/1wheel/0fe7b82d7c188c2d26a3) +### [Remake trib baseball chart](https://blocks.roadtolarissa.com/1wheel/0fe7b82d7c188c2d26a3) - https://twitter.com/waynekamidoi/status/657359312520638464 - https://twitter.com/kleinmatic/status/657400344394276864 @@ -130,6 +131,10 @@ https://news.ycombinator.com/item?id=9177469 ### Log scales are pretty great! - https://www.washingtonpost.com/national/americas-new-tobacco-crisis-the-rich-stopped-smoking-the-poor-didnt/2017/06/13/a63b42ba-4c8c-11e7-9669-250d0b15f83b_story.html?tid=ss_tw&utm_term=.aab13303a01e +- https://www.washingtonpost.com/business/2018/10/30/owning-your-own-home-doesnt-make-you-rich-owning-somebody-elses-does/?utm_term=.80dc77d29762 +- https://fivethirtyeight.com/features/which-countries-terrorist-attacks-are-ignored-by-the-u-s-media/ +- https://www.nytimes.com/2014/04/23/upshot/the-american-middle-class-is-no-longer-the-worlds-richest.html +- https://www.washingtonpost.com/graphics/2018/business/hq-trivia/?noredirect=on&utm_term=.4b8a7ca8e79c (percent remaining chart) ### Which team is the best at 2-1? - look at scoring at the end of the quarter @@ -153,8 +158,10 @@ https://news.ycombinator.com/item?id=9177469 - During a rare happy stretch of Philly's blowout loss to the Hawks on Friday, the Sixers' broadcast team pointed out that Philly was on "an 8-3 run." I know the Sixers aren't good enough to put together normal NBA runs, but an 8-3 scoring gap is not a run. It is a randomly occurring blip that happens every game. - Which players are the streakest/have the most improbable runs? www.espn.com/nba/story/_/page/presents-19573519/heating-fire-klay-thompson-truth-hot-hand-nba - Which players do the best/worst after hiting/missing a FT? Do some players always go 7/10 or do some go 5/10 and 10/10 more often than they would randomly. +- What's the closest game ever? Has any game stayed within 10 points? 5 points? +- Which game had the shortest scoring streak? -### [Curl states into each other](https://bl.ocks.org/1wheel/4c1658719cfec9ac352ff1e0edc51317) +### [Curl states into each other](https://blocks.roadtolarissa.com/1wheel/4c1658719cfec9ac352ff1e0edc51317) - https://medium.com/@zachlieberman/land-lines-e1f88c745847#.t1x3ozhdt - noah's stuff @@ -209,9 +216,10 @@ https://news.ycombinator.com/item?id=9177469 - http://www.wsj.com/graphics/build-your-own-trading-bot/?mod=e2twg - Scatter plot of buy after tk days of gains/sell after tk days of losses -### new hp +### [new hp](https://roadtolarissa.com) - some sort of 3d scroll zoom/rotate -- once saw a nice portfolio site with sum(1/2^n) = 1. they had done something with game of thrones but can't find +- once saw a nice portfolio site with sum(1/2^n) = 1. they had worked on http://www.themill.com/portfolio/3861/winter-is-here%3A-facebook-ar-effects, but I can't find their site. +- https://beta.observablehq.com/@mbostock/golden-mona-lisa ### Structure of fiction - http://twinegarden.tumblr.com/ @@ -243,7 +251,7 @@ https://news.ycombinator.com/item?id=9177469 ### Encoding line width - setting y0 and y1 doesn't work on a slope - https://www.axios.com/countries-gdp-this-century-2484484895.html -- https://bl.ocks.org/veltman/e45cc3a2670779a0bc942ba18163228f +- https://blocks.roadtolarissa.com/veltman/e45cc3a2670779a0bc942ba18163228f - https://www.washingtonpost.com/graphics/2017/politics/tax-breaks/ ### Hapax Legomena @@ -251,7 +259,7 @@ https://news.ycombinator.com/item?id=9177469 ### [Hacking Hot Reloading](https://roadtolarissa.com/hot-reload/) -### That blog post about how the blog is set up +### [That blog post about how the blog is set up](https://roadtolarissa.com/literate-blogging/) ### Flappy Beep @@ -261,7 +269,7 @@ https://news.ycombinator.com/item?id=9177469 - and an explanation layer ### delaunay-triangulation -- https://bl.ocks.org/1wheel/6cd8f2c2be0bd0bde0818fc8c0fb895a +- https://blocks.roadtolarissa.com/1wheel/6cd8f2c2be0bd0bde0818fc8c0fb895a ### Kelly betting - https://www.gwern.net/Coin-flip @@ -275,7 +283,9 @@ https://news.ycombinator.com/item?id=9177469 - "No one ever got fired for buying IBM" - The paper gets things I know about totally wrong, but I trust them on everything else From Michael Crichton? - “It is difficult to get a man to understand something, when his salary depends on his not understanding it.” - +- "little know" tips on reddit +- https://tinysubversions.com/stuff/known-places/ +- every "there's always a tweet", connections between original date and rt What does reddit repeat? @@ -283,26 +293,294 @@ What does reddit repeat? - Scroll down and see all the movies that have been the 'best selling' - https://www.axios.com/black-panther-box-office-titanic-top-3-north-america-avatar-star-wars-32a35770-59fc-4ccc-bd5b-3a85d7144266.html -### MSI 2018 +### [MSI 2018](https://roadtolarissa.com/msi-4096/) - https://www.nytimes.com/elections/2012/results/president/scenarios.html ### Spurs 50 win streak - every streak line of 50+ wins on some kind of scatter plot? - compare to other sports with win percent? +- https://cleaningtheglass.com/two-for-one-or-two-for-none/ +### [2018 chart diary](https://roadtolarissa.com/2018-chart-diary/) -### 2018 chart diary -### New homepage zoooom +### [New homepage zoooom](https://roadtolarissa.com) - https://beta.observablehq.com/@mbostock/golden-mona-lisa +### DISSOLVING THE FERMI PARADOX +- http://slatestarcodex.com/2018/07/03/ssc-journal-club-dissolving-the-fermi-paradox/ + + +### 3d animation thinger +- https://imgur.com/a/5nu25 +- https://www.youtube.com/watch?v=FGhr3kvaWcs +- https://www.reddit.com/r/place/comments/64d8vy/3d_visualization_timelapse_of_place/ +- "Microdisplacement in Cycles", "Displacement texture", "Animated textures in Cycles" +- https://www.reddit.com/r/dataisbeautiful/comments/8v0m98/oc_3d_animation_of_chinas_nitrogen_dioxide/ + + +### Winning by at least 17 after Q1 -> final margin of victory +- https://twitter.com/jon_bois/status/1000580952047931393 +- What's the biggest drop in win probabily at each minute of the game? +- Most lead changes? + + +### animated illusions +- https://vimeo.com/287093172 +- https://www.youtube.com/watch?v=DkVOIJAaWO0&index=120&list=WL&t=67s + + +### rotating vector field +- https://www.windy.com/?40.781,-73.977,5 +- want to smoothy animate a hurricane wind map + + +### zoom into a pixel looping forever +- https://twitter.com/jashkenas/status/1044370517522694144f + + +### most popular canceled show +- tuca and bertie + + +### continuity +- https://www.reddit.com/r/nba/comments/ch7kr5/oc_we_may_never_see_roster_continuity_like_we_saw/ +- want a box for each player, gets 1px higher each year + + +### [spotify webplayer winamp skin](https://roadtolarissa.com/winampify/) +- don't like looking at ads to listen to music! +- why? +- - new pornographer low density screenshot +- - https://www.stereogum.com/2105993/pavement-harness-your-hopes-spotify/columns/sounding-board/ + + +### weather charts +- https://weatherspark.com/ +- a map with showing them in a tooltip? +- two of them showing 5% hottest and 95% hottest. and you can adjust the width of the spread +- show the actual hourly values for a given year + + +### aita +- identify score with gpt2? +- see ratings that change over time (auto find edits) +- just show the distributions of all the scores for all posts in a year +- https://public.tableau.com/profile/farhan7#!/vizhome/AmITheAssholeApeakintoallDilemmas__/TopicClusters + + +### [wild fire indexing](https://blocks.roadtolarissa.com/1wheel/46874895034f5bded13c97097bf25a83) +- https://twitter.com/damiandn/status/1216002437137469441 + + +### year end slug consistency +- https://lisawaananenjones.com/noted/2020/01/03/end-of-year-graphics-lists/ +- 2015-year-in-graphics + + +### Bulls are 1-16 v teams with a winning record and in 9th seed +- Jan 2020 + + +### LeBron beat Kemba 28 times in a row + +### Lebron hit 5 threes in a few minutes +- fastest streak of shots? +- longest streak of no misses? +- longest streak of no one else shooting? + +### visual snakes and ladders + +- https://www.research.ibm.com/haifa/ponderthis/challenges/February2020.html + + + +### Best winning streak of a time period +- color by win rate or min wins a season +- spurs made playoffs / 50 wins forever + + +### hyper cube portfolio page +- https://www.youtube.com/watch?v=q5Qh2XpoCsY + + +### usable spiral portfolio +- add sidebar of things (maybe horizontal on mobile?) +- hover highlights square + + +### zoomable dorling cartogram +- https://www.nytimes.com/interactive/2020/02/03/us/elections/results-iowa-caucus-precinct-map.html +- construct topology and check angle + + +### are cow's actually better repped in the senate? +- https://www.washingtonpost.com/opinions/2020/01/16/are-cows-better-represented-senate-than-people/?arc404=true +- compare gini coeffient +- find closest plant or animal + + +### Airbnb lawsuits over time +- https://www.bloomberg.com/graphics/2020-airbnb-ipo-challenges/ +- the number of lawsuits looks like it dropped in 2020, but that's because it doesn't show ones that haven't been filed +- make animation showing what this looks like over time +- make alternative + + +### d3 learning +- update to v6 +- link to others? +- separate from projects + + +### chicago neighborhoods +- https://pair-code.github.io/interpretability/uncertainty-over-space/neighborhood/ +- svg2tiles lib to converty + + +### chart podcast audio +- https://www.adblockradio.com/blog/2018/11/15/designing-audio-ad-block-radio-podcast/ +- 1 px is about 5 sec. show intro, ads, outro and content in different colors +- click to play! +- programmatic ads might mess this up + +### chart TAL replays +- air date v show index scatter plot is obv, but swoopy lines would be fun too +- diff transcripts to show updates + + +### local observable +- store state is query str +- node interop +- https://github.com/asg017/unofficial-observablehq-compiler + + +### umap of amazon review for a product +- color by date +- "When we become aware of negative changes, we investigate and often retest to determine whether we need to update our recommendation. For example, staff writer Sarah Witman looks for patterns: If one review mentions an issue with an item’s handle, for example, she’ll search for other reviews with the keyword “handle” to see if the issue is isolated or if it seems to be part of a trend—a good strategy for reviewers and readers alike" +- https://thewirecutter.com/blog/why-some-picks-have-bad-reviews/ +- filter by score / length / fakespot + + +### codenames embeddings +- looking at CLS token delta might be better than comparing raw word embedding +- maybe look at early layer? + + +### every bitcoin explanation +- replies to jk rowling tweak, maybe BERT + UMAP +- [CLS embedding](https://huggingface.co/transformers/quickstart.html#bert-example) +- [scatter plot with a 100k points](https://observablehq.com/@bmschmidt/zoom-strategies-for-huge-scatterplots-with-three-js) + +### commute v. cost +- http://www.verysmallarray.com/best-new-york-city-neighborhoods-again/ +- mouseover map to update scatter plot + + +### hacker news reposts +- Network graph showing links to old discussions +- Which page has been submitted the most? (only include on per month or something like that...) +- https://news.ycombinator.com/item?id=23775707 + + +### scotus wars +- network diagram or grid +- https://scotuswars.gilslotd.com/ + + +### stock returns +- which stock has had the best return since the pandemic? +- http://benschmidt.org/mvp/#-Batting-oWAR-counting +- http://amandacox.github.io/img/big/returns.png +- Bottom triangle shows which have done the worst (what would have done the best if you shorted) +- scrolly intro building chart or live updating thing? +- [tidyquant](https://cran.r-project.org/web/packages/tidyquant/vignettes/TQ05-performance-analysis-with-tidyquant.html) for data + + +### Momentum transition +- https://blocks.roadtolarissa.com/1wheel/54f90245720d7e3210cea1edfa42089b +- it isn't a change in like absolute capacity, but i'm really interested in interfaces that don't gate interaction behind animation - don't think my version is there yet, but you can start using tools in totally different ways if there isn't latency. +- 538 game theory +- wsj stock picker +- propublica immigration slider + + +### Multi dimensional arraybuffers for js +- ndarray +- node write out npy files +- https://github.com/aplbrain/npyjs +- https://github.com/NicholasTancredi/read-npy-file +- hdfs +- apache arrow? +- https://google.github.io/flatbuffers/ +- https://github.com/GoogleChromeLabs/buffer-backed-object + +### forecast outliers + + +### track flair changes on subreddits +- https://www.reddit.com/r/nba/comments/ix0s3f/charania_paul_george_was_preaching_to_teammates/g63r5bm/ +- i think there was a NYT or 538 graphic about searches or something like that for 2014 world cup - after a country is elimated, who do their fans cheer for? + +### umap + oeis +- http://www.sspectra.com/math/MovieFrames/ + +### Animal pictures +- https://storage.googleapis.com/openimages/web/visualizer/index.html?set=train&type=segmentation&r=false&c=%2Fm%2F0gd36 +- bing api? + +### Basketball WP by margin +- trace out paths of games +- https://twitter.com/inpredict/status/1314734826696503298 +- https://roadtolarissa.com/golf-paths/ + +### NBA team changes +- [Zion is now the longest tenured Pelican](https://www.reddit.com/r/nba/comments/jyifrm/zion_is_now_the_longest_tenured_pelican/) +- Is there, like, a knicks team made up mostly of former suns players or something like that? +- Which team has had a player for the longest? Which team has had the lowest % returning players ever? + +### RCP polling +- Cut off dates for polls were selectively picked; make a chart that shows shifting day windows and how it always errors for GOP +- https://github.com/1wheel/scraping-2018/tree/master/rcp-avg +- https://www.nytimes.com/2020/11/17/us/politics/real-clear-politics.html + +### Citibike + +- Which stations have no bikes or too many bikes? +- How does this change throughout the day / over time +- https://www.citibikenyc.com/system-data + +### Distribution of gymnastics ages over time +- https://thecorrespondent.com/739/why-womens-gymnastics-is-legal-child-abuse/1740638383-e7ff4274 + +### weatherspark +- https://weatherspark.com/y/23912/Average-Weather-in-New-York-City-New-York-United-States-Year-Round +- show distribution instead of mean, facet by hour or month instead +- 3d? +- or change over years + +### Covid polarization but with bars + +- https://kieranhealy.org/blog/archives/2021/10/30/the-polarization-of-death/ + +### Rewrite NYT webheadline as a print +- fine tune t5 +### Has the NYT stopped reviewing as many off broadway shows? +### Custom tool to make diverging color scales +### LeBron Point Record +- Show every season as a grid games, color by points or other things +- NYT/WaPo did vertical lines which aren't readable (he's played 1421 games!) +### LeBron reddit nick names +### Smushed Voroni +> “One-dimensional” is a slight misnomer: the pointerX and pointerY transforms consider distance in both dimensions, but the distance along the non-dominant dimension is divided by 100. +https://observablehq.com/plot/interactions/pointer diff --git a/source/_posts/2012-09-29-maximin-connect-4-completed.md b/source/_posts/2012-09-29-maximin-connect-4-completed.md index d7364df5..d47d361f 100644 --- a/source/_posts/2012-09-29-maximin-connect-4-completed.md +++ b/source/_posts/2012-09-29-maximin-connect-4-completed.md @@ -1,6 +1,7 @@ --- title: Maximin Connect 4 Completed template: post.html +date: 2012-09-29 permalink: /maximin-connect-4-completed --- I've finished working on the Maximin Connect 4 program. I've set up a [page][1] where you can play around with the AI since I'm not sure how to embed HTML in these posts. Some general things I learned (I'll make a separate post with more Connect 4 specific ideas once I've run some more tests on the AI): diff --git a/source/_posts/2012-09-30-connect-4-ai-how-it-works.md b/source/_posts/2012-09-30-connect-4-ai-how-it-works.md index 74cfc201..b0e44f2b 100644 --- a/source/_posts/2012-09-30-connect-4-ai-how-it-works.md +++ b/source/_posts/2012-09-30-connect-4-ai-how-it-works.md @@ -1,6 +1,7 @@ --- title: Connect 4 AI: How it Works template: post.html +date: 2012-09-30 permalink: /connect-4-ai-how-it-works --- The [connect 4 playing program][1] uses a [minmax algorithm][2]. diff --git a/source/_posts/2012-10-06-speed-issues-with-gokos-online-dominion-implementation.md b/source/_posts/2012-10-06-speed-issues-with-gokos-online-dominion-implementation.md index 8b4fc118..64d7df8e 100644 --- a/source/_posts/2012-10-06-speed-issues-with-gokos-online-dominion-implementation.md +++ b/source/_posts/2012-10-06-speed-issues-with-gokos-online-dominion-implementation.md @@ -1,6 +1,7 @@ --- title: Speed Issues Goko Dominion template: post.html +date: 2012-10-06 permalink: /speed-issues-with-gokos-online-dominion-implementation --- This isn't very scientific, but to get a better sense of how slow playing [Dominion][1] on [goko][2] is compared to [isotropic][3] and to find out exactly what is making it slower, I spent an hour on both and recorded how the time was spent: diff --git a/source/_posts/2012-10-10-yglesias-on-amazons-pe-ratio.md b/source/_posts/2012-10-10-yglesias-on-amazons-pe-ratio.md index df58bb9d..a51a7b05 100644 --- a/source/_posts/2012-10-10-yglesias-on-amazons-pe-ratio.md +++ b/source/_posts/2012-10-10-yglesias-on-amazons-pe-ratio.md @@ -1,6 +1,7 @@ --- title: Yglesias on Amazon's P/E Ratio template: post.html +date: 2012-10-10 permalink: /yglesias-on-amazons-pe-ratio --- Yglesias [wonders][1] why Amazon's P/E is so high: diff --git a/source/_posts/2012-10-19-reddit-comment-visualizer.md b/source/_posts/2012-10-19-reddit-comment-visualizer.md index bf8deb6f..15c011c2 100644 --- a/source/_posts/2012-10-19-reddit-comment-visualizer.md +++ b/source/_posts/2012-10-19-reddit-comment-visualizer.md @@ -1,6 +1,7 @@ --- title: Reddit Comment Visualizer template: post.html +date: 2012-10-19 permalink: /reddit-comment-visualizer --- I've spent the last few days working on a [visualizer for reddit comments][1]. Using reddit's API, the program downloads a user's comments and graphs them with [flot][2]. diff --git a/source/_posts/2012-11-17-redditgraphs-retrospective.md b/source/_posts/2012-11-17-redditgraphs-retrospective.md index 0194784b..bc83c332 100644 --- a/source/_posts/2012-11-17-redditgraphs-retrospective.md +++ b/source/_posts/2012-11-17-redditgraphs-retrospective.md @@ -1,6 +1,7 @@ --- title: Redditgraphs Retrospective template: post.html +date: 2012-11-17 permalink: /redditgraphs-retrospective --- It's been nearly a month since my last post, about a comment visualizer I created for reddit. Since then, I've mostly been polishing the application and trying to share it with people. After posting the basic demo on /r/javascript, I was encouraged make improvements and host the project on its own domain. Registering “[redditgraphs.com][1]” for a year only cost $5 and it seemed more memorable and easier to access than “roadtolarissa.com/javascript/reddit-comment-visualizer“. I spent another week adding functionality – hourly trends, weekly trends, direct linking to user names – and making the UI prettier. diff --git a/source/_posts/2012-11-20-next-project.md b/source/_posts/2012-11-20-next-project.md index 5e83e91a..01515100 100644 --- a/source/_posts/2012-11-20-next-project.md +++ b/source/_posts/2012-11-20-next-project.md @@ -1,6 +1,7 @@ --- title: Next Project template: post.html +date: 2012-11-20 permalink: /next-project --- Finished with redditgraphs, I have a couple of ideas about what I'd like to work on next; I'm posting them to clarify my own thoughts and to get feedback. diff --git a/source/_posts/2012-12-19-interactive-visualization-of-white-house-petition-signatures.md b/source/_posts/2012-12-19-interactive-visualization-of-white-house-petition-signatures.md index 9a2bbb0b..233867db 100644 --- a/source/_posts/2012-12-19-interactive-visualization-of-white-house-petition-signatures.md +++ b/source/_posts/2012-12-19-interactive-visualization-of-white-house-petition-signatures.md @@ -1,6 +1,7 @@ --- title: White House Petition Signatures template: post.html +date: 2012-12-19 permalink: /interactive-visualization-of-white-house-petition-signatures --- diff --git a/source/_posts/2012-12-21-zoomable-sierpinski-triangle-with-d3-js.md b/source/_posts/2012-12-21-zoomable-sierpinski-triangle-with-d3-js.md index 58066004..88ed8216 100644 --- a/source/_posts/2012-12-21-zoomable-sierpinski-triangle-with-d3-js.md +++ b/source/_posts/2012-12-21-zoomable-sierpinski-triangle-with-d3-js.md @@ -1,6 +1,7 @@ --- title: Zoomable Sierpinski Triangle template: post.html +date: 2012-12-21 permalink: /zoomable-sierpinski-triangle-with-d3-js ---
diff --git a/source/_posts/2013-01-21-unemployment-rates.md b/source/_posts/2013-01-21-unemployment-rates.md
index cbfd640e..7dfa8c1a 100644
--- a/source/_posts/2013-01-21-unemployment-rates.md
+++ b/source/_posts/2013-01-21-unemployment-rates.md
@@ -1,6 +1,7 @@
---
title: Unemployment Rates
template: post.html
+date: 2013-01-21
permalink: /unemployment-rates
---
[
][1]
diff --git a/source/_posts/2013-01-28-whale-words.md b/source/_posts/2013-01-28-whale-words.md
index 1bd72659..1c569dd6 100644
--- a/source/_posts/2013-01-28-whale-words.md
+++ b/source/_posts/2013-01-28-whale-words.md
@@ -1,6 +1,7 @@
---
title: Whale Words
template: post.html
+date: 2013-01-28
permalink: /whale-words
---
[
][1]
diff --git a/source/_posts/2013-05-02-film-strips-post.md b/source/_posts/2013-05-02-film-strips-post.md
index d5e5887c..acb937ce 100644
--- a/source/_posts/2013-05-02-film-strips-post.md
+++ b/source/_posts/2013-05-02-film-strips-post.md
@@ -1,6 +1,7 @@
---
title: Film Strips
template: post.html
+date: 2013-05-02
permalink: /film-strips-post
---
[
][1]
diff --git a/source/_posts/2013-05-19-meteor-map.md b/source/_posts/2013-05-19-meteor-map.md
index 712dc0ee..e0c5d12d 100644
--- a/source/_posts/2013-05-19-meteor-map.md
+++ b/source/_posts/2013-05-19-meteor-map.md
@@ -1,6 +1,7 @@
---
title: Meteor Map
template: post.html
+date: 2013-05-19
permalink: /meteor-map
---
[
][1]
diff --git a/source/_posts/2013-06-16-nba_draft.md b/source/_posts/2013-06-16-nba_draft.md
index 02237728..f3ed82ea 100644
--- a/source/_posts/2013-06-16-nba_draft.md
+++ b/source/_posts/2013-06-16-nba_draft.md
@@ -1,6 +1,7 @@
---
title: NBA Draft
template: post.html
+date: 2013-06-16
permalink: /nba-draft
---
diff --git a/source/_posts/2013-10-22-twisters-post.md b/source/_posts/2013-10-22-twisters-post.md index 96ba7657..c22b0bf8 100644 --- a/source/_posts/2013-10-22-twisters-post.md +++ b/source/_posts/2013-10-22-twisters-post.md @@ -1,6 +1,7 @@ --- title: Twisters template: post.html +date: 2013-10-22 permalink: /twisters-post ---
@@ -46,7 +47,7 @@ But! I haven’t posted anything for four months and I’m looking forwa [1]: http://www.roadtolarissa.com/wp-content/uploads/2013/10/ok.png [2]: https://github.com/mbostock/d3/wiki/Zoom-Behavior - [3]: http://bl.ocks.org/mbostock/4699541 + [3]: http://blocks.roadtolarissa.com/mbostock/4699541 [4]: https://github.com/1wheel/tornado-tuners/blob/master/matchStates.py [5]: http://www.roadtolarissa.com/wp-content/uploads/2013/10/arc.png [6]: http://www.roadtolarissa.com/zoomable-sierpinski-triangle-with-d3-js/ diff --git a/source/_posts/2014-01-15-synth-scales.markdown b/source/_posts/2014-01-15-synth-scales.markdown index ce3bd8e9..558070be 100644 --- a/source/_posts/2014-01-15-synth-scales.markdown +++ b/source/_posts/2014-01-15-synth-scales.markdown @@ -1,6 +1,7 @@ --- template: post.html title: Making Music with d3 +date: 2014-01-15 permalink: /synth --- diff --git a/source/_posts/2014-03-06-population-division.markdown b/source/_posts/2014-03-06-population-division.markdown index 7bca5a01..cc67c69a 100644 --- a/source/_posts/2014-03-06-population-division.markdown +++ b/source/_posts/2014-03-06-population-division.markdown @@ -1,6 +1,7 @@ --- template: post.html title: Population Division +date: 2014-03-06 permalink: /population-division --- diff --git a/source/_posts/2014-06-23-even-fewer-lamdas-with-d3.markdown b/source/_posts/2014-06-23-even-fewer-lamdas-with-d3.markdown index 31164539..3937f8bd 100644 --- a/source/_posts/2014-06-23-even-fewer-lamdas-with-d3.markdown +++ b/source/_posts/2014-06-23-even-fewer-lamdas-with-d3.markdown @@ -1,9 +1,10 @@ --- template: post.html title: Even Fewer Lambdas +date: 2014-06-23 permalink: /even-fewer-lamdas-with-d3 --- -Writing d3 typically involves writing lots of anonymous functions. The [scatter plot](http://bl.ocks.org/mbostock/3887118) example illustrates two typical use cases: scales and attributes. +Writing d3 typically involves writing lots of anonymous functions. The [scatter plot](http://blocks.roadtolarissa.com/mbostock/3887118) example illustrates two typical use cases: scales and attributes. ## Scale computations diff --git a/source/_posts/2014-08-05-215-teeth.md b/source/_posts/2014-08-05-215-teeth.md index 960a77fe..1ee5f7f3 100644 --- a/source/_posts/2014-08-05-215-teeth.md +++ b/source/_posts/2014-08-05-215-teeth.md @@ -1,6 +1,7 @@ --- template: post.html title: 215 teeth / 1008 beats +date: 2014-08-05 permalink: /215-teeth --- @@ -22,7 +23,7 @@ While (I think) this is nicely elegant exploitation of 7, 8 and 9's relative pri I'm getting to work on more straightforward visualizations of data at [my job](http://www.bloomberg.com/visual-data) now; hoping to post more experimental work with [algorithms](http://bost.ocks.org/mike/algorithms/) and/or [rhythm](http://www.pianophase.com/) here soon. -Code for [gears](https://github.com/1wheel/roadtolarissa/blob/master/source/javascripts/posts/synthComp/gears.js) (drawing heavily from [Bostock’s Epicyclic Gearing bl.ocks](http://bl.ocks.org/mbostock/1353700) and [audio](https://github.com/1wheel/roadtolarissa/blob/master/source/javascripts/posts/synthComp/audio.js)) is on github. +Code for [gears](https://github.com/1wheel/roadtolarissa/blob/master/source/javascripts/posts/synthComp/gears.js) (drawing heavily from [Bostock’s Epicyclic Gearing bl.ocks](http://blocks.roadtolarissa.com/mbostock/1353700) and [audio](https://github.com/1wheel/roadtolarissa/blob/master/source/javascripts/posts/synthComp/audio.js)) is on github. diff --git a/source/_posts/2014-08-19-drawdown.md b/source/_posts/2014-08-19-drawdown.md index ab3ad731..22da7c17 100644 --- a/source/_posts/2014-08-19-drawdown.md +++ b/source/_posts/2014-08-19-drawdown.md @@ -1,6 +1,7 @@ --- template: post.html title: Drawdown +date: 2014-08-19 permalink: /drawdown --- @@ -33,7 +34,7 @@ var peak = 0; var n = prices.length for (var i = 1; i < n; i++){ dif = prices[peak] - prices[i]; - peak = dif < 0 ? i : j; + peak = dif < 0 ? i : peak; maxDrawdown = maxDrawdown > dif ? maxDrawdown : dif; } ``` diff --git a/source/_posts/2014-10-04-golf-paths.markdown b/source/_posts/2014-10-04-golf-paths.markdown index 06d7ff84..7dff9604 100644 --- a/source/_posts/2014-10-04-golf-paths.markdown +++ b/source/_posts/2014-10-04-golf-paths.markdown @@ -1,5 +1,6 @@ --- template: post.html +date: 2014-10-04 permalink: /golf-paths title: Golf Paths --- diff --git a/source/_posts/2014-10-19-dragon-curve.markdown b/source/_posts/2014-10-19-dragon-curve.markdown index 48e67301..ce06eba6 100644 --- a/source/_posts/2014-10-19-dragon-curve.markdown +++ b/source/_posts/2014-10-19-dragon-curve.markdown @@ -1,5 +1,6 @@ --- template: post.html +date: 2014-10-19 permalink: /dragon-curve title: Dragon Curve --- diff --git a/source/_posts/2014-12-24-convex-hulls.markdown b/source/_posts/2014-12-24-convex-hulls.markdown index 0b4c03c2..8e18ba29 100644 --- a/source/_posts/2014-12-24-convex-hulls.markdown +++ b/source/_posts/2014-12-24-convex-hulls.markdown @@ -1,6 +1,7 @@ --- template: post.html title: Convex Hulls +date: 2014-12-24 permalink: /convex-hulls --- diff --git a/source/_posts/2015-01-04-coloring-maps-with-d3.markdown b/source/_posts/2015-01-04-coloring-maps-with-d3.markdown index 4867cb07..e93a3b4b 100644 --- a/source/_posts/2015-01-04-coloring-maps-with-d3.markdown +++ b/source/_posts/2015-01-04-coloring-maps-with-d3.markdown @@ -1,6 +1,7 @@ --- template: post.html title: Coloring Maps +date: 2015-01-04 permalink: /blog/2015/01/04/coloring-maps-with-d3 --- @@ -12,7 +13,7 @@ This post describes several [d3 quantitative scales](https://github.com/mbostock We start with an array of objects - `places` - representing the filled in areas on the right choropleth. Each has a `value` property equal to a number that we'll encode as a color using the `colorScale` defined in the center code snippet. The scatter plot on the left shows the distribution of values. -The code in the center uses a few libraries: `purples` an array of 5 [colorbrewer](http://bl.ocks.org/mbostock/5577023) purple shades, `_` [library](https://lodash.com/) of helper functions, `ss` [simple-statistics](http://www.macwright.org/simple-statistics/), `ƒ` a [field accessor](http://roadtolarissa.com/blog/2014/06/23/even-fewer-lamdas-with-d3/), and `d3` [itself](http://d3js.org). +The code in the center uses a few libraries: `purples` an array of 5 [colorbrewer](http://blocks.roadtolarissa.com/mbostock/5577023) purple shades, `_` [library](https://lodash.com/) of helper functions, `ss` [simple-statistics](http://www.macwright.org/simple-statistics/), `ƒ` a [field accessor](http://roadtolarissa.com/blog/2014/06/23/even-fewer-lamdas-with-d3/), and `d3` [itself](http://d3js.org). \ No newline at end of file diff --git a/source/_posts/2017-11-25-d3-mp4.md b/source/_posts/2017-11-25-d3-mp4.md index dd13cb45..a454922b 100644 --- a/source/_posts/2017-11-25-d3-mp4.md +++ b/source/_posts/2017-11-25-d3-mp4.md @@ -1,13 +1,14 @@ --- template: post.html title: D3 to MP4 +date: 2017-11-25 permalink: /d3-mp4 draft: false --- -Generating a high-resolution video from a d3 animation is tricky. [LICEcap](https://www.cockos.com/licecap/) and QuickTime screen recording work in a pinch, but they aren't scriptable and lose FPS without a beefy video card. +Generating a [high-resolution video](https://www.nytimes.com/interactive/2018/01/24/world/is-there-something-wrong-with-democracy.html) from a d3 animation is tricky. [LICEcap](https://www.cockos.com/licecap/) and QuickTime screen recording work in a pinch, but they aren't scriptable and lose FPS without a beefy video card. -Noah Veltman has [written about](https://github.com/veltman/gifs) and [presented](http://slides.com/veltman/d3unconf/#/) different techniques for exporting d3 graphics. The best way I've found of exporting video come from him and uses a delightful hack: [modifying time itself](https://bl.ocks.org/veltman/5de325668417b1d504dc). +Noah Veltman has [written about](https://github.com/veltman/gifs) and [presented](http://slides.com/veltman/d3unconf/#/) different techniques for exporting d3 graphics. The best way I've found of exporting video come from him and uses a delightful hack: [modifying time itself](https://blocks.roadtolarissa.com/veltman/5de325668417b1d504dc). ## Mutate Time @@ -17,18 +18,14 @@ Inside of your clientside code, overwrite [performance.now](https://developer.mo if (document.URL.includes('d3-video-recording')){ window.currentTime = 0 performance.now = () => currentTime - window.setTime = t => curTime = t - - var graphSel = d3.select('html') - .st({width: 1920, height: 1080, position: 'absolute'}) } ``` -This code only runs if the url contains `d3-video-recording`, making it easy to toggle between automatic and manual animations with a query string. It also sets the chart's dimensions to `1920x1080` and positions it at the upper-left corner of the screen so cropping will be simple. +This code only runs if the url contains `d3-video-recording`, making it easy to toggle between automatic and manual animations with a query string. ## Take Screenshots -[puppeteer](https://github.com/GoogleChrome/puppeteer) loads the page, moving time forward slowly and taking a screenshot over and over again. Even though each screenshot takes over half a second to render, controlling the browser's perception of time ensures no frames are dropped. +[puppeteer](https://github.com/GoogleChrome/puppeteer) loads the page, moving time forward slowly and taking a screenshot over and over again. Even though each screenshot takes over [half a second](https://bugs.chromium.org/p/chromium/issues/detail?id=741689&can=1&q=is%3Astarred%20&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified) to render, controlling the browser's perception of time ensures no frames are dropped. ```js const puppeteer = require('puppeteer') @@ -49,8 +46,10 @@ const d3 = require('d3') await sleep(50) let path = __dirname + '/png/' + d3.format('05')(frame) + '.png' - let clip = {x: 0, y: 0, width: 1920, height: 1080} - await page.screenshot({path, clip}) + + await page.setViewport({width: 1920, height: 1080, deviceScaleFactor: 2}) + const chartEl = await page.$('.chart') + await chartEl.screenshot({path}) } browser.close() diff --git a/source/_posts/2017-11-28-2017-chart-diary.md b/source/_posts/2017-11-28-2017-chart-diary.md index 5145e96a..52bfc8b7 100644 --- a/source/_posts/2017-11-28-2017-chart-diary.md +++ b/source/_posts/2017-11-28-2017-chart-diary.md @@ -1,6 +1,7 @@ --- template: post.html title: 2017 Chart Diary +date: 2017-11-28 permalink: /2017-chart-diary shareimg: http://roadtolarissa.com/images/posts/2017-chart-diary.png --- @@ -11,7 +12,7 @@ shareimg: http://roadtolarissa.com/images/posts/2017-chart-diary.png The idea is cribbed from an [Upshot piece](http://www.nytimes.com/interactive/2015/05/28/upshot/you-draw-it-how-family-income-affects-childrens-college-chances.html). We got a little crunched for time and weren't as fancy about customizing feedback for incorrectly drawn lines. Still, I think the core idea of making people put their assumptions down and overlaying reality over them works and increases [memorability/engagement](http://faculty.washington.edu/jhullman/explaining_the_gap.pdf). -I'm a little surprised this form hasn't been used more. The chart dragging code isn't super complex - just [60 lines of d3](http://bl.ocks.org/1wheel/07d9040c3422dac16bd5be741433ff1e) for an mpv. +I'm a little surprised this form hasn't been used more. The chart dragging code isn't super complex - just [60 lines of d3](http://blocks.roadtolarissa.com/1wheel/07d9040c3422dac16bd5be741433ff1e) for an mpv. One bit that we should have spent more time on before publishing: clearly labeling the years. We originally put the year labels [directly below](https://imgur.com/xUZurSS) the tick, but there was a lot of confusion over Obama getting credit/blame for Bush's last year in office. Moving the year labels to the [left of the tick](https://imgur.com/vIqA2Q1) clarified that the data points were for values at the end of the year. @@ -74,7 +75,7 @@ Jeremy got a hold of some interesting data this afternoon and we threw together I made the map with d3 and a couple of canvas tricks from an [old Bloomberg piece](https://imgur.com/XdCmjNR---https://www.bloomberg.com/graphics/2015-uk-election/messy.html). There are too many points (80,000+!) to animate with svg, so I used two canvas layers. The top one is cleared every frame and each moving point is redrawn. The bottom frame only has points drawn on it and is never cleared so it keeps a record of every location. -We briefly talked about showing time in different ways - a line chart or small multiple maps by hour - but there was a chunk of time missing. After publishing, I explored an alternative representation with [d3-contour](https://imgur.com/4pmDBhy---https://bl.ocks.org/1wheel/5d6990abfff925e6a37e0557f1de18e5) which clearly shows the higher rate of hacking in Eastern Europe and China. It's easier to use a nonlinear scale when you're programming at a higher level than drawing rectangles on top of each other. +We briefly talked about showing time in different ways - a line chart or small multiple maps by hour - but there was a chunk of time missing. After publishing, I explored an alternative representation with [d3-contour](https://imgur.com/4pmDBhy---https://blocks.roadtolarissa.com/1wheel/5d6990abfff925e6a37e0557f1de18e5) which clearly shows the higher rate of hacking in Eastern Europe and China. It's easier to use a nonlinear scale when you're programming at a higher level than drawing rectangles on top of each other. Of course, number of hacked IPs per square mile is not the most meaningful thing in the world to show. Perhaps some kind of binning to compare the amount of hacking to the number of computers in different regions of the world would have been a better approach. @@ -119,9 +120,9 @@ One of my favorite things about writing code in response to the news cycle is ge This came together quite a lot faster than the 2015 UK Election Results piece I did at Bloomberg. I think we only decided that we were going to purchase a live feed of election results from the Press Association about a week and a half ahead of the election night. -Not sure if we were actually going actually do anything, I played around trying to generate a [hex cartogram](https://imgur.com/zom9SuO---https://bl.ocks.org/1wheel/raw/b833c3490bacc377f9485c060f1c470a/). It was harder than I thought it would be (Greater London is quite dense); we used [Ben Flanagan's layout](https://imgur.com/6NZ8spP---https://www.arcgis.com/home/item.html?id=15baaa6fecd54aa4b7250780b6534682) instead. +Not sure if we were actually going actually do anything, I played around trying to generate a [hex cartogram](https://imgur.com/zom9SuO---https://blocks.roadtolarissa.com/1wheel/raw/b833c3490bacc377f9485c060f1c470a/). It was harder than I thought it would be (Greater London is quite dense); we used [Ben Flanagan's layout](https://imgur.com/6NZ8spP---https://www.arcgis.com/home/item.html?id=15baaa6fecd54aa4b7250780b6534682) instead. -In retrospect, spending so much time exploring cartograms wasn't a great idea. I think this [arrow chart](https://imgur.com/HauRsAm---https://bl.ocks.org/1wheel/c7e86b96a0f9c4cafa4218515ff163ef) showing the shift in UKIP's vote share along with the Labour/Conservative split had potential but there wasn't enough time to finish it. +In retrospect, spending so much time exploring cartograms wasn't a great idea. I think this [arrow chart](https://imgur.com/HauRsAm---https://blocks.roadtolarissa.com/1wheel/c7e86b96a0f9c4cafa4218515ff163ef) showing the shift in UKIP's vote share along with the Labour/Conservative split had potential but there wasn't enough time to finish it. ## [The Golden State Warriors’ Record-Setting Postseason](https://www.nytimes.com/interactive/2017/06/17/sports/basketball/golden-state-warriors-post-season.html) @@ -143,7 +144,7 @@ I had trouble squeezing all the [annotations](https://imgur.com/qsjUFmH) in. Tom ## [It’s Not Your Imagination. Summers Are Getting Hotter.](https://www.nytimes.com/interactive/2017/07/28/climate/more-frequent-extreme-summer-heat.html) -Nadja did almost all the work on this. The [original animation](https://imgur.com/Mognewr) had a single frame for each time period. I thought it'd be cool to transition between the time periods - not too hard if you know to use the [mask element](https://bl.ocks.org/1wheel/76a07ca0d23f616d29349f7dd7857ca5)! +Nadja did almost all the work on this. The [original animation](https://imgur.com/Mognewr) had a single frame for each time period. I thought it'd be cool to transition between the time periods - not too hard if you know to use the [mask element](https://blocks.roadtolarissa.com/1wheel/76a07ca0d23f616d29349f7dd7857ca5)! ## [Good, Evil, Ugly, Beautiful: Help Us Make a ‘Game of Thrones’ Chart](https://www.nytimes.com/interactive/2017/08/09/upshot/game-of-thrones-chart.html) @@ -174,7 +175,7 @@ This started as a follow-up to reports that the [DOJ was going to challenge affi The design of the top charts went through several iterations. We started out with [slope charts](http://imgur.com/QnZyGDP) showing how the student population of different demographics had changed at different types of schools over the last 35 years. Fitting the white percentages on common scales was [tricky](http://imgur.com/FkH1Pzq), so we switched to showing the [difference](http://imgur.com/buvzjrZ) between percent admissions and population. -I really wanted the gap charts to work - they show so many different stories with just a few lines! - so I spent some time [tweaking the layout](http://imgur.com/zfFGOQJ) to squeeze them in. Distinguishing between positive and negative gaps wasn't intuitive though ([even with particle animation](https://imgur.com/3ZkgDV9---https://bl.ocks.org/1wheel/4b9d34d74bd64a63d34028f160a71d7b)), so we ended up using an even more slimmed down version of the [slope charts](http://imgur.com/oAnVpuG). +I really wanted the gap charts to work - they show so many different stories with just a few lines! - so I spent some time [tweaking the layout](http://imgur.com/zfFGOQJ) to squeeze them in. Distinguishing between positive and negative gaps wasn't intuitive though ([even with particle animation](https://imgur.com/3ZkgDV9---https://blocks.roadtolarissa.com/1wheel/4b9d34d74bd64a63d34028f160a71d7b)), so we ended up using an even more slimmed down version of the [slope charts](http://imgur.com/oAnVpuG). If I had a little more time, I would have liked to try including more chart forms and alternative gap measurements (the ratio of percents isn't the same as the difference of percents!) by transitioning between them in a scrollytelling piece. That would have required a big rewrite of copy/code which didn't make sense to attempt while we were waiting for a break in the news to publish. Other things to explore: a wider selection of schools (we had a drop down that let you chart any of the ~4,000 colleges in the US, but weren't 100% confident in the data so it was cut) and graduation rates. @@ -219,7 +220,7 @@ To give his numbers a little bit of context, we started exploring different ways All of the 500+ lines of javascript that create the charts were written in 25 hours. This was probably a little too ambitious. Including all of the hurricanes looked great, but after running into performance issues on mobile and retina displays we decided to only including category 3 hurricanes. Coming at it fresh, a canvas rewrite would only have taken an hour or two (d3.line is super flexible!) but by the time that I realized we needed one I was too worn out to do it. -I took a couple days the week after to [rewrite in regl](https://imgur.com/fSrst3U---https://bl.ocks.org/1wheel/9c90f55041220c600162b85f84e807c5). Includes my right to left time scale (so the westward paths don't invert) and line to scatter transition that were just a little too confusing to publish. +I took a couple days the week after to [rewrite in regl](https://imgur.com/fSrst3U---https://blocks.roadtolarissa.com/1wheel/9c90f55041220c600162b85f84e807c5). Includes my right to left time scale (so the westward paths don't invert) and line to scatter transition that were just a little too confusing to publish. ## [We Charted Arctic Sea Ice for Nearly Every Day Since 1979. You’ll See a Trend.](https://www.nytimes.com/interactive/2017/09/22/climate/arctic-sea-ice-shrinking-trend-watch.html) @@ -250,7 +251,7 @@ Design based on one of my [favorite graphics](https://imgur.com/C2Aopfu---http:/ After getting a couple of requests for an update to the [2016 version](https://roadtolarissa.com/worlds-group), I grabbed this year's [data](http://lol.esportswikis.com/wiki/2017_Season_World_Championship/Main_Event#Schedule) and threw it into the charts. The [code](https://github.com/1wheel/roadtolarissa/blob/master/source/worlds-group-2017/script.js) wasn't quite as pretty as I remembered, but I think I've fixed the three-way tiebreaker bug that threw off the [MSI chart](https://imgur.com/FH7Mndt---https://roadtolarissa.com/msi-group/)—if not please let me know! -Hopefully next year I'll have a chance to explore another [representation](https://imgur.com/h5sCVoz---https://bl.ocks.org/1wheel/edb19f67a301bdd8f28abc70db7e869f) of this data. I'd like something that you can read top to bottom as matches progress. With our World Cup coverage [canceled](https://twitter.com/adamrpearce/status/917935378748837889) there should be plenty of time! +Hopefully next year I'll have a chance to explore another [representation](https://imgur.com/h5sCVoz---https://blocks.roadtolarissa.com/1wheel/edb19f67a301bdd8f28abc70db7e869f) of this data. I'd like something that you can read top to bottom as matches progress. With our World Cup coverage [canceled](https://twitter.com/adamrpearce/status/917935378748837889) there should be plenty of time! ## [Every Tax Cut and Tax Increase in the House G.O.P. Bill and What It Would Cost](https://www.nytimes.com/interactive/2017/11/15/us/politics/every-tax-cut-in-the-house-tax-bill.html) @@ -259,23 +260,23 @@ We wanted to enumerate everything in the tax bill while also providing a higher Some of the provisions in the bill had a comparatively small impact on revenue and weren't tall enough to see as stacked boxes. Since we were also trying to show everything in the bill, I stole an idea from a [Bloomberg piece](https://www.bloomberg.com/graphics/2016-who-marries-whom/) and laid out a short description of each provision in a grid. -We also briefly explored ways of showing numbers to represent a ten year window, making a [stacked area chart](https://imgur.com/LOwj9ji.png) and putting a chart of revenue impact over time in a tooltip. I thought it would be fun to transition from boxes to an area chart, but there wasn't much to say about the timing of different provisions. A [treemap alternative](https://i.imgur.com/r81uKKS.gif---https://bl.ocks.org/1wheel/45f3ed2f6931c286932fe34058c096c0) I played with wasn't quite ready. +We also briefly explored ways of showing numbers to represent a ten year window, making a [stacked area chart](https://imgur.com/LOwj9ji.png) and putting a chart of revenue impact over time in a tooltip. I thought it would be fun to transition from boxes to an area chart, but there wasn't much to say about the timing of different provisions. A [treemap alternative](https://i.imgur.com/r81uKKS.gif---https://blocks.roadtolarissa.com/1wheel/45f3ed2f6931c286932fe34058c096c0) I played with wasn't quite ready. One detail I'd explore if I was studying human perception: how people process `1.2 trillion v. 86 billion` compared to how they understand `1,215 billion v. 86 billion`. My intuition is that our brains don't actually divide by a thousand to compare a `trillion` to `billion`. Consensus within the department was that the comma was pretty confusing, so I might be out thinking myself. ## [Tax Bill Calculator: Will Your Taxes Go Up or Down?](https://www.nytimes.com/interactive/2017/12/17/upshot/tax-calculator.html) -Finally published something with WebGL! I started working on this last month when Bui and Ben realized they could model the impact of the tax bill on thousands of households by running CPS data through [an open source tax model](https://github.com/open-source-economics/Tax-Calculator). Thinking it'd be interesting to see how different demographics' tax bills would change, I set up a [crossfilterish](http://square.github.io/crossfilter/) [interface](https://imgur.com/1IiOWS4---https://bl.ocks.org/1wheel/raw/e051435d784dae23360cdddd6b832a16/) to explore. With only 25,000 data points, filtering on multiple dimensions made the chart pretty sparse. So Bui used [small multiples](https://imgur.com/3A0h16U---https://www.nytimes.com/interactive/2017/11/28/upshot/what-the-tax-bill-would-look-like-for-25000-middle-class-families.html) instead, which also don't [require interaction to compare](http://worrydream.com/MagicInk/#interactivity_considered_harmful). +Finally published something with WebGL! I started working on this last month when Bui and Ben realized they could model the impact of the tax bill on thousands of households by running CPS data through [an open source tax model](https://github.com/open-source-economics/Tax-Calculator). Thinking it'd be interesting to see how different demographics' tax bills would change, I set up a [crossfilterish](http://square.github.io/crossfilter/) [interface](https://imgur.com/1IiOWS4---https://blocks.roadtolarissa.com/1wheel/raw/e051435d784dae23360cdddd6b832a16/) to explore. With only 25,000 data points, filtering on multiple dimensions made the chart pretty sparse. So Bui used [small multiples](https://imgur.com/3A0h16U---https://www.nytimes.com/interactive/2017/11/28/upshot/what-the-tax-bill-would-look-like-for-25000-middle-class-families.html) instead, which also don't [require interaction to compare](http://worrydream.com/MagicInk/#interactivity_considered_harmful). While Bui's piece provided a good overview of the tax bill, it still didn't answer everyone's biggest question: how will this affect *my* taxes? To get more data points with information about what people actually paid in taxes, Bui started talking to the IRS. -Canvas can't animate hundreds of thousands of points, so we decided to rewrite in [regl](http://regl.party/). [Peter's](https://peterbeshai.com/beautifully-animate-points-with-webgl-and-regl.html) tutorial helped me start [animating the points](https://bl.ocks.org/1wheel/5f0913c88cf80c6a3b00afb7b4f832db), but I ran into difficulties pretty fast. Rich Harris showed me how to draw opaque points, but they didn't stack quite right; the areas with the highest densities weren't the [darkest]( https://bl.ocks.org/1wheel/2322a47e760dcdc378dae1cd89d635af). Totally stuck, we tried rewriting in canvas, but the [lack of zoom](https://imgur.com/fQNJHCw) was lame. I ended up asking for help in the regl chat and Ricky Reusser showed me how to fix it with [a white background color](https://codepen.io/rsreusser/pen/LOKOxZ?editors=1010). +Canvas can't animate hundreds of thousands of points, so we decided to rewrite in [regl](http://regl.party/). [Peter's](https://peterbeshai.com/beautifully-animate-points-with-webgl-and-regl.html) tutorial helped me start [animating the points](https://blocks.roadtolarissa.com/1wheel/5f0913c88cf80c6a3b00afb7b4f832db), but I ran into difficulties pretty fast. Rich Harris showed me how to draw opaque points, but they didn't stack quite right; the areas with the highest densities weren't the [darkest]( https://blocks.roadtolarissa.com/1wheel/2322a47e760dcdc378dae1cd89d635af). Totally stuck, we tried rewriting in canvas, but the [lack of zoom](https://imgur.com/fQNJHCw) was lame. I ended up asking for help in the regl chat and Ricky Reusser showed me how to fix it with [a white background color](https://codepen.io/rsreusser/pen/LOKOxZ?editors=1010). There were a couple of similar problems that were hard to debug - no inspect element like SVG has! On some computers, the points with 0 `gl_pointSize` were still [getting drawn](https://imgur.com/fQNJHCw). My hacky fix was to draw very small points off-screen. We also had difficulties getting all the data to the browser. At first we tried loading 20% of the rows at a time. This caused the chart to flicker on load and the successive redraws made the page laggy. So instead we loaded the data incrementally by column. Initially, just the income and tax change columns needed to position the points are loaded. Then the columns with the categorical data for the filters are loaded in the the order that they appear on the page. -Getting this done before the bill passed was challenging. Some of the functions I've added to [jetpack](https://github.com/gka/d3-jetpack) like tooltips and [layers](https://bl.ocks.org/1wheel/f9b9909f10ed0f01780c5338ad38bd50) made it a little easier. And Blacki actually made finishing possible, jumping in right after starting at the Times and doing a ton of work while I was suffering from the flu. +Getting this done before the bill passed was challenging. Some of the functions I've added to [jetpack](https://github.com/gka/d3-jetpack) like tooltips and [layers](https://blocks.roadtolarissa.com/1wheel/f9b9909f10ed0f01780c5338ad38bd50) made it a little easier. And Blacki actually made finishing possible, jumping in right after starting at the Times and doing a ton of work while I was suffering from the flu. For more on the collection of the data and the actual story, check out [Ben's writeup](https://www.nytimes.com/2017/12/19/insider/how-to-build-a-tax-calculator-thats-actually-useful.html). diff --git a/source/_posts/2018-01-20-aaronson-oracle.md b/source/_posts/2018-01-20-aaronson-oracle.md index 98b7988c..8ca41674 100644 --- a/source/_posts/2018-01-20-aaronson-oracle.md +++ b/source/_posts/2018-01-20-aaronson-oracle.md @@ -1,6 +1,7 @@ --- template: post.html title: Aaronson Oracle +date: 2018-01-20 permalink: /oracle shareimg: https://i.imgur.com/rfwNaUx.png --- diff --git a/source/_posts/2018-03-01-same-sex-legal.md b/source/_posts/2018-03-01-same-sex-legal.md index 69189e60..0bdeaf35 100644 --- a/source/_posts/2018-03-01-same-sex-legal.md +++ b/source/_posts/2018-03-01-same-sex-legal.md @@ -1,6 +1,7 @@ --- template: post.html title: The Rise and Fall of Same-Sex Marriage Bans +date: 2018-03-01 permalink: /same-sex-legal shareimg: https://i.imgur.com/YeoOlAC.png --- diff --git a/source/_posts/2018-03-30-stringline-scrape.md b/source/_posts/2018-03-30-stringline-scrape.md index 2a99670e..504324c6 100644 --- a/source/_posts/2018-03-30-stringline-scrape.md +++ b/source/_posts/2018-03-30-stringline-scrape.md @@ -1,6 +1,7 @@ --- template: post.html title: MTA Marey +date: 2018-03-30 permalink: /mta-marey draft: true shareimg: http://roadtolarissa.com/images/posts/tktk.png diff --git a/source/_posts/2018-04-15-top-3-movies.md b/source/_posts/2018-04-15-top-3-movies.md index 1818df75..b4428826 100644 --- a/source/_posts/2018-04-15-top-3-movies.md +++ b/source/_posts/2018-04-15-top-3-movies.md @@ -1,6 +1,7 @@ --- template: post.html title: Every Top Three Grossing Movie Over The Last 25 Years +date: 2018-04-15 permalink: /top-3-movies shareimg: https://i.imgur.com/0IADOwR.png --- diff --git a/source/_posts/2018-04-25-hot-reload-hack.md b/source/_posts/2018-04-25-hot-reload-hack.md index f47968b4..7ac598c5 100644 --- a/source/_posts/2018-04-25-hot-reload-hack.md +++ b/source/_posts/2018-04-25-hot-reload-hack.md @@ -1,6 +1,7 @@ --- template: post.html title: Hackable Hot Reloading +date: 2018-04-25 permalink: /hot-reload shareimg: https://i.imgur.com/ZNkXwEx.png --- @@ -10,7 +11,34 @@ shareimg: https://i.imgur.com/ZNkXwEx.png Ever since seeing Bret Victor rewire a platformer live on stage, I've wanted to write code more interactively. - + + + +
getting plastered all over it. Hopefully this post shows how far a little glue code can go when paired with a folder of markdown files, `rsync` and a static server.
+
+If you'd like to try it without futzing with the literate bits, there's a [javascript only](https://github.com/1wheel/roadtolarissa/blob/master/source/literate-blogging/index.js) version.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/_posts/2018-06-01-2018-chart-diary.md b/source/_posts/2018-06-01-2018-chart-diary.md
index 0b5f1562..f1ece623 100644
--- a/source/_posts/2018-06-01-2018-chart-diary.md
+++ b/source/_posts/2018-06-01-2018-chart-diary.md
@@ -1,274 +1,190 @@
---
template: post.html
title: 2018 Chart Diary
+date: 2018-12-03
permalink: /2018-chart-diary
-shareimg: http://roadtolarissa.com/images/posts/2017-chart-diary.png
-draft: true
+shareimg: https://roadtolarissa.com/imgur-down/2018-chart-diary-promo.png
---
-Previously: [2016](https://roadtolarissa.com/2017-chart-diary/) [2017](https://roadtolarissa.com/2017-chart-diary/)
+_Previously: [2016](https://roadtolarissa.com/2016-chart-diary/) [2017](https://roadtolarissa.com/2017-chart-diary/)_
## [Is There Something Wrong with Democracy?](https://www.nytimes.com/interactive/2018/01/24/world/is-there-something-wrong-with-democracy.html)
-Larry [sketched out](https://imgur.com/9gl9sPf) a Hans Rosling style connected scatter plot about democracy and I turned it into an [unstyled animation](https://imgur.com/XiKMDYi) with a bit of d3.
+Larry [sketched out](https://imgur.com/9gl9sPf) a Hans Rosling-style connected scatter plot about democracy and I turned it into an [unstyled animation](https://imgur.com/XiKMDYi) with a bit of d3.
The tricky bit: he was producing an actual video, not a webpage. I found an objectively bad way of [exporting](https://roadtolarissa.com/d3-mp4/) a d3 animation as a video by taking a bunch of screenshots with a headless browser and stitching them together.
I wish there was an easier way of doing this. [Chart Party](https://imgur.com/tEN3bkf---https://www.youtube.com/watch?v=t_SsIKgwvz4) does incredibly creative work and I think some of that's because video lets you walk people through complex forms in a way that's even more friendly than scrolling. I'd like to try, but learning a whole new way of working, especially with something that requires sharing more of yourself, is [daunting](https://imgur.com/zgthTOM---https://www.youtube.com/user/jonbois/videos).
-
-
## [The Rise and Fall of Same-Sex Marriage Bans](https://roadtolarissa.com/same-sex-legal/)
Basically a stacked bar chart with two twists.
-First, labeling the states lets you follow an individual state over time. States that change are highlighted with bolding and tweaking the sort order so you can easily count how many states switched into each group. This doesn't do great job highlighting which group the state [switched from](https://imgur.com/a/gWSUy), but that's not too important here since the progression is always No Law → Ban → Legal.
+First, labeling the states lets you follow an individual state over time. States that change are highlighted with bolding and tweaking the sort order so you can easily count how many states switched into each group. This doesn't do great job highlighting which group the state [switched from](https://imgur.com/a/gWSUy---https://imgur.com/fVuvDJJ), but that's not too important here since the progression is always No Law → Ban → Legal.
-Second, the baseline is adjusted so that No Law always sits in middle of the chart. This puts more emphasis on the total number of places with bans.
-
-TKTK imgs, baseline switch
+Second, the baseline is adjusted to puts more emphasis on the total number of places with bans, giving the whole shape a fun outline.
## [Rich White Boys Stay Rich. Black Boys Don’t](https://www.nytimes.com/interactive/2018/03/19/upshot/race-class-white-and-black-men.html)
-Kevin did most of the charting work on this piece - I just got pulled in as an expert dot animator.
-
-We started out with a [SVG animation](https://bl.ocks.org/1wheel/7ddedc637c07104886f6909215a41b7f), tried out Elijah's [canvas sankey particles](https://bl.ocks.org/emeeks/e9d64d27f286e61493c9) and ended up rewriting in regl to get more dots on the screen.
+Amanda and Kevin did most of the charting work on this piece - I just got pulled in as an expert dot animator.
-The final version gets better performance by passing in [array of attributes](https://bl.ocks.org/1wheel/9b3bcc4ce8266913c0a0ddd4120a41de) to the vertex shader - after publishing the very helpful [regl chat](gitter.im/mikolalysenko/regl) showed me how to fix.
+We started out with a [SVG animation](https://blocks.roadtolarissa.com/1wheel/7ddedc637c07104886f6909215a41b7f---https://roadtolarissa.com/imgur-down/income-svg.gif), tried out Elijah's [canvas sankey particles](https://blocks.roadtolarissa.com/emeeks/e9d64d27f286e61493c9---https://roadtolarissa.com/imgur-down/income-meeks.gif) and ended up rewriting in [regl](https://blocks.roadtolarissa.com/1wheel/9b3bcc4ce8266913c0a0ddd4120a41de---https://roadtolarissa.com/imgur-down/income-regl.gif) to get more dots on the screen.
-This piece probably has the worst data to ink ratio of anything I've made; 10,000 dots to show 10 data points. I think it would have been interesting to try show more of distributions across race/sex/parent income at once, but when you've got such important numbers going on big a couple of them can work.
+This piece probably has the worst data to ink ratio of anything I've made; 10,000 dots to show 10 data points. I think it would have been interesting to try show more of distributions across race/sex/parent income at once, but when you've got such important numbers going big on a couple of them can work.
-I got a reader email complaining how long it took watch the animation. I made a [static version](https://bl.ocks.org/1wheel/1629f9dbc0d48137ac3a8cb395e5ec4c) incorporating some of his suggestions]. Definitely more information dense, but it doesn't have quite the same impact.
+I got a reader email complaining how long it took watch the animation, and made a [static version](https://blocks.roadtolarissa.com/1wheel/1629f9dbc0d48137ac3a8cb395e5ec4c---https://roadtolarissa.com/imgur-down/income-boring.png) incorporating some of his suggestions. Definitely more information-dense, but it doesn't have quite the same impact.
## [Every Top Three Grossing Movie Over The Last 25 Years](https://roadtolarissa.com/top-3-movies/)
-After seeing Axios's [piece](https://www.axios.com/black-panther-box-office-titanic-top-3-north-america-avatar-star-wars-32a35770-59fc-4ccc-bd5b-3a85d7144266.html) on Black Panther becoming one of the highest (non-inflation adjusted) grossing movies of all time, I was curious how many other movies had done so. Originally, I copied the step interpolation - it looks cool! - [but Lisa's post](https://blog.datawrapper.de/weekly-chart-altitude/) convinced me that it was a little misleading for cumulative data.
+After seeing Axios's [piece](https://www.axios.com/black-panther-box-office-titanic-top-3-north-america-avatar-star-wars-32a35770-59fc-4ccc-bd5b-3a85d7144266.html) on Black Panther becoming one of the highest (non-inflation adjusted) grossing movies of all time, I was curious how many other movies had done so. Originally, I copied the step interpolation - it looks cool! - [but Lisa's post](https://imgur.com/3NiBsQL---https://blog.datawrapper.de/weekly-chart-altitude/) convinced me that it was a little misleading for continuous cumulative data.
-I like the scrubbability of seeing the scale suddenly increase when there's a new record, but some of the drama gets lost if you scroll too quickly. Updating the y scale elastically (like this [this path](https://www.bloomberg.com/politics/graphics/2015-redistricting/) or [this zoom](https://www.nytimes.com/interactive/2015/10/27/world/greenland-is-melting-away.html)) instead of instantly might have worked better.
+I like the scrubbability of seeing the scale suddenly increase when there's a new record, but some of the drama gets lost if you scroll too quickly. Updating the y scale elastically (like [this path](https://www.bloomberg.com/politics/graphics/2015-redistricting/) or [this zoom](https://www.nytimes.com/interactive/2015/10/27/world/greenland-is-melting-away.html)) instead of instantly might have worked better.
Grabbing data from Axios instead of having to find it, scrape it and check for errors is the best. In theory, I should have updated with more recent data (Infinity War!) and gotten a better sample of top grossing movies in the 80s...
## [Selling Low and Buying High Can Beat the Market](https://roadtolarissa.com/sell-strat/)
-I got the idea for this piece after Feburary dip in stock prices and seeing comments like ["I like to look at it as stocks going on sale. Time to buy!"](https://www.reddit.com/r/personalfinance/comments/7vngon/dont_sell_the_stocks_in_your_retirement_portfolio/dttomu6/). Is it actually better to buy after a dip in prices? Or should you sell?
+I got the idea for this piece after the Feburary dip in stock prices and seeing comments like ["I like to look at it as stocks going on sale. Time to buy!"](https://www.reddit.com/r/personalfinance/comments/7vngon/dont_sell_the_stocks_in_your_retirement_portfolio/dttomu6/). Is it actually better to buy after a dip in prices? Or should you sell?
+
+[Elliot Bently](http://ejb.github.io/2017/06/25/trading-bot-sketches.html) made a [trading simulator](https://www.wsj.com/graphics/build-your-own-trading-bot/) for the WSJ last year that came close to answering my question, but trying to understand the impact of tweaking the trading thresholds required [fiddling](https://i.imgur.com/uFl91hM.png) with a text field and waiting for an animation to play. [Animations](https://fivethirtyeight.com/features/how-to-win-a-trade-war/) are good for introducing a concept, but they start to get frustrating when they block interaction.
+
+Besides disabling the animation, I took a step and a half up the [ladder of abstraction](http://worrydream.com/LadderOfAbstraction/) and showed the entire space of different trading thresholds with a series of [heatmaps](https://i.imgur.com/zPehFto.png). People don't click on buttons as much as we'd like to imagine and mobile is a huge design constraint, but I don't think graphics desks are exploiting the possiblies of the medium when we don't give readers a chance to explore and examine our models without pulling down an IPython Notebook.
+
+Making something like this is more work; the [rough draft](https://blocks.roadtolarissa.com/1wheel/raw/18b49093b0a41888d4ff45281cb66f66/0b4c9ee45c6d625c7fdd48101963cdb70de190fa/) got [banged out](https://i.imgur.com/zNzmoCq.png) in an evening, but all the polishing touches took [more time](https://i.imgur.com/zPehFto.png) to get right and the [code](https://github.com/1wheel/roadtolarissa/blob/master/source/sell-strat/_script.js) ended up pretty ugly (didn't want to prematurally optimize, but dragging the date slider was laggy so I hacked in caching without cleanly rewriting, thinking the finish line was close… it wasn't).
+
+## [The 4096 Paths Into MSI](https://roadtolarissa.com/msi-4096/)
+
+My brother helped me update the [rules for three-way ties](http://esports-assets.s3.amazonaws.com/production/files/rules/MSI-Ruleset-2018-25APR.pdf) after they changed this year. The grid design didn’t change much from the first sketch. To stuff in more at-glance information, I added [bars showing high impact matches](https://imgur.com/oEOvnTc) and a final [small multiples slide](https://imgur.com/Jw4vqTR).
+
+Since this was for my blog I took a [bike ride](https://bertspaan.nl/dutch-farmhouses-of-brooklyn/) yesterday instead of making a mobile version `¯\_(ツ)_/¯`
+
+## [How 2 M.T.A. Decisions Pushed the Subway Into Crisis](https://www.nytimes.com/interactive/2018/05/09/nyregion/subway-crisis-mta-decisions-signals-rules.html)
+
+[Hard to sum this one up...](https://twitter.com/adamrpearce/status/1008340664315236352)
+
+## [Energized Democrats Are Voting in Competitive Primaries in Droves](https://www.nytimes.com/interactive/2018/06/25/us/politics/midterm-primaries-voter-turnout.html)
+
+About 30 seconds after walking back into the office post-paternity leave, Tom grabbed me: "Do you have a minute? We want to look at Democratic primary turnout."
+
+I put my bag down and started pulling party turnout numbers from secretary of state websites. The mechanics of party registration vary state to state, and states that did breakdown turnout by party were slow to post results. So we tried counting voters by just summing votes for Democratic and Republican candidates. House races didn't work for this--lots of seats don't have a primary--but we could compare turnout in states with a governor or senate race in 2014 and 2018. It [looked interesting](https://imgur.com/Ylxufyt), but there wasn't quite enough there to hang a story on.
+
+So we decided to zoom in and compare turnout in house races. My first attempt was a [log-scaled scatter plot](https://imgur.com/0qk98KV) showing how turnout shifted for both parties. Nice and dense! After [annonations](https://imgur.com/XRal9cV) didn't increase readabilty we started to worry it might be too complex. I still think it might have been doable with some [rotation](https://imgur.com/p12xa7D---https://roadtolarissa.com/nba-win-loss/) and quadrant labeling.
+
+Larry suggested trying out a less dense form, so I sketched the [distrubution](https://imgur.com/zp7AoeP) of how turnout shifted for each party in each race. This suggested a simpler metric: instead of trying to show how both parties' turnout changed, just use the change in [partisan vote share](https://imgur.com/y6ratvF). Haeyoun was curious if the Democratic share was up more in competive races, so I made [slope charts](https://imgur.com/NGSnPvr) faceted by the race's Cook rating. Since we didn't have data on a ton of races (the AP only reports vote totals for contested primaries and we needed vote totals for both parties in both years; a surprising number of primaries go uncontested), I switched over to [small multiples slope charts](https://imgur.com/5cj2z2F) which needed even less explanation. To emphasize the direction of the slope even more, we put all the races that increased their Democratic turnout on the left. Pulling the competive races, all of which had increased Democratic vote share, to the top kept the breakdown that Haeyoun wanted and enlarging them created a key.
+
+As we got closer to publication, Alex pointed out that we were missing lots of races in which readers would be interested. I drug my feet, not wanting to go back to dozens of secretary of state websites before realizing that I'd just need to copy/paste a single candidate's votes to get the vote total for each uncontested race, not several candidates as I had when collecting senate turnout. This gave us a ton of races so I shrunk the slope charts down to fit 10 in a column, essentially making the whole thing a [bar chart](https://imgur.com/Fyp5tec).
+
+The design got postpublication pushback: "Readers don't know where or what GA-4 is, you need to offer some human context." There's some truth to this. My reporting on this piece was done with spreadsheets and I didn't have much to add about individual races. I know Ocasio-Cortez won my district, but couldn't tell you my district number. Still, I didn't want to add a section with photos of candidates and details about every single race. That's been done dozens of times already! And turnout shifts in one race can be explained by its particulars; zooming out shows that there's actually a trend. Matthew whipped up some [maps](https://imgur.com/Y1SGZap) with [mapshaper](https://imgur.com/F95ukMB---http://mapshaper.org/) to provide some of that context without overwelming the rest of the piece.
+
+## [LeBron James Is Carrying the Cavaliers in a Historic Way](https://www.nytimes.com/interactive/2018/06/08/sports/basketball/lebron-nba-finals.html)
+
+Missed my chance to make something about the Spurs' 50 win streak, but still got my yearly LeBron chart in. He's pretty good!
+
+The design on the main chart didn't change too much from my [first sketch](https://imgur.com/Ylk9OuM---https://blocks.roadtolarissa.com/1wheel/raw/23837f1a9f5734a3e9e7a694b32a6aa3/). The gap between players each year ends up a little too emphasized with the lines, but the connection really helps recall each year. Plus it looks nice. Kevin suggested a bar chart version with space for all the players' names, but year encoding gets a little messy and including the 0 baseline makes the chart less dramatic.
+
+I added [labels](https://i.imgur.com/pklAgmR.png) for a few players and was thinking about using the little stat cards as a tooltip. Joe suggested laying out the cards by player so you could see their details [without interacting](http://worrydream.com/MagicInk/#interactivity_considered_harmful) (it makes a little bar chart [in print](https://i.imgur.com/jYHrPqF.png)!). Without anything to put in the tooltip, I tried just showing the [name](https://i.imgur.com/ayXUpjr) on hover.
+
+That was super frustrating to use though; it takes so much mousing to read the chart. So I shrunk the circles and printed all the names directly on the chart.
+
+I had planned on making a game-by-game stats share for every finals team, like I did for [total playoff points](https://www.nytimes.com/interactive/2017/05/25/sports/basketball/lebron-career-playoff-points-record.html) last year. The cards used the historic small multiples space, so I put a bigger 2018 game-by-game chart on top. Was originally going to stack them on mobile, but Archie pointed out that you really want to see them side by side so I squeeze them together, dropping the player labels and [reusing the y-axis](https://i.imgur.com/8ol1aZo.png). Wish I could have gotten some annotations in, but couldn't find space. : /
+
+The top still wasn't simple so we put in a 2018 LeBron stat card to introduce the piece.
+
+Also pitched for the 2018 playoffs: a [histogram of histograms.](https://imgur.com/RaNPhXX---https://blocks.roadtolarissa.com/1wheel/raw/e880b577009cf0bc5ca2a0d24c4c01b2/)
+
+## [These 20 Representatives Have Not Had a Primary Challenger for at Least a Decade](https://www.nytimes.com/interactive/2018/06/30/us/elections/representatives-running-unopposed-uncontested-primaries.html)
+
+When Crowley got primaried after not facing a primary opponent for over decade, Troy wondered how unusual it was to have a streak of uncontested primaries. I had House primary data sitting around from the turnout project and whipped up a chart showing how long it had been since each incumbent had been [challenged in a primary](https://imgur.com/tEBGPC4).
+
+Trying to turn the piece around before the news cycle moved on, Troy started writing and I started checking the data. It was way messier than I had hoped. The FEC collects [election results](https://transition.fec.gov/pubrec/electionresults.shtml) from states, but the names and FECIDs aren't 100% consistent between years. We ended up spending a day checking everything.
+
+I had big dreams of [remaking the NFL streak chart](http://www.nytimes.com/newsgraphics/2013/09/28/eli-manning-milestone/index.html---https://imgur.com/oFJhwPR), but the FEC didn't start posting spreadsheets till 2000. So we stuck to current incumbents. Going back farther, the results degrade from [HTML in 1998](https://transition.fec.gov/pubrec/fe1998/sch.htm---https://imgur.com/HDL7OSc) to [PDF in 1994](https://transition.fec.gov/pubrec/fe1994/federalelections94.pdf---https://imgur.com/EeMLOks) to [not proving primary results in 1992](https://transition.fec.gov/pubrec/fe1992/federalelections92.pdf---https://imgur.com/1xyW3fR). DeLauro and Lowey still had active unopposed streaks, so I called their offices to find out when they had their last primary--the person who picked up the phone for Lowey asked around for me and no one knew!
+
+To provide more historical context, I made a [line chart](https://imgur.com/hZjU3JK) that didn't relay on streaks. I wanted to get a little more information in it, so I switched to two stacked area charts showing [the number of candidates](https://imgur.com/IDvwR6K) in each House primary. To keep the piece focused on incumbents, I kept that form but switched to showing [how often they were challenged and how often they won](https://imgur.com/GOQvzXb). If I had seen Boatright's chart showing [competitive challenges earlier](https://imgur.com/h7bHtY0---https://www.washingtonpost.com/news/monkey-cage/wp/2018/06/05/heres-what-weve-learned-from-the-u-s-congressional-primaries-so-far/?utm_term=.c607cbf9096b), I would have added another layer showing the percentage of incumbents facing non-competitive primaries.
-[Elliot Bently](http://ejb.github.io/2017/06/25/trading-bot-sketches.html) made a [trading simulator](https://www.wsj.com/graphics/build-your-own-trading-bot/) for the WSJ last year that came close to answering my question, but getting trying to understand impact of tweaking the trading thresholds required [fiddling](https://i.imgur.com/uFl91hM.png) with a text field and waiting for an animation to play. [Animations](https://fivethirtyeight.com/features/how-to-win-a-trade-war/) are good for introducing a concept, but they start to get frustrating when they block interaction.
+Troy did all the styling and fixes in illustrator, like making time go left to right (whoops). I wish there was more time to report out _why_ incumbents aren't challenged: the [Queens machine](https://www.nytimes.com/2018/06/28/nyregion/joseph-crowley-party-boss-queens.html) and [New York ballot access](http://www.nydailynews.com/new-york/queens/ballot-frustrating-inefficient-article-1.3289020) create some formidable barriers. But between Kennedy retiring and a mass shooting, we had already missed the beat of the news cycle.
-Besides disabling the animation, I took a step and a half up the [ladder of abstraction](http://worrydream.com/LadderOfAbstraction/) and showed the entire space of different trading thresholds with a series of [heatmaps](https://i.imgur.com/zPehFto.png). People don't click on buttons as much as we'd like to image and mobile is a huge design constraint, but I don't think graphics desks are exploiting the possiblies of the medium when we don't give readers a chance to explore and examine our models without pulling down an IPython Notebook.
+## [DeMarcus Cousins Gives the Warriors a Fifth All-Star](https://www.nytimes.com/2018/07/02/sports/demarcus-cousins-warriors.html)
-Making something like this is more work; the [rough draft](https://bl.ocks.org/1wheel/raw/18b49093b0a41888d4ff45281cb66f66/0b4c9ee45c6d625c7fdd48101963cdb70de190fa/) got [banged out](https://i.imgur.com/zNzmoCq.png) in a evening, but all the polishing touches took [more time](https://i.imgur.com/zPehFto.png) to get right and the [code](https://github.com/1wheel/roadtolarissa/blob/master/source/sell-strat/_script.js) ended up pretty ugly (didn't want to prematurally optimize, but dragging the date slider was laggy so I hacked in caching without cleanly rewriting thinking the finish line was close… it wasn't).
+I [tweeted](https://imgur.com/9GOPDkW) this out after the news broke. Getting it inside of our [CMS](https://imgur.com/Caisl1H) took longer than making the chart! And I think it looks worse; taking off the monospace makes the columns less bar-like (typography is an object) and requiring the title on top stopped it from directly labeling the x-axis.
+A reddit user suggested that I learn a data vis tool besides d3:
+> You could have made this in Microsoft Paint. Why go through the additional effort.
-TK TK animation gifs. rough draft chart
-exploiting sentence needs work
+## [Mapping Florence’s Impact](https://www.nytimes.com/interactive/2018/09/13/us/hurricane-florence-impact-damage-map.html)
+Sure, the [Post](https://twitter.com/driven_by_data/status/1039698579466670082) had the best hurricane tracker maps. But they use my [tutorial](https://roadtolarissa.com/hurricane) to make [one of them](https://imgur.com/uEOCMez)!
+
+With the data file getting bigger and bigger during the storm, the Post reduced the temporal resoultion of their animation. I didn’t. Keeping the data hourly really shows the movement of the storm. And if loading a 10 MB file on the page was a bad idea, why is there a 50 MB video ad a little farther down? (On mobile, where bandwidth matters more, I decreased the spatial resolution).
+
+## [See Flood Waters Rise Across the Carolinas After Hurricane Florence](https://www.nytimes.com/interactive/2018/09/18/us/hurricane-florence-flooding.html)
+
+While sticking the rainfall map at the bottom, I noticed I was having a hard time [parsing](https://imgur.com/0zHzrwl) the height of the bars when they stacked on top of each other. I added a [gradient and a little curve](https://imgur.com/KAK41t0) so the color and angle of the curve would also encode the flooding height. Also they looked kind of like rain or water drops!
+
+I’m not sure why we stuck with the bars; it got rushed to publication before we got a chance to hash it out.
+
+## [Live Polling](https://www.nytimes.com/interactive/2018/upshot/elections-polls.html)
+
+My favorite chart from this project was for an internal dashboard. Call centers don’t usually provide real time results of polls; the best we could get them to do was 15 minute dumps of all the calls they had done that night, along with the start time of the call.
+
+The timeseries and call stream animation assumed they recived the calls in order of start time; when they started showing on the front end unordered they caused lots of hard to track down bugs. I thought there was an error with our data processing, but by [charting](https://imgur.com/NWM3UoP) the call center timestamp against the upload time found that high call volumes led to a [bottle neck](https://imgur.com/GIXN8eC). We ended up randomly distributing the new calls we recived over the next 15 minutes—not as magical as seeing them show up as they happened or exactly replayed, but the best we could do.
+
+ I didn’t end up watching too many polls come in as they happend. I really wanted to make the stream animation a little slicker and less laggy, but got [bogged down](https://twitter.com/Rich_Harris/status/1037903141960867840) coming up with awful hacks to cram our sleek 100kb svelte app inside of the NYT’s react app. Kids, always make sure everyone is on board with your publishing pipeline *before* you start working.
+
+## [2018 Worlds Group Advancement](https://roadtolarissa.com/worlds-group-2018/)
+
+Didn't think I would have time this year, but the [fan art](https://www.reddit.com/r/leagueoflegends/comments/9nxhmw/worlds_simulation_site/---https://imgur.com/r6RMB4f) inspired me.
+
+## [Live Forecast: Who Will Win the House?](https://www.nytimes.com/interactive/2018/11/06/us/elections/results-house-forecast.html)
+
+I tried lots of ideas for showing our model's margin of uncertainty for house races. A [lava lamp](https://blocks.roadtolarissa.com/1wheel/raw/37344ee99e7d23dee2122bdd08c84d92/---https://roadtolarissa.com/imgur-down/lava-lamp.gif), a [bouncing histogram](https://blocks.roadtolarissa.com/1wheel/raw/c806ed704adee9ec82e580dff7763388/---https://roadtolarissa.com/imgur-down/bouncing-histogram.gif), a [grid of needles](https://blocks.roadtolarissa.com/1wheel/3d13f6f7399ce3458984ca031081be7e---https://roadtolarissa.com/imgur-down/dial-grid.gif), a grid of [every house race](https://blocks.roadtolarissa.com/1wheel/raw/c8d5a69a194de0ff69192f7951b3d514/---https://roadtolarissa.com/imgur-down/house-0.png)
+
+To clearly show the balance of power, I [stacked](https://roadtolarissa.com/imgur-down/house-1.png) races each party was favored to win. This was a little tall, so I squeezed each house race down to a [single vertical pixel](https://roadtolarissa.com/imgur-down/house-4.png) and drew their range of possible outcomes. Too dense; with the lines adjacent it wasn't clear they represented individual seats. And the closest races were stuck in the muddy middle of the chart.
+
+Looking to create space between the lines without increasing the height of the chart, I layed the races out in an [arc](https://blocks.roadtolarissa.com/1wheel/raw/692e7bb028b822a74a5517daf8d946c5/---https://roadtolarissa.com/imgur-down/space-arc.png). This also pulled the closest races to the top of the chart, encoded the balance of power with the angle of the lines and also kinda looked like the needle at the top of the page. I thought it was great, but there were too many bewildered looks internally and we cut it.
+
+## [Republicans Dominate State Politics. But Democrats Made a Dent This Year.](https://www.nytimes.com/interactive/2018/11/10/upshot/republicans-dominate-state-politics-but-democrats-made-a-dent.html)
+
+Last spring I took a look at state and local [election results](https://i.imgur.com/LYxA4bF.png), wondering if more Republican state legislators would lead to more [pre-emption](https://www.nytimes.com/2017/07/06/upshot/blue-cities-want-to-make-their-own-rules-red-states-wont-let-them.html), The National Conference of State Legislatures tracks the number of legislators over time, so I tried [plotting all of them](https://imgur.com/1Kqyuvj) (a [line chart](https://imgur.com/SqDAfKI) is probably a better way to show this information).
+
+The raw number of representives also isn't that meaningful (New Hampshire's lower chamber has [400 members](https://imgur.com/7SSSmWa)!), so I looked at control of upper and lower chambers in each state over the last hundred years with a [cartogram](https://imgur.com/s1Egu2U). National trends are hard to pick out with this form; state boxes are only 70 pixels wide so each election is only a pixel wide.
+
+To pull those trends out, I made a [stacked "area" chart](https://imgur.com/X4azqdJ) out of the state's intitals. Changes in control are highlighted and the states with split chambers are vertically centered so the outline of the chart shows changes in control. I was happy with this form--it'd make a great poster!--but didn't have a story to attach it to so it sat untouched till Bui and Emily started working on a post-midterms state legislative piece.
+
+Bui built similar charts for governors and overall state control, then dropped the [baseline](https://imgur.com/NnIwauh) to make them denser. I thought the shape of the outlines looked nice, but with three catorgies it is totally unnessary. After publishing, Kevin pointed the Times had previously published [both](https://imgur.com/HSLBNSx) [types](https://imgur.com/8joPL2f).
+
+## [See How Close the Results Are in Arizona, Georgia and Florida](https://www.nytimes.com/interactive/2018/11/10/us/elections/2018-possible-midterm-recounts-georgia-florida-arizona.html)
+
+Troy did a [mockup](https://imgur.com/UtXrZ5T) with fun lines. When I hooked up the [real data](https://imgur.com/u95Wsba) and dropped the election night oscillations it wasn’t quite as interesting.
+
+We tried using [yellow](https://imgur.com/ULOkNHe) to highlight recount zones, but it made the chart really noisy. Archie suggested cross hatching the zone and emphasizing the date ticks with a black background. And once we were closer to publishing, the real data was [more exciting](https://imgur.com/XY3O9Xg)!
+
+I knew this would be the last breaking news thing I’d work on so I tried to get the little touches right, sticking in a [hover+opacity](https://www.nytimes.com/interactive/2016/upshot/presidential-polls-forecast.html---https://imgur.com/NmGA7MO) effect lifted from Gregor.
+
+## [7 Train Signal Upgrades Complete After Years of Delays. Up Next: The Rest of the Subway.](https://roadtolarissa.com/flushing-cbtc-finished/)
+
+I moved to Sunnyside in late 2016, shortly before work was supposed to be finishing up on the 7 train's signal modernizations. Work was just completed yesterday. I was curious what caused the delay and also will take any excuse to duel encode time.
+
+Hoping to do more train charts, but getting people to answer your questions is a lot harder when you can’t say “I’m calling from the New York Times.”
+
+
+
+
-
-
-
+
+
diff --git a/source/_posts/2018-10-13-worlds-group.md b/source/_posts/2018-10-13-worlds-group.md
new file mode 100644
index 00000000..47925a92
--- /dev/null
+++ b/source/_posts/2018-10-13-worlds-group.md
@@ -0,0 +1,36 @@
+---
+template: post.html
+title: 2018 Worlds Group Advancement
+date: 2018-10-13
+permalink: /worlds-group-2018
+shareimg: http://roadtolarissa.com/images/posts/worlds-group-2018.png
+---
+
+The second half of League of Legends' World Group Stage starts tomorrow morning! Each team will play the other three teams in their group once more. The best two teams in each group advance to the quarterfinals.
+
+The charts below show how each team could advance. With six games left in each group, there are 2^6 = 64 ways for group play to end. Each of these 64 outcomes is represented by a circle. Green circles show ways a team could advance and red circles show elimination scenarios. Yellow circles indicate scenarios with a tiebreaker match.
+
+With rough 1-2 starts, all three North American teams need at least two wins to advance.
+
+[NYC case data](https://github.com/nychealth/coronavirus-data/blob/master/tests.csv) // [chart code](https://github.com/1wheel/roadtolarissa/blob/master/source/regression-discontinuity/script.js) + +
The chart from the paper has been lightly edited for clarity. + +
The top line 66,000 number comes from a similarly suspect regression on cumulative cases. The discontinuous regression was more interesting to illustrate and the results are in the same ballpark. + + +
[538 2019-20 NBA Predictions](https://projects.fivethirtyeight.com/2020-nba-predictions) // [Chart Code](https://github.com/1wheel/roadtolarissa/blob/master/source/playoff-probabilities/script.js) +
Only 5,000 scenarios are shown on the scatter plots; the scenarios are a snapshot from 2020-10-25 and not updated (looking at the correlations over time might be interesting though!). The rendered electoral college scenarios ignore the possibility of `NE` or `ME` spliting their votes. + +
The correlations matrix orders states by clustering on 538's correlations. Sorting using the Economist correlations [splits up](https://i.imgur.com/JH9FC8I.png) the negative 538 correlations. + +
chart code + +
scraping code // chart code + +
[Inflation adjusted](https://help.imdb.com/article/imdbpro/industry-research/box-office-mojo-by-imdbpro-faq/GCWTV4MQKGWRAUAP?ref_=mojo_cso_md#inflation) data [scraped](https://github.com/1wheel/scraping-2018/tree/master/box-office-mojo) from Box Office Mojo // [chart code](https://github.com/1wheel/roadtolarissa/tree/master/source/box-office-hits) + +
[scraping code](https://github.com/1wheel/scraping-2018/tree/master/2022-wp) // [chart code](https://github.com/1wheel/roadtolarissa/tree/master/source/live-forecast-2022) +
[scraping code](https://github.com/1wheel/scraping-2018/tree/master/2024-wp) // [chart code](https://github.com/1wheel/roadtolarissa/tree/master/source/live-forecast-2024) +
[Data from NOAA](https://www.ncei.noaa.gov/cdo-web/) // [chart code](https://github.com/1wheel/roadtolarissa/tree/master/source/central-park-rain) +
[scraping code](https://github.com/1wheel/scraping-2018/tree/master/2024-advent-of-code) // [chart code](https://github.com/1wheel/roadtolarissa/tree/master/source/advent-of-code) +
Over 3,000 people have joined the Data Visualization Society. The glyphs here represent their self reported skill levels at different aspects of charting. + +
The data released by DVS lists city and submission time, but doesn't include the raw responses to the nine skill questions on the survey. To protect respondents' privacy, the questions were combined into three categories—data, visualization and society—and averaged together. `, + +`
Even with that dimensionality reduction, it's still hard to pick out patterns in the data. + +
We can simplify more by reducing the granularity of the data. Instead of trying to show every skill at its exact level, we can bucket them as low, medium or high. + +
We can see more already! Medium in all three categories is the modal choice. +`, + +` +
Grouping glyphs with the same bucketed skills removes noise from the chart, making it easier to find little insights. + +
It looks like high society skills are less common than data or visualization skills, for example. +`, + +`
This method of grouping is flexible. I've added back some granularity, using six buckets for each skill to match the original 0-5 scale. All 0s are way more common than straight 5s. + +
In the biggest groups all the skills are within a point of each other. More variance isn't as common; I think there's a high data / visualization and low society group with just me in it! + +
In total, there are 28 groups here with just one person in them. +`, + +`
Adding back even more granularity—remember each skill slice represents the average of three questions, so fractional values are possible—there are about 600 people who have a unique combination of averaged skills. +`, + +`
In addition to the redacted survey data, DVS also created PNG and SVG badges visualizing every member's response to the nine questions. Here's a bit of one: + +
By extracting the nine raw responses from the SVGs, I was able to link them to 600 people’s submission times and locations by calculating the skill category averages. + +
This linked data was intentionally not released. + +`, + +`
Significantly more detailed information about the visualization community has been published before, so the impact of this inadvertent leakage of survey data is quite low. But it does point to the difficulties of releasing data on the internet. + +
I'm conflicted about this. Two of my favorite NYT pieces required detailed, administrative data about sensitive topics. How can we use data to understand the world if the most important and interesting data is impossible to share? + +
One common solution, k-anonymity, selectively reduces granularity to guarantee that there'll always be several people in any given grouping. This gets tricky with higher dimensional data. + +
The state-of-the-art differential privacy uses random noise and cryptographic math to construct summary statistics that don’t reveal any single individual's response. I'm not aware of an easy way to use it though. + +
In this instance, the much maligned "security through obscurity" would have been sufficient. If the badges were only released as PNGs I definitely wouldn't have taken the time to parse them. + +
+` + +] + + +var slideSel = d3.select('#slides').html('') + .appendMany('div.slide', slides) + .append('div').html(d => d) + +gs = d3.graphScroll() + .eventId('lol-scroll') + .container(d3.select('#container')) + .sections(slideSel) + .offset(innerHeight - 100) + + +var c = d3.conventions({ + sel: d3.select('html').selectAppend('div#graph').html(''), + layers: 'ds', + margin: {left: innerWidth < 500 ? 10 : 20, top: 10, right: 10, bottom: 10} +}) + + +if (window.data){ + init() +} else { + // d3.loadData('https://roadtolarissa.com/data/dvs/membership.json', (err, res) => { + // data = res[0] + // init() + // }) + d3.loadData('membership.json', (err, res) => { + data = res[0] + init() + }) +} + +function init(){ + data = data//.slice(0, 100) + + data.forEach((d, i) => { + d.groups = [ + {d, type: 'data', val: d.data/5}, + {d, type: 'visualization', val: d.visualization/5}, + {d, type: 'society', val: d.society/5}, + ] + + d.groups.forEach(d => { + d.val2 = Math.round(d.val*2)/2 + d.val6 = Math.round(d.val*5)/5 + d.val9 = d.val + }) + + d.val2Key = d.groups.map(d => d.val2).join(' ') + d.val6Key = d.groups.map(d => d.val6).join(' ') + d.val9Key = d.groups.map(d => d.val9).join(' ') + }) + + data = _.sortBy(data, d => d3.sum(d.groups, d => d.val2)) + data = _.sortBy(data, d => d.val2Key) + byVal2 = d3.nestBy(data, d => d.val2Key) + byVal6 = d3.nestBy(data, d => d.val6Key) + byVal9 = d3.nestBy(data, d => d.val9Key) + .filter(d => d.length == 1 && d[0].match) + .map(d => d[0]) + + var s = Math.sqrt(c.width*c.height/data.length) + var nCols = Math.ceil(c.width/s) + var r = s/2 - 1*0 + data.forEach((d, i) => { + d.flatPos = [s*(i % nCols), s*(Math.floor(i/nCols))] + d.i = i + }) + + var s9 = Math.sqrt(c.width*c.height/byVal9.length) + var nCols = Math.floor(c.width/s9) + var r9 = s9/2 - 1*0 + byVal9.forEach((d, i) => { + d.pos9 = [s9*(i % nCols + .3), s9*(.5 + Math.floor(i/nCols))] + d.i9 = i + }) + _.shuffle(byVal9).forEach((d, i) => { + d.ir = i + }) + + + var rScale = d3.scaleSqrt().range([1, r]) + var rScale = d3.scaleLinear().range([0, r]) + var rScale9 = d3.scaleLinear().range([0, r9]) + + var arc = d3.arc() + .outerRadius(d => rScale(d.data.val)) + .innerRadius(0) + + var pie = d3.pie() + .sort(null) + .value(d => 1) + + layer0Sel = c.svg.append('g.layer0') + layer2Sel = c.svg.append('g.layer2') + layer6Sel = c.svg.append('g.layer6') + layer9Sel = c.svg.append('g.layer9') + + + // first two slides + glphySel0 = layer0Sel.appendMany('g', data) + .translate(d => d.flatPos) + .call(d3.attachTooltip) + + glphySel0.append('circle') + .at({ + r, + stroke: '#ddd', + fill: 'none', + strokeWidth: .5, + }) + + var sliceSel0 = glphySel0.appendMany('path', d => pie(d.groups)) + .at({ + d: arc, + fill: (d, i) => colors[i] + }) + + + + + function runSim(array, key, numTicks){ + array.forEach(combined => { + combined.forEach(d => { + d[key] = combined + }) + + combined.vals = combined.key.split(' ').map(d => d) + combined.groups = combined.vals.map(d => d*combined.length) + combined.r = rScale1(combined.length) + + combined.mean = d3.mean(combined.vals) + + combined.count = combined.length + }) + + array = _.sortBy(array, d => d.length).reverse() + + var total = 0 + array.slice().reverse().forEach((d, i) => { + total += d.length + d.total = total + }) + + c.y.domain([1, 0]) + c.x.domain(d3.extent(array, d => d.length)) + c.x.domain([0, data.length]) + + // var sim1 = d3.forceSimulation(byVal2) + // .force('x', d3.forceX(c.width / 2).strength(.1)) + // .force('x', d3.forceX(d => c.x(d.variance)).strength(.1)) + // .force('x', d3.forceX(d => c.x(d.length)).strength(.1)) + // .force('y', d3.forceY(c.height / 2).strength(1)) + // .force('collide', d3.forceCollide(d => d.r + 2).strength(1.5)) + // .stop() + + if (key == 'combined9'){ + array.forEach(d => { + if (d.length > 1) return + + d.x = Math.random()*c.width + d.y = Math.random()*c.height + }) + array = array.filter(d => d.length > 1) + } + + var xForce = key == 'combined2' ? + d3.forceX(c.width / 2).strength(.05) : + d3.forceX(d => c.x(d.total)).strength(.3) + + var yForce = d3.forceY(d => c.y(d.mean)).strength(.5) + + if (key == '2to6-transition'){ + xForce = d3.forceX(d => d[0].combined2.x).strength(1) + yForce = d3.forceY(d => d[0].combined2.y).strength(1) + } + + var sim = d3.forceSimulation(array) + .force('x', xForce) + .force('y', yForce) + .force('collide', d3.forceCollide(d => d.r + 2).strength(1.5)) + .force('container', forceContainer([[0, 0],[c.width, c.height]]).strength(1.5)) + .stop() + + for (var i = 0; i < numTicks; ++i){ + sim.tick() + array.forEach(d => { + if (i % 10 != 9) return + d.x = d3.clamp(d.r*.5, d.x, c.width - d.r*.5) + d.y = d3.clamp(d.r*.5, d.y, c.height - d.r*.5) + }) + } + + } + + + + + rScale1 = d3.scaleSqrt() + .domain([0, 100]) + .range([1, r*8]) + + function randCirclePos(){ + var r0 = 1 + var r1 = 1 + + while (r0*r0 + r1*r1 > 1){ + r0 = Math.random()*2 - 1 + r1 = Math.random()*2 - 1 + } + + return [r0, r1] + } + + function randCircleBorder(){ + var θ = Math.random()*Math.PI*2 + + return [Math.cos(θ), Math.sin(θ)] + } + + function phyllotaxis(i) { + var radius = r*Math.sqrt(i)*.6 + var θ = Math.PI*(3 - Math.sqrt(5))*i + return [radius*Math.cos(θ), radius*Math.sin(θ)] + } + + // third slide + runSim(byVal2, 'combined2', 200) + + // calc 0 -> 2 transition + // data.forEach(d => { + // var c = d.combined2 + + // var [r0, r1] = randCirclePos() + // d.pos2 = [r0*(c.r - r) + c.x, r1*(c.r - r) + c.y] + // }) + + byVal2.forEach(c => { + c.forEach((d, i) => { + var [x, y] = phyllotaxis(i) + d.pos2 = [x + c.x, y + c.y] + }) + }) + + _.sortBy(byVal2, d => d[0].i).forEach((d, i) => { + d.animationIndex = i + }) + + + + + glphySel2 = layer2Sel.appendMany('g', byVal2) + .translate(d => [d.x, d.y]) + .call(d3.attachTooltip) + + glphySel2.append('circle.combined') + .at({r: d => d.r}) + // .st({stroke: d => d.count == 1 && d[0].match ? 'red' : ''}) + + glphySel2.appendMany('path', d => pie(d.groups)) + .at({ + d: arc.outerRadius(d => rScale1(d.data)), + fill: (d, i) => colors[i] + }) + + + // fourth slide + runSim(byVal6, 'combined6', 300) + + byVal6.forEach(d => d.pos = [d.x, d.y]) + _.sortBy(byVal6, d => d.x).forEach((d, i) => d.animationIndex = i) + + // calc 2 -> 6 transition + d3.nestBy(byVal6, d => d[0].combined2).forEach(c2 =>{ + var sorted = _.sortBy(c2, d => -d.length) + sorted[0].is2to6Max = true + + var c = c2[0][0].combined2 + sorted.forEach((d, i) => { + var θ = Math.PI*2*i/(c2.length - 1) + + var [r0, r1] = [Math.cos(θ), Math.sin(θ)] + d.pos2 = [r0*.8*(c.r - d.r) + c.x, r1*.8*(c.r - d.r) + c.y] + + if (d.is2to6Max) d.pos2 = [c.x, c.y] + }) + }) + + + glphySel6 = layer6Sel.appendMany('g', byVal6) + .translate(d => d.pos2) + .call(d3.attachTooltip) + + glphySel6.append('circle.combined') + .at({r: d => d.r}) + .st({stroke: d => d.count == 1 && d[0].match ? 'red' : ''}) + .filter(d => d.count == 1) + .st({stroke: '#000', strokeWidth: 1.5}) + + glphySel6.appendMany('path', d => pie(d.groups)) + .at({ + d: arc.outerRadius(d => rScale1(d.data)), + fill: (d, i) => colors[i] + }) + + + + // calc 6 -> 9 transition + d3.nestBy(byVal9, d => d.val6Key).forEach(c6 =>{ + var sorted = _.sortBy(c6, d => -d.length) + sorted[0].is6to9Max = true + + var c = c6[0].combined6 + sorted.forEach((d, i) => { + var θ = Math.PI*2*i/(c6.length - 1) + + var [r0, r1] = [Math.cos(θ), Math.sin(θ)] + d.pos6to9 = [r0*.8*(c.r - r) + c.x, r1*.8*(c.r - r) + c.y] + // throw 'up' + if (d.is6to9Max) d.pos6to9 = [c.x, c.y] + }) + }) + + + // last two slides + glphySel9 = layer9Sel.appendMany('g', byVal9) + .translate(d => d.pos6to9) + .call(d3.attachTooltip) + + var circleSel9 = glphySel9.append('circle.combined') + .at({r}) + .st({strokeWidth: .5}) + + byVal9.forEach(d => { + d.groups9 = [] + + d.match.triangles.forEach(tri => { + var vals = tri.vals.map(d => d/5) + var mean = d3.mean(vals) + + vals.forEach(val => { + d.groups9.push({d, val, mean}) + }) + }) + }) + + var sliceSel9 = glphySel9.appendMany('path', d => pie(d.groups9)) + .at({ + d: arc.outerRadius(d => rScale(d.data.mean)), + fill: (d, i) => colors[Math.floor(i/3)], + stroke: '#fff', + strokeWidth: .1 + }) + + var locTimeSel = layer9Sel.append('g') + + + + + + + + + + var prevI = 4 + onScroll(0) + // onScroll(5) + + function onScroll(i){ + var isNormal = i - prevI == 1 + + console.log({i, prevI, isNormal}) + + if (i == 0){ + + sliceSel0 + .transition().duration(0) + .at({d: arc.outerRadius(d => rScale(d.data.val))}) + } + if (i == 1){ + var l = byVal2.length + sliceSel0 + .transition() + .duration(5000/l) + .delay(d => d.data.d.combined2.animationIndex/l*5000) + .at({d: arc.outerRadius(d => rScale(d.data.val2))}) + + // sliceSel0 + // .at({d: arc.outerRadius(d => rScale(d.data.val2))}) + } + + if (isNormal){ + if (i == 2){ + // var l = data.length + // glphySel0 + // .transition().duration(0).delay((d, i) => i/l*5000) + // .translate(d => d.pos2) + var l = byVal2.length + glphySel0 + .transition() + .duration(5000/l) + .delay(d => d.combined2.animationIndex/l*5000) + .translate(d => d.pos2) + + layer0Sel.transition().duration(1000).delay(5000) + .st({opacity: 0}) + + layer2Sel.transition().duration(1000).delay(5000) + .st({opacity: 1}) + } + + if (i == 3){ + layer2Sel.transition().duration(500) + .st({opacity: 0}) + + layer6Sel.transition().duration(500) + .st({opacity: 1}) + + var l = byVal2.length + glphySel6 + .transition() + .duration(500) + .delay(d => d.animationIndex/l*200 + 1000) + .translate(d => d.pos) + } + + if (i == 4){ + layer6Sel.transition().duration(500) + .st({opacity: 0}) + + layer9Sel.transition().duration(500) + .st({opacity: 1}) + + var l = byVal6.length + glphySel9 + .transition() + .duration(500) + .delay((d, i) => i/l*500 + 1000) + .translate(d => d.pos9) + } + if (i == 5){ + sliceSel9.transition().duration(150).delay(d => d.data.d.ir*300) + .at({d: arc.outerRadius(d => rScale9(d.data.mean))}) + .transition().delay(200).duration(700) + .at({d: arc.outerRadius(d => rScale9(d.data.val))}) + + circleSel9.transition().duration(150).delay(d => d.ir*300) + .at({r: r9}) + .on('start', d => { + var isShowing = d.ir % 3 == 0 || true + var sel = locTimeSel.append('g.loctime') + .translate([ + d.pos9[0] - r9, + d.pos9[1] + (isShowing ? r9 + 8 : -r9 - 14) + ]) + .st({fontSize: 10, fontFamily: 'monospace'}) + + sel.transition().duration(isShowing ? 3000 : 0) + .st({opacity: 0}) + .remove() + + + sel.append('text').at({y: 12}) + // .at({textAnchor: 'middle'}) + // .text([d.lat, d.long].map(Math.round).map(d3.format('02')).join(', ')) + .text([d.lat, d.long].map(d3.format('04.1f'))) + // .text([d.lat, d.long].map(d => d3.format('05.1f')(d))) + // .join(', ')) + + sel.append('text') + // .at({textAnchor: 'middle'}) + .text(d.date_with_hour.replace('/2019', '') + (+d.hour < 12 ? 'AM' : 'PM')) + .text(d.date_with_hour.replace('/2019', '') + ':00') + + }) + + } + + } else { + glphySel0.transition().duration(0) + .translate(d => d.flatPos) + glphySel6.transition().duration(0) + .translate(d => i < 3 ? d.pos2 : d.pos) + glphySel9.transition().duration(0) + .translate(d => i < 4 ? d.pos6to9 : d.pos9) + + layer0Sel.transition().duration(0) + .st({opacity: i < 2 ? 1 : 0}) + layer2Sel.transition().duration(0) + .st({opacity: i == 2 ? 1 : 0}) + layer6Sel.transition().duration(0) + .st({opacity: i == 3 ? 1 : 0}) + layer9Sel.transition().duration(0) + .st({opacity: i > 3 ? 1 : 0}) + + if (i < 5){ + sliceSel9.transition().duration(0) + .at({d: arc.outerRadius(d => rScale(d.data.mean))}) + + circleSel9.transition().duration(0) + .at({r}) + } + } + + layer0Sel.st({pointerEvents: i < 2 ? 'all' : 'none'}) + layer2Sel.st({pointerEvents: i == 2 ? 'all' : 'none'}) + layer6Sel.st({pointerEvents: i == 3 ? 'all' : 'none'}) + layer9Sel.st({pointerEvents: i == 4 ? 'all' : 'none'}) + + prevI = i + } + + gs.on('active', onScroll) + +} + + + + + + + + + +function forceContainer (bbox){ + var nodes, strength = 1;; + + if (!bbox || bbox.length < 2) bbox = [[0, 0], [100, 100]] + + + function force(alpha) { + var i, + n = nodes.length, + node, + x = 0, + y = 0; + + for (i = 0; i < n; ++i) { + node = nodes[i], x = node.x, y = node.y, r = node.r; + + if (x - r < bbox[0][0]) node.vx += (bbox[0][0] - x + r)*alpha*strength + if (y - r < bbox[0][1]) node.vy += (bbox[0][1] - y + r)*alpha*strength + if (x + r > bbox[1][0]) node.vx += (bbox[1][0] - x - r)*alpha*strength + if (y + r > bbox[1][1]) node.vy += (bbox[1][1] - y - r)*alpha*strength + } + } + + force.initialize = function(_){ + nodes = _; + }; + + force.bbox = function(_){ + return arguments.length ? (bbox = +_, force) : bbox; + }; + force.strength = function(_){ + return arguments.length ? (strength = +_, force) : strength; + } + + return force; +} + + + + + + diff --git a/source/dvs-privacy/style.css b/source/dvs-privacy/style.css new file mode 100644 index 00000000..3294fb37 --- /dev/null +++ b/source/dvs-privacy/style.css @@ -0,0 +1,131 @@ +html{ +} + +body{ + margin: 0px auto; + /*pointer-events: none;*/ +} + +#container{ + margin: 0px auto; + margin-top: 30px; + position: relative; + min-height: 4000px; + /*pointer-events: none;*/ +} + +.slide{ + margin-bottom: 75vh; + background: rgba(255,255,255, .95); + padding: 15px; + padding-top: 1px; + padding-bottom: 1px; + max-width: 700px; + /*opacity: 0;*/ +} + +.slide:last-child{ + margin-bottom: 30vh; +} + +.text-d { + background: #DDB32B; +} +.text-v { + background: #2DB2A5; +} +.text-s { + background: #A05E9C; +} +.text-d, .text-v, .text-s{ + padding-left: 2px; + padding-right: 2px; + color: #fff; + border-radius: 2px; + font-weight: 500; +} + + + +#graph{ + height: 100vh; + width: 100vw; + position: fixed !important; + z-index: -10; + top: 0px; + left: 0px; +} + + +circle.combined{ + stroke: #aaa; + fill: #f5f5f5; + stroke-width: .5px; +} + + +.header > span{ + /*display: none;*/ + text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; + +} + +h1{ + font-size: 45px; + margin-top: 5px; + /*-webkit-text-fill-color: white; */ + -webkit-text-stroke-width: 1px; + -webkit-text-stroke-color: white; + text-shadow: 0 2px 0 #fff, 2px 0 0 #fff, 0 -2px 0 #fff, -2px 0 0 #fff; +} + + +svg{ + overflow: visible; +} + + + +text{ + pointer-events: none; + text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; +} + + + +.tooltip { + top: -1000px; + position: fixed; + padding: 10px; + background: rgba(255, 255, 255, .90); + border: 1px solid lightgray; + pointer-events: none; + display: none; +} +.tooltip-hidden{ + opacity: 0; + transition: all .3s; + transition-delay: .1s; +} + +@media (max-width: 590px){ + div.tooltip{ + bottom: -1px; + width: calc(100%); + left: -1px !important; + right: -1px !important; + top: auto !important; + width: auto !important; + } +} + + + +#circle-icon{ + width: 12px; + height: 12px; + border: 1.5px solid #000; + display: inline-block; + border-radius: 12px; +} + diff --git a/source/dvs-privacy/test.html b/source/dvs-privacy/test.html new file mode 100644 index 00000000..b5c6d0cc --- /dev/null +++ b/source/dvs-privacy/test.html @@ -0,0 +1,15 @@ + + + + + + +