因此,我制作了一个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>
以下是首次加载页面时的屏幕截图:
在我从网站的其他模板导航后回到页面后的空容器。
知道发生了什么事吗?
答案 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;
在你的链接功能内。这解决了我的问题。