使用 D3.js 渲染 topoJSON 数据
Render topoJSON data using D3.js
在我的项目中,我尝试使用 d3 和 GeoJSON 显示印度地图。它不能正常工作,我发现很难显示每个印度州。请帮我找出答案,在此先感谢...,
我在代码下面的数据和输出中添加了一个link。
这是我的源代码,我正在使用来自 https://www.covid19india.org/mini_maps/india.json 的数据,我想使用 D3.js
渲染(印度各州)
<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>
我得到这种类型的输出
你能帮帮我吗,有什么问题吗?我是一名学生,正在学习这个。
您好,我曾经有一个名为 covid19news.org 的网站。现在倒下了。我在那里做过类似的工作。代码如下。
<!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>
完整的工作代码在这里。 stackblitz
因为你的JSON已经投影了,你只需要将null
传递给投影:
var path = d3.geo.path()
.projection(null);
这里是你的代码有那个变化:
<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>
提供的答案适用于 D3 v3。
对于寻找 D3 v6 的任何人,下面是解决方案。
Note: in D3 v6 d3.geo.path()
has been changed to d3.geoPath()
// Reference:
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>
在我的项目中,我尝试使用 d3 和 GeoJSON 显示印度地图。它不能正常工作,我发现很难显示每个印度州。请帮我找出答案,在此先感谢..., 我在代码下面的数据和输出中添加了一个link。
这是我的源代码,我正在使用来自 https://www.covid19india.org/mini_maps/india.json 的数据,我想使用 D3.js
渲染(印度各州)<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>
我得到这种类型的输出
你能帮帮我吗,有什么问题吗?我是一名学生,正在学习这个。
您好,我曾经有一个名为 covid19news.org 的网站。现在倒下了。我在那里做过类似的工作。代码如下。
<!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>
完整的工作代码在这里。 stackblitz
因为你的JSON已经投影了,你只需要将null
传递给投影:
var path = d3.geo.path()
.projection(null);
这里是你的代码有那个变化:
<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>
对于寻找 D3 v6 的任何人,下面是解决方案。
Note: in D3 v6
d3.geo.path()
has been changed tod3.geoPath()
// Reference:
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>