class Rubyvis::Flatten

Represents a flatten operator for the specified array. Flattening allows hierarchical maps to be flattened into an array. The levels in the input tree are specified by key functions.

<p>For example, consider the following hierarchical data structure of Barley yields, from various sites in Minnesota during 1931-2:

<pre>{ 1931: {

  Manchuria: {
    "University Farm": 27.00,
    "Waseca": 48.87,
    "Morris": 27.43,
    ... },
  Glabron: {
    "University Farm": 43.07,
    "Waseca": 55.20,
    ... } },
1932: {
  ... } }</pre>

To facilitate visualization, it may be useful to flatten the tree into a tabular array:

<pre>var array = pv.flatten(yields)

.key("year")
.key("variety")
.key("site")
.key("yield")
.array();</pre>

This returns an array of object elements. Each element in the array has attributes corresponding to this flatten operator’s keys:

<pre>{ site: “University Farm”, variety: “Manchuria”, year: 1931, yield: 27 }, { site: “Waseca”, variety: “Manchuria”, year: 1931, yield: 48.87 }, { site: “Morris”, variety: “Manchuria”, year: 1931, yield: 27.43 }, { site: “University Farm”, variety: “Glabron”, year: 1931, yield: 43.07 }, { site: “Waseca”, variety: “Glabron”, year: 1931, yield: 55.2 }, …</pre>

<p>The flatten operator is roughly the inverse of the {@link pv.Nest} and {@link pv.Tree} operators.

Public Class Methods

new(map) click to toggle source
# File lib/rubyvis/flatten.rb, line 50
def initialize(map)
  @map=map
  @keys=[]
  @leaf=nil
end

Public Instance Methods

array() click to toggle source

Returns the flattened array. Each entry in the array is an object; each object has attributes corresponding to this flatten operator’s keys.

@returns an array of elements from the flattened map.

# File lib/rubyvis/flatten.rb, line 107
def array
  @entries=[]
  @stack=[]
  if @leaf
    recurse(@map,0)
    return @entries
  end
  visit(@map,0)
  @entries.map {|stack|
    m={}
    @keys.each_with_index {|k,i|
      v=stack[i]
      m[k.name]=k.value ? k.value.js_call(self,v) : v
    }
    m
  }
end
Also aliased as: to_a
key(k, f=nil) click to toggle source

Flattens using the specified key function. Multiple keys may be added to the flatten; the tiers of the underlying tree must correspond to the specified keys, in order. The order of the returned array is undefined; however, you can easily sort it.

@param {string} key the key name. @param {function} [f] an optional value map function. @returns {pv.Nest} this.

# File lib/rubyvis/flatten.rb, line 64
def key(k, f=nil)
  @keys.push(OpenStruct.new({:name=>k, :value=>f}))
  @leaf=nil
  self
end
leaf(f) click to toggle source

Flattens using the specified leaf function. This is an alternative to specifying an explicit set of keys; the tiers of the underlying tree will be determined dynamically by recursing on the values, and the resulting keys will be stored in the entries :keys attribute. The leaf function must return true for leaves, and false for internal nodes.

@param {function} f a leaf function. @returns {pv.Nest} this.

# File lib/rubyvis/flatten.rb, line 76
def leaf(f)
  @keys.clear
  @leaf=f
  self
end
recurse(value,i) click to toggle source
# File lib/rubyvis/flatten.rb, line 81
def recurse(value,i)
  if @leaf.call(value)
    @entries.push({:keys=>@stack.dup, :value=>value})
  else
    value.each {|key,v|
      @stack.push(key)
      recurse(v, i+1)
      @stack.pop
    }
  end
end
to_a() click to toggle source
Alias for: array
visit(value,i) click to toggle source
# File lib/rubyvis/flatten.rb, line 92
def visit(value,i)
  if (i < @keys.size - 1)
    value.each {|key,v|
      @stack.push(key)
      visit(v,i+1)
      @stack.pop
    }
  else 
    @entries.push(@stack+[value])
  end
end