使用Ordinal Crossfilter Scales进行D3.js画笔控制

时间:2015-05-19 16:10:29

标签: javascript svg d3.js crossfilter brush

我的目标是像this wonderful example.那样对我的等值进行分组。我已经查看了API文档和Mike's Ordinal Brushing example

不幸的是,我仍然没有深入了解刷子应该如何工作。

这些例子很复杂,对于新手来说有些难以接近(大量的转向操作员和图表对象数组等)。

我选择不使用dc.js,因为我不得不对以后需要处理的事情提供支持。不错的工作和尼克齐朱的道具。

有人可以查看我的(原生d3)方法并告诉我我做错了什么吗?

我已经设置好了我的条形图。基本上是正态分布中的值的计数。

// Setup Crossfilter dimensions and groups
var nation      = crossfilter(MSPB),
    byScr       = nation.dimension(function(d){ return d.score; }),
    byScrGrp    = byScr.group().reduceCount(),
    byHosp      = nation.dimension(function(d){ return d.FIPS; }); 

// Histogram X-Axis ordinal scale
var x = d3.scale.ordinal()
        .domain(d3.range(0,2,0.1))
        .rangeBands([0, width, 0.5, 0.5 ]);

// Histogram Y-Axis linear scale
var y = d3.scale.linear()
        .domain([0, d3.max(byScrGrp.all(), function(d){ return d.value; })])
        .range([height/2, 0]);

// Histogram SVG containiner    
var svg = d3.select("#histogram").append("svg:svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height/2 + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // Histogram bars
    svg.selectAll("rect")
        .data(byScrGrp.all())
        .enter().append("rect")
        .attr("x", function(d,i){ return i * (width / byScrGrp.size() ); })
        .attr("width", width / byScrGrp.size() - barPadding )
        .attr("y", function(d){ return  y(d.value) ; })
        .attr("height", function(d){ return ((height/2) -y(d.value)); })
        .attr("fill", function(d){ return color(d.key); })
        .on("mouseover", function(d){ d3.select(this).attr("fill", "teal"); })
        .on("mouseout", function(d) { d3.select(this).attr("fill", function(d){return color(d.key);}) } );

之后,我尝试像这样添加我的画笔控件。最初我只想让条形图上的拖动选择工作。我会担心获取xAxis范围值以便稍后过滤等值线。

 var brush = d3.svg.brush()
            .x(x)
            .on("brushstart", brushstart)
            .on("brush", brushmove)
            .on("brushend", brushend)

var brushg = svg.append("g")
            .attr("class", "brush")
            .call(brush)

    brushg.selectAll("rect")
                .attr("height", height/2)
                .attr("width", width);


function brushstart() {
  svg.classed("selecting", true);
}

function brushmove() {
  var s = brush.extent();
  brushg.classed("selected", function(d) { return s[0] <= (d = x(d)) && d <= s[1]; });
}

function brushend() {
  svg.classed("selecting", !d3.event.target.empty());
}

我看到十字准线拖动手柄但没有看到我期望的东西,当然也没有达到预期的效果。

这个网络服务器的速度很慢,但是full js file is herepartially working example here

编辑:我试图创建一个JSFiddle here.

任何指针都会非常感激。

由于

1 个答案:

答案 0 :(得分:0)

很难说没有实验(任何创建JSfiddle或类似的机会?)。我怀疑问题是你正在设置画笔中所有rects的宽度。我相信你只需要设定高度。这可能是导致你的范围变得疯狂的原因。

一旦理顺,您将需要根据画笔范围过滤Crossfilter维度。

此外,Crossfilter的group.reduceCount函数不带参数,如果有可能缺少数据,则需要确保在维度访问器中测试/转换数据,以确保它们始终返回自然排序的数字或字符串。