Demo of how to create an Angular.js directive which provides a d3.js visualization.
The data used by the visualisation is provided by a controller and is synced by Angular.
'use strict'; | |
/** | |
* @ngdoc overview | |
* @name angularD3DemoApp | |
* @description | |
* # angularD3DemoApp | |
* | |
* Main module of the application. | |
*/ | |
angular | |
.module('angularD3DemoApp', []); |
'use strict'; | |
/** | |
* @ngdoc directive | |
* @name angularD3DemoApp.directive:d3test | |
* @description | |
* # d3test | |
*/ | |
angular.module('angularD3DemoApp') | |
.directive('d3test', function () { | |
return { | |
template: '<div></div>', | |
restrict: 'E', | |
replace: false, | |
scope: { data: '='}, | |
link: function postLink(scope, element, attrs) { | |
var w = 500; | |
var h = 400; | |
var svg = d3.select(element[0]).append('svg') | |
.attr('width', w) | |
.attr('height', h); | |
scope.$watch('data', function(data) { | |
if (data) { | |
var escala = function(m) { | |
return d3.scale | |
.linear() | |
.domain([d3.min(data), d3.max(data)]) | |
.range([10, m - 50]); | |
} | |
var ancho = escala(w); | |
var alto = escala(h); | |
var radio = d3.scale | |
.linear() | |
.domain([d3.min(data), d3.max(data)]) | |
.range([10, 50]); | |
var color = function(d) { | |
return d3.hsl(d*10,1,0.5); | |
}; | |
var circle_set = function(c) { | |
c | |
.attr('r', radio) | |
.attr('cx', ancho) | |
.attr('cy', alto) | |
.style('fill', color); | |
}; | |
var circles = svg.selectAll('circle'); | |
var sel = circles.data(data); | |
sel | |
.transition() | |
.ease('bounce') | |
.duration(500) | |
.call(circle_set); | |
sel.enter() | |
.append('circle') | |
.call(circle_set); | |
sel.exit() | |
.remove(); | |
} | |
}); | |
} | |
}; | |
}); |
<!doctype html> | |
<html class="no-js"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Angular.js and d3.js demo</title> | |
<meta name="description" content="Angular bind d3.js demo visualization."> | |
</head> | |
<body ng-app="angularD3DemoApp"> | |
<div ng-controller="MydataCtrl"> | |
<input | |
ng-init="circlecount=10" | |
ng-change="getTheData(circlecount)" | |
ng-model="circlecount" | |
type="range" name="points" min="2" max="20"> | |
<div>Count: {{circlecount}} Data: {{theData}}</div> | |
<d3test | |
ng-init="getTheData(circlecount)" | |
data="theData"> | |
</d3test> | |
</div> | |
</body> | |
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="app.js"></script> | |
<script src="mydata.js"></script> | |
<script src="d3test.js"></script> | |
</html> |
'use strict'; | |
/** | |
* @ngdoc function | |
* @name angularD3DemoApp.controller:MydataCtrl | |
* @description | |
* # MydataCtrl | |
* Controller of the angularD3DemoApp | |
*/ | |
angular.module('angularD3DemoApp') | |
.controller('MydataCtrl', function ($scope) { | |
$scope.getTheData = function(circlecount) { | |
// Generate an array of sequential numbers. | |
$scope.theData = d3.range($scope.circlecount).map(function(i) { return (i + 1) * 5; }); | |
}; | |
}); |