简体   繁体   English

使用 D3.js 渲染 topoJSON 数据

[英]Render topoJSON data using D3.js

In my project, I am trying to display the India map using d3 and GeoJSON.在我的项目中,我尝试使用 d3 和 GeoJSON 显示 India map。 It does not work properly, I am finding it difficult to display each Indian state.它不能正常工作,我发现很难显示每个印度 state。 Please help me to find out, thanks in advance..., I have added a link to the data and output below the code.请帮我找出来,提前谢谢...,我在代码下面添加了数据和output的链接。

This is my source code and I am using data from https://www.covid19india.org/mini_maps/india.json and I want to render (Indian states) using D3.js这是我的源代码,我正在使用来自https://www.covid19india.org/mini_maps/india.json的数据,我想使用 Z70F99800D4B03F4FE3CB9915FD 渲染(印度各州)

 <html> <head> <meta charset="utf-8"> <title>A D3 map using topojson</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script> <link href="http://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css"> <style> path { fill: #ccc; stroke: #fff; stroke-width: .5px; } path:hover { fill: red; } </style> </head> <body> <script> var width = 900, height = 600; var path = d3.geo.path(); var svg = d3.select("body").append("svg").attr("width", width).attr("height", height); queue().defer(d3.json, "https://www.covid19india.org/mini_maps/india.json").await(ready); function ready(error, counties) { svg.append("g").selectAll("path").data(topojson.feature(counties, counties.objects.ele).features).enter().append("path").attr("d", path).attr("class", "state"); } </script> </body> </html>

I am getting this type of output我得到这种类型的 output

代码输出

Can you please help me, what is the problem?你能帮我吗,有什么问题吗? I am a student and learning this.我是一名学生,正在学习这个。

Since your JSON is already projected, you just need to pass null to the projection:由于您的 JSON 已经投影,您只需将null传递给投影:

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

Here is your code with that change:这是您进行更改的代码:

 <html> <head> <meta charset="utf-8"> <title>A D3 map using topojson</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script> <link href="http://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css"> <style> path { fill: #ccc; stroke: #fff; stroke-width: .5px; } path:hover { fill: red; } </style> </head> <body> <script> var width = 900, height = 600; var path = d3.geo.path().projection(null); var svg = d3.select("body").append("svg").attr("width", width).attr("height", height); queue().defer(d3.json, "https://www.covid19india.org/mini_maps/india.json").await(ready); function ready(error, counties) { svg.append("g").selectAll("path").data(topojson.feature(counties, counties.objects.states).features).enter().append("path").attr("d", path).attr("class", "state"); } </script> </body> </html>

Hi I used to have a website called covid19news.org.嗨,我曾经有一个名为 covid19news.org 的网站。 Which is now down.现在已经下降了。 There I have worked on something similar.在那里我做过类似的事情。 the code is like below.代码如下。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    #map    { position: relative; min-height: 500px;  
       width: 800px;
    height: 770px;
    background-color: white;
}

.district, .disputed, .state rect, .state path { stroke: #a9a9a9; stroke-width: 1px; }

.district:hover { stroke: #777777; stroke-width: 1px; fill-opacity: .7; }
.state:hover rect { stroke: #777777; stroke-width: 2px; fill-opacity: .7; }
.state:hover path { fill-opacity: .7; }

#select {
    position:absolute;
    left: 500px;
    top: 100px;
        font: 12px sans-serif;
        color: #333;
}

#tooltip h3 {
        margin:2px;
        font-size:14px;
}
#tooltip h4 {
        margin:2px;
        font-size:10px;
}
#tooltip {
        position: absolute;           
        background:rgba(0,0,0,0.8);
        text-align: left;
        border:1px;
        border-radius:5px;
        font: 12px sans-serif;        
        width:auto;
        padding:4px;
        color:white;
        opacity:0;
        pointer-events: none;         
}
#tooltip table{
        table-layout:fixed;
}
#tooltip tr td{
        padding:2px;
        margin:0;
}
</style>
</head>
<body>
        <div id="map">
        </div>
    <script src="./topo/d3.v3.min.js" charset="utf-8"></script>
    <script src="./topo/d3-queue.v3.min.js"></script>
    <script src="./topo/topojson.v1.min.js"></script>
    <script>
    function districtMap(districts, disputed) {

var width  = 800, height = 700, scale = 1200;
var propTag = 'zone', ttName = 'Zone', unit = '';
var extraTop = 0, extraLeft = 0;
function render(selection) {
  selection.each(function() {

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

    d3.select(this).select("#tooltip").remove();
    d3.select(this).append("div").attr("id", "tooltip").style("opacity", 1);

    var projection = d3.geo.mercator()
        .center([83, 23])
        .scale(scale)
        .translate([width / 2, height / 2]);

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

    svg.selectAll(".district")
        .data(districts.features)
      .enter().append("path")
        .attr("class", "district")
        .style("fill", function(d) { return 'd.properties.zone.toLowerCase();' })
        .attr("d", path)
      .on("mouseover", function(d) {      
             d3.select("#tooltip").transition()        
                .duration(200)      
                .style("opacity", .9);     
             d3.select("#tooltip").html("<h3>"+(d.id)+"</h3><h4>("+(d.properties.NAME_1)+")</h4><table>"+
                      "<tr><td>"+ttName+"::</td><td>"+(d.properties[propTag])+"</td></tr>"+
                      "</table>")
                .style("left", (d3.event.pageX-document.getElementById('map').offsetLeft - extraLeft) + "px") 
                .style("top", (d3.event.pageY-document.getElementById('map').offsetTop - 160 - extraTop) + "px");
      })  
      .on("mouseout", function(d) {       
             d3.select("#tooltip").transition()        
                .duration(500)      
                .style("opacity", 1);   
      });
      
    svg.selectAll(".disputed")
        .data(disputed.features)
      .enter().append("path")
        .attr("class", "disputed")
        .style("fill", function(d) { return d.color; })
        .attr("d", path);

  });
} // render
render.height = function(value) {
            if (!arguments.length) return height;
            height = value;
            return render;
        };
render.width = function(value) {
            if (!arguments.length) return width;
            width = value;
            return render;
        };
render.scale = function(value) {
            if (!arguments.length) return scale;
            scale = value;
            return render;
        };
render.propTag = function(value) {
            if (!arguments.length) return propTag;
            propTag = value;
            return render;
        };
render.ttName = function(value) {
            if (!arguments.length) return ttName;
            ttName = value;
            return render;
        };
render.unit = function(value) {
            if (!arguments.length) return unit;
            unit = value;
            return render;
        };

return render;
} // districtMap
    (function() {
    d3.queue()
        .defer(d3.json, "./topo/zone-data.json")
        .defer(d3.json, "./topo/Kashmir.json")
        .await(function(error, topoMain, topoKashmir) {
            var districts, disputed;
            if (error) throw error;
            districts   = topojson.feature(topoMain, topoMain.objects.IND_adm2);
            disputed    = topojson.feature(topoKashmir, topoKashmir.objects.ne_10m_admin_0_Kashmir_Occupied);
            colorDisputed(disputed.features);

            // Map render
            var map     = districtMap(districts, disputed).width(800).height(700).scale(1200); //.propTag(filter);
          
            d3.select("#map").call(map);
       
        });
}());
          

function colorDisputed(data) {
    var color         = "#eaeafa";
    data.forEach(function(d) { 
        d.color       = color;
    });
}
    </script>
</body>
</html>

Full working code is here.完整的工作代码在这里。 stackblitz 堆栈闪电战

The answer provided by @Gerardo above is for D3 v3.上面@Gerardo提供的答案适用于 D3 v3。

For anyone looking for the D3 v6, below is the solution.对于寻找 D3 v6 的任何人,以下是解决方案。

Note: in D3 v6 d3.geo.path() has been changed to d3.geoPath()注意:在 D3 v6 中d3.geo.path()已更改为d3.geoPath()

 // Reference: https://stackoverflow.com/a/66622694/6908282 var width = 900, height = 600; var path = d3.geoPath().projection(null); var svg = d3.select("body").append("svg").attr("width", width).attr("height", height); fetch("https://www.covid19india.org/mini_maps/india.json").then(response => response.json()).then(json => { svg.append("g").selectAll("path").data(topojson.feature(json, json.objects.states).features).enter().append("path").attr("d", path).attr("class", "state"); });
 path { fill: #ccc; stroke: #fff; stroke-width: .5px; } path:hover { fill: red; }
 <script src="https://d3js.org/d3.v6.min.js"></script> <script src="https://unpkg.com/topojson@3"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM