我已经看过许多使用D3实时数据绘图的精彩演示。 http://bl.ocks.org/simenbrekken/6634070是我喜欢的人。但是,我见过的所有示例都使用随机生成的值。我想绘制实时数据,并将最新值显示为更新数字显示。我使用python脚本将传感器读数中的数据写入csv文件。 csv在每一行上有3个值:unixtime,sensor1_value,sensor2_value。每5秒钟就有一个新的数据线被添加到一个具有720行数据的环形缓冲区文件中。当显示网页时,我想读取缓冲区文件中的720行,然后使用写入文件末尾的每个新值更新图形。我还可以每5秒创建一个只有新行csv的文件,这样就可以通过只读取1行csv而不是操作整个缓冲区来执行更新。
有没有人知道一个例子,或者正确的代码来实现这个目标?
上述例子的代码是:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.graph .axis {
stroke-width: 1;
}
.graph .axis .tick line {
stroke: black;
}
.graph .axis .tick text {
fill: black;
font-size: 0.7em;
}
.graph .axis .domain {
fill: none;
stroke: black;
}
.graph .group {
fill: none;
stroke: black;
stroke-width: 1.5;
}
</style>
</head>
<body>
<div class="graph"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var limit = 60 * 1,
duration = 750,
now = new Date(Date.now() - duration)
var width = 500,
height = 200
var groups = {
current: {
value: 0,
color: 'orange',
data: d3.range(limit).map(function() {
return 0
})
},
target: {
value: 0,
color: 'green',
data: d3.range(limit).map(function() {
return 0
})
},
output: {
value: 0,
color: 'grey',
data: d3.range(limit).map(function() {
return 0
})
}
}
var x = d3.time.scale()
.domain([now - (limit - 2), now - duration])
.range([0, width])
var y = d3.scale.linear()
.domain([0, 100])
.range([height, 0])
var line = d3.svg.line()
.interpolate('basis')
.x(function(d, i) {
return x(now - (limit - 1 - i) * duration)
})
.y(function(d) {
return y(d)
})
var svg = d3.select('.graph').append('svg')
.attr('class', 'chart')
.attr('width', width)
.attr('height', height + 50)
var axis = svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(x.axis = d3.svg.axis().scale(x).orient('bottom'))
var paths = svg.append('g')
for (var name in groups) {
var group = groups[name]
group.path = paths.append('path')
.data([group.data])
.attr('class', name + ' group')
.style('stroke', group.color)
}
function tick() {
now = new Date()
// Add new values
for (var name in groups) {
var group = groups[name]
//group.data.push(group.value) // Real values arrive at irregular intervals
group.data.push(20 + Math.random() * 100)
group.path.attr('d', line)
}
// Shift domain
x.domain([now - (limit - 2) * duration, now - duration])
// Slide x-axis left
axis.transition()
.duration(duration)
.ease('linear')
.call(x.axis)
// Slide paths left
paths.attr('transform', null)
.transition()
.duration(duration)
.ease('linear')
.attr('transform', 'translate(' + x(now - (limit - 1) * duration) + ')')
.each('end', tick)
// Remove oldest data point from each group
for (var name in groups) {
var group = groups[name]
group.data.shift()
}
}
tick()
</script>
</body>
</html>
而我用来创建一个静态图表的代码来自我的csv和一行:
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<!-- load the d3.js library -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 900 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Set the ranges
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(10);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(10);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.o2); });
// Adds the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Get the data
d3.csv("./data/buffer.txt", function(error, data) {
data.forEach(function(d) {
d.time = +d.time;
d.o2 = +d.o2;
console.log(d.time);
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.time; }));
y.domain([0, d3.max(data, function(d) { return d.o2; })]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
</body>