D3 Ordinal Slider过滤数据

时间:2015-05-01 17:45:35

标签: javascript d3.js

我正在尝试将画笔滑块(此处显示为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>

0 个答案:

没有答案