Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Brushing on ordinal data does not work

I really like this graph and its functionality and it is perfect for what I want/need. The only thing I need to change is I need it to allow ordinal data on the y-axis and I cannot seem to get that to work (I am a beginner).

When I change the y scale from linear to ordinal:

yscale[k] = d3.scale.linear() .domain(d3.extent(data, function(d) { return +d[k]; })) .range([h, 0]));

to

yscale[k] = d3.scale.ordinal().rangePoints([h, 0]),
      yscale[k].domain(data.map(function(d) { return d[k]; })))

Brushing still shows up and works by itself but it does not filter leaving the selected lines. No lines show up unless I move it to the very top of the axis then, all or mostly all show up. When I stepped through the code with firebug it looked like it was just not getting the lines that were in the brush area but all(?)... and I can't seem to figure out. :(

If anyone could help out with this (especially all the places I have to change and how), I would love to get this working and learn what I am doing wrong :-\

like image 603
the surfer Avatar asked Nov 02 '12 21:11

the surfer


1 Answers

Brushing an ordinal axis returns the pixels, while brushing a quantitative axis returns the domain.

https://github.com/mbostock/d3/wiki/SVG-Controls#wiki-brush_x

The scale is typically defined as a quantitative scale, in which case the extent is in data space from the scale's domain; however, it may instead be defined as an ordinal scale, where the extent is in pixel space from the scale's range extent.

My guess is that you need to work backwards and translate the pixels to the domain values. I found this question because I'm trying to do the same thing. If I figure it out, I'll let you know.

EDIT: Here's an awesome example to get you started.

http://philau.willbowman.com/2012/digitalInnovation/DevelopmentReferences/LIBS/d3JS/examples/brush/brush-ordinal.html

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

He grabs the selection extent (in pixels), then selects all of the series elements and determines whether they lie within the extent. You can filter elements based on that, and return data keys or what have you to add to your filters.

like image 73
Andrew Kirkegaard Avatar answered Oct 24 '22 01:10

Andrew Kirkegaard