Javascript 如何使用d3.js(可缩放圆包)更新数据格式文件json

Javascript 如何使用d3.js(可缩放圆包)更新数据格式文件json,javascript,json,d3.js,updating,circle-pack,Javascript,Json,D3.js,Updating,Circle Pack,我正在研究存储在json文件中的传入数据的实时可视化。我使用D3进行可视化。这是我使用的图表: 这是所有代码页: <body onload="visualize()"> <h2> <input type="button" value="Get new data" onclick='ajaxSyncRequest("get-current-time")' /> <br /> <br /> Message

我正在研究存储在json文件中的传入数据的实时可视化。我使用D3进行可视化。这是我使用的图表:

这是所有代码页:

<body onload="visualize()">

<h2>
    <input type="button" value="Get new data"
        onclick='ajaxSyncRequest("get-current-time")' /> <br /> <br />
    Message from server :: <span id="message"></span>
</h2>

<script type="text/javascript">

function ajaxSyncRequest(reqURL) {
    //Creating a new XMLHttpRequest object
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest(); //for IE7+, Firefox, Chrome, Opera, Safari
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //for IE6, IE5
    }
    //Create a asynchronous GET request
    xmlhttp.open("GET", reqURL, false);
    xmlhttp.send(null);

    //Execution blocked till server send the response
    if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
            document.getElementById("message").innerHTML = xmlhttp.responseText;
            //alert(xmlhttp.responseText);
            update();

        } else {
            alert('Something is wrong !!');
        }
    }
}
</script>



<script type="text/javascript" src="d3/d3.js"></script>
<script type="text/javascript" src="d3/d3.layout.js"></script>
<script type="text/javascript">
    function visualize() {

        var w = 1280, h = 800, r = 720, x = d3.scale.linear().range(
                [ 0, r ]), y = d3.scale.linear().range([ 0, r ]), node, root;

        var pack = d3.layout.pack().size([ r, r ]).value(function(d) {
            return d.size;
        })

        var vis = d3.select("body").insert("svg:svg", "h2")
                .attr("width", w).attr("height", h).append("svg:g").attr(
                        "transform",
                        "translate(" + (w - r) / 2 + "," + (h - r) / 2
                                + ")");

        d3.json("flare.json", function(data) {
            node = root = data;

            var nodes = pack.nodes(root);

            vis.selectAll("circle").data(nodes).enter()
                    .append("svg:circle").attr("class", function(d) {
                        return d.children ? "parent" : "child";
                    }).attr("cx", function(d) {
                        return d.x;
                    }).attr("cy", function(d) {
                        return d.y;
                    }).attr("r", function(d) {
                        return d.r;
                    }).on("click", function(d) {
                        return zoom(node == d ? root : d);
                    });

            vis.selectAll("text").data(nodes).enter().append("svg:text")
                    .attr("class", function(d) {
                        return d.children ? "parent" : "child";
                    }).attr("x", function(d) {
                        return d.x;
                    }).attr("y", function(d) {
                        return d.y;
                    }).attr("dy", ".35em").attr("text-anchor", "middle")
                    .style("opacity", function(d) {
                        return d.r > 20 ? 1 : 0;
                    }).text(function(d) {
                        return d.name;
                    });

            d3.select(window).on("click", function() {
                zoom(root);
            });
        });

        function zoom(d, i) {
            var k = r / d.r / 2;
            x.domain([ d.x - d.r, d.x + d.r ]);
            y.domain([ d.y - d.r, d.y + d.r ]);

            var t = vis.transition().duration(d3.event.altKey ? 7500 : 750);

            t.selectAll("circle").attr("cx", function(d) {
                return x(d.x);
            }).attr("cy", function(d) {
                return y(d.y);
            }).attr("r", function(d) {
                return k * d.r;
            });

            t.selectAll("text").attr("x", function(d) {
                return x(d.x);
            }).attr("y", function(d) {
                return y(d.y);
            }).style("opacity", function(d) {
                return k * d.r > 20 ? 1 : 0;
            });

            node = d;
            d3.event.stopPropagation();
        }
    }
</script>

<script type="text/javascript">
    function update() {

        var w = 1280, h = 800, r = 720, x = d3.scale.linear().range(
                [ 0, r ]), y = d3.scale.linear().range([ 0, r ]), node, root;

        var pack = d3.layout.pack().size([ r, r ]).value(function(d) {
            return d.size;
        })

        var vis = d3.select("svg").attr("width", w).attr("height", h)
                .append("svg:g").attr(
                        "transform",
                        "translate(" + (w - r) / 2 + "," + (h - r) / 2
                                + ")");

        d3.json("flare.json", function(data) {

            node = root = data;

            var nodes = pack.nodes(root);
            // DATA JOIN
            // Join new data with old elements, if any.
            var newG = vis.selectAll("circle").data(nodes);

            // UPDATE
            // Update old elements as needed.
            newG.attr("class", "update").transition();

            // ENTER
            // Create new elements as needed.
            newG.enter().append("svg:circle").attr("class", function(d) {
                return d.children ? "parent" : "child";
            }).attr("cx", function(d) {
                return d.x;
            }).attr("cy", function(d) {
                return d.y;
            }).attr("r", function(d) {
                return d.r;
            }).on("click", function(d) {
                return zoom(node == d ? root : d);
            });

            newG.enter().append("svg:text")
            .attr("class", function(d) {
                return d.children ? "parent" : "child";
            }).attr("x", function(d) {
                return d.x;
            }).attr("y", function(d) {
                return d.y;
            }).attr("dy", ".35em").attr("text-anchor", "middle")
            .style("opacity", function(d) {
                return d.r > 20 ? 1 : 0;
            }).text(function(d) {
                return d.name;
            });

            // EXIT
            // Remove old elements as needed.
            newG.exit().attr("class", "exit").transition().remove();

            d3.select(window).on("click", function() {
                zoom(root);
            });
        });

        function zoom(d, i) {
            var k = r / d.r / 2;
            x.domain([ d.x - d.r, d.x + d.r ]);
            y.domain([ d.y - d.r, d.y + d.r ]);

            var t = vis.transition().duration(d3.event.altKey ? 7500 : 750);

            t.selectAll("circle").attr("cx", function(d) {
                return x(d.x);
            }).attr("cy", function(d) {
                return y(d.y);
            }).attr("r", function(d) {
                return k * d.r;
            });

            t.selectAll("text").attr("x", function(d) {
                return x(d.x);
            }).attr("y", function(d) {
                return y(d.y);
            }).style("opacity", function(d) {
                return k * d.r > 20 ? 1 : 0;
            });

            node = d;
            d3.event.stopPropagation();
        }
    }
</script>
我想从服务器上获取的新文件中动态更新图表。但有了这个功能,它就可以在旧的基础上绘制新的图表。我尝试了不同的解决方案来更新图表,但没有一个有效。
如何修改代码以获得动态更新?

以下更改是实现此功能所必需的。首先,您需要在更新函数中选择现有SVG元素及其子体g作为vis:

var vis = d3.select("svg > g");
然后,您需要分别计算和处理圆和文本的输入、更新和退出选择:

var newG = vis.selectAll("circle").data(nodes);

newG.enter().append("svg:circle");
newG.exit().remove();
newG.attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("cx", function(d) {
    return d.x;
  }).attr("cy", function(d) {
    return d.y;
  }).attr("r", function(d) {
    return d.r;
  }).on("click", function(d) {
    return zoom(node == d ? root : d);
  });

var texts = vis.selectAll("text").data(nodes);

texts.enter().append("svg:text");
texts.exit().remove();
texts.append("svg:text")
  .attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("x", function(d) {
    return d.x;
  }).attr("y", function(d) {
    return d.y;
  }).attr("dy", ".35em")
  .attr("text-anchor", "middle")
  .style("opacity", function(d) {
    return d.r > 20 ? 1 : 0;
  }).text(function(d) {
    return d.name;
  }); 

您还可以合并您的函数,因为它们都做几乎相同的事情,并且存在大量冗余代码。但上述内容应足以使其工作。

以下更改是使其工作所必需的。首先,您需要在更新函数中选择现有SVG元素及其子体g作为vis:

var vis = d3.select("svg > g");
然后,您需要分别计算和处理圆和文本的输入、更新和退出选择:

var newG = vis.selectAll("circle").data(nodes);

newG.enter().append("svg:circle");
newG.exit().remove();
newG.attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("cx", function(d) {
    return d.x;
  }).attr("cy", function(d) {
    return d.y;
  }).attr("r", function(d) {
    return d.r;
  }).on("click", function(d) {
    return zoom(node == d ? root : d);
  });

var texts = vis.selectAll("text").data(nodes);

texts.enter().append("svg:text");
texts.exit().remove();
texts.append("svg:text")
  .attr("class", function(d) {
    return d.children ? "parent" : "child";
  }).attr("x", function(d) {
    return d.x;
  }).attr("y", function(d) {
    return d.y;
  }).attr("dy", ".35em")
  .attr("text-anchor", "middle")
  .style("opacity", function(d) {
    return d.r > 20 ? 1 : 0;
  }).text(function(d) {
    return d.name;
  }); 


您还可以合并您的函数,因为它们都做几乎相同的事情,并且存在大量冗余代码。但是上面的内容应该足以让它工作。

您的代码在调用时总是插入一个新的SVG。您必须选择并修改现有的一个来更新。您能更具体一点吗?感谢您在visualize函数中执行d3.selectbody.insertsvg:svg,h2。这将始终创建一个新的SVG。要选择一个现有的,您可以执行类似于d3.selectsvg的操作。在问题中,我添加了我使用的函数update。我使用你的建议,但我有同样的行为。你能发布一个完整的例子吗?你的代码总是在调用时插入一个新的SVG。您必须选择并修改现有的一个来更新。您能更具体一点吗?感谢您在visualize函数中执行d3.selectbody.insertsvg:svg,h2。这将始终创建一个新的SVG。要选择一个现有的,您可以执行类似于d3.selectsvg的操作。在问题中,我添加了我使用的函数update。我使用你的建议,但是我有同样的行为。你能发布一个完整的例子吗?谢谢,现在更新工作很好。只有一个问题:当我在json文件中增加一个节点大小时,在可视化中,它会自动增加我指定的节点的大小,但会减少其他节点的半径,即使它们在文件中的大小没有改变。如何避免这种行为?这就是包布局的作用。如果要保持相对大小,还需要将其他节点的值增加相同的相对量。确定。使用此包布局是否可以更改父节点的大小?我试过这个{名字:食物,尺码:900000,孩子:[{name:dish,size:8000…但它不起作用。根节点将覆盖整个布局。最后,此图表不适合我必须执行的操作。我正在搜索一个图表,该图表显示节点之间的层次关系,并允许我指定其所有绝对大小。我刚刚尝试了可折叠的强制布局,在这里我可以指定叶节点的绝对大小,但我想设置父节点的大小。您认为我可以使用哪个图表?谢谢,现在更新效果很好。只有一个问题:当我在json文件中增加一个节点大小时,在可视化中,它会自动增加我指定的节点的大小,但会减少ot的半径她的节点,即使它们在文件中的大小没有改变。我如何避免这种行为?这就是包布局所做的。如果要保持相对大小,还需要将其他节点的值增加相同的相对量。确定。使用此包布局可以改变父节点的大小吗?我已经尝试过了{姓名:食品,尺码:900000,儿童:[{name:dish,size:8000…但它不起作用。根节点将覆盖整个布局。最后,此图表不适合我必须执行的操作。我正在搜索一个图表,该图表显示节点之间的层次关系,并允许我指定其所有绝对大小。我刚刚尝试了可折叠的强制布局,在这里我可以指定叶节点的绝对大小,但我想设置父节点的大小。您认为我可以使用哪个图表?