mirror of
https://gitee.com/antv/g6.git
synced 2024-12-05 05:09:07 +08:00
Merge remote-tracking branch 'antv/master' into g6-react-node
This commit is contained in:
commit
4ea639dad2
22
CHANGELOG.md
22
CHANGELOG.md
@ -1,5 +1,27 @@
|
||||
# ChangeLog
|
||||
|
||||
#### 4.1.7
|
||||
|
||||
- fix: polyline with negative endpoints;
|
||||
- fix: polyline direction when linkCenter;
|
||||
- fix: remove g6-core browser since it has no umd output;
|
||||
- feat: custom texts for the time range and time point text in timeBar plugin;
|
||||
- chore: types for strict mode;
|
||||
|
||||
#### 4.1.6
|
||||
|
||||
- fix: webworker problem after removing broswer in pc and g6;
|
||||
|
||||
#### 4.1.5
|
||||
|
||||
- fix: wrong style for modelRect after updating and state changing, closes: #2613;
|
||||
- fix: drag-canvas with shouldBegin false, closes: #2571;
|
||||
- fix: pack plugin with es module, closes: #2577;
|
||||
- feat: dijkstra with multiple shortest paths, closes: #2297;
|
||||
- fix: setMode while the delegates of brush-select and drag-node is on the canvas, closes: #2607;
|
||||
- docs: update the english TimeBar docs, closes: #2597;
|
||||
- fix: TimeBar time point switch text configurable, closes: #2597;
|
||||
|
||||
#### 4.1.4
|
||||
|
||||
- fix: drag-canvas with touch on mobile;
|
||||
|
@ -115,6 +115,16 @@ graph.render();
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# lerna bootstrap for multiple packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build the packages
|
||||
$ npm run build:all
|
||||
|
||||
# if you wanna watch one of the packages, e.g. packages/core
|
||||
$ cd ./packages/core
|
||||
$ npm run watch
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
|
||||
@ -149,7 +159,7 @@ $ npm run demos
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 [issues](https://github.com/antvis/g6/issues) 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md).
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md).
|
||||
|
||||
## License
|
||||
|
||||
|
12
README.md
12
README.md
@ -115,6 +115,16 @@ For more information of the usage, please refer to [Getting Started](https://ant
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# lerna bootstrap for multiple packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build the packages
|
||||
$ npm run build:all
|
||||
|
||||
# if you wanna watch one of the packages, e.g. packages/core
|
||||
$ cd ./packages/core
|
||||
$ npm run watch
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
|
||||
@ -145,7 +155,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out [issues](https://github.com/antvis/g6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/g6/blob/master/CONTRIBUTING.md).
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -64,10 +64,15 @@
|
||||
"typescript": "^3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@umijs/fabric": "^2.3.1",
|
||||
"pre-commit": "^1.2.2",
|
||||
"@types/react": "^16.9.35",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@umijs/fabric": "^2.3.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-unicorn": "^27.0.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"react-scripts": "3.1.2"
|
||||
},
|
||||
"resolutions": {
|
||||
|
@ -115,8 +115,17 @@ graph.render();
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -149,7 +158,7 @@ $ npm run demos
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 [issues](https://github.com/antvis/g6/issues) 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md).
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -115,8 +115,17 @@ For more information of the usage, please refer to [Getting Started](https://ant
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -145,7 +154,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out [issues](https://github.com/antvis/g6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/g6/blob/master/CONTRIBUTING.md).
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-core",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.9",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -31,7 +31,6 @@
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"browser": "dist/g6-core.min.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"scripts": {
|
||||
"start": "father build --watch",
|
||||
@ -59,7 +58,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/algorithm": "^0.0.6",
|
||||
"@antv/algorithm": "^0.0.7",
|
||||
"@antv/dom-util": "^2.0.1",
|
||||
"@antv/event-emitter": "~0.1.0",
|
||||
"@antv/g-base": "^0.5.1",
|
||||
|
@ -8,6 +8,7 @@ import { IPoint, Item, LabelStyle, ShapeStyle, ModelConfig, EdgeConfig } from '.
|
||||
import Global from '../global';
|
||||
import { ext } from '@antv/matrix-util';
|
||||
import { deepMix, each, mix, isBoolean, isPlainObject, clone } from '@antv/util';
|
||||
import { cloneBesidesImg } from '../util/graphic';
|
||||
|
||||
const transform = ext.transform;
|
||||
|
||||
@ -401,11 +402,11 @@ export const shapeBase: ShapeOptions = {
|
||||
}
|
||||
} else {
|
||||
// 所有生效的 state 的样式
|
||||
const enableStatesStyle = clone(item.getCurrentStatesStyle());
|
||||
const enableStatesStyle = cloneBesidesImg(item.getCurrentStatesStyle());
|
||||
|
||||
const model = item.getModel();
|
||||
// 原始样式
|
||||
const originStyle = mix({}, model.style, clone(item.getOriginStyle()));
|
||||
const originStyle = mix({}, model.style, cloneBesidesImg(item.getOriginStyle()));
|
||||
|
||||
const keyShapeName = shape.get('name');
|
||||
|
||||
@ -416,7 +417,7 @@ export const shapeBase: ShapeOptions = {
|
||||
Object.keys(shapeAttrs).forEach((key) => {
|
||||
if (key === 'img') return;
|
||||
const attr = shapeAttrs[key];
|
||||
if (typeof attr === 'object') {
|
||||
if (attr && typeof attr === 'object') {
|
||||
keyShapeStyles[key] = clone(attr);
|
||||
} else {
|
||||
keyShapeStyles[key] = attr;
|
||||
@ -466,7 +467,6 @@ export const shapeBase: ShapeOptions = {
|
||||
} else {
|
||||
filtetDisableStatesStyle[keyShapeName] = keyShapeStyles;
|
||||
}
|
||||
|
||||
for (const key in enableStatesStyle) {
|
||||
if (keptAttrs[key]) continue;
|
||||
const enableStyle = enableStatesStyle[key];
|
||||
|
@ -64,7 +64,7 @@ const colorSet = {
|
||||
};
|
||||
|
||||
export default {
|
||||
version: '0.0.7',
|
||||
version: '0.0.9',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
@ -120,6 +120,7 @@ export default class ModeController {
|
||||
graph.emit('beforemodechange', { mode });
|
||||
|
||||
each(this.currentBehaves, behave => {
|
||||
if (behave.delegate) behave.delegate.remove();
|
||||
behave.unbind(graph);
|
||||
});
|
||||
|
||||
|
@ -360,7 +360,7 @@ export interface IAbstractGraph extends EventEmitter {
|
||||
* @param {string} mode 指定的模式中的行为,不指定则为 default
|
||||
* @return {Graph} Graph
|
||||
*/
|
||||
updateBehavior: (behavior: string, newCfg: object, modes: string | string[]) => Graph;
|
||||
updateBehavior: (behavior: string, newCfg: object, mode?: string) => Graph;
|
||||
|
||||
/**
|
||||
* 清除画布元素
|
||||
|
@ -363,5 +363,5 @@ export interface ICombo extends INode {
|
||||
* @param node 节点实例
|
||||
* @return boolean 移除成功返回 true,否则返回 false
|
||||
*/
|
||||
removeNode: (node: string | INode) => boolean;
|
||||
removeNode: (node: INode) => boolean;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IGroup } from '@antv/g-base';
|
||||
import { ICombo, INode, IItemBaseConfig } from '../interface/item';
|
||||
import Node from './node';
|
||||
import { ComboConfig, IBBox, IShapeBase } from '../types';
|
||||
import { ComboConfig, IBBox, IShapeBase, ModelConfig } from '../types';
|
||||
import Global from '../global';
|
||||
import { getBBox } from '../util/graphic';
|
||||
import { isNumber } from '@antv/util';
|
||||
@ -21,7 +21,7 @@ export default class Combo extends Node implements ICombo {
|
||||
};
|
||||
}
|
||||
|
||||
public getShapeCfg(model: ComboConfig): ComboConfig {
|
||||
public getShapeCfg(model: ModelConfig): ModelConfig {
|
||||
const styles = this.get('styles');
|
||||
const bbox = this.get('bbox');
|
||||
if (styles && bbox) {
|
||||
|
@ -217,13 +217,18 @@ export default class ItemBase implements IItemBase {
|
||||
originStyles[name] =
|
||||
shapeType !== 'image' ? clone(child.attr()) : self.getShapeStyleByName(name);
|
||||
} else {
|
||||
// !name || name === keyShape
|
||||
const keyShapeStyle: ShapeStyle = self.getShapeStyleByName(); // 可优化,需要去除 child.attr 中其他 shape 名的对象
|
||||
if (keyShapeStyle.path) delete keyShapeStyle.path;
|
||||
if (keyShapeStyle.matrix) delete keyShapeStyle.matrix;
|
||||
if (!keyShapeName) {
|
||||
Object.assign(originStyles, keyShapeStyle);
|
||||
} else {
|
||||
originStyles[keyShapeName] = keyShapeStyle;
|
||||
} else { // 若 keyShape 有 name 且 !name,这个图形不是 keyShape,给这个图形一个 name
|
||||
if (!name) {
|
||||
const shapeName = uniqueId('shape');
|
||||
child.set('name', shapeName);
|
||||
originStyles[shapeName] = shapeType !== 'image' ? clone(child.attr()) : self.getShapeStyleByName(name);
|
||||
} else originStyles[keyShapeName] = keyShapeStyle
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { each, isNil, mix } from '@antv/util';
|
||||
import { IEdge, INode } from '../interface/item';
|
||||
import { IPoint, IShapeBase, NodeConfig } from '../types';
|
||||
import { IPoint, IShapeBase, ModelConfig, NodeConfig } from '../types';
|
||||
import { getBBox } from '../util/graphic';
|
||||
import {
|
||||
distance,
|
||||
@ -237,7 +237,7 @@ export default class Node extends Item implements INode {
|
||||
* 是否仅仅移动节点,其他属性没变化
|
||||
* @param cfg 节点数据模型
|
||||
*/
|
||||
public isOnlyMove(cfg: NodeConfig): boolean {
|
||||
public isOnlyMove(cfg: ModelConfig): boolean {
|
||||
if (!cfg) {
|
||||
return false;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
} from '../types';
|
||||
import { applyMatrix } from './math';
|
||||
import letterAspectRatio from './letterAspectRatio';
|
||||
import { isString, clone, isNumber } from '@antv/util';
|
||||
import { isString, clone, isNumber, isObject } from '@antv/util';
|
||||
import { IAbstractGraph } from '../interface/graph';
|
||||
|
||||
const { PI, sin, cos } = Math;
|
||||
@ -648,3 +648,22 @@ export const shouldRefreshEdge = (cfg) => {
|
||||
isNumber(cfg.style.ry);
|
||||
return refreshEdge;
|
||||
};
|
||||
|
||||
export const cloneBesidesImg = (obj) => {
|
||||
const clonedObj = {};
|
||||
Object.keys(obj).forEach(key1 => {
|
||||
const obj2 = obj[key1];
|
||||
if (isObject(obj2)) {
|
||||
const clonedObj2 = {};
|
||||
Object.keys(obj2).forEach(key2 => {
|
||||
const v = obj2[key2];
|
||||
if(key2 === 'img' && !isString(v)) return;
|
||||
clonedObj2[key2] = clone(v);
|
||||
})
|
||||
clonedObj[key1] = clonedObj2;
|
||||
} else {
|
||||
clonedObj[key1] = clone(obj2);
|
||||
}
|
||||
});
|
||||
return clonedObj;
|
||||
}
|
@ -47,7 +47,7 @@ const isBetween = (value: number, min: number, max: number) => value >= min && v
|
||||
* @return {Point} 交点
|
||||
*/
|
||||
export const getLineIntersect = (p0: Point, p1: Point, p2: Point, p3: Point): Point | null => {
|
||||
const tolerance = 0.001;
|
||||
const tolerance = 0.0001;
|
||||
|
||||
const E: Point = {
|
||||
x: p2.x - p0.x,
|
||||
@ -63,12 +63,13 @@ export const getLineIntersect = (p0: Point, p1: Point, p2: Point, p3: Point): Po
|
||||
};
|
||||
const kross: number = D0.x * D1.y - D0.y * D1.x;
|
||||
const sqrKross: number = kross * kross;
|
||||
const invertKross: number = 1 / kross;
|
||||
const sqrLen0: number = D0.x * D0.x + D0.y * D0.y;
|
||||
const sqrLen1: number = D1.x * D1.x + D1.y * D1.y;
|
||||
let point: Point | null = null;
|
||||
if (sqrKross > tolerance * sqrLen0 * sqrLen1) {
|
||||
const s = (E.x * D1.y - E.y * D1.x) / kross;
|
||||
const t = (E.x * D0.y - E.y * D0.x) / kross;
|
||||
const s = (E.x * D1.y - E.y * D1.x) * invertKross;
|
||||
const t = (E.x * D0.y - E.y * D0.x) * invertKross;
|
||||
if (isBetween(s, 0, 1) && isBetween(t, 0, 1)) {
|
||||
point = {
|
||||
x: p0.x + s * D0.x,
|
||||
|
@ -115,8 +115,17 @@ graph.render();
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -149,7 +158,7 @@ $ npm run demos
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 [issues](https://github.com/antvis/g6/issues) 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md).
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -115,8 +115,17 @@ For more information of the usage, please refer to [Getting Started](https://ant
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -145,7 +154,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out [issues](https://github.com/antvis/g6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/g6/blob/master/CONTRIBUTING.md).
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-element",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.8",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -61,7 +61,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g6-core": "^0.0.7",
|
||||
"@antv/g6-core": "^0.0.9",
|
||||
"@antv/util": "~2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -66,14 +66,13 @@ export const filterConnectPoints = (points: PolyPoint[]): PolyPoint[] => {
|
||||
// pre-process: remove duplicated points
|
||||
const result: any[] = [];
|
||||
const pointsMap: any = {};
|
||||
points.forEach((p) => {
|
||||
const id = `${p.x}-${p.y}`;
|
||||
p.id = id;
|
||||
pointsMap[id] = p;
|
||||
});
|
||||
each(pointsMap, (p) => {
|
||||
const pointsLength = points.length;
|
||||
for (let i = 0; i < pointsLength; i++) {
|
||||
const p = points[i];
|
||||
p.id = `${p.x}|||${p.y}`;
|
||||
pointsMap[p.id] = p;
|
||||
result.push(p);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
export const simplifyPolyline = (points: PolyPoint[]): PolyPoint[] => {
|
||||
@ -102,13 +101,37 @@ export const getExpandedBBox = (bbox: any, offset: number): PBBox => {
|
||||
width: bbox.width + 2 * offset,
|
||||
};
|
||||
};
|
||||
export const isHorizontalPort = (port: PolyPoint, bbox: PBBox): boolean => {
|
||||
export const isHorizontalPort = (port: PolyPoint, bbox: PBBox): boolean | number => {
|
||||
const dx = Math.abs(port.x - bbox.centerX);
|
||||
const dy = Math.abs(port.y - bbox.centerY);
|
||||
if (dx === 0 && dy === 0) return 0;
|
||||
return dx / bbox.width > dy / bbox.height;
|
||||
};
|
||||
export const getExpandedBBoxPoint = (bbox: any, point: PolyPoint): PolyPoint => {
|
||||
export const getExpandedBBoxPoint = (
|
||||
bbox: any,
|
||||
point: PolyPoint,
|
||||
anotherPoint: PolyPoint,
|
||||
): PolyPoint => {
|
||||
const isHorizontal = isHorizontalPort(point, bbox);
|
||||
if (isHorizontal === 0) {
|
||||
// 说明锚点是节点中心,linkCenter: true。需要根据两个节点的相对关系决定方向
|
||||
let x = bbox.centerX;
|
||||
let y = bbox.centerY;
|
||||
if (anotherPoint.y < point.y) {
|
||||
// 另一端在左上/右上方时,总是从上方走
|
||||
y = bbox.minY;
|
||||
} else if (anotherPoint.x > point.x) {
|
||||
// 另一端在右下方,往右边走
|
||||
x = bbox.maxX;
|
||||
} else if (anotherPoint.x < point.x) {
|
||||
// 另一端在左下方,往左边走
|
||||
x = bbox.minX;
|
||||
} else if (anotherPoint.x === point.x) {
|
||||
// 另一段在正下方,往下走
|
||||
y = bbox.maxY;
|
||||
}
|
||||
return { x, y };
|
||||
}
|
||||
if (isHorizontal) {
|
||||
return {
|
||||
x: point.x > bbox.centerX ? bbox.maxX : bbox.minX,
|
||||
@ -266,15 +289,21 @@ export const isSegmentsIntersected = (
|
||||
p2: PolyPoint,
|
||||
p3: PolyPoint,
|
||||
): boolean => {
|
||||
const s1X = p1.x - p0.x;
|
||||
const s1Y = p1.y - p0.y;
|
||||
const s2X = p3.x - p2.x;
|
||||
const s2Y = p3.y - p2.y;
|
||||
const v1x = p2.x - p0.x;
|
||||
const v1y = p2.y - p0.y;
|
||||
const v2x = p3.x - p0.x;
|
||||
const v2y = p3.y - p0.y;
|
||||
const v3x = p2.x - p1.x;
|
||||
const v3y = p2.y - p1.y;
|
||||
const v4x = p3.x - p1.x;
|
||||
const v4y = p3.y - p1.y;
|
||||
|
||||
const s = (-s1Y * (p0.x - p2.x) + s1X * (p0.y - p2.y)) / (-s2X * s1Y + s1X * s2Y);
|
||||
const t = (s2X * (p0.y - p2.y) - s2Y * (p0.x - p2.x)) / (-s2X * s1Y + s1X * s2Y);
|
||||
const pd1 = v1x * v2y - v1y * v2x;
|
||||
const pd2 = v3x * v4y - v3y * v4x;
|
||||
const pd3 = v1x * v3y - v1y * v3x;
|
||||
const pd4 = v2x * v4y - v2y * v4x;
|
||||
|
||||
return s >= 0 && s <= 1 && t >= 0 && t <= 1;
|
||||
return pd1 * pd2 <= 0 && pd3 * pd4 <= 0;
|
||||
};
|
||||
export const isSegmentCrossingBBox = (p1: PolyPoint, p2: PolyPoint, bbox: PBBox): boolean => {
|
||||
if (bbox.width === 0 && bbox.height === 0) {
|
||||
@ -483,10 +512,9 @@ export const getPolylinePoints = (
|
||||
// the expanded bounding boxes of source and target nodes are overlapping
|
||||
return simplifyPolyline(getSimplePolyline(start, end));
|
||||
}
|
||||
const sPoint = getExpandedBBoxPoint(sxBBox, start);
|
||||
const tPoint = getExpandedBBoxPoint(txBBox, end);
|
||||
const sPoint = getExpandedBBoxPoint(sxBBox, start, end);
|
||||
const tPoint = getExpandedBBoxPoint(txBBox, end, start);
|
||||
const lineBBox = getBBoxFromPoints([sPoint, tPoint]);
|
||||
const outerBBox = mergeBBox(sxBBox, txBBox);
|
||||
const sMixBBox = mergeBBox(sxBBox, lineBBox);
|
||||
const tMixBBox = mergeBBox(txBBox, lineBBox);
|
||||
let connectPoints: any = [];
|
||||
|
@ -37,7 +37,7 @@ registerEdge(
|
||||
routeCfg: {
|
||||
obstacles: [], // 希望边绕过的障碍节点
|
||||
maxAllowedDirectionChange: 90, // 允许的最大转角
|
||||
maximumLoops: 1000,
|
||||
maximumLoops: 500,
|
||||
gridSize: 10, // 指定精度
|
||||
},
|
||||
stateStyles: {
|
||||
|
@ -97,8 +97,9 @@ export const octolinearCfg: RouterCfg = {
|
||||
};
|
||||
|
||||
const pos2GridIx = (pos: number, gridSize: number) => {
|
||||
const gridIx = Math.floor(pos / gridSize);
|
||||
return gridIx < 0 ? 0 : gridIx;
|
||||
const gridIx = Math.floor(Math.abs(pos / gridSize));
|
||||
const sign = pos < 0 ? -1 : 1;
|
||||
return gridIx < 0 ? 0 : sign * gridIx;
|
||||
};
|
||||
|
||||
const getObstacleMap = (items: Item[], gridSize: number, offset: number) => {
|
||||
@ -113,7 +114,7 @@ const getObstacleMap = (items: Item[], gridSize: number, offset: number) => {
|
||||
y <= pos2GridIx(bbox.maxY, gridSize);
|
||||
y += 1
|
||||
) {
|
||||
const gridKey = `${x}-${y}`;
|
||||
const gridKey = `${x}|||${y}`;
|
||||
map[gridKey] = true;
|
||||
}
|
||||
}
|
||||
@ -158,7 +159,13 @@ const estimateCost = (from: PolyPoint, endPoints: PolyPoint[], distFunc) => {
|
||||
};
|
||||
|
||||
// 计算考虑 offset 后的 BBox 上的连接点
|
||||
const getBoxPoints = (point: PolyPoint, node: INode, cfg: RouterCfg): PolyPoint[] => {
|
||||
const getBoxPoints = (
|
||||
point: PolyPoint,
|
||||
oriPoint: PolyPoint,
|
||||
node: INode,
|
||||
anotherPoint: PolyPoint,
|
||||
cfg: RouterCfg,
|
||||
): PolyPoint[] => {
|
||||
const points = [];
|
||||
// create-edge 生成边的过程中,endNode 为 null
|
||||
if (!node) {
|
||||
@ -167,15 +174,16 @@ const getBoxPoints = (point: PolyPoint, node: INode, cfg: RouterCfg): PolyPoint[
|
||||
|
||||
const { directions, offset } = cfg;
|
||||
const bbox = node.getBBox();
|
||||
const expandBBox = getExpandedBBox(node.getBBox(), offset);
|
||||
const isInside =
|
||||
oriPoint.x > bbox.minX &&
|
||||
oriPoint.x < bbox.maxX &&
|
||||
oriPoint.y > bbox.minY &&
|
||||
oriPoint.y < bbox.maxY;
|
||||
|
||||
const expandBBox = getExpandedBBox(bbox, offset);
|
||||
for (const i in expandBBox) {
|
||||
expandBBox[i] = pos2GridIx(expandBBox[i], cfg.gridSize);
|
||||
}
|
||||
const isInside =
|
||||
point.x > pos2GridIx(bbox.minX, cfg.gridSize) &&
|
||||
point.x < pos2GridIx(bbox.maxX, cfg.gridSize) &&
|
||||
point.y > pos2GridIx(bbox.minY, cfg.gridSize) &&
|
||||
point.y < pos2GridIx(bbox.maxY, cfg.gridSize);
|
||||
|
||||
if (isInside) {
|
||||
// 如果 anchorPoint 在节点内部,允许第一段线穿过节点
|
||||
@ -230,16 +238,16 @@ const getBoxPoints = (point: PolyPoint, node: INode, cfg: RouterCfg): PolyPoint[
|
||||
boundLine[0],
|
||||
boundLine[1],
|
||||
) as PolyPoint;
|
||||
if (insterctP && !isSegmentCrossingBBox(point, insterctP, node.getBBox())) {
|
||||
insterctP.id = `${insterctP.x}-${insterctP.y}`;
|
||||
if (insterctP && !isSegmentCrossingBBox(point, insterctP, bbox)) {
|
||||
insterctP.id = `${insterctP.x}|||${insterctP.y}`;
|
||||
points.push(insterctP);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果 anchorPoint 在节点上,只有一个可选方向
|
||||
const insterctP = getExpandedBBoxPoint(expandBBox, point);
|
||||
insterctP.id = `${insterctP.x}-${insterctP.y}`;
|
||||
const insterctP = getExpandedBBoxPoint(expandBBox, point, anotherPoint);
|
||||
insterctP.id = `${insterctP.x}|||${insterctP.y}`;
|
||||
points.push(insterctP);
|
||||
}
|
||||
|
||||
@ -266,10 +274,10 @@ export const pathFinder = (
|
||||
y: pos2GridIx(endPoint.y, cfg.gridSize),
|
||||
};
|
||||
|
||||
startPoint.id = `${scaleStartPoint.x}-${scaleStartPoint.y}`;
|
||||
endPoint.id = `${scaleEndPoint.x}-${scaleEndPoint.y}`;
|
||||
const startPoints = getBoxPoints(scaleStartPoint, startNode, cfg);
|
||||
const endPoints = getBoxPoints(scaleEndPoint, endNode, cfg);
|
||||
startPoint.id = `${scaleStartPoint.x}|||${scaleStartPoint.y}`;
|
||||
endPoint.id = `${scaleEndPoint.x}|||${scaleEndPoint.y}`;
|
||||
const startPoints = getBoxPoints(scaleStartPoint, startPoint, startNode, scaleEndPoint, cfg);
|
||||
const endPoints = getBoxPoints(scaleEndPoint, endPoint, endNode, scaleStartPoint, cfg);
|
||||
startPoints.forEach((point) => {
|
||||
delete map[point.id];
|
||||
});
|
||||
@ -311,8 +319,8 @@ export const pathFinder = (
|
||||
} else {
|
||||
const prevDirectionAngle = getDirectionAngle(
|
||||
{
|
||||
x: parseFloat(cameFrom[current.id].split('-')[0]),
|
||||
y: parseFloat(cameFrom[current.id].split('-')[1]),
|
||||
x: parseFloat(cameFrom[current.id].split('|||')[0]),
|
||||
y: parseFloat(cameFrom[current.id].split('|||')[1]),
|
||||
},
|
||||
current,
|
||||
);
|
||||
@ -324,8 +332,8 @@ export const pathFinder = (
|
||||
const getControlPoints = (currentId: string) => {
|
||||
const controlPoints = [endPoint];
|
||||
const lastPoint = {
|
||||
x: parseFloat(currentId.split('-')[0]),
|
||||
y: parseFloat(currentId.split('-')[1]),
|
||||
x: parseFloat(currentId.split('|||')[0]),
|
||||
y: parseFloat(currentId.split('|||')[1]),
|
||||
id: currentId,
|
||||
};
|
||||
if (getDirectionChange(lastPoint, scaleEndPoint)) {
|
||||
@ -336,14 +344,14 @@ export const pathFinder = (
|
||||
}
|
||||
while (cameFrom[currentId] && cameFrom[currentId] !== currentId) {
|
||||
const point = {
|
||||
x: parseFloat(currentId.split('-')[0]),
|
||||
y: parseFloat(currentId.split('-')[1]),
|
||||
x: parseFloat(currentId.split('|||')[0]),
|
||||
y: parseFloat(currentId.split('|||')[1]),
|
||||
id: currentId,
|
||||
};
|
||||
const preId = cameFrom[currentId];
|
||||
const prePoint = {
|
||||
x: parseFloat(preId.split('-')[0]),
|
||||
y: parseFloat(preId.split('-')[1]),
|
||||
x: parseFloat(preId.split('|||')[0]),
|
||||
y: parseFloat(preId.split('|||')[1]),
|
||||
id: preId,
|
||||
};
|
||||
const directionChange = getDirectionChange(prePoint, point);
|
||||
@ -359,8 +367,8 @@ export const pathFinder = (
|
||||
|
||||
// 和startNode对齐
|
||||
const firstPoint = {
|
||||
x: parseFloat(currentId.split('-')[0]),
|
||||
y: parseFloat(currentId.split('-')[1]),
|
||||
x: parseFloat(currentId.split('|||')[0]),
|
||||
y: parseFloat(currentId.split('|||')[1]),
|
||||
id: currentId,
|
||||
};
|
||||
controlPoints[0].x = firstPoint.x === scaleStartPoint.x ? startPoint.x : controlPoints[0].x;
|
||||
@ -399,7 +407,7 @@ export const pathFinder = (
|
||||
const neighbor = {
|
||||
x: current.x + direction.stepX,
|
||||
y: current.y + direction.stepY,
|
||||
id: `${current.x + direction.stepX}-${current.y + direction.stepY}`,
|
||||
id: `${current.x + direction.stepX}|||${current.y + direction.stepY}`,
|
||||
};
|
||||
|
||||
if (closedSet[neighbor.id]) continue;
|
||||
|
@ -302,6 +302,8 @@ registerNode(
|
||||
y: 7,
|
||||
text: cfg.label,
|
||||
},
|
||||
className: 'text-shape',
|
||||
name: 'text-shape',
|
||||
draggable: true,
|
||||
});
|
||||
}
|
||||
|
@ -115,8 +115,17 @@ graph.render();
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -149,7 +158,7 @@ $ npm run demos
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 [issues](https://github.com/antvis/g6/issues) 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md).
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -115,8 +115,17 @@ For more information of the usage, please refer to [Getting Started](https://ant
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -145,7 +154,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out [issues](https://github.com/antvis/g6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/g6/blob/master/CONTRIBUTING.md).
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6",
|
||||
"version": "4.1.4",
|
||||
"version": "4.1.7",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -31,7 +31,7 @@
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"browser": "dist/g6.min.js",
|
||||
"unpkg": "dist/g6.min.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"scripts": {
|
||||
"start": "father build --watch",
|
||||
@ -66,7 +66,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g6-pc": "^0.0.8"
|
||||
"@antv/g6-pc": "^0.0.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.7",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import G6 from '@antv/g6-pc';
|
||||
|
||||
G6.version = '4.1.4';
|
||||
G6.version = '4.1.7';
|
||||
|
||||
export * from '@antv/g6-pc';
|
||||
export default G6;
|
||||
export const version = '4.1.4';
|
||||
export const version = '4.1.7';
|
||||
|
@ -12,7 +12,8 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"]
|
||||
"lib": ["esnext", "dom"],
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
@ -115,8 +115,17 @@ graph.render();
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -149,7 +158,7 @@ $ npm run demos
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 [issues](https://github.com/antvis/g6/issues) 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md).
|
||||
成为一个贡献者前请阅读 [代码贡献规范](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -115,8 +115,17 @@ For more information of the usage, please refer to [Getting Started](https://ant
|
||||
```bash
|
||||
$ npm install
|
||||
|
||||
# run bootstrap to link the packages
|
||||
$ npm run bootstrap
|
||||
|
||||
# build all the packages
|
||||
$ npm run build:all
|
||||
|
||||
# run test case
|
||||
$ npm test
|
||||
$ npm run test
|
||||
|
||||
# run lint
|
||||
$ npm run lint
|
||||
|
||||
# run test case in watch mode
|
||||
npm test -- --watch ./tests/unit/algorithm/find-path-spec
|
||||
@ -145,7 +154,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out [issues](https://github.com/antvis/g6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/g6/blob/master/CONTRIBUTING.md).
|
||||
To become a contributor, please follow our [contributing guide](https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/g6-pc",
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.12",
|
||||
"description": "A Graph Visualization Framework in JavaScript",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -75,10 +75,10 @@
|
||||
"@antv/g-math": "^0.1.1",
|
||||
"@antv/g-svg": "^0.5.1",
|
||||
"@antv/g-webgpu": "^0.5.1",
|
||||
"@antv/g6-core": "^0.0.7",
|
||||
"@antv/g6-plugin": "^0.0.6",
|
||||
"@antv/g6-element": "^0.0.6",
|
||||
"@antv/algorithm": "^0.0.6",
|
||||
"@antv/g6-core": "^0.0.9",
|
||||
"@antv/g6-plugin": "^0.0.8",
|
||||
"@antv/g6-element": "^0.0.8",
|
||||
"@antv/algorithm": "^0.0.7",
|
||||
"@antv/hierarchy": "^0.6.2",
|
||||
"@antv/layout": "^0.0.16",
|
||||
"@antv/matrix-util": "^3.0.4",
|
||||
|
@ -190,6 +190,7 @@ export default {
|
||||
name: 'brush-shape',
|
||||
});
|
||||
this.brush = brush;
|
||||
this.delegate = brush;
|
||||
return brush;
|
||||
},
|
||||
updateBrush(e: IG6GraphEvent) {
|
||||
|
@ -94,6 +94,10 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.shouldBegin.call(this, e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.keydown) return;
|
||||
if (!(e.target && e.target.isCanvas && e.target.isCanvas())) return;
|
||||
|
||||
|
@ -444,6 +444,7 @@ export default {
|
||||
},
|
||||
name: 'combo-delegate-shape',
|
||||
});
|
||||
this.delegate = this.delegateShape;
|
||||
} else {
|
||||
const clientX = evt.x - this.origin.x + this.originPoint.minX;
|
||||
const clientY = evt.y - this.origin.y + this.originPoint.minY;
|
||||
|
@ -378,6 +378,7 @@ export default {
|
||||
},
|
||||
name: 'rect-delegate-shape',
|
||||
});
|
||||
this.delegate = this.delegateRect;
|
||||
this.delegateRect.set('capture', false);
|
||||
} else {
|
||||
const clientX = e.x - this.origin.x + this.originPoint.minX;
|
||||
|
@ -216,6 +216,7 @@ export default {
|
||||
name: 'lasso-shape',
|
||||
});
|
||||
this.lasso = lasso;
|
||||
this.delegate = lasso;
|
||||
this.points = [];
|
||||
return lasso;
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
import '@antv/g6-element';
|
||||
import '@antv/g6-element';
|
@ -7,7 +7,7 @@ const textColor = 'rgb(0, 0, 0)';
|
||||
const colorSet = getColorsWithSubjectColor(subjectColor, backColor);
|
||||
|
||||
export default {
|
||||
version: '0.0.8',
|
||||
version: '0.0.12',
|
||||
rootContainerClassName: 'root-container',
|
||||
nodeContainerClassName: 'node-container',
|
||||
edgeContainerClassName: 'edge-container',
|
||||
|
@ -85,5 +85,5 @@ export default {
|
||||
Algorithm,
|
||||
Arrow,
|
||||
Marker,
|
||||
Shape,
|
||||
Shape
|
||||
};
|
||||
|
@ -11,9 +11,9 @@ export const mixColor = (backColor, frontColor, frontAlpha) => {
|
||||
const bc = color(backColor);
|
||||
const fc = color(frontColor);
|
||||
return color([
|
||||
(1 - frontAlpha) * bc.color[0] + frontAlpha * fc.color[0],
|
||||
(1 - frontAlpha) * bc.color[1] + frontAlpha * fc.color[1],
|
||||
(1 - frontAlpha) * bc.color[2] + frontAlpha * fc.color[2],
|
||||
(1 - frontAlpha) * bc.red() + frontAlpha * fc.red(),
|
||||
(1 - frontAlpha) * bc.green() + frontAlpha * fc.green(),
|
||||
(1 - frontAlpha) * bc.blue() + frontAlpha * fc.blue(),
|
||||
]).rgb();
|
||||
};
|
||||
|
||||
|
61
packages/pc/tests/unit/element/polyline-spec.ts
Normal file
61
packages/pc/tests/unit/element/polyline-spec.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { Graph } from '../../../src';
|
||||
import '../../../src';
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'edge-shape';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe('polyline edge', () => {
|
||||
it('polyline edge', () => {
|
||||
const graph = new Graph({
|
||||
container: div,
|
||||
width: 500,
|
||||
height: 500,
|
||||
// linkCenter: true,
|
||||
modes: {
|
||||
default: ['drag-node', 'zoom-canvas', 'drag-canvas'],
|
||||
},
|
||||
defaultEdge: {
|
||||
type: 'polyline',
|
||||
},
|
||||
defaultNode: {
|
||||
type: 'rect',
|
||||
size: [10, 10],
|
||||
},
|
||||
fitCenter: true,
|
||||
});
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: '1',
|
||||
x: -100,
|
||||
y: -300,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
x: -200,
|
||||
y: -200,
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
source: '1',
|
||||
target: '2',
|
||||
},
|
||||
],
|
||||
};
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
const edge = graph.getEdges()[0];
|
||||
const keyShape = edge.getKeyShape();
|
||||
const path = keyShape.attr('path');
|
||||
// expect(path[0][1]).toBe(100);
|
||||
// expect(path[0][2]).toBe(300);
|
||||
// expect(path[2][1]).toBe(100);
|
||||
// expect(path[2][2]).toBe(200);
|
||||
// expect(path[4][1]).toBe(200);
|
||||
// expect(path[4][2]).toBe(200);
|
||||
|
||||
// graph.destroy();
|
||||
});
|
||||
});
|
179
packages/pc/tests/unit/graph/graph-setmode-spec.ts
Normal file
179
packages/pc/tests/unit/graph/graph-setmode-spec.ts
Normal file
@ -0,0 +1,179 @@
|
||||
import { Graph } from '../../../src';
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'hull-spec';
|
||||
document.body.appendChild(div);
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: '1',
|
||||
label: '公司1',
|
||||
group: 1,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
label: '公司2',
|
||||
group: 1,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
label: '公司3',
|
||||
group: 1,
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
label: '公司4',
|
||||
group: 1,
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
label: '公司5',
|
||||
group: 2,
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
label: '公司6',
|
||||
group: 2,
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
label: '公司7',
|
||||
group: 2,
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
label: '公司8',
|
||||
group: 2,
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
label: '公司9',
|
||||
group: 2,
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
source: '1',
|
||||
target: '1',
|
||||
type: 'loop',
|
||||
},
|
||||
{
|
||||
source: '2',
|
||||
target: '2',
|
||||
type: 'loop',
|
||||
},
|
||||
{
|
||||
source: '1',
|
||||
target: '2',
|
||||
data: {
|
||||
type: 'A',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '1',
|
||||
target: '3',
|
||||
data: {
|
||||
type: 'B',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '2',
|
||||
target: '5',
|
||||
data: {
|
||||
type: 'C',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '5',
|
||||
target: '6',
|
||||
data: {
|
||||
type: 'B',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '3',
|
||||
target: '4',
|
||||
data: {
|
||||
type: 'C',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '4',
|
||||
target: '7',
|
||||
data: {
|
||||
type: 'B',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '1',
|
||||
target: '8',
|
||||
data: {
|
||||
type: 'B',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
{
|
||||
source: '1',
|
||||
target: '9',
|
||||
data: {
|
||||
type: 'C',
|
||||
amount: '100,000 元',
|
||||
date: '2019-08-03',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe('graph setmode and clean the delegates', () => {
|
||||
const graph = new Graph({
|
||||
container: div,
|
||||
width: 500,
|
||||
height: 500,
|
||||
modes: {
|
||||
default: [{
|
||||
type: 'drag-node',
|
||||
enableDelegate: true
|
||||
},
|
||||
'zoom-canvas',
|
||||
{
|
||||
type: 'brush-select',
|
||||
trigger: 'drag'
|
||||
}],
|
||||
custom: ['drag-canvas']
|
||||
},
|
||||
});
|
||||
|
||||
graph.data(data);
|
||||
graph.render();
|
||||
|
||||
it('executing a behavior and set mode', () => {
|
||||
const node = graph.getNodes()[0];
|
||||
graph.emit('node:dragstart', { x: 100, y: 100, item: node });
|
||||
graph.emit('node:drag', { x: 220, y: 220, item: node });
|
||||
graph.setMode('custom');
|
||||
const brushRect = graph.get('canvas').find(e => e.get('name') === 'brush-shape')
|
||||
expect(!brushRect || brushRect.destroyed).toBe(true);
|
||||
|
||||
graph.setMode('default');
|
||||
graph.emit('keydown', { canvasX: 20, canvasY: 20, key: 'shift' });
|
||||
graph.emit('dragstart', { canvasX: 20, canvasY: 20 });
|
||||
graph.emit('drag', { canvasX: 120, canvasY: 120 });
|
||||
graph.setMode('custom');
|
||||
const dragDelegate = graph.get('group').find(e => e.get('name') === 'rect-delegate-shape')
|
||||
expect(!dragDelegate || dragDelegate.destroyed).toBe(true);
|
||||
});
|
||||
});
|
@ -1,8 +1,7 @@
|
||||
import { Graph } from '../../../src';
|
||||
import G6, { Graph } from '../../../src';
|
||||
import '../../../src/behavior';
|
||||
import { GraphData, Item } from '@antv/g6-core';
|
||||
import Core from '@antv/g6-core';
|
||||
// import Plugin from '../../../src/plugins';
|
||||
|
||||
const { scale, translate } = Core.Util;
|
||||
|
||||
@ -71,7 +70,7 @@ describe('graph', () => {
|
||||
width: 500,
|
||||
height: 500,
|
||||
modes: {
|
||||
default: ['drag-node'],
|
||||
default: ['drag-node', 'drag-canvas', 'zoom-canvas'],
|
||||
},
|
||||
});
|
||||
const length = div.childNodes.length;
|
||||
|
@ -13,7 +13,8 @@
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"],
|
||||
"types": ["jest"]
|
||||
"types": ["jest"],
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src", "tests"],
|
||||
"typedocOptions": {
|
||||
|
@ -13,8 +13,6 @@ coverage
|
||||
# Dependency directories
|
||||
node_modules
|
||||
**/node_modules
|
||||
**/lib
|
||||
**/es
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
@ -33,10 +31,6 @@ jspm_packages/
|
||||
# IDE
|
||||
.idea
|
||||
|
||||
# build
|
||||
lib
|
||||
build
|
||||
|
||||
# lock
|
||||
package-lock.json
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@antv/g6-plugin",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.8",
|
||||
"description": "G6 Plugin",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.ts",
|
||||
"module": "es/index.js",
|
||||
"scripts": {
|
||||
"build": "npm run clean && father build",
|
||||
"ci": "npm run build && npm run coverage",
|
||||
@ -22,7 +22,7 @@
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@antv/g-canvas": "^0.5.2",
|
||||
"@antv/g-svg": "^0.5.2",
|
||||
"@antv/g6-core": "^0.0.7",
|
||||
"@antv/g6-core": "^0.0.8",
|
||||
"@antv/matrix-util": "^3.0.4",
|
||||
"@antv/scale": "^0.3.4",
|
||||
"@antv/util": "^2.0.9",
|
||||
@ -57,6 +57,6 @@
|
||||
"jquery": "^3.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^26.4.4",
|
||||
"@antv/g6": "^4.1.3"
|
||||
"@antv/g6": "*"
|
||||
}
|
||||
}
|
@ -59,6 +59,8 @@ export type ControllerCfg = Partial<{
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
readonly fontFamily?: string;
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string;
|
||||
}>;
|
||||
|
||||
export default class ControllerBtn {
|
||||
@ -329,7 +331,7 @@ export default class ControllerBtn {
|
||||
|
||||
this.checkedText = this.toggleGroup.addShape('text', {
|
||||
attrs: {
|
||||
text: '单一时间',
|
||||
text: this.controllerCfg?.timePointControllerText || '单一时间',
|
||||
x: width - TOGGLE_MODEL_OFFSET + 20,
|
||||
y: this.speedAxisY[1] + 15,
|
||||
fill: '#ccc',
|
||||
@ -365,11 +367,11 @@ export default class ControllerBtn {
|
||||
const isChecked = evt.target.get('isChecked');
|
||||
if (!isChecked) {
|
||||
this.checkedIcon.show();
|
||||
this.checkedText.attr('text', '时间范围');
|
||||
this.checkedText.attr('text', this.controllerCfg?.timeRangeControllerText || '时间范围');
|
||||
this.currentType = 'single';
|
||||
} else {
|
||||
this.checkedIcon.hide();
|
||||
this.checkedText.attr('text', '单一时间');
|
||||
this.checkedText.attr('text', this.controllerCfg?.timePointControllerText || '单一时间');
|
||||
this.currentType = 'range';
|
||||
}
|
||||
evt.target.set('isChecked', !isChecked);
|
||||
|
@ -213,7 +213,7 @@ export default class TrendTimeBar {
|
||||
this.ticks = ticks;
|
||||
this.trendCfg = trendCfg;
|
||||
this.controllerCfg = controllerCfg;
|
||||
this.currentSpeed = controllerCfg.speed;
|
||||
this.currentSpeed = controllerCfg.speed || 1;
|
||||
// style
|
||||
if (type === 'trend') {
|
||||
this.backgroundStyle = { ...BACKGROUND_STYLE, ...backgroundStyle };
|
||||
@ -467,6 +467,7 @@ export default class TrendTimeBar {
|
||||
y: this.y + height + 25,
|
||||
width,
|
||||
height: 40,
|
||||
...this.controllerCfg
|
||||
});
|
||||
|
||||
// 根据 start end 更新 ui 的位置信息
|
||||
|
@ -109,7 +109,7 @@ describe('timeline play with timebar', () => {
|
||||
// stroke: '#1890ff'
|
||||
// }
|
||||
// }
|
||||
},
|
||||
}
|
||||
// loop: true
|
||||
});
|
||||
const graph = new G6.Graph({
|
||||
|
@ -32,7 +32,7 @@
|
||||
"@antv/g-base": "^0.5.1",
|
||||
"@types/yoga-layout": "^1.9.3",
|
||||
"react": "^16.12.0",
|
||||
"yoga-layout": "^1.9.3"
|
||||
"yoga-layout-prebuilt": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@umijs/test": "^3.0.5",
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 图配置 G6.Graph(cfg)
|
||||
order: 0
|
||||
redirect_from:
|
||||
- /en/docs/api
|
||||
---
|
||||
|
||||
Graph 是 G6 图表的载体,所有的 G6 节点实例操作以及事件,行为监听都在 Graph 实例上进行。Graph 的初始化通过 new 进行实例化,实例化时需要传入需要的参数。
|
||||
|
@ -339,123 +339,315 @@ const graph = new G6.Graph({
|
||||
|
||||
## TimeBar
|
||||
|
||||
**Important Note:** The latest Timebar document is to be updated, please refer to the components in the official website -> TimeBar DEMO.
|
||||
There are three types of built-in TimeBar in G6:
|
||||
|
||||
The built-in TimeBar plugin has the following abilities:
|
||||
- Time bar with a line chart as background;
|
||||
- Simple time bar;
|
||||
- Time bar with descrete ticks.
|
||||
|
||||
- Filtering the data of the graph by changing the time range;
|
||||
- Demonstrating the trending of the data by an attribute on the TimeBar.
|
||||
All the three types of timebar supports play, fast forward, and fast backward.
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*lfvIQJYbs7oAAAAAAAAAAAAAARQnAQ' width=700 alt='img'/>
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*DOo6QpfFfMUAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with a line chart as background<br />
|
||||
|
||||
**Description:** It is a beta version of TimeBar, which will support complex time series graph and analysis in the future.
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*bzGBQKkewZMAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Simple time bar<br />
|
||||
|
||||
### Configuration
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*kHRkQpnvBmwAAAAAAAAAAAAAARQnAQ' width='500' />
|
||||
<br />Time bar with descrete ticks<br />
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | The container of the TimeBar. A DOM container with className 'g6-component-timebar' will be used by default |
|
||||
| width | number | 400 | The width of the TimeBar's container |
|
||||
| height | number | 400 | The height of the TimeBar's container |
|
||||
| timebar | TimeBarOption | {} | The style configurations for TimeBar |
|
||||
| rangeChange | (graph: IGraph, min: number, max: number) => void | null | The callback function after changing the time range |
|
||||
<br />Refer to the demos [HERE](https://g6.antv.vision/en/examples/tool/timebar#timebar)<br />
|
||||
|
||||
**TimeBarOption for timebar**
|
||||
### Common Usage
|
||||
|
||||
```
|
||||
interface HandleStyle {
|
||||
width: number;
|
||||
height: number;
|
||||
style: ShapeStyle;
|
||||
}
|
||||
```
|
||||
Same to other plugins of G6, the users can initiate the TimeBar and assign it to the graph as:
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The begining x of the TimeBar |
|
||||
| y | number | 0 | The begining y of the TimeBar |
|
||||
| width | number | 400 | The width of the TimeBar |
|
||||
| height | number | 400 | The height of the TimeBar |
|
||||
| backgroundStyle | ShapeStyle | {} | The background style of the TimeBar |
|
||||
| foregroundStyle | ShapeStyle | {} | The foreground style of the TimeBar, which indicates the selected area |
|
||||
| handlerStyle | HandleStyle | null | The style of the slider handler |
|
||||
| textStyle | ShapeStyle | null | The style of the texts |
|
||||
| minLimit | number | 0 | The minimum position for the slider on the left, range from 0 to 1 |
|
||||
| maxLimit | number | 1 | The maximum position for the slider on the right, range from 0 to 1 |
|
||||
| start | number | 0 | The initial start position of the slider |
|
||||
| end | number | 1 | The initial end position of the slider |
|
||||
| minText | string | null | The text for the minimum value |
|
||||
| maxText | string | null | The text for the maximum value |
|
||||
| trend | TrendConfig | null | The configuration of the trend chart on the TimeBar |
|
||||
```javascript
|
||||
import G6 from '@antv/g6';
|
||||
|
||||
**TrendConfig for trend**
|
||||
|
||||
```
|
||||
interface Data {
|
||||
date: string;
|
||||
value: number;
|
||||
}
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| data | Data[] | [] | The data of the TimeBar |
|
||||
| smooth | boolean | false | Whether use the smooth curve instead of polylines for the trend chart |
|
||||
| isArea | boolean | false | Whether use the area chart instead of line chart |
|
||||
| lineStyle | ShapeStyle | null | The style of the line for line chart, takes effect when `isArea` is `false` |
|
||||
| areaStyle | ShapeStyle | null | The style of the area for area chart, takes effect when `isArea` is `true` |
|
||||
|
||||
### Usage
|
||||
|
||||
#### Default Usage
|
||||
|
||||
```
|
||||
const timebar = new G6.TimeBar();
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
});
|
||||
```
|
||||
|
||||
##### Style Configuration
|
||||
|
||||
It is free to configure the style for the TimeBar, and listen to the value changing to do some response.
|
||||
|
||||
```
|
||||
const timebar = new G6.TimeBar({
|
||||
width: 600,
|
||||
timebar: {
|
||||
width: 600,
|
||||
backgroundStyle: {
|
||||
fill: '#08979c',
|
||||
opacity: 0.3
|
||||
},
|
||||
foregroundStyle: {
|
||||
fill: '#40a9ff',
|
||||
opacity: 0.4
|
||||
},
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
isArea: false,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
stroke: '#9254de'
|
||||
}
|
||||
}
|
||||
width: 500,
|
||||
height: 150,
|
||||
padding: 10,
|
||||
type: 'trend',
|
||||
trend: {
|
||||
data: timeBarData,
|
||||
},
|
||||
rangeChange: (graph, min, max) => {
|
||||
// Get the instance of the graph and the range of the timebar, you can control the rendering of the graph by yourself here
|
||||
console.log(graph, min, max)
|
||||
}
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
//... Other configurations
|
||||
plugins: [timebar], // Use timebar plugin
|
||||
container: 'container',
|
||||
width,
|
||||
height,
|
||||
plugins: [timebar],
|
||||
});
|
||||
```
|
||||
|
||||
<br />If you want to use the TimeBar with line chart, assign the `type` to be `trend` when instantiating the TimeBar, which results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*lfvIQJYbs7oAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />Assigning the `type` to be `simple` results in:
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*g2zhQqP6ruYAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
<br />And assigning the `type` to be `tick` results in a TimeBar with descrete ticks. Note that it is different from the above two types of TimeBar, \*\*The TimeBar with decrete ticks is configured with the `tick` object but not the `trend` object.
|
||||
|
||||
```javascript
|
||||
const timebar = new G6.TimeBar({
|
||||
width,
|
||||
height: 150,
|
||||
type: 'tick',
|
||||
tick: {
|
||||
data: timeBarData,
|
||||
width,
|
||||
height: 42,
|
||||
tickLabelFormatter: (d) => {
|
||||
const dateStr = `${d.date}`;
|
||||
if ((count - 1) % 10 === 0) {
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
tooltipFomatter: (d) => {
|
||||
const dateStr = `${d}`;
|
||||
return `${dateStr.substr(0, 4)}-${dateStr.substr(4, 2)}-${dateStr.substr(6, 2)}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*n6ECQ7Jn5pQAAAAAAAAAAAAAARQnAQ' width='600' />
|
||||
|
||||
### Definition of the Configurations
|
||||
|
||||
#### Definition of the Interfaces
|
||||
|
||||
The complete interfaces for the TimeBar is shown below:
|
||||
|
||||
```javascript
|
||||
interface TimeBarConfig extends IPluginBaseConfig {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
readonly type?: 'trend' | 'simple' | 'tick';
|
||||
// the configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple'
|
||||
readonly trend?: TrendConfig;
|
||||
|
||||
// the configurations for the two sliders
|
||||
readonly slider?: SliderOption;
|
||||
|
||||
// the configuration for the TimeBar with descrete ticks, takes effect whtn the type is 'tick'
|
||||
readonly tick?: TimeBarSliceOption;
|
||||
|
||||
// the buttons for play, fast forward, and back forward
|
||||
readonly controllerCfg?: ControllerCfg;
|
||||
|
||||
rangeChange?: (graph: IGraph, minValue: string, maxValue: string) => void;
|
||||
valueChange?: (graph: IGraph, value: string) => void;
|
||||
}
|
||||
```
|
||||
|
||||
#### The Parameters of the Interfaces
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| container | HTMLDivElement | null | The DOM container of the TimeBar. By default, the plugin will create a container DOM with 'g6-component-timebar' as className |
|
||||
| x | number | 0 | The beginning x position of the TimeBar plugin |
|
||||
| y | number | 0 | The beginning y position of the TimeBar plugin |
|
||||
| width | number | | **Requred**, the width of the TimBar |
|
||||
| height | number | | **Requred**, the height of the TimBar |
|
||||
| padding | number/number[] | 10 | The padding of the container of the TimeBar |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | The type of the TimeBar, 'trend' by default |
|
||||
| trend | TrendConfig | null | The configuration for the TimeBar with line chart and simple TimeBar, takes effect whtn the type is 'trend' or 'simple' |
|
||||
| slider | SliderOption | null | The configurations for the two sliders |
|
||||
| tick | TimeBarSliceOption | null | The configuration for the TimeBar with descrete ticks, takes effect whtn the type is 'tick' |
|
||||
| controllerCfg | ControllerCfg | null | The buttons for play, fast forward, and back forward |
|
||||
| rangeChange | Function | null | The callback function after the time range is changed. When it is not assigned, the graph elements will be filtered after the time range is changed |
|
||||
|
||||
#### Interface for TrendConfig
|
||||
|
||||
> Does not support the configurations for the style of the tick labels.
|
||||
|
||||
```javascript
|
||||
interface TrendConfig {
|
||||
// The data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
// The position and size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
// The styles
|
||||
readonly smooth?: boolean;
|
||||
readonly isArea?: boolean;
|
||||
readonly lineStyle?: ShapeStyle;
|
||||
readonly areaStyle?: ShapeStyle;
|
||||
readonly interval?: Interval;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters of the TrendConfig
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position of the trend line chart |
|
||||
| y | number | 0 | The beginning y position of the trend line chart |
|
||||
| width | number | The width of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `width` of the slider in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the TimeBar | The width of the trend line chart of the TimeBar, we suggest to use the default value. If you wanna custom it, please assign the `height` of the slider in the same time |
|
||||
| smooth | boolean | false | Whether to show a smooth line on the trend line chart |
|
||||
| isArea | boolean | false | Whether to show a area chart instead |
|
||||
| lineStyle | ShapeStyle | null | The configurations for the style of the line in the line chart |
|
||||
| areaStyle | ShapeStyle | null | The configuration for the style of the area in the chart when `isArea` is `true` |
|
||||
| interval | Interval | null | The configuration for the style of the bars in the chart. When it is assigned, a mixed trend chart will take place |
|
||||
|
||||
#### Interfaces of SliderOption
|
||||
|
||||
```javascript
|
||||
export type SliderOption = Partial<{
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly backgroundStyle?: ShapeStyle;
|
||||
readonly foregroundStyle?: ShapeStyle;
|
||||
// The style of the sliders
|
||||
readonly handlerStyle?: {
|
||||
width?: number;
|
||||
height?: number;
|
||||
style?: ShapeStyle;
|
||||
};
|
||||
readonly textStyle?: ShapeStyle;
|
||||
// The start and end position for the sliders, which indicate the data range for the filtering. Ranges from 0 to 1
|
||||
readonly start: number;
|
||||
readonly end: number;
|
||||
// The labels for the sliders
|
||||
readonly minText: string;
|
||||
readonly maxText: string;
|
||||
}>;
|
||||
```
|
||||
|
||||
#### Parameters for the SliderOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| width | number | The width of the container of the TimeBar - 2 \* padding | The width of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `width` in the `trend` in the same time |
|
||||
| height | number | 28 when type='trend'<br />8 when type='simple' | The height of the background trend chart. We suggest to use the default value. If you wanna custom it, assign it the the `height` in the `trend` in the same time |
|
||||
| backgroundStyle | ShapeStyle | null | The configuration for the style of the background |
|
||||
| foregroundStyle | ShapeStyle | null | The configuration for the style of the forground |
|
||||
| handlerStyle | ShapeStyle | null | The configuration for the style of the two sliders |
|
||||
| textStyle | ShapeStyle | null | The configuration for the style of the labels on the two sliders |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| minText | string | min | The label for the left slider |
|
||||
| maxText | string | max | The label for the right slider |
|
||||
|
||||
#### TimeBarSliceOption
|
||||
|
||||
```javascript
|
||||
export interface TimeBarSliceOption {
|
||||
// position size
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width?: number;
|
||||
readonly height?: number;
|
||||
readonly padding?: number;
|
||||
|
||||
// styles
|
||||
readonly selectedTickStyle?: TickStyle;
|
||||
readonly unselectedTickStyle?: TickStyle
|
||||
readonly tooltipBackgroundColor?: string;
|
||||
|
||||
readonly start?: number;
|
||||
readonly end?: number;
|
||||
|
||||
// data
|
||||
readonly data: {
|
||||
date: string;
|
||||
value: string;
|
||||
}[];
|
||||
|
||||
// custom the formatter function for the tick labels
|
||||
readonly tickLabelFormatter?: (d: any) => string | boolean;
|
||||
// custom the formatter function for the tooltip
|
||||
readonly tooltipFomatter?: (d: any) => string;
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters for the TimeBarSliceOption
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the TimeBar |
|
||||
| width | number | | **Requred**, the width of the TimeBar |
|
||||
| height | number | | **Requred**, the height of the TimeBar |
|
||||
| padding | number / number[] | 0 | The padding of the container of the TimeBar |
|
||||
| selectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) selected |
|
||||
| unselectedTickStyle | ShapeStyle | null | The style of the tick(s) which is(are) unselected |
|
||||
| tooltipBackgroundColor | ShapeStyle | null | The background style for the tooltip |
|
||||
| start | number | 0.1 | The start position for the sliders, which indicate the start of the data range for the filtering. Ranges from 0 to `end` |
|
||||
| end | number | 0.9 | The end position for the sliders, which indicate the end of the data range for the filtering. Ranges from `start` to 1 |
|
||||
| data | any[] | [] | **Requred**, the data for the ticks |
|
||||
| tickLabelFormatter | Function | null | The formatter function for customing the labels of the ticks |
|
||||
| tooltipFomatter | Function | null | The formatter function for customing the tooltip |
|
||||
|
||||
#### Interface of the ControllerCfg
|
||||
|
||||
> Does not support for now
|
||||
|
||||
> Does not support the style configuration for controller buttons
|
||||
|
||||
> Does not support loop play
|
||||
|
||||
```javascript
|
||||
type ControllerCfg = Partial<{
|
||||
readonly x?: number;
|
||||
readonly y?: number;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
/** the play spped, means the playing time for 1 tick */
|
||||
readonly speed?: number;
|
||||
/** whether play in loop */
|
||||
readonly loop?: boolean;
|
||||
readonly hiddleToggle: boolean;
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** style of the back forward button */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
/** style of the fast forward button */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
/** style of the play button */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
/** the text for the right-botton switch controlling play with single time point or time range */
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string
|
||||
}>
|
||||
```
|
||||
|
||||
#### Parameters for ControllerCfg
|
||||
|
||||
| Name | Type | Default Value | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| x | number | 0 | The beginning x position for the buttons group of the TimeBar |
|
||||
| y | number | 0 | The beginning y position for the buttons group of the TimeBar |
|
||||
| width | number | The width of the TimeBar | The width of the buttons group of the TimeBar |
|
||||
| height | number | 40 | The width of the buttons group of the TimeBar |
|
||||
| speed | number | 1 | The play speed |
|
||||
| loop | boolean | false | _Does not support for now_, whether play in loop |
|
||||
| hiddleToggle | boolean | true | Whther hide the switch of the time range type |
|
||||
| fill | string | | The fillling color for the buttons group |
|
||||
| stroke | string | | The stroke color for the buttons group |
|
||||
| preBtnStyle | ShapeStyle | null | The style configuration for the backward button |
|
||||
| nextBtnStyle | ShapeStyle | null | The style configuration for the forward button |
|
||||
| playBtnStyle | ShapeStyle | null | The style configuration for the play button |
|
||||
| timePointControllerText | string | "单一时间" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
| timeRangeControllerText | string | "时间范围" | The text for the right-botton switch controlling play with single time point or time range |
|
||||
## ToolTip
|
||||
|
||||
ToolTip helps user to explore detail infomations on the node and edge. Do note that, This Tooltip Plugins will replace the tooltip in the built-in behavior after G6 4.0.
|
||||
@ -486,7 +678,7 @@ const tooltip = new G6.Tooltip({
|
||||
const outDiv = document.createElement('div');
|
||||
outDiv.style.width = '180px';
|
||||
outDiv.innerHTML = `
|
||||
<h4>自定义tooltip</h4>
|
||||
<h4>Custom Tooltip</h4>
|
||||
<ul>
|
||||
<li>Label: ${e.item.getModel().label || e.item.getModel().id}</li>
|
||||
</ul>`
|
||||
|
@ -649,8 +649,8 @@ interface TimeBarConfig extends IPluginBaseConfig {
|
||||
| container | HTMLDivElement | null | TimeBar 容器,如果不设置,则默认创建 className 为 g6-component-timebar 的 DOM 容器 |
|
||||
| x | number | 0 | TimeBar 开始 x 坐标 |
|
||||
| y | number | 0 | TimeBar 开始 y 坐标 |
|
||||
| width | number | | 必选,TimeBar 容器宽度 |
|
||||
| height | number | | 必选,TimeBar 高度 |
|
||||
| width | number | | **必选**,TimeBar 容器宽度 |
|
||||
| height | number | | **必选**,TimeBar 高度 |
|
||||
| padding | number/number[] | 10 | TimeBar 距离容器的间距值 |
|
||||
| type | 'trend' / 'simple' / 'tick' | trend | 默认的 TimeBar 类型,默认为趋势图样式 |
|
||||
| trend | TrendConfig | null | Timebar 中趋势图的配置项,当 type 为 trend 或 simple 时,该字段必选 |
|
||||
@ -808,9 +808,15 @@ type ControllerCfg = Partial<{
|
||||
readonly hiddleToggle: boolean;
|
||||
readonly fill?: string;
|
||||
readonly stroke?: string;
|
||||
/** 快退按钮样式 */
|
||||
readonly preBtnStyle?: ShapeStyle;
|
||||
/** 快进按钮样式 */
|
||||
readonly nextBtnStyle?: ShapeStyle;
|
||||
/** 播放按钮样式 */
|
||||
readonly playBtnStyle?: ShapeStyle;
|
||||
/** 右下角“单一时间”和“时间范围”文本 */
|
||||
readonly timePointControllerText?: string;
|
||||
readonly timeRangeControllerText?: string
|
||||
}>
|
||||
```
|
||||
|
||||
@ -830,3 +836,5 @@ type ControllerCfg = Partial<{
|
||||
| preBtnStyle | ShapeStyle | null | 后退按钮样式配置项 |
|
||||
| nextBtnStyle | ShapeStyle | null | 前进按钮样式配置项 |
|
||||
| playBtnStyle | ShapeStyle | null | 播放按钮样式配置项 |
|
||||
| timePointControllerText | string | "单一时间" | 右下角“单一时间”文本,默认为”单一时间“ |
|
||||
| timePointControllerText | string | "时间范围" | 右下角“单一时间”文本,默认为”时间范围时间“ |
|
||||
|
@ -17,7 +17,7 @@ Implemented the redo function, refer to[here](https://github.com/antvis/G6/blob/
|
||||
| --------- | ------- | -------- | ------------------------------------------------ | --------------------------------------------------- |
|
||||
| action | string | false | operation type,the value of 'update' by default |
|
||||
| data | unknown | false | Stacked data |
|
||||
| stackType | 'redo' | 'undo' | false | push operation type,the value of 'redo' by default |
|
||||
| stackType | 'redo' / 'undo' | false | push operation type,the value of 'undo' by default |
|
||||
|
||||
## getUndoStack()
|
||||
|
||||
|
@ -17,7 +17,7 @@ order: 13
|
||||
| --------- | ------- | -------- | ------------------------- | --------------------- |
|
||||
| action | string | false | 操作类型,默认值为 update |
|
||||
| data | unknown | false | 入栈的数据 |
|
||||
| stackType | 'redo' | 'undo' | false | 入栈类型,默认为 redo |
|
||||
| stackType | 'redo' / 'undo' | false | 入栈类型,默认为 undo |
|
||||
|
||||
## getUndoStack()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: TreeGraph Functions
|
||||
order: 5
|
||||
order: 4
|
||||
---
|
||||
|
||||
### data()
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: TreeGraph 实例方法
|
||||
order: 5
|
||||
order: 4
|
||||
---
|
||||
|
||||
### data()
|
||||
|
@ -127,7 +127,7 @@ Users are welcome to join the **G6 Communication Group** or **G6 Communication G
|
||||
|
||||
Please let us know what you are you going to help. Do check out <a href='https://github.com/antvis/g6/issues' target='_blank'>issues</a> for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our <a href='https://github.com/antvis/g6/blob/master/CONTRIBUTING.md' target='_blank'>Contributing Guide</a>.
|
||||
To become a contributor, please follow our <a href='https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.md' target='_blank'>Contributing Guide</a>.
|
||||
|
||||
## License
|
||||
|
||||
|
@ -128,7 +128,7 @@ graph.render();
|
||||
|
||||
请让我们知道您要解决或贡献什么,所以在贡献之前请先提交 <a href='https://github.com/antvis/g6/issues' target='_blank'>issues</a> 描述 bug 或建议。
|
||||
|
||||
成为一个贡献者前请阅读 <a href='https://github.com/antvis/g6/blob/master/CONTRIBUTING.zh-CN.md' target='_blank'>代码贡献规范</a>。
|
||||
成为一个贡献者前请阅读 <a href='https://github.com/antvis/G6/blob/master/packages/g6/CONTRIBUTING.zh-CN.md' target='_blank'>代码贡献规范</a>。
|
||||
|
||||
## License
|
||||
|
||||
|
@ -197,8 +197,8 @@ G6.registerNode(
|
||||
const tooltip = new G6.Tooltip({
|
||||
// offsetX and offsetY include the padding of the parent container
|
||||
// offsetX 与 offsetY 需要加上父容器的 padding
|
||||
offsetX: 140 + 10,
|
||||
offsetY: 100 + 10,
|
||||
offsetX: 10,
|
||||
offsetY: 10,
|
||||
// the types of items that allow the tooltip show up
|
||||
// 允许出现 tooltip 的 item 类型
|
||||
itemTypes: ['node'],
|
||||
|
@ -1,6 +1,6 @@
|
||||
import G6 from '@antv/g6';
|
||||
import AntVUtil from '@antv/util';
|
||||
|
||||
const Util = G6.Util;
|
||||
let showNodes = [];
|
||||
let showEdges = [];
|
||||
let curShowNodes = [];
|
||||
@ -308,7 +308,7 @@ G6.registerEdge(
|
||||
drawShape(cfg, group) {
|
||||
const self = this;
|
||||
let shapeStyle = self.getShapeStyle(cfg);
|
||||
shapeStyle = Util.mix(shapeStyle, {
|
||||
shapeStyle = AntVUtil.mix(shapeStyle, {
|
||||
opacity: 0,
|
||||
strokeOpacity: 0,
|
||||
});
|
||||
|
@ -538,8 +538,8 @@ const initGraph = (data) => {
|
||||
const tooltip = new G6.Tooltip({
|
||||
// offsetX and offsetY include the padding of the parent container
|
||||
// offsetX 与 offsetY 需要加上父容器的 padding
|
||||
offsetX: 140 + 10,
|
||||
offsetY: 100 + 10,
|
||||
offsetX: 20,
|
||||
offsetY: 30,
|
||||
// the types of items that allow the tooltip show up
|
||||
// 允许出现 tooltip 的 item 类型
|
||||
itemTypes: ['node'],
|
||||
|
@ -222,7 +222,8 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/8c2353b0-99a9-4a93-a5e1-3e7
|
||||
graph.get('container').style.background = '#000';
|
||||
graph.get('container').style.backgroundImage =
|
||||
'url("https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*G23iRqkiibIAAAAAAAAAAABkARQnAQ")';
|
||||
graph.get('container').style.backgroundSize = 'auto 100%';
|
||||
graph.get('container').style.backgroundSize = '500px 500px';
|
||||
graph.get('container').style.backgroundRepeat = 'no-repeat';
|
||||
|
||||
function scaleNodesPoints(nodes, edges, graphSize) {
|
||||
const size = graphSize[0] < graphSize[1] ? graphSize[0] : graphSize[1];
|
||||
|
@ -16,8 +16,8 @@ insertCss(`
|
||||
const tooltip = new G6.Tooltip({
|
||||
// offsetX and offsetY include the padding of the parent container
|
||||
// offsetX 与 offsetY 需要加上父容器的 padding
|
||||
offsetX: 140 + 10,
|
||||
offsetY: 100 + 10,
|
||||
offsetX: 30,
|
||||
offsetY: 30,
|
||||
// the types of items that allow the tooltip show up
|
||||
// 允许出现 tooltip 的 item 类型
|
||||
itemTypes: ['node', 'edge'],
|
||||
|
@ -16,8 +16,8 @@ insertCss(`
|
||||
const tooltip = new G6.Tooltip({
|
||||
// offsetX and offsetY include the padding of the parent container
|
||||
// offsetX 与 offsetY 需要加上父容器的 padding
|
||||
offsetX: 140 + 10,
|
||||
offsetY: 100 + 10,
|
||||
offsetX: 30,
|
||||
offsetY: 30,
|
||||
// the types of items that allow the tooltip show up
|
||||
// 允许出现 tooltip 的 item 类型
|
||||
itemTypes: ['node', 'edge'],
|
||||
|
@ -195,8 +195,10 @@ G6.registerNode(
|
||||
});
|
||||
image.animate(
|
||||
(ratio) => {
|
||||
const matrix = Util.mat3.create();
|
||||
const toMatrix = Util.transform(matrix, [['r', ratio * Math.PI * 2]]);
|
||||
const toMatrix = Util.transform(
|
||||
[1, 0, 0, 0, 1, 0, 0, 0, 1],
|
||||
[['r', ratio * Math.PI * 2]],
|
||||
);
|
||||
return {
|
||||
matrix: toMatrix,
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ const width = container.scrollWidth;
|
||||
const height = container.scrollHeight || 500;
|
||||
|
||||
const toolbar = new G6.ToolBar({
|
||||
position: { x: 130, y: 70 },
|
||||
position: { x: 10, y: 10 },
|
||||
});
|
||||
|
||||
const graph = new G6.Graph({
|
||||
|
@ -1,5 +1,5 @@
|
||||
window.g6 = require('../g6/es'); // import the source for debugging
|
||||
// window.g6 = require('@antv/g6'); // import the package for webworker
|
||||
// window.g6 = require('../g6/es'); // import the source for debugging
|
||||
window.g6 = require('@antv/g6/dist/g6.min.js'); // import the package for webworker
|
||||
window.insertCss = require('insert-css');
|
||||
window.Chart = require('@antv/chart-node-g6');
|
||||
window.AntVUtil = require('@antv/util');
|
||||
|
@ -233,7 +233,7 @@ module.exports = {
|
||||
zh: '图布局 Graph Layout',
|
||||
en: 'Graph Layout',
|
||||
},
|
||||
order: 1,
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
slug: 'api/graphFunc',
|
||||
@ -241,7 +241,7 @@ module.exports = {
|
||||
zh: 'Graph 实例方法',
|
||||
en: 'Graph Functions',
|
||||
},
|
||||
order: 2,
|
||||
order: 1,
|
||||
},
|
||||
{
|
||||
slug: 'api/treeGraphLayout',
|
||||
@ -249,10 +249,10 @@ module.exports = {
|
||||
zh: '树图布局 TreeGraph Layout',
|
||||
en: 'TreeGraph Layout',
|
||||
},
|
||||
order: 4,
|
||||
order: 5,
|
||||
},
|
||||
{
|
||||
slug: 'api/items',
|
||||
slug: 'api/Items',
|
||||
title: {
|
||||
zh: '元素方法和配置',
|
||||
en: 'Item Functions & Options',
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/g6-site",
|
||||
"version": "4.1.3",
|
||||
"version": "4.1.7",
|
||||
"description": "G6 sites deployed on gh-pages",
|
||||
"keywords": [
|
||||
"antv",
|
||||
@ -34,8 +34,8 @@
|
||||
"dependencies": {
|
||||
"@antv/chart-node-g6": "^0.0.3",
|
||||
"@antv/util": "^2.0.9",
|
||||
"@antv/g6": "^4.1.3",
|
||||
"@antv/gatsby-theme-antv": "^1.0.5",
|
||||
"@antv/g6": "^4.1.7",
|
||||
"@antv/gatsby-theme-antv": "1.0.6",
|
||||
"gatsby": "^2.24.40",
|
||||
"gh-pages": "^2.1.1",
|
||||
"typedoc": "^0.17.6",
|
||||
@ -43,7 +43,8 @@
|
||||
"@types/react": "^16.9.35",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"react-i18next": "^11.1.0",
|
||||
"@ant-design/icons": "^4.0.6"
|
||||
"@ant-design/icons": "^4.0.6",
|
||||
"typescript": "^3.6.5"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "^16.9.35"
|
||||
|
Loading…
Reference in New Issue
Block a user