我想在我的d3 svg中添加带标签的复选框。我希望它们位于单独的g
元素中,因为出于某种原因,如果标签位于foreignObject中,则字体呈现与svg的其余部分不匹配(与我的问题无关,尽管我是也很满意那里的解释。
然而,我无法弄清楚如何让它们垂直对齐。是的,我可以介绍一些软糖因素,但似乎只能对应一个特定大小的svg,这可能会改变。我该怎么做?
let y=40;
svg.append("g")
.append("foreignObject")
.attr("x", "4ex")
.attr("y", y)
.attr("width", 75)
.attr("height", 25)
.append("xhtml:body")
.html("<form><input type=checkbox id=check/>text1</form>");
//seems I must render this outside the foreignObject in order to match font rendering of the svg
svg.append("g")
.append("text")
.attr("y", y)
.attr("height", 25)
.attr("x", "7ex")
.text("text2")
也就是说,我希望文本与复选框对齐,就好像文本已经在foreignObject
的html中一样。看起来我应该能够为两者设置y
的相同值。
http://jsfiddle.net/48rdrp6a/2/
如果是设置vertical-align
的问题,我无法弄清楚放在哪里。
答案 0 :(得分:1)
主要问题是y
上的foreignObject
属性指定了框中的顶部,而y
上的text
属性}指定文本的基线。
在给定的示例中,foreignObject
因此从40开始向下增长到65,而text
的基线从40开始,上升和下降分别从40上升和下降
可以通过the alignment-baseline
property更改此行为。使用before-edge
移动EM框,以便y
指定text
的上边缘,使两个元素兼容。
除了这个根本区别之外,浏览器默认样式还存在问题。 body
中的foreignObject
将具有特定于浏览器的默认样式,可能会偏移表单和复选框,使其再次不对齐。例如,在Chrome中,这会增加8px的保证金。
var svg = d3.select("#chart").append("svg")
.attr("width", 200)
.attr("height", 200);
let y = 40;
svg.append("g")
.append("foreignObject")
.attr("x", "4ex")
.attr("y", y)
.attr("width", 75)
.attr("height", 25)
.append("xhtml:body")
.html("<form><input type=checkbox id=check/></form>");
svg.append("g")
.append("text")
.attr("y", y)
.attr("height", 25)
.attr("x", "6ex")
.text("text2")
// svg repositioning
$("svg").css({
top: 200,
left: 200,
position: 'absolute'
});
&#13;
#chart {
border: 1px solid green;
}
svg {
background: #AABBFF;
border: 2px solid #8899EE;
}
text {
alignment-baseline: before-edge;
}
foreignObject body {
all: unset;
display: block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
&#13;
我使用CSS来设置alignment-baseline
,但使用相应的属性也可以。
为了抵消body
默认样式,我使用all: unset
组合删除所有浏览器样式,然后恢复display: block
。