A simple framework for visualizing hierarchical data with interconnected relationships.
https://codepen.io/PhantomV1989/pen/MWJvbrO
https://codepen.io/PhantomV1989/pen/NWdvbMd
https://codepen.io/PhantomV1989/pen/abpyBRP
https://codepen.io/PhantomV1989/pen/rNjzWEq
https://codepen.io/PhantomV1989/pen/jOyLyOZ
Load the following dependencies before loading this script
- d3.v6.min.js
- jquery-3.5.1.slim.min.js eg
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
You may want to setup svg-pan-zoom for a better navigation experience. https://github.com/luncheon/svg-pan-zoom-container
<script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom-container@0.5.0"></script>
The rendering function drawGraphHierarchicalTreemap has 4 arguments, of which 2, both being color functions, are optional.
drawGraphHierarchicalTreemap(
nodes,
links,
rectColoring, // optional
lineColoring // optional
);
Refer to https://raw.githubusercontent.com/PhantomV1989/GraphHierarchicalTreemap/master/demos/minimalExample.html for a running example.
Each node has 3 parameters: n(UNIQUE name), v(value), c(children). Root node MUST always be named "root". v is used by d3's treemap for calculating the node's relative rectangle size.
let data = {
n: "root", // always starts with root node
v: 1, // just set as 1, needed because of d3's sizing algo
c: [
{
n: "a", // child a
v: 1,
c: [{ n: "qwe", v: 1, c: [] }],
},
{
n: "b", //child b
v: 1,
c: [
{ n: "ba", v: 1, c: [] },
{ n: "asd", v: 1, c: [] },
{ n: "qwe", v: 1, c: [] },
],
},
],
};
Links contain directional information of the node data. They are described using key-value pairs, where keys are unique node names (node.n) of source nodes and values are a set of destination node names these sources are linked to.
let links = { // 1 source, qwe to 2 destinations ba and bc
"qwe": new Set(["ba", "bc"]),
};
The above example illustrate the following relationships: qwe ->ba, qwe -> bc
rectColoring defines how rectangles should be colored according to their first ancestor name.
Using the example below, a 'a.b.4.6.2.v' rectangle, would have first ancestor 'a', hence interpolateBlues is used based on the example. 'a.b.4.6.2.v' is 5 levels(from 0), hence the color for the rectangle would be d3.scaleSequential([GraphHierarchicalTreemap.maxDepth, 0], d3.interpolateBlues)(5)
maxDepth is set to 10.
let rectColoring = (firstAncestorName) => {
// ref https://github.com/d3/d3-scale-chromatic/blob/master/README.md
let colors = {
'a': d3.scaleSequential([GraphHierarchicalTreemap.maxDepth, 0], d3.interpolateBlues),
'b': d3.scaleSequential([GraphHierarchicalTreemap.maxDepth, 0], d3.interpolateReds),
};
return colors[firstAncestorName]
}
You can also define coloring function for lines to depict different colors at different layers
let lineColoring = d3.scaleSequential([GraphHierarchicalTreemap.maxDepth, 0], d3.interpolateCool)
- Lines always leave source nodes from the upper sides and join destination nodes from the lower sides
- Currently drawing up to a minimum length of 10 pixels for either side for rectangles
- Maximum depth drawn is 10.