d3.js是一个JavaScript库,用于根据数据操作文档。d3可以使用HTML、SVG和CSS将数据变为现实。d3对网络标准的强调让你拥有了现代浏览器的全部功能,而不会将自己束缚在专有框架中,将强大的可视化组件和数据驱动的DOM操作方法结合在一起。

最近使用d3做了一个中国地图,也实现了一些交互,所以记录下来:

1.首先得准备一份中国地图的json文件,这里就不提供了,网上可以找到下载链接,也可以参考这个项目

https://github.com/clemsos/d3-china-map

2.这里就不对d3的具体api进行介绍了,直接上源码

<style type="text/css">
    body {
        background: #fdfdfd;
    }
    path {
        stroke-width: 1px;
    }
    .subProvince {
        fill: #fff;
        transform: translate(0, 5px);
    }
    .choose-city {
        fill: #ee9b8a !important;
        stroke: #df9269 !important;
    }
    .thirdProvince {
        fill: #e6f3f3;
        transform: translate(0, 10px);
    }
    .cityExist {
        fill: #daf6f6;
        stroke: #bceaea;
    }
    .cityNoExist {
        fill: #afd8f6;
        stroke: #8ec7e2;
    }
    text {
        font-size: 14px;
        font-weight: 700;
        fill: #56abab;
    }
    .cityExist+text,
    .cityNoExist+text {
        fill: #56abab;
    }
    .choose-city+text {
        fill: #fff;
    }
    .whiteFont {
        fill: #fff !important;
    }
    circle {
        fill: steelblue;
        fill-opacity: .8;
        stroke: #fff;
    }
</style>

// svg元素
<svg width="960" height="960">

</svg>

<script>
    'use strict';
    const d3 = window.d3;

    const mapData = window.map; // 地图数据

    // 选择SVG对象
    const $svg = d3.select('svg');

    // 地图阴影效果
    const $thirdProvince = $svg.append('svg:g')
        .attr('id', 'thirdProvince');
    // 地图阴影效果
    const $subProvince = $svg.append('svg:g')
        .attr('id', 'subProvince');

    const $province = $svg.append('svg:g')
        .attr('id', 'province');

    const width = $svg.attr('width');
    const height = $svg.attr('height');
    // 生成投影函数
    const projection = d3.geoMercator() // 设定经纬度3D转2D算法
        .center([103, 30]) // 设置经纬度中心点
        .scale(850) // 设定标尺
        .translate([width / 2, height / 2]); // 设定转换宽高
    const path = d3.geoPath(projection); // 设置路径转换函数
    // 选中省路径并插入路径数据

    $subProvince.append('path')
        .datum(mapData)
        .attr('d', path)
        .attr('class', 'subProvince');

    $thirdProvince.append('path')
        .datum(mapData)
        .attr('d', path)
        .attr('class', 'thirdProvince');

    const $provinceGraph = $province.selectAll('path')
        .data(mapData.features) // 绑定数据
        .enter() // 获取所有数据
        .append('g')
    $provinceGraph.append('path') // 插入路径
        .attr('d', path) // 使用地理位置生成器
        .attr('data-exist', function (d) { // 插入属性
            return d.properties.exist ? "true" : '';
        })
        .attr('class', function (d) { // 插入属性
            return d.properties.exist ? 'cityExist common-city-class city' + d.properties.id :
                'cityNoExist common-city-class city' + d.properties.id
        });

    $provinceGraph.append('text')
        .attr('transform', function (d) {
            return 'translate(' + projection(d.properties.cp) + ')';
        })
        .attr('dy', '.35em')
        .attr('dx', '-1em')
        .text(function (d) { // 插入名称
            return d.properties.name;
        });

    $('.common-city-class').mouseenter(function () {
        $('.common-city-class').removeClass('choose-city');
        $(this).addClass('choose-city');
    });
</script>

4.以上代码可以直接使用,只需要引入d3 .js以及中国地图的json文件,需要特别注意的是,svg 对象中设置某个元素的样式与css不太相同,比如设置区块填充颜色使用的是fill,其他的可以根据具体的数据设置不同的地图属性,如

$provinceGraph.append('path') // 插入路径
    .attr('d', path) // 使用地理位置生成器
    .attr('data-exist', function (d) { // 插入属性
    return d.properties.exist ? "true" : '';
})
    .attr('class', function (d) { // 插入属性
    return d.properties.exist ? 'cityExist common-city-class city' + d.properties.id :
    'cityNoExist common-city-class city' + d.properties.id
});

这里return d.properties.exist ? 'cityExist common-city-class city' + d.properties.id : 'cityNoExist common-city-class city' + d.properties.id指的是如果属性中有exist属性这返回前者,反之返回后者,这样就方便我们一些实际的项目开发需求,另外最好使用原生js操作svg对象。

关于d3的文档可以参考官网:https://github.com/d3/d3/wiki 也可以看下https://github.com/xswei/d3-selection/blob/master/README.md