【问题标题】:D3 - redraw SVG after DOM changeD3 - DOM 更改后重绘 SVG
【发布时间】:2017-03-08 17:31:09
【问题描述】:

我正在努力重绘/更新我的 SVG。我为我的数据添加了 enter-update-exit 方法,我的 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 树中的一个新组。可以在 schedule 函数的第二行看到。

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

【问题讨论】:

  • 如何将&lt;g id="Group1"&gt; 添加到DOM?你能提供一些工作/可运行的代码吗?
  • @Mark 第二行 schedule 函数将 Group1 添加到 DOM。我添加了一些可运行的示例代码。
  • 如果我只是使用纯 DOM API 为它附加一个新的组元素和新的子元素,我会得到相同的结果,DOM 树可以正常工作,但可视化 svg 不能跨度>

标签: javascript dom d3.js svg data-visualization


【解决方案1】:

在您的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);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2013-06-20
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多