MogerCS
MogerCS

Reputation: 342

How to display each state name in d3 india map using GeoJSON

In my project, I am trying to display India map using d3 and GeoJSON. It works properly, but I am finding difficulties to display each state name on top of the respective state. How to find the centroid of each state. Please help me to find out, Thanks in advance...,
In the below image, it is displaying at top left corner.

enter image description here Index.html

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
.state {
    fill: none;
    stroke: #a9a9a9;
    stroke-width: 1;
}

.state:hover {
    fill-opacity: 0.5;
}

#tooltip {
    position: absolute;
    text-align: center;
    padding: 20px;
    margin: 10px;
    font: 12px sans-serif;
    background: lightsteelblue;
    border: 1px;
    border-radius: 2px;
    pointer-events: none;
}

#tooltip h4 {
    margin: 0;
    font-size: 14px;
}

#tooltip {
    background: rgba(0, 0, 0, 0.9);
    border: 1px solid grey;
    border-radius: 5px;
    font-size: 12px;
    width: auto;
    padding: 4px;
    color: white;
    opacity: 0;
}

#tooltip table {
    table-layout: fixed;
}

#tooltip tr td {
    padding: 0;
    margin: 0;
}

#tooltip tr td:nth-child(1) {
    width: 50px;
}

#tooltip tr td:nth-child(2) {
    text-align: center;
}
</style>

<body>
    <div id="tooltip"></div>
    <!-- div to hold tooltip. -->
    <div style="height: 600px;" id="statesvg"></div>
    <!-- svg to hold the map. -->
    <!-- <script src="indiaState.js"></script> -->
    <!-- creates india State. -->
    <script src="d3.v3.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
    function tooltipHtml(n, id, d) { /* function to create html content string in tooltip div. */
        return "<h4>" + id + "</h4>" +
            "<h4>" + n + "</h4>";
    }

    function getRandomColor() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
    var sampleData = {}; /* Sample random data. */
    ["AP", "AR", "AS", "BR", "CT", "DL", "GA", "GJ", "HR", "HP", "JK", "JH", "KA", "KL", "MP", "MH", "MN", "ML", "MZ", "NL", "OR", "PB", "RJ", "SK", "TN", "TR", "UP", "UT", "WB"]
    .forEach(function(d) {
        var low = Math.round(100 * Math.random());
        sampleData[d] = { color: getRandomColor()};
    });

    /* draw states on id #statesvg */
    //iStates.draw("#statesvg", sampleData, tooltipHtml);

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

    d3.json("county.json", function(json) {
        console.log(json)
        var projection = d3.geo.mercator()
            .scale(1)
            .translate([0, 0]);

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

        function mouseOver(d) {

            d3.select("#tooltip").transition().duration(200).style("opacity", .9);
            d3.select("#tooltip").html(tooltipHtml(d.n, d.id, sampleData[d.id]))
                .style("left", (d3.event.layerX) + "px")
                .style("top", (d3.event.layerY) + "px");
        }

        function mouseOut() {

            d3.select("#tooltip").transition().duration(500).style("opacity", 0);
        }

        function Click(d) {
            delete d.d
            console.log(d)
        }

        var svg = d3.select("#statesvg")
            .append("svg")
            .attr("width", "100%")
            .attr("height", "100%")
            .append("g");


        svg.selectAll(".state")
            .data(json)
            .enter()
            .append("path")
            .attr("class", "state")
            .attr("d", function(d) {

                return d.d;
            })
            .style("fill", function(d) {
                return sampleData[d.id].color;
            })
            .on("mousemove", mouseOver).on("mouseout", mouseOut).on("click", Click);

        svg.selectAll("text")
            .data(json)
            .enter()
            .append("text")
            .attr("fill", "black")
            .attr("x", function(d) {
                return path.centroid(d.d)[0];
            })
            .attr("y", function(d) {
                return path.centroid(d.d)[1];
            })
            .attr("text-anchor", "middle")
            .attr("dy", ".35em")
            .text(function(d) {
                return d.id;
            });

    });
    </script>
</body>

</html>

I tried using below code, but its giving both cordinates as NaN, how to solve this... var projection = d3.geo.mercator() .scale(1) .translate([0, 0]);

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

