Как работает выбор узла D3 в графе сил D3?

Я пытаюсь создать граф силы и вставляя ForeignObject для каждого узла.

    simulation
            .nodes(graph.nodes)
            .on("tick", ticked)
            .on("end", graphended);

       var node   = svg.append("g")
                    .attr("class", "nodes")
                    .selectAll("circle")
                    .data(graph.nodes)
                    .enter().append("foreignObject")
                                 .attr("width",img_w)
                                 .attr("height",img_h)
                            .append("xhtml:body")
                            .html(function(d){ 
                                return '<span class="custom-icon-container-circle">Some sample content</span>';
                            })
                            .call(d3.drag()
                                    .on("start", dragstarted)
                                    .on("drag", dragged)
                                    .on("end", dragended));

и в функции TICK у меня есть следующий способ назначить x а также y координаты.

function ticked() {
            node
                .attr("x", function(d) {
                    var xPos = findPosX(d.x, img_w);
                    return xPos-img_w/2;
                })
                .attr("y", function(d) {
                    var yPos = findPosY(d.y, img_h);
                    return yPos-img_h/2;
                });
        }

Но в этом методе галочки, вместо того, чтобы давать x а также y Положение к foreignObject это назначение позиции body элемент в foreignObject, который заставляет узел не позиционироваться в реальных координатах.

Теперь код работает (если я удаляю foreignObject и помещаю другой тег элемента, и позиция присваивается этому элементу), так что я думаю, что есть проблема в моем селекторе и операторе добавления, который создает foreignObject выше, так как он выбирает внутри тела элемента.

1 ответ

Решение

d3 цепочка методов возвращает последнее, что возвращает что-то, в вашем случае это .append("xhtml:body"), так node держит ссылку на это, а не на foreignObject, Измените свой код на:

var node = svg.append("g")
 .attr("class", "nodes")
 .selectAll("circle")
 .data(graph.nodes)
 .enter().append("foreignObject")
 .attr("width",img_w)
 .attr("height",img_h);

node.append("xhtml:body")
  .html(function(d){ 
    return '<span class="custom-icon-container-circle">Some sample content</span>';
  })
  .call(d3.drag()
  .on("start", dragstarted)
  .on("drag", dragged)
  .on("end", dragended));
Другие вопросы по тегам