node d3

by Yoshiharu Kamata

HTML

<script src="//d3js.org/d3.v3.min.js"></script>
<div>
    
<label>P
<input type="radio" name="layer" value="p"/>
</label>
<label>L
<input type="radio" name="layer" value="l" />
</label>
</div>
<svg width="400" height="300"></svg>

CSS

svg g.select {
    fill: red;
}

CoffeeScript

dataset = {}
class Node
  constructor: ->
    @_children = []
    @_parents = {}
    @id = _.uniqueId()
    dataset[@id] = @
  addChild: (node)->
    node._parents[@type] = @id
    @_children.push node.id
  parent: (type)->
    dataset[@parents[type]]
  children: ->
    _.map @_children, (id)->
      dataset[id]
        
class R extends Node
  type: "R"
    
class C extends Node
  type: "C"

class P extends Node
  type: "P"

class V extends Node
  type: "V"

class L extends Node
  type: "L"

class A extends Node
  type: "A"

ls = _.times 20, ->
  new L
_.times 6, ->
  c = new C
  _.times 10, ->
    p = new P
    c.addChild p
    _.times 6, ->
      v = new V
      p.addChild v
      _.sample(ls).addChild v

        
pNodes = ->
  _.select dataset, (d)->
    d.type == "C"
    
pLayout = (data)->
  _.map data, (d, i)->
    id: d.id
    type: d.type
    x: 60*i + 10
    y: 10
    width: 50
    height: 50

data = pLayout(pNodes())    
nodes = d3.select("svg")
.selectAll("g")
.data(data)

nodes.enter()
.append("g")
.each (d,i)->
  g = d3.select @
  g.append "rect"
  g.append "circle"
  g.on "click", (d)->
    d3.select(@).classed "select", !(d3.select(@).classed "select")
nodes.each (d,i)->
  g = d3.select @
  g.select("rect")
  .attr("x", d.x)
  .attr("y", d.y)
  .attr("width", d.width)
  .attr("height", d.height)
  g.select("circle")
  .attr("cx", d.x + 10)
  .attr("cy", 20)
  .attr("r", 5)
  .attr("fill", "yellow")