[英]d3 - unable to add select/option drop down to svg-g element
我打算将Circle Pack,收音机和下拉菜单添加到SVG,并在它们之间切换(在同一svg上)。
我无法将选择/选项下拉菜单添加到以600/600的宽度/高度创建的SVG。 在元素控制台中,我可以看到g
-element和下拉选择选项。 但是在屏幕上, g#menu
的大小为0x0吗? 为什么会这样呢? 有指针/输入吗?
注意:在这里,我尝试使用D3.js动态添加下拉菜单,而不是在body元素中硬编码selectio / option或div。 我这样做是为了在不同的视图之间切换。
var svg1 = d3.select("body")
.append("svg")
.attr("width", 600)
.attr("height", 600)
.append("g")
.attr("transform",
"translate(0,0)"));
var buttonNames = ["button 1", "button 2", "button 3", "button 4"];
var menug = svg1.append("g")
.attr("id","menug")
.attr("transform","translate(60,60)");
var menu = d3.select("#menug")
.append("select")
.attr("id", "menu");
menu.selectAll("option")
.data(buttonNames)
.enter().append("option")
.text(function(d){return d;});
这个问题非常普遍,以至于我在文档中创建了此示例。 与SVG元素的例子交易错误地附加到SVG,但同样的道理也适用于HTML元素被附加到SVG:你必须知道哪些元素可以有孩子,他们能有什么样的孩子。 更多细节在这篇文章的底部。
简而言之:您不能将任何HTML元素附加到SVG(除非使用foreignObject)。 该元素将显示在控制台中,但不起作用。
注意:我正在回答您的书面问题,而忽略了您的代码,因为很有趣,在您的代码中,您正确地将HTML元素附加到了body
。
正确附加SVG元素
这是一个相对常见的错误:例如,您在条形图中创建了一个rect
元素,并且想要添加文本标签(例如,该条的值)。 因此,使用与追加rect
并定义其x
和y
位置相同的变量,即可追加text
元素。 您可能会认为,这很合逻辑。 但这是行不通的。
如何发生此错误?
让我们看一个具体的示例,这是一个用于创建条形图的非常基本的代码( 此处为小提琴 ):
var data = [210, 36, 322, 59, 123, 350, 290];
var width = 400, height = 300;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var bars = svg.selectAll(".myBars")
.data(data)
.enter()
.append("rect");
bars.attr("x", 10)
.attr("y", function(d,i){ return 10 + i*40})
.attr("width", function(d){ return d})
.attr("height", 30);
这给了我们这个结果:
但是您想添加一些文本元素,可能在每个栏中添加一个简单的值。 因此,您可以这样做:
bars.append("text")
.attr("x", 10)
.attr("y", function(d,i){ return 10 + i*40})
.text(function(d){ return d});
而且,瞧!什么也没发生! 如果您对此表示怀疑, 这是小提琴 。
“但是我在看标签!”
如果您检查由上一个代码创建的SVG,您将看到以下内容:
在这一点上,很多人说:“但是我看到了文本标签,它被附加了!”。 是的,是的,但这并不意味着它将起作用。 您可以附加任何内容 ! 参见此示例:
svg.append("crazyTag");
它会给你这个结果:
<svg>
<crazyTag></crazyTag>
</svg>
但是,仅仅因为标签在那里,您不会期待任何结果,对吗?
正确添加SVG元素
阅读规范 ,了解SVG元素可以容纳哪些孩子。 在我们的最后一个示例中,代码不起作用,因为rect
元素不能包含text
元素。 那么,如何显示我们的文字呢?
创建另一个变量,并将text
附加到SVG:
var texts = svg.selectAll(".myTexts")
.data(data)
.enter()
.append("text");
texts.attr("x", function(d){ return d + 16})
.attr("y", function(d,i){ return 30 + i*40})
.text(function(d){ return d});
这是结果:
这是小提琴 。
试试看
var buttonNames = ["button 1", "button 2", "button 3", "button 4"]; var l=4; for(i=0;i<buttonNames.length;i++){if(l<buttonNames[i].length)l=buttonNames[i].length}; var width = 400, height = 300; l=l*10; var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("class","dropdown"); select = svg.append("g") .attr("class","select"); select.append("rect") .attr("x", 10) .attr("y", 10 ) .attr("width", l) .attr("height", 30); select.append("text") .attr("x", 15) .attr("y",30 ) .attr("id","mydropdown") .text( buttonNames[0]); var options = svg.selectAll(".myBars") .data(buttonNames) .enter() .append("g"); options.attr("class", "option").on("click", function() { document.getElementById("mydropdown").innerHTML=this.getElementsByTagName("text")[0].innerHTML; d3.event.stopPropagation(); }); options.append("rect").attr("x", 10) .attr("y", function(d,i){ return 40 + i*30}) .attr("width", l) .attr("height", 30); options.append("text").attr("x", function(d){ return 15}) .attr("y", function(d,i){ return 60 + i*30}) .text(function(d){ return d});
rect { fill: teal; } .dropdown .option { display:none; } .dropdown rect{ stroke-width:0.5; stroke:rgb(0,0,0) } .dropdown:hover .option { display:unset; } .dropdown { cursor:pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.