Skip to content

Instantly share code, notes, and snippets.

@vicapow
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vicapow/9591312 to your computer and use it in GitHub Desktop.
Save vicapow/9591312 to your computer and use it in GitHub Desktop.
Using Angular expressions for D3 accessors
season title directed_by written_by air_date us_viewers
1 Days Gone Bye Frank Darabont Teleplay by: Frank Darabont 2010-10-31 5.35
1 Guts Michelle MacLaren Frank Darabont 2010-11-07 4.71
1 Tell It to the Frogs Gwyneth Horder-Payton Story by: Charles H. Eglee & Jack LoGiudice Teleplay by: Charles H. Eglee & Jack LoGiudice and Frank Darabont 2010-11-14 5.07
1 Vatos Johan Renck Robert Kirkman 2010-11-21 4.75
1 Wildfire Ernest Dickerson Glen Mazzara 2010-11-28 5.56
1 TS-19 Guy Ferland Adam Fierro and Frank Darabont 2010-12-05 5.97
2 What Lies Ahead Ernest Dickerson & Gwyneth Horder-Payton Ardeth Bey and Robert Kirkman 2011-10-16 7.26
2 Bloodletting Ernest Dickerson Glen Mazzara 2011-10-23 6.70
2 Save the Last One Phil Abraham Scott M. Gimple 2011-10-30 6.10
2 Cherokee Rose Billy Gierhart Evan Reilly 2011-11-06 6.29
2 Chupacabra Guy Ferland David Leslie Johnson 2011-11-13 6.12
2 Secrets David Boyd Angela Kang 2011-11-20 6.08
2 Pretty Much Dead Already Michelle MacLaren Scott M. Gimple 2011-11-27 6.62
2 Nebraska Clark Johnson Evan Reilly 2012-02-12 8.10
2 Triggerfinger Billy Gierhart David Leslie Johnson 2012-02-19 6.89
2 18 Miles Out Ernest Dickerson Scott M. Gimple & Glen Mazzara 2012-02-26 7.04
2 Judge, Jury, Executioner Greg Nicotero Angela Kang 2012-03-04 6.77
2 Better Angels Guy Ferland Evan Reilly & Glen Mazzara 2012-03-11 6.89
2 Beside the Dying Fire Ernest Dickerson Robert Kirkman & Glen Mazzara 2012-03-18 8.99
3 Seed Ernest Dickerson Glen Mazzara 2012-10-14 10.87
3 Sick Billy Gierhart Nichole Beattie 2012-10-21 9.55
3 Walk with Me Guy Ferland Evan Reilly 2012-10-28 10.51
3 Killer Within Guy Ferland Sang Kyu Kim 2012-11-04 9.27
3 Say the Word Greg Nicotero Angela Kang 2012-11-11 10.37
3 Hounded Dan Attias Scott M. Gimple 2012-11-18 9.21
3 When the Dead Come Knocking Dan Sackheim Frank Renzulli 2012-11-25 10.43
3 Made to Suffer Billy Gierhart Robert Kirkman 2012-12-02 10.48
3 The Suicide King Lesli Linka Glatter Evan Reilly 2013-02-10 12.26
3 Home Seith Mann Nichole Beattie 2013-02-17 11.05
3 I Ain't a Judas Greg Nicotero Angela Kang 2013-02-24 11.01
3 Clear Tricia Brock Scott M. Gimple 2013-03-03 11.30
3 Arrow on the Doorpost David Boyd Ryan C. Coleman 2013-03-10 11.46
3 Prey Stefan Schwartz Glen Mazzara & Evan Reilly 2013-03-17 10.84
3 This Sorrowful Life Greg Nicotero Scott M. Gimple 2013-03-24 10.99
3 Welcome to the Tombs Ernest Dickerson Glen Mazzara 2013-03-31 12.42
4 30 Days Without an Accident Greg Nicotero Scott M. Gimple 2013-10-13 16.11
4 Infected Guy Ferland Angela Kang 2013-10-20 13.95
4 Isolation Dan Sackheim Robert Kirkman 2013-10-27 12.92
4 Indifference Tricia Brock Matthew Negrete 2013-11-03 13.31
4 Internment David Boyd Channing Powell 2013-11-10 12.20
4 Live Bait Michael Uppendahl Nichole Beattie 2013-11-17 12.00
4 Dead Weight Jeremy Podeswa Curtis Gwinn 2013-11-24 11.29
4 Too Far Gone Ernest Dickerson Seth Hoffman 2013-12-01 12.05
4 After Greg Nicotero Robert Kirkman 2014-02-09 15.76
4 Inmates Tricia Brock Matthew Negrete & Channing Powell 2014-02-16 13.34
4 Claimed Seith Mann Nichole Beattie & Seth Hoffman 2014-02-23 13.12
4 Still Julius Ramsay Angela Kang 2014-03-02 12.61
4 Alone Ernest Dickerson Curtis Gwinn 2014-03-09 12.65
4 The Grove Michael Satrazemis Scott M. Gimple 2014-03-16
4 Us David S. Goyer 2014-03-23
4 A Michelle MacLaren 2014-03-30
<!DOCTYPE html>
<html>
<head>
<title>Walking Dead Viewership</title>
</head>
<style>
body, html{
margin: 0;
width: 900px;
color: white;
background-color: black;
font-family: helvetica;
margin: auto;
}
.scatter-container{
width: 50%;
float: left;
height: 400px;
}
.detail{
width: 50%;
float: left;
height: 400px;
}
scatter{
width: 100%;
height: 100%;
display: block;
z-index: 0;
overflow: hidden;
font-size: 10px;
}
scatter circle{
opacity: 0.4;
cursor: pointer;
stroke-width: 2;
}
scatter circle:hover{
stroke: white;
}
scatter text{
fill: white;
stroke: none;
}
scatter .x-axis path, scatter .y-axis path{
stroke: none;
fill: none;
}
scatter .x-axis line, scatter .y-axis line{
stroke: rgba(255, 255, 255, 0.2);
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<body ng-app="myApp" ng-controller="MainCtrl">
<h1>Walking Dead Viewership</h1>
<div class="scatter-container">
<scatter
data="episodes"
accessor-x="d.air_date"
accessor-y="d.us_viewers"
selected-point="selectedEpisode"
color="color(d.season)">
</scatter>
</div>
<div class="detail">
<h2>Episode: {{selectedEpisode.title}}</h2>
<h3>season: {{selectedEpisode.season}}</h3>
<h3>us viewers: {{selectedEpisode.us_viewers | number}}</h3>
</div>
</body>
<script>
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope, $window){
$scope.color = d3.scale.category10();
angular.element($window).on('resize', function(){ $scope.$apply(); });
d3.csv('./episodes.csv', function(row){
row.season = +row.season; // number
row.air_date = new Date(row.air_date);
row.us_viewers = +row.us_viewers * 1e6; // us viwers in millions
return row;
}, function(err, episodes){
if(err){ throw err; }
$scope.$apply(function(){
// remove the few episodes that haven't air yet at time of writing.
episodes = episodes.slice(0, -3);
$scope.episodes = episodes;
$scope.selectedEpisode = episodes[0];
});
});
});
app.directive('scatter', function(){
function link(scope, el, attr){
el = el[0];
var w, h;
var svg = d3.select(el).append('svg');
var xAxisG = svg.append('g').attr('class', 'x-axis');
var yAxisG = svg.append('g').attr('class', 'y-axis');
var points = svg.append('g').attr('class', 'points').selectAll('g.point');
var x = d3.scale.linear();
var y = d3.scale.linear();
var yFormat = d3.format('.2s');
var timeFormat = d3.time.format('%m-%y');
var xFormat = function(d){ return timeFormat(new Date(d)) };
var xAxis = d3.svg.axis().scale(x).orient('bottom').tickFormat(xFormat);
var yAxis = d3.svg.axis().scale(y).orient('left').tickFormat(yFormat);
var m = 50;
scope.$watch(function(){
w = el.clientWidth;
h = el.clientHeight;
return w + h;
}, resize);
function resize(){
svg.attr({width: w, height: h});
x.range([m, w - m]);
y.range([h - m, m]);
xAxis.tickSize(-h + 2 * m);
yAxis.tickSize(-w + 2 * m);
xAxisG.attr('transform', 'translate(' + [0, y.range()[0] + 0.5] + ')');
yAxisG.attr('transform', 'translate(' + [x.range()[0], 0] + ')');
update();
}
scope.$watch('data', update);
function update(){
if(!scope.data){ return };
var data = scope.data;
var x_extent = d3.extent(data, function(d){ return scope.accessorX({d:d}) });
x.domain(x_extent);
var y_max = d3.max(data, function(d){ return scope.accessorY({d:d}) });
y.domain([0, y_max]);
points = points.data(data);
points.exit().remove();
var point = points.enter().append('g').attr('class', 'point');
point.append('circle').attr('r', 5)
.style('fill', function(d){ return scope.color({d:d}); })
.on('mouseover', function(d){
scope.$apply(function(){
scope.selectedPoint = d;
});
})
// update the position of all the points
points.attr('transform', function(d){
return 'translate(' + [x(scope.accessorX({d:d})), y(scope.accessorY({d:d}))] + ')';
});
xAxisG.call(xAxis);
yAxisG.call(yAxis);
};
}
return {
link: link,
restrict: 'E',
scope: { data: '=', accessorX: '&', accessorY: '&', color: '&', selectedPoint: '=' }
};
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment