erikbrinkman / d3-dag Goto Github PK
View Code? Open in Web Editor NEWLayout algorithms for visualizing directed acyclic graphs
Home Page: https://erikbrinkman.github.io/d3-dag/
License: MIT License
Layout algorithms for visualizing directed acyclic graphs
Home Page: https://erikbrinkman.github.io/d3-dag/
License: MIT License
ERROR in ./node_modules/d3-dag/src/index.ts
Module build failed (from ./node_modules/@ngtools/webpack/src/index.js):
Error: /home/projects/ETL/newdrawnode/node_modules/d3-dag/src/index.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
The missing file seems to be part of a third party library. TS files in published libraries are often a sign of a badly packaged library. Please open an issue in the library repository to alert its author and ask them to package the library using the Angular Package Format (https://goo.gl/jB3GVv).
at AngularCompilerPlugin.getCompiledFile (/home/projects/ETL/newdrawnode/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:949:23)
at plugin.done.then (/home/projects/ETL/newdrawnode/node_modules/@ngtools/webpack/src/loader.js:43:31)
at process._tickCallback (internal/process/next_tick.js:68:7)
Tried this in tsconfig.ts, still the same error
"files": ["/home/projects/ETL/newdrawnode/node_modules/d3-dag/src/index.ts"]
Any idea on how to resolve this?
Hi, I am using your lib in a website built by Webpack. However the latest functional version is 0.4.1 on a specific commit hash. Otherwise the webpack build fails on Module not found: Error: Can't resolve 'child_process'
and Module not found: Error: Can't resolve 'fs'
. Should I try to fix it and send a Pull request or should I just fork the repo and maintain my paralel version of this project?
Hi! Is it possible to attach metadata to nodes and links?
Something like
{
"id": 1,
"data": {
"name": "john",
"age": 28
},
"children": [
{
"linkData": {
"text": "marriage"
},
"node": {
"id": 2,
"data": {
"name": "jane",
"age": 32
}
}
},
{
"linkData": {
"text": "son"
},
"node": {
"id": 3,
"data": {
"name": "jack",
"age": 3
}
}
}
]
}
or analogous for stratify?
I sometimes have graphs that only have one node, or only unrelated, disconnected nodes. How do I display these with the dagConnect
reader?
If this is not possible, can I do it with dagStratify
?
javascript-lp-solver
over 0.4.5
add External
module which requires node internal fs
and child_process
leads to the compilation error of webpack
projects
Does d3-dag have any in-built functionality to be able to minimize/collapse subgraphs?
I saw this demo of collapsible trees on d3: https://observablehq.com/@d3/collapsible-tree
Is it possible to do something like this with d3-dag?
Also, can you use a dom node as a graph node? Say I build an elaborate HTML node with input elements and few images, can I use this dom node as my graph node?
Here is a minimal repro. I can reproduce this on a recent model of MacBook Pro in both Safari and Chrome:
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Crash browser tab on Mac Chrome with D3 Dag</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/[email protected]"></script>
<script>
let sourceData2 = []
// creating a lesser amount of nodes will no longer crash
for (i = 0; i < 100; i++) {
sourceData2.push({"id":`${i}`, parentIds:[]});
}
for (i = 0; i < 100; i++) {
sourceData2.push({"id":`${i+100}`, parentIds:[`${i}`]});
}
layout = d3
.sugiyama()
.decross(
d3
.decrossTwoLayer()
.order(
// changing twolayerOpt to twolayerMedian will no longer crash
//d3.twolayerMedian()
d3.twolayerOpt()
)
)
var result = layout(d3.dagStratify()(sourceData2))
console.log(result)
</script>
</head>
<body>
</body>
</html>
The doc of node.count() in the readme says:
Set the value of each node to be the number of descendants including itself.
However, it looks to me, from the behaviour and the code, that it counts the number of leaves among the descendants of the node.
Hi,
This library is great. Are there any plans to release Typescript types for d3-dag?
Thanks.
Hi @erikbrinkman,
Thank you for this library!
I'm trying to build components based on it for nivo, however I had an error during build phase, javascript-lp-solver
cannot be resolved as it's not defined as a dependency but as a dev dependency.
Hi @erikbrinkman!
A user filed a bug in js_family_tree, which uses d3-dag for display. After digging down, I realized that in his particular case, the dag does not return the correct number of descendants. I prepared a minimum working example, which reproduces the bug:
<!DOCTYPE html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3-dag.min.js"></script>
<script>
links = [
["id1", "id3"],
// ["id2", "id3"],
["id3", "id4"],
]
dag = d3.dagConnect()(links);
nodes = dag.descendants();
root = nodes.find(n => n.id == "id3");
dag.children = [root];
children_of_root = dag.descendants(); // expected: id3, id4, returned: id1, id3, id4
</script>
</body>
</html>
Interestingly, the error does not occur, if id3
has another parent (you can test this by uncommenting the link).
I know it seems a bit weird to use dag.descendants
here instead of root.descendants
but that's because it is a minimum example. In the working code, have to get the descendants of the whole dag because I am expecting multiple root nodes.
Cheers,
Ben
Hey, thanks for creating this awesome repository
The immediate thing, which I noticed, was lack of online examples, which user could play with.
So, I recreated repository examples and ported them into ObservableHQ, where all users can play with the notebooks, change things ...
https://beta.observablehq.com/collection/@bumbeishvili/d3-dag
I get
Error: matrix D in quadratic function is not positive definite!
Hi!
Running into an issue where I have a dynamic DAG structure that may be technically two independent trees.
The verify
step that tests that a DAG is connected throws an error currently and so doesn't allow rendering to finish. However, removing the throw allows the rendering to continue and I end up with two (or more) really nice, independent trees.
Is there a reason the library should be throwing an error there? Could there perhaps be a console.warn
instead, in case of potential overlap issues?
I was just trying to implement dag
graphs in my project with dagre
and at the moment,
realized that it isn't maintained anymore and concerned with using it in my project.
This currently wraps dagre, but I'd prefer to reimplement a DAG layout to not require it as a dependency, and to allow more options about the different phases of DAG layout. This would be a good place to start. Ideally each phase will just be a callback, similar to the way other d3 layouts are done.
And really thrilled it'll be reimplemented without darge
project.
Looking forward to heavily using in my project!
Cheers! ๐
I'm having a non-fixed size graph, so I need to compute its width given the dag-layout. To do so I'd need to know how many dummy nodes there are in a given line. Could you consider adding this feature ?
as dag is generated using sugiyama how are we going to render it in HTML?
Do you plan to add support for nodes clustering ?
Currently you only provide an UMD build, you could also consider providing an ES module build.
not sure why. arq.columnWidth(() => 100);
returns the same as arq.columnWidth(() => 1);
.
Hi,
I am using your library in an angular project and the eslint comma dangle rule is causing issues with the angular build.
The following issue is
ERROR in main.81d528981f082d6185f9.js from Terser
Unexpected token: punc ()) [main.81d528981f082d6185f9.js:188447,4]
One of the places the issue is found is in src/sugiyama/coord/center.js line 12
I have a commit that applies this rule across the code base. Would you allow me to become a contributor so that I can push my changes to a branch
Regards
Matthew
Hey, just wanted to say, thank you. i wanted this years ago and never got around to making it. thanks!
Hello,
the following classes are not exported: LayoutDagRoot, LayoutDagNode, LayoutChildLink.
I tryed to import theses classe, and use them directly to build with custom code the DAG graph.
import { LayoutDagRoot, LayoutDagNode, LayoutChildLink } from 'd3-dag'; /// does not compile!!
import { LayoutDagRoot, LayoutDagNode, LayoutChildLink } from 'd3-dag/dist/dag/node'; // compile in IDE, but does not work at runtime !!
..
let fooObjs: Fooj[] = ... with child dependencies to bars
let barObjs: Fooj[] = ... with child dependencies to some baz, and parent dependencies from some baz (typically, read/write relation between data and process)
let bazObjs: Fooj[] = ... other dependencies ...
// create node objects
let dagNodeMap = new Map<string,LayoutDagNode>();
fooObjs.forEach(obj => {
let fooId = 'foo:' + obj.id;
let nodeData = { type:'foo', foo };
dagNodeMap.set(fooId, new LayoutDagNode(fooId, nodeData));
});
barObjs.forEach(barObj => ... similar create LayoutDagNode ..
bazObjs.forEach(bazObj => ... similar create LayoutDagNode ..
// create child dependency links between objects..
// dependency between foo-[dep1]->bar(s)
fooObjs.forEach(fooObj => {
let fooNode = dagNodeMap.get('foo:' + fooObj.id);
fooObj.dep1Bars.forEach(barObj => {
let childBarNode = dagNodeMap.get('bar:' + barObj.id);
let linkData = { linkType:'foo_dep1_bar' };
fooNode.dataChildren.push( new LayoutChildLink(barObj, linkData));
});
// dependency between bar-[dep2]->foo(s)
fooObj.dep2Bars.forEach(barObj => {
let = dagNodeMap.get('bar:' + barObj.id);
let linkData = { linkType:'bar_dep2_foo' };
parentBarNode.dataChildren.push( new LayoutChildLink(fooNode, linkData));
});
// other dendencies between foo,bar,baz...
});
Maybe I could use directly some other graph builder operator?
I did not understand the doc, and what is effectively exported/private from the doc
Thanks for your answer, or fix
Hi. First of all, thanks for this amazing library!
I am wondering if there is a way to define custom x and y position of single node and then calculate all the links? I am looking for a way to mark node/s with custom or predefined position to not be included in calculating of their positions but links should be correctly calculated to them. Is that currently possible? Thanks in advance.
I'm not d3 fluent, I figured I should ask: Is there a way to change the appearance of the nodes/vertex?
I forked the first example:
https://beta.observablehq.com/@bumbeishvili/d3-dag-vert
And just changed the data to my graph with 39 nodes.
https://beta.observablehq.com/@zfrenchee/d3-dag-vert
Which basically freezes -- eats up all my CPU and can't layout the nodes.
There are no cycles in my graph, and I can d3.dratify()(graph)
without a problem. Why does the layout struggle so much with my graph?
Here's the graph for reference:
[{"id":"GO:0005575"},
{"id":"GO:1903561","parentIds":["GO:0031982","GO:0043230"]},
{"id":"GO:0005737","parentIds":["GO:0044424"]},
{"id":"GO:0030666","parentIds":["GO:0030139","GO:0030659","GO:0098588","GO:0098805"]},
{"id":"GO:0043230","parentIds":["GO:0043226","GO:0044421"]},
{"id":"GO:0005623","parentIds":["GO:0005575"]},
{"id":"GO:0005938","parentIds":["GO:0071944","GO:0099568"]},
{"id":"GO:0031982","parentIds":["GO:0043227"]},
{"id":"GO:0099568","parentIds":["GO:0005737","GO:0044444"]},
{"id":"GO:0097708","parentIds":["GO:0031982","GO:0043229"]},
{"id":"GO:0005622","parentIds":["GO:0044464"]},
{"id":"GO:0016020","parentIds":["GO:0005575"]},
{"id":"GO:0043226","parentIds":["GO:0005575"]},
{"id":"GO:0030055","parentIds":["GO:0030054"]},
{"id":"GO:0005576","parentIds":["GO:0005575"]},
{"id":"GO:0030054","parentIds":["GO:0005575"]},
{"id":"GO:0031410","parentIds":["GO:0044444","GO:0097708"]},
{"id":"GO:0031090","parentIds":["GO:0016020","GO:0043227","GO:0044422"]},
{"id":"GO:0030139","parentIds":["GO:0031410"]},
{"id":"GO:0070062","parentIds":["GO:0005615","GO:1903561"]},
{"id":"GO:0044464","parentIds":["GO:0005575","GO:0005623"]},
{"id":"GO:0005925","parentIds":["GO:0005924"]},
{"id":"GO:0044444","parentIds":["GO:0005737","GO:0044424"]},
{"id":"GO:0044421","parentIds":["GO:0005575","GO:0005576"]},
{"id":"GO:0012506","parentIds":["GO:0031090","GO:0031982"]},
{"id":"GO:0098805","parentIds":["GO:0016020"]},
{"id":"GO:0005615","parentIds":["GO:0044421"]},
{"id":"GO:0098588","parentIds":["GO:0031090"]},
{"id":"GO:0044433","parentIds":["GO:0031410","GO:0044444","GO:0044446"]},
{"id":"GO:0043227","parentIds":["GO:0043226"]},
{"id":"GO:0005912","parentIds":["GO:0070161"]},
{"id":"GO:0044422","parentIds":["GO:0005575","GO:0043226"]},
{"id":"GO:0070161","parentIds":["GO:0030054"]},
{"id":"GO:0030659","parentIds":["GO:0012506","GO:0044433"]},
{"id":"GO:0043229","parentIds":["GO:0043226","GO:0044424"]},
{"id":"GO:0044424","parentIds":["GO:0005622","GO:0044464"]},
{"id":"GO:0044446","parentIds":["GO:0043229","GO:0044422","GO:0044424"]},
{"id":"GO:0071944","parentIds":["GO:0044464"]},
{"id":"GO:0005924","parentIds":["GO:0005912","GO:0030055"]}
];
Adding this issue as I can (seemingly) cause infinite layout cycle in d3-dag using the following test data and configuration:
const layout = d3.sugiyama()
.layering(d3.layeringSimplex())
.decross(d3.decrossOpt())
.coord(d3.coordVert())
.nodeSize((node) => {
return [130, 130];
})
I plan on attempting to debug further but thought, if nothing else, it might be useful to have the data for a future test. While I cannot confirm that this isn't some awful mistake on my part (made worse by the fact that this makes chrome go to the bad place really fast so it's hard to test), I did confirm that the data is not infinitely recursive and is render-able through other DAG renders (e.g. dagitty)
Will post more here if I determine a root cause (including if it is me)
Hi, I updated to v0.2.3
and noticed that the arrow calculation stopped working.
I updated the online example to make it run:
grafo.json
from examples folderdagStratify
instead of dratify
However the arrow are always placed at the top left corner.
I suspect that the position calculation is somehow changed as links
are now provided at creation time.
Can you please update the example to make it actually work as with v0.1.x
?
Thanks a lot!
I get "Error: no roots" when I run dagConnect on an array of edges. The edges are JS objects with an id, source and target nodes. I am using accessors to get the ids of the nodes. Upon debugging, it seems to happen when dagConnect calls dagStratify.
The dag I'm building has 3 nodes and 2 edges and looks like this:
(node) (node)
\ /
(node)
The array of edges (edgeData) looks something like this in debug:
0: { id: 1572447089979, sourceNode: {id: 1572447087123, โฆ}, targetNode: {id: 1572447087506, ...}}
1: { id: 1572447090797, sourceNode: {id: 1572447087331, โฆ}, targetNode: {id: 1572447087506, ...}}
My call looks like this:
let dag = d3.dagConnect().sourceAccessor((e) => e.id).targetAccessor((e) => e.id)(edgeData);
Not sure if this is a bug or if I am doing something wrong? Am I supposed to pass in a pseudo-edge from the root nodes to an 'undefined' node?
Nuxt @ v2.15.7
EROR in ./node_modules/d3-dag/bundle/d3-dag.esm.min.js friendly-errors 13:21:07
Module parse failed: Unexpected character '#' (14:9934)
The links of a DAG have directions.
Are there any options in d3-dag
to display arrows in link header or body, to show directions?
@erikbrinkman d3-dag
is a great project and I would love to contribute this part if not supported yet :)
Thanks for the package. It looks nice.
Do you have the code for the examples (like https://observablehq.com/@erikbrinkman/d3-dag-sugiyama) so that I can try to create and render them myself? The only example I have found is https://github.com/ArquintL/d3-dag-example but it seems to be out of date and I can't get it to work.
Adding a minimal reproducible example somewhere would be nice. Would you consider doing so?
I know this is trivial, however the work 'acyclic' is spelled 'acylic' in the projects description
Hi ! Very impressive library, thanks for sharing it !
I was wondering whether there is a way to specify the rank of a node. Sometimes, you want to constraint your graph so that certain nodes are laid out on the same level.
Thanks a lot !
Hi,
Is there a tutorial/reference for how to use this library in Javascript? I poked around on Observable HQ and put together this little script. However, when I run it on the browser, I get an error.
function run()
{
var data = [
{
"id": "0",
"parentIds": []
},
{
"id": "1",
"parentIds": ["0"]
},
{
"id": "2",
"parentIds": ["0"]
},
{
"id": "3",
"parentIds": ["1", "2"]
},
{
"id": "4",
"parentIds": ["0"]
},
{
"id": "5",
"parentIds": ["4"]
}
];
var layout = d3.sugiyama()
.size([400, 400])
.layering(d3.layeringSimplex())
.decross(d3.decrossOpt())
.coord(d3.coordCenter());
layout(d3.dagConnect(data));
}
The error:
d3-dag.min.js:16 Uncaught Error: got arguments to dagConnect([object Object],[object Object],[object Object],[object Object],[object Object],[object Object]), but constructor takes no aruguments. These were probably meant as data which should be called as dagConnect()(...)
at Object.t.dagConnect (d3-dag.min.js:16)
at run (dag.js:36)
Thanks
Wow, Interesting project!
on the initial readme...
I need to draw a dynamic DAG. I have to use sugiyama layout first, so while nodes increases, the space become tight. So is there a nodeSize API like d3 that could solve this problem
Hello there.
Would you consider adding a vertical zherebko render method? My use-case involves a topological sort and a >100 node graph.
It's great that zherebko renders them sorted, but I feel it would be a pain to horizontal scroll through everything.
Thanks for rewriting d3-dag in typescript! I'm starting to use your lib & it looks very promising!
It would be helpful to publish types, so users of the lib can get ide support.
Here is a guide: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
Thank you :)
The current method of setting a size or nodeSize and separation while trying to mimic d3-hierarchy doesn't seem to be doing a good job for users who know roughly the sizes of nodes they want to layout.
The proposal is this:
Instead of supplying a separation, dag size or nodeSize, users can specify a node width and height accessor (or nodeSize accessor) and a dagSize. The node with accessor will be used in place of the separation accessor and will return left.width + right.width / 2
thus enforcing this constraint. For height, we'll find the maximum height of each layer, and similarly set the spacing between heights to be bottom.height + top.height / 2
. If an optional dag size is specified than the coordinates will be rescaled to fit within the specified size, centering if all coordinates are 0. (special care might need to be taken for graphs that are disconnected across layers as you'll get some really strange layouts, although handling that is not a top priority as reasonable layerings won't produce that). The node height accessor can default to 1 for every node. The node width accessor will default to 1 for normal nodes and 0 for dummy nodes, thus keeping in line with the new default separation function.
I believe this will make it easier for people who have dags with known sizes to set appropriate layouts. It should also make it fairly reasonable to take nodes that are attached to dom objects to measure the objects in advance and then set node sizes accordingly.
App is unable to compile when using d3-dag version 0.8.1 with Create React App.
This can be replicated by
Attached example project
my-app.zip
Hi Erik,
I'm trying to figure out how to get constant spacing between neighboring nodes. When I have two nodes, they are positioned such that one is on the far left and the other is one the far right. As I add more nodes, the they move closer and closer together. At some point, they overlap. I want to prevent this. I would like to have the spacing independent of the number of nodes in a layer. I'd rather have the nodes move out of the screen when there are too many (it's not a problem because I have panning activated).
I'm using sugiyama layout like this:
var tree = d3.sugiyama()
.size([height, width])
.layering(d3.layeringSimplex())
.decross(d3.decrossTwoLayer())
.coord(d3.coordVert())
.separation( (a, b) => { return 1 } );
`
I figured out that I can get constant separation between layers by setting
nodes.forEach(d => d.x = d.depth().layer * 140);
Is there something similar for the y-position?
Best regards
Ben
I'm having trouble preventing node overlap on complex graphs and I'm not sure what the best avenue to correct it is.
I am generating DAGs and using the layout's layers + nodes per layer to dynamically compute width and height based on node size and a separation value. This works well with smaller graphs but as complexity increases my nodes don't seem to be utilizing space well:
There's more than enough space to separate those tightly packed clusters of nodes but I'm not having much luck figuring out how to do it well over a variety of graph complexities.
Should I explore the coord accessors or is this something that the separation function takes care of? How do I specify that the separation between nodes should be at least the node width + a separation value that I specify?
These layouts are being generated by the react hook below:
import { useMemo, useEffect, useState } from 'react';
import * as d3dag from 'd3-dag';
import { groupBy, map } from 'lodash';
const dagStratify = d3dag.dagStratify();
export default function useSugiyamaDag<DT>(
data: NodeDef<DT>[],
{
nodeWidth,
nodeHeight,
nodeSeparationX,
nodeSeparationY,
}: {
nodeWidth: number;
nodeHeight: number;
nodeSeparationX: number;
nodeSeparationY: number;
}
): UseSugiyamaDagOut<DT> {
// Start with width and height of 0. This gets overwritten below
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
// Re-stratify data + remake layout fn whenever changes are detected
const dag = useMemo(() => dagStratify(data), [data]);
const layout = useMemo(() => {
console.warn('(Re)creating DAG layout function');
return (
d3dag
.sugiyama()
// .debug(true)
.size([width, height])
// .layering(d3dag.layeringLongestPath())
// .coord(d3dag.coordCenter())
// not sure if this is working
.separation((_a: {}, _b: {}) => nodeWidth + nodeSeparationX)
);
}, [width, height, nodeWidth, nodeSeparationX]);
// Layout the tree
const { tree, descendants, descendantsByLayer } = useMemo<{
tree: UseSugiyamaDagOut<DT>['tree'];
descendants: {}[];
descendantsByLayer: Record<number, {}[]>;
}>(() => {
console.warn('Laying out DAG');
const t = layout(dag);
const d = t.descendants();
const dBL = groupBy(d, n => n.layer);
return { tree: t, descendants: d, descendantsByLayer: dBL };
}, [layout, dag]);
// Calculate and set height and width of the graph dynamically
useEffect(() => {
// Start with width and height of 0. This gets overwritten below once layout has been computed
const newHeight =
Object.keys(descendantsByLayer).length * (nodeHeight + nodeSeparationY);
// Find each layers width (number of nodes per layer * width of each node) and
// set the overall width to the max computed layer width
const newWidth = Math.max(
...map(
descendantsByLayer,
layer => layer.length * (nodeWidth + nodeSeparationX)
)
);
// Set height/width if values don't match
if (height !== newHeight || width !== newWidth) {
setHeight(newHeight);
setWidth(newWidth);
}
}, [
descendants,
descendantsByLayer,
height,
nodeHeight,
nodeSeparationY,
nodeWidth,
width,
nodeSeparationX,
]);
return { height, width, tree, descendants };
}
export interface NodeDef<Data extends {}> {
id: string;
parentIds?: string[];
data: Data;
}
export interface LayoutNodeDef<DT> {
id: string;
layer: number;
x: number;
y: number;
children: LayoutNodeDef<DT>[];
data: NodeDef<DT>;
}
interface UseSugiyamaDagOut<DT> {
height: number;
width: number;
tree: {
links: () => {
source: LayoutNodeDef<DT>;
target: LayoutNodeDef<DT>;
}[];
descendants: () => LayoutNodeDef<DT>[];
};
descendants: {}[];
}
Hi, is it possible to create the DAG with disconnected components but that still meet DAG's requirements? Or it must be a single connected component? (image representation: https://i.stack.imgur.com/CCoZ2.jpg)
If not, I was wondering how would we integrate d3-dag in React?
Hello, thanks so much for the excellent library!
I'm working on using d3-dag to develop a software for the generation of pedigrees, which requires live regeneration of my graph as data is inputted. I'm noticing serious slowdowns of the plotting functions as I add more nodes to the graph. Here is an example of a fairly simple graph that is causing serious slowdowns (around 10 seconds to render):
Any idea what might be causing these performance issues? Below is the performance profile of the above rendering operation if it is at all helpful:
Thanks to a hint in a previous issue from @erikbrinkman, I've tried the following:
function layering(dag) {
// Run layering once so that everything has a level.
layeringSimplex()(dag);
dag.descendants().forEach(node => {
// Give everything a rank, but unions have a rank one less than their level.
node.rank = node.layer;
if (node.data.isUnion) {
node.rank -= 1;
}
});
// Re-run layering to allow ranks to take effect.
layeringSimplex()(dag)
}
let treeFn = sugiyama()
.nodeSize(nodeSize)
.layering(layering)
.decross(decrossOpt())
.coord(coordQuad());
treeFn(dag);
Running this has not altered the layout at all - as if the ranks are invalid and being ignored.
At least using stratify, spaces in the id are unsupported and cause some confusion at the moment.
There may be more than one place but guessing this is part of the culprit
stratify.id = id;
I would be happy to adjust and create a PR but, before I did, I wanted to make sure that this wasn't an intentional issue or something you would prefer left alone.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.