添加过滤,搜索和分页的实时流表
Adding filtering, searching and pagination to realtime streaming table
我有一个使用节点提供的数据实时更新的表。表是用d3.js渲染的。
我的问题是,我不知道如何添加过滤,搜索和分页功能的表使用d3.js。我是一个乞丐,很难理解哪里是放置代码的最佳位置。我一直在考虑使用外部库来完成它,但如果我找到一种方法来使用d3.js,它会更好更干净。
这是我的代码:
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 is 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)
});
看起来你的主要D3图表渲染方法已经设置为使用一般更新模式,所以你应该很好地去那里。
过滤和搜索的最佳选择可能只是使用原生JavaScript解决方案。只要用过滤后的数据集调用setupData
方法,图表就会更新。例如:
var allData;
var loadItems = function(items) {
var item;
allData = [];
for (item in items) {
allData.push(item);
}
}
var filterMatching = function(matcher) {
var item;
var filteredData = [];
for (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); });
分页有点棘手,但仍然非常简单。你只需要做一点数学运算。
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);
}
现在让它们很好地一起工作可能需要一些努力。
或者,你可以考虑使用像Crossfilter这样的库,它可以很好地与D3配合使用。在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 a dimension
conversion_rate.filterRange([0.5, 1]);
title.filterFunction(function (d) { return /foobar/.test(d); });
// take the top x of a dimension
conversion.group().top(5);
如果你有很多数据要过滤,使用交叉过滤器会快得多。然而,由于一开始就将所有数据绘制成图表,因此似乎没有那么多数据,因此使用原生JavaScript手工处理可能是一种方法。
相关文章:
- 如何使用skip参数使用angular ui引导进行服务器端分页
- 如何通过引用var Using DataTables来进行分页或排序
- 使用CSS或JavaScript计算分页符的数量
- DataTables-创建自定义分页样式(加载更多样式)
- 使用ajax的服务器端分页&jQuery
- 分页:如何用AJAX加载第一个页面
- dataTables-如何自定义分页类型以显示最后一个页码后面的省略号,
- 不带jquery的全屏分页
- 更改组合框分页后,getValue和getRawValue返回相同的值
- jQuery简单分页
- 使用jQuery在表中分页
- jQuery分页下一页和上一页按钮在点击零或超过最后一页后失败
- jQuery:根据select选项中的每页项目进行分页
- 如何为我的分页添加格式
- 用键盘分页jQuery下一个和上一个控件.触发器('点击')不'不起作用
- 如何在emberjs中使用幻影假数据进行分页
- 如何在分页事件中突出显示数据表中的单词
- 在网页网格表上进行实时搜索,分页仅在实际页面上工作
- jquery中分页列表的实时搜索
- 添加过滤,搜索和分页的实时流表