|
<head> |
|
<script src="//cdn.jsdelivr.net/g/d3js,coffeescript,handlebarsjs(handlebars.min.js)"> |
|
</script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.2.6/js-yaml.min.js"></script> |
|
</head> |
|
|
|
<body> |
|
<script type="text/coffeescript"> |
|
autofill = ( d, s) -> |
|
#{ autofill class, attr, and style from a yaml list } |
|
if d.hasOwnProperty('class') |
|
d['class'].forEach (c) -> |
|
s.classed c, true |
|
if d.hasOwnProperty('id') |
|
s.attr 'id', d['id'] |
|
if d.hasOwnProperty('style') |
|
d['style'].forEach (d) -> |
|
if typeof d == 'object' |
|
s.style d3.keys(d)[0], d3.values(d)[0] |
|
if d.hasOwnProperty('attr') |
|
d['attr'].forEach (d) -> |
|
if typeof d == 'object' |
|
s.attr d3.keys(d)[0], d3.values(d)[0] |
|
|
|
d3.text 'manifest.yaml', (yml) -> |
|
|
|
yml = jsyaml.load yml |
|
|
|
traverse = (a) -> |
|
#{ Allows d3 to bind tree indices instead of entire child element } |
|
a.reduce (p,n,i) -> |
|
if (i == 0) |
|
p[n] |
|
else |
|
p['children'][n] |
|
, yml |
|
|
|
init = () -> |
|
if yml[0]['stylesheet'] |
|
yml[0]['stylesheet'].forEach (url) -> |
|
d3.select 'head' |
|
.append 'link' |
|
.attr 'rel', 'stylesheet' |
|
.attr 'type', 'text/css' |
|
.attr 'href', url |
|
if yml[0]['script'] |
|
yml[0]['script'].forEach (url) -> |
|
d3.select 'head' |
|
.append 'script' |
|
.attr 'src', url |
|
|
|
templater = ( d, $el) -> |
|
d['template'].forEach (_d,i) -> |
|
if _d['type'] == 'text/x-handlebars-template' |
|
template = d3.select _d['selector'] |
|
.html() |
|
template = Handlebars.compile(template) |
|
d3.select $el |
|
.append 'div' |
|
.call (s) -> |
|
autofill( _d, s) |
|
.html () -> |
|
template d |
|
|
|
|
|
create = ( $el, i , depth) -> |
|
d = traverse( i ) |
|
n = d3 |
|
.select $el |
|
.append 'div' #{add a new container} |
|
.datum i |
|
.call (s) -> |
|
autofill d, s |
|
|
|
n.call (s) -> |
|
if d.hasOwnProperty( 'template' ) && d['template'] == null |
|
#{ don't do anything } |
|
console.log d, ' has been ignored' |
|
else if d.hasOwnProperty( 'template' ) |
|
#{ custom template } |
|
templater( d, s.node() ) |
|
else |
|
if d.hasOwnProperty( 'children' ) |
|
#{ temporary template } |
|
s.append 'h' + ( depth + 1 ) |
|
.text d.heading |
|
|
|
d3.range d['children'].length |
|
.forEach (_i) -> |
|
create s.node(), d3.merge( [i, [_i]] ) , depth++ |
|
else |
|
s.append 'h' + ( depth + 1 ) |
|
.text d.heading |
|
s.append 'p' |
|
.text d.content |
|
|
|
init() |
|
create 'body', [0], 0 |
|
</script> |
|
</body> |
|
|
|
<script id="template" type="text/x-handlebars-template"> |
|
<div class="panel-heading">This is a template</div> |
|
<div class="panel-body">{{heading}}</div> |
|
<ul> |
|
{{#each content}} |
|
<li>{{heading}}</li> |
|
{{/each}} |
|
</ul> |
|
</script> |
|
|
|
<script id="template2" type="text/x-handlebars-template"> |
|
<div class="panel-heading">This is a template</div> |
|
<div class="panel-body">{{heading}}</div> |
|
<ul> |
|
{{#each content}} |
|
<li>{{content}}</li> |
|
{{/each}} |
|
</ul> |
|
</script> |