docs
使用示例
D3

D3.js

D3.js 支持 GeoJSON 、TopoJSON 、shapefiles 创建地图,同时支持大量的投影及交互效果。

参考文档

示例代码

<div id="container" style="width: 1000px;height: 800px"></div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
    //...
</script>
 
const colors = ["#2caffe", "#544fc5", "#00e272", "#fe6a35", "#6b8abc", "#d568fb", "#2ee0ca", "#fa4b42", "#feb56a", "#91e8e1"];
 
function renderFeature(features, projection, path) {
	features.each(function(f, i) {
		const featureEl = d3.select(this);
		f.color = colors[i%colors.length];
		featureEl.append('path')
			.attr('d', path)
			.attr('fill', f.color)
			.attr('stroke', '#333')
			.attr('stroke-width', 0.5)
			.attr('opacity', 0.5);
		let center = f.properties.center && projection(f.properties.center);
		if(!center) return false;
		featureEl.append('circle')
			.attr('cx', center[0])
			.attr('cy', center[1])
			.attr('r', 3)
			.attr('fill', '#444');
		
		featureEl.append('text')
			.attr('class', 'dataLabels')
			.attr('text-anchor', 'middle')
			.style('fill', '#333')
			.style('font-size', '12px')
			.text((d) => d.properties.name || '')
			.attr('transform', (d) => {
				if(!d.properties.name) return '';
				let center = null;
				let centroid = null;
				if (d.properties.center) {
					center = projection(d.properties.center);
				}
				if (d.properties.centroid) {
					centroid = projection(d.properties.centroid);
				}
				if (!centroid) {
					centroid = path.centroid(d);
				}
				if (!center) {
					return `translate(${centroid.join(',')})`;
				}
				let distance = 20; // 10 pixels
				let angle = Math.atan2(centroid[1] - center[1], centroid[0] - center[0]);
				let newPoint = [center[0] + distance * Math.cos(angle), center[1] + distance * Math.sin(angle)];
				return `translate(${newPoint.join(',')})`;
		})
	})
}
 
 
function createMap(el, mapdata) {
  
	// 生成随机数据
	const size = [
		el.clientWidth,
		el.clientHeight
	];
 
	const svg = d3.select(this.options.el)
		.append('svg')
		.attr('width', this.size[0])
		.attr('height', this.size[1]);
 
	const group = svg.append('g')
            .attr('class', 'features');
	
	const projection = d3.geoMercator().fitSize(size, mapdata);
	const path = d3.geoPath().projection(projection);
	const features = group.selectAll('g')
		.data(mapdata.features)
		.enter()
		.append('g')
		.attr('class', 'feature');
	
	  const zoom = d3.zoom()
            .scaleExtent([0.25, 16])
            .on('zoom', function (event) {
                const isTranslationOnly = event.sourceEvent ? true : false;
                if (isTranslationOnly ) {
                    group.attr('transform', event.transform); // 直接应用变换
                } else {
                    group.transition() // 添加动画
                        .duration(300) // 设置动画持续时间
                        .attr('transform', event.transform); // 应用变换
                }
            });
	
	
	renderFeature(features, projection, path);
	
	svg.call(zoom)
			
}
 
 
fetch('https://geojson.cn/api/china/china.topo.json')
    .then(response => response.json())
    .then(mapdata => {
        createMap(
            document.querySelector('#container'),
            mapdata
        )
    });

示例

基础例子