d3.js - Graphing live re-syncing data in D3js in a fixed window with linear easing -
i'm interested in graphing live-ish data in d3js. now, when "live-ish" mean i'll collecting data every 200ms +/- 10ms, there may several minute long periods of inactivity. fortunately, input data time-stamped!
what have far: i've followed line drawing in d3 guides (eg: this) , have y axis value range/domain want. have x axis range want , moving domain per standard time-series fixed-width graph. is, if graph's x axis domain (0:15, 0:35) in 5 seconds (0:20, 0:40). transitions nicely it's using linear easing.
i have mock-data being output each iteration of graph tick. domain set such new points out of x-axis domain such allow smooth effect per 1. in all, looks great.
so go here? desired result: data comes in asynchronously , placed precisely @ x-axis time-stamped location. if data date, gets placed juuust outside x-axis domain , has smooth transition in. if data doesn't arrive in time, graph continues without drawing new points until data received, @ time adds each point @ appropriate time-stamp retroactively. if data missing period doesn't arrive @ all, continue gap in graph. can emulate calling...
d3.select(window).on("click", .. ) effectively, can click add random data @ current time-stamp using anonymous function allows me mimic data / event structure code should handle.
i think current confusion due how add data , draw path it.
var line = d3.svg.line() .interpolate("basis-open") .x(function(d, i) { return x(now - (n-1-i)*duration); }) .y(function(d, i) { return y(d); }); var axis = svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(x.axis = d3.svg.axis().scale(x).orient("bottom")); svg.append("g") .attr("class", "y axis") .call(d3.svg.axis().scale(y).orient("left")); var path = svg.append("g") .attr("clip-path", "url(#clip)") .append("path") .datum(data) .attr("class", "line") the big question: y-values correspond path.datum(data) (data array of values) appropriately, when push data array draw line, places each point graphically @ equal distance apart. how break out of mono-variable graph without destroying time-series smooth scrolling animation? record second array of timestamps alongside data array, how integrate line? ideally, i'd have them both part of same array sort timestamp when call data.shift() oldest data gone. tried changing "duration" of transition function made graph accelerate weirdly , didn't break equidistance of points on x.
how set y-axis graph take account x-location without breaking graph?
alright, figured out pretty straightforward way of doing wanted while still using .datum(data) instead of .data(data) (where 'data' array). instead of passing in array of values .datum, pass in array of objects. or, once data = [value1, value2, ...] data = [{gx:timestamp1, gy:value1}, {gx:timestamp2, gy:value2}, ...].
my line x-axis / y-axis functions now...
.x(function(d, i) { return x(d.gx); }) .y(function(d, i) { return y(d.gy); }); which ends being bit neater initial run @ it. transition functions didn't have change.
the final puzzle piece data comes in time-stamped out of order. fortunately, display domain isn't large , thus, don't need store many values in array. such, when new data comes in sort make line not wobbly-bobbly mess.
data.sort(function(a,b){ return a.gx - b.gx}); and voila! if size of array beyond boundary, shift off data. gives effect of sliding timeseries window of past n seconds time-stamped data points may arbitrarily dumped on , displayed properly.
Comments
Post a Comment