Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

d3-flame-graph

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-flame-graph - npm Package Compare versions

Comparing version 1.0.1 to 1.0.4

example/minified.html

3

bower.json

@@ -30,5 +30,4 @@ {

"d3": "~4",
"d3-tip": "~0.7.1",
"lodash": "~4.17.4"
"d3-tip": "~0.7.1"
}
}
(function() {
'use strict';
/*jshint eqnull:true */
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
}
});
}
if (!Array.prototype.filter)
Array.prototype.filter = function(func, thisArg) {
if ( ! ((typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
c = 0, i = -1;
if (thisArg === undefined)
while (++i !== len)
// checks to see if the key was set
if (i in this)
if (func(t[i], i, t))
res[c++] = t[i];
else
while (++i !== len)
// checks to see if the key was set
if (i in this)
if (func.call(thisArg, t[i], i, t))
res[c++] = t[i];
res.length = c; // shrink down array to proper size
return res;
};
/*jshint eqnull:false */
function flameGraph() {
var w = 960, // graph width
h = 540, // graph height
h = null, // graph height
c = 18, // cell height

@@ -14,5 +86,6 @@ selection = null, // selection

transitionEase = d3.easeCubic, // tooltip offset
sort = true,
sort = false,
reversed = false, // reverse the graph direction
clickHandler = null;
clickHandler = null,
minFrameSize = 0;

@@ -27,4 +100,16 @@ var tip = d3.tip()

function name(d) {
return d.data.n || d.data.name;
}
function children(d) {
return d.c || d.children;
}
function value(d) {
return d.v || d.value;
}
var label = function(d) {
return d.data.name + " (" + d3.format(".3f")(100 * (d.x1 - d.x0), 3) + "%, " + d.data.value + " samples)";
return name(d) + " (" + d3.format(".3f")(100 * (d.x1 - d.x0), 3) + "%, " + value(d) + " samples)";
};

@@ -38,8 +123,4 @@

function name(d) {
return d.data.name;
}
var colorMapper = function(d) {
return d.highlight ? "#E600E6" : colorHash(d.data.name);
return d.highlight ? "#E600E6" : colorHash(name(d));
};

@@ -85,8 +166,11 @@

if(!d.data.original) {
d.data.original = d.data.value;
d.data.original = value(d);
}
d.data.value = 0;
if(d.children) {
d.children.forEach(hide);
d.data.v = 0;
if (d.data.value) {
delete d.data.value;
}
if(children(d)) {
children(d).forEach(hide);
}
}

@@ -97,6 +181,6 @@

if(d.data.original) {
d.data.value = d.data.original;
d.data.v = d.data.original;
}
if(d.children) {
d.children.forEach(show);
if(children(d)) {
children(d).forEach(show);
}

@@ -155,6 +239,6 @@ }

function searchInner(d) {
var label = d.data.name;
var label = name(d);
if (d.children) {
d.children.forEach(function (child) {
if (children(d)) {
children(d).forEach(function (child) {
searchInner(child);

@@ -178,4 +262,4 @@ });

d.highlight = false;
if(d.children) {
d.children.forEach(function(child) {
if(children(d)) {
children(d).forEach(function(child) {
clear(child);

@@ -190,3 +274,3 @@ });

} else if (sort) {
return d3.ascending(a.data.name, b.data.name);
return d3.ascending(name(a), name(b));
}

@@ -197,2 +281,13 @@ }

function filterNodes(root) {
var nodeList = root.descendants();
if (minFrameSize > 0) {
var kx = w / (root.x1 - root.x0);
nodeList = nodeList.filter(function(el) {
return ((el.x1 - el.x0) * kx) > minFrameSize;
});
}
return nodeList;
}
function update() {

@@ -204,4 +299,3 @@

if (sort)
root.sort(doSort);
if (sort) root.sort(doSort);
root.sum(function(d) {

@@ -212,6 +306,7 @@ if (d.fade) {

// The node's self value is its total value minus all children.
var v = d.v || d.value || 0;
if (d.children) {
for (var i = 0; i < d.children.length; i++) {
v -= d.children[i].value;
var v = value(d) || 0;
if (children(d)) {
var c = children(d);
for (var i = 0; i < c.length; i++) {
v -= c[i].value;
}

@@ -226,3 +321,4 @@ }

var g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
var descendants = filterNodes(root);
var g = d3.select(this).select("svg").selectAll("g").data(descendants, function(d) { return d.id; });

@@ -234,5 +330,3 @@ g.transition()

g.select("rect").transition()
.duration(transitionDuration)
.ease(transitionEase)
g.select("rect")
.attr("width", width);

@@ -243,5 +337,8 @@

.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + (reversed ? y(d.depth) : (h - y(d.depth) - c)) + ")"; });
node.append("svg:rect").attr("width", width);
node.append("svg:rect")
.transition()
.delay(transitionDuration / 2)
.attr("width", width);
if (!tooltip)

@@ -254,7 +351,7 @@ node.append("svg:title");

// Now we have to re-select to see the new elements (why?).
g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
g = d3.select(this).select("svg").selectAll("g").data(descendants, function(d) { return d.id; });
g.attr("width", width)
.attr("height", function(d) { return c; })
.attr("name", function(d) { return d.data.name; })
.attr("name", function(d) { return name(d); })
.attr("class", function(d) { return d.data.fade ? "frame fade" : "frame"; });

@@ -276,2 +373,4 @@

.style("display", function(d) { return (width(d) < 35) ? "none" : "block";})
.transition()
.delay(transitionDuration)
.text(name);

@@ -281,3 +380,4 @@

g.exit().remove();
g.exit()
.remove();

@@ -296,4 +396,4 @@ g.on('mouseover', function(d) {

samples.forEach(function (sample) {
var node = _.find(data, function (element) {
return element.name === sample.name;
var node = data.find(function (element) {
return (name(element) === name(sample));
});

@@ -319,4 +419,19 @@

function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
function injectIds(node) {
node.id = s4();
var children = node.c || node.children || [];
for (var i = 0; i < children.length; i++) {
injectIds(children[i]);
}
}
function chart(s) {
var root = d3.hierarchy(s.datum(), function(d) { return d.c || d.children; });
var root = d3.hierarchy(s.datum(), function(d) { return children(d); });
injectIds(root);
selection = s.datum(root);

@@ -326,2 +441,6 @@

if (!h) {
h = (root.height + 2) * c;
}
selection.each(function(data) {

@@ -452,3 +571,3 @@

merge([root.data], [samples]);
newRoot = d3.hierarchy(root.data, function(d) { return d.c || d.children; });
newRoot = d3.hierarchy(root.data, function(d) { return children(d); });
});

@@ -465,2 +584,8 @@ selection = selection.datum(newRoot);

chart.minFrameSize = function (_) {
if (!arguments.length) { return minFrameSize; }
minFrameSize = _;
return chart;
};
return chart;

@@ -467,0 +592,0 @@ }

@@ -1,1 +0,1 @@

!function(){"use strict";function t(){function t(t){var n=document.getElementById("details");n&&(n.innerHTML=t)}function n(t){return t.data.name}function e(t){var n=0,e=1,r=0;if(t){for(var a=0;a<t.length&&!(a>6);a++)n+=e*(t.charCodeAt(a)%10),r+=9*e,e*=.7;r>0&&(n/=r)}return n}function r(t){var n=0;if(t){var r=t.split("`");r.length>1&&(t=r[r.length-1]),n=e(t=t.split("(")[0])}return"rgb("+(200+Math.round(55*n))+","+(0+Math.round(230*(1-n)))+","+(0+Math.round(55*(1-n)))+")"}function a(t){t.data.original||(t.data.original=t.data.value),t.data.value=0,t.children&&t.children.forEach(a)}function i(t){t.data.fade=!1,t.data.original&&(t.data.value=t.data.original),t.children&&t.children.forEach(i)}function c(t){var n=[];if(t.parent){var e=t.parent.children.indexOf(t);(n=t.parent.children.slice(0)).splice(e,1)}return n}function u(t){c(t).forEach(function(t){a(t)}),t.parent&&u(t.parent)}function o(t){t.parent&&(t.parent.data.fade=!0,o(t.parent))}function l(t){O.hide(t),u(t),i(t),o(t),s(),"function"==typeof L&&L(t)}function d(t,n){function e(t){var n=t.data.name;t.children&&t.children.forEach(function(t){e(t)}),n.match(r)?(t.highlight=!0,a.push(t)):t.highlight=!1}var r=new RegExp(n),a=[];return e(t),a}function f(t){t.highlight=!1,t.children&&t.children.forEach(function(t){f(t)})}function h(t,n){return"function"==typeof A?A(t,n):A?d3.ascending(t.data.name,n.data.name):void 0}function s(){y.each(function(e){function r(t){return(t.x1-t.x0)*c}var a=d3.scaleLinear().range([0,m]),i=d3.scaleLinear().range([0,E]);A&&e.sort(h),e.sum(function(t){if(t.fade)return 0;var n=t.v||t.value||0;if(t.children)for(var e=0;e<t.children.length;e++)n-=t.children[e].value;return n}),T(e);var c=m/(e.x1-e.x0),u=d3.select(this).select("svg").selectAll("g").data(e.descendants());u.transition().duration(M).ease(k).attr("transform",function(t){return"translate("+a(t.x0)+","+(C?i(t.depth):x-i(t.depth)-E)+")"}),u.select("rect").transition().duration(M).ease(k).attr("width",r);var o=u.enter().append("svg:g").attr("transform",function(t){return"translate("+a(t.x0)+","+(C?i(t.depth):x-i(t.depth)-E)+")"});o.append("svg:rect").attr("width",r),w||o.append("svg:title"),o.append("foreignObject").append("xhtml:div"),(u=d3.select(this).select("svg").selectAll("g").data(e.descendants())).attr("width",r).attr("height",function(t){return E}).attr("name",function(t){return t.data.name}).attr("class",function(t){return t.data.fade?"frame fade":"frame"}),u.select("rect").attr("height",function(t){return E}).attr("fill",function(t){return H(t)}),w||u.select("title").text(j),u.select("foreignObject").attr("width",r).attr("height",function(t){return E}).select("div").attr("class","label").style("display",function(t){return r(t)<35?"none":"block"}).text(n),u.on("click",l),u.exit().remove(),u.on("mouseover",function(n){w&&O.show(n),t(j(n))}).on("mouseout",function(n){w&&O.hide(n),t("")})})}function g(t,n){n.forEach(function(n){var e=_.find(t,function(t){return t.name===n.name});e?(e.original?e.original+=n.value:e.value+=n.value,n.children&&(e.children||(e.children=[]),g(e.children,n.children))):t.push(n)})}function p(t){var n=d3.hierarchy(t.datum(),function(t){return t.c||t.children});if(y=t.datum(n),!arguments.length)return p;y.each(function(t){v||(v=d3.select(this).append("svg:svg").attr("width",m).attr("height",x).attr("class","partition d3-flame-graph").call(O)).append("svg:text").attr("class","title").attr("text-anchor","middle").attr("y","25").attr("x",m/2).attr("fill","#808080").text(b)}),s()}var v,m=960,x=540,E=18,y=null,w=!0,b="",M=750,k=d3.easeCubic,A=!0,C=!1,L=null,O=d3.tip().direction("s").offset([8,0]).attr("class","d3-flame-graph-tip").html(function(t){return j(t)}),j=function(t){return t.data.name+" ("+d3.format(".3f")(100*(t.x1-t.x0),3)+"%, "+t.data.value+" samples)"},H=function(t){return t.highlight?"#E600E6":r(t.data.name)},T=d3.partition();return p.height=function(t){return arguments.length?(x=t,p):x},p.width=function(t){return arguments.length?(m=t,p):m},p.cellHeight=function(t){return arguments.length?(E=t,p):E},p.tooltip=function(t){return arguments.length?("function"==typeof t&&(O=t),w=!!t,p):w},p.title=function(t){return arguments.length?(b=t,p):b},p.transitionDuration=function(t){return arguments.length?(M=t,p):M},p.transitionEase=function(t){return arguments.length?(k=t,p):k},p.sort=function(t){return arguments.length?(A=t,p):A},p.reversed=function(t){return arguments.length?(C=t,p):C},p.label=function(t){return arguments.length?(j=t,p):j},p.search=function(t){var n=[];return y.each(function(e){n=d(e,t),s()}),n},p.clear=function(){y.each(function(t){f(t),s()})},p.zoomTo=function(t){l(t)},p.resetZoom=function(){y.each(function(t){l(t)})},p.onClick=function(t){return arguments.length?(L=t,p):L},p.merge=function(t){var n;y.each(function(e){g([e.data],[t]),n=d3.hierarchy(e.data,function(t){return t.c||t.children})}),y=y.datum(n),s()},p.color=function(t){return arguments.length?(H=t,p):H},p}"undefined"!=typeof module&&module.exports?module.exports=t:d3.flameGraph=t}();
!function(){"use strict";function n(){function t(t){return t.data.n||t.data.name}function n(t){return t.c||t.children}function r(t){return t.v||t.value}function e(t){var n=document.getElementById("details");n&&(n.innerHTML=t)}function i(t){var n=0,r=1,e=0,i=10,a=6;if(t){for(var u=0;u<t.length&&!(u>a);u++)n+=r*(t.charCodeAt(u)%i),e+=r*(i-1),r*=.7;e>0&&(n/=e)}return n}function a(t){var n=0;if(t){var r=t.split("`");r.length>1&&(t=r[r.length-1]),t=t.split("(")[0],n=i(t)}var e=200+Math.round(55*n),a=0+Math.round(230*(1-n)),u=0+Math.round(55*(1-n));return"rgb("+e+","+a+","+u+")"}function u(t){t.data.original||(t.data.original=r(t)),t.data.v=0,t.data.value&&delete t.data.value,n(t)&&n(t).forEach(u)}function o(t){t.data.fade=!1,t.data.original&&(t.data.v=t.data.original),n(t)&&n(t).forEach(o)}function c(t){var n=[];if(t.parent){var r=t.parent.children.indexOf(t);n=t.parent.children.slice(0),n.splice(r,1)}return n}function f(t){var n=c(t);n.forEach(function(t){u(t)}),t.parent&&f(t.parent)}function l(t){t.parent&&(t.parent.data.fade=!0,l(t.parent))}function h(t){B.hide(t),f(t),o(t),l(t),v(),"function"==typeof H&&H(t)}function d(r,e){function i(r){var e=t(r);n(r)&&n(r).forEach(function(t){i(t)}),e.match(a)?(r.highlight=!0,u.push(r)):r.highlight=!1}var a=new RegExp(e),u=[];return i(r),u}function s(t){t.highlight=!1,n(t)&&n(t).forEach(function(t){s(t)})}function g(n,r){return"function"==typeof L?L(n,r):L?d3.ascending(t(n),t(r)):void 0}function p(t){var n=t.descendants();if(S>0){var r=b/(t.x1-t.x0);n=n.filter(function(t){return(t.x1-t.x0)*r>S})}return n}function v(){O.each(function(i){function a(t){return(t.x1-t.x0)*c}var u=d3.scaleLinear().range([0,b]),o=d3.scaleLinear().range([0,M]);L&&i.sort(g),i.sum(function(t){if(t.fade)return 0;var e=r(t)||0;if(n(t))for(var i=n(t),a=0;a<i.length;a++)e-=i[a].value;return e}),G(i);var c=b/(i.x1-i.x0),f=p(i),l=d3.select(this).select("svg").selectAll("g").data(f,function(t){return t.id});l.transition().duration(k).ease(C).attr("transform",function(t){return"translate("+u(t.x0)+","+(z?o(t.depth):A-o(t.depth)-M)+")"}),l.select("rect").attr("width",a);var d=l.enter().append("svg:g").attr("transform",function(t){return"translate("+u(t.x0)+","+(z?o(t.depth):A-o(t.depth)-M)+")"});d.append("svg:rect").transition().delay(k/2).attr("width",a),T||d.append("svg:title"),d.append("foreignObject").append("xhtml:div"),l=d3.select(this).select("svg").selectAll("g").data(f,function(t){return t.id}),l.attr("width",a).attr("height",function(t){return M}).attr("name",function(n){return t(n)}).attr("class",function(t){return t.data.fade?"frame fade":"frame"}),l.select("rect").attr("height",function(t){return M}).attr("fill",function(t){return F(t)}),T||l.select("title").text(D),l.select("foreignObject").attr("width",a).attr("height",function(t){return M}).select("div").attr("class","label").style("display",function(t){return a(t)<35?"none":"block"}).transition().delay(k).text(t),l.on("click",h),l.exit().remove(),l.on("mouseover",function(t){T&&B.show(t),e(D(t))}).on("mouseout",function(t){T&&B.hide(t),e("")})})}function m(n,r){r.forEach(function(r){var e=n.find(function(n){return t(n)===t(r)});e?(e.original?e.original+=r.value:e.value+=r.value,r.children&&(e.children||(e.children=[]),m(e.children,r.children))):n.push(r)})}function y(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}function x(t){t.id=y();for(var n=t.c||t.children||[],r=0;r<n.length;r++)x(n[r])}function w(t){var r=d3.hierarchy(t.datum(),function(t){return n(t)});return x(r),O=t.datum(r),arguments.length?(A||(A=(r.height+2)*M),O.each(function(t){E||(E=d3.select(this).append("svg:svg").attr("width",b).attr("height",A).attr("class","partition d3-flame-graph").call(B),E.append("svg:text").attr("class","title").attr("text-anchor","middle").attr("y","25").attr("x",b/2).attr("fill","#808080").text(j))}),void v()):w}var E,b=960,A=null,M=18,O=null,T=!0,j="",k=750,C=d3.easeCubic,L=!1,z=!1,H=null,S=0,B=d3.tip().direction("s").offset([8,0]).attr("class","d3-flame-graph-tip").html(function(t){return D(t)}),D=function(n){return t(n)+" ("+d3.format(".3f")(100*(n.x1-n.x0),3)+"%, "+r(n)+" samples)"},F=function(n){return n.highlight?"#E600E6":a(t(n))},G=d3.partition();return w.height=function(t){return arguments.length?(A=t,w):A},w.width=function(t){return arguments.length?(b=t,w):b},w.cellHeight=function(t){return arguments.length?(M=t,w):M},w.tooltip=function(t){return arguments.length?("function"==typeof t&&(B=t),T=!!t,w):T},w.title=function(t){return arguments.length?(j=t,w):j},w.transitionDuration=function(t){return arguments.length?(k=t,w):k},w.transitionEase=function(t){return arguments.length?(C=t,w):C},w.sort=function(t){return arguments.length?(L=t,w):L},w.reversed=function(t){return arguments.length?(z=t,w):z},w.label=function(t){return arguments.length?(D=t,w):D},w.search=function(t){var n=[];return O.each(function(r){n=d(r,t),v()}),n},w.clear=function(){O.each(function(t){s(t),v()})},w.zoomTo=function(t){h(t)},w.resetZoom=function(){O.each(function(t){h(t)})},w.onClick=function(t){return arguments.length?(H=t,w):H},w.merge=function(t){var r;O.each(function(e){m([e.data],[t]),r=d3.hierarchy(e.data,function(t){return n(t)})}),O=O.datum(r),v()},w.color=function(t){return arguments.length?(F=t,w):F},w.minFrameSize=function(t){return arguments.length?(S=t,w):S},w}Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(t){if(null==this)throw new TypeError('"this" is null or not defined');var n=Object(this),r=n.length>>>0;if("function"!=typeof t)throw new TypeError("predicate must be a function");for(var e=arguments[1],i=0;r>i;){var a=n[i];if(t.call(e,a,i,n))return a;i++}return void 0}}),Array.prototype.filter||(Array.prototype.filter=function(n,r){if("function"!=typeof n||!this)throw new TypeError;var e=this.length>>>0,i=new Array(e),a=0,u=-1;if(void 0===r)for(;++u!==e;)if(u in this)if(n(t[u],u,t))i[a++]=t[u];else for(;++u!==e;)u in this&&n.call(r,t[u],u,t)&&(i[a++]=t[u]);return i.length=a,i}),"undefined"!=typeof module&&module.exports?module.exports=n:d3.flameGraph=n}();
{
"name": "d3-flame-graph",
"version": "1.0.1",
"version": "1.0.4",
"description": "A d3.js library to produce flame graphs.",

@@ -10,3 +10,4 @@ "main": "src/d3.flame.js",

"scripts": {
"test": "mocha --reporter nyan"
"test": "mocha --reporter nyan",
"dist": "gulp dist && git add src/*"
},

@@ -48,4 +49,8 @@ "repository": {

"d3": "^4.10.0",
"d3-tip": "^0.7.1",
"graceful-fs": "^4.1.11"
}
},
"pre-commit": [
"dist"
]
}

@@ -5,3 +5,3 @@ # d3-flame-graph

[![Flame Graph Example](http://giant.gfycat.com/DelectableResponsibleHart.gif)](http://spiermar.github.io/d3-flame-graph/)
[![Flame Graph Example](https://media.giphy.com/media/l41JMjBaxrZw1bqpi/giphy.gif)](http://spiermar.github.io/d3-flame-graph/)

@@ -14,16 +14,39 @@ If you don't know what flame graphs are, check [Brendan Gregg's post](http://www.brendangregg.com/flamegraphs.html).

## Disclaimer
## Examples
This is the first release of this plugin. As such, expect to find bugs and issues. We count on your support to find and report them!
Click [here](http://spiermar.github.io/d3-flame-graph/) to check the demo, and [source](https://github.com/spiermar/d3-flame-graph/blob/gh-pages/index.html).
**At this point, the plugin provides only basic flame graph functionality. Please check the [issues](https://github.com/spiermar/d3-flame-graph/issues) page for roadmap information.**
Click [here](http://spiermar.github.io/d3-flame-graph/live.html) to check the animated assembly demo, and [source](https://github.com/spiermar/d3-flame-graph/blob/gh-pages/live.html)
## Demo
Click [here](http://bl.ocks.org/spiermar/4509343495f8d6e214cb) to check the simplified demo on bl.ocks.org.
Click [here](http://spiermar.github.io/d3-flame-graph/) to check the fully-featured demo!
## Getting Started
Click [here](http://bl.ocks.org/spiermar/4509343495f8d6e214cb) to check the simplified demo on bl.ocks.org!
### jsdelivr CDN
## Getting Started
Just reference the CDN hosted CSS and JS files!
```html
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/spiermar/d3-flame-graph@1.0.4/dist/d3.flameGraph.min.css">
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/spiermar/d3-flame-graph@1.0.4/dist/d3.flameGraph.min.js"></script>
<script type="text/javascript">
var flamegraph = d3.flameGraph()
.width(960);
d3.json("data.json", function(error, data) {
if (error) return console.warn(error);
d3.select("#chart")
.datum(data)
.call(flamegraph);
});
</script>
</body>
```
### Bower

@@ -48,20 +71,28 @@

```html
<script type="text/javascript" src="bower_components/d3/d3.js"></script>
<script type="text/javascript" src="bower_components/d3-flame-graph/dist/d3.layout.flame.js"></script>
<script type="text/javascript">
var flamegraph = d3.flameGraph()
.width(960)
.height(540);
<head>
<link rel="stylesheet" type="text/css" href="bower_components/d3-flame-graph/dist/d3.flameGraph.css">
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="bower_components/d3/d3.js"></script>
<script type="text/javascript" src="bower_components/d3-tip/index.js"></script>
<script type="text/javascript" src="bower_components/d3-flame-graph/dist/d3.flameGraph.js"></script>
<script type="text/javascript">
var flamegraph = d3.flameGraph()
.width(960);
d3.json("stacks.json", function(error, data) {
if (error) return console.warn(error);
d3.select("#chart")
d3.json("data.json", function(error, data) {
if (error) return console.warn(error);
d3.select("#chart")
.datum(data)
.call(flamegraph);
});
</script>
});
</script>
</body>
```
### Input Format
More detailed examples in the [/example](/example) directory.
## Input Format
Input stack is a simple hierarchical data structure in JSON format.

@@ -79,5 +110,5 @@

JSON format can be converted from the folded stack format using the [node-stack-convert](https://github.com/spiermar/node-stack-convert) CLI tool.
JSON format can be converted from the folded stack format using the [stacko](https://github.com/spiermar/stacko) CLI tool.
### Interacting with entries
## Interacting with entries

@@ -99,6 +130,4 @@ Internally, the data is transformed into a d3 **hierarchy**.

**This is a breaking change from previous versions of d3-flame-graph, which were based on version 3 of the d3 library***
This is a breaking change from previous versions of d3-flame-graph, which were based on version 3 of the d3 library. See [d3-hierarchy](https://github.com/d3/d3-hierarchy#hierarchy).
See [d3-hierarchy](https://github.com/d3/d3-hierarchy#hierarchy).
## API Reference

@@ -112,15 +141,19 @@

Graph width in px. Defaults to 960px if not set. If <i>size</i> is specified, it will set de graph width, otherwise it will return the flameGraph object.
Graph width in px. Defaults to 960px if not set. If <i>size</i> is specified, it will set the graph width, otherwise it will return the flameGraph object.
<a name="height" href="#height">#</a> flameGraph.<b>height</b>(<i>[size]</i>)
Graph height in px. Defaults to 540px if not set. If <i>size</i> is specified, it will set de graph height, otherwise it will return the flameGraph object.
Graph height in px. Defaults to the number of cell rows times <a name="cellHeight" href="#cellHeight"><b>cellHeight</b></a> if not set. If <i>size</i> is specified, it will set the cell height, otherwise it will return the flameGraph object.
<a name="cellHeight" href="#cellHeight">#</a> flameGraph.<b>cellHeight</b>(<i>[size]</i>)
Cell height in px. Defaults to 18px if not set. If <i>size</i> is specified, it will set de cell height, otherwise it will return the flameGraph object.
Cell height in px. Defaults to 18px if not set. If <i>size</i> is specified, it will set the cell height, otherwise it will return the flameGraph object.
<a name="minFrameSize" href="#minFrameSize">#</a> flameGraph.<b>minFrameSize</b>(<i>[size]</i>)
Minimum size of a frame, in px, to be displayed in the flame graph. Defaults to 0px if not set. If <i>size</i> is specified, it will set the minimum frame size, otherwise it will return the flameGraph object.
<a name="title" href="#title">#</a> flameGraph.<b>title</b>(<i>[title]</i>)
Title displayed on top of graph. Defaults to empty if not set. If <i>title</i> is specified, it will set de title displayed on the graph, otherwise it will return the flameGraph object.
Title displayed on top of graph. Defaults to empty if not set. If <i>title</i> is specified, it will set the title displayed on the graph, otherwise it will return the flameGraph object.

@@ -151,2 +184,12 @@ <a name="tooltip" href="#tooltip">#</a> flameGraph.<b>tooltip</b>(<i>[enabled]</i>)

<a name="label" href="#label">#</a> flameGraph.<b>label</b>(<i>[function]</i>)
Adds a function that returns a formatted label. Example:
```js
flameGraph.label(function(d) {
return "name: " + d.name + ", value: " + d.value;
});
```
<a name="sort" href="#sort">#</a> flameGraph.<b>sort</b>(<i>[enabled]</i>)

@@ -153,0 +196,0 @@

(function() {
'use strict';
/*jshint eqnull:true */
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
}
});
}
if (!Array.prototype.filter)
Array.prototype.filter = function(func, thisArg) {
if ( ! ((typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
c = 0, i = -1;
if (thisArg === undefined)
while (++i !== len)
// checks to see if the key was set
if (i in this)
if (func(t[i], i, t))
res[c++] = t[i];
else
while (++i !== len)
// checks to see if the key was set
if (i in this)
if (func.call(thisArg, t[i], i, t))
res[c++] = t[i];
res.length = c; // shrink down array to proper size
return res;
};
/*jshint eqnull:false */
function flameGraph() {
var w = 960, // graph width
h = 540, // graph height
h = null, // graph height
c = 18, // cell height

@@ -14,5 +86,6 @@ selection = null, // selection

transitionEase = d3.easeCubic, // tooltip offset
sort = true,
sort = false,
reversed = false, // reverse the graph direction
clickHandler = null;
clickHandler = null,
minFrameSize = 0;

@@ -27,4 +100,16 @@ var tip = d3.tip()

function name(d) {
return d.data.n || d.data.name;
}
function children(d) {
return d.c || d.children;
}
function value(d) {
return d.v || d.value;
}
var label = function(d) {
return d.data.name + " (" + d3.format(".3f")(100 * (d.x1 - d.x0), 3) + "%, " + d.data.value + " samples)";
return name(d) + " (" + d3.format(".3f")(100 * (d.x1 - d.x0), 3) + "%, " + value(d) + " samples)";
};

@@ -38,8 +123,4 @@

function name(d) {
return d.data.name;
}
var colorMapper = function(d) {
return d.highlight ? "#E600E6" : colorHash(d.data.name);
return d.highlight ? "#E600E6" : colorHash(name(d));
};

@@ -85,8 +166,11 @@

if(!d.data.original) {
d.data.original = d.data.value;
d.data.original = value(d);
}
d.data.value = 0;
if(d.children) {
d.children.forEach(hide);
d.data.v = 0;
if (d.data.value) {
delete d.data.value;
}
if(children(d)) {
children(d).forEach(hide);
}
}

@@ -97,6 +181,6 @@

if(d.data.original) {
d.data.value = d.data.original;
d.data.v = d.data.original;
}
if(d.children) {
d.children.forEach(show);
if(children(d)) {
children(d).forEach(show);
}

@@ -155,6 +239,6 @@ }

function searchInner(d) {
var label = d.data.name;
var label = name(d);
if (d.children) {
d.children.forEach(function (child) {
if (children(d)) {
children(d).forEach(function (child) {
searchInner(child);

@@ -178,4 +262,4 @@ });

d.highlight = false;
if(d.children) {
d.children.forEach(function(child) {
if(children(d)) {
children(d).forEach(function(child) {
clear(child);

@@ -190,3 +274,3 @@ });

} else if (sort) {
return d3.ascending(a.data.name, b.data.name);
return d3.ascending(name(a), name(b));
}

@@ -197,2 +281,13 @@ }

function filterNodes(root) {
var nodeList = root.descendants();
if (minFrameSize > 0) {
var kx = w / (root.x1 - root.x0);
nodeList = nodeList.filter(function(el) {
return ((el.x1 - el.x0) * kx) > minFrameSize;
});
}
return nodeList;
}
function update() {

@@ -204,4 +299,3 @@

if (sort)
root.sort(doSort);
if (sort) root.sort(doSort);
root.sum(function(d) {

@@ -212,6 +306,7 @@ if (d.fade) {

// The node's self value is its total value minus all children.
var v = d.v || d.value || 0;
if (d.children) {
for (var i = 0; i < d.children.length; i++) {
v -= d.children[i].value;
var v = value(d) || 0;
if (children(d)) {
var c = children(d);
for (var i = 0; i < c.length; i++) {
v -= c[i].value;
}

@@ -226,3 +321,4 @@ }

var g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
var descendants = filterNodes(root);
var g = d3.select(this).select("svg").selectAll("g").data(descendants, function(d) { return d.id; });

@@ -234,5 +330,3 @@ g.transition()

g.select("rect").transition()
.duration(transitionDuration)
.ease(transitionEase)
g.select("rect")
.attr("width", width);

@@ -243,5 +337,8 @@

.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + (reversed ? y(d.depth) : (h - y(d.depth) - c)) + ")"; });
node.append("svg:rect").attr("width", width);
node.append("svg:rect")
.transition()
.delay(transitionDuration / 2)
.attr("width", width);
if (!tooltip)

@@ -254,7 +351,7 @@ node.append("svg:title");

// Now we have to re-select to see the new elements (why?).
g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
g = d3.select(this).select("svg").selectAll("g").data(descendants, function(d) { return d.id; });
g.attr("width", width)
.attr("height", function(d) { return c; })
.attr("name", function(d) { return d.data.name; })
.attr("name", function(d) { return name(d); })
.attr("class", function(d) { return d.data.fade ? "frame fade" : "frame"; });

@@ -276,2 +373,4 @@

.style("display", function(d) { return (width(d) < 35) ? "none" : "block";})
.transition()
.delay(transitionDuration)
.text(name);

@@ -281,3 +380,4 @@

g.exit().remove();
g.exit()
.remove();

@@ -296,4 +396,4 @@ g.on('mouseover', function(d) {

samples.forEach(function (sample) {
var node = _.find(data, function (element) {
return element.name === sample.name;
var node = data.find(function (element) {
return (name(element) === name(sample));
});

@@ -319,4 +419,19 @@

function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
function injectIds(node) {
node.id = s4();
var children = node.c || node.children || [];
for (var i = 0; i < children.length; i++) {
injectIds(children[i]);
}
}
function chart(s) {
var root = d3.hierarchy(s.datum(), function(d) { return d.c || d.children; });
var root = d3.hierarchy(s.datum(), function(d) { return children(d); });
injectIds(root);
selection = s.datum(root);

@@ -326,2 +441,6 @@

if (!h) {
h = (root.height + 2) * c;
}
selection.each(function(data) {

@@ -452,3 +571,3 @@

merge([root.data], [samples]);
newRoot = d3.hierarchy(root.data, function(d) { return d.c || d.children; });
newRoot = d3.hierarchy(root.data, function(d) { return children(d); });
});

@@ -465,2 +584,8 @@ selection = selection.datum(newRoot);

chart.minFrameSize = function (_) {
if (!arguments.length) { return minFrameSize; }
minFrameSize = _;
return chart;
};
return chart;

@@ -467,0 +592,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc