Loading and parsing TOPOJSON
导入Topojson
d3文件
地址:https://unpkg.com/topojson@3.0.2/dist/topojson.min.js
想要找d3文件的话去unpkg.com好像大部分都能找到的样子
Rendering geographic features
寻找合适的地图数据:谷歌搜索world-atlas npm
,第一个网站点进去,然后选择合适的d3文件。
这个文件里面的地图是Topojson
格式的,想要转化为geojson
需要使用topojson
中的feature
函数,传入两个参数,例如:
json('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json').then(data => { const countries = feature(data, data.objects.countries);console.log(countries); }
然后就可以使用数据,给每个数据添加path
,然后通过设置属性d
进行绘制
Using different map projections
图形的不同关键就在绘制d
的函数的不同。
d3
官网上有许多绘制不同形状地图的函数,可以根据需要选择自己喜欢的。
网址:https://github.com/d3/d3-geo-projection
这里选择的是geoEqualEarth
,这个函数需要从d3文件中导入。于此同时还需要导入geoPath
函数
const projection = geoEqualEarth();
const pathGenerator = geoPath().projection(projection);json('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json').then(data => { const countries = feature(data, data.objects.countries);console.log(countries); svg.selectAll('path').data(countries.features).enter().append('path').attr('class', 'country').attr('d', pathGenerator);});
Rendering the projected sphere outline
然后就是通过设置CSS文件设置颜色,为了让地图的圆形凸显出来,我们要先给边框创建一个path
svg.append('path').attr('class', 'sphere').attr('d', pathGenerator({type:"Sphere"}));
然后在CSS文件中根据设置的类设置颜色:
.country{fill: #15ed76;stroke: black;stroke-opacity: 0.3;
}.sphere{fill: #15beed;
}
Tweaking map styles
最后的图形效果如图:
代码地址:https://vizhub.com/Edward-Elric233/b21d1d4d6db34c9092c3252f39212bda
Highlighting on Hover using CSS
上面的效果已经不错了,但是如果我们想要鼠标放在上面就自动变色的话,我们可以在CSS文件里面添加hover
属性,然后就可以了。
styles.css
.country:hover {
/* 鼠标放在上面可以变色 */fill : red;
}
效果图:
Adding simple tooltips(using )
我们还希望鼠标停留在上面的画可以提示国家的名称,想要做到这点,我们可以给每个path
添加title
,然后设置文本为国家名称即可。例如:
index.js
g.selectAll('path').data(countries.features).enter().append('path').attr('class', 'country').attr('d', pathGenerator).append('title')//添加title,然后鼠标放在上面就可以出现标题.text(d => d.properties.name);
我这里的数据直接就有国家名称,视频中的没有还需要使用tsv
文件查找。如果有需要的话可以看原视频。
Loading multiple data files
Looking up country name from id
Panning & Zooming
当然我们还希望能够放大和缩小,这样才能看到更多的细节。为了实现这个效果,我们要把所有的东西都放到g
上,然后再让svg.call(zoom().on('zoom', callback))
添加鼠标滑轮事件。具体到这里我们希望图像的大小可以跟随滑轮的滚动而变化:
const g = svg.append('g');svg.call(zoom().on('zoom',() => {g.attr('
效果图:
这里的地图应该比上面的清晰许多,是因为这里使用的数据是以10m为单位的,所以分辨率高一点。如果需要的话只需要把最前面地图的topojson
的网址换成10m的即可:https://cdn.jsdelivr.net/npm/world-atlas@2.0.2/countries-10m.json
(比较大,加载稍微有点慢)
视频中的内容到这里就结束了,可是我总觉得这样的颜色有些丑,我想起来在以前做柱状图的时候我嫌弃他的颜色太丑自己做了一个选择颜色的函数,在这里也可以用一下:
let colorSet = ['#eb2617', '#ffaa00', '#4dff00', '#00fbff', '#bb00ff', '#eeff00'];const createGetColor = (idx)=>{var i = idx || -1;return {get : () => {i=(i+1)%colorSet.length; return colorSet[i];}};
};const getColor = createGetColor();
createGetColor
函数会返回一个对象,对象中get
属性为函数,这个函数中使用了外层的变量i
,因此i
不会被释放掉,相当于静态变量,每次调用这个函数这个变量都会加一,起到遍历颜色数组的功能。
在有了这个获取颜色函数以后我们只需要删掉CSS文件中设置地图颜色语句,然后在append
后面设置属性即可。
g.selectAll('path').data(countries.features).enter().append('path').attr('class', 'country').attr('fill', getColor.get).attr('d', pathGenerator).append('title')//添加title,然后鼠标放在上面就可以出现标题.text(d => d.properties.name);
效果图:
颜色选择的有点鲜艳,不过看起来还不错,有点世界地图的感觉。
代码地址:https://vizhub.com/Edward-Elric233/2e91c94015e345afb0c9f3ae6cde412f
感觉这个球体部分地方有些变形,我们可以换一个地图的形状
例如换成geoMercator
: