javascript - Adding filtering, searching and pagination to realtime streaming table -


i have table updates using data served node in realtime. table rendered using d3.js.

my problem don't know how add filtering, searching , pagination capabilities table using d3.js. i'm begginer , having trouble understanding best place put code. i've been thinking using external library it's better , cleaner if find way d3.js.

this code:

var table = d3.select('#data')  table.append('thead')     .append('tr')     .selectall('th')         .data(['title', 'visits', 'sales', 'conversion(%)'])     .enter()         .append('th')         .text(function (d) { return d })  table.append('tbody')  function setupdata(data) {     var rows = d3.select('tbody')         .selectall('tr')         .data(data, function(d) { return d.title })      var entertd = rows.enter()         .append('tr')             .selectall('td')                 .data(function(d) { return d3.map(d).values() })             .enter()                 .append('td')      entertd.append('div')     entertd.append('span')      var td = rows.selectall('td')         .data(function(d) { return d3.map(d).entries() })         .attr('class', function (d) { return d.key })      td.select('div')         .transition()         .duration(800)         .style('width', function(d) {             switch (d.key) {                 case 'conversion_rate' :                     // percentage scale static                     scale = d3.scale.linear()                         .domain([0, 1])                         .range([0, 100])                     break;                 case 'today_visits':                  case 'sold_today' :                     scale = d3.scale.linear()                     .domain(d3.extent(data, function(d1) { return d1[d.key] }))                     .range([0, 100])                     break;                 default:                     return '0px'             }             return scale(d.value) + 'px'         })     td.select('span')         .text(function(d) {             if (d.key == 'conversion_rate') {                 return math.round(100*d.value).tofixed(2) + '%';             }             return d.value         }) }   var socket = io();  //var data = []; socket.on('sellers-'.concat(<%= seller %>), function(msg){     var data = [];     var seller = $.parsejson(msg);     var items = seller['items'];     for(item in items) {         var item_data = items[item];         data.push({'title': item_data['title'], 'today_visits': item_data['today_visits'], 'sold_today': item_data['sold_today'], 'conversion_rate': item_data['conversion_rate']});     }     setupdata(data);     //setupdata(json.parse(msg).items) }); 

it looks main d3 chart render method set use general update pattern, should go there.

you're best bet filtering , searching using native javascript solution. call setupdata method filtered data set, , chart update. instance:

var alldata;  var loaditems = function(items) {     var item;      alldata = [];     (item in items) {         alldata.push(item);     } }  var filtermatching = function(matcher) {     var item;     var filtereddata = [];     (item in alldata) {         if (matcher(item)) filtereddata.push(item);     }     setupdata(filtereddata); }  // filter on conversion rate filtermatching(function(item) { return item.conversion_rate > 0.5; });  // search on title filtermatching(function(item) { return /foobar/.test(item); }); 

pagination little bit trickier, still pretty straightforward. need little math.

var itemsperpage = 10;  var numberofpages() {     return math.ceil(alldata.length / itemsperpage); }  var gotopage(pagenumber) {     var firstindex = (pagenumber - 1) * itemsperpage;     var pageitems = alldata.slice(firstindex, firstindex + itemsperpage);      setupdata(pageitems); } 

now getting work nicely may take bit of effort.

alternatively, applying library crossfilter, plays nicely d3. filtering , pagination might in crossfilter:

var filter = crossfilter(records);  var conversion_rate = filter.dimension(function(d) { return d.conversion_rate; }); var title = filter.dimension(function(d) { return d.title; });  // filter on dimension conversion_rate.filterrange([0.5, 1]); title.filterfunction(function (d) { return /foobar/.test(d); });  // take top x of dimension conversion.group().top(5); 

if have lot of data filter using crossfilter faster. however, since you're charting data @ start anyway, doesn't seem have much, hand-rolling native javascript might way go.


Comments

Popular posts from this blog

node.js - Using Node without global install -

How to access a php class file from PHPFox framework into javascript code written in simple HTML file? -

java - Null response to php query in android, even though php works properly -