Skip to content

Commit

Permalink
Add cmGraph and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
kerzner committed Apr 4, 2016
1 parent 5e4c0f7 commit fdbef64
Show file tree
Hide file tree
Showing 17 changed files with 1,103 additions and 37 deletions.
3 changes: 3 additions & 0 deletions .bowerrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"directory": "bower_components"
}
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# http://editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
17 changes: 17 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": "eslint:recommended",
"plugins": ["angular"],
"env": {
"es6": true,
"browser": true,
"jasmine": true
},
"ecmaFeatures": {
"modules": true
},
"globals": {
"angular": true,
"module": true,
"inject": true
}
}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ coverage/
.idea/
.tmp/
dist/
npm-debug.log
78 changes: 78 additions & 0 deletions .yo-rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"generator-gulp-angular": {
"version": "1.0.2",
"props": {
"angularVersion": "~1.4.2",
"angularModules": [
{
"key": "animate",
"module": "ngAnimate"
},
{
"key": "cookies",
"module": "ngCookies"
},
{
"key": "touch",
"module": "ngTouch"
},
{
"key": "sanitize",
"module": "ngSanitize"
},
{
"key": "messages",
"module": "ngMessages"
},
{
"key": "aria",
"module": "ngAria"
}
],
"jQuery": {
"key": "jquery2"
},
"resource": {
"key": "$http",
"module": null
},
"router": {
"key": "ui-router",
"module": "ui.router"
},
"ui": {
"key": "bootstrap",
"module": null
},
"bootstrapComponents": {
"key": "ui-bootstrap",
"module": "ui.bootstrap"
},
"cssPreprocessor": {
"key": "noCssPrepro",
"extension": "css"
},
"jsPreprocessor": {
"key": "babel",
"extension": "js",
"srcExtension": "es6"
},
"htmlPreprocessor": {
"key": "noHtmlPrepro",
"extension": "html"
},
"foundationComponents": {
"name": null,
"version": null,
"key": null,
"module": null
},
"paths": {
"src": "src",
"dist": "dist",
"e2e": "e2e",
"tmp": ".tmp"
}
}
}
}
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"moment": "~2.10.6",
"animate.css": "~3.4.0",
"angular": "~1.4.2",
"d3": "~3.5"
"d3": "~3.5",
"graphlib": "*"
},
"devDependencies": {
"angular-mocks": "~1.4.2"
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function listFiles() {
var patterns = wiredep(wiredepOptions).js
.concat([
path.join(conf.paths.tmp, '/serve/app/index.module.js'),
path.join(conf.paths.src, '/mock/**.js')
])
.concat(pathSrcHtml);

Expand Down
247 changes: 247 additions & 0 deletions src/app/components/connectivityMatrix/cmGraph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
/*global
graphlib
*/
export class cmGraph {

constructor(jsonGraph) {
this.jsonGraph = jsonGraph;
this.activate();
}

activate() {
this.graph = new graphlib.Graph({multigraph: true});

// create nodes
this.nodeAttributes = this.activateNodeAttributes(this.jsonGraph.node_attributes);
for (var i = 0; i < this.nodeAttributes.length; ++i) {
if (this.nodeAttributes[i].isIndex) {
this.indexAttributeIndex = i;
} else if (this.nodeAttributes[i].isId) {
this.idAttributeIndex = i;
}
}

for (i = 0; i < this.jsonGraph.nodes.length; ++i) {
var node = this.jsonGraph.nodes[i];
var index = this.parseNodeId(node, this.nodeAttributes, this.indexAttributeIndex);
var attributes = this.parseAttributes(node, this.nodeAttributes, this.indexAttributeIndex);
this.graph.setNode(index, attributes);
}

// create edges.
for (i = 0; i < this.jsonGraph.edges.length; ++i) {
var edge = this.jsonGraph.edges[i];
var sourceId = edge.SourceID;
var targetId = edge.TargetID;
var source = this.getNode(sourceId);
var target = this.getNode(targetId);

if (source == undefined || target == undefined) {
throw 'Error creating edge in graph! ' + sourceId + ', ' + targetId;
}

attributes = {
linkedStructures: edge.LinkedStructures,
sourceStructureId: edge.SourceStructureID,
targetStructureId: edge.TargetStructureID,
type: edge.Type
};

this.graph.setEdge(sourceId, targetId, attributes);
}
}


activateNodeAttributes(attributes) {
var result = [];
result.attributes = [];

// find the primary attribute
for (var i = 0; i < attributes.length; ++i) {
var input = attributes[i];
var current = {};

current.name = input.DisplayName;
current.parseName = input.Name;
current.isId = false; // is unique identifier of nodes
current.isIndex = false; // is index used to store node in the graph
current.isCategorical = false;
current.isQuantitative = false;
current.isString = false;
current.parseFn = null;

if (input.DataType == 'index') {
current.isIndex = true;
current.parseFn = parseInt;
} else if (input.DataType == 'id') {
current.isId = true;
if (!(input.Type == 'string' || input.Type == 'int')) {
throw 'Invalid data type for id!';
}
} else if (input.DataType == 'categorical') {
current.isCategorical = true;
} else if (input.DataType == 'quantitative') {
current.isQuantitative = true;
}

if (input.Type == 'int') {
current.parseFn = parseInt;
} else if (input.Type == 'float') {
current.parseFn = parseFloat;
} else if (input.Type == 'string') {
if (current.isQuantitative) {
throw 'Bad datatype!';
} else {
current.parseFn = function (x) {
return x;
}
}
}
result.push(current);
}

for (i = 0; i < result.length; ++i) {
if (result[i].parseFn == null) {
throw "Bad attribute definitions!";
}
}

return result;
}

convertEdgeToLink(edge, nodes) {
var targetIndex = undefined;
var sourceIndex = undefined;

// convert edge's node ids to indexes of the node list.
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
if (edge.v == node.id) {
sourceIndex = i;
}
if (edge.w == node.id) {
targetIndex = i;
}
}

// did we find both source and target?
if (targetIndex == undefined || sourceIndex == undefined) {
throw 'Error converting edge to link!';
}

return {
source: sourceIndex,
target: targetIndex,
value: this.graph.edge(edge)
};

}

getAsD3Input(nodeIdFilter) {
var result = {
nodes: [],
links: []
};

// Get list of nodes that are in the filter.
var nodes = this.getNodes();
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
var attributes = this.graph.node(node);
if ((nodeIdFilter == undefined) || (nodeIdFilter != undefined && nodeIdFilter.indexOf(Number(node)) != -1)) {
result.nodes.push(
{
id: node,
attributes: attributes
});
}
}

// Get list of edges that are in the filter
var edges = this.graph.edges();
var edgesToConvert = [];
for (i = 0; i < edges.length; ++i) {
var edge = edges[i];
var edgeTargetInFilter = true;
var edgeSourceInFilter = true;

if (nodeIdFilter != undefined) {
edgeTargetInFilter = edgeTargetInFilter && nodeIdFilter.indexOf(Number(edge.v)) != -1;
edgeSourceInFilter = edgeSourceInFilter && nodeIdFilter.indexOf(Number(edge.w)) != -1;
}

if (edgeTargetInFilter && edgeSourceInFilter) {
edgesToConvert.push(edge);
}

}

// convert edges into links - links use indexes of the nodes to represent connections.
for (i = 0; i < edgesToConvert.length; ++i) {
result.links.push(this.convertEdgeToLink(edgesToConvert[i], result.nodes));
}

return result;
}

getEdges() {
var edges = this.graph.edges();
var list = [];
for (var i = 0; i < edges.length; ++i) {
list.push(this.graph.edge(edges[i]));
}
return list;
}

getJsonGraph() {
return this.jsonGraph;
}

getNode(id) {
return this.graph.node(id);
}

getNodes() {
return this.graph.nodes();
}

parseNodeId(node, nodeAttributes, idAttributeIndex) {
var attribute = nodeAttributes[idAttributeIndex];
return attribute.parseFn(node[attribute.parseName]);
}

parseAttributes(node, attributes, skipIndex) {
var result = {};
for (var i = 0; i < attributes.length; ++i) {
if (i != skipIndex) {
var attribute = attributes[i];
result[attribute.name] = attribute.parseFn(node[attribute.parseName]);
}
}
return result;
}

getQuantNodeAttrNames() {
var names = [];
for (var i = 0; i < this.nodeAttributes.length; ++i) {
if (this.nodeAttributes[i].isQuantitative) {
names.push(this.nodeAttributes[i].name);
}
}
return names;
}

getCategoricalNodeAttrNames() {
var names = [];
for (var i = 0; i < this.nodeAttributes.length; ++i) {
if (this.nodeAttributes[i].isCategorical) {
names.push(this.nodeAttributes[i].name);
}
}
return names;
}

getNodeIdName() {
return this.nodeAttributes[this.idAttributeIndex].name;
}
}
Loading

0 comments on commit fdbef64

Please sign in to comment.