2016-10-26 2 views
0

Я борюсь с перерисовыванием/обновлением SVG. Я включил метод ввода-обновления-выход для моих данных и моя структура DOM выглядит следующим образом:D3 - перерисовать SVG после изменения DOM

<svg> 
    <g id="groupOfRectangles"> 
    <rect> 
    <rect> 
    <rect> 
    <rect> 
    ... 
    </g> 
</svg> 

Теперь я хочу, чтобы сгруппировать некоторые конкретные прямоугольники вместе в моей структуре DOM. Например:

<svg> 
    <g id="groupOfRectangles"> 
    <rect> 
    <g id="Group1"> 
     <rect> 
     <rect> 
    </g> 
    <rect> 
    ... 
    </g> 
</svg> 

Здесь я получил до сих пор:

var rect = render(); 
//until here, everything is displayed correctly 
d3.select(rect._groups[0][x]).before('g').attr("id", "Group" + 1); 
document.getElementById("Group1").appendChild(rect._groups[0][x]); 
document.getElementById("Group1").appendChild(rect._groups[0][x]); 
render(); 

После выполнения этой прямоугольники, которые группируются по «Group1» скрыты в моей визуализации, но все-таки сгруппированных прямо в моем DOM дерево. Поэтому я попытался вспомнить мою функцию рендеринга, но ничего не изменилось.

function render() { 
    var group = rectGroup.selectAll("rect").data(nodes); 

    group = group.enter() 
      .append("rect") 
      .attr("width", function(d) { return d.value; }) 
      .attr("height", rectHeight) 
      .attr("x", function(d) { return d.x; }) 
      .attr("y", function(d) { return d.y; }); 

    group.select("rect") 
      .attr("width", function(d) { return d.value; }) 
      .attr("height", rectHeight) 
      .attr("x", function(d) { return d.x; }) 
      .attr("y", function(d) { return d.y; }); 

    group.exit().remove(); 

    return group; 
} 

Причина этого заключается в взаимодействии с прямоугольниками, которые я хочу реализовать позже. То, что мне нужно только взаимодействовать с одной группой прямоугольников, вместо того, чтобы искать каждый отдельный прямоугольник, который принадлежит вместе. Так что я делаю неправильно? Есть ли более эффективный метод группировки конкретных прямоугольников?

Или возможно (возможно, проще?) Объединить их вместе, прежде чем я вызову функцию рендеринга?

EDIT-1:
Вот некоторые рабочий код, где я переключение 2 прямоугольника элементы новой группы в дереве DOM. Вы можете увидеть его во второй строке функции расписания.

var width = 500; 
var height = 500; 

obj1 = {value: 99, x: 0, y:25, height: 20}; 
obj2 = {value: 200, x: 0, y:50, height: 20}; 
obj3 = {value: 300, x: 0, y:100, height: 20}; 
obj4 = {value: 250, x: 0, y:125, height: 20}; 
obj5 = {value: 370, x: 0, y:75, height: 20}; 
var myData = [obj1, obj2, obj3, obj4, obj5]; 

var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

var rectGroup = svg.append("g").attr("id", "groupOfRectangles"); 

d3.selection.prototype.before = function(tagName) { 
    var elements = []; 

    this.each(function() { 
     var element = document.createElement(tagName); 
     this.parentNode.insertBefore(element, this); 
     elements.push(element); 
    }); 

    return d3.selectAll(elements); 
}; 

function render() { 
    var group = rectGroup.selectAll("rect").data(myData); 

    group = group.enter() 
      .append("rect") 
      .attr("width", function(d) { return d.value; }) 
      .attr("height", rectHeight) 
      .attr("x", function(d) { return d.x; }) 
      .attr("y", function(d) { return d.y; }); 

    group.select("rect") 
      .attr("width", function(d) { return d.value; }) 
      .attr("height", rectHeight) 
      .attr("x", function(d) { return d.x; }) 
      .attr("y", function(d) { return d.y; }); 

    group.exit().remove(); 

    return group; 
} 

function schedule() { 
    var rect = render(); 
    d3.select(rect._groups[0][3]).before('g').attr("id", "Group" + 1); 
    document.getElementById("Group1").appendChild(rect._groups[0][3]); 
    document.getElementById("Group1").appendChild(rect._groups[0][4]); 
} 

schedule(); 
+0

Как добавить '' к DOM? Можете ли вы предоставить некоторый рабочий/исполняемый код? – Mark

+1

@Mark вторая строка функции расписания добавляет Group1 в DOM. Я добавил некоторый код исполняемого кода. – endkugelfang

+0

Если я просто использую чистый DOM API для добавления нового элемента группы и новых дочерних элементов для него, я получаю те же результаты, дерево DOM работает корректно, но визуализация svg not – endkugelfang

ответ

0

В вашем before прототип, вам нужно использовать createElementNS и указать SVG имен:

this.each(function() { 
    var element = document.createElementNS("http://www.w3.org/2000/svg", tagName); 
    this.parentNode.insertBefore(element, this); 
    elements.push(element); 
}); 
Смежные вопросы