有两个jQuery下拉列表的依赖过滤

时间:2018-10-18 19:53:35

标签: javascript jquery d3.js leaflet

我有两个下拉菜单。一个下拉列表(包含定量变量)确定圆的大小,另一个下拉列表(包含分类变量)确定传单图上创建的圆形的颜色。当我选择大小变量时,我希望将颜色变量固定为他先前选择的变量。 “ sizedropdown”和“ colordropdown”包含变量的名称,而sizeExtents包含定量变量的最小值和最大值,colorextent包含唯一的类别。

var dropDown_size = d3.select("#sizeSection")
    .selectAll("option").data(sizedropDown)
    .enter().append("option")
    .text(function(d) {return d ;} )
    .attr("value", function(d,i) { return i;} );

var dropDown_color = d3.select("#colorSection")
    .selectAll("option").data(colordropDown)
    .enter().append("option")
    .text(function(d) { return d;} )
    .attr("value", function(d,i) {return i;} );

d3.select('#sizeSection')
  .on("change", function () {
      var section_color = 0;
      var sect_size = document.getElementById("sizeSection");
      var section_size = sect_size.options[sect_size.selectedIndex].value;
      updateSubset(all_data.features,section_size,section_color);
  });

d3.select('#colorSection')
  .on("change", function () {
      var section_size = 0;
      var sect_color = document.getElementById("colorSection");
      var section_color = sect_color.options[sect_color.selectedIndex].value;
      updateSubset(all_data.features,section_size,section_color);
  });

我的updateSubset函数可在地图上使用。更新子集函数如下所示:

function updateSubset(subset,section_size,section_color) {

    var size_name = sizedropDown[section_size];
    var size_extent = sizeExtents[section_size];
    var sizeScale = d3.scale.sqrt()
        .domain(size_extent)
        .range([5,15]);

    var color_name = colordropDown[section_color]
    var color_extent = colorExtents[section_color];
    var c10 = function(d){
        var colors = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099",
                      "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395",
                      "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300",
                      "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"];
        return  colors.slice(0,d)};
    var ordinalScale = d3.scale.ordinal()
        .domain(color_extent)
        .range(c10(color_extent.length));

    var bounds = path.bounds({
        type: "FeatureCollection",
        features: subset
    });
    var topLeft = bounds[0];
    var bottomRight = bounds[1];
    var arc = d3.svg.symbol().type('circle');

    svg.attr("width", bottomRight[0] - topLeft[0])
       .attr("height", bottomRight[1] - topLeft[1])
       .style("left", topLeft[0] + "px")
       .style("top", topLeft[1] + "px");

    g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");

    var points = g.selectAll("path")
        .data(subset,function(d){return d.geometry.coordinates;});

    points.enter().append("path");
    points.attr("d", path).attr("class", "points");
    points.attr("d",path.pointRadius(function(d) {
        return sizeScale(d.properties[size_name]);})
    );
    points.style("fill-opacity", 0.4);
    points.style("fill", function(d){
        return ordinalScale(d.properties[color_name]);}
    );
}

我不明白当另一个过滤器改变时如何存储一个过滤器的选择。

1 个答案:

答案 0 :(得分:1)

有几种方法可以解决此问题,但我认为最简单的方法是将当前值存储在select元素更改侦听器和需要它的任何代码(例如updateSubset)都可以访问的变量中。这是一个简单的示例:

// all functions in this script can access `current`
var current = {
  colour: 'schemeBlues',
  size: '30'
}

// when the select element changes, set the current value of `this.name`
// (i.e. either current.colour or current.size) to `this.value`
// `this` is the element that triggered the event
function changeListener () {
  current[ this.name ] = this.value

  // print out current values
  d3.select('#result')
    .append('p')
    .text('Colour: ' + current.colour + '; size: ' + current.size)
}

// add a select element with `arr` as the option items and `name` as 
// the select element id and name
function addCntrl ( arr, name ) {
  // add a select element
  var cntrl = d3.select('#controls')
    .append('select')
    .attr('name', name )
    .attr('id', name )

  cntrl.selectAll('option')
  .data( arr )
    .enter()
    .append( 'option' )
    .attr('value', d => d.value )
    .text( d => d.name )

  // set the selected value to current[name] (i.e. current.colour or current.size)
  cntrl.property('value', current[name])

  cntrl.on('change', changeListener)
}

function init() {
  var colours = Object.keys(d3)
      .filter( function(c){ return (c.indexOf('scheme') !== -1) })
      .map( function(c) {
          return {
            value: c,
            name: c.replace('scheme','')
                   .replace(/(\D)(\d)/, '$1 $2')
          }
        } ),
  sizes = [ '10', '20', '30', '40', '50' ].map( e => { return { value: e, name: e } } )

  // add select elements to the page
  addCntrl(colours, 'colour')
  addCntrl(sizes, 'size')
  
}


init()
<script src="http://d3js.org/d3.v5.js"></script>
<div id="controls"></div>
<div id="result"></div>

我不知道整个脚本的外观,但是您可以执行类似的操作:

var current = {
  color: 'blue',
  size: 'super_massive'
}

function updateSubset( subset ) {
  var section_size = current.size,
  section_color = current.color
  [ ... ]

}

function selectChanged() {
  current[this.name] = this.value;
  updateSubset( all_data.features )
}

[ ... ]

// make sure that both select elements have their `name` attribute set, then:
d3.select('#sizeSection')
  .on('change', selectChanged)
d3.select('#colorSection')
  .on('change', selectChanged)

[ ... ]

或者,如果您想更严格地控​​制范围,也可以传入current

function updateSubset( subset, opts ) {
  var section_size = opts.size,
  section_color = opts.color
  [ ... ]

}

[ ... ]

function selectChanged() {
  current[this.name] = this.value;
  updateSubset( all_data.features, current )
}