Skip to content

Instantly share code, notes, and snippets.

@mwunsch

mwunsch/.block Secret

Last active January 11, 2017 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mwunsch/f041519e6c2795f5419d09771dd14da2 to your computer and use it in GitHub Desktop.
Save mwunsch/f041519e6c2795f5419d09771dd14da2 to your computer and use it in GitHub Desktop.
Tinyletter Metrics
license: bsd-3-clause

This column graph displays the subscriber counts and open rates for my Tinyletter, This Week's Program. Each bar represents a letter I've published and the color of the bar is derived from the rate of unique opens each letter has received.

My Tinyletter is a weekly summary of the code I've written over the course of the week. I've grown the subscriber count entirely through shameless self-promotion.

The metrics are gathered with the tinystats command-line utility. I use the brilliant csvkit to choose just the columns I'm most interested in.

This is my first project with D3.

id sent_at send_count stats.unique_opens subject
3104105 1483721125 100 58 The Programs of the First Week of 2017
3085461 1483115589 100 48 The Programs of the Last Week of 2016
3073541 1482522869 101 50 The Programs of the Week of Christmas & Hanukkah
3057393 1481939489 102 62 The Programs of the Week of a Polar Vortex
3038501 1481302890 102 65 The Programs of the Week of Ludum Dare 37
3020693 1480708738 98 50 The Programs of the Week of Cyber Monday
3001873 1480102002 98 51 The Programs of Thanksgiving Week
2984545 1479493142 96 54 The Programs of the Week of a Supermoon
2963117 1478879916 96 55 This Week's Program
2945493 1478278892 97 45 The Programs of the Week of Halloween
2926493 1477666937 98 60 The Programs of the Week of the Hearthstone World Championship
2905685 1477084583 100 55 The Programs of the Week We Were Kept in Suspense
2887537 1476467017 100 57 The Programs of the Week the Shackles Have Been Taken Off
2863553 1475857153 96 57 The Programs of the Week of the Anniversary of this Tinyletter
2829473 1475266825 97 52 The Programs of the Week of the First Presidential Debate
2804421 1474643403 93 54 The Programs of the Week of the Autumnal Equinox
2770777 1474072534 92 56 The Programs of the Week After XOXO
2748861 1473474033 91 50 The Programs of the Week of XOXO
2727229 1472827465 91 50 The Programs of the First Week of September
2710105 1472236326 93 54 The Programs of the Week of My Birthday
2693537 1471626107 90 55 The Programs of the Week I Started Something New
2678353 1471024665 86 44 The Programs of the Week After Launch
2661737 1470405373 85 58 The Programs of the Week @sonic_sketches Launched
2646457 1469814185 77 41 The Programs of the Week a Woman Was Nominated for President
2629721 1469199923 77 38 The Programs of the Week We Were Covered in a Heat Dome
2614857 1468598067 76 38 The Programs of the Week We Caught Pokemon
2598869 1467990364 77 38 The Programs of the Week of America's Birthday
2583629 1467394239 77 50 The Programs of the Week I Spent in the Cloud
2566345 1466776359 76 44 The Programs of the Week I Broke My Streak
2550257 1466176138 75 44 The Programs of a Year of Deliberate Practice
2532961 1465570105 73 39 The Programs of a Week in June
2514673 1464961734 75 43 The Programs of the Week of My Wedding Anniversary
2498273 1464376373 75 43 The Programs Leading to a Three-Day Weekend
2479837 1463754889 74 45 The Programs of My Second Week at Harry's
2462489 1463163381 75 40 The Programs of the Week I Started a New Job
2443397 1462545085 70 44 Job Transition Week 2
2425817 1461967106 70 51 Job Transition Week 1
2405953 1461333394 70 40 The Programs of my Last Week at Rent the Runway
2389217 1460746981 70 37 The Programs of the Week the Taxman Cometh
2370397 1460129504 64 36 The Programs of the Week the Panama Papers Were Leaked
2352053 1459531488 65 33 The Programs of the Week the Internet Gets Real Unfunny
2332965 1458917200 66 31 The Programs of the Week of Purim
2312885 1458315041 66 31 The Programs of the Week the Clocks Rolled Forward
2293509 1457710121 66 40 The Programs of the Week NYC Got a Hint of Spring
2275981 1457148930 66 42 The Programs of the Week of the Leap Day
2254297 1456511279 66 41 The Programs of the Week of Washington's Birthday
2229909 1455908412 66 37 The Programs of the Week of Valentine's Day
2211517 1455296068 66 47 The Programs of the Week of Lincoln's Birthday
2193577 1454730759 66 45 The Programs of the Week the Groundhog Predicted Spring
2172825 1454086682 66 42 The Programs of the Week After the Blizzard
2140593 1453480109 65 36 The Programs of the Week We Prepared for a Blizzard
2122777 1452872135 63 45 The Programs of the Week We Lost David Bowie
2106473 1452271845 61 40 The Programs of the First Week of 2016
2090365 1451667035 62 43 The Programs of the Last Week of 2015
2078861 1451070011 60 41 The Programs of Christmas Week
2064885 1450455876 61 49 The Programs of the Week Star Wars Premiered
2047369 1449854282 61 41 The Programs of the Week of Hanukkah
2031009 1449249575 57 41 The Programs of the Week of Cyber Monday
2013833 1448675444 44 29 The Programs of Thanksgiving Week
1997517 1448040347 39 29 Overtone Week 3
1982057 1447454690 40 26 Overtone Week 2
1964925 1446848687 37 29 Overtone Week 1
1947217 1446238020 37 26 The Programs of the Week I Took a Break
1929601 1445608617 37 27 The Programs of the Week I was in Philadelphia
1912789 1445011738 36 32 The Programs of the Week the Mets Won
1896009 1444421786 35 30 The Sophomore Slump Week: Following up
1896001 1444421249 36 28 The Programs of the Sophomore Slump Week
1876565 1443819687 28 22 The Programs of the Week of Hurricane Joaquin
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.legend-axis path {
stroke: #fff;
stroke-width: 2px;
}
.caption {
font-size: 10px;
font-family: sans-serif;
font-weight: bold;
}
</style>
<svg width="960" height="500">
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 30, bottom: 80, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
gradient = svg.append("defs")
.append("linearGradient")
.attr("id","color-scheme"),
g = svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`),
legend = svg.append("g")
.attr("class","legend"),
x = d3.scaleBand()
.rangeRound([0,width])
.padding(0.4),
y = d3.scaleLinear()
.rangeRound([height,0]),
timeScale = d3.scaleTime()
.rangeRound([0,width]),
color = d3.scaleSequential(d3.interpolateViridis);
gradient.selectAll("stop")
.data(d3.range(0,1,0.11).map(color))
.enter()
.append("stop")
.attr("offset",(d,i,colors) => `${i * colors.length}%`)
.attr("stop-color", (d) => d);
var legendWidth = width / 4,
legendScale = d3.scaleLinear()
.rangeRound([0,legendWidth]);
legend.attr("transform", `translate(${(width / 2) - (legendWidth / 2)}, ${height + (margin.bottom * 0.85)})`)
.append("rect")
.attr("width", legendWidth)
.attr("height", 10)
.attr("fill", "url(#color-scheme)");
legend.append("text")
.attr("class","caption")
.attr("text-anchor","start")
.attr("y", -6)
.text("Open Rate");
legend.append("g")
.attr("class","legend-axis")
.call(d3.axisBottom(legendScale)
.tickSize(12)
.tickValues(d3.range(0.1,1,0.4))
.tickFormat(d3.format(".0%")));
d3.csv("data.csv", (d,i) => {
d.date = new Date(+d.sent_at * 1000);
d.sends = +d.send_count;
d.opens = +d["stats.unique_opens"] / d.sends;
return d;
}, (error, data) => {
if (error) throw error;
x.domain(data.reverse().map(d => d.id));
y.domain([0, d3.max(data, (d) => d.sends)]);
timeScale.domain(d3.extent(data, (d) => d.date));
var rect = g.selectAll("rect")
.data(data)
.enter()
.append("rect");
rect.attr("x", (d) => x(d.id))
.attr("y", (d) => y(d.sends))
.attr("width", x.bandwidth())
.attr("height", (d) => height - y(d.sends))
.attr("fill", (d) => color(d.opens));
g.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(timeScale));
g.append("g")
.attr("class", "y-axis")
.attr("fill", "none")
.call(d3.axisLeft(y));
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment