Skip to content

Instantly share code, notes, and snippets.

@ckuijjer
Last active December 23, 2015 14:29
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 ckuijjer/6649479 to your computer and use it in GitHub Desktop.
Save ckuijjer/6649479 to your computer and use it in GitHub Desktop.
Increase in subscribers

An implementation in D3 of Figure 4-25 "Scatterplot created in R and designed in Illustrator" in "Visualize This" by Nathan Yau.

Date Subscribers Reach Item Views Hits
01-01-2010 25047 4627 9682 27225
01-02-2010 25204 1676 5434 28042
01-03-2010 25491 1485 6318 29824
01-04-2010 26503 6290 17238 48911
01-05-2010 26654 6544 16224 45521
01-06-2010 26851 6574 16717 43071
01-07-2010 26899 8026 22485 37825
01-08-2010 26791 6235 17706 41712
01-09-2010 25783 1626 6928 29823
01-10-2010 26093 1440 6374 31816
01-11-2010 27153 7204 17633 47007
01-12-2010 9495 7383 18405 44242
01-13-2010 9546 6672 17209 39722
01-14-2010 26756 7313 19343 38598
01-15-2010 27133 6287 18488 35961
01-16-2010 26124 1666 6377 31445
01-17-2010 25874 1728 6155 33733
01-18-2010 27245 6283 16287 38239
01-19-2010 27595 7585 19709 40198
01-20-2010 27667 8180 25778 45718
01-21-2010 27098 6889 20924 39998
01-22-2010 27592 8068 24207 38831
01-23-2010 26525 2760 9073 38339
01-24-2010 26974 2272 9251 40491
01-25-2010 28171 8885 23076 54885
01-26-2010 28357 8047 21261 41371
01-27-2010 28400 7683 19367 52517
01-28-2010 28267 8471 25166 52350
01-29-2010 28104 7725 19812 43748
01-30-2010 27175 2206 0 34352
01-31-2010 27611 6317 15620 44449
<!DOCTYPE html>
<body>
<style>
body {
font-family: Georgia;
font-size: 14px;
color: #333;
}
#container {
width: 500px;
height: 500px;
margin: 0 auto;
position: relative;
border: 1px solid #eee;
}
#inner-container {
position: absolute;
top: 20px;
left: 20px;
bottom: 20px;
right: 20px;
}
svg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
}
#header {
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
}
#header-text {
width: 420px;
}
#max-subscribers {
position: absolute;
left: 26px;
top: 109px;
}
#subscribers-1st {
position: absolute;
font-weight: bold;
font-size: 12px;
left: 50px;
top: 195px;
}
#subscribers-31st {
position: absolute;
font-weight: bold;
font-size: 12px;
left: 415px;
top: 195px;
}
#gain-31st {
position: absolute;
font-size: 12px;
color: #999;
left: 415px;
top: 210px;
}
#reporting-error {
position: absolute;
font-size: 12px;
left: 230px;
top: 290px;
font-weight: bold;
}
#reporting-error-text {
position: absolute;
font-size: 11px;
width: 210px;
left: 230px;
top: 305px;
}
#footer-month {
position: absolute;
bottom: 10px;
left: 60px;
font-size: 12px;
}
#footer {
position: absolute;
bottom: 0;
right: 0;
font-size: 12px;
}
.axis.x path {
stroke-width: 1;
}
.axis.x line {
fill: none;
stroke: #999;
shape-rendering: crispEdges;
}
.axis.x path {
display: none;
}
.axis.y path {
display: none;
}
.axis-rule.y {
stroke-width: 1;
stroke: #eee;
shape-rendering: crispEdges;
}
.axis-rule-0.y {
stroke-width: 2;
stroke: #333;
shape-rendering: crispEdges;
}
.subscribers-line {
stroke-width: 2;
stroke: #999;
shape-rendering: crispEdges;
}
</style>
<div id="container">
<div id="inner-container">
<div id="header">INCREASE IN SUBSCRIBERS</div>
<div id="header-text">In January 2010, the number of subscribers via RSS and email increase to 27,611, making it the tenth month in a row with at least a ten percent increase.</div>
<div id="max-subscribers">thousand subscribers</div>
<div id="subscribers-1st">25,047</div>
<div id="subscribers-31st">27,611</div>
<div id="gain-31st">(+10%)</div>
<div id="reporting-error">Reporting Error</div>
<div id="reporting-error-text">A source reported incorrect subscriber counts for January 12 and 13. Counts are more than 17,000 to low.</div>
<div id="footer-month">JANUARY 2010</div>
<div id="footer">Source: FeedBurner | Nathan Yau</div>
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var width = 500,
height = 500,
margin = { top: 150, right: 20, bottom: 75, left: 20},
padding = { top: 0, right: 15, bottom: 0, left: 60 };
// Radius and color of the data points
var radius = 4,
color = '#8B001B';
// Width/height of the chart without margin and padding
var chartWidth = width - margin.left - margin.right - padding.left - padding.right;
var chartHeight = height - margin.top - margin.bottom - padding.top - padding.bottom;
var xValue = function(d) { return d.date; },
xScale = d3.time.scale().range([0, chartWidth]),
xMap = function(d) { return xScale(xValue(d)); },
xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.tickFormat(function(d) { return d.getDate(); })
.tickSize(8)
.ticks(function() { // To create a specific set of tickmarks
return [1,5,10,15,20,25,30]
.map(function(d) { return new Date(2010, 0, d); })
}),
xAxisMinor = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(31) // A minor tick for each of the Days
.tickSize(4)
.tickFormat(function(d) { return; })
var yValue = function(d) { return d.subscribers; },
yScale = d3.scale.linear().range([chartHeight, 0]),
yMap = function(d) { return yScale(yValue(d)); },
yAxis = d3.svg.axis()
.scale(yScale)
.orient('right')
.tickFormat(function(d) { return d / 1000; });
var svg = d3.select('#container').append('svg')
.attr('width', width)
.attr('height', height);
var chart = svg.append('g')
.attr('class', 'chart')
.attr('transform', 'translate(' + (margin.left + padding.left) + ', ' + (margin.top + padding.top) + ')');
var csvfile = 'flowingdata_subscribers.csv';
d3.csv(csvfile, function(d) {
return {
date: d3.time.format('%m-%d-%Y').parse(d.Date),
subscribers: +d['Subscribers']
};
}, function(error, data) {
// Set the domain based on the data
xScale.domain(d3.extent(data, xValue));
yScale.domain([0, d3.max(data, yValue)]).nice(); // nice to extent the domain to a round value
// Render the X axis (major and minor ticks as two axis)
chart.append('g')
.attr('class', 'axis x')
.attr('transform', 'translate(0, ' + chartHeight + ')')
.call(xAxis)
chart.append('g')
.attr('class', 'axis x')
.attr('transform', 'translate(0, ' + chartHeight + ')')
.call(xAxisMinor)
// Render the Y axis
chart.append('g')
.attr('transform', 'translate(' + (-padding.left - 5) + ', -12)')
.attr('class', 'axis y')
.call(yAxis);
// Render the Y axis rules
chart.selectAll('.axis-rule.y')
.data(yScale.ticks(7))
.enter()
.append('line')
.attr('class', function(d) {
if (d == 0) {
return 'axis-rule-0 y';
} else {
return 'axis-rule y'
}
})
.attr('x1', -padding.left)
.attr('x2', chartWidth + padding.right)
.attr('y1', function(d) { return yScale(d); })
.attr('y2', function(d) { return yScale(d); })
// Add a vertical line for the 1st and 31st data point
chart.selectAll('.description-line')
.data([data[0], data[data.length - 1]])
.enter()
.append('line')
.attr('class', 'subscribers-line')
.attr('x1', xMap)
.attr('x2', xMap)
.attr('y1', yMap)
.attr('y2', 64)
// Render the data
chart.selectAll('.point')
.data(data)
.enter()
.append('circle')
.attr('class', 'point')
.attr('cx', xMap)
.attr('cy', yMap)
.attr('r', radius)
.attr('fill', color);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment