@antv/layout 2.0.0-alpha.3 β 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -23
- package/dist/index.js +11 -14
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/lib/algorithm/circular/index.js +2 -2
- package/lib/algorithm/circular/index.js.map +1 -1
- package/lib/algorithm/combo-combined/index.js +4 -4
- package/lib/algorithm/combo-combined/index.js.map +1 -1
- package/lib/algorithm/d3-force/index.js +3 -9
- package/lib/algorithm/d3-force/index.js.map +1 -1
- package/lib/util/order.d.ts +1 -1
- package/lib/util/order.js +4 -1
- package/lib/util/order.js.map +1 -1
- package/lib/worker.js +8 -11
- package/lib/worker.js.map +1 -1
- package/package.json +5 -3
- package/src/algorithm/circular/index.ts +2 -2
- package/src/algorithm/combo-combined/index.ts +5 -5
- package/src/algorithm/d3-force/index.ts +5 -8
- package/src/util/order.ts +4 -0
package/README.md
CHANGED
|
@@ -1,43 +1,105 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# AntV Layout
|
|
4
|
+
|
|
5
|
+
Basic layout algorithms for visualization
|
|
4
6
|
|
|
5
7
|
[](https://github.com/antvis/layout/actions)
|
|
6
|
-
[](https://app.codecov.io/gh/antvis/layout/tree/v5)
|
|
7
9
|
[](https://www.npmjs.com/package/@antv/layout)
|
|
8
10
|
[](https://www.npmjs.com/package/@antv/layout)
|
|
9
11
|
[](https://www.npmjs.com/package/@antv/layout)
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
<img src="https://mdn.alipayobjects.com/huamei_aphk1k/afts/img/A*oV6nR7oW4PMAAAAAgFAAAAgAegfkAQ/original" width="720" alt="AntV Layout Preview">
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
</div>
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
**@antv/layout** is a collection of basic layout algorithms. It ships with a wide range of layouts, unifies graph data and layout APIs, and turns graph structures into renderable coordinates.
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
<div align="center">
|
|
20
|
+
<a href="https://layout.antv.vision/">
|
|
21
|
+
<img src="https://img.shields.io/badge/Website-2F54EB?style=for-the-badge" alt="Website" />
|
|
22
|
+
</a>
|
|
23
|
+
<a href="https://layout.antv.vision/guide/start/getting-started">
|
|
24
|
+
<img src="https://img.shields.io/badge/Docs-722ED1?style=for-the-badge" alt="Docs" />
|
|
25
|
+
</a>
|
|
26
|
+
<a href="https://layout.antv.vision/guide/api/api/introduction">
|
|
27
|
+
<img src="https://img.shields.io/badge/API%20Reference-13C2C2?style=for-the-badge" alt="API Reference" />
|
|
28
|
+
</a>
|
|
29
|
+
<!-- <a href="https://observablehq.com/d/2db6b0cc5e97d8d6">
|
|
30
|
+
<img src="https://img.shields.io/badge/Demo-FA8C16?style=for-the-badge" alt="Demo" />
|
|
31
|
+
</a> -->
|
|
32
|
+
<a href="https://layout.antv.vision/perf">
|
|
33
|
+
<img src="https://img.shields.io/badge/Benchmark-D46A6A?style=for-the-badge" alt="Benchmark" />
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
## β¨ Highlights
|
|
20
38
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
39
|
+
- **Coverage**: common graph layouts (force, dagre, radial, grid, combo)
|
|
40
|
+
- **Built for visualization**: real-world scenarios and workflows
|
|
41
|
+
- **Performance**: fast defaults + optional WebWorker offloading
|
|
42
|
+
- **Integration**: easy to plug into your rendering pipeline
|
|
43
|
+
- **TypeScript & docs**: typed APIs with complete documentation
|
|
25
44
|
|
|
26
|
-
##
|
|
45
|
+
## π§© Layouts
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
47
|
+
| Layout | Preview | Description |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| <img alt="Force" src="https://img.shields.io/badge/Force-2F54EB?style=flat-square"> [ForceAtlas2](https://layout.antv.vision/guide/api/force/force-atlas2) | <img alt="ForceAtlas2" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*-HgiS6CyuuEAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Force-directed layout for large graphs with acceleration options (e.g. BarnesβHut). |
|
|
50
|
+
| <img alt="Force" src="https://img.shields.io/badge/Force-2F54EB?style=flat-square"> [Force](https://layout.antv.vision/guide/api/force/force) | <img alt="Force" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Ce2WSIlo_fcAAAAAAAAAAABkARQnAQ" width="240" /> | Highly configurable force model for fine-grained tuning and process control. |
|
|
51
|
+
| <img alt="Force" src="https://img.shields.io/badge/Force-2F54EB?style=flat-square"> [Fruchterman](https://layout.antv.vision/guide/api/force/fruchterman) | <img alt="Fruchterman" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*1AvnTorIogUAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Classic force-directed layout for small/medium graphs with balanced distribution. |
|
|
52
|
+
| <img alt="Force" src="https://img.shields.io/badge/Force-2F54EB?style=flat-square"> [D3Force](https://layout.antv.vision/guide/api/force/d3-force) | <img alt="D3Force" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*9VXcQLLyzHgAAAAAAAAAAABkARQnAQ" width="240" /> | d3-force style simulation wrapper for composing link/manyBody/collide forces. |
|
|
53
|
+
| <img alt="Force" src="https://img.shields.io/badge/Force-2F54EB?style=flat-square"> [D3Force3D](https://layout.antv.vision/guide/api/force/d3-force-3d) | <img alt="D3Force3D" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*4mbSTJLOXkgAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | 3D force layout based on d3-force-3d with z-axis forces and z output. |
|
|
54
|
+
| <img alt="Hierarchy" src="https://img.shields.io/badge/Hierarchy-722ED1?style=flat-square"> [Dagre](https://layout.antv.vision/guide/api/hierarchy/dagre) | <img alt="Dagre" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*v5mBSopYr_wAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Layered directed layout for DAGs, workflows, and dependency graphs. |
|
|
55
|
+
| <img alt="Hierarchy" src="https://img.shields.io/badge/Hierarchy-722ED1?style=flat-square"> [AntVDagre](https://layout.antv.vision/guide/api/hierarchy/antv-dagre) | <img alt="AntVDagre" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*gQGOTYlN6BMAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Production-oriented hierarchical layout with spacing, alignment, and path info. |
|
|
56
|
+
| <img alt="Radial" src="https://img.shields.io/badge/Radial-13C2C2?style=flat-square"> [Circular](https://layout.antv.vision/guide/api/radial/circular) | <img alt="Circular" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*qJi5Q4qg6W8AAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Place nodes on a circle (or spiral) with ordering, angle, and radius controls. |
|
|
57
|
+
| <img alt="Radial" src="https://img.shields.io/badge/Radial-13C2C2?style=flat-square"> [Concentric](https://layout.antv.vision/guide/api/radial/concentric) | <img alt="Concentric" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*KXunQKOLCSAAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Layer nodes by an importance score (default: degree), pulling higher scores inward. |
|
|
58
|
+
| <img alt="Radial" src="https://img.shields.io/badge/Radial-13C2C2?style=flat-square"> [Radial](https://layout.antv.vision/guide/api/radial/radial) | <img alt="Radial" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*vpXjTIFKy1QAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Focus-centered rings based on shortest-path distance for relationship exploration. |
|
|
59
|
+
| <img alt="Regular" src="https://img.shields.io/badge/Regular-52C41A?style=flat-square"> [Grid](https://layout.antv.vision/guide/api/regular/grid) | <img alt="Grid" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*8RYVTrENVCcAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Stable grid placement for predictable layouts like cards, lists, and matrices. |
|
|
60
|
+
| <img alt="Others" src="https://img.shields.io/badge/Others-8C8C8C?style=flat-square"> [MDS](https://layout.antv.vision/guide/api/others/mds) | <img alt="MDS" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*myM6T6R_d34AAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Multidimensional scaling to match ideal distances and produce a balanced global structure. |
|
|
61
|
+
| <img alt="Combo" src="https://img.shields.io/badge/Combo-FA8C16?style=flat-square"> [ComboCombined](https://layout.antv.vision/guide/api/combo/combo-combined) | <img alt="ComboCombined" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*zPAzSZ3XxpUAAAAAAAAAAAAADmJ7AQ/original" width="240" /> | Composite layout for combos/subgraphs with per-level strategies and consistent bounds/spacing. |
|
|
31
62
|
|
|
32
|
-
##
|
|
63
|
+
## π Installation
|
|
33
64
|
|
|
34
65
|
```bash
|
|
35
|
-
|
|
66
|
+
npm install @antv/layout
|
|
36
67
|
```
|
|
37
68
|
|
|
38
|
-
|
|
69
|
+
## π Quick Start
|
|
39
70
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
71
|
+
```ts
|
|
72
|
+
import { CircularLayout } from '@antv/layout';
|
|
73
|
+
|
|
74
|
+
const data = {
|
|
75
|
+
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }],
|
|
76
|
+
edges: [
|
|
77
|
+
{ source: 'node1', target: 'node2' },
|
|
78
|
+
{ source: 'node2', target: 'node3' },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
async function run() {
|
|
83
|
+
const layout = new CircularLayout({ center: [200, 200], radius: 150 });
|
|
84
|
+
|
|
85
|
+
await layout.execute(data);
|
|
86
|
+
|
|
87
|
+
layout.forEachNode((node) => {
|
|
88
|
+
console.log(node.id, node.x, node.y);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
run();
|
|
43
93
|
```
|
|
94
|
+
|
|
95
|
+
## π§΅ Worker support
|
|
96
|
+
|
|
97
|
+
Set `enableWorker: true` to run layouts in a WebWorker when supported. See the docs for worker setup and layout configuration details.
|
|
98
|
+
|
|
99
|
+
## π€ Contributing
|
|
100
|
+
|
|
101
|
+
Contributions are welcome. See `CONTRIBUTING.md` for guidelines and local workflows.
|
|
102
|
+
|
|
103
|
+
## π License
|
|
104
|
+
|
|
105
|
+
MIT licensed. See `LICENSE` for details.
|
package/dist/index.js
CHANGED
|
@@ -693,10 +693,13 @@
|
|
|
693
693
|
model.setNodeOrder(nodes);
|
|
694
694
|
return model;
|
|
695
695
|
}
|
|
696
|
-
function orderByDegree(model) {
|
|
696
|
+
function orderByDegree(model, order = 'desc') {
|
|
697
697
|
return sort$1(model, (nodeA, nodeB) => {
|
|
698
698
|
const degreeA = model.degree(nodeA.id);
|
|
699
699
|
const degreeB = model.degree(nodeB.id);
|
|
700
|
+
if (order === 'asc') {
|
|
701
|
+
return degreeA - degreeB; // ascending order
|
|
702
|
+
}
|
|
700
703
|
return degreeB - degreeA; // descending order
|
|
701
704
|
});
|
|
702
705
|
}
|
|
@@ -5476,7 +5479,7 @@
|
|
|
5476
5479
|
}
|
|
5477
5480
|
else if (ordering === 'degree') {
|
|
5478
5481
|
// layout according to the descent order of degrees
|
|
5479
|
-
orderByDegree(this.model);
|
|
5482
|
+
orderByDegree(this.model, 'asc');
|
|
5480
5483
|
}
|
|
5481
5484
|
let { radius, startRadius, endRadius } = this.options;
|
|
5482
5485
|
const nodes = this.model.nodes();
|
|
@@ -7447,14 +7450,7 @@
|
|
|
7447
7450
|
});
|
|
7448
7451
|
}
|
|
7449
7452
|
parseOptions(options) {
|
|
7450
|
-
var _a, _b;
|
|
7451
7453
|
const _ = options;
|
|
7452
|
-
// process nodeSize
|
|
7453
|
-
if (_.collide && ((_a = _.collide) === null || _a === void 0 ? void 0 : _a.radius) === undefined) {
|
|
7454
|
-
_.collide = _.collide || {};
|
|
7455
|
-
// @ts-ignore
|
|
7456
|
-
_.collide.radius = (_b = _.nodeSize) !== null && _b !== void 0 ? _b : 10;
|
|
7457
|
-
}
|
|
7458
7454
|
// process iterations
|
|
7459
7455
|
if (_.iterations === undefined) {
|
|
7460
7456
|
if (_.link && _.link.iterations === undefined) {
|
|
@@ -7650,13 +7646,14 @@
|
|
|
7650
7646
|
}
|
|
7651
7647
|
}
|
|
7652
7648
|
getCollisionOptions(options) {
|
|
7653
|
-
if (options.preventOverlap === false
|
|
7649
|
+
if (options.preventOverlap === false &&
|
|
7650
|
+
(options.collide === false || options.collide === undefined))
|
|
7654
7651
|
return undefined;
|
|
7655
7652
|
const radius = options.nodeSize || options.nodeSpacing
|
|
7656
7653
|
? (d) => formatNodeSizeFn(options.nodeSize, options.nodeSpacing)(d._original) / 2
|
|
7657
7654
|
: undefined;
|
|
7658
7655
|
return assignDefined({}, options.collide || {}, {
|
|
7659
|
-
radius: options.collide || radius,
|
|
7656
|
+
radius: (options.collide && options.collide.radius) || radius,
|
|
7660
7657
|
strength: options.collideStrength,
|
|
7661
7658
|
iterations: options.collideIterations,
|
|
7662
7659
|
});
|
|
@@ -32443,9 +32440,9 @@ ${indent}columns: ${matrix.columns}
|
|
|
32443
32440
|
? { type: 'force', preventOverlap: true }
|
|
32444
32441
|
: { type: 'concentric', preventOverlap: true },
|
|
32445
32442
|
nodeSize: 20,
|
|
32446
|
-
nodeSpacing:
|
|
32447
|
-
comboPadding:
|
|
32448
|
-
comboSpacing:
|
|
32443
|
+
nodeSpacing: 0,
|
|
32444
|
+
comboPadding: 10,
|
|
32445
|
+
comboSpacing: 0,
|
|
32449
32446
|
};
|
|
32450
32447
|
const ROOT_ID = 'root';
|
|
32451
32448
|
/**
|