我正在尝试将画笔滑块(此处显示为http://bl.ocks.org/mbostock/6452972)修改为序数滑块,然后根据滑块选择过滤数据。
当我将d3.scale.linear()
更改为d3.scale.ordinal()
时,滑块不再滑动。我假设这是因为滑块的位置不再是数字,并且需要以某种方式将值映射到序数比例。我怎么能做到这一点?
滑块移动后,我需要在数据对象中选择相应的数组。结构类似这样:
var data = {
'a': [1,2,3,4],
'b': [2,4,6,8],
'c': ['foo', 'bar'],
'd': ['x', 9, 'y', 1]
};
要检查我是否能够过滤,我添加了此代码以显示已过滤的数据(data.a
应与滑块选择的序数值相对应):
//display flitered data
d3.select("body").selectAll("p")
.data(data.a) //use slider selection to filter data
.enter()
.append("p")
.text(function(d) {return d;});
以下是我正在使用的完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Ordinal Slider</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
svg {font: 10px sans-serif;}
.axis {font: 10px sans-serif;-webkit-user-select: none;-moz-user-select: none;user-select: none;}
.axis .domain {fill: none;stroke: #000;stroke-opacity: .3;stroke-width: 10px;stroke-linecap: round;}
.axis .halo {fill: none;stroke: #ddd;stroke-width: 8px;stroke-linecap: round;}
.slider .handle {fill: #fff;stroke: #000;stroke-opacity: .5;stroke-width: 1.25px;cursor: crosshair;}
p {text-align: left;margin-left: 380px;}
</style>
</head>
<body>
<script type="text/javascript">
var data = {
'a': [1,2,3,4],
'b': [2,4,6,8],
'c': ['foo', 'bar'],
'd': ['x', 9, 'y', 1]
};
var margin = {top: 10, right: 10, bottom: 20, left:10},
width = 960 - margin.right - margin.left,
height = 100 - margin.top - margin.bottom;
//use ordinal scale based on Object.keys
var x = d3.scale.ordinal()
.domain(Object.keys(data))
.rangePoints([0, width - 200]);
var brush = d3.svg.brush()
.x(x)
.extent([0, 0])
.on("brush", brushed);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height - margin.top) + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d) { return d; })
.tickSize(0)
.tickPadding(12))
.select(".domain")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "halo");
var slider = svg.append("g")
.attr("class", "slider")
.call(brush);
slider.selectAll(".extent,.resize")
.remove();
var handle = slider.append("circle")
.attr("class", "handle")
.attr("transform", "translate(0," + (height - margin.top) + ")")
.attr("r", 9);
slider
.call(brush.event)
.transition()
.duration(750)
.call(brush.extent([70, 70]))
.call(brush.event);
//display flitered data
d3.select("body").selectAll("p")
.data(data.a) //use slider selection to filter data
.enter()
.append("p")
.text(function(d) {return d;});
//brushed function
function brushed() {
var value = brush.extent()[0];
if (d3.event.sourceEvent) {
value = x.invert(d3.mouse(this)[0]);
brush.extent([value, value]);
}
handle.attr("cx", x(value));
}
</script>
</body>
</html>