A D3.js plugin that produces flame graphs from hierarchical data.

Overview

d3-flame-graph

A D3.js plugin that produces flame graphs from hierarchical data.

Flame Graph Example

If you don't know what flame graphs are, check Brendan Gregg's post.

Flame graphs are a visualization of profiled software, allowing the most frequent code-paths to be identified quickly and accurately. They can be generated using my open source programs on github.com/brendangregg/FlameGraph, which create interactive SVGs.

Brendan Gregg

Examples

Click here to check the demo, and source.

Click here to check the animated assembly demo, and source

Click here to check the simplified demo on bl.ocks.org.

Getting Started

jsdelivr CDN

Just reference the CDN hosted CSS and JS files!

">
<head>
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-flamegraph.css">
head>
<body>
  <div id="chart">div>
  <script type="text/javascript" src="https://d3js.org/d3.v7.js">script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-flamegraph.min.js">script>
  <script type="text/javascript">
  var chart = flamegraph()
    .width(960);

  d3.json("data.json", function(error, data) {
    if (error) return console.warn(error);
    d3.select("#chart")
      .datum(data)
      .call(chart);
  });
  script>
body>

NPM

Make sure Node and npm installed on your system.

Install the d3-flame-graph plugin.

$ npm install d3-flame-graph --save

And use it!

">
<head>
  <link rel="stylesheet" type="text/css" href="node_modules/d3-flame-graph/dist/d3-flamegraph.css">
head>
<body>
  <div id="chart">div>
  <script type="text/javascript" src="node_modules/d3/d3.js">script>
  <script type="text/javascript" src="node_modules/d3-flame-graph/dist/d3-flamegraph.js">script>
  <script type="text/javascript">
  var chart = flamegraph()
    .width(960);
  
  d3.json("data.json")
    .then((data) => {
      d3.select("#chart")
        .datum(data)
        .call(chart);
    })
    .catch(error => {
      return console.warn(error);
    });
  script>
body>

More detailed examples in the /examples directory.

Input Format

Input stack is a simple hierarchical data structure in JSON format.

", "value": , "children": [ ] } ">
{
  "name": "
     
      "
     ,
  "value": <value>,
  "children": [
    <Object>
  ]
}

The burn CLI tool can convert multiple file formats to this hierarchical data structure.

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:

, "parent": , "children": [ ], "x1": , // x2 - x1 is the size of this node, as a fraction of the root. "x2": } ">
{
  "data": 
          
           ,
  "parent": 
           
            ,
  "children": [
    
            
             
  ],
  "x1": 
             
              ,  // x2 - x1 is the size of this node, as a fraction of the root.
  "x2": 
              
                } 
              
             
            
           
          

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.

API Reference

# flamegraph()

Create a new Flame Graph.

# flamegraph.selfValue([enabled])

Defines if the plugin should use the self value logic to calculate the node value for the Flame Graph frame size. If set to true, it will assume the node value from the input callgraph represents only the internal node value, or self value, not the sum of all children. If set to false it will assume the value includes the chidren values too. Defaults to false if not explicitely set, which if the same behavior 1.x had.

# flamegraph.width([size])

Graph width in px. Defaults to 960px if not set. If size is specified, it will set the graph width, otherwise it will return the current graph width.

# flamegraph.height([size])

Graph height in px. Defaults to the number of cell rows times cellHeight if not set. If size is specified, it will set the cell height, otherwise it will return the current graph height. If minHeight is specified, and higher than the provided or calculated values, it will override height.

# flamegraph.minHeight([size])

Minumum graph height in px. If size is specified, and higher than the provided or calculated height, it will override it.

# flamegraph.cellHeight([size])

Cell height in px. Defaults to 18px if not set. If size is specified, it will set the cell height, otherwise it will return the current cell height.

# flamegraph.minFrameSize([size])

Minimum size of a frame, in px, to be displayed in the flame graph. Defaults to 0px if not set. If size is specified, it will set the minimum frame size, otherwise it will return the current minimum frame size.

# flamegraph.title([title])

Title displayed on top of graph. Defaults to empty if not set. If title is specified, it will set the title displayed on the graph, otherwise it will return the current title.

# flamegraph.tooltip([function])

Sets a tooltip for the flamegraph frames. The tooltip function should implement two methods, .show(d) and .hide(), that will be called when the tooltip should be made visible or hidden respectively. The .show method takes a single argument, which is the flamegraph frame. The d3-flame-graph package includes a simple tooltip function, flamegraph.tooltip.defaultFlamegraphTooltip().

">
<script type="text/javascript" src="d3-flamegraph-tooltip.js">script>
var tip = flamegraph.tooltip.defaultFlamegraphTooltip()
    .html(function(d) { return "name: " + d.data.name + ", value: " + d.data.value; });
flamegraph.tooltip(tip)

The tooltip is compatible with d3-tip. This was the default library until version 2.1.10.

">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js">script>
var tip = d3.tip()
  .attr('class', 'd3-flame-graph-tip')
  .html(function(d) { return "name: " + d.data.name + ", value: " + d.data.value; });
flamegraph.tooltip(tip)

# flamegraph.transitionDuration([duration])

Specifies transition duration in milliseconds. The default duration is 750ms. If duration is not specified, returns the current transition duration.

See d3.duration.

# flamegraph.transitionEase([ease])

Specifies the transition easing function. The default easing function is d3.easeCubic.

See d3-ease.

# flamegraph.label([function])

Adds a function that returns a formatted label. Example:

flamegraph.label(function(d) {
    return "name: " + d.name + ", value: " + d.value;
});

# flamegraph.sort([enabled])

Enables/disables sorting of children frames. Defaults to true 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 current sort configuration.

# flamegraph.inverted([bool])

Invert the flame graph direction. A top-down visualization of the flame graph, also known as icicle plot. Defaults to false if not set. If a value is specified, it will enable/disable the inverted flame graphs direction, otherwise it will return the current inverted configuration.

# flamegraph.computeDelta([bool])

If enabled, computes delta for all nodes. Delta value of each node is a sum of its own value from the getDelta(node) function, plus its children. Defaults to false if not set. If a value is specified, it will enable/disable the delta computation, otherwise it will return the current computeDelta configuration.

# flamegraph.resetZoom()

Resets the zoom so that everything is visible.

# flamegraph.onClick([function])

Adds a function that will be called when the user clicks on a frame. Example:

flamegraph.onClick(function (d) {
    console.info("You clicked on frame "+ d.data.name);
});

If called with no arguments, onClick will return the click handler.

# flamegraph.onHover([function])

Adds a function that will be called when the user hovers on a frame. Example:

flamegraph.onHover(function (d) {
    console.info("You hovered over frame "+ d.data.name);
});

If called with no arguments, onHover will return the hover handler.

# flamegraph.setDetailsElement([element])

Sets the element that should be updated with the focused sample details text. Example:

">
<div id="details">
div>
flamegraph.setDetailsElement(document.getElementById("details"));

If called with no arguments, setDetailsElement will return the current details element.

# flamegraph.setDetailsHandler([function])

Sets the handler function that is called when the details element needs to be updated. The function receives a single paramenter, the details text to be set. Example:

let detailsHandler = function (d) { if (detailsElement) { if (d) { detailsElement.innerHTML = d } else { if (typeof searchDetails === 'function') { searchDetails() } else { detailsElement.innerHTML = '' } } } }

flamegraph.setDetailsHandler(
  function (d) {
    if (detailsElement) {
        if (d) {
            detailsElement.innerHTML = d
        } else {
            detailsElement.innerHTML = ''
        }
    }
  }
);

If not set, setDetailsHandler will default to the above function.

If called with no arguments, setDetailsHandler will reset the details handler function.

# flamegraph.setSearchHandler([function])

Sets the handler function that is called when search results are returned. The function receives a three paramenters, the search results array, the search sample sum, and root value, Example:

let searchHandler = function (searchResults, searchSum, totalValue) { searchDetails = () => { if (detailsElement) { detailsElement.innerHTML = 'search: ' + searchSum + ' of ' + totalValue + ' total samples ( ' + format('.3f')(100 * (searchSum / totalValue), 3) + '%)' } } searchDetails() }

flamegraph.setSearchHandler(
  (searchResults, searchSum, totalValue) => {
    searchDetails = () => { // searchDetails is a global variable
        if (detailsElement) {
            detailsElement.innerHTML = 'search: ' + searchSum + ' of ' + totalValue + ' total samples ( ' + format('.3f')(100 * (searchSum / totalValue), 3) + '%)'
        }
    }
    searchDetails()
  }
);

If not set, setSearchHandler will default to the above function.

If called with no arguments, setSearchHandler will reset the search handler function.

# flamegraph.setColorMapper([function])

Replaces the built-in node color hash function. Function takes two arguments, the node data structure and the original color string for that node. It must return a color string. Example:

// Purple if highlighted, otherwise the original color
flamegraph.setColorMapper(function(d, originalColor) {
    return d.highlight ? "#E600E6" : originalColor;
});

If called with no arguments, setColorMapper will reset the color hash function.

# flamegraph.setColorHue([string])

Sets the flame graph color hue. Options are warm, cold, red, orange, yellow, green and aqua.

If called with no arguments, setColorHue will reset the color hash function.

# flamegraph.setSearchMatch([function])

Replaces the built-in node search match function. Function takes three arguments, the node data structure, the search term and an optional boolean argument to ignore case during search. If the third argument is not provided, the search will be case-sensitive by default. The function must return a boolean. Example:

flamegraph.setSearchMatch(function(d, term, true) {
  // Non-regex implementation of the search function
  return d.data.name.indexOf(term) != 0;
})

If called with no arguments, setSearchMatch will return reset the search match function.

# flamegraph.merge(date)

Merges the current data with the given data.

# flamegraph.update([data])

Updates the current chart. If the data parameters is passed, replaces the current data.

# flamegraph.destroy()

Removes the flamegraph.

All API functions will return the flame graph object if no other behavior is specified in the function details.

Issues

For bugs, questions and discussions please use the GitHub Issues.

Contributing

We love contributions! But in order to avoid total chaos, we have a few guidelines.

If you found a bug, have questions or feature requests, don't hesitate to open an issue.

If you're working on an issue, please comment on it so we can assign you to it.

If you have code to submit, follow the general pull request format. Fork the repo, make your changes, and submit a pull request.

Build

This plugin uses Webpack as build system. It includes a development server with live refresh on any changes. To start it, just execute the serve npm script.

$ git clone https://github.com/spiermar/d3-flame-graph.git
$ cd d3-flame-graph
$ npm install
$ npm run serve

Template

A standalone template with all JavaScript and CSS inlined gets built at dist/templates/d3-flamegraph-base.html. It contains a placeholder /** @flamegraph_params **/ which needs to be replaced with the stacks in the format described in Input Format.

License

Copyright 2018 Martin Spier. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Owner
Martin Spier
Performance Engineer @snowflakedb. Ex-Netflix. Venture Advisor. Investor. Adventurer.
Martin Spier
Python+Numpy+OpenGL: fast, scalable and beautiful scientific visualization

Python+Numpy+OpenGL: fast, scalable and beautiful scientific visualization

Glumpy 1.1k Jan 05, 2023
The open-source tool for building high-quality datasets and computer vision models

The open-source tool for building high-quality datasets and computer vision models. Website • Docs • Try it Now • Tutorials • Examples • Blog • Commun

Voxel51 2.4k Jan 07, 2023
AB-test-analyzer - Python class to perform AB test analysis

AB-test-analyzer Python class to perform AB test analysis Overview This repo con

13 Jul 16, 2022
EPViz is a tool to aid researchers in developing, validating, and reporting their predictive modeling outputs.

EPViz (EEG Prediction Visualizer) EPViz is a tool to aid researchers in developing, validating, and reporting their predictive modeling outputs. A lig

Jeff 2 Oct 19, 2022
A Python Library for Self Organizing Map (SOM)

SOMPY A Python Library for Self Organizing Map (SOM) As much as possible, the structure of SOM is similar to somtoolbox in Matlab. It has the followin

Vahid Moosavi 497 Dec 29, 2022
A guide for using Bootstrap 5 classes in Dash Bootstrap Components V1

dash-bootstrap-cheatsheet This handy interactive cheatsheet makes it easy to use the Bootstrap 5 classes with your Dash app made with the latest versi

10 Dec 22, 2022
FURY - A software library for scientific visualization in Python

Free Unified Rendering in Python A software library for scientific visualization in Python. General Information • Key Features • Installation • How to

169 Dec 21, 2022
PolytopeSampler is a Matlab implementation of constrained Riemannian Hamiltonian Monte Carlo for sampling from high dimensional disributions on polytopes

PolytopeSampler PolytopeSampler is a Matlab implementation of constrained Riemannian Hamiltonian Monte Carlo for sampling from high dimensional disrib

9 Sep 26, 2022
PyFlow is a general purpose visual scripting framework for python

PyFlow is a general purpose visual scripting framework for python. State Base structure of program implemented, such things as packages disco

1.8k Jan 07, 2023
A simple script that displays pixel-based animation on GitHub Activity

GitHub Activity Animator This project contains a simple Javascript snippet that produces an animation on your GitHub activity tracker. The project als

16 Nov 15, 2021
The windML framework provides an easy-to-use access to wind data sources within the Python world, building upon numpy, scipy, sklearn, and matplotlib. Renewable Wind Energy, Forecasting, Prediction

windml Build status : The importance of wind in smart grids with a large number of renewable energy resources is increasing. With the growing infrastr

Computational Intelligence Group 125 Dec 24, 2022
LinkedIn connections analyzer

LinkedIn Connections Analyzer 🔗 https://linkedin-analzyer.herokuapp.com Hey hey 👋 , welcome to my LinkedIn connections analyzer. I recently found ou

Okkar Min 5 Sep 13, 2022
View part of your screen in grayscale or simulated color vision deficiency.

monolens View part of your screen in grayscale or filtered to simulate color vision deficiency. Watch the demo on YouTube. Install with pip install mo

Hans Dembinski 31 Oct 11, 2022
Generate SVG (dark/light) images visualizing (private/public) GitHub repo statistics for profile/website.

Generate daily updated visualizations of GitHub user and repository statistics from the GitHub API using GitHub Actions for any combination of private and public repositories, whether owned or contri

Adam Ross 2 Dec 16, 2022
HM02: Visualizing Interesting Datasets

HM02: Visualizing Interesting Datasets This is a homework assignment for CSCI 40 class at Claremont McKenna College. Go to the project page to learn m

Qiaoling Chen 11 Oct 26, 2021
Data Visualizations for the #30DayChartChallenge

The #30DayChartChallenge This repository contains all the charts made for the #30DayChartChallenge during the month of April. This project aims to exp

Isaac Arroyo 7 Sep 20, 2022
Graphing communities on Twitch.tv in a visually intuitive way

VisualizingTwitchCommunities This project maps communities of streamers on Twitch.tv based on shared viewership. The data is collected from the Twitch

Kiran Gershenfeld 312 Jan 07, 2023
Displaying plot of death rates from past years in Poland. Data source from these years is in readme

Average-Death-Rate Displaying plot of death rates from past years in Poland The goal collect the data from a CSV file count the ADR (Average Death Rat

Oliwier Szymański 0 Sep 12, 2021
Graphical display tools, to help students debug their class implementations in the Carcassonne family of projects

carcassonne_tools Graphical display tools, to help students debug their class implementations in the Carcassonne family of projects NOTE NOTE NOTE The

1 Nov 08, 2021
Use Perspective to create the chart for the trader’s dashboard

Task Overview | Installation Instructions | Link to Module 3 Introduction Experience Technology at JP Morgan Chase Try out what real work is like in t

Abdulazeez Jimoh 1 Jan 22, 2022