如何同时使用2个范围滑块?

时间:2017-09-03 14:58:17

标签: d3.js dc.js crossfilter

我想使用2个范围的滑块同时根据年龄和身高过滤表格中的数据。

我使用d3.slider.jsdc.dataTable实现了2个范围滑块(年龄和高度)。我想同时使用这两个范围滑块,但似乎它们无法正常工作。

此外,在表格下方,有49条记录中选择了“49条”。使用滑块时,数字不会改变。

代码:

    var dataTable = dc.dataTable("table#list");
    var dispatch = d3.dispatch('load','filter');

    d3.json('data.json',function(json){
        dispatch.load(json)
    });

    dispatch.on('load',function(json) {
        var formatNumber = d3.format( ",d");
        var facts = crossfilter(json);
        var dimensionAge = facts.dimension(function(d) {
            return +d.age;
        });
        var accessorAge = function(d) {
            return d.age;
        };
        var dimensionHeight = facts.dimension(function(d) {
            return +d.height;
        });
        var accessorHeight = function(d) {
            return d.height;
        };
        var range = d3.extent(json, accessorAge);
        var range2 = d3.extent(json, accessorHeight);
        var all = facts.groupAll();

        d3.select("div#slider3")
            .call(d3.slider().axis(true).min(range[0]).max(range[1]).value(range)
            .on("slide", function(evt,value) {
                dispatch.filter(value);
                d3.select("#slider3textmin").text(Math.floor(value[0]));
                d3.select("#slider3textmax").text(Math.floor(value[1]))
            }))

        d3.select("div#slider4")
            .call(d3.slider().axis(true).min(range2[0]).max(range2[1]).value(range2)
            .on("slide", function(evt,value) {
                dispatch.filter(value);
                d3.select("#slider4textmin").text(Math.floor(value[0]));
                d3.select("#slider4textmax").text(Math.floor(value[1]))
            }))


        FieldNames = [
            "",
            "Age",
            "Weight",
            "Height",
            "Eye Color",
            "Hair Color",
            "Race",
            "Sex",
            "Annual Income"
        ];

        d3.select("tr#FieldNames").selectAll("th")
            .data(FieldNames)
            .enter()
            .append("th") 
            .append("text")
            .text(function(d){ 
                return d;
            });

        dataTable
            .dimension(dimensionAge)
            .group(function(d) {
                return d.sex;
            })
            .columns([
                function(d) {return "";},
                function(d) {return d.age;},
                function(d) {return d.weight;},
                function(d) {return d.height;},
                function(d) {return d.eyeColor;},
                function(d) {return d.hairColor;},
                function(d) {return d.race;},
                function(d) {return d.sex;},
                function(d) {return formatNumber(d.annualIncome);}
            ]);   

        dispatch.on('filter',function(value){
            dataTable.replaceFilter(dc.filters.RangedFilter(value[0], value[1]));
            dataTable.redraw();
        })

        dc.dataCount(".dc-data-count")
            .dimension(facts)
            .group(all);

        dc.renderAll();

    });

Link to the website

Plunker

2 个答案:

答案 0 :(得分:2)

原始回复on the dc.js users group

  

很好地使用了d3.slider.js - 我以前没有看到过与dc.js一起使用过的。

     

快速浏览一下,我发现这里有两个问题。首先,你正在使用一个   两个滑块的发送,所以两个滑块都过滤了年龄,   因为这是表格的维度。你可能想要创造   另一个按高度过滤的维度,你真的不需要   将其附加到图表上。

     

其次,而不是仅使用dataTable.redraw()重绘图表,   你可能想调用dataTable.redrawGroup()以便所有图表   在其图表组中重新绘制,包括dataCount。

具体做法是:

  1. 您的发送中需要两个过滤器事件

    var dispatch = d3.dispatch('load','filterAge','filterHeight');
    
  2. 年龄滑块将调用filterAge

                dispatch.filterAge(value);
    

    并且高度滑块将调用filterHeight

                dispatch.filterHeight(value);
    
  3. 当前filter事件处理程序现在将处理filterAge,它将调用redrawGroup

        dispatch.on('filterAge',function(value){
            dataTable.replaceFilter(dc.filters.RangedFilter(value[0], value[1]));
            dataTable.redrawGroup();
        })
    
  4. 我们添加了另一个filterHeight处理程序,它直接过滤dimensionHeight并重绘图表组

        dispatch.on('filterHeight',function(value){
            dimensionHeight.filter([value[0], value[1]]);
            dataTable.redrawGroup();
        })
    
  5. 全部重置也必须清除dimensionHeight。 (由于此维度未被任何图表使用,dc.filterAll()无法找到它。)

            <a href="javascript: dimensionHeight.filter(null); dc.filterAll(); dc.renderAll();">Reset All</a>
    
  6. Fork of your plunker

答案 1 :(得分:0)

这对于全部重置,49条记录中的49条已经正确改变

替换此

<a href="javascript: dimensionHeight.filter(null); dc.filterAll(); dc.renderAll();">Reset All</a>

到这个

<a href="#" onclick="sololo()">Reset All</a>

在加载调度后添加此内容

dispatch.on('load',function(json) {
//your code
})       

function sololo(){
                   //table
               dispatch.filterAge([0,100]);
               dispatch.filterHeight([0,100]);
               //text slider
               d3.select("#slider4textmin").text(0)
                     d3.select("#slider4textmax").text(0)
                     d3.select("#slider3textmin").text(0);
                     d3.select("#slider3textmax").text(0)
                     //slider
                     d3.select('#slider3').select('#handle-one').style('left','0%')
               d3.select('#slider3').select('#handle-two') .style('right','0%')
               d3.select('#slider3').select('div').style('left','0%').style('right','0%') 
                     d3.select('#slider4').select('#handle-one').style('left','0%')
               d3.select('#slider4').select('#handle-two') .style('right','0%')
               d3.select('#slider4').select('div').style('left','0%').style('right','0%') 
    }