我无法找到在D3中绘制点时获得平滑过渡的方法。我有一个绘制世界地图的脚本。我正在听一个给我经度和经度的服务器。我想在屏幕上绘制事件,使圆圈在1秒内从0增加到10。因为我正在收听服务器,所以我可以在1秒内拥有多个数据点。当前一个点仍在转换时,我该如何绘制另一个点?
这是我提出的代码,但我无法找到一种方法可以将d3类型转换添加到“圆圈”,因为只有在使用d3.data([coords])时才可以。输入()。因为我可以直接更改属性,所以在这里使用d3似乎有些过分。
修改
稍微简化我的问题我决定收集1秒钟的数据,然后一次显示这些点数。但是,我认为我无法理解exit()的本质,因为我的下面的代码并没有删除先前的点并在coords上创造新的点。 Points.exit()。remove不起作用,因为它返回一个大小为0的数组,尽管coords每次都会改变。此外,它会在地图上连续显示第一组数据,之后不会改变任何内容。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
sse = new EventSource('/my_event_source');
sse.onmessage = function(message) {
console.log('A message has arrived!');
var data = JSON.parse(message.data);
data.data.forEach(function(d){
d.lat = +d.lat;
d.lg = +d.lg;
});
console.log(data.data)
plot(data.data);
}
})
</script>
<style>
.point{
fill:rgb(247,148, 32);
stroke:black;
stroke-width:0.7;
opacity:0.7;
}
</style>
<script type ="text/javascript">
function draw(geo_data){
"use strict";
var margin = 75,
width = 1920 -margin,
height = 1080 -margin;
var svg = d3.select('body')
.append("svg")
.attr('class',"main")
.attr('width', width+margin)
.attr('height', height+margin)
var svg2 = svg.append('g')
.attr('class','map');
// convrt the long, lat to pixels ()x,y
var projection = d3.geo.mercator()
.scale(220)
.translate([width/2, height/1.5]);
//svg objects
var path = d3.geo.path().projection(projection);
var map = svg2.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.style('fill','rgb(9,157,217)')
.style('stroke','black')
.style('stroke-width', 0.5);
svg.append("g").attr("class","point");
}
function plot(data){
"use strict";
var margin = 75,
width = 1920 -margin,
height = 1080 -margin;
var spot = d3.select('svg.main').select("g.point");
// convrt the long, lat to pixels ()x,y
var projection = d3.geo.mercator()
.scale(220)
.translate([width/2, height/1.5]);
var coords = data.map(function(d) {
return projection([d.lg, d.lat]);
});
var points = spot.selectAll("circle")
.data(coords);
points.exit().remove();
points.enter()
.append("circle")
.classed("circle", true)
.attr('cx', function(d){return d[0];})
.attr('cy', function(d){return d[1];})
.attr('r', 10);
}
</script>
</head>
<body>
<script type = "text/javascript">
/*Use d3 to load the GeoJSON file*/
d3.json("/static/world_countries.json", draw);
</script>
</body>
</html>
答案 0 :(得分:1)
你应该查看Mike Bostock的Thinking with Joins文章。你遇到的问题是概念化如何使用D3来操作一个项目数组,但只有D3动画最近添加到数组中的新项目。这是通过.data()。enter()命令完成的。
我把你想要实现的目标放在一起,省略了地理方面的维度。该示例有三个主要部分,变量初始化,每次将新项目添加到数组时运行的绘制函数,以及随机添加项目然后调用draw()的服务器模拟。
你会看到所有的魔法都发生在draw()函数中。即使我们反复将不断增长的数据数组传递给函数,该函数也只会动画新添加的数据项。