繁体   English   中英

d3-无法将选择/选项下拉列表添加到svg-g元素

[英]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并定义其xy位置相同的变量,即可追加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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM