node graph
by Yoshiharu Kamata
HTML
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<svg width="100%"></svg>
CSS
svg g.node rect {
fill: lightgray;
stroke: gray;
}
svg g.node.select rect {
stroke: red;
stroke-width: 10px;
}
svg g.node.sonar rect {
stroke: black;
fill: yellow;
}
CoffeeScript
###
Ch
Ps
Ls
Lp
Tn
ch - psv
emp - psv
class Base
layer: 0
childrenIds: null
parentIds: null
parents: ->
children: ->
siblings:->
sonar: ->
@parents()
@siblings()
@descendants()
###
class Node extends Backbone.Model
defaults:
order: 10000
initialize: (options)->
id = _.uniqueId()
@set 'id', id
@set 'name', "#{options.type}-#{id}"
@set 'children', []
@set 'parents', []
addChild: (child)->
@get('children').push child.get('id')
child.get('parents').push @get('id')
children: ->
result = _(@get('children')).map (id)=>
@collection.get id
.sortBy (model)->
model.get('order')
.valueOf()
parents: ->
_.map @get('parents'), (id)=>
@collection.get id
siblings: ->
_(@parents()).reject (parent)->
parent.get 'isEmpty'
.invoke("children")
.flatten()
.uniq()
.valueOf()
descendants: ->
children = @children()
if _.isEmpty children
[]
else
_(children).map (child)->
child.descendants()
.flatten()
.union(children)
.valueOf()
ancestors: ->
parents = @parents()
if _.isEmpty parents
[]
else
_(parents).map (parent)->
parent.ancestors()
.union(parents)
.flatten()
.valueOf()
leafs: (descendants = @descendants() )->
_.select descendants, (model)->
_.isEmpty model._children
reflect: (descendants = @descendants())->
myTypes = _(descendants).map (model)->
model.get 'type'
.uniq()
.valueOf()
reflectParents = _(@leafs descendants).invoke("parents")
.flatten()
.compact()
.reject (parent)->
_.include myTypes, parent.get('type')
.valueOf()
_(reflectParents).invoke("ancestors")
.flatten()
.concat(reflectParents)
.valueOf()
sonar: ->
descendants = @descendants()
_.union...