gpt4 book ai didi

d3.js - 如何根据纬度/经度在 D3 map 上的两点之间绘制一条线/链接?

转载 作者:行者123 更新时间:2023-12-03 13:57:23 26 4
gpt4 key购买 nike

我正在尝试在 D3 中创建 10 个主要 NASA 设施的 map 。我已经成功地生成了美国的基本 map ,并根据带有纬度和经度的 .csv 在每个中心位置附加了 NASA Logo 。但是,我想不出任何优雅的方式来在 map 上的点之间绘制线/链接/弧/连接。

在下面的代码中,我在 GSFC 和 KSC 之间画了一条线(使用 'var = places'、'var = route' 和 'svg.append("path")'),但它位于 SVG 层上,所以它位于 Logo 顶部(看起来很糟糕)并且在单击放大状态时不会缩放(或者消失也可以)。我希望能够根据 .csv 中的纬度和经度数据在中心之间绘制链接。

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.background {
fill: none;
pointer-events: all;
}

#states {
fill: #aaaaaa;
}

#states .active {
fill: #ff0000;
fill-opacity: .5;
}

#state-borders {
fill: none;
stroke: #ffffff;
stroke-width: 1.5px;
stroke-linejoin: round;
stroke-linecap: round;
pointer-events: none;
}

path.link {
fill: none;
stroke: #666666;
stroke-width: 1.5px;
}

.stroke {
fill: none;
stroke: #000;
stroke-width: 3px;
}

.fill {
fill: #fff;
}

.graticule {
fill: none;
stroke: #777;
stroke-width: .5px;
stroke-opacity: .5;
}

.route {
fill: none;
stroke: blue;
stroke-width: 3px;
}

</style>
<body>
<h2>
<span>NASA Centers</span>
</h2>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>

var width = 1000,
height = 600,
centered;

var projection = d3.geo.albersUsa()
.scale(1070)
.translate([width / 2, height / 2]);

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

var graticule = d3.geo.graticule();

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

var g = svg.append("g");

var places = {
GSFC: [-76.852587, 38.991621],
KSC: [-80.650813, 28.524963]
};

var route = {
type: "LineString",
coordinates: [
places.GSFC,
places.KSC
]
};

var point = svg.append("g")
.attr("class", "points")
.selectAll("g")
.data(d3.entries(places))
.enter().append("g")
.attr("transform", function(d) { return "translate(" + projection(d.value) + ")"; });

point.append("text")
.attr("y", 5)
.attr("dx", "1em")
.text(function(d) { return d.key; });

d3.json("us.json", function(error, us) {
g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path)
.on("click", clicked);

g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("id", "state-borders")
.attr("d", path);

d3.csv("nasacenters.csv", function(error, data) {
g.selectAll("image").data([0])
.data(data)
.enter()
.append("image")
.attr("xlink:href", "nasalogo.png")
.attr("width", "30")
.attr("height", "30")
.attr("x", function(d) {
return projection([d.lon, d.lat])[0]-15;
})
.attr("y", function(d) {
return projection([d.lon, d.lat])[1]-15;
})

svg.append("path")
.datum(route)
.attr("class", "route")
.attr("d", path)
.style("opacity", 0.5);

});

});

function clicked(d) {
var x, y, k;

if (d && centered !== d) {
var centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}

g.selectAll("path")
.classed("active", centered && function(d) { return d === centered; });

g.transition()
.duration(750)
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
}

</script>
</body>
</html>

.csv 文件采用以下格式:
code,center,lat,lon
GSFC,Goddard Space Flight Center,38.991621,-76.852587
KSC,Kennedy Space Center,28.524963,-80.650813
JPL,Jet Propulsion Laboratory,34.200463,-118.176008
DFRC,Dryden Flight Research Center,34.613714,-118.076790
GRC,Glenn Research Center,41.415891,-81.861774
MSFC,Marshall Space Flight Center,34.646554,-86.674368
ARC,Ames Research Center,37.409574,-122.064292
LaRC,Langley Research Center,37.092123,-76.376230
JSC,Johnson Space Center,29.551508,-95.092256
SSC,Stennis Space Center,30.363692,-89.600036

最佳答案

我根据您描述的问题稍微修改了您的示例:http://bl.ocks.org/erikhazzard/6201948

看起来有三个问题:

  • 路径绘制在图标上 .要解决此问题,您可以更改将项目添加到组的顺序,或将子组添加到主组 g组,确保您添加组的顺序与您希望事物出现的顺序相匹配。
  • 缩放 map 时,点之间的路径不会缩放 .要解决此问题,请确保将所有内容添加到您正在修改 clicked() 函数的组中。在这种情况下,您的 g组正在放大,所以如果您将路径添加到 g组而不是 svg路径也会直接缩放。在提供的示例中,文本也不会放大 - 这是因为它直接添加到 SVG 而不是 g正在转型的群体。
  • 路径不是从数据中自动创建的 .要解决此问题,您可以从数据中生成一个包含 LineString 对象的数组。例如,
        for(var i=0, len=data.length-1; i<len; i++){
    // (note: loop until length - 1 since we're getting the next
    // item with i+1)
    links.push({
    type: "LineString",
    coordinates: [
    [ data[i].lon, data[i].lat ],
    [ data[i+1].lon, data[i+1].lat ]
    ]
    });
    }

    然后,执行标准数据连接模式并传入 links列出数据。当你传入path作为 d属性,它将根据每个项目的坐标生成一个很大的弧:
    // Standard enter / update 
    var pathArcs = arcGroup.selectAll(".arc")
    .data(links);

    //enter
    pathArcs.enter()
    .append("path").attr({
    'class': 'arc'
    }).style({
    fill: 'none',
    });

    //update
    pathArcs.attr({
    //d is the points attribute for this path, we'll draw
    // an arc between the points using the arc function
    d: path
    })
    .style({
    stroke: '#0000ff',
    'stroke-width': '2px'
    })

  • 在我的示例 ( http://bl.ocks.org/enoex/6201948) 中,我在大弧路径上添加了一个过渡,以说明如何根据传递给链接对象的坐标对的顺序来绘制路径。

    希望有帮助!

    关于d3.js - 如何根据纬度/经度在 D3 map 上的两点之间绘制一条线/链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18165533/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com