在地图D3上更改颜色

时间:2016-04-17 04:38:17

标签: javascript json d3.js

我是Js的初学者,我正在尝试使用D3.js更改其ID的特定国家/地区(函数 colorCountry )的颜色。但是,我选择的颜色并不重要。结果将始终显示以橙色突出显示的地图。我该怎么做才能解决这个问题?

我的代码如下。

感谢。

json文件可以在这里下载 - https://gist.githubusercontent.com/d3noob/5193723/raw/6e1434b2c2de24aedde9bcfe35f6a267bd2c04f5/world-110m2.json

<!DOCTYPE html>
<meta charset="utf-8">
<style>

    body {
        background: #fcfcfa;
    }

    .stroke {
        fill: none;
        stroke: #000;
        stroke-width: 3px;
    }

    .fill {
        fill: #fff;
    }

    .graticule {
        fill: none;
        stroke: #777;
        stroke-width: .5px;
        stroke-opacity: .5;
    }

    .land {
        fill: #888;
    }

    .boundary {
        fill: none;
        stroke: #fff;
        stroke-width: .5px;
    }

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

    var countryCode = 840;   //36: AUSTRALIA * 643: RUSSIA * 76: BRAZIL * 840: USA

    var width = 960,
            height = 580;

    var color = d3.scale.category10();

    var projection = d3.geo.mercator()
            .scale(170)
            .translate([width / 2, height / 2])
            .precision(.1);

    var path = d3.geo.path()
            .projection(projection);

    var graticule = d3.geo.graticule();

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

    svg.append("defs").append("path")
            .datum({type: "Sphere"})
            .attr("id", "sphere")
            .attr("d", path);

    svg.append("use")
            .attr("class", "stroke")
            .attr("xlink:href", "#sphere");

    svg.append("use")
            .attr("class", "fill")
            .attr("xlink:href", "#sphere");

    svg.append("path")
            .datum(graticule)
            .attr("class", "graticule")
            .attr("d", path);



    d3.json("world-110m2.json", function(error, world) {
        if (error) throw error;

        var countries = topojson.feature(world, world.objects.countries).features,
                neighbors = topojson.neighbors(world.objects.countries.geometries);
        svg.selectAll(".country")
                .data(countries)
                .enter().insert("path", ".graticule")
                .attr("class", "country")
                .attr("d", path)
                .style("fill", function(d) { if (d.id == countryCode) { return color(colorCountry(d, d.id));} });

        svg.insert("path", ".graticule")
                .datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
                .attr("class", "boundary")
                .attr("d", path);

        console.log("value : " + countries[99].id);
        console.log("value : " + countries[12].id);
        console.log("value : " + countries[108].color);

    });

    /*HERE*/
    function colorCountry(country, countryId) {
        if (country.id == countryId) {
            return color(country.color = "#FF0000");
        }
    }

    d3.select(self.frameElement).style("height", height + "px");

</script>

2 个答案:

答案 0 :(得分:1)

而不是这样做到国家路径:

.style("fill", function(d) {
    if (d.id == countryCode) { //there is no need for a condition.
        return color(colorCountry(d, d.id));//this is buggy, not clear what you trying to achieve. Color scale already return a color for the country id.
    }
}); 

这样做

.style("fill", function(d) {return color( d.id); });

工作代码here

答案 1 :(得分:0)

我对d3不是很熟悉,但这一行似乎有太多if

.style("fill", function(d) { if (d.id == countryCode) { return color(colorCountry(d, d.id));} });
如果您这样做,

会更简单:

.style("fill", colorCountry);

并将您的colorCountry功能更改为

function colorCountry(country) {
    if (country.id == countryCode) {
        return '#FF0000';
    } else {
        return color(country.id);
    }
}

或者只是简单地删除colorCountry函数并使用此

.style("fill", function(d) {
    return (d.id == countryCode) ? '#FF0000' : color(d.id);
});

但为什么你不能更新JSON数据呢?