d3-flame-graph
Advanced tools
Comparing version 0.2.1 to 0.3.0
{ | ||
"name": "d3-flame-graph", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"homepage": "https://github.com/spiermar/d3-flame-graph", | ||
@@ -5,0 +5,0 @@ "authors": [ |
var gulp = require('gulp'), | ||
uglify = require('gulp-uglify'), | ||
connect = require('gulp-connect'), | ||
concat = require('gulp-concat'), | ||
notify = require("gulp-notify"), | ||
rename = require('gulp-rename'), | ||
jshint = require('gulp-jshint'), | ||
del = require('del'), | ||
@@ -13,4 +14,4 @@ browserSync = require('browser-sync').create(); | ||
gulp.task('dist', function() { | ||
return gulp.src('src/**/*.js') | ||
gulp.task('dist', ['lint'], function() { | ||
return gulp.src('./src/**/*.js') | ||
.pipe(concat('d3.flame.js')) | ||
@@ -24,2 +25,8 @@ .pipe(gulp.dest('dist')) | ||
gulp.task('lint', function() { | ||
return gulp.src('./src/**/*.js') | ||
.pipe(jshint()) | ||
.pipe(jshint.reporter('jshint-stylish')); | ||
}); | ||
gulp.task('browser-sync', function() { | ||
@@ -26,0 +33,0 @@ browserSync.init({ |
{ | ||
"name": "d3-flame-graph", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "A d3.js library to produce flame graphs.", | ||
@@ -36,6 +36,7 @@ "main": "src/d3.flame.js", | ||
"gulp-concat": "^2.6.0", | ||
"gulp-connect": "^2.2.0", | ||
"gulp-jshint": "^1.11.2", | ||
"gulp-notify": "^2.2.0", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-uglify": "^1.4.1", | ||
"jshint-stylish": "^2.0.1", | ||
"mocha": "^2.3.3" | ||
@@ -42,0 +43,0 @@ }, |
# d3-flame-graph | ||
A d3.js library to produce flame graphs. | ||
A D3.js library that produces flame graphs from hierarchical data. | ||
@@ -46,3 +46,3 @@ ![Flame Graph example](screenshot.png) | ||
if (error) return console.warn(error); | ||
d3.select("svg g.partition") | ||
d3.select("#chart") | ||
.datum(data) | ||
@@ -49,0 +49,0 @@ .call(flamegraph); |
@@ -7,9 +7,15 @@ (function() { | ||
var container = null, | ||
w = 1200, | ||
h = 600, | ||
frameheight = 18; | ||
w = 1200, // graph width | ||
h = 600, // graph height | ||
c = 18, // cell height | ||
tooltip = true; // enable tooltip | ||
function label(d) { | ||
return d.name + " (" + d3.round(100 * d.dx, 3) + "%, " + d.value + " samples)"; | ||
if (!d.dummy) { | ||
return d.name + " (" + d3.round(100 * d.dx, 3) + "%, " + d.value + " samples)"; | ||
} else { | ||
return ""; | ||
} | ||
} | ||
function name(d) { | ||
@@ -19,3 +25,3 @@ return d.name; | ||
function hash(name) { | ||
function generateHash(name) { | ||
// Return a vector (0.0->1.0) that is a hash of the input string. | ||
@@ -38,3 +44,3 @@ // The hash is computed to favor early characters over later ones, so | ||
function color_hash(name) { | ||
function colorHash(name) { | ||
// Return an rgb() color string that is a hash of the provided name, | ||
@@ -46,3 +52,3 @@ // and with a warm palette. | ||
name = name.replace(/\(.*/, ""); // drop extra info | ||
vector = hash(name); | ||
vector = generateHash(name); | ||
} | ||
@@ -61,14 +67,14 @@ var r = 200 + Math.round(55 * vector); | ||
root.children.forEach(augment); | ||
var child_values = 0; | ||
var childValues = 0; | ||
root.children.forEach(function(child) { | ||
child_values += child.value; | ||
childValues += child.value; | ||
}); | ||
if (child_values < root.value) { | ||
if (childValues < root.value) { | ||
root.children.push( | ||
{ | ||
"name": null, | ||
"value": root.value - child_values, | ||
"name": "", | ||
"value": root.value - childValues, | ||
"dummy": true | ||
} | ||
) | ||
); | ||
} | ||
@@ -79,3 +85,3 @@ } | ||
var partition = d3.layout.partition() | ||
.sort(function(a, b) {return d3.ascending(a.name, b.name)}) | ||
.sort(function(a, b) {return d3.ascending(a.name, b.name);}) | ||
.value(function(d) {return d.v || d.value;}) | ||
@@ -87,49 +93,145 @@ .children(function(d) {return d.c || d.children;}); | ||
var x = d3.scale.linear().range([0, w]), | ||
y = d3.scale.linear().range([0, frameheight]); | ||
y = d3.scale.linear().range([0, c]); | ||
selector.each(function(data) { | ||
container = d3.select(this); | ||
container = d3.select(this).append("svg:svg") | ||
.attr("width", w) | ||
.attr("height", h) | ||
.attr("class", "partition"); | ||
augment(data); | ||
var nodes = partition(data); | ||
var kx = w / data.dx; | ||
var tip = d3.tip().attr('class', 'd3-tip').html(function(d) { return label(d); }); | ||
function hide(d) { | ||
if(!d.original) { | ||
d.original = d.value; | ||
} | ||
d.value = 0; | ||
if(d.children) { | ||
d.children.forEach(hide); | ||
} | ||
} | ||
container.call(tip); | ||
function show(d) { | ||
d.flag = false; | ||
if(d.original) { | ||
d.value = d.original | ||
} | ||
if(d.children) { | ||
d.children.forEach(show); | ||
} | ||
} | ||
var g = container.selectAll("rect") | ||
.data(nodes) | ||
.enter() | ||
.append("svg:g") | ||
.attr("width", function(d) { return d.dx * kx }) | ||
.attr("height", function(d) { return frameheight; }) | ||
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.depth) - frameheight) + ")"; }) | ||
.attr("class", "frame") | ||
.attr("name", function(d) { return d.name; }) | ||
.on('mouseover', tip.show) | ||
.on('mouseout', tip.hide); | ||
function getSiblings(d) { | ||
var siblings = [] | ||
if (d.parent) { | ||
var me = d.parent.children.indexOf(d); | ||
siblings = d.parent.children.slice(0); | ||
siblings.splice(me, 1); | ||
} | ||
return siblings; | ||
} | ||
g.append("svg:rect") | ||
.attr("width", function(d) { return d.dx * kx }) | ||
.attr("height", function(d) { return frameheight; }) | ||
.attr("fill", function(d) {return color_hash(d.name); }) | ||
.style("opacity", function(d) {return d.dummy ? 0 : 1;}) | ||
function hideSiblings(d) { | ||
var siblings = getSiblings(d); | ||
siblings.forEach(function(s) { | ||
hide(s); | ||
}) | ||
if(d.parent) { | ||
hideSiblings(d.parent); | ||
} | ||
} | ||
g.each(function(d) { | ||
if (!d.dummy) { | ||
var thisGroup = d3.select(this); | ||
thisGroup.append("svg:title").text(label); | ||
thisGroup.append("foreignObject") | ||
.attr("class", "foreignObject") | ||
.attr("width", function (d) { return d.dx * kx; }) | ||
.attr("height", function (d) { return frameheight; }) | ||
.append("xhtml:div") | ||
.attr("class", "label") | ||
.style("display", function (d) { return d.dx * kx < 35 ? "none" : "block";}) | ||
.text(name) | ||
function flagAncestors(d) { | ||
if(d.parent) { | ||
d.parent.flag = true; | ||
flagAncestors(d.parent); | ||
} | ||
}); | ||
} | ||
function zoom(d) { | ||
hideSiblings(d); | ||
show(d); | ||
flagAncestors(d); | ||
update(data); | ||
} | ||
function update(root) { | ||
var nodes = partition(root), | ||
kx = w / root.dx; | ||
// create new elements as needed | ||
var svg = container.selectAll("g").data(nodes); | ||
// update old elements with new data | ||
svg.attr("width", function(d) { return d.dx * kx; }) | ||
.attr("height", function(d) { return c; }) | ||
.attr("name", function(d) { return d.name; }) | ||
.attr("class", function(d) { return d.flag ? "frame flag" : "frame"; }) | ||
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.depth) - c) + ")"; }); | ||
svg.select("rect") | ||
.attr("width", function(d) { return d.dx * kx; }) | ||
.attr("height", function(d) { return c; }) | ||
.attr("fill", function(d) { return colorHash(d.name); }) | ||
.style("visibility", function(d) { return d.dummy ? "hidden" : "visible";}); | ||
svg.select("title").text(label); | ||
svg.select("foreignObject") | ||
.attr("width", function (d) { return d.dx * kx; }) | ||
.attr("height", function (d) { return c; }) | ||
.select("div") | ||
.attr("class", "label") | ||
.style("display", function(d) { return (d.dx * kx < 35) || d.dummy ? "none" : "block";}) | ||
.text(name); | ||
// and join new data with old elements, if any. | ||
var g = svg.enter().append("svg:g") | ||
.attr("width", function(d) { return d.dx * kx; }) | ||
.attr("height", function(d) { return c; }) | ||
.attr("name", function(d) { return d.name; }) | ||
.attr("class", function(d) { return d.flag ? "frame flag" : "frame"; }) | ||
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.depth) - c) + ")"; }) | ||
.on('click', zoom); | ||
g.append("svg:rect") | ||
.attr("width", function(d) { return d.dx * kx; }) | ||
.attr("height", function(d) { return c; }) | ||
.attr("fill", function(d) {return colorHash(d.name); }) | ||
.style("visibility", function(d) {return d.dummy ? "hidden" : "visible";}); | ||
g.append("svg:title") | ||
.text(label); | ||
g.append("foreignObject") | ||
.attr("width", function(d) { return d.dx * kx; }) | ||
.attr("height", function(d) { return c; }) | ||
.append("xhtml:div") | ||
.attr("class", "label") | ||
.style("display", function(d) { return (d.dx * kx < 35) || d.dummy ? "none" : "block";}) | ||
.text(name); | ||
// remove old elements as needed. | ||
svg.exit().remove(); | ||
// including tooltip | ||
if (tooltip) { | ||
var tip = d3.tip() | ||
.attr('class', 'd3-tip') | ||
.html(function(d) { return label(d); }); | ||
container.call(tip); | ||
g.on('mouseover', function(d) { | ||
if(!d.dummy) { tip.show(d); } | ||
}).on('mouseout', function(d) { | ||
if(!d.dummy) { tip.hide(d); } | ||
}); | ||
} | ||
} | ||
// first draw | ||
update(data); | ||
}); | ||
} | ||
@@ -141,3 +243,3 @@ | ||
return flameGraph; | ||
} | ||
}; | ||
@@ -148,4 +250,16 @@ flameGraph.width = function (_) { | ||
return flameGraph; | ||
} | ||
}; | ||
flameGraph.cellHeight = function (_) { | ||
if (!arguments.length) { return c; } | ||
c = _; | ||
return flameGraph; | ||
}; | ||
flameGraph.tooltip = function (_) { | ||
if (!arguments.length) { return tooltip; } | ||
tooltip = _; | ||
return flameGraph; | ||
}; | ||
return flameGraph; | ||
@@ -152,0 +266,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
237341
2888
11