Skip to content

Instantly share code, notes, and snippets.

@threestory
Last active December 3, 2015 20:31
Show Gist options
  • Save threestory/2bd38fc6db5171a9493b to your computer and use it in GitHub Desktop.
Save threestory/2bd38fc6db5171a9493b to your computer and use it in GitHub Desktop.
Social Media Usage Stacked Area
application indicator 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
snapchat duration 335 476 420 1040 571 214 399 238 0 574 164 685 804 585 803 526 619 539 679 1060 530 653 516 710 523 658 520 583
instagram duration 324 399 644 562 233 104 343 82 0 273 106 457 349 304 639 276 328 445 518 575 315 325 345 403 279 318 298 394
facebook duration 0 41 47 30 16 0 37 13 0 16 26 12 30 56 41 68 73 83 62 87 18 66 156 93 98 39 73 121
tfbnw duration 0 0 0 0 0 0 0 0 0 0 0 0 0 45 57 27 26 65 206 225 104 78 34 11 121 45 101 166
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Stacked Area Sample: Mobile Social Media Usage</title>
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="http://use.typekit.com/brf5jpj.js"></script>
<script src="//use.typekit.net/drk2sev.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<style type="text/css">
body {
margin: 0;
background-color: #48494B;
font-family: "proxima-nova", "Source Sans Pro", sans-serif;
}
#container {
width: 850px;
margin-left: 30px;
margin-right: auto;
margin-top: 30px;
padding: 30px;
background-color: white;
box-shadow: 3px 3px 7px #222;
}
#tooltip {
width: 150px;
height: auto;
padding: 5px;
background-color: #fff;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.4);
box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.4);
pointer-events: none;
position: absolute;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-size: 14px;
line-height: 18px;
}
h1 {
font-size: 24px;
margin: 0;
}
p {
font-size: 16px;
margin: 15px 0 10px 0;
}
a {
color: #799DCB;
text-decoration: none;
transition: color .3s, background .3s, border .3s;
}
a:hover {
color: #48494b;
background: #e7e8e9;
}
svg {
background-color: white;
padding-left: 20px;
}
#fb_label {
position:absolute;
left: 784px;
top: 308px;
color: #3b5998;
font-weight:bold;
font-size:12px;
}
#inst_label {
position:absolute;
left: 784px;
top: 343px;
color: #3f729b;
font-weight:bold;
font-size:12px;
}
#snap_label {
position:absolute;
left: 784px;
top: 410px;
color: #BBB800;
font-weight:bold;
font-size:12px;
}
#fbm_label {
position:absolute;
left: 784px;
top: 290px;
color: #2998ff;
font-weight:bold;
font-size:12px;
}
.facebook {
fill: #3b5998;
}
.facebook:hover {
fill: #222;
cursor:pointer;
}
.snapchat {
fill: #FFFC00;
}
.snapchat:hover {
fill: #222;
cursor:pointer;
}
.tfbnw {
fill: #2998ff;
}
.tfbnw:hover {
fill: #222;
cursor:pointer;
}
.instagram {
fill: #3f729b;
}
.instagram:hover {
fill: #222;
cursor:pointer;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
</style>
</head>
<body>
<div id="container">
<h1>Social Media Usage</h1>
<p>In order to facilitate productive conversations about one of my children's social media usage, I created this handy dandy data-driven graphic. No more he-said, she-said arguments - just talk to the data.<br /><strong>Source:</strong> <a href="http://www.curbi.com/">Curbi</a>
</p>
</div>
<!-- <div id="tooltip" class="hidden">
<p><strong><span id="name">User name</strong></p>
<p>@<span id="handle">Screen name</span></p>
<p>Followers: <span id="followers">Followers</span></p>
<p>Following: <span id="following">Following</span></p>
<p>Tweets: <span id="tweets">Tweets</span></p>
</div>
-->
<div id="fb_label">Facebook</div>
<div id="inst_label">Instagram</div>
<div id="snap_label">Snapchat</div>
<div id="fbm_label">FB Network</div>
<script type="text/javascript">
//set up stack method
var stack = d3.layout.stack()
.values(function(d){
return d.duration;
});
//Dimensions and padding
var w = 800;
var h = 300;
var padding = [ 20, 60, 20, 40 ]; //Top, right, bottom, left
var dataset;
// Various range scales
//linear scales
var xScale = d3.scale.linear().range([ padding[3], w - padding[1] - padding[3] ]),
// var xScale = d3.scale.linear().range([ 0, w ]),
yScale = d3.scale.linear().range([ padding[0] , h - padding[2] ]);
// //set up date formatting
// var dateFormat = d3.time.format.utc("%e %b %Y");
// var dateFormatCalc = d3.time.format.utc("%Y-%m-%e"); //for Firefox date calculations
// The axes - linear
var xAxis = d3.svg.axis()
.orient("bottom")
.scale(xScale)
.ticks(20);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
//set up area generator
var area = d3.svg.area()
.x(function(d) {
return xScale(d.x);
})
.y0(function(d) {
return yScale(d.y0);
})
.y1(function(d) {
return yScale(d.y0 + d.y);
});
//Easy colors accessible via a 10-step ordinal scale
var color = d3.scale.category10();
//Create the empty SVG image
var svg = d3.select("#container")
.append("svg")
.attr("width", w )
.attr("height", h );
//Load data
d3.csv("curbi_data2.csv", function(data) {
console.log(data);
// new array with week numbers
var weeks = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28"];
dataset = [];
//loop for each row in data to restructure
for (var i = 0; i < data.length; i++) {
//new object with app name and empty duration array
dataset[i] = {
application: data[i].application,
duration: []
};
//loop through all the weeks
for (var j = 0; j < weeks.length; j++) {
//default value, in case of blank value
var amount = null;
//if not empty
if (data[i][weeks[j]]) {
amount = +data[i][weeks[j]];
}
//add new object to the array for this app
dataset[i].duration.push({
x: weeks[j],
y: amount
});
}
}
//stack the data
console.log(dataset);
stack(dataset);
//Now that the data is ready, we can check its
//min and max values to set our scales' domains!
xScale.domain([ 1 , 28 ]);
//loop once for each week, get total value of duration for that week
var totals = [];
for (i = 0; i < weeks.length; i++) {
totals[i] = 0;
for (j = 0; j < dataset.length; j++) {
totals[i] += dataset[j].duration[i].y;
}
}
yScale.domain([ d3.max(totals), 0 ]);
//make a path for each application
var paths = svg.selectAll("path")
.data(dataset)
.enter()
.append("path")
// .attr("class", "area")
.attr("class", function(d){
return d.application;
})
.attr("d", function(d) {
return area(d.duration);
})
.attr("stroke", "none")
.attr("fill", function(d, i) {
return color(i);
});
paths.append("text")
.attr("x", w - 180)
// .attr("y", function(d){
// if (d.application == "snapchat") return h - 35;
// if (d.application == "instagram") return h - 50;
// if (d.application == "facebook") return h - 62;
// if (d.application == "tfbnw") return h - 65;
// })
.attr("text-anchor", "start")
.attr("font-family", "ff-nuvo-sc-web-pro-1,ff-nuvo-sc-web-pro-2, sans-serif")
.attr("font-size", "11px")
.attr("class", function(d){
return d.application})
.text(function(d){
return d.application});
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (h - padding[2]) + ")")
.call(xAxis);
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + padding[3] + ",0)")
.call(yAxis);
// Add an x-axis label.
svg.append("text")
.attr("class", "x label")
.attr("text-anchor", "start")
.attr("x", w - padding[1])
.attr("y", h - 3)
// .attr("transform", "translate(" + padding[3] + ",0)")
// .attr("transform", "translate(0,0)")
.text("Week #");
// Add a y-axis label.
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("y", 6)
.attr("dy", ".75em")
.attr("transform", "translate(" + padding[3] + "," + padding[0] + ")rotate(-90)")
.text("Minutes Spent");
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment