2017-09-03 64 views
2

我想使用2個範圍滑塊同時過濾基於年齡和高度的表中的數據。如何在同一時間使用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

原始響應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

+0

你可不可以,pl緩解,解決問題與表中的文字「49選出49記錄」?當我使用年齡滑塊時,數字根本沒有改變。並且「全部重置」鏈接無法正常工作。 –

+0

無法保存'filterAge'的'redrawGroup'更改,因爲我不習慣Plunker。修正了這一點,並添加**重置所有**到我的答案。 – Gordon

+0

@戈登我想編輯你的答案,但我不知道如何編輯猛擊,抱歉.. – KEKUATAN

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%') 
    } 
+0

關於重置滑塊的好處。 Oof,這是做到這一點的唯一方法嗎? – Gordon

+0

mmmm ....你不使用liblary手動繪製滑塊,所以最好的辦法是注入html元素,你可以使用循環,你可以刪除該滑塊並再次繪製,或使用該滑塊上的構建函數。 js要這樣做,如果有一個 – KEKUATAN

+0

我戳了一下d3.slider.js,看起來好像沒有好的API - 它允許更新值,但它期望值是標量,並且如果你崩潰傳遞數組進行更新。所以我認爲這是現在最好的滑塊解決方案。一部分似乎缺少 - 這不會重置右側滑塊,只是藍色背景。 – Gordon