我有两个下拉菜单。一个下拉列表(包含定量变量)确定圆的大小,另一个下拉列表(包含分类变量)确定传单图上创建的圆形的颜色。当我选择大小变量时,我希望将颜色变量固定为他先前选择的变量。 “ 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]);}
);
}
我不明白当另一个过滤器改变时如何存储一个过滤器的选择。
答案 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 )
}