Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Madge Builder to graph commonJS/AMD dependencies. #4

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't commit that file.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I created this file, is that during npm's publishing process it misses the dist folder due to it being in my .gitignore file. https://www.npmjs.org/doc/developers.html
You could create an empty .gitignore file so that it doesn't use by default what is in .gitignore.

*.iml
*.xml
16 changes: 16 additions & 0 deletions build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use strict";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move that to another PR. Not sure I'll merge that one, by the way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build.js is a crossplatform way of publishing the content (it also includes minification). If you don't wish to add the package.json i'll submit it to npm myself with a reference to your repository.


var UglifyJS = require('uglify-js'),
fs = require('fs'),
pkgInfo = require('./package.json'),
sourceFile = __dirname + '/lib/' + pkgInfo.main.replace('dist/', ''),
targetFile = __dirname + '/' + pkgInfo.main,
targetMinFile = __dirname + '/' + pkgInfo.main.replace(/.js$/, '') + '.min.js',
source = fs.readFileSync(sourceFile);

if (!fs.existsSync('./dist')) {
fs.mkdirSync('./dist');
}

fs.writeFileSync(targetFile, source);
fs.writeFileSync(targetMinFile, UglifyJS.minify(targetFile).code);
1 change: 1 addition & 0 deletions data/madge-express.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"benchmarks/middleware":["http","index"],"index":["lib/express"],"lib/application":["debug","escape-html","http","lib/middleware/init","lib/middleware/query","lib/router/index","lib/utils","lib/view","methods","utils-merge"],"lib/express":["events","lib/application","lib/middleware/query","lib/request","lib/response","lib/router/index","lib/router/route","serve-static","utils-merge"],"lib/middleware/init":[],"lib/middleware/query":["parseurl","qs"],"lib/request":["accepts","fresh","http","parseurl","proxy-addr","range-parser","type-is"],"lib/response":["cookie","cookie-signature","escape-html","http","lib/utils","path","send","utils-merge"],"lib/router/index":["debug","lib/router/layer","lib/router/route","methods","parseurl"],"lib/router/layer":["debug","path-to-regexp"],"lib/router/route":["debug","lib/utils","methods"],"lib/utils":["buffer-crc32","path","proxy-addr","send","util"],"lib/view":["fs","lib/utils","path"],"support/app":["index"]}
21 changes: 17 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
margin: 1em 0;
}

#chart_placeholder {
#chart_placeholder, #express_chart {
text-align: center;
margin-bottom: 20px;
}
Expand Down Expand Up @@ -101,6 +101,11 @@ <h2>Usage</h2>

<h2>Sharing your DependencyWheels</h2>
<p>The best way to share your DependencyWheels is to use <a href="http://pages.github.com/">GitHub Pages</a>, just like this very page. So just fork the <a href="https://github.com/fzaninotto/DependencyWheel">fzaninotto/DependencyWheel</a> repository, add your own JSON data under the <code>data/</code> directory, commit the code, and push to the <code>gh-pages</code> branch. GitHub will publish the result for you.</p>

<h2>Example Using Madge Tree Output from express.js</h2>

<div id="express_chart"></div>

<h2>Licence</h2>
<p>All this work is open-source, published by <a href="https://twitter.com/francoisz">François Zaninotto</a> under the MIT license. Sponsored by <a href="http://marmelab.com">marmelab</a>.</p>

