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 0.4.2 to 1.0.0

example/live.html

7

bower.json

@@ -27,8 +27,9 @@ {

"dependencies": {
"d3": "~3.5.5",
"d3-tip": "~0.6.7"
"d3": "~4",
"d3-tip": "~0.7.1",
"lodash": "~3.10.1"
},
"resolutions": {
"d3": "3.5.5"
"d3": "4.8.0"
}
}
{
"name": "d3-flame-graph",
"version": "0.4.2",
"version": "1.0.0",
"description": "A d3.js library to produce flame graphs.",

@@ -5,0 +5,0 @@ "main": "src/d3.flame.js",

@@ -21,4 +21,6 @@ # d3-flame-graph

Click [here](http://spiermar.github.io/d3-flame-graph/) to check the demo!
Click [here](http://spiermar.github.io/d3-flame-graph/) to check the fully-featured demo!
Click [here](http://bl.ocks.org/spiermar/4509343495f8d6e214cb) to check the simplified demo on bl.ocks.org!
## Getting Started

@@ -43,3 +45,3 @@

```
```html
<script type="text/javascript" src="bower_components/d3/d3.js"></script>

@@ -65,3 +67,3 @@ <script type="text/javascript" src="bower_components/d3-flame-graph/dist/d3.layout.flame.js"></script>

```
```js
{

@@ -78,2 +80,23 @@ "name": "<name>",

### Interacting with entries
Internally, the data is transformed into a d3 **hierarchy**.
Functions like `onClick`, `label` and `zoom` expose individual entries as hierarchy Nodes, which wrap the provided data and add more properties:
```
{
"data": <original user-provided object>,
"parent": <another hierarchy node>,
"children": [
<hierarchy node>
],
"x1": <double>, // x2 - x1 is the size of this node, as a fraction of the root.
"x2": <double>
}
```
**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).
## API Reference

@@ -107,3 +130,3 @@

```
```js
.attr('class', 'd3-flame-graph-tip')

@@ -122,28 +145,26 @@ ```

Specifies the transition easing function. The default easing function is "cubic-in-out". If ease is not specified, returns the flameGraph object. The following easing types are supported:
Specifies the transition easing function. The default easing function is `d3.easeCubic`.
* linear - the identity function, t.
* poly(k) - raises t to the specified power k (e.g., 3).
* quad - equivalent to poly(2).
* cubic - equivalent to poly(3).
* sin - applies the trigonometric function sin.
* exp - raises 2 to a power based on t.
* circle - the quarter circle.
* elastic(a, p) - simulates an elastic band; may extend slightly beyond 0 and 1.
* back(s) - simulates backing into a parking space.
* bounce - simulates a bouncy collision.
See [d3-ease](https://github.com/d3/d3-ease).
These built-in types may be extended using a variety of modes:
<a name="sort" href="#sort">#</a> flameGraph.<b>sort</b>(<i>[enabled]</i>)
* in - the identity function.
* out - reverses the easing direction to [1,0].
* in-out - copies and mirrors the easing function from [0,.5] and [.5,1].
* out-in - copies and mirrors the easing function from [1,.5] and [.5,0].
Enables/disables sorting of children frames. Defaults to <i>true</i> if not set to sort in ascending order by frame's name. If set to a function, the function takes two frames (a,b) and returns -1 if frame a is less than b, 1 if greater, or 0 if equal. If a value is specified, it will enable/disable sorting, otherwise it will return the flameGraph object.
See [d3.ease](https://github.com/mbostock/d3/wiki/Transitions#d3_ease).
<a name="resetZoom" href="#resetZoom">#</a> flameGraph.<b>resetZoom</b>()
<a name="sort" href="#sort">#</a> flameGraph.<b>sort</b>(<i>[enabled]</i>)
Resets the zoom so that everything is visible.
Enables/disables sorting of children frames. Defaults to <i>true</i> if not set to sort in ascending order by frame's name. If set to a function, the function takes two frames (a,b) and returns -1 if frame a is less than b, 1 if greater, or 0 if equal. If a value is specified, it will enable/disable sorting, otherwise it will return the flameGraph object.
<a name="onClick" href="#onClick">#</a> flameGraph.<b>onClick</b>(<i>[function]</i>)
Adds a function that will be called when the user clicks on a frame. Example:
```js
flameGraph.onClick(function (d) {
console.info("You clicked on frame "+ d.data.name);
});
```
If called with no arguments, `onClick` will return the click handler.
## Issues

@@ -150,0 +171,0 @@

@@ -13,4 +13,6 @@ (function() {

transitionDuration = 750,
transitionEase = "cubic-in-out", // tooltip offset
sort = true;
transitionEase = d3.easeCubic, // tooltip offset
sort = true,
reversed = false, // reverse the graph direction
clickHandler = null;

@@ -23,6 +25,8 @@ var tip = d3.tip()

var labelFormat = function(d) {
return d.name + " (" + d3.round(100 * d.dx, 3) + "%, " + d.value + " samples)";
}
var svg;
var label = function(d) {
return d.data.name + " (" + d3.format(".3f")(100 * (d.x1 - d.x0), 3) + "%, " + d.data.value + " samples)";
};
function setDetails(t) {

@@ -34,14 +38,10 @@ var details = document.getElementById("details");

function label(d) {
if (!d.dummy) {
return labelFormat(d);
} else {
return "";
}
}
function name(d) {
return d.name;
return d.data.name;
}
var colorMapper = function(d) {
return d.highlight ? "#E600E6" : colorHash(d.data.name);
};
function generateHash(name) {

@@ -80,29 +80,7 @@ // Return a vector (0.0->1.0) that is a hash of the input string.

function augment(data) {
// Augment partitioning layout with "dummy" nodes so that internal nodes'
// values dictate their width. Annoying, but seems to be least painful
// option. https://github.com/mbostock/d3/pull/574
if (data.children && (data.children.length > 0)) {
data.children.forEach(augment);
var childValues = 0;
data.children.forEach(function(child) {
childValues += child.value;
});
if (childValues < data.value) {
data.children.push(
{
"name": "",
"value": data.value - childValues,
"dummy": true
}
);
}
}
}
function hide(d) {
if(!d.original) {
d.original = d.value;
if(!d.data.original) {
d.data.original = d.data.value;
}
d.value = 0;
d.data.value = 0;
if(d.children) {

@@ -114,5 +92,5 @@ d.children.forEach(hide);

function show(d) {
d.fade = false;
if(d.original) {
d.value = d.original;
d.data.fade = false;
if(d.data.original) {
d.data.value = d.data.original;
}

@@ -146,3 +124,3 @@ if(d.children) {

if(d.parent) {
d.parent.fade = true;
d.parent.data.fade = true;
fadeAncestors(d.parent);

@@ -165,2 +143,5 @@ }

update();
if (typeof clickHandler === 'function') {
clickHandler(d);
}
}

@@ -170,15 +151,23 @@

var re = new RegExp(term),
label = d.name;
searchResults = [];
if(d.children) {
d.children.forEach(function(child) {
searchTree(child, term);
});
function searchInner(d) {
var label = d.data.name;
if (d.children) {
d.children.forEach(function (child) {
searchInner(child);
});
}
if (label.match(re)) {
d.highlight = true;
searchResults.push(d);
} else {
d.highlight = false;
}
}
if (label.match(re)) {
d.highlight = true;
} else {
d.highlight = false;
}
searchInner(d);
return searchResults;
}

@@ -190,3 +179,3 @@

d.children.forEach(function(child) {
clear(child, term);
clear(child);
});

@@ -200,3 +189,3 @@ }

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

@@ -207,24 +196,36 @@ return 0;

var partition = d3.layout.partition()
.sort(doSort)
.value(function(d) {return d.v || d.value;})
.children(function(d) {return d.c || d.children;});
var partition = d3.partition();
function update() {
selection.each(function(data) {
selection.each(function(root) {
var x = d3.scaleLinear().range([0, w]),
y = d3.scaleLinear().range([0, c]);
var x = d3.scale.linear().range([0, w]),
y = d3.scale.linear().range([0, c]);
root.sort(doSort);
root.sum(function(d) {
if (d.fade) {
return 0;
}
// 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;
}
}
return v;
});
partition(root);
var nodes = partition(data);
var kx = w / (root.x1 - root.x0);
function width(d) { return (d.x1 - d.x0) * kx; }
var kx = w / data.dx;
var g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
var g = d3.select(this).select("svg").selectAll("g").data(nodes);
g.transition()
.duration(transitionDuration)
.ease(transitionEase)
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.depth) - c) + ")"; });
.attr("transform", function(d) { return "translate(" + x(d.x0) + ","
+ (reversed ? y(d.depth) : (h - y(d.depth) - c)) + ")"; });

@@ -234,10 +235,10 @@ g.select("rect").transition()

.ease(transitionEase)
.attr("width", function(d) { return d.dx * kx; });
.attr("width", width);
var node = g.enter()
.append("svg:g")
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.depth) - c) + ")"; });
.attr("transform", function(d) { return "translate(" + x(d.x0) + ","
+ (reversed ? y(d.depth) : (h - y(d.depth) - c)) + ")"; });
node.append("svg:rect")
.attr("width", function(d) { return d.dx * kx; });
node.append("svg:rect").attr("width", width);

@@ -250,11 +251,13 @@ if (!tooltip)

g.attr("width", function(d) { return d.dx * kx; })
// Now we have to re-select to see the new elements (why?).
g = d3.select(this).select("svg").selectAll("g").data(root.descendants());
g.attr("width", width)
.attr("height", function(d) { return c; })
.attr("name", function(d) { return d.name; })
.attr("class", function(d) { return d.fade ? "frame fade" : "frame"; });
.attr("name", function(d) { return d.data.name; })
.attr("class", function(d) { return d.data.fade ? "frame fade" : "frame"; });
g.select("rect")
.attr("height", function(d) { return c; })
.attr("fill", function(d) {return d.highlight ? "#E600E6" : colorHash(d.name); })
.style("visibility", function(d) {return d.dummy ? "hidden" : "visible";});
.attr("fill", function(d) { return colorMapper(d); });

@@ -266,7 +269,7 @@ if (!tooltip)

g.select("foreignObject")
.attr("width", function(d) { return d.dx * kx; })
.attr("width", width)
.attr("height", function(d) { return c; })
.select("div")
.attr("class", "label")
.style("display", function(d) { return (d.dx * kx < 35) || d.dummy ? "none" : "block";})
.style("display", function(d) { return (width(d) < 35) ? "none" : "block";})
.text(name);

@@ -276,16 +279,10 @@

g.exit().remove();
g.on('mouseover', function(d) {
if(!d.dummy) {
if (tooltip) tip.show(d);
setDetails(label(d));
}
if (tooltip) tip.show(d);
setDetails(label(d));
}).on('mouseout', function(d) {
if(!d.dummy) {
if (tooltip) tip.hide(d);
setDetails("");
}
if (tooltip) tip.hide(d);
setDetails("");
});

@@ -295,6 +292,30 @@ });

function merge(data, samples) {
samples.forEach(function (sample) {
var node = _.find(data, function (element) {
return element.name === sample.name;
});
if (node) {
if (node.original) {
node.original += sample.value;
} else {
node.value += sample.value;
}
if (sample.children) {
if (!node.children) {
node.children = [];
}
merge(node.children, sample.children)
}
} else {
data.push(sample);
}
});
}
function chart(s) {
var root = d3.hierarchy(s.datum(), function(d) { return d.c || d.children; });
selection = s.datum(root);
selection = s;
if (!arguments.length) return chart;

@@ -304,26 +325,22 @@

var svg = d3.select(this)
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("class", "partition d3-flame-graph")
.call(tip);
if (!svg) {
svg = d3.select(this)
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("class", "partition d3-flame-graph")
.call(tip);
svg.append("svg:text")
.attr("class", "title")
.attr("text-anchor", "middle")
.attr("y", "25")
.attr("x", w/2)
.attr("fill", "#808080")
.text(title);
svg.append("svg:text")
.attr("class", "title")
.attr("text-anchor", "middle")
.attr("y", "25")
.attr("x", w/2)
.attr("fill", "#808080")
.text(title);
}
});
augment(data);
// "creative" fix for node ordering when partition is called for the first time
partition(data);
// first draw
update();
});
// first draw
update();
}

@@ -382,13 +399,21 @@

chart.reversed = function (_) {
if (!arguments.length) { return reversed; }
reversed = _;
return chart;
};
chart.label = function(_) {
if (!arguments.length) { return labelFormat; }
labelFormat = _;
if (!arguments.length) { return label; }
label = _;
return chart;
}
};
chart.search = function(term) {
var searchResults = [];
selection.each(function(data) {
searchTree(data, term);
searchResults = searchTree(data, term);
update();
});
return searchResults;
};

@@ -403,4 +428,36 @@

chart.zoomTo = function(d) {
zoom(d);
};
chart.resetZoom = function() {
selection.each(function (data) {
zoom(data); // zoom to root
});
};
chart.onClick = function(_) {
if (!arguments.length) {
return clickHandler;
}
clickHandler = _;
return chart;
};
chart.merge = function(samples) {
var newRoot; // Need to re-create hierarchy after data changes.
selection.each(function (root) {
merge([root.data], [samples]);
newRoot = d3.hierarchy(root.data, function(d) { return d.c || d.children; });
});
selection = selection.datum(newRoot);
update();
}
chart.color = function(_) {
if (!arguments.length) { return colorMapper; }
colorMapper = _;
return chart;
};
return chart;

@@ -407,0 +464,0 @@ }

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