// construct keys, start and end time; currently using 1 hour as baseline var keys = ["a", "b", "c", "d", "e"] , now = new Date().valueOf() , duration = 1000 * 60 * 60 , start = now - duration , end = now , min = 1 , max = 100 , sample_count = 20 ; // generate some data var data = generateData(keys, sample_count, start, end, min, max); // need the time range for the slider var t = d3.scale.linear().domain([0, 1]).rangeRound([start, end]); // start with the last known values var cursor = R.map(R.last, data); // draw the table var $table = d3.select("#data-table"); $table.selectAll("tr") .data(cursor) .enter().append("tr").selectAll("td") .data(function(d) { return [d.series, d.value, d.iso_time]; }) .enter().append("td") .text(function(d) { return d; }); // setup the range slider; update when the value changes $slider = d3.select("#time-slider").on("input", function() { updateTable($table, select(t(this.value), data)); }); // debugging table var $debugging = d3.selectAll("div.series") .data(data) .enter().append("div").classed("series", true); $debugging.append("h3").text(function(d) { return d[0].series; }); $debugging.append("table") .selectAll("tr") .data(function(d) { return d; }) .enter().append("tr") .selectAll("td") .data(function(d) { return [d.series, d.step, d.value, d.time, d.iso_time]; }) .enter().append("td") .text(function(d) { return d; }); // update the table values function updateTable($target, data) { $target.selectAll("tr") .data(data) .selectAll("td") .data(function(d) { return [d.series, d.value, d.iso_time]; }) .text(function(d) { return d; }); } function select(time, data) { // var predicate = R.compose(R.gte(time), R.prop("time")); // return R.map(R.find(predicate), data); // ugh return R.map(function(d) { return R.findLast(function(v) { return v.time <= time; })(d) || R.head(d); })(data); } /** * data generation * */ function generateData(keys, count, start, end, min, max) { var generateFn = R.curry(generateDataForKey)(R.__, count, start, end, min, max); return R.map(generateFn, keys); } /** * generate data for a single key */ function generateDataForKey(key, count, start, end, min, max) { // setup ranges var timeRange = d3.scale.linear().domain([0, 1]).rangeRound([start, end]) , valueRange = d3.scale.linear().domain([0, 1]).rangeRound([min, max]) ; // sample function var sampleFn = R.curry(makeSample)(timeRange, valueRange, key); // generate samples return R.sortBy( R.prop("time"), R.map(sampleFn, R.range(0, count)) ); } /** * generate a single random sample */ function makeSample(timeRange, valueRange, key, step) { var t = timeRange(Math.random()) , isoTime = new Date(t).toISOString() ; return { series: key , step: step , time: t , iso_time: isoTime , value: valueRange(Math.random()) }; }