From a4be99b90be663631d367b25c490b6951368714a Mon Sep 17 00:00:00 2001 From: Way Of The Future Date: Sun, 12 Jun 2016 10:30:44 -0500 Subject: [PATCH 1/2] beta 1 --- bin/dependo | 12 +++++++++++- lib/dependo.js | 14 ++++++++++++-- lib/html.js | 19 +++++++++++-------- lib/html/d3-graph.js | 10 +++++++--- lib/html/filesaver.js | 2 ++ lib/html/style.css | 10 ++++++++++ lib/html/template.html | 14 +++++++++++++- readme.md | 13 +++++++------ 8 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 lib/html/filesaver.js diff --git a/bin/dependo b/bin/dependo index 4682606..4a83e68 100755 --- a/bin/dependo +++ b/bin/dependo @@ -15,6 +15,7 @@ Commander .option('-f, --format ', 'format to parse (amd/cjs/es6/json)', 'amd') .option('-x, --exclude ', 'a regular expression for excluding modules') .option('-t, --title ', 'the title of the generated document (dependo)') + .option('-l, --layout <filename>', 'load a previously saved layout (json)') .option('-v, --reverse', 'reverse direction of arrows', false) .parse(process.argv); @@ -25,16 +26,25 @@ if (!Commander.args.length) { var src = Commander.args[0]; -var directDeps = Commander.format==='json' && +var directDeps = Commander.format === 'json' && fs.existsSync(src) && JSON.parse(fs.readFileSync(src)); +if (Commander.layout && typeof (Commander.layout) == 'string' && fs.existsSync(Commander.layout)) { + var data = JSON.parse(fs.readFileSync(Commander.layout)); + if (data) { + Commander.layoutData = data; + } +} + var dependo = new Dependo(src, { basePath: path.resolve(src).replace(/\\/g, '/') + '/', format: Commander.format, exclude: Commander.exclude, directDeps: directDeps, title: Commander.title, + layout: Commander.layout, + layoutData: Commander.layoutData, transform: Commander.reverse ? converse : undefined }); diff --git a/lib/dependo.js b/lib/dependo.js index b01852a..48638f4 100644 --- a/lib/dependo.js +++ b/lib/dependo.js @@ -9,9 +9,19 @@ function Dependo(targetPath, options) { this.basePath = options.basePath; this.config.format = String(options.format || 'amd').toLowerCase(); this.config.exclude = options.exclude || null; - this.identification = sha1(targetPath + JSON.stringify(this.config)) || ~~(Math.random()*999999999); this.title = options.title || 'dependo'; + //console.log('a:' + this.config.layout || ''); + //console.log('b:' + this.config.layoutData || ''); + + if (this.config.layout && this.config.layoutData) { + this.identification = 'CustomLayout'; + this.layoutData = this.config.layoutData; + } + else { + this.identification = sha1(targetPath + JSON.stringify(this.config)) || ~~(Math.random()*999999999); + } + if (this.config.format==='json') { this.dependencies = this.config.directDeps; } else { @@ -25,7 +35,7 @@ function Dependo(targetPath, options) { } Dependo.prototype.generateHtml = function () { - return require('./html').output(this.basePath, this.dependencies, this.identification, this.title); + return require('./html').output(this.basePath, this.dependencies, this.identification, this.title, this.layoutData); }; module.exports = Dependo; diff --git a/lib/html.js b/lib/html.js index faee869..54d2869 100644 --- a/lib/html.js +++ b/lib/html.js @@ -33,7 +33,7 @@ function generateGraphData(dependencies) { var link = { source: _.indexOf(components, component), - target: _.indexOf(components, dependency), + target: _.indexOf(components, dependency) }; if (sourceIndex > -1 && targetIndex > -1) { @@ -52,30 +52,33 @@ function generateGraphData(dependencies) { "links": links } -}; +} -function generateHtml(basePath, graphData, identification, title) { +function generateHtml(basePath, graphData, identification, title, layoutData) { var templatePath = fs.readFileSync(__dirname + '/html/template.html', 'utf8'); var css = fs.readFileSync(__dirname + '/html/style.css', 'utf8'); - var js = fs.readFileSync(__dirname + '/html/d3-graph.js', 'utf8'); + var jsgraph = fs.readFileSync(__dirname + '/html/d3-graph.js', 'utf8'); + var jssaver = fs.readFileSync(__dirname + '/html/filesaver.js', 'utf8'); var data = { css: css, - js: js, + jsgraph: jsgraph, + jssaver: jssaver, title: title, basePath: basePath, graphData: JSON.stringify(graphData, null), - graphID: identification + graphID: identification, + layoutData: JSON.stringify(layoutData, null) }; return _.template(templatePath)(data); } -module.exports.output = function(basePath, dependencies, identification, title) { +module.exports.output = function(basePath, dependencies, identification, title, layoutData) { var graphData = generateGraphData(dependencies); - return generateHtml(basePath, graphData, identification, title); + return generateHtml(basePath, graphData, identification, title, layoutData); }; diff --git a/lib/html/d3-graph.js b/lib/html/d3-graph.js index b0bdc97..3d3812f 100644 --- a/lib/html/d3-graph.js +++ b/lib/html/d3-graph.js @@ -262,7 +262,7 @@ } function onControlZoomClicked(e) { - var elmTarget = $(this) + var elmTarget = $(this); var scaleProcentile = 0.20; // Scale @@ -308,9 +308,13 @@ function getNodes() { try { - if(window.nodePositions){ + if (window.graphIdentification == "CustomLayout") { + return JSON.parse(window.localStorage.getItem("dependo"+window.graphIdentification)) || {}; + } + else if (window.nodePositions) { return JSON.parse(window.nodePositions); - }else{ + } + else { return JSON.parse(window.localStorage.getItem("dependo"+window.graphIdentification)) || {}; } } catch (e) { diff --git a/lib/html/filesaver.js b/lib/html/filesaver.js new file mode 100644 index 0000000..3ef971c --- /dev/null +++ b/lib/html/filesaver.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,i=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/constructor/i.test(e.HTMLElement),f=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},u="application/octet-stream",s=1e3*40,d=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,s)},c=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(i){f(i)}}}},l=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},p=function(t,f,s){if(!s){t=l(t)}var p=this,v=t.type,w=v===u,m,y=function(){c(p,"writestart progress write writeend".split(" "))},h=function(){if(w&&a&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=r.result;e.location.href="data:attachment/file"+t.slice(t.search(/[,;]/));p.readyState=p.DONE;y()};r.readAsDataURL(t);p.readyState=p.INIT;return}if(!m){m=n().createObjectURL(t)}if(w){e.location.href=m}else{var o=e.open(m,"_blank");if(!o){e.location.href=m}}p.readyState=p.DONE;y();d(m)};p.readyState=p.INIT;if(o){m=n().createObjectURL(t);setTimeout(function(){r.href=m;r.download=f;i(r);y();d(m);p.readyState=p.DONE});return}h()},v=p.prototype,w=function(e,t,n){return new p(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=l(e)}return navigator.msSaveOrOpenBlob(e,t)}}v.abort=function(){};v.readyState=v.INIT=0;v.WRITING=1;v.DONE=2;v.error=v.onwritestart=v.onprogress=v.onwrite=v.onabort=v.onerror=v.onwriteend=null;return w}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define([],function(){return saveAs})} diff --git a/lib/html/style.css b/lib/html/style.css index 178aab9..2c72b82 100644 --- a/lib/html/style.css +++ b/lib/html/style.css @@ -96,3 +96,13 @@ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJAQMAAADaX5RTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkU5MjRDMEQ5NjQzNzExRTBCM0JDQkU2MzVGQTBCNjRDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkU5MjRDMERBNjQzNzExRTBCM0JDQkU2MzVGQTBCNjRDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTkyNEMwRDc2NDM3MTFFMEIzQkNCRTYzNUZBMEI2NEMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTkyNEMwRDg2NDM3MTFFMEIzQkNCRTYzNUZBMEI2NEMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7uh53jAAAABlBMVEUAAAD///+l2Z/dAAAAAnRSTlP/AOW3MEoAAAARSURBVAhbY/jfwABBcAATAQB6xwj7vHGbwAAAAABJRU5ErkJggg==); margin-bottom: 5px; } + + .save-layout { + position: fixed; + top: 0; + right: 0; + padding: 3px 5px; + border: none; + background: #333; + color: #ddd; + } diff --git a/lib/html/template.html b/lib/html/template.html index a721105..68f935f 100644 --- a/lib/html/template.html +++ b/lib/html/template.html @@ -13,6 +13,7 @@ <a class="control-zoom-out" href="#" title="Zoom out"></a> </div> </div> + <input type="button" class="save-layout" value="Save Layout" onclick="saveLayout();"> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> @@ -23,7 +24,18 @@ var graphIdentification = "<%= graphID %>"; var nodePositions = null; //replace with the object you find in console to persist node positions - <%= js %> + var getLayoutData = function() { return <%= layoutData %>;}; + if (getLayoutData()) { + localStorage.setItem("dependo" + graphIdentification, JSON.stringify(getLayoutData())); + } + + function saveLayout() { + var b = new Blob([localStorage.getItem("dependo" + graphIdentification)], { type: 'application/json;charset=UTF-8;' }); + saveAs(b, "dependo-layout.json"); + } + + <%= jsgraph %> + <%= jssaver %> </script> </body> diff --git a/readme.md b/readme.md index 12beb40..b706c53 100644 --- a/readme.md +++ b/readme.md @@ -86,12 +86,13 @@ CLI Options: - -h, --help output usage information - -V, --version output the version number - -f, --format <name> format to parse (amd/cjs/es6/json) - -x, --exclude <regex> a regular expression for excluding modules - -t, --title <title> the title of the generated document (dependo) - -v, --reverse reverse direction of arrows + -h, --help output usage information + -V, --version output the version number + -f, --format <name> format to parse (amd/cjs/es6/json) + -x, --exclude <regex> a regular expression for excluding modules + -t, --title <title> the title of the generated document (dependo) + -l, --layout <filename> load a previously saved layout (json) + -v, --reverse reverse direction of arrows ### Generate HTML report of all module dependencies (AMD), and save it to /example/report.html From bffd169e3c07b1a39c753913d87310c25ad77d81 Mon Sep 17 00:00:00 2001 From: Way Of The Future <scuzzlebuzzle@yahoo.com> Date: Mon, 13 Jun 2016 20:32:43 -0500 Subject: [PATCH 2/2] final --- lib/dependo.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/dependo.js b/lib/dependo.js index 48638f4..dc6ce20 100644 --- a/lib/dependo.js +++ b/lib/dependo.js @@ -11,9 +11,6 @@ function Dependo(targetPath, options) { this.config.exclude = options.exclude || null; this.title = options.title || 'dependo'; - //console.log('a:' + this.config.layout || ''); - //console.log('b:' + this.config.layoutData || ''); - if (this.config.layout && this.config.layoutData) { this.identification = 'CustomLayout'; this.layoutData = this.config.layoutData;