代码改变世界

D3学习笔记一 bars in angular

2017-03-23 18:11  蝶梦中  阅读(337)  评论(0编辑  收藏  举报

1 使用factory在页面添加d3.js。也可以选择在页面直接引入d3.js。

d3.factory('d3Service',['$document','$q', '$rootScope', function($document, $q, $rootScope){
    var d = $q.defer();
    function onScriptLoad(){
        $rootScope.$apply(function(){d.resolve(window.d3);})
    }

  // 建立一个D3的脚本标签,当这个标签加载完毕后运行onScriptLoad方法来load D3

     var scriptTag = $document[0].createElement('script');

    scriptTag.type='text/javascript';
    scriptTag.async=true;
    scriptTag.src='../js/common/d3/d3.js';
    scriptTag.onreadystatechange = function(){
        if(this.readyState == 'complete')onScriptLoad();
    };
    scriptTag.onload = onScriptLoad;

    var s = $document[0].getElementsByTagName('body')[0];

    s.appendChild(scriptTag);

    return {
        d3:function(){return d.promise}
    };
}]);

2 建立一个d3 directive。

d3Module.directive('d3Bars',['$window', 'd3Service',function($window, d3Service){
    return{
        restrict:'EA',
        scope:{
            data:'=',
            clickBar:'&'
        },
        link:function(scope, element, attrs){
            d3Service.d3().then(function(d3){
                var svg = d3.select(element[0]).append('svg').style('width','100%');

                var margin = parseInt(attrs.margin) || 20,
                    barHeight = parseInt(attrs.barHeight) || 20,
                    barPadding = parseInt(attrs.barPadding) || 5;
                //页面大小调整时元素也进行调整
                window.onresize = function(){
                    scope.$apply();
                };

                //scope.data = [
                //    {name: 'Greg', score:98},
                //    {name: 'Ari', score:96},
                //    {name: 'Q', score:75},
                //    {name: 'Loser', score:48}
                //];

                scope.$watch(function(){
                    return angular.element($window)[0].innerWidth;
                },function(){
                    scope.render(scope.data)
                });

                scope.render = function(data) {
                    //刷新前移除之前的svg
                    svg.selectAll('*').remove();

                    if(!data) return;

                    // 设置变量
                    var width = d3.select(element[0]).node().offsetWidth - margin,
                    // 计算高度
                        height = scope.data.length * (barHeight + barPadding),
                    // 使用category20()函数来生成颜色
                        color = d3.scale.category20(),
                    // 定义比例尺
                        xScale = d3.scale.linear()
                            .domain([0, d3.max(data, function (d) {
                                return d.score;
                            })])
                            .range([0, width]);

                    svg.attr('height', height);

                    //生成柱状图的长方形
                    svg.selectAll('rect')
                        .data(data).enter()
                        .append('rect')
                        .attr('height',barHeight)
                        .attr('width',140)
                        .attr('x',Math.round(margin/2))
                        .attr('y',function(d,i){
                            return i * (barHeight + barPadding);
                        })
                        .attr('fill',function(d){return color(d.score);})
                        .transition()
                        .duration(1000)
              //根据比例尺计算柱状图的宽度 .attr(
'width',function(d){ return xScale(d.score); }); svg.selectAll('rect').on('click',function(d,i){ return scope.clickBar({item: d}); }) } }); } } }]);
 

效果图: