gpt4 book ai didi

javascript - 如何防止新元素覆盖 d3.js 中的现有元素?

转载 作者:行者123 更新时间:2023-11-28 01:11:11 25 4
gpt4 key购买 nike

我正在玩mbostock's example of using d3.js with google maps ,尝试用我自己的数据的二维数组来调整它。

我的数据是一个对象数组,每个对象都有一个时间戳和一个地理坐标数组,坐标

[{"TimeStamp":"2014-06-18T22:18:07+04:30","Coordinates":[{"Latitude":40.416775,"Longitude":-3.70379},{"Latitude":40.415793,"Longitude":-3.707424},{"Latitude":40.414142,"Longitude":-3.707982}]}
,{"TimeStamp":"2014-06-18T22:23:07+04:30","Coordinates":[{"Latitude":40.411365,"Longitude":-3.708712},{"Latitude":40.411986,"Longitude":-3.705021},{"Latitude":40.406774,"Longitude":-3.711716}]}
,{"TimeStamp":"2014-06-18T22:28:07+04:30","Coordinates":[{"Latitude":40.401365,"Longitude":-3.720449},{"Latitude":40.388455,"Longitude":-3.731843},{"Latitude":40.383568,"Longitude":-3.738881}]}]

我找不到迭代所有坐标对象的方法,因此为第一级数组的每个元素添加了一个 for 循环:

// Add the container when the overlay is added to the map.
overlay.onAdd = function() {
var layer = d3.select(this.getPanes().overlayLayer).append("div")
.attr("class", "stations");

// Draw each marker as a separate SVG element.
// We could use a single SVG, but what size would it have?
overlay.draw = function() {
var projection = this.getProjection(),
padding = 10;
for( var i = 0; i < data.length; i++)
{
var marker = layer.selectAll("svg")
.data(data[i].Coordinates)
.each(transform) // update existing markers
.enter()
.append("svg:svg")
.each(transform)
.attr("class", "marker");

// Add a circle.
marker.append("svg:circle")
.attr("r", 4.5)
.attr("cx", padding)
.attr("cy", padding);

// Add a label.
marker.append("svg:text")
.attr("x", padding + 7)
.attr("y", padding)
.attr("dy", ".31em")
.text(function(d, i){
return i;
});
}

function transform(d) {
d = new google.maps.LatLng(d.Latitude, d.Longitude);
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x - padding) + "px")
.style("top", (d.y - padding) + "px");
}
};
};

但是,d3 在每次迭代中都会覆盖标记 svg 元素,并且在本例中仅显示 3 个标记,而不是 9 个。

这是为什么?

最佳答案

为了直接回答这个问题,d3 会覆盖每个循环上的 SVG 元素,因为它们是按数组中的位置进行索引的。您必须提供一个 id 函数,它是 data() 函数的第二个参数。要遵循的代码。

嵌套选择不太适合这种情况,因为您不需要嵌套 html,其原因在链接代码中指出:“我们可以使用单个 SVG,但它的大小是多少?”。所以我们确实想在某个时候使用 for 循环。

另请注意,只有“进入阶段”需要进入 for 循环,但如果您也将渲染放在那里,应该不会有太大区别。

var map = new google.maps.Map(d3.select("#map").node(), {
zoom: 8,
center: new google.maps.LatLng(40.411365, -3.708712),
mapTypeId: google.maps.MapTypeId.ROADMAP
});

// Load the station data. When the data comes back, create an overlay.
d3.json("soQuest.json", function(data) {
var overlay = new google.maps.OverlayView();

// Add the container when the overlay is added to the map.
overlay.onAdd = function() {
var layer = d3.select(this.getPanes().overlayLayer).append("div")
.attr("class", "stations");

// Draw each marker as a separate SVG element.
// We could use a single SVG, but what size would it have?
overlay.draw = function() {
var projection = this.getProjection(),
padding = 10,
marker;


for (i = 0; i < data.length; i++) {
marker = layer.selectAll("svg")
.data(data[i].Coordinates, function(d, index){
return data[i].TimeStamp + index + d.Latitude + d.Longitude;
})
.enter().append("svg");
}

marker = layer.selectAll("svg")
.each(transform) // update existing markers
.attr("class", "marker");

// Add a circle.
marker.append("svg:circle")
.attr("r", 4.5)
.attr("cx", padding)
.attr("cy", padding);

// Add a label.
marker.append("svg:text")
.attr("x", padding + 7)
.attr("y", padding)
.attr("dy", ".31em")
.text(function(d) {
return "MARKER"; //d.key;
});

function transform(d) {
d = new google.maps.LatLng(d.Latitude, d.Longitude);
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x - padding) + "px")
.style("top", (d.y - padding) + "px");
}
};
};

// Bind our overlay to the map…
overlay.setMap(map);
});

关于javascript - 如何防止新元素覆盖 d3.js 中的现有元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24409545/

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