Skip to content

Commit

Permalink
refactor(graphin):add graphin-line shape
Browse files Browse the repository at this point in the history
  • Loading branch information
pomelo-nwu committed Jan 18, 2021
1 parent 228f530 commit 8fc761b
Showing 1 changed file with 160 additions and 109 deletions.
269 changes: 160 additions & 109 deletions packages/graphin/src/shape/graphin-line.ts
Original file line number Diff line number Diff line change
@@ -1,123 +1,174 @@
import G6, { IGroup, IShape, IEdge } from '@antv/g6';
import { isString } from '@antv/util';
// @ts-nocheck
import { Group } from '@antv/g-canvas';
import G6, { EdgeConfig, EdgeConfig } from '@antv/g6';

import { IUserEdge } from '../typings/type';
import { deepMix } from '@antv/util';
import { EdgeStyle } from '../typings/type';
import { setStatusStyle } from './utils';

export enum EnumNodeAndEdgeStatus {
NORMAL = 'normal',
SELECTED = 'selected',
HOVERED = 'hovered',
DISABLED = 'disabled',
}

export function removeDumpAttrs(attrs) {
Object.keys(attrs).forEach(key => {
if (attrs[key] === undefined) {
delete attrs[key];
}
});
return attrs;
}
export function parseLabel(json) {
const { value, ...others } = json;
const attrs = {
id: 'label',
x: 0,
y: 0,
text: value,
...others,
};
return removeDumpAttrs(attrs);
}

export function parseKeyShape(json) {
const { ...others } = json;
const attrs = {
id: 'keyshape',
...others,
};
return removeDumpAttrs(attrs);
}

export function parseHalo(json) {
const { ...others } = json;
const attrs = {
id: 'halo',
...others,
};
return removeDumpAttrs(attrs);
}

const parseAttr = (style, itemShapeName: string) => {
if (itemShapeName === 'keyshape') {
return parseKeyShape(style);
}
if (itemShapeName === 'halo') {
return parseKeyShape(style);
}
if (itemShapeName === 'label') {
return parseLabel(style);
}
return style;
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default () => {
G6.registerEdge(
'graphin-line',
{
options: {
style: {
stroke: 'rgb(239, 244, 255)',
opacity: 1,
labelCfg: {
fill: 'rgb(0, 0, 0)',
fontSize: 12,
},
},
status: {
selected: {
fill: 'rgb(239, 244, 255)',
},
hover: {
fill: 'rgb(239, 244, 255)',
},
},
},
G6.registerEdge('graphin-line', {
draw(cfg: EdgeConfig, group: Group) {
try {
const style = deepMix({}, cfg.style) as EdgeStyle;
/** 将初始化样式存储在model中 */

// eslint-disable-next-line no-underscore-dangle
cfg._initialStyle = { ...style };

const { label, halo, keyshape: keyShapeStyle } = style;

afterDraw(cfg: IUserEdge, group: IGroup, keyShape: IShape) {
const path = keyShape.attr('path');
const lineWidth = keyShape.attr('lineWidth');
const shape = group.addShape('path', {
const hasLabel = label.value;
const { startPoint, endPoint } = cfg;

const d = (keyShapeStyle?.lineWidth || 1) + 1;
// TODO:支持多边
const path = [
['M', startPoint.x, startPoint.y],
['L', endPoint.x, endPoint.y],
];

/** 光环 */
group.addShape('path', {
attrs: {
id: 'halo',
path,
lineWidth: lineWidth * 10,
// opacity: 0.1,
stroke: 'rgb(239, 244, 255)',
lineWidth: keyShapeStyle.lineWidth + 10,
...halo,
},
name: 'external-shape',
draggable: true,
name: 'halo',
visible: false,
});
shape.toBack();
},

setState(name: string, value: string, item: IEdge) {
const keyShape = item.getKeyShape();
const group = item.get('group');
const model = item.getModel() as IUserEdge;
const children = group.get('children');
if (!model.status || !model.status[name]) return;

const shape = children.find((element: any) => element.get('name') === 'external-shape');
if (value) {
// selected 状态显示边上的 shape
if (name === 'selected') {
shape.show();
}

// 是否有配置动画
const { animation, ...otherAttr } = model.status[name];
for (let key in otherAttr) {
const value = (otherAttr as any)[key];
keyShape.attr(key, value);
}
/** 主路径 */
const key = group.addShape('path', {
attrs: {
id: 'keyshape',
path,
endArrow: {
d: -d / 2,
path: `M 0,0 L ${d},${d / 2} L ${d},-${d / 2} Z`,
},
...keyShapeStyle,
},
draggable: true,
name: 'keyshape',
});

if (animation) {
const { delay = 0, duration = 3000, easing = 'easeLinear', repeat = true } = animation;
let index = 0;
keyShape.animate(
() => {
index++;
if (index > 9) {
index = 0;
}

const conf = {
lineDash: [3, 3],
lineDashOffset: -index,
};

return conf;
},
{
easing,
delay,
repeat,
duration,
},
);
}
} else {
shape.hide();
keyShape.stopAnimate();
keyShape.attr('lineDash', null);

// 恢复到原来的样式
const originStyle = item.getOriginStyle() as any;
for (let key in originStyle) {
const currentShape = children.find((element: any) => element.get('name') === key);
if (currentShape) {
for (let value in originStyle[key]) {
const currentValue = originStyle[key][value];
if (isString(currentValue)) {
currentShape.attr(value, currentValue);
}
}
/** 标签 */
if (hasLabel) {
const { value, ...others } = label;
const labelShape = group.addShape('text', {
attrs: {
id: 'label',
x: 0,
y: 0,
text: value,
...others,
},
draggable: true,
name: 'label',
});
/** 处理标签自动旋转问题 */
labelShape.rotate(
endPoint.x - startPoint.x === 0
? Math.PI / 2
: Math.atan((endPoint.y - startPoint.y) / (endPoint.x - startPoint.x)),
);
labelShape.translate((startPoint.x + endPoint.x) / 2, (startPoint.y + endPoint.y) / 2);
}
return key;
} catch (error) {
console.error(error);
}
},
setState(name: EnumNodeAndEdgeStatus, value: string, item: EdgeConfig) {
if (!name) return;
const model = item.getModel() as EdgeConfig;
const shapes = item.getContainer().get('children'); // 顺序根据 draw 时确定
const initStateStyle = deepMix({}, model.style.status);

const initialStyle = item.getModel()._initialStyle as EdgeStyle;

const status = item._cfg?.states || [];

try {
Object.keys(initStateStyle).forEach(statusKey => {
if (name === statusKey) {
if (value) {
setStatusStyle(shapes, initStateStyle[statusKey], parseAttr); // 匹配到status就改变
} else {
setStatusStyle(shapes, initialStyle, parseAttr); // 没匹配到就重置
status.forEach(key => {
// 如果cfg.status中还有其他状态,那就重新设置回来
setStatusStyle(shapes, initStateStyle[key], parseAttr);
});
}
}
}
},
afterUpdate(cfg: IUserEdge, item: IEdge) {
const keyShape = item.getKeyShape();
const group = item.get('group');
const shape = group.get('children').find((element: any) => element.get('name') === 'external-shape');
if (shape) {
shape.attr('path', keyShape.attr('path'));
}
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any,
'line',
);
});
} catch (error) {
console.error(error);
}
},
});
};

0 comments on commit 8fc761b

Please sign in to comment.