【问题标题】:How can I use 2 range sliders at the same time?如何同时使用 2 个范围滑块?
【发布时间】:2018-02-11 23:06:43
【问题描述】:

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

我使用d3.slider.jsdc.dataTable 实现了2 个范围滑块(年龄和身高)。我想同时使用这 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

【问题讨论】:

    标签: d3.js dc.js crossfilter


    【解决方案1】:

    原始回复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>
      

    Fork of your plunker.

    【讨论】:

    • 能否也请您解决表格下方“49 条记录中选择了49 条”的问题?当我使用年龄滑块时,数字根本没有变化。而且“全部重置”链接也无法正常工作。
    • 未能为filterAge 保存redrawGroup 更改,因为我不习惯Plunker。修复了这个问题,并在我的答案中添加了 Reset All
    【解决方案2】:

    这个reset all,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%') 
        }
    

    【讨论】:

    • 关于重置滑块的要点。 Oof,这是唯一的方法吗?
    • mmmm.... 你不是手动绘制滑块你使用库,所以最好的办法是注入 html 元素,你可以使用循环,你可以删除该滑块并再次绘制它,或者使用如果有,则在该 slider.js 上构建函数来做到这一点
    • 我稍微戳了一下 d3.slider.js,确实看起来没有好的 API 用于此 - 它允许更新值,但它希望该值是标量,如果您通过则崩溃用于更新的数组。所以我认为这是目前滑块的最佳解决方案。似乎缺少一部分 - 这不会重置右侧滑块,只是重置蓝色背景。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    相关资源
    最近更新 更多