我正在尝试使用世界其他地区的其他数据点来创建世界地图的裂框d3视觉效果。基本上,应该使世界地图在页面下垂直方向重复几次,每张地图突出显示不同的大陆。这是我的代码:
svg.selectAll('.cont')
.data(data)
.attr('class','cont')
.enter()
.append('g');
问题在于我无法弄清楚如何像通常使用以下方法那样重复地图:
data
可以将多个svg对象绑定到数据(例如,将文本放入rect或将rect放入圆圈等)。因为我必须用绘制地图所需的topojson数据覆盖变量g
。我当时以为我可以打两个数据电话,但这没用。您可能会从上面的代码中注意到,只绘制了一张地图。
我可以以某种方式存储topojson几何,以便可以将其附加到{{1}}上以用于分割框架图吗?在这里,每张地图的背景都是不同的大陆(蓝色)。
答案 0 :(得分:2)
这是附加多个SVG的解决方案。这种方法的优势在于,您可以将每个SVG封装在一个div中,这样就可以轻松地垂直分布(例如,使用flex
)。为简便起见,在这里,我只是使用display: block;
。
您有两个输入选择:SVG输入选择使用您的data
变量:
var svg = d3.select("body").selectAll(null)
.data(data)
.enter()
.append('svg')
.attr('width', 300)
.attr('height', 150)
然后,在每个SVG中,路径输入选择将使用下载的拓扑数据(此处重命名为mapData
):
var map = svg.selectAll(null)
.data(continents)
.enter()
.append('path')
.attr('class', 'continent')
.attr('d', path)
唯一复杂的部分是从父级获取数据。可以使用局部变量each
完成,或者在此解决方案中,可以使用this.parentNode
完成:
map.style('fill', function(d) {
var thisContinent = d3.select(this.parentNode).datum().continent;
if (d.properties.continent === thisContinent) {
return "#003366";
} else {
return "none";
}
});
这是演示 * :
svg {
border: 1px solid gray;
margin-bottom: 6px;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
</head>
<body>
<script>
var projection = d3.geoMercator().rotate([-10, 0]).scale(50).translate([160, 100]);
var path = d3.geoPath().projection(projection);
var data = [{
'continent': 'Asia',
't1fg': 19,
't2fg': 24,
't1fc': 758,
't2fc': 773
},
{
'continent': 'Europe',
't1fg': 6,
't2fg': 37,
't1fc': 234,
't2fc': 241
},
{
'continent': 'North America',
't1fg': 20,
't2fg': 60,
't1fc': 102,
't2fc': 102
},
{
'continent': 'South America',
't1fg': -2,
't2fg': 22,
't1fc': 1,
't2fc': 1
},
{
'continent': 'Other',
't1fg': 3,
't2fg': 4,
't1fc': 5,
't2fc': 5
},
];
var topoData = d3.json("https://piwodlaiwo.github.io/topojson//world-continents.json");
topoData.then(function(mapData) {
var svg = d3.select("body").selectAll(null)
.data(data)
.enter()
.append('svg')
.attr('width', 300)
.attr('height', 150)
.style("display", "block")
var continents = topojson.feature(mapData, mapData.objects.continent).features;
var map = svg.selectAll(null)
.data(continents)
.enter()
.append('path')
.attr('class', 'continent')
.attr('d', path)
.style('stroke', "#a6a6a6")
.style('fill', function(d) {
var thisContinent = d3.select(this.parentNode).datum().continent;
if (d.properties.continent === thisContinent) {
return "#003366";
} else {
return "none";
}
});
})
</script>
</body>
*使用我发现的here
拓扑