From 958b7e0d0fe52164a4548f0e7ce537cc19b7005f Mon Sep 17 00:00:00 2001 From: gmamaladze Date: Fri, 1 Sep 2017 10:47:30 +0200 Subject: [PATCH] initial draft --- .gitignore | 2 + README.md | 39 ++++++++++++- example/index.html | 131 ++++++++++++++++++++++++++++++++++++++++++++ example/summary.dot | 14 +++++ package.json | 29 ++++++++++ src/d3-dot-graph.js | 43 +++++++++++++++ src/index.html | 131 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 example/index.html create mode 100644 example/summary.dot create mode 100644 package.json create mode 100644 src/d3-dot-graph.js create mode 100644 src/index.html diff --git a/.gitignore b/.gitignore index 00cbbdf..a9519e7 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,5 @@ typings/ # dotenv environment variables file .env +# MacOsX +.DS_Store diff --git a/README.md b/README.md index ead78e1..bee1551 100644 --- a/README.md +++ b/README.md @@ -1 +1,38 @@ -# d3-dot-graph \ No newline at end of file +# d3-dot-graph + +This module provides [D3js](#d3js) compatible library to parse and load files in graphviz [.dot](#dot) (graph description language) format. + +## why? +While working on Java Platform Module System migration projects coming with Java 9 (as of August 2017), I am havily using jdeps which is generating DOT (.dot) files. These are usually visualized using dot tool of graphviz. + +In most cases it is enough, but I wanted to have nicer d3js visualization and interaction. + +## usage + +Usage is identical with well known ´d3.json([url], [callback])´ or ´d3.csv([url], [callback])´. + +```js +d3.dot("/path/to/graph.dot", function(error, graph) { + if (error) throw error; + console.log(JSON.stringify(graph, null, true)); + //{ + // "nodes": [ {"id": "Myriel"}, {"id": "Napoleon"}], + // "links": [ {"source": "Myriel"}, {"target": "Napoleon"}] + //} +}); +``` + +## parser + +The parser was generated using [PEG.js](#pegjs). The grammer is taken from here [cpettitt/graphlib-dot](https://github.com/cpettitt/graphlib-dot). Thanks to Chris Pettitt. + +You can also use parser independently from loader and converter. + +# build + + +## notes + +[#d3js]: https://www.d3js.org +[#dot]: https://en.wikipedia.org/wiki/DOT_(graph_description_language) +[#pegjs]: https://pegjs.org diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..fd42613 --- /dev/null +++ b/example/index.html @@ -0,0 +1,131 @@ + + + + + + + + diff --git a/example/summary.dot b/example/summary.dot new file mode 100644 index 0000000..5638422 --- /dev/null +++ b/example/summary.dot @@ -0,0 +1,14 @@ +digraph "summary" { + "ui" -> "java.desktop (java.desktop)"; + "ui" -> "logic"; + "ui" -> "model"; + "logic" -> "data"; + "logic" -> "model"; + "app" -> "logic"; + "app" -> "ui"; + "model" -> "java.xml (java.xml)"; + "data" -> "java.sql (java.sql)"; + "data" -> "model"; + "api" -> "data"; + "api" -> "logic"; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d4b0551 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "d3-dot-graph", + "version": "1.0.0", + "description": "D3js compatible library to parse and load files in graphviz .dot (graph description language) format.", + "main": "index.js", + "scripts": { + "test": "mocha test/*.js", + "build": "pegjs --format globals --export-var d3dot grammar/dot.pegjs ", + "start": "npm run build" + }, + , + "keywords": [ + "dot", + "graphviz", + "d3", + "graph" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/gmamaladze/d3-dot-graph.git" + }, + "author": "George Mamaladze", + "license": "MIT", + "bugs": { + "url": "https://github.com/gmamaladze/d3-dot-graph/issues" + }, + "homepage": "https://github.com/gmamaladze/d3-dot-graph#readme", + "dependencies": {} +} diff --git a/src/d3-dot-graph.js b/src/d3-dot-graph.js new file mode 100644 index 0000000..f49b693 --- /dev/null +++ b/src/d3-dot-graph.js @@ -0,0 +1,43 @@ +d3.dot = + function(url, converter, callback) { + if (arguments.length < 3) callback = converter, converter = simple; + var r = d3 + .request(url) + .mimeType("text/vnd.graphviz") + .response(function(xhr) { + return converter(d3dot.parse(xhr.responseText)); }); + return callback ? r.get(callback) : r; + }; + + function simple(dotgraph) { + + let nodeMap = {}; + function addNode(node) { + if (nodeMap[node.id]) return; + nodeMap[node.id] = node; + } + + if (dotgraph.length===0) return null; + let fgraph = dotgraph[0]; + + fgraph.stmts.filter((s) => s.type === "node" ).forEach(addNode); + let edges = fgraph.stmts.filter((s) => s.type === "edge" ); + let links = []; + for(let i=0; i Object.assign({id:n.id}, n.attrs)); + return { + nodes, + links + }; + } diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..fd42613 --- /dev/null +++ b/src/index.html @@ -0,0 +1,131 @@ + + + + + + + +