Skip to content

Instantly share code, notes, and snippets.

@ajfarkas
Last active Jun 2, 2016
Embed
What would you like to do?
Realtime Line Graph

Realtime Line Graph

A simple line graph that updates in realtime. In this case, it is showing the millisecond value generated by Javascript every 100ms, over the course of 12 seconds.

Notes:

if you leave this tab for a second and come back, you can see that window.setTimeout slows down. D3 is simply connecting points, so when the data becomes sparse, you get unexpected patterns.

You may also notice that the points never hit the X-axis: again, points are only generated every 100ms, so unless you load this script at exactly 000ms, D3 will never see a 0ms value. Limitations of data…

// store a bunch of time values for the graph
times = []
function createGraph() {
// this is how time would be stored on the server
var now = Date.now()
// add datum
times.push({
milliseconds: parseInt(now.toString().slice(-3)),
time: now
})
// remove old data
if (times.length > 120)
times.shift()
// define plot boundaries
var width = 300,
height = 60
var margin = {
top: 0,
right: 10,
bottom: 5,
left: 50
}
var plot = {
width: width - margin.right - margin.left,
height: height - margin.top - margin.bottom
}
// x-axis is time
var x = d3.time.scale()
.range([0, plot.width])
// y-axis is numerical
var y = d3.scale.linear()
.range([plot.height, 0])
// set axis scales
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom')
.tickFormat('')
.tickSize(0, 0)
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
.tickSize(0, 0).ticks(3)
// set time span to show
var timeCap = width * 40 // 12s
var latest = times.length
? times[times.length - 1].time
: 0
var data = times.filter(function(d) {
return d.time >= latest - timeCap
})
x.domain([latest - timeCap, latest])
y.domain([0, 1000])
var line = d3.svg.line()
.x(function(d) { return x(parseInt(d.time)) })
.y(function(d) { return y(d.milliseconds) })
// make the graph
var svg = d3.select('#graph')
var graph = undefined
if (d3.select('.graph-g').empty()) {
graph = svg.append('g')
.attr('class', 'graph-g')
.attr('width', plot.width)
.attr('height', plot.height)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
//add axes
graph.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + plot.height + ')')
.call(xAxis)
.append('text')
.attr('dx', (plot.width / 2))
.attr('dy', '1em')
.style('text-anchor', 'middle')
.text('Time')
graph.append('g')
.attr('class', 'y axis')
.call(yAxis)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('dx', (0 - plot.height / 2))
.attr('dy', '-2.8em')
.style('text-anchor', 'middle')
.text('ms');
} else {
graph = d3.select('.graph-g')
}
// remove old line
graph.select('.line').remove()
//add data line
graph.append('path')
.datum(data)
.attr('class', 'line')
.attr('d', line)
}
var startGraph = window.setInterval(createGraph, 100)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<link href="styles.css" rel="stylesheet" type="text/css"/>
<title>Realtime Line Graph</title>
</head>
<body>
<svg id="graph" viewBox="0 0 300 60"></svg>
</body>
<script src="graph.js" rel="javascrip" type="text/javascript"></script>
</html>
#graph {
width: 960px;
height: 480px;
}
.line {
fill: none;
stroke: black;
}
text {
font-size: 0.5rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment