Javascript 通过d3js绘制圆并转换坐标
我有以下d3js代码,它通过Javascript 通过d3js绘制圆并转换坐标,javascript,html,d3.js,Javascript,Html,D3.js,我有以下d3js代码,它通过d3.json和renderMap函数基于geojson绘制国家地图。我想将城市添加到地图中,并将其表示为圆形。城市将与国家地图位于同一svg中。 城市位于ua\u Cities\u admin.csv中,并通过renderCity功能进行渲染 我不了解的是如何将renderCity中的数据数组放置在svg组件中,以及如何将城市坐标映射到国家地图 在此方面的任何帮助都将不胜感激 <!DOCTYPE html> <meta charset="
d3.json
和renderMap
函数基于geojson绘制国家地图。我想将城市添加到地图中,并将其表示为圆形。城市将与国家地图位于同一svg中。
城市位于ua\u Cities\u admin.csv
中,并通过renderCity
功能进行渲染
我不了解的是如何将renderCity
中的数据数组放置在svg组件中,以及如何将城市坐标映射到国家地图
在此方面的任何帮助都将不胜感激
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<title>geoPath measures</title>
</head>
<body>
<div align="center">
<svg id="my_dataviz"></svg>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>
<script>
var height = window.innerHeight - 100;
var width = window.innerWidth - 100;
var svg = d3.select('#my_dataviz')
.attr("width", width)
.attr("height", height);
function renderMap(data) {
var projection = d3.geoIdentity().reflectY(true).fitSize([width, height], data)
var geoGenerator = d3.geoPath().projection(projection);
svg.append("g")
.selectAll("path")
.data(data.features)
.enter()
.append('path')
.attr('d', geoGenerator)
.attr('fill', 'steelblue');
};
function renderCity(data) {
var projection = d3.geoIdentity().reflectY(true).fitSize([width, height], data)
console.log(data)
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", 3);
};
d3.json('https://raw.githubusercontent.com/EugeneBorshch/ukraine_geojson/master/Ukraine.json', renderMap);
d3.csv('ua_cities_admin.csv', renderCity);
</script>
</body>
</html>
地质路径措施
变量高度=window.innerHeight-100;
变量宽度=window.innerWidth-100;
var svg=d3.select('my#u dataviz')
.attr(“宽度”,宽度)
.attr(“高度”,高度);
函数renderMap(数据){
var projection=d3.geointity().reflectY(true).fitSize([width,height],data)
var geoGenerator=d3.geoPath().projection(projection);
svg.append(“g”)
.selectAll(“路径”)
.数据(数据.特征)
.输入()
.append('路径')
.attr('d',地球发电机)
.attr('fill','steelblue');
};
函数呈现(数据){
var projection=d3.geointity().reflectY(true).fitSize([width,height],data)
console.log(数据)
svg.selectAll(“圆圈”)
.数据(数据)
.输入()
.附加(“圆圈”)
.attr(“cx”,50)
.attr(“cy”,50)
.attr(“r”,3);
};
d3.json('https://raw.githubusercontent.com/EugeneBorshch/ukraine_geojson/master/Ukraine.json,renderMap);
d3.csv(“ua_cities_admin.csv”,renderCity);
ua_cities_admin.csv文件包含以下字段:
城市
lat
- 液化天然气
- 您有两个输入数据集,包括地理数据、geojson文件和csv文件。两者都使用经纬度作为坐标系
- 您希望投影它们,但希望它们共享相同的投影坐标系,以便它们彼此对齐 但是,如果使用两个不同的投影,则无法获得对齐:两个输入数据集中的任何公共坐标都将通过每个不同的投影进行不同的投影 解决此问题的最简单方法是对两个数据集重复使用相同的投影,并使用地理投影,例如:
- 以下是您的前提:
var projection = d3.geoMercator()
var geoGenerator = d3.geoPath().projection(projection);
function renderMap(data) {
projection.fitSize([width, height], data)
svg.append("g")
.selectAll("path")
.data(data.features)
.enter()
.append('path')
.attr('d', geoGenerator)
.attr('fill', 'steelblue');
};
function renderCity(data) {
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", d=>projection([d.lon,d.lat])[0])
.attr("cy", d=>projection([d.lon,d.lat])[1])
.attr("r", 3);
};
d3.json("file", function(geojson) {
d3.csv("file", function(csv) {
renderMap(geojson);
renderCity(csv);
})
})
我嵌套了您的请求,因为否则,首先加载的文件将首先绘制。我们还需要首先加载geojson来设置用于csv圆的投影数据
附加细节 Projection.fitSize() 作为参考,
projection.fitSize()
需要有效的geojson对象。d3.csv生成的数据是一个对象数组。如果希望fitSize
工作,我们需要将其转换为geojson。Geojson点功能如下所示:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [longitude, latitude]
},
"properties": { /* ... */ }
}
因此,要创建geojson,我们需要稍微处理一下您的数据:
var features = data.map(function(d) {
return {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [d.lng, d.lat]
},
"properties": { "name":d.city }
}
})
但我们确实需要传递对象,而不是数组,因此我们需要创建geojson功能集合:
var featureCollection = { type:"FeatureCollection", features:features }
投影与身份对比
与d3.geoIdentity不同,d3.geoProjection可以向project传递坐标。geoIdenity可以工作,但是对上面的代码进行了一些调整;但是,它可能会导致感兴趣区域的形状异常或不熟悉的表示,因为它基本上实现了板卡里投影:lat/long被视为平面,并适当缩放/平移到中心,并适当调整地图大小。d3.1地质投影可能适用于此处,投影也允许使用fitSize()
如果希望获得与d3.geoIdentity相同的形状,可以在上面的代码中使用d3.GeoEqui矩形()代替d3.geoMercator
手动设置投影参数
fitSize()设置标识/投影的比例和平移-仅此而已
您可以只定义一次投影,而不是在加载数据后等待重新定义其参数。如果数据是静态的,您可以在运行
fitSize()
后,通过记录projection.scale()
和projection.translate()
来提取fitSize()
使用的比例和转换值,然后使用这些值设置投影比例并自行转换。这可能意味着您无需等待geojson加载后再绘制任何圆(前提是您确保没有在圆的顶部绘制geojson)。谢谢您的回答。但是我得到了以下错误:Uncaught TypeError:投影不是一个函数我找不到解决方案。今晚晚些时候将生成一个工作片段我的错误,在定位上出错(需要在函数中嵌套投影),还需要使用d3投影(不是标识)如果我们想得到一个调整最少的解决方案。还有例子,谢谢安德鲁·里德!我真的很感谢你的帮助!