Обновление макета круга D3

Я пытаюсь динамически обновлять макет пакета кругов d3 с данными, которые я получаю в json. Каждую секунду я вызываю 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>


person capkutay    schedule 03.08.2012    source источник


Ответы (1)


Взгляните на мой пример здесь.

По сути, есть код начальной загрузки, где все круги, всплывающие подсказки и т. д. создаются и располагаются в исходных местах. Также создается макет (пак).

Затем при каждом нажатии кнопки в пак загружаются новые данные, и пак пересчитывается. Этот важный код находится здесь:

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 если)

После этого элементы перемещаются на новые позиции, а их атрибуты изменяются по вашему усмотрению.

Вот несколько фотографий с переходом в действии:

Начинать:

start

Переход:

transition

Конец:

end

person VividD    schedule 29.12.2013