4

我正在尝试使用我在 json 中收到的数据动态更新 d3 圆形包布局。每一秒我都会调用 d3.json() 来获取新的 json。我的实现不是更新现有的可视化,而是在旧的可视化下创建一个新的可视化。我想动态更新现有布局...

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="d3.v2.js"> 
</script>

<script type="text/javascript" src="jquery-1.4.min.js"></script>

<link rel="stylesheet" href="style.css" type="text/css">
<link rel="stylesheet" href="syntax.css" type="text/css">
<link rel="stylesheet" href="pack.css" type="text/css">

</head>

<body>

<div id="chart"> </div>
<script type="text/javascript">

    var width = 960,
        height = 960,
        format = d3.format(",d");

    var pack = d3.layout.pack()
        .size([width - 4, height -4])
        .value(function(d) { return d.size; });

    var vis = null;
    var node = null;

    vis = d3.select("#chart").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "pack");
/*      vis.append("g")
    .attr("transform", "translate(2, 2)"); */

    function update(json){


        // Creating the circle packed core
        var gNodes = vis.data([json]).selectAll("g.node")
          .data(pack.nodes);

               //remove old data
        gNodes.exit().remove();


    }


setInterval(function(){
    d3.json("http://10.0.1.4:8080/cluster", function(json) {        
        update(json);
//update the visualization

        vis
          .selectAll("circle")
          .data([json]).selectAll("g.node")
          .data(pack.nodes)
          .attr("class", function(d) { return d.children ? "node" : "leaf node"; })
          .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
          .transition()
          .duration(500)
          .attr("r", function(d) { return d.children ? coreSize : d.r; });

        var node = gNodes
          .enter().append("g")
          .attr("class", function(d) { return d.children ? "node" : "leaf node"; })
          .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
        node.append("title")
        .text(function(d) { return (d==null? "": d.name + (d.children ? "" : ": " + format(d.size))); });

        node.append("circle")
        .attr("r", function(d) { return (d==null? 0: d.r); });

        node.filter(function(d) { return (d==null? "" : !d.children); }).append("text")
        .attr("text-anchor", "middle")
        .attr("dy", ".3em")
        .text(function(d) { return (d==null?"":d.name.substring(0, d.r / 3)); });

    });
    }, 1000);

    </script>

4

1 回答 1

3

看看我这里的例子。

基本上,有用于初始加载的代码,其中所有圆圈、工具提示等都被创建并定位在初始位置。同样,布局(包)被创建。

然后,在每次按下按钮时,都会将新数据加载到包中,并重新计算包。关键代码在这里:

if (dataSource == 0)
    pack.value(function(d) { return d.size; });
if (dataSource == 1)
    pack.value(function(d) { return 100; });
if (dataSource == 2)
    pack.value(function(d) { return 1 +
             Math.floor(Math.random()*501); });

var data1 = pack.nodes(data);

(我有三个按钮,这就是为什么 3 ifs)

之后,元素被转换到新的位置,并且它的属性会根据你的决定而改变。

以下是一些带有过渡效果的图片:

开始:

开始

过渡:

过渡

结尾:

结尾

于 2013-12-29T12:03:52.667 回答