Skip to content

Instantly share code, notes, and snippets.

@mpmckenna8
Created May 17, 2017 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpmckenna8/9fca06f5001d3cc7001409b508d45d4d to your computer and use it in GitHub Desktop.
Save mpmckenna8/9fca06f5001d3cc7001409b508d45d4d to your computer and use it in GitHub Desktop.
hacky solution for friends' problem
<!DOCTYPE html >
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.node circle {
fill: #999;
}
.node text {
font: 10px sans-serif;
}
.node--internal circle {
fill: #555;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<svg class = 'squares'></svg>
<svg class= 'treemap' width = "800" height = "896" ></svg>
<script>
var data = [
{
'name': 'request-promise',
"dependencies": {
"name": "request-promise",
"children": [{
"name": "dependency",
"children": [{
"name": "request-promise-core"
}, {
"name": "bluebird"
}, {
"name": "stealthy-require"
}, {
"name": "tough-cookie"
}]
}, {
"name": "devDependency",
"children": [{
"name": "body-parser"
}, {
"name": "chai"
}, {
"name": "chalk"
}, {
"name": "gulp"
}, {
"name": "gulp-coveralls"
}, {
"name": "gulp-eslint"
}, {
"name": "gulp-istanbul"
}, {
"name": "gulp-mocha"
}, {
"name": "lodash"
}, {
"name": "publish-please"
}, {
"name": "request"
}, {
"name": "rimraf"
}, {
"name": "run-sequence"
}]
}, {
"name": "peerDependency",
"children": [{
"name": "request"
}]
}]
}},
{
'name': 'webpack',
"dependencies": {
"name": "webpack",
"children": [{
"name": "dependency",
"children": [{
"name": "acorn"
}, {
"name": "acorn-dynamic-import"
}, {
"name": "ajv"
}, {
"name": "ajv-keywords"
}, {
"name": "async"
}, {
"name": "enhanced-resolve"
}, {
"name": "interpret"
}, {
"name": "json-loader"
}, {
"name": "json5"
}, {
"name": "loader-runner"
}, {
"name": "loader-utils"
}, {
"name": "memory-fs"
}, {
"name": "mkdirp"
}, {
"name": "node-libs-browser"
}, {
"name": "source-map"
}, {
"name": "supports-color"
}, {
"name": "tapable"
}, {
"name": "uglify-js"
}, {
"name": "watchpack"
}, {
"name": "webpack-sources"
}, {
"name": "yargs"
}]
}, {
"name": "devDependency",
"children": [{
"name": "beautify-lint"
}, {
"name": "benchmark"
}, {
"name": "bundle-loader"
}, {
"name": "codacy-coverage"
}, {
"name": "codecov.io"
}, {
"name": "coffee-loader"
}, {
"name": "coffee-script"
}, {
"name": "coveralls"
}, {
"name": "css-loader"
}, {
"name": "es6-promise-polyfill"
}, {
"name": "eslint"
}, {
"name": "eslint-plugin-node"
}, {
"name": "express"
}, {
"name": "extract-text-webpack-plugin"
}, {
"name": "file-loader"
}, {
"name": "i18n-webpack-plugin"
}, {
"name": "istanbul"
}, {
"name": "jade"
}, {
"name": "jade-loader"
}, {
"name": "js-beautify"
}, {
"name": "less"
}, {
"name": "less-loader"
}, {
"name": "lodash"
}, {
"name": "mocha"
}, {
"name": "mocha-lcov-reporter"
}, {
"name": "nsp"
}, {
"name": "raw-loader"
}, {
"name": "react"
}, {
"name": "react-dom"
}, {
"name": "script-loader"
}, {
"name": "should"
}, {
"name": "simple-git"
}, {
"name": "sinon"
}, {
"name": "style-loader"
}, {
"name": "url-loader"
}, {
"name": "val-loader"
}, {
"name": "vm-browserify"
}, {
"name": "webpack-dev-middleware"
}, {
"name": "worker-loader"
}]
}]
}},
{
'name': 'yargs',
"dependencies": {
"name": "yargs",
"children": [{
"name": "dependency",
"children": [{
"name": "camelcase"
}, {
"name": "cliui"
}, {
"name": "decamelize"
}, {
"name": "get-caller-file"
}, {
"name": "os-locale"
}, {
"name": "read-pkg-up"
}, {
"name": "require-directory"
}, {
"name": "require-main-filename"
}, {
"name": "set-blocking"
}, {
"name": "string-width"
}, {
"name": "which-module"
}, {
"name": "y18n"
}, {
"name": "yargs-parser"
}]
}, {
"name": "devDependency",
"children": [{
"name": "chai"
}, {
"name": "chalk"
}, {
"name": "coveralls"
}, {
"name": "cpr"
}, {
"name": "cross-spawn"
}, {
"name": "es6-promise"
}, {
"name": "hashish"
}, {
"name": "mocha"
}, {
"name": "nyc"
}, {
"name": "rimraf"
}, {
"name": "standard"
}, {
"name": "standard-version"
}, {
"name": "which"
}, {
"name": "yargs-test-extends"
}]
}]
}
},
{
"name": 'bluebird',
"dependencies": {
"name": "bluebird",
"children": [{
"name": "devDependency",
"children": [{
"name": "acorn"
}, {
"name": "baconjs"
}, {
"name": "bluebird"
}, {
"name": "body-parser"
}, {
"name": "browserify"
}, {
"name": "cli-table"
}, {
"name": "co"
}, {
"name": "cross-spawn"
}, {
"name": "glob"
}, {
"name": "grunt-saucelabs"
}, {
"name": "highland"
}, {
"name": "istanbul"
}, {
"name": "jshint"
}, {
"name": "jshint-stylish"
}, {
"name": "mkdirp"
}, {
"name": "mocha"
}, {
"name": "open"
}, {
"name": "optimist"
}, {
"name": "rimraf"
}, {
"name": "rx"
}, {
"name": "serve-static"
}, {
"name": "sinon"
}, {
"name": "uglify-js"
}, {
"name": "kefir"
}]
}]
}
}];
//////////////////////////////////////////////////
// Clicking the black boxes will render the dependency tree map
// The bug is in the node data join
// The paths seem to render fine but old nodes are not removed
////////////////////////////////////////////////
const dependencies = d3.select('.treemap'),
width = window.innerHeight- 250,
height = window.innerWidth- 250;
const treemap = d3.tree()
.size([height, width]);
const buildDependencies = function(pkg){
console.log(pkg)
d3.selectAll('g.node').remove()
const stratify = d3.stratify()
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });
let nodes = d3.hierarchy(pkg.dependencies, function(d) {
return d.children;
});
nodes = treemap(nodes); //here is where stratify is called
const updateLinks = dependencies.selectAll(".link")
.data(nodes.descendants().slice(1))
const enterLinks = updateLinks.enter().append("path")
.attr("class", "link")
const exitLink = updateLinks.exit().remove();
updateLinks.merge(enterLinks).attr("d", function(d) {
return "M" + d.y + "," + d.x
+ "C" + (d.y + d.parent.y) / 2 + "," + d.x
+ " " + (d.y + d.parent.y) / 2 + "," + d.parent.x
+ " " + d.parent.y + "," + d.parent.x;
});
const updateNodes = dependencies.selectAll("g.nodes")
.data(nodes.descendants(), d => d)
const enterNodes = updateNodes.enter().append("g")
.attr("class", function(d) {
return "node" +
(d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")"; })
enterNodes.append("circle")
.attr("r", function(d) { return 15; })
.style("stroke", function(d) { return 'yellow'; })
.style("fill", function(d) { return 'green'; });
enterNodes.append("text")
.attr("dy", ".35em")
.attr("x", function(d) {
return 25 })
.style("text-anchor", function(d) {
return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
updateNodes.merge(enterNodes)
const exitNode = updateNodes.exit().remove();
}
const squares = d3.select('svg.squares')
.attr('height', 400).attr('width', 400)
squares.append('g').selectAll('rects')
.data(data).enter()
.append('rect').attr('x', (d, i) => {
return i * 100
}).attr('y', (d, i) => {
console.log(d)
return 100
})
.attr('width', 50).attr('height', 50)
.attr('fill', 'black')
.on('click', (d) => {
console.log(d)
buildDependencies(d)
})
</script>
</body>
<!DOCTYPE html >
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.node circle {
fill: #999;
}
.node text {
font: 10px sans-serif;
}
.node--internal circle {
fill: #555;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<svg class = 'squares'></svg>
<svg class= 'treemap' width = "800" height = "896" ></svg>
<script>
var data = [
{
'name': 'request-promise',
"dependencies": {
"name": "request-promise",
"children": [{
"name": "dependency",
"children": [{
"name": "request-promise-core"
}, {
"name": "bluebird"
}, {
"name": "stealthy-require"
}, {
"name": "tough-cookie"
}]
}, {
"name": "devDependency",
"children": [{
"name": "body-parser"
}, {
"name": "chai"
}, {
"name": "chalk"
}, {
"name": "gulp"
}, {
"name": "gulp-coveralls"
}, {
"name": "gulp-eslint"
}, {
"name": "gulp-istanbul"
}, {
"name": "gulp-mocha"
}, {
"name": "lodash"
}, {
"name": "publish-please"
}, {
"name": "request"
}, {
"name": "rimraf"
}, {
"name": "run-sequence"
}]
}, {
"name": "peerDependency",
"children": [{
"name": "request"
}]
}]
}},
{
'name': 'webpack',
"dependencies": {
"name": "webpack",
"children": [{
"name": "dependency",
"children": [{
"name": "acorn"
}, {
"name": "acorn-dynamic-import"
}, {
"name": "ajv"
}, {
"name": "ajv-keywords"
}, {
"name": "async"
}, {
"name": "enhanced-resolve"
}, {
"name": "interpret"
}, {
"name": "json-loader"
}, {
"name": "json5"
}, {
"name": "loader-runner"
}, {
"name": "loader-utils"
}, {
"name": "memory-fs"
}, {
"name": "mkdirp"
}, {
"name": "node-libs-browser"
}, {
"name": "source-map"
}, {
"name": "supports-color"
}, {
"name": "tapable"
}, {
"name": "uglify-js"
}, {
"name": "watchpack"
}, {
"name": "webpack-sources"
}, {
"name": "yargs"
}]
}, {
"name": "devDependency",
"children": [{
"name": "beautify-lint"
}, {
"name": "benchmark"
}, {
"name": "bundle-loader"
}, {
"name": "codacy-coverage"
}, {
"name": "codecov.io"
}, {
"name": "coffee-loader"
}, {
"name": "coffee-script"
}, {
"name": "coveralls"
}, {
"name": "css-loader"
}, {
"name": "es6-promise-polyfill"
}, {
"name": "eslint"
}, {
"name": "eslint-plugin-node"
}, {
"name": "express"
}, {
"name": "extract-text-webpack-plugin"
}, {
"name": "file-loader"
}, {
"name": "i18n-webpack-plugin"
}, {
"name": "istanbul"
}, {
"name": "jade"
}, {
"name": "jade-loader"
}, {
"name": "js-beautify"
}, {
"name": "less"
}, {
"name": "less-loader"
}, {
"name": "lodash"
}, {
"name": "mocha"
}, {
"name": "mocha-lcov-reporter"
}, {
"name": "nsp"
}, {
"name": "raw-loader"
}, {
"name": "react"
}, {
"name": "react-dom"
}, {
"name": "script-loader"
}, {
"name": "should"
}, {
"name": "simple-git"
}, {
"name": "sinon"
}, {
"name": "style-loader"
}, {
"name": "url-loader"
}, {
"name": "val-loader"
}, {
"name": "vm-browserify"
}, {
"name": "webpack-dev-middleware"
}, {
"name": "worker-loader"
}]
}]
}},
{
'name': 'yargs',
"dependencies": {
"name": "yargs",
"children": [{
"name": "dependency",
"children": [{
"name": "camelcase"
}, {
"name": "cliui"
}, {
"name": "decamelize"
}, {
"name": "get-caller-file"
}, {
"name": "os-locale"
}, {
"name": "read-pkg-up"
}, {
"name": "require-directory"
}, {
"name": "require-main-filename"
}, {
"name": "set-blocking"
}, {
"name": "string-width"
}, {
"name": "which-module"
}, {
"name": "y18n"
}, {
"name": "yargs-parser"
}]
}, {
"name": "devDependency",
"children": [{
"name": "chai"
}, {
"name": "chalk"
}, {
"name": "coveralls"
}, {
"name": "cpr"
}, {
"name": "cross-spawn"
}, {
"name": "es6-promise"
}, {
"name": "hashish"
}, {
"name": "mocha"
}, {
"name": "nyc"
}, {
"name": "rimraf"
}, {
"name": "standard"
}, {
"name": "standard-version"
}, {
"name": "which"
}, {
"name": "yargs-test-extends"
}]
}]
}
},
{
"name": 'bluebird',
"dependencies": {
"name": "bluebird",
"children": [{
"name": "devDependency",
"children": [{
"name": "acorn"
}, {
"name": "baconjs"
}, {
"name": "bluebird"
}, {
"name": "body-parser"
}, {
"name": "browserify"
}, {
"name": "cli-table"
}, {
"name": "co"
}, {
"name": "cross-spawn"
}, {
"name": "glob"
}, {
"name": "grunt-saucelabs"
}, {
"name": "highland"
}, {
"name": "istanbul"
}, {
"name": "jshint"
}, {
"name": "jshint-stylish"
}, {
"name": "mkdirp"
}, {
"name": "mocha"
}, {
"name": "open"
}, {
"name": "optimist"
}, {
"name": "rimraf"
}, {
"name": "rx"
}, {
"name": "serve-static"
}, {
"name": "sinon"
}, {
"name": "uglify-js"
}, {
"name": "kefir"
}]
}]
}
}];
//////////////////////////////////////////////////
// Clicking the black boxes will render the dependency tree map
// The bug is in the node data join
// The paths seem to render fine but old nodes are not removed
////////////////////////////////////////////////
const dependencies = d3.select('.treemap'),
width = window.innerHeight- 250,
height = window.innerWidth- 250;
const buildDependencies = function(pkg){
const treemap = d3.tree()
.size([height, width]);
const stratify = d3.stratify()
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });
let nodes = d3.hierarchy(pkg.dependencies, function(d) {
return d.children;
});
nodes = treemap((nodes)); //here is where stratify is called
const updateLinks = dependencies.selectAll(".link")
.data(nodes.descendants().slice(1))
const enterLinks = updateLinks.enter().append("path")
.attr("class", "link")
const exitLink = updateLinks.exit().remove();
updateLinks.merge(enterLinks).attr("d", function(d) {
return "M" + d.y + "," + d.x
+ "C" + (d.y + d.parent.y) / 2 + "," + d.x
+ " " + (d.y + d.parent.y) / 2 + "," + d.parent.x
+ " " + d.parent.y + "," + d.parent.x;
});
const updateNodes = dependencies.selectAll("g.nodes")
.data(nodes.descendants(), d => d)
const enterNodes = updateNodes.enter().append("g")
.attr("class", function(d) {
return "node" +
(d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")"; })
enterNodes.append("circle")
.attr("r", function(d) { return 15; })
.style("stroke", function(d) { return 'yellow'; })
.style("fill", function(d) { return 'green'; });
enterNodes.append("text")
.attr("dy", ".35em")
.attr("x", function(d) {
return 25 })
.style("text-anchor", function(d) {
return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
updateNodes.merge(enterNodes)
const exitNode = updateNodes.exit().remove();
}
const squares = d3.select('svg.squares')
.attr('height', 400).attr('width', 400)
squares.append('g').selectAll('rects').data(data).enter()
.append('rect').attr('x', (d, i) => {
return i * 100
}).attr('y', (d, i) => {
console.log(d)
return 100
})
.attr('width', 50).attr('height', 50)
.attr('fill', 'black')
.on('click', (d) => {
console.log(d)
buildDependencies(d)
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment