-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathd3.html
130 lines (119 loc) · 4.1 KB
/
d3.html
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<!doctype html>
<html ng-app="myApp">
<head>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/d3/d3.min.js"></script>
<script src="bower_components/angular-d3/dist/angular-d3.min.js"></script>
<!-- <script type="text/javascript" src="d3.js"> -->
</script>
</head>
<body ng-controller="DemoCtrl">
{{d3Data}}
<d3-bars data="d3Data" label="name" on-click="d3OnClick(item)"></d3-bars>
<script type="text/javascript">
angular.module('myApp', [
'myApp.controllers',
'myApp.directives'
]);
// setup dependency injection
angular.module('d3', []);
angular.module('myApp.controllers', []);
angular.module('myApp.directives', ['d3']);
angular.module('myApp.directives')
.directive('d3Bars', ['d3', function(d3) {
return {
restrict: 'EA',
scope: {
data: "=",
label: "@",
onClick: "&"
},
link: function(scope, iElement, iAttrs) {
var svg = d3.select(iElement[0])
.append("svg")
.attr("width", "100%");
// on window resize, re-render d3 canvas
window.onresize = function() {
return scope.$apply();
};
scope.$watch(function() {
return angular.element(window)[0].innerWidth;
}, function() {
return scope.render(scope.data);
});
// watch for data changes and re-render
scope.$watch('data', function(newVals, oldVals) {
return scope.render(newVals);
}, true);
// define render function
scope.render = function(data) {
// remove all previous items before render
svg.selectAll("*").remove();
// setup variables
var width, height, max;
width = d3.select(iElement[0])[0][0].offsetWidth - 20;
// 20 is for margins and can be changed
height = scope.data.length * 35;
// 35 = 30(bar height) + 5(margin between bars)
max = 98;
// this can also be found dynamically when the data is not static
// max = Math.max.apply(Math, _.map(data, ((val)-> val.count)))
// set the height based on the calculations above
svg.attr('height', height);
//create the rectangles for the bar chart
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.on("click", function(d, i) {
return scope.onClick({
item: d
});
})
.attr("height", 30) // height of each bar
.attr("width", 0) // initial width of 0 for transition
.attr("x", 10) // half of the 20 side margin specified above
.attr("y", function(d, i) {
return i * 35;
}) // height + margin between bars
.transition()
.duration(1000) // time of duration
.attr("width", function(d) {
return d.score / (max / width);
}); // width based on scale
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "#fff")
.attr("y", function(d, i) {
return i * 35 + 22;
})
.attr("x", 15)
.text(function(d) {
return d[scope.label];
});
};
}
};
}]);
angular.module('myApp.controllers')
.controller('DemoCtrl', ['$scope', function($scope) {
$scope.title = "DemoCtrl";
$scope.d3Data = [{
name: "Greg",
score: 98
}, {
name: "Ari",
score: 96
}, {
name: "Loser",
score: 48
}];
$scope.d3OnClick = function(item) {
alert(item.name);
};
}]);
</script>
</body>
</html>