Skip to content

Instantly share code, notes, and snippets.

@vicapow
Last active August 29, 2015 13:57
Show Gist options
  • Save vicapow/9716306 to your computer and use it in GitHub Desktop.
Save vicapow/9716306 to your computer and use it in GitHub Desktop.
Responsive visualizations using Angular directives
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<style>
body, html{
margin: 0;
color: white;
background-color: black;
font-family: helvetica;
margin: auto;
width: 100%;
height: 100%;
}
scatter{
display: block;
z-index: 0;
overflow: hidden;
font-size: 10px;
}
scatter circle{
fill: yellow;
opacity: 1;
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);
}
.scatter-1{
width: 30%;
}
.scatter-2{
width: 70%;
}
.scatter-3{
width: 100%;
}
.scatter-1, .scatter-2, .scatter-3{
height: 50%;
float: left;
}
</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">
<scatter class="scatter-1" data="employers"></scatter>
<scatter class="scatter-2" data="employers"></scatter>
<scatter class="scatter-3" data="employers"></scatter>
</body>
<script>
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope, $window){
angular.element($window).on('resize', function(){ $scope.$apply() })
// world's largest employers
// source: https://en.wikipedia.org/wiki/List_of_largest_employers
$scope.employers = [
{ value: 3.2, name: 'United States Department of Defense' }
, { value: 2.3, name: 'People\'s Liberation Army' }
, { value: 2.1, name: 'Walmart' }
, { value: 1.9, name: 'McDonald\'s' }
, { value: 1.7, name: 'National Health Service' }
, { value: 1.6, name: 'China National Petroleum Corporation' }
, { value: 1.5, name: 'State Grid Corporation of China' }
, { value: 1.4, name: 'Indian Railways' }
, { value: 1.3, name: 'Indian Armed Forces' }
, { value: 1.2, name: 'Hon Hai Precision Industry (Foxconn)' }
]
});
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 xAxis = d3.svg.axis().scale(x).orient('bottom')
.tickFormat(function(d, i){ return i + 1; }); // 1 index the company ranks
var yAxis = d3.svg.axis().scale(y).orient('left');
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, i){ return i });
x.domain(x_extent);
var y_max = d3.max(data, function(d){ return d.value });
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)
// update the position of all the points
points.attr('transform', function(d, i){
return 'translate(' + [x(i), y(d.value)] + ')';
});
xAxisG.call(xAxis);
yAxisG.call(yAxis);
};
}
return {
link: link,
restrict: 'E',
scope: { data: '=' }
};
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment