mirror of
https://gitee.com/antv/g6.git
synced 2024-12-02 11:48:29 +08:00
feat: support use alias import files
This commit is contained in:
parent
fc6f66ed32
commit
831c5df4af
20
jest.config.js
Normal file
20
jest.config.js
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
module.exports = {
|
||||
runner: 'jest-electron/runner',
|
||||
testEnvironment: 'jest-electron/environment',
|
||||
preset: 'ts-jest',
|
||||
collectCoverage: false,
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.{ts,js}',
|
||||
'!**/node_modules/**',
|
||||
'!**/vendor/**'
|
||||
],
|
||||
testRegex: '/tests/.*-spec\\.ts?$',
|
||||
moduleDirectories: [ 'node_modules', 'src' ],
|
||||
moduleFileExtensions: [ 'js', 'ts', 'json' ],
|
||||
moduleNameMapper: {
|
||||
'@g6/(.*)': '<rootDir>/src/$1',
|
||||
'@g6/types': '<rootDir>/types'
|
||||
}
|
||||
};
|
14
package.json
14
package.json
@ -26,7 +26,7 @@
|
||||
"clean": "rimraf esm lib dist",
|
||||
"lint": "lint-staged",
|
||||
"test": "jest",
|
||||
"test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/behavior/index-spec.ts",
|
||||
"test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/graph/controller/mode-spec.ts",
|
||||
"coverage": "jest --coverage",
|
||||
"ci": "run-s build coverage",
|
||||
"doc": "rimraf apis && typedoc",
|
||||
@ -81,18 +81,6 @@
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"runner": "jest-electron/runner",
|
||||
"testEnvironment": "jest-electron/environment",
|
||||
"preset": "ts-jest",
|
||||
"collectCoverage": false,
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.{ts,js}",
|
||||
"!**/node_modules/**",
|
||||
"!**/vendor/**"
|
||||
],
|
||||
"testRegex": "/tests/.*-spec\\.ts?$"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/antvis/g6"
|
||||
|
1
src/graph/controller/index.ts
Normal file
1
src/graph/controller/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Mode } from './mode'
|
175
src/graph/controller/mode.ts
Normal file
175
src/graph/controller/mode.ts
Normal file
@ -0,0 +1,175 @@
|
||||
import each from '@antv/util/lib/each'
|
||||
import isArray from '@antv/util/lib/is-array'
|
||||
import isString from '@antv/util/lib/is-string'
|
||||
import Behavior from '@g6/behavior/behavior'
|
||||
import { IGraph, IMode, IModeType } from '@g6/interface/graph';
|
||||
import { IBehavior } from 'types';
|
||||
|
||||
export default class Mode {
|
||||
private graph: IGraph
|
||||
/**
|
||||
* modes = {
|
||||
* default: [ 'drag-node', 'zoom-canvas' ],
|
||||
* edit: [ 'drag-canvas', {
|
||||
* type: 'brush-select',
|
||||
* trigger: 'ctrl'
|
||||
* }]
|
||||
* }
|
||||
*
|
||||
* @private
|
||||
* @type {IMode}
|
||||
* @memberof Mode
|
||||
*/
|
||||
public modes: IMode
|
||||
|
||||
/**
|
||||
* mode = 'drag-node'
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
* @memberof Mode
|
||||
*/
|
||||
public mode: string
|
||||
private currentBehaves: IBehavior[]
|
||||
constructor(graph: IGraph) {
|
||||
this.graph = graph
|
||||
this.modes = graph.get('modes') || {
|
||||
default: []
|
||||
}
|
||||
this.formatModes()
|
||||
|
||||
this.mode = graph.get('defaultMode') || 'default'
|
||||
this.currentBehaves = []
|
||||
|
||||
this.setMode(this.mode)
|
||||
}
|
||||
|
||||
private formatModes() {
|
||||
const modes = this.modes;
|
||||
each(modes, mode => {
|
||||
each(mode, (behavior, i) => {
|
||||
if (isString(behavior)) {
|
||||
mode[i] = { type: behavior };
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private setBehaviors(mode: string) {
|
||||
const graph = this.graph;
|
||||
const behaviors = this.modes[mode];
|
||||
const behaves: IBehavior[] = [];
|
||||
let behave: IBehavior;
|
||||
each(behaviors, behavior => {
|
||||
const BehaviorInstance = Behavior.getBehavior(behavior.type)
|
||||
if (!BehaviorInstance) {
|
||||
return;
|
||||
}
|
||||
behave = new BehaviorInstance(behavior);
|
||||
if(behave) {
|
||||
behave.bind(graph)
|
||||
behaves.push(behave);
|
||||
}
|
||||
});
|
||||
this.currentBehaves = behaves;
|
||||
}
|
||||
|
||||
private mergeBehaviors(modeBehaviors: IModeType[], behaviors: IModeType[]): IModeType[] {
|
||||
each(behaviors, behavior => {
|
||||
if (modeBehaviors.indexOf(behavior) < 0) {
|
||||
if (isString(behavior)) {
|
||||
behavior = { type: behavior };
|
||||
}
|
||||
modeBehaviors.push(behavior);
|
||||
}
|
||||
});
|
||||
return modeBehaviors;
|
||||
}
|
||||
|
||||
private filterBehaviors(modeBehaviors: IModeType[], behaviors: IModeType[]): IModeType[] {
|
||||
const result: IModeType[] = [];
|
||||
modeBehaviors.forEach(behavior => {
|
||||
let type: string = ''
|
||||
if(isString(behavior)) {
|
||||
type = behavior
|
||||
} else {
|
||||
type = behavior.type
|
||||
}
|
||||
if (behaviors.indexOf(type) < 0) {
|
||||
result.push(behavior);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public setMode(mode: string): Mode {
|
||||
const modes = this.modes;
|
||||
const graph = this.graph;
|
||||
const behaviors = modes[mode];
|
||||
if (!behaviors) {
|
||||
return;
|
||||
}
|
||||
graph.emit('beforemodechange', { mode });
|
||||
|
||||
each(this.currentBehaves, behave => {
|
||||
behave.unbind(graph);
|
||||
});
|
||||
|
||||
this.setBehaviors(mode);
|
||||
|
||||
graph.emit('aftermodechange', { mode });
|
||||
this.mode = mode;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增加或删除 Behavior
|
||||
*
|
||||
* @param {IModeType[]} behaviors
|
||||
* @param {(IModeType[] | IModeType)} modes
|
||||
* @param {boolean} isAdd
|
||||
* @returns {Mode}
|
||||
* @memberof Mode
|
||||
*/
|
||||
public manipulateBehaviors(behaviors: IModeType[], modes: IModeType[] | IModeType, isAdd: boolean): Mode {
|
||||
const self = this
|
||||
if(!isArray(behaviors)) {
|
||||
behaviors = [ behaviors ]
|
||||
}
|
||||
|
||||
if(isArray(modes)) {
|
||||
each(modes, mode => {
|
||||
if (!self.modes[mode]) {
|
||||
if (isAdd) {
|
||||
self.modes[mode] = [].concat(behaviors);
|
||||
}
|
||||
} else {
|
||||
if (isAdd) {
|
||||
self.modes[mode] = this.mergeBehaviors(self.modes[mode], behaviors);
|
||||
} else {
|
||||
self.modes[mode] = this.filterBehaviors(self.modes[mode], behaviors);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
let currentMode: string = ''
|
||||
if(!modes) {
|
||||
currentMode = this.mode
|
||||
}
|
||||
|
||||
if (isAdd) {
|
||||
self.modes[currentMode] = this.mergeBehaviors(self.modes[currentMode], behaviors);
|
||||
} else {
|
||||
self.modes[currentMode] = this.filterBehaviors(self.modes[currentMode], behaviors);
|
||||
}
|
||||
|
||||
self.setMode(this.mode)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
13
src/graph/graph.ts
Normal file
13
src/graph/graph.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import EventEmitter from '@antv/event-emitter'
|
||||
import { IGraph, IGraphOptions } from '@g6/interface/graph';
|
||||
|
||||
export default class Graph extends EventEmitter implements IGraph {
|
||||
private _cfg: IGraphOptions
|
||||
constructor(cfg: IGraphOptions) {
|
||||
super()
|
||||
this._cfg = cfg
|
||||
}
|
||||
public get(key: string) {
|
||||
|
||||
}
|
||||
}
|
0
src/graph/tree-graph.ts
Normal file
0
src/graph/tree-graph.ts
Normal file
@ -1,7 +1,147 @@
|
||||
import { G6Event } from '../../types'
|
||||
import EventEmitter from '@antv/event-emitter';
|
||||
import { G6Event, IModelStyle, IShapeStyle } from '@g6/types'
|
||||
|
||||
export interface IGraph {
|
||||
on: (event: G6Event, handler: () => void) => void;
|
||||
off: (event: G6Event, handler: () => void) => void;
|
||||
export interface IModeOption {
|
||||
type: string;
|
||||
}
|
||||
|
||||
export type IModeType = string | IModeOption
|
||||
|
||||
export interface IMode {
|
||||
default: IModeType[]
|
||||
[key: string]: IModeType[]
|
||||
}
|
||||
|
||||
export interface ILayoutOptions {
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface IGraphOptions {
|
||||
/**
|
||||
* 图的 DOM 容器,可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象
|
||||
*/
|
||||
container: string | HTMLElement;
|
||||
/**
|
||||
* 指定画布宽度,单位为 'px'
|
||||
*/
|
||||
width: number;
|
||||
/**
|
||||
* 指定画布高度,单位为 'px'
|
||||
*/
|
||||
height: number;
|
||||
/**
|
||||
* 渲染引擎,支持canvas和svg。
|
||||
*/
|
||||
renderer?: 'canvas' | 'svg';
|
||||
|
||||
fitView?: boolean;
|
||||
|
||||
layout?: ILayoutOptions;
|
||||
|
||||
/**
|
||||
* 图适应画布时,指定四周的留白。
|
||||
* 可以是一个值, 例如:fitViewPadding: 20
|
||||
* 也可以是一个数组,例如:fitViewPadding: [20, 40, 50,20]
|
||||
* 当指定一个值时,四边的边距都相等,当指定数组时,数组内数值依次对应 上,右,下,左四边的边距。
|
||||
*/
|
||||
fitViewPadding?: number[] | number;
|
||||
/**
|
||||
* 各种元素是否在一个分组内,决定节点和边的层级问题,默认情况下所有的节点在一个分组中,所有的边在一个分组中,当这个参数为 false 时,节点和边的层级根据生成的顺序确定。
|
||||
* 默认值:true
|
||||
*/
|
||||
groupByTypes?: boolean;
|
||||
|
||||
groupStyle?: {
|
||||
style: {
|
||||
[key: string]: IShapeStyle
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 当图中元素更新,或视口变换时,是否自动重绘。建议在批量操作节点时关闭,以提高性能,完成批量操作后再打开,参见后面的 setAutoPaint() 方法。
|
||||
* 默认值:true
|
||||
*/
|
||||
autoPaint?: boolean;
|
||||
|
||||
/**
|
||||
* 设置画布的模式。详情可见G6中的Mode文档。
|
||||
*/
|
||||
modes?: IMode;
|
||||
|
||||
/**
|
||||
* 默认状态下节点的配置,比如 shape, size, color。会被写入的 data 覆盖。
|
||||
*/
|
||||
defaultNode?: {
|
||||
shape?: string,
|
||||
size?: string,
|
||||
color?: string,
|
||||
} & IModelStyle;
|
||||
|
||||
/**
|
||||
* 默认状态下边的配置,比如 shape, size, color。会被写入的 data 覆盖。
|
||||
*/
|
||||
defaultEdge?: {
|
||||
shape?: string,
|
||||
size?: string,
|
||||
color?: string,
|
||||
} & IModelStyle;
|
||||
|
||||
nodeStateStyles?: IModelStyle;
|
||||
|
||||
edgeStateStyles?: IModelStyle;
|
||||
|
||||
/**
|
||||
* 向 graph 注册插件。插件机制请见:plugin
|
||||
*/
|
||||
plugins?: any[];
|
||||
/**
|
||||
* 是否启用全局动画。
|
||||
*/
|
||||
animate?: boolean;
|
||||
|
||||
/**
|
||||
* 动画配置项,仅在animate为true时有效。
|
||||
*/
|
||||
animateCfg?: {
|
||||
/**
|
||||
* 回调函数,用于自定义节点运动路径。
|
||||
*/
|
||||
onFrame?: () => void | null;
|
||||
/**
|
||||
* 动画时长,单位为毫秒。
|
||||
*/
|
||||
duration?: number;
|
||||
/**
|
||||
* 动画动效。
|
||||
* 默认值:easeLinear
|
||||
*/
|
||||
easing?: string;
|
||||
};
|
||||
/**
|
||||
* 最小缩放比例
|
||||
* 默认值 0.2
|
||||
*/
|
||||
minZoom?: number;
|
||||
/**
|
||||
* 最大缩放比例
|
||||
* 默认值 10
|
||||
*/
|
||||
maxZoom?: number;
|
||||
/**
|
||||
* 像素比率
|
||||
* 默认值 1.0
|
||||
*/
|
||||
pixelRatio?: number;
|
||||
|
||||
groupType?: string;
|
||||
|
||||
/**
|
||||
* Edge 是否连接到节点中间
|
||||
*/
|
||||
linkCenter?: boolean;
|
||||
}
|
||||
|
||||
export interface IGraph extends EventEmitter {
|
||||
get: (key: string) => any;
|
||||
}
|
||||
|
||||
|
19
tests/unit/graph/controller/mode-spec.ts
Normal file
19
tests/unit/graph/controller/mode-spec.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Mode } from '../../../../src/graph/controller'
|
||||
import Graph from '../../../../src/graph/graph'
|
||||
import { IGraph, IGraphOptions } from '../../../../src/interface/graph';
|
||||
|
||||
describe('Mode Controller', () => {
|
||||
it('signle mode', () => {
|
||||
const cfg: IGraphOptions = {
|
||||
container: 'x',
|
||||
width: 200,
|
||||
height: 100
|
||||
}
|
||||
const graph: IGraph = new Graph(cfg)
|
||||
const modeController = new Mode(graph)
|
||||
expect(Object.keys(modeController.modes).length).toBe(1);
|
||||
expect(modeController.modes.default).not.toBe(undefined);
|
||||
expect(modeController.modes.default.length).toBe(0);
|
||||
expect(modeController.mode).toBe('default');
|
||||
})
|
||||
})
|
@ -11,7 +11,12 @@
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"],
|
||||
"types": ["jest"]
|
||||
"types": ["jest"],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@g6/*": ["./src/*"],
|
||||
"@g6/types": ["./types"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"typedocOptions": {
|
||||
|
Loading…
Reference in New Issue
Block a user