D3数据图的Angular指令只渲染一次

时间:2015-05-15 07:42:36

标签: angularjs svg d3.js angular-directive datamaps

因此,我制作了一个Angular指令,它在HTML模板中呈现D3数据图。我通过'data'属性将数据传递给指令。我面临的问题是,当第一次加载页面时,地图会完美显示。但是,当我通过从其他模板导航(通过'ui-route'完成路由)回到模板时,地图不会被渲染,并且控制台中也没有错误。 这是我的指示

app.directive('stabilityMap', function() {
    var containerid = document.getElementById('world-map-container');
    var margin = 20,
        padding = 50,
        width = containerid.offsetWidth - margin;
        height = containerid.offsetHeight - margin;
    return {
        restrict: 'A',
        scope: {
            data: '=',
        },
        link : function(scope, element, attrs) {
            scope.$watch('data', function(newVal, oldVal) {   
                var colorScale = d3.scale.linear().domain([50, 100]).range(['#ff0000', '#280000']);
                var Fills = {defaultFill: '#ddd'};
                var Data = {};
                var countries = Datamap.prototype.worldTopo.objects.world.geometries;
                for(var i = 0; i < newVal.length; i++) {
                    for (var j = 0; j < countries.length; j++) {
                        if(countries[j].properties.name == newVal[i].Country) {
                            Fills[countries[j].id] = colorScale(newVal[i]['Stability Index']);
                            Data[countries[j].id] = { fillKey : countries[j].id};
                        }
                    }
                }
                var map = new Datamap({
                    element: containerid,
                    responsive: true,
                    projection: 'mercator',
                    setProjection: function(element) {
                                    var projection = d3.geo.mercator()
                                      .center([0, padding])
                                      .scale(105)
                                      .translate([element.offsetWidth / 2, element.offsetHeight / 2 - 70]);
                                    var path = d3.geo.path()
                                      .projection(projection);
                                    return {path: path, projection: projection};
                                  },
                    fills: Fills,
                    data: Data
                })
                d3.select(window).on('resize', function() {
                    map.resize();
                });
            })
        }
    }
})

这是模板的角度控制器:

app.controller('CountryCtrl', ['$scope', '$http', function($scope, $http) {
    $scope.countriesData = [
        {'Country': 'Australia', 'Stability Index':'85'},
        {'Country':'United States of America', 'Stability Index':'90'},
        {'Country':'Russia', 'Stability Index':'70'},
        {'Country':'India', 'Stability Index':'84.2'},
        {'Country':'China', 'Stability Index':'50'}
    ]
}]);

以下是HTML模板:

<div class="row" id="world-map">
    <div stability-map data="countriesData" id="world-map-container">
    </div>
</div>

以下是首次加载页面时的屏幕截图:

when page/website loaded first

在我从网站的其他模板导航后回到页面后的空容器。

Empty container that should contain the svg

知道发生了什么事吗?

2 个答案:

答案 0 :(得分:0)

地图不会再次渲染,因为该函数仅在首次执行代码时运行一次。我建议你将你的地图创建包装在一个函数中,并在每次加载页面时(从控制器)调用该函数。

$scope.renderMap = function() { 
   var map = new Datamap({
                    element: containerid,
                    responsive: true,
                    projection: 'mercator',
                    setProjection: function(element) {
                                    var projection = d3.geo.mercator()
                                  .center([0, padding])
                                  .scale(105)
                                  .translate([element.offsetWidth / 2, element.offsetHeight / 2 - 70]);
                                var path = d3.geo.path()
                                  .projection(projection);
                                return {path: path, projection: projection};
                              },
                    fills: Fills,
                    data: Data
                })
}

您需要渲染地图的代码如下:

$scope.renderMap()

我希望这会有所帮助。

XOXO

答案 1 :(得分:0)

我找到了答案。您必须将变量放在链接函数中。这意味着移动

var containerid = document.getElementById('world-map-container');
var margin = 20,
    padding = 50,
    width = containerid.offsetWidth - margin;
    height = containerid.offsetHeight - margin;

在你的链接功能内。这解决了我的问题。