Angular: D3js Simple stacked Graphs Example

by Matthew Marcus

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
<div ng-controller="MyCtrl">
    <button ng-click="sort()">Sort</button>
    <table>
        <tbody>
            <tr ng-repeat="item in arr">
                <td>
                    <d3 class="stacked-bar span12" data-type="stacked-h" data-data="item.graphData"></d3>
                </td>
            </tr>
        </tbody>
    </table>
</div>

CSS

th, td {
    padding:1px;
}
table {
    width: 100%;
}
td d3 span {
    display:inline-block;
    height:5px;
}
table d3.stacked-bar {
    height: 10px;
    display:block;
}
.span12 {
    width: 100%;
}

JavaScript

var myApp = angular.module('myApp', []);

myApp.directive('d3', function () {
    return {
        restrict: 'E',
        scope: {
            data: '=',
            mouseEnter: '=',
            mouseLeave: '='
        },
        link: function (scope, elem, attrs) {
            var
            data = scope.data, //JSON.parse(attrs.data),

                d3Elem = null;

            d3Elem = d3.select(elem[0]);

            scope.$watch('data', function (newData) {
                scope.render(newData);
            }, true);

            scope.render = function (data) {
                //					console.log('rendering D3 data:');
                //					console.log(data);
                if (data) {
                    (d3Elem) ? d3Elem.selectAll('*').remove() : angular.noop;

                    switch (attrs.type) {

                        case 'stacked-h':

                            d3Elem.selectAll('span')
                                .data(data)
                                .enter().append('span')
                                .style('width', function (d) {
                                return (d && d.perc) ? d.perc + '%' : null;
                            })
                                .style('background-color', function (d) {
                                return (d && d.fill) ? d.fill : null;
                            });
                            break;
                    }
                }
            }
        }
    }
});
//myApp.factory('myService', function() {});

myApp.controller('MyCtrl', function ($scope, $filter) {
    $scope.arr = [];
    var color = d3.scale.category20();
    for (var i = 1; i <= 4100; i++) {
        var perc = parseInt(Math.random() * 100);
        $scope.arr.push({
            percentage: perc,
            graphData: [
                {
                    perc: perc,
                    fill: color(perc)
                }, {
                    perc: 100 - perc,
                    fill: '#ccc'
        ...