mirror of
https://gitee.com/antv/g6.git
synced 2024-12-04 20:59:15 +08:00
fix: custom layout warning and layout failed problem; (#3758)
* fix: custom layout warning and layout failed problem; fix: upgrade layout to fix DagreLayoutOptions type error; fix: upgrade layout to fix comboCombined with original node infomations problem; * chore: tests refine * Truncate node labels (#3690) * Added maxLength property to LabelStyle * Added unit test for label max length * Added truncateLabelByLength util function * Added safety checks for negative and non-number maxLength values * Moved maxLength prop to labelCfg * feat: maxLength for labelCfg; * chore: upgrade version nums Co-authored-by: Tony <51513780+TonyN96@users.noreply.github.com>
This commit is contained in:
parent
778720cc89
commit
4512b10bcb
@ -1,5 +1,12 @@
|
||||
# ChangeLog
|
||||
|
||||
#### 4.6.10
|
||||
|
||||
- feat: maxLength for labelCfg;
|
||||
- fix: custom layout warning and layout failed problem;
|
||||
- fix: upgrade layout to fix DagreLayoutOptions type error;
|
||||
- fix: upgrade layout to fix comboCombined with original node infomations problem;
|
||||
|
||||
#### 4.6.8
|
||||
|
||||
- fix: spelling error for 'nodeselectChange', closes: #3736;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-core",
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.10",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
|
@ -10,6 +10,7 @@ import { formatPadding } from '../util/base';
|
||||
import Global from '../global';
|
||||
import Shape from './shape';
|
||||
import { shapeBase } from './shapeBase';
|
||||
import { truncateLabelByLength } from '../util/graphic';
|
||||
|
||||
const singleNode: ShapeOptions = {
|
||||
itemType: 'node',
|
||||
@ -48,11 +49,19 @@ const singleNode: ShapeOptions = {
|
||||
},
|
||||
// 私有方法,不希望扩展的节点复写这个方法
|
||||
getLabelStyleByPosition(cfg: NodeConfig, labelCfg: ILabelConfig): LabelStyle {
|
||||
const labelMaxLength = labelCfg.maxLength;
|
||||
|
||||
let text = cfg!.label as string;
|
||||
|
||||
if (labelMaxLength) {
|
||||
text = truncateLabelByLength(text, labelMaxLength);
|
||||
}
|
||||
|
||||
const labelPosition = labelCfg.position || this.labelPosition;
|
||||
|
||||
// 默认的位置(最可能的情形),所以放在最上面
|
||||
if (labelPosition === 'center') {
|
||||
return { x: 0, y: 0, text: cfg!.label as string, textBaseline: 'middle', textAlign: 'center' };
|
||||
return { x: 0, y: 0, text, textBaseline: 'middle', textAlign: 'center' };
|
||||
}
|
||||
|
||||
let { offset } = labelCfg;
|
||||
@ -98,7 +107,7 @@ const singleNode: ShapeOptions = {
|
||||
};
|
||||
break;
|
||||
}
|
||||
style.text = cfg.label;
|
||||
style.text = text;
|
||||
return style;
|
||||
},
|
||||
getLabelBgStyleByPosition(
|
||||
|
@ -64,7 +64,7 @@ const colorSet = {
|
||||
};
|
||||
|
||||
export default {
|
||||
version: '0.6.8',
|
||||
version: '0.6.10',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
@ -211,7 +211,7 @@ export default abstract class LayoutController {
|
||||
|
||||
let start = Promise.resolve();
|
||||
layoutMethods?.forEach((layoutMethod: any, index: number) => {
|
||||
const currentCfg = layoutCfg[index];
|
||||
const currentCfg = layoutCfg[index] || layoutCfg;
|
||||
start = start.then(() => this.reLayoutMethod(layoutMethod, currentCfg));
|
||||
});
|
||||
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
IG6GraphEvent,
|
||||
IPoint,
|
||||
FitViewRules,
|
||||
G6Event
|
||||
} from '../types';
|
||||
import { IEdge, INode, ICombo } from './item';
|
||||
import Hull from '../item/hull';
|
||||
@ -625,12 +626,12 @@ export interface IAbstractGraph extends EventEmitter {
|
||||
/**
|
||||
* 重新定义监听函数,复写参数类型
|
||||
*/
|
||||
on: <T = IG6GraphEvent>(eventName: string, callback: (e: T) => void, once?: boolean) => this;
|
||||
on: <T = IG6GraphEvent>(eventName: G6Event, callback: (e: T) => void, once?: boolean) => this;
|
||||
|
||||
/**
|
||||
* 移除指定的監聽函數
|
||||
*/
|
||||
off: <T = IG6GraphEvent>(eventName: string, callback: (e: T) => void, once?: boolean) => this;
|
||||
off: <T = IG6GraphEvent>(eventName: G6Event, callback: (e: T) => void, once?: boolean) => this;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@ export type ILabelConfig = Partial<{
|
||||
refY: number;
|
||||
autoRotate: boolean;
|
||||
style: LabelStyle;
|
||||
maxLength?: number;
|
||||
}>;
|
||||
|
||||
export type ShapeDefine = string | ((cfg: ModelConfig) => string);
|
||||
|
@ -185,7 +185,7 @@ export type MobileInteractionEventType = MobileInteractionEvent;
|
||||
* @example
|
||||
* https://g6.antv.vision/en/docs/api/Event#combo-interaction-event
|
||||
*/
|
||||
export type G6Event = NodeEventType | EdgeEventType | ComboEventType | CanvasEventType | GraphTimingEventType | MobileInteractionEventType | CommonInteractionEvent | CommonInteractionEvent;
|
||||
export type G6Event = NodeEventType | EdgeEventType | ComboEventType | CanvasEventType | GraphTimingEventType | MobileInteractionEventType | CommonInteractionEvent | CommonInteractionEvent | (string & {});
|
||||
|
||||
export interface IG6GraphEvent extends GraphEvent {
|
||||
item: Item | null;
|
||||
|
@ -375,6 +375,13 @@ export const getTextSize = (text: string, fontSize: number) => {
|
||||
return [width, fontSize];
|
||||
};
|
||||
|
||||
export const truncateLabelByLength = (text: string, length: number) => {
|
||||
if (typeof length !== 'number' || length <= 0 || length >= text.length) {
|
||||
return text;
|
||||
}
|
||||
return text.substring(0, length) + '...';
|
||||
}
|
||||
|
||||
/**
|
||||
* construct the trees from combos data
|
||||
* @param array the combos array
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { clone, groupBy } from '@antv/util';
|
||||
import { clone, groupBy, isNumberEqual } from '@antv/util';
|
||||
import Graph from '../implement-graph';
|
||||
|
||||
const div = document.createElement('div');
|
||||
@ -477,11 +477,11 @@ describe('hierarchy data 1: combo A has one child: an empty combo B', () => {
|
||||
comboB = graph.findById('B');
|
||||
comboBModel = comboB.getModel();
|
||||
|
||||
expect(comboBModel.x).toBe(100);
|
||||
expect(comboBModel.y).toBe(200);
|
||||
expect(isNumberEqual(comboBModel.x, 100, 1)).toBe(true);
|
||||
expect(isNumberEqual(comboBModel.y, 200, 1)).toBe(true);
|
||||
// A has no position, follows the child
|
||||
expect(comboAModel.x).toBe(100);
|
||||
expect(comboAModel.y).toBe(200);
|
||||
expect(isNumberEqual(comboAModel.x, 100, 1)).toBe(true);
|
||||
expect(isNumberEqual(comboAModel.y, 200, 1)).toBe(true);
|
||||
});
|
||||
it('parent combo collapsed with pos, child combo with pos', (done) => {
|
||||
const testData = clone(data);
|
||||
|
@ -247,6 +247,27 @@ describe('shape node test', () => {
|
||||
expect(shape.attr('lineWidth')).toBe(1);
|
||||
});
|
||||
|
||||
it('max label length', () => {
|
||||
const mockLabel = 'This is a test label';
|
||||
const group = canvas.addGroup();
|
||||
factory.draw(
|
||||
'simple-circle',
|
||||
{
|
||||
size: 20,
|
||||
color: 'blue',
|
||||
label: mockLabel,
|
||||
labelCfg: {
|
||||
maxLength: 5,
|
||||
},
|
||||
},
|
||||
group,
|
||||
);
|
||||
canvas.draw();
|
||||
const label = group.get('children')[1];
|
||||
|
||||
expect(label.attr('text')).toBe(mockLabel.substring(0, 5) + '...');
|
||||
});
|
||||
|
||||
it('clear', () => {
|
||||
canvas.destroy();
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { traverseTree, traverseTreeUp, getTextSize } from '../../../src/util/graphic';
|
||||
import { traverseTree, traverseTreeUp, getTextSize, truncateLabelByLength } from '../../../src/util/graphic';
|
||||
|
||||
interface TreeNode {
|
||||
id: string;
|
||||
@ -89,4 +89,22 @@ describe('graphic unit test', () => {
|
||||
result = getTextSize('体验技术', 14);
|
||||
expect(result).toEqual([56, 14]);
|
||||
});
|
||||
|
||||
it('truncateLabelByLength' ,() => {
|
||||
const label = 'This is a test label';
|
||||
let length = 5;
|
||||
|
||||
let result = truncateLabelByLength(label, length);
|
||||
expect(result).toEqual(label.substring(0, 5) + '...');
|
||||
|
||||
length = 100;
|
||||
|
||||
result = truncateLabelByLength(label, length);
|
||||
expect(result).toEqual(label);
|
||||
|
||||
length = -1;
|
||||
|
||||
result = truncateLabelByLength(label, length);
|
||||
expect(result).toEqual(label);
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-element",
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.10",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -61,7 +61,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g6-core": "0.6.8",
|
||||
"@antv/g6-core": "0.6.10",
|
||||
"@antv/util": "~2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6",
|
||||
"version": "4.6.8",
|
||||
"version": "4.6.10",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -66,7 +66,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g6-pc": "0.6.8"
|
||||
"@antv/g6-pc": "0.6.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.7",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import G6 from '@antv/g6-pc';
|
||||
|
||||
G6.version = '4.6.8';
|
||||
G6.version = '4.6.10';
|
||||
|
||||
export * from '@antv/g6-pc';
|
||||
export default G6;
|
||||
export const version = '4.6.8';
|
||||
export const version = '4.6.10';
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-pc",
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.10",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -75,11 +75,11 @@
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-math": "^0.1.1",
|
||||
"@antv/g-svg": "^0.5.1",
|
||||
"@antv/g6-core": "0.6.8",
|
||||
"@antv/g6-element": "0.6.8",
|
||||
"@antv/g6-plugin": "0.6.8",
|
||||
"@antv/g6-core": "0.6.10",
|
||||
"@antv/g6-element": "0.6.10",
|
||||
"@antv/g6-plugin": "0.6.10",
|
||||
"@antv/hierarchy": "^0.6.7",
|
||||
"@antv/layout": "^0.2.1",
|
||||
"@antv/layout": "^0.2.5",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
"@antv/path-util": "^2.0.3",
|
||||
"@antv/util": "~2.0.5",
|
||||
|
@ -7,7 +7,7 @@ const textColor = 'rgb(0, 0, 0)';
|
||||
const colorSet = getColorsWithSubjectColor(subjectColor, backColor);
|
||||
|
||||
export default {
|
||||
version: '0.6.8',
|
||||
version: '0.6.10',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
@ -136,12 +136,12 @@ describe('text background label', () => {
|
||||
}, 30);
|
||||
}, 100)
|
||||
});
|
||||
it('text background with autoRotate false and clearItemStates', () => {
|
||||
it('text background with autoRotate false and clearItemStates', (done) => {
|
||||
let edge = graph.getEdges()[0];
|
||||
let labelBgShape = edge.getContainer().get('children')[1];
|
||||
let { x, y } = labelBgShape.attr();
|
||||
expect(labelBgShape.attr().x).toBe(176.85302734375);
|
||||
expect(labelBgShape.attr().y).toBe(116);
|
||||
expect(x).toBe(176.85302734375);
|
||||
expect(y).toBe(116);
|
||||
|
||||
graph.updateItem(graph.getNodes()[0], {
|
||||
x: graph.getNodes()[0].getModel().x + 100,
|
||||
@ -150,8 +150,11 @@ describe('text background label', () => {
|
||||
graph.clearItemStates(edge, ['active']);
|
||||
|
||||
labelBgShape = edge.getContainer().get('children')[1];
|
||||
const { x: newX, y: newY } = labelBgShape.attr();
|
||||
expect(numberEqual(newX, 226, 2)).toBe(true);
|
||||
expect(numberEqual(newY, 166, 2)).toBe(true);
|
||||
setTimeout(() => {
|
||||
const { x: newX, y: newY } = labelBgShape.attr();
|
||||
expect(numberEqual(newX, 226, 2)).toBe(true);
|
||||
expect(numberEqual(newY, 166, 2)).toBe(true);
|
||||
done()
|
||||
}, 16);
|
||||
});
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-plugin",
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.10",
|
||||
"description": "G6 Plugin",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -22,8 +22,8 @@
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-svg": "^0.5.2",
|
||||
"@antv/g6-core": "0.6.8",
|
||||
"@antv/g6-element": "0.6.8",
|
||||
"@antv/g6-core": "0.6.10",
|
||||
"@antv/g6-element": "0.6.10",
|
||||
"@antv/matrix-util": "^3.1.0-beta.3",
|
||||
"@antv/scale": "^0.3.4",
|
||||
"@antv/util": "^2.0.9",
|
||||
|
@ -2,4 +2,6 @@
|
||||
title: API
|
||||
---
|
||||
|
||||
`markdown:docs/api/graphLayout/comboCombined.en.md`
|
||||
|
||||
`markdown:docs/api/graphLayout/comboForce.en.md`
|
||||
|
@ -2,4 +2,6 @@
|
||||
title: API
|
||||
---
|
||||
|
||||
`markdown:docs/api/graphLayout/comboCombined.zh.md`
|
||||
|
||||
`markdown:docs/api/graphLayout/comboForce.zh.md`
|
||||
|
472
packages/site/examples/net/comboForce/demo/comboCombined.js
Normal file
472
packages/site/examples/net/comboForce/demo/comboCombined.js
Normal file
@ -0,0 +1,472 @@
|
||||
import G6 from '@antv/g6';
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: '0',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '11',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '12',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '13',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '14',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '15',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '16',
|
||||
comboId: 'b',
|
||||
},
|
||||
{
|
||||
id: '17',
|
||||
comboId: 'b',
|
||||
},
|
||||
{
|
||||
id: '18',
|
||||
comboId: 'b',
|
||||
},
|
||||
{
|
||||
id: '19',
|
||||
comboId: 'b',
|
||||
},
|
||||
{
|
||||
id: '20',
|
||||
},
|
||||
{
|
||||
id: '21',
|
||||
},
|
||||
{
|
||||
id: '22',
|
||||
},
|
||||
{
|
||||
id: '23',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '24',
|
||||
comboId: 'a',
|
||||
},
|
||||
{
|
||||
id: '25',
|
||||
},
|
||||
{
|
||||
id: '26',
|
||||
},
|
||||
{
|
||||
id: '27',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '28',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '29',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '30',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '31',
|
||||
comboId: 'c',
|
||||
},
|
||||
{
|
||||
id: '32',
|
||||
comboId: 'd',
|
||||
},
|
||||
{
|
||||
id: '33',
|
||||
comboId: 'd',
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
source: 'a',
|
||||
target: 'b',
|
||||
label: 'Combo A - Combo B',
|
||||
size: 3,
|
||||
labelCfg: {
|
||||
autoRotate: true,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
style: {
|
||||
stroke: 'red',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: 'a',
|
||||
target: '33',
|
||||
label: 'Combo-Node',
|
||||
size: 3,
|
||||
labelCfg: {
|
||||
autoRotate: true,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
lineWidth: 5,
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
style: {
|
||||
stroke: 'blue',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '1',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '2',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '3',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '4',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '5',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '7',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '8',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '9',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '10',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '11',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '13',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '14',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '15',
|
||||
},
|
||||
{
|
||||
source: '0',
|
||||
target: '16',
|
||||
},
|
||||
{
|
||||
source: '2',
|
||||
target: '3',
|
||||
},
|
||||
{
|
||||
source: '4',
|
||||
target: '5',
|
||||
},
|
||||
{
|
||||
source: '4',
|
||||
target: '6',
|
||||
},
|
||||
{
|
||||
source: '5',
|
||||
target: '6',
|
||||
},
|
||||
{
|
||||
source: '7',
|
||||
target: '13',
|
||||
},
|
||||
{
|
||||
source: '8',
|
||||
target: '14',
|
||||
},
|
||||
{
|
||||
source: '9',
|
||||
target: '10',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '22',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '14',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '12',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '24',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '21',
|
||||
},
|
||||
{
|
||||
source: '10',
|
||||
target: '20',
|
||||
},
|
||||
{
|
||||
source: '11',
|
||||
target: '24',
|
||||
},
|
||||
{
|
||||
source: '11',
|
||||
target: '22',
|
||||
},
|
||||
{
|
||||
source: '11',
|
||||
target: '14',
|
||||
},
|
||||
{
|
||||
source: '12',
|
||||
target: '13',
|
||||
},
|
||||
{
|
||||
source: '16',
|
||||
target: '17',
|
||||
},
|
||||
{
|
||||
source: '16',
|
||||
target: '18',
|
||||
},
|
||||
{
|
||||
source: '16',
|
||||
target: '21',
|
||||
},
|
||||
{
|
||||
source: '16',
|
||||
target: '22',
|
||||
},
|
||||
{
|
||||
source: '17',
|
||||
target: '18',
|
||||
},
|
||||
{
|
||||
source: '17',
|
||||
target: '20',
|
||||
},
|
||||
{
|
||||
source: '18',
|
||||
target: '19',
|
||||
},
|
||||
{
|
||||
source: '19',
|
||||
target: '20',
|
||||
},
|
||||
{
|
||||
source: '19',
|
||||
target: '33',
|
||||
},
|
||||
{
|
||||
source: '19',
|
||||
target: '22',
|
||||
},
|
||||
{
|
||||
source: '19',
|
||||
target: '23',
|
||||
},
|
||||
{
|
||||
source: '20',
|
||||
target: '21',
|
||||
},
|
||||
{
|
||||
source: '21',
|
||||
target: '22',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '24',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '25',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '26',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '23',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '28',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '30',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '31',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '32',
|
||||
},
|
||||
{
|
||||
source: '22',
|
||||
target: '33',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '28',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '27',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '29',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '30',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '31',
|
||||
},
|
||||
{
|
||||
source: '23',
|
||||
target: '33',
|
||||
},
|
||||
{
|
||||
source: '32',
|
||||
target: '33',
|
||||
},
|
||||
],
|
||||
combos: [
|
||||
{
|
||||
id: 'a',
|
||||
label: 'Combo A',
|
||||
},
|
||||
{
|
||||
id: 'b',
|
||||
label: 'Combo B',
|
||||
},
|
||||
{
|
||||
id: 'c',
|
||||
label: 'Combo D',
|
||||
},
|
||||
{
|
||||
id: 'd',
|
||||
label: 'Combo D',
|
||||
parentId: 'b',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const container = document.getElementById('container');
|
||||
const width = container.scrollWidth;
|
||||
const height = container.scrollHeight || 500;
|
||||
const graph = new G6.Graph({
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
fitView: true,
|
||||
fitViewPadding: 50,
|
||||
minZoom: 0.00000001,
|
||||
layout: {
|
||||
type: 'comboCombined',
|
||||
},
|
||||
defaultNode: {
|
||||
size: 15,
|
||||
color: '#5B8FF9',
|
||||
style: {
|
||||
lineWidth: 2,
|
||||
fill: '#C6E5FF',
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
size: 2,
|
||||
color: '#e2e2e2',
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-combo', 'drag-node', 'drag-canvas', 'zoom-canvas', 'collapse-expand-combo'],
|
||||
},
|
||||
});
|
||||
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
|
||||
if (typeof window !== 'undefined')
|
||||
window.onresize = () => {
|
||||
if (!graph || graph.get('destroyed')) return;
|
||||
if (!container || !container.scrollWidth || !container.scrollHeight) return;
|
||||
graph.changeSize(container.scrollWidth, container.scrollHeight);
|
||||
};
|
@ -4,6 +4,14 @@
|
||||
"en": "Category"
|
||||
},
|
||||
"demos": [
|
||||
{
|
||||
"filename": "comboCombined.js",
|
||||
"title": {
|
||||
"zh": "ComboCombined 力导向布局",
|
||||
"en": "Combo Combined Layout"
|
||||
},
|
||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*GK34T7F1_CYAAAAAAAAAAABkARQnAQ"
|
||||
},
|
||||
{
|
||||
"filename": "basicComboForce.js",
|
||||
"title": {
|
||||
|
@ -1,10 +1,12 @@
|
||||
---
|
||||
title: Combo Force Layout
|
||||
title: Combo Related Layout
|
||||
order: 10
|
||||
---
|
||||
|
||||
_It is a new feature of V3.5._ Combo Force is designed for the graph with combos based on classical force directed layout algorith. It modifies the forces between nodes according to their combo infomation to achieve a final result with clustering nodes inside each combo and no overlappings.
|
||||
_New feature of V4.6_ Designed for graph with combos. Support configuring the layout for items inside a combo and the layout for the outer combos and nodes.
|
||||
|
||||
_New feature of V3.5._ Combo Force is designed for the graph with combos based on classical force directed layout algorith. It modifies the forces between nodes according to their combo infomation to achieve a final result with clustering nodes inside each combo and no overlappings.
|
||||
|
||||
## Usage
|
||||
|
||||
We suggest to use `'comboForce'` for the graph with combos. Other layouts in G6 are also availabel, but they do not consider the combo infomation.
|
||||
We suggest to use `'comboCombined'` or `'comboForce'` for the graph with combos. Other layouts in G6 are also availabel, but they do not consider the combo infomation.
|
||||
|
@ -1,10 +1,12 @@
|
||||
---
|
||||
title: Combo 力导布局
|
||||
title: Combo 相关布局
|
||||
order: 10
|
||||
---
|
||||
|
||||
*V4.6.0 新增功能。*是 G6 自研的、适用于带有 combo 的图,可自由组合内外布局,默认情况下,内部使用同心圆布局,外部使用力导向布局,可以有较好的效果,推荐有 combo 的图使用该布局。
|
||||
|
||||
*V3.5 新增功能。*Combo Force 是基于力导向的专用于带有 combo 的图的布局算法。通过自研改造经典力导向算法,将根据节点的 combo 信息,施加不同的力以达到同 combo 节点尽可能聚集,不同 combo 之间尽可能无重叠的布局。
|
||||
|
||||
## 使用指南
|
||||
|
||||
在有 Combo 的图上,推荐使用 `'comboForce'` 布局。其他内置布局将不会考虑 Combo 信息对布局的影响。
|
||||
在有 Combo 的图上,推荐使用 `'comboCombined'` 或 `'comboForce'` 布局。其他内置布局将不会考虑 Combo 信息对布局的影响。
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/g6-site",
|
||||
"version": "4.6.8",
|
||||
"version": "4.6.10",
|
||||
"description": "G6 sites deployed on gh-pages",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -36,7 +36,7 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.0.6",
|
||||
"@antv/chart-node-g6": "^0.0.3",
|
||||
"@antv/g6": "4.6.8",
|
||||
"@antv/g6": "4.6.10",
|
||||
"@antv/gatsby-theme-antv": "1.1.15",
|
||||
"@antv/util": "^2.0.9",
|
||||
"@antv/vis-predict-engine": "^0.1.1",
|
||||
|
Loading…
Reference in New Issue
Block a user