2016-08-08 2 views
0

Я собираюсь добавить набор кругов, радио и выпадающее меню в SVG и переключиться между ними (на том же svg).d3 - невозможно добавить параметр select/option в элемент svg-g

Мне не удалось добавить раскрывающееся меню select/option в SVG, который создается с шириной/высотой 600/600. В консоли элемента я могу видеть элемент g и выпадающий выбор. Но на экране g#menu имеет размер 0x0? Почему это так? Любые указатели/входы?

ПРИМЕЧАНИЕ. Здесь я пытаюсь добавить выпадающее меню динамически, используя D3.js вместо hardcoding selectio/option или div в элементе body. Я делаю это, чтобы переключиться между разными видами.

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;}); 
+1

Я написал ответ, но я удалил его, потому что я запутался: в тексте, вы говорите, что вы прилагая выберите в SVG , но в вашем коде вы добавляете его в тело. Какой из них правильный? –

+1

Кроме того, в вашем вопросе вы ссылаетесь на 'g # menu', хотя в вашем фрагменте id' menu' присваивается 'select'. Что-то здесь не так. – altocumulus

+0

ОК, @gayathri, я восстановил свой ответ. Если вы добавляете его в SVG, посмотрите. Если вы добавляете его в тело, игнорируйте мой ответ. –

ответ

1

Попробовать это

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") 
 
\t .append("svg") 
 
\t .attr("width", width) 
 
\t .attr("height", height) 
 
    .append("g") 
 
    .attr("class","dropdown"); 
 
select = svg.append("g") 
 
    .attr("class","select"); 
 
select.append("rect") 
 
    .attr("x", 10) 
 
\t .attr("y", 10) 
 
\t .attr("width", l) 
 
\t .attr("height", 30); 
 
select.append("text") 
 
    .attr("x", 15) 
 
\t .attr("y",30) 
 
    .attr("id","mydropdown") 
 
\t .text(buttonNames[0]); 
 
    
 
var options = svg.selectAll(".myBars") 
 
\t .data(buttonNames) 
 
\t .enter() 
 
\t .append("g"); 
 
\t 
 
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) 
 
\t .attr("y", function(d,i){ return 40 + i*30}) 
 
\t .attr("width", l) 
 
\t .attr("height", 30); 
 

 
options.append("text").attr("x", function(d){ return 15}) 
 
\t .attr("y", function(d,i){ return 60 + i*30}) 
 
\t .text(function(d){ return d});
rect { 
 
\t 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>

+0

Спасибо Mr.A. Попробуем ... поэтому мы построим выпадающее меню select/option в виде прямоугольников и добавим их в SVG. Я изменил свой код, чтобы использовать элементы выбора/опции HTML, а также использовать opacity и z-index для слоев с помощью SVG. – gayathri

+0

Just попробовал это! Единственным преимуществом использования svgs даже для этих настраиваемых выпадающих (вместо старых старых HTML элементов) является g-элемент. Группировка с использованием «g» облегчит переключение между представлениями разных «g» на том же SVG.попробует это, не знаю, если я абсолютно прав – gayathri

+0

Это очень умное обходное решение! –

4

Этот вопрос настолько распространен, что я создал этот пример в документации. В примере рассматриваются элементы SVG, неправильно добавленные к SVG, но те же рассуждения применимы к элементам HTML, которые добавляются к SVG: вы должны знать, какие элементы могут иметь детей, а - то, что есть у детей. Подробнее в нижней части этой публикации.

Вкратце: вы не можете добавить какой-либо элемент HTML в SVG (за исключением использования foreignObject). Элемент появится в консоли, но не будет работать.

Примечание: Я отвечаю на ваш письменный вопрос и игнорирую ваш код, потому что, достаточно забавно, в вашем коде вы правильно добавляете элемент HTML в body.


Правильно присоединени SVG элемент

Это довольно распространенная ошибка: Вы создали rect элемент в виде гистограммы, например, и вы хотите добавить текстовую метку (скажем, значение этого бара). Итак, используя ту же переменную, которую вы использовали для добавления rect и определите ее позицию x и y, вы добавляете свой элемент text. Очень логично, вы можете подумать. Но это не сработает.

Как происходит эта ошибка?

Давайте посмотрим конкретный пример, базовый код для создания гистограммы (fiddle here):

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); 

Что дает нам этот результат:

enter image description here

Но вы хотите добавьте некоторые текстовые элементы, возможно, простое значение для каждого бара. Итак, вы делаете это:

bars.append("text") 
    .attr("x", 10) 
    .attr("y", function(d,i){ return 10 + i*40}) 
    .text(function(d){ return d}); 

И, вуаля: ничего не происходит! Если вы сомневаетесь в этом, here is the fiddle.

«Но я вижу бирку!«

Если вы осмотрите SVG, созданный этим последним кодом, вы собираетесь увидеть это:

enter image description here

И в этот момент многие люди говорят:» Но я видя текстовый тег, он добавляется»Да, это так, но это не означает, что он будет работать Вы можете добавить ничего Смотрите это, например:..!

svg.append("crazyTag"); 

это даст вам этот результат:

<svg> 
    <crazyTag></crazyTag> 
</svg> 

Но вы не ожидаете результата только потому, что там есть тэг?

Append SVG элементы правильный путь

Узнайте, что SVG элементы могут держать детей, чтение specifications. В нашем последнем примере код не работает, потому что элементы 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}); 

И это результат:

enter image description here

И here is the fiddle.

+1

спасибо @Gerado. Извините за ошибку в коде. Я действительно старался добавить капля вниз к svg, а не к телу (да, добавив его в тело, прямое fwd и будет работать). Так что это действительно полезно, не все HTML-элементы не могут быть добавлены как дети в SVG ..... и если я настаиваю, вам нужно использовать посторонние объекты, то еще нужно разрабатывать посторонние объекты, используя svgs самостоятельно ... – gayathri

+0

Да, но сохраняйте в виду, что foreignObject не работает в Internet Explorer ... Просто добавьте выбор в HTML, а не в SVG, и вы в безопасности. –

+1

k @Gerardo. Добавили их как HTML-элементы с zindex и непрозрачность для слоев с SVG – gayathri

Смежные вопросы