javascript - 如何使用 d3.js (可缩放圆包) 更新数据表单文件 json

标签 javascript json d3.js updating circle-pack

我正在研究存储在 json 文件中的传入数据的实时可视化。我使用 D3 进行可视化。这是我使用的图表:http://mbostock.github.io/d3/talk/20111116/pack-hierarchy.html

enter image description here

这是全部代码页:

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

我想根据从服务器获取的新文件动态更新图表。但通过这个函数,它可以在旧图表上绘制新图表。我尝试了不同的解决方案来更新图表,但没有一个有效。 我必须如何修改代码才能动态更新?

最佳答案

要实现此目的,需要进行以下更改。首先,您需要在 update 函数中选择现有的 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;
  }); 

您还可以合并您的函数,因为它们几乎执行相同的操作,并且有很多冗余代码。但以上内容应该足以使其工作。

关于javascript - 如何使用 d3.js (可缩放圆包) 更新数据表单文件 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21600858/

相关文章:

javascript - REGEX 用于获取 URL 末尾不带/的 ID

javascript - 文本输入中仅允许输入数字,并允许连字符作为可选的第一个字符

json - 返回多个键值对的 json,而不是单对键值 json 的列表

javascript - 在 d3.js 中加载 json

javascript - 对空输入什么都不做 - 结合表单上的动态操作

javascript - 为什么可以提交这个表单? (火狐)

json - PIG中的JSONStorage问题

java - 无法解析 javascript 中的 json 字符串,这是 java 方法的响应

css - 如何使用 :before pseudo element 设置 SVG 节点的样式

d3.js - 预期 ')' - SVG 转换抛出错误