This is a code excerpt from the book D3 on Angular. http://leanpub.com/d3angularjs
The data was scraped from Wikipedia on 3/15/2014: https://en.wikipedia.org/wiki/List_of_The_Walking_Dead_episodes
xxxxxxxxxx
<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="https://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>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js
https://d3js.org/d3.v3.min.js