// =================================================== // =============== PARSING =========================== // =================================================== // Input // { links : [ {source: sourceName, dest : destName} * ] } // Output: let objcdv = { version: "0.0.1", _createGraph: function () { return { nodes: [], links: [], nodesSet: {}, node_index: 0, addLink: function (link) { var source_node = this.getNode(link.source); source_node.source++; var dest_node = this.getNode(link.dest); dest_node.dest++; this.links.push({ // d3 js properties source: source_node.idx, target: dest_node.idx, // Additional link information sourceNode: source_node, targetNode: dest_node }) }, getNode: function (nodeName) { var node = this.nodesSet[nodeName]; if (node == null) { var idx = this.node_index; this.nodesSet[nodeName] = node = {idx: idx, name: nodeName, source: 1, dest: 0}; this.node_index++; } return node }, updateNodes: function (f) { _.values(this.nodesSet).forEach(f) }, d3jsGraph: function () { // Sorting up nodes, since, in some cases they aren't returned in correct number var nodes = _.values(this.nodesSet).slice(0).sort((a, b) => a.idx - b.idx); return {nodes: nodes, links: this.links}; }, nodesStartingFromNode: function (node, {max_level = 100, use_backward_search = false, use_forward_search = true } = {} ) { // Figure out the neighboring node id's with brute strength because the graph is small var neighbours = {}; neighbours[node.index] = node; var nodesToCheck = [node.index]; let current_level = 0; while (Object.keys(nodesToCheck).length != 0) { var forwardNeighbours = []; var backwardNeighbours = []; let tmpNeighbours = {}; if (use_forward_search) { forwardNeighbours = this.links .filter((link) => link.source.index in neighbours) .filter((link) => !(link.target.index in neighbours)) .map((link) => { tmpNeighbours[link.target.index] = link.target; return link.target.index; }); } if (use_backward_search) { backwardNeighbours = this.links .filter((link) => link.target.index in neighbours) .filter((link) => !(link.source.index in neighbours)) .map((link) => { tmpNeighbours[link.source.index] = link.source; return link.source.index; }); } _.extend(neighbours, tmpNeighbours); nodesToCheck = forwardNeighbours.concat(backwardNeighbours); console.log("Nodes to check" + nodesToCheck); // Skip if we reached max level current_level++; if (current_level == max_level) { console.log("Reached max at level" + current_level); break; } } return _.values(neighbours); } }; }, _createPrefixes: function () { return { _prefixesDistr: {}, _sortedPrefixes: null, addName: function (name) { this._sortedPrefixes = null; var prefix = name.substring(0, 2); if (!(prefix in this._prefixesDistr)) { this._prefixesDistr[prefix] = 1; } else { this._prefixesDistr[prefix]++; } }, prefixIndexForName: function (name) { var sortedPrefixes = this._getSortedPrefixes(); var prefix = name.substring(0, 2); return _.indexOf(sortedPrefixes, prefix) }, _getSortedPrefixes: function () { if (this._sortedPrefixes == null) { this._sortedPrefixes = _.map(this._prefixesDistr, (v, k) => ({"key": k, "value": v})) .sort((a, b) => b.value - a.value) .map(o => o.key) } return this._sortedPrefixes } }; }, parse_dependencies_graph: function (dependencies) { var graph = this._createGraph(); var prefixes = this._createPrefixes(); dependencies.links.forEach((link) => { graph.addLink(link); prefixes.addName(link.source); prefixes.addName(link.dest); }); graph.updateNodes((node) => { node.weight = node.source; node.group = prefixes.prefixIndexForName(node.name) + 1 }); return graph } };