How can I use 2 range sliders at the same time?

I want to filter the data in a table based on age and height at the same time using 2 range sliders.

I implemented 2 range sliders (age and height) using d3.slider.js and a dc.dataTable . I want to use these 2 range sliders at the same time, but it seems that they are not working properly.

In addition, under the table there is the text "49 selected from 49 entries." Numbers do not change when using sliders.

code:

  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

Plunker

+2
source share
2 answers

Original answer in dc.js user group .

Good use of d3.slider.js - I have not seen that I used dc.js. before

With a quick look, I see two problems here. Firstly, you use the same submission for both sliders, so both sliders filter age, as this is the dimension of the table. You probably want to create another dimension to filter by height, and you really don't need to attach to the chart.

Secondly, instead of just redrawing the chart with dataTable.redraw (), you probably want to call dataTable.redrawGroup () so that all the charts in its group chart are redrawn, including dataCount.

In particular:

  • you will need two filtering events in your newsletter

     var dispatch = d3.dispatch('load','filterAge','filterHeight'); 
  • the age slider will call filterAge

      dispatch.filterAge(value); 

    and the height slider will call filterHeight

      dispatch.filterHeight(value); 
  • the current filter event handler will now process filterAge and it will call redrawGroup

      dispatch.on('filterAge',function(value){ dataTable.replaceFilter(dc.filters.RangedFilter(value[0], value[1])); dataTable.redrawGroup(); }) 
  • add another filterHeight handler that directly filters dimensionHeight and also redraws the group of diagrams

      dispatch.on('filterHeight',function(value){ dimensionHeight.filter([value[0], value[1]]); dataTable.redrawGroup(); }) 
  • Reset Everyone will also need to clear the dimensionHeight . (Since this dimension is not used by any chart, dc.filterAll() will not find it.)

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

Plug your plunker .

+2
source

this to reset all, 49 selected from 49 entries are already changing accordingly

replace it

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

to that

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

add this after sending at boot

 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
source

Source: https://habr.com/ru/post/1274009/


All Articles