我正在对存储在json文件中的传入数据进行实时可视化。我使用D3进行可视化。这是我使用的图表:http://mbostock.github.io/d3/talk/20111116/pack-hierarchy.html
这是所有代码页:
<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>
我想从我从服务器获取的新文件中动态更新图表。但是通过这个功能,它绘制了一个旧图表。我尝试了不同的解决方案来更新图表但没有一个工作。 我如何修改代码以获得动态更新?
答案 0 :(得分:4)
进行此项工作需要进行以下更改。首先,您需要在g
函数中选择现有的SVG元素(及其后代vis
)作为update
:
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;
});
你也可以合并你的功能,因为它们几乎都做同样的事情并且有很多冗余代码。但上述内容应足以使其发挥作用。