【发布时间】:2016-08-10 09:03:32
【问题描述】:
我正在使用通过套接字 io 从服务器接收的值,并且我想制作一个在新值到达时实时更新的图表。
为了绘制图表,我使用了此示例中的代码:http://jsfiddle.net/chrisJamesC/YruDh/ 我收到以下表格的数据:
socket.on('news', function (data) { /*I make the chart here*/...});
我将next() 函数中的value 字段替换为我自己的值,即我从套接字接收的值,并且一切正常。
唯一的问题是,每当一个新的数据点到达时,每两秒,不仅图表会更新,而且我会在浏览器中获得相同图表的精确副本,位于现有图表下方。每次我收到一个新的数据点时,这种情况都会继续发生,直到最终我的浏览器中有 20 个或更多图表,导致它在某个时候崩溃。
我尝试在socket.on 之外创建图表,即使使用与上面示例中完全相同的随机数据,它也没有显示任何内容。所以我假设我需要在 socket.on() 方法中创建图表并每两秒更新一次。
如何在不制作多个副本的情况下创建和更新图表?
这是我现在拥有的完整代码:
socket.on('news', function (data) {
var o= JSON.parse(data);
awesome=o;
note3.push(awesome.valuee);
var t = -1
var n = 40,
duration = 750
data = d3.range(n).map(next);
function next(){
return {time: ++t, value: awesome.valuee }
}
var margin = {
top: 6,
right: 0,
bottom: 20,
left: 40
},
width = 560 - margin.right,
height = 120 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([t-n+1, t])
.range([0, width]);
var y = d3.time.scale()
.range([height, 0])
.domain([0, 400]);;
var line = d3.svg.line()
.interpolate("basis")
.x(function (d, i) {return x(d.time);})
.y(function (d, i) {return y(d.value);});
var svg = d3.select("body").append("p").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("margin-left", -margin.left + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var axis = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(x.axis=xAxis); */
var path = svg.append("g")
.attr("clip-path", "url(#clip)")
.append("path")
.data([data])
.attr("class", "line");
tick();
function tick() {
// update the domains
x.domain([t - n + 2 , t]);
// push the accumulated count onto the back, and reset the count
data.push(next());
// redraw the line
svg.select(".line")
.attr("d", line)
.attr("transform", null);
// slide the x-axis left
axis.transition()
.duration(duration)
.ease("linear")
.call(x.axis);
// slide the line left
path.transition()
.duration(duration)
.ease("linear")
.attr("transform", "translate(" + x(t-n) + ")")
.each("end", tick);
// pop the old data point off the front
data.shift();
}
});
非常感谢。
【问题讨论】:
-
在您引用的代码中,
tick函数正在更新图表。听起来您正在重新运行整个图表创建。当然,这是一个猜测,因为您没有显示任何代码...为您的问题创建一个可重现的示例,否则我们将无法提供帮助。 -
@Mark,我已经用相关代码编辑了这个问题。希望它可以帮助您理解问题。
-
查看您的代码确认,您正在对每个套接字事件重新运行整个图表创建。您只需要在每个套接字事件上运行
tick函数即可。 -
@Mark 这很有道理。但是,如果你看
next()函数,它使用了变量awesome,这基本上是我从服务器接收到的数据,我不能在socket.on方法之外使用它的值。
标签: javascript node.js sockets d3.js