关于d3.js:如何使用GeoJSON在d3印度地图中显示每个州名称

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

在我的项目中,我试图使用d3和GeoJSON显示印度地图。 它可以正常工作,但是我发现很难在每个州的顶部显示每个州的名称。 如何找到每个状态的质心。
请帮助我找出答案,在此先感谢...,
在下图中,它显示在左上角。

enter image description here
Index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!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 to hold tooltip. -->
   
    <!-- svg to hold the map. -->
    <!-- <script src="indiaState.js"> -->
    <!-- creates india State. -->
    <script src="d3.v3.min.js">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
   
    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;
            });

    });
   
</body>

</html>

我尝试使用下面的代码,但是它给两个坐标都为NaN,如何解决这个问题...
var projection = d3.geo.mercator()
.scale(1)
.translate([0,0]);

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


由于您的json返回的是实际路径d元素,而不是topojson,因此我将直接在路径上使用getBBox。 我还简化了对路径和文本进行分组的选择:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<!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">
    <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 to hold tooltip. -->
   
    <!-- svg to hold the map. -->
    <!-- <script src="indiaState.js"> -->
    <!-- creates india State. -->
    <!--<script src="d3.v3.min.js">-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
   
    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;
            });
    });
   
  </body>

</html>