Expand All @@ -115,9 +120,10 @@ <h2>Licence</h2>
</div>
</div>
<a href="https://github.com/fzaninotto/DependencyWheel"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
<script src="js/d3.min.js"></script>
<script src="js/d3.dependencyWheel.js"></script>
<script src="js/composerBuilder.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min.js"></script>
<script src="lib/d3.dependencyWheel.js"></script>
<script src="lib/composerBuilder.js"></script>
<script src="lib/madgeBuilder.js"></script>
<script>
var gitHubApiUrl = 'https://api.github.com/repos/';
var getData = function(target, callback) {
Expand All @@ -142,6 +148,13 @@ <h2>Licence</h2>

var chart = d3.chart.dependencyWheel();

d3.json('data/madge-express.json', function(madgejson) {
var data = buildMatrixFromMadge(madgejson);
d3.select('#express_chart')
.datum(data)
.call(chart);
});

d3.json('data/composer.json', function(composerjson) {
d3.json('data/composer.lock', function(composerlock) {
var data = buildMatrixFromComposerJsonAndLock(composerjson, composerlock);
Expand Down
5 changes: 0 additions & 5 deletions js/d3.min.js

This file was deleted.

37 changes: 30 additions & 7 deletions js/composerBuilder.js → lib/composerBuilder.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
(function(root, factory) {
if(typeof define === 'function' && define.amd) {
define([], factory);
} else if(typeof exports === 'object') {
module.exports = factory();
} else {
var ret = factory(root);
root.buildMatrixFromComposerJson = ret.buildMatrixFromComposerJson;
root.buildMatrixFromComposerJsonAndLock = ret.buildMatrixFromComposerJsonAndLock;
}
}(this, function() {

"use strict";

var buildMatrixFromComposerJson = function(composerjson) {
var n = Object.keys(composerjson.require).length;
var matrix = [];
Expand All @@ -12,7 +26,7 @@ var buildMatrixFromComposerJson = function(composerjson) {
}
var packageNames = Object.keys(composerjson.require);
packageNames.unshift(composerjson.name);

return {
matrix: matrix,
packageNames: packageNames
Expand All @@ -34,14 +48,14 @@ var buildMatrixFromComposerJsonAndLock = function(composerjson, composerlock) {
// List the replacements
packages.forEach(function(p) {
if (!p.replace) return;
for (replaced in p.replace) {
for (var replaced in p.replace) {
replaces[replaced] = p.name;
}
});

// update required packages with replacements
packages.forEach(function(p) {
for (packageName in p.require) {
for (var packageName in p.require) {
if (packageName in replaces) {
p.require[replaces[packageName]] = p.require[packageName];
delete p.require[packageName];
Expand All @@ -51,7 +65,7 @@ var buildMatrixFromComposerJsonAndLock = function(composerjson, composerlock) {

// Compute a unique index for each package name.
packages.forEach(function(p) {
packageName = p.name;
var packageName = p.name;
if (!(packageName in indexByName)) {
packageNames[n] = packageName;
indexByName[packageName] = n++;
Expand All @@ -66,8 +80,8 @@ var buildMatrixFromComposerJsonAndLock = function(composerjson, composerlock) {
row = matrix[source] = [];
for (var i = -1; ++i < n;) row[i] = 0;
}
for (packageName in p.require) {
row[indexByName[packageName]]++;
for (var packageName in p.require) {
row[indexByName[packageName]]++;
}
});

Expand All @@ -88,3 +102,12 @@ var buildMatrixFromComposerJsonAndLock = function(composerjson, composerlock) {
packageNames: packageNames
}
};


return {
buildMatrixFromComposerJson: buildMatrixFromComposerJson,
buildMatrixFromComposerJsonAndLock: buildMatrixFromComposerJsonAndLock
}


}));
19 changes: 18 additions & 1 deletion js/d3.dependencyWheel.js → lib/d3.dependencyWheel.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Uses modified umd returnExports pattern:
// https://github.com/umdjs/umd/blob/master/returnExports.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['d3'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('d3'));
} else {
factory(root.d3);
}
}(this, function (d3) {

"use strict";

d3.chart = d3.chart || {};

/**
Expand Down Expand Up @@ -66,7 +80,7 @@ d3.chart.dependencyWheel = function(options) {

var fill = function(d) {
if (d.index === 0) return '#ccc';
return "hsl(" + parseInt(((packageNames[d.index][0].charCodeAt() - 97) / 26) * 360, 10) + ",90%,70%)";
return "hsl(" + parseInt(((packageNames[d.index][0].charCodeAt(0) - 97) / 26) * 360, 10) + ",90%,70%)";
};

// Returns an event handler for fading a given chord group.
Expand Down Expand Up @@ -167,3 +181,6 @@ d3.chart.dependencyWheel = function(options) {

return chart;
};

return d3;
}));
43 changes: 43 additions & 0 deletions lib/madgeBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(function(root, factory) {
if(typeof define === 'function' && define.amd) {
define([], factory);
} else if(typeof exports === 'object') {
module.exports = factory();
} else {
root.buildMatrixFromMadge = factory();
}
}(this, function() {

"use strict";

var buildMatrixFromMadge = function(madgeTree) {

var packageNames = [], matrix = [], i = 0, mapModIdx = {};

//populate packagenames
for(var module in madgeTree) {
packageNames.push(module);
mapModIdx[module] = i;
i++;
}

for(var module in madgeTree) {
var deps = madgeTree[module],
matrixRow = Array.apply(null, new Array(packageNames.length)).map(Number.prototype.valueOf, 0);

deps.forEach(function(mod) {
matrixRow[mapModIdx[mod]] = 1;
});

matrix.push(matrixRow);
}

return {
packageNames: packageNames,
matrix: matrix
}
};

return buildMatrixFromMadge;

}));
42 changes: 42 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "dependency-wheel",
"version": "0.1.0",
"description": "A package dependency visualization using d3.js. Currently supports Composer for PHP and Madge for AMD/CommonJS.",
"main": "dist/d3.dependencyWheel.js",
"repository": {
"type": "git",
"url": "https://github.com/fzaninotto/DependencyWheel.git"
},
"scripts": {
"prepublish": "node build.js"
},
"keywords": [
"D3",
"Graph",
"Package",
"Dependency",
"Composer",
"PHP"
],
"author": "François Zaninotto",
"license": "MIT",
"bugs": {
"url": "https://github.com/fzaninotto/DependencyWheel/issues"
},
"homepage": "https://github.com/fzaninotto/DependencyWheel",
"devDependencies": {
"uglify-js": "^2.4.13"
},
"npmName": "dependency-wheel",
"npmFileMap": [
{
"basePath": "/dist/",
"files": [
"*.js"
]
}
],
"dependencies": {
"d3": "^3.4.8"
}
}
5 changes: 5 additions & 0 deletions test/createExpressMadge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var madge = require('madge');

var dependencies = madge('./express-master/', {exclude: '^examples*|^test*'}).tree;

console.log(JSON.stringify(dependencies));