Upvotes: 1

Views: 6972

Answers (1)

Mark
Mark

Reputation: 108537

Since your json is returning the actual path d element and not topojson, I'd just use getBBox on the path directly. I also simplified your selections to group the path and the text:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <script data-require="[email protected]" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
    <style>
.state {
    fill: none;
    stroke: #a9a9a9;
    stroke-width: 1;
}

.state:hover {
    fill-opacity: 0.5;
}

#tooltip {
    position: absolute;
    text-align: center;
    padding: 20px;
    margin: 10px;
    font: 12px sans-serif;
    background: lightsteelblue;
    border: 1px;
    border-radius: 2px;
    pointer-events: none;
}

#tooltip h4 {
    margin: 0;
    font-size: 14px;
}

#tooltip {
    background: rgba(0, 0, 0, 0.9);
    border: 1px solid grey;
    border-radius: 5px;
    font-size: 12px;
    width: auto;
    padding: 4px;
    color: white;
    opacity: 0;
}

#tooltip table {
    table-layout: fixed;
}

#tooltip tr td {
    padding: 0;
    margin: 0;
}

#tooltip tr td:nth-child(1) {
    width: 50px;
}

#tooltip tr td:nth-child(2) {
    text-align: center;
}
    </style>
  </head>

  <body>
    <div id="tooltip"></div>
    <!-- div to hold tooltip. -->
    <div style="height: 600px;" id="statesvg"></div>
    <!-- svg to hold the map. -->
    <!-- <script src="indiaState.js"></script> -->
    <!-- creates india State. -->
    <!--<script src="d3.v3.min.js"></script>-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
    function tooltipHtml(n, id, d) { /* function to create html content string in tooltip div. */
        return "<h4>" + id + "</h4>" +
            "<h4>" + n + "</h4>";
    }

    function getRandomColor() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
    var sampleData = {}; /* Sample random data. */
    ["AP", "AR", "AS", "BR", "CT", "DL", "GA", "GJ", "HR", "HP", "JK", "JH", "KA", "KL", "MP", "MH", "MN", "ML", "MZ", "NL", "OR", "PB", "RJ", "SK", "TN", "TR", "UP", "UT", "WB"]
    .forEach(function(d) {
        var low = Math.round(100 * Math.random());
        sampleData[d] = { color: getRandomColor()};
    });

    /* draw states on id #statesvg */
    //iStates.draw("#statesvg", sampleData, tooltipHtml);

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

    d3.json("https://api.myjson.com/bins/l36bq", function(json) {
        //console.log(json)
        var projection = d3.geo.mercator()
            .scale(1)
            .translate([0, 0]);

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

        function mouseOver(d) {

            d3.select("#tooltip").transition().duration(200).style("opacity", .9);
            d3.select("#tooltip").html(tooltipHtml(d.n, d.id, sampleData[d.id]))
                .style("left", (d3.event.layerX) + "px")
                .style("top", (d3.event.layerY) + "px");
        }

        function mouseOut() {

            d3.select("#tooltip").transition().duration(500).style("opacity", 0);
        }

        function Click(d) {
            delete d.d
            console.log(d)
        }

        var svg = d3.select("#statesvg")
            .append("svg")
            .attr("width", "100%")
            .attr("height", "100%")
            .append("g");


        var eS = svg.selectAll(".state")
            .data(json)
            .enter()
            .append("g");
            
        eS.append("path")
            .attr("class", "state")
            .attr("d", function(d) {
                return d.d;
            })
            .style("fill", function(d) {
                return sampleData[d.id].color;
            })
            .on("mousemove", mouseOver).on("mouseout", mouseOut).on("click", Click)
            
        eS.append("text")
            .attr("fill", "black")
            .attr("transform", function(d) {
                var bbox = this.previousSibling.getBBox();
                return "translate(" + (bbox.x + bbox.width/2) + "," + (bbox.y + bbox.height/2) + ")";
            })
            .attr("text-anchor", "middle")
            .attr("dy", ".35em")
            .text(function(d) {
                return d.id;
            });
    });
    </script>
  </body>

</html>

Upvotes: 4

Related Questions