使用D3创建渐变符号映射

时间:2013-07-31 18:58:13

标签: d3.js

我正在尝试创建一个graduated symbol map,并且正在努力寻找实现这一目标的方法。我可以创建饼图,我可以创建一个符号图,但是如何将饼图放在地图上的特定坐标上?

我已成功将比例符号放在适当的坐标上,但我无法弄清楚如何用饼图替换符号。每次尝试都会留下一张空地图。

我试图将Mike Bostock的Pie Multiples example与他的Symbol Map example合并,但却只是让我对d3的数据和事件功能缺乏了解。

的index.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <title>Graduated Symbol Map</title>
    <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
    <script type="text/javascript" src="http://d3js.org/topojson.v1.min.js"></script>
    <script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script>
    <style type="text/css">

body {
text-align: center;
}

    </style>
</head>
<body>
    <script type="text/javascript">

var width = 400,
    height = 500;

var radius = d3.scale.sqrt()
    .domain([0, 5e5])
    .range([0, 40]);

// Define map projection
var projection = d3.geo.transverseMercator()
    .rotate([72.57, -44.20])
    .translate([175,190])
    .scale([12000]);

// Define path generator
var path = d3.geo.path()
    .projection(projection);

// Create SVG Element
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

queue()
    .defer(d3.json, "vermont.json")
    .defer(d3.json, "fed.json")
    .await(ready)

function ready(error, vt, centroid) {
    svg.append("path")
        .attr("class", "towns")
        .datum(topojson.feature(vt, vt.objects.vt_towns))
        .attr("d", path)
        .style("stroke", "#ddd")
        .style("stroke-width", "1px")
        .style("fill", "#ccc");

    svg.append("path")
        .datum(topojson.feature(vt, vt.objects.lake))
        .attr("d", path)
        .style("stroke", "#89b6ef")
        .style("stroke-width", "1px")
        .style("fill", "#b6d2f5");

    svg.selectAll(".symbol")
        .data(centroid.features.sort(function(a,b) {
            return b.properties.dollars - a.properties.dollars; }))
        .enter().append("path")
            .attr("class", "symbol")
            .attr("d", path.pointRadius(function(d) {
                return radius(d.properties.dollars); })
            )
            .style("fill", "#509e2f")
            .style("stroke", "#ddd")
            .style("fill-opacity", 0.7);
}

    </script>
</body>
</html>        

fed.json(有14个点,全部格式相同)

'美元'是四个组织花费的总金额,饼图的大小应与此值相关。

{
    "type": "Feature",
    "id": "53",
    "geometry": {
        "type": "Point",
        "coordinates": [-73.1349605, 43.0278745]
    },
    "properties": {
        "name": "Bennington County",
        "dollars": 79730,
        "unit": "county",
        "ECP": 49608,
        "LIP": 3451,
        "NAP": 0,
        "SURE": 26671
    }
}, 

vermont.json

大文件,地图不是问题。

我使用的参考资料

1 个答案:

答案 0 :(得分:2)

这是我的解决方案,使用来自this question的@ LarsKotthoff答案来解决预测问题。

我以相当骇人的方式缩放了饼图。

的index.html

以下是就绪功能。其他一切都没有改变。

function ready(error, vt, centroid) {
    svg.append("path")
        .attr("class", "towns")
        .datum(topojson.feature(vt, vt.objects.vt_towns))
        .attr("d", path)
        .style("stroke", "#ddd")
        .style("stroke-width", "1px")
        .style("fill", "#ccc");

    svg.append("path")
        .datum(topojson.feature(vt, vt.objects.lake))
        .attr("d", path)
        .style("stroke", "#89b6ef")
        .style("stroke-width", "1px")
        .style("fill", "#b6d2f5");

    var pieArray = [],
        pieMeta = [];

    function pieData() {
        for (var i=0; i<centroid.features.length; i++) {
            pieArray.push([
                parseInt(centroid.features[i].properties.ECP),
                parseInt(centroid.features[i].properties.LIP),
                parseInt(centroid.features[i].properties.NAP),
                parseInt(centroid.features[i].properties.SURE)
                ]);
            pieMeta.push([
                projection(centroid.features[i].geometry.coordinates),
                radius(parseInt(centroid.features[i].properties.dollars))
                ]);
        }
        return [pieArray, pieMeta];
    };

    var svgSvg = d3.select("body").select("svg").selectAll("g")
            .data(pieData()[0])
        .enter().append("svg:svg")
            .attr("width", width)
            .attr("height", height)
        .append("svg:g")
            .style("opacity", 0.8)
            .attr("property", function (d,i) {
                return pieData()[1][i][1];
            })
            .attr("transform", function (d,i) {
                var coordinates = pieData()[1][i][0];
                return ("translate(" + (coordinates[0]) + "," +
                    (coordinates[1]) + ")");
                });

    svgSvg.selectAll("path")
            .data(d3.layout.pie())
        .enter().append("svg:path")
            .attr("d", d3.svg.arc()
                .innerRadius(0)
                .outerRadius(function (d) {
                    var chartList = d3.select(this.parentNode).attr("property");
                    return chartList;
                }))
            .style("fill", function(d, i) { return color[i]; });

}