我正在使用通过套接字io从服务器收到的值,并且我希望制作一个实时更新的图表,因为新值会到达。
为了绘制图表,我使用的是此示例中的代码:http://jsfiddle.net/chrisJamesC/YruDh/ 我收到以下表格中的数据:
socket.on('news', function (data) { /*I make the chart here*/...});
我用自己的值替换了value
函数中的next()
字段,也就是我从套接字收到的值,一切都很好。
唯一的问题是,每当新数据点到达时,每两秒钟,不仅图表会更新,而且我会在浏览器中获得相同图表的精确副本,位于现有图表下方。每当我收到一个新的数据点时,这种情况就会继续发生,直到最终我的浏览器中有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();
}
});
非常感谢你。
答案 0 :(得分:2)
完全未经测试的代码,但您需要重构为以下内容:
var t = -1,
n = 40,
duration = 750,
data = [];
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");
function tick() {
// update the domains
x.domain([t - n + 2, t]);
// 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) + ")");
// pop the old data point off the front
if (data.length > 40) data.shift();
}
socket.on('news', function(p) {
p = JSON.parse(p);
data.push({
time: ++t,
value: p.valuee
})
tick();
});
答案 1 :(得分:0)
我已经使用ws websocket实现了这个实时绘图,你可以查看它,这是脚本,你也将在这里有html,但没有添加,而且,有一个服务器,它服务于此d3文件以及生成随机json,您可以创建此服务器并检查其实时是否实时
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
</div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var ws = new WebSocket("ws://localhost:3000/");
var count = 0, tempArr = [];
ws.onmessage = function (message) {
if(count<10) {
tempArr.push(JSON.parse(message.data));
count++;
}
init();
}
function init(){
var vis = d3.select("#visualisation"),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
},
xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([2000, 2010]),
yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([134, 215]),
xAxis = d3.svg.axis()
.scale(xScale),
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineGen = d3.svg.line()
.x(function(d) {
return xScale(d.year);
})
.y(function(d) {
return yScale(d.sale);
})
.interpolate("basis");
vis.append('svg:path')
//.enter()
.attr('d', lineGen(tempArr/*data*/))
//.attr('d', lineGen(obj.year))
.transition()
.duration(1000)
//.delay(2000)
.attr('stroke', 'green')
.attr('stroke-width', 2)
.attr('fill', 'none');
console.log(JSON.parse(message.data));