Change color on a map D3

◇◆丶佛笑我妖孽 提交于 2021-02-07 14:51:47

问题


I'm a beginner in Js and I'm trying to change the color of a specific country (function colorCountry) by its Id using D3.js. However, doesn't matter what color I choose. The result will always show the map highlighted in orange. What could I do to solve this?

My code follows below.

Thanks.

The json file can be downloaded here - 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>

回答1:


I am not very familiar with d3, but there seem to be too many ifs in this line:

.style("fill", function(d) { if (d.id == countryCode) { return color(colorCountry(d, d.id));} });

would be simpler if you just do this:

.style("fill", colorCountry);

and change your colorCountry function to

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

or simply get rid of the colorCountry function all together and use this

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

But why wouldn't you just update the JSON data?




回答2:


Instead of doing this to country path:

.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.
    }
}); 

Do this

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

Working code here.



来源:https://stackoverflow.com/questions/36672732/change-color-on-a-map-d3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!