Javascript 如何相对于另一个对象定位一个对象
我正在使用SVG渲染模型。我将尝试提供一个比我正在研究的更清楚的例子。假设数据结构是一个JSON对象,如下所示:Javascript 如何相对于另一个对象定位一个对象,javascript,d3.js,svg,Javascript,D3.js,Svg,我正在使用SVG渲染模型。我将尝试提供一个比我正在研究的更清楚的例子。假设数据结构是一个JSON对象,如下所示: vehicle = { "axles": [ { "id": 0, "wheels": [ { "id": 0, "diameter": 18 },
vehicle = {
"axles": [
{
"id": 0,
"wheels": [
{
"id": 0,
"diameter": 18
},
{
"id": 1,
"diameter": 18
}
]
},
{
"id": 1,
"wheels": [
{
"id": 0,
"diameter": 18
},
{
"id": 1,
"diameter": 18
}
]
}
]
}
我想为车辆、每个车轴和车轴上的每个车轮渲染一些形状。我可以成功地为车辆和车轴绘制形状,但不能为车轮绘制形状
(我将忽略大多数样式/大小属性)
然后,我想根据轴的位置“绘制车轮”,但在append语句的末尾应用data(),将轴元素的内部放入,使其不显示-我需要车轮元素与轴元素一起位于父元素中,但我需要在数据结构中读取轴的子数据
我希望这一切都有意义,希望有人能帮忙。你不能把一个矩形放在一个矩形里,但你可以把一个组放在另一个组里。将“汽车”设为一个组是有意义的,它包含每个“车轴”的一个组,每个“车轴”包含一对“车轮”(可以是
rects
,也可以是组)
除了链接所有表达式之外,您还可以将选择分配给变量并重用它,或者通过选择器选择所有元素(如果您绑定的数据不依赖于前面的上下文)。您还可以使用each()
并使用d3对选择中的每个元素重复代码。选择(此)
以引用父元素
这里有一个例子。您可以将“car”附加为一个组(其中可以包含任意数量的元素,包括rect
):
然后预先选择要在“汽车”组内创建的“车轴”对象:
用这个试试。我为
文本
替换了矩形
,并稍微修改了JSON数据以说明解决方案。太棒了!我现在唯一的问题是,当悬停在元素上时,悬停伪类将应用于元素的所有祖先。如果我有.car:hover、.axe:hover、.wheel:hover{stroke:blue}
,则仅将鼠标悬停在一个wheel元素上也会将hover伪类应用于它的每个祖先,即axe和car。我甚至试着将轮子元素从其他元素移开,这样就不会有任何重叠,并且仍然会发生。编辑:我修复了它,哈。我忘了这些课程是为团体而设的,而不是为rect而设的。将样式选择器更改为。car-rect:hover、.axe-rect:hover、.wheel-rect:hover{stroke:blue}
再次感谢您的回答!您还可以使用CSS“指针事件:无”禁用元素上的事件。这在堆叠层时非常有用,并且可能希望忽略层上的事件(典型示例是文本标签)。
var svg = d3.select("body").append("svg");
svg.append("rect").attr("class", "car") // Only 1 car object
svg.selectAll(".car).data(vehicle.axles, function(d){return d.id}) // Render each axle
.append("rect")
svg.append("g").attr("class", "car") // this group is the car
.append("rect") // a rect inside the car group
...
svg.select(".car") // selects the group car (where we will append axles)
.selectAll(".axle") // pre-select all axles
.data(vehicle.axles) // bind the data
.enter()
.append("g").attr("class", "axle") // will append new axle for each data item
.each(function(d,i) { // now repeat for each axle
d3.select(this) // selects the current axle
.selectAll(".wheel") // pre-select the wheels you are going to create
.data(d.wheels) // bind the data
.enter()
.append("g").attr("class", "wheel") // append a wheel for the current axle
.append("rect") // the rect representing the wheel
...
})
.append("rect") // the rect representing the axle