DC.js dataTable的自定义文本过滤器

rbr*_*tow 9 javascript d3.js crossfilter dc.js

我正在构建一个仪表板来显示一些数据.我有几个图表和一个列出所有数据的表格.我正在尝试添加搜索功能来过滤图表.我有很多公司和一些关于每个公司的数据.因此,如果我搜索"Appl",只有以"Appl"开头的公司将列在数据表中,图表将反映这一点.

我对当前实现的唯一问题是当我更改此过滤器或清除它时.数据似乎很好,但图表渲染不正确.清除后它们不会返回原始位置,或者以某种方式添加额外数据.任何提示将不胜感激.

 $("#table-search").on('input',function(){
   text_filter(companyDimension,this.value);//companyDimension is the dimension for the data table

function text_filter(dim,q){
 dashTable.filterAll();
 var re = new RegExp(q,"i")
 if (q!='')
 {
    dim.filter(function(d){
        if (d.search(re)==0)
            return d;
    });
}
dc.redrawAll();
graphCustomizations();  }});
Run Code Online (Sandbox Code Playgroud)

dc.js代码

var ndx = crossfilter(resource_data);
//Dimensions 
companyDimension = ndx.dimension(function(d){
    return d["Company Name"]
});
dashTable.width(800).height(800)
    .dimension(companyDimension)
    .group(function(d){
        return "List of all Selected Companies";
    })
    .size(1774)
    .columns([
            function(d){return d["Company Name"]; },
            function(d){return d["Revenue Source"];},
            function(d){return d["Commodity"];},
            function(d){return "$"+parseFloat(d["Revenue"]).formatMoney(0,'.',',');}
        ])
    .sortBy(function(d){return d["Company Name"]})
    .order(d3.ascending);
Run Code Online (Sandbox Code Playgroud)

就是这样,图表只是在同一个crossfilter对象上过滤不同的维度.

我试着做几件事情给text_filter等功能,dim.filterAll(),dim.filter(null),dc.renderAll().当我检查维度中的数据时,在每个过滤器之前和之后它是正确的,其他图表似乎没有正确处理它.

我已经尝试直接向dc dataTable添加一个基本过滤器,但是我无法使用自定义过滤器功能.所以我可以做类似的事情dashTable.filter(q),它会起作用,但我必须给它整个公司名称才能显示任何内容,但是当我应用它并删除它时,图表会正确呈现.我尝试过使用 dashTable.filterHandler()但它总是会返回一个错误,但是如果你知道如何使它工作,我会很好奇,因为即使使用dc.js文档中的示例我也无法使它运行.

任何帮助将不胜感激.

编辑:

这里是大部分完整代码的小提琴,我将一些代码混杂在一起以使其正常工作.http://jsfiddle.net/rbristow/HW52d/1/

要重现该错误,请在搜索框中输入一个字母然后清除它并输入另一个字母,您可以看到总数未正确重置.

Jas*_*n S 10

在这个块中:

if (q != '') {
    dim.filter(function(d) {
        if (d.search(re) == 0)
            return d;
    });
}
Run Code Online (Sandbox Code Playgroud)

您的过滤器需要是:

dim.filter(function(d) { return 0 == d.search(re); });
Run Code Online (Sandbox Code Playgroud)

不过呢,你不应用任何过滤器,dim如果q == ''因此它应该是

if (q != '') {
    dim.filter(function(d) {
        return 0 == d.search(re);
    });
} else {
    dim.filterAll();
}
Run Code Online (Sandbox Code Playgroud)

说明:

crossfilter.js过滤器的返回值中,回调测试如下:

if (!(filters[k = index[i]] & one) ^ (x = f(values[i], i))) {
    if (x) filters[k] &= zero, added.push(k);
    else filters[k] |= one, removed.push(k);
}
Run Code Online (Sandbox Code Playgroud)

如果过滤器返回true并且项目已经在当前视图中,则不应该执行任何操作.true ^ true -> false.

但在你的情况下,true正在使用字符串xor-ed - 注意,这是按位xor,而不是逻辑,因为Javascript缺少逻辑xor - 它将始终计算为true值.因此,当您added应该单独使用时,您希望在过滤集中使用的值.

这是一个奇怪的使用按位xor.我在SO上看了这个,最高投票回答为什么JavaScript中没有逻辑xor?包含"Bitwise XOR非常有用,但在我多年的编程中,我从未需要逻辑异或." 鉴于crossfilter.js强调性能可能会丢弃一些错误检查,并希望使用快速"mathy"操作.

  • 为了使过滤器对输入框中包含子字符串的任何字符串起作用,您可以将return 0 == d.search(re);修改为return -1!= d.search(re); `。否则,过滤器仅返回以您输入的子字符串开头的项目。 (2认同)