0

因此,我制作了一个 Angular 指令,它在 HTML 模板中呈现 D3 数据图。我通过“数据”属性将数据传递给指令。我面临的问题是第一次加载页面时地图显示完美。但是,当我通过从其他模板导航(通过“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>

这是第一次加载页面时的屏幕截图:

第一次加载页面/网站时

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

应包含 svg 的空容器

知道发生了什么吗?

4

2 回答 2

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

于 2015-06-08T14:02:35.793 回答
0

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

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

就在您的链接功能内。这为我解决了这个问题。

于 2018-03-11T05:58:31.673 回答