Skip to content

Instantly share code, notes, and snippets.

@bcardarella
Last active September 20, 2016 10:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bcardarella/8343688ec39c38b5cb4dc4c29f76905a to your computer and use it in GitHub Desktop.
Save bcardarella/8343688ec39c38b5cb4dc4c29f76905a to your computer and use it in GitHub Desktop.
ember-object-inheritance-graph
import Ember from 'ember';
export default Ember.Component.extend({
showPrivate: false,
filterValues: '',
showEmberData: false,
run: function() {
var g = new dagreD3.Digraph(), rootNode = {name: 'Object', namespace: 'Ember', children: []},
layout = dagreD3.layout().nodeSep(5).rankSep(60),
renderer = new dagreD3.Renderer();
this.set('counter', 0);
this.findChildNodes(rootNode);
this.drawTree(rootNode, g);
renderer.layout(layout).run(g, d3.select("svg g"));
}.observes('showPrivate','showEmberData', 'filterValues').on('didInsertElement'),
drawTree: function(node, parentNode, g) {
var self = this;
if (!g) {
g = parentNode;
parentNode = null;
}
if (node.draw) {
g.addNode(node.namespace+'.'+node.name, {label: this.renderLink(node.name, node.namespace)});
if (parentNode) {
g.addEdge(null, parentNode.namespace+'.'+parentNode.name, node.namespace+'.'+node.name);
}
node.children.forEach(function(childNode) {
self.drawTree(childNode, node, g);
});
}
},
renderLink: function(name, namespace) {
var filepath = '';
if (namespace === 'DS') {
filepath = 'data/';
}
filepath = filepath + 'classes/' + namespace + '.' + name + '.html';
return "<div><a href='http://emberjs.com/api/"+filepath+"' target='_blank'>"+namespace+"."+name+"</a></div>";
},
findClasses: function(namespace) {
var self = this;
return Object.keys(window[namespace]).filter(function(key) {
return (window[namespace][key] && window[namespace][key].superclass &&(self.get('showPrivate') || key[0] != '_'));
}).map(function(key) {
return namespace + '.' + key;
});
},
findChildNodes: function(parentNode, g) {
var self = this;
this.get('classes').filter(function(key) {
return (Ember.get(window, key).superclass === Ember.get(window, parentNode.namespace + '.' + parentNode.name));
}).forEach(function(key) {
var namespace = key.split('.')[0], name = key.split('.')[1], newNode = {name: name, namespace: namespace, children: [] };
if (Ember.isEmpty(self.get('filterValues')) || self.get('filterValues').split(',').join(' ').split(' ' ).any(function(filterValue) { if (Ember.isEmpty(filterValue)) { return false; } else { return (namespace+'.'+name).match(new RegExp(filterValue, 'i')); }})) {
newNode.draw = true;
self.incrementProperty('counter');
}
self.findChildNodes(newNode);
if (newNode.draw && !parentNode.draw) {
parentNode.draw = true;
self.incrementProperty('counter');
}
parentNode.children.push(newNode);
});
},
'classes': function() {
var classes = this.findClasses('Ember');
if (this.get('showEmberData')) {
classes = classes.concat(this.findClasses('DS'));
}
return classes.sort();
}.property('showEmberData', 'showPrivate')
});
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
emberVersion: Ember.VERSION,
dsVersion: DS.VERSION
});
/* Put your CSS here */
html, body {
margin: 20px;
}
a {
text-decoration: none;
color: black;
}
a:hover {
text-decoration: underline;
}
span.small {
font-size: 12px;
}
label:hover {
cursor: pointer;
}
svg {
overflow: hidden;
}
.node rect {
stroke: #333;
stroke-width: 1.5px;
fill: #fff;
}
/* Use a css selector to set up padding */
.node div {
padding: 3px;
}
.edgeLabel rect {
fill: #fff;
}
.edgePath {
stroke: #333;
stroke-width: 1.5px;
fill: none;
}
<h2>Ember.Object Ancestor Tree</h2>
<span class="small">(Click and drag the graph)</span>
<h4>Ember.VERSION {{emberVersion}}</h4>
<h4>DS.VERSION {{dsVersion}}</h4>
{{class-tree}}
<h5>Total Classes: {{counter}}</h5>
<div>
{{input value=filterValues placeholder="Filter by name"}}
</div>
<div>
<label>Ember Data {{input checked=showEmberData type="checkbox"}}</label>
</div>
<svg width=4850 height=780>
<g transform="translate(21,20)"/>
</svg>
{
"version": "0.10.4",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.7.0",
"ember-data": "2.7.0",
"ember-template-compiler": "2.7.0",
"d3": "https://d3js.org/d3.v3.min.js",
"dagre": "https://cpettitt.github.io/project/dagre-d3/v0.2.9/dagre-d3.min.js"
},
"addons": {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment