ng-d3
by g
HTML
<div ng-controller="Ctrl">
<div d3>
<div class="node"
d3-enter="node in nodes"
d3-classed="{ collapsed: node.collapsed }"
d3-style="{ opacity: 0 }"
d3-on-click="toggleChildren(node)">
<span class="text name">{{ node.Name }}</span>
<div class="node-manager">
<span class="text manager pointer"
d3-on-click="openContact(node.Manager)">{{ node.Manager.Name }}</span>
<div class="picture">
<img d3-attr-src="node.Manager.Picture" />
</div>
</div>
<div class="node-contacts">
<ul class="contact-list">
<li class=""
d3-enter="contact in (node.ResponsiblePersons || []).concat(node.Contacts || [])">
</li>
</ul>
</div>
</div>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>
CSS
.node {
display: block;
height: 30px;
width: 30px;
border: solid 1px #ccc;
}
JavaScript
var module = angular.module('app', []);
module.directive("d3", function(){
return {
terminal: true,
link: function(scope, element, attrs) {
var node = element.clone();
element.html('');
var $root = d3.select(element[0]);
var children = node.children();
for (var childIdx = 0; childIdx < children.length; childIdx++) {
var childNode = children[childIdx];
var attrMap = {};
for (var attrIdx = 0; attrIdx < childNode.attributes.length; attrIdx++) {
var attr = childNode.attributes[attrIdx];
if (attr.specified) {
attrMap[attr.name] = attr.value;
}
}
console.log({ node: childNode }, attrMap);
var d3Enter = attrMap['d3-enter'];
if (d3Enter) {
var tagName = childNode.tagName;
var className = childNode.className;
var selector = tagName;
if (className) {
selector = selector + "." + childNode.className; // TODO: handle multiple classes
}
var $child = $root.selectAll(selector)
.data(scope.nodes);
var $childEnter = $child.enter()
.append(tagName)
.classed(className, true);
}
}
// console.log(element.html());
}
};
});
module.controller('Ctrl', function($scope) {
$scope.nodes = [
{ name: 'Guillaume' },
{ name: 'Marx' }
];
});
angular.bootstrap(document.body, ['app']);