const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
];
};
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
['M', x, y - 2 * r + 2],
['L', x, y - 2],
];
};
const getIcon = function getIcon(cfg) {
if (cfg.hasChildren && cfg.collapsed === undefined) {
return EXPAND_ICON
} else {
return cfg.collapsed ? EXPAND_ICON : COLLAPSE_ICON
}
}
drawGqTree(data) {
G6.registerNode('icon-node', {
options: {
size: [60, 20],
stroke: '#91d5ff',
fill: '#fff',
},
draw(cfg, group) {
const styles = this.getShapeStyle(cfg);
const {labelCfg = {}} = cfg;
const w = styles.width;
const h = styles.height;
const keyShape = group.addShape('rect', {
attrs: {
...styles,
},
});
if (cfg.hasChildren) {
group.addShape('marker', {
attrs: {
x: 66,
y: 6,
r: 6,
stroke: '#128BED',
fill: '#fff',
cursor: 'pointer',
symbol: getIcon(cfg),
click: function (params) {
// console.log(params)
}
},
name: 'collapse-icon'
})
}
if (cfg.name) {
/** 判断文字位置,折行等 **/
let textY;
let content = cfg.name;
if (cfg.name.length < 8) {
textY = 6
} else {
textY = 32 - h / 2
}
if (cfg.name.length > 8 && cfg.name.length <= 16) {
content = content.slice(0, 8) + '\n' + content.slice(8)
} else if (cfg.name.length > 16) {
content = content.slice(0, 8) + '\n' + content.slice(8, 16) + '...'
}
/**添加节点名称**/
group.addShape('text', {
attrs: {
...labelCfg.style,
text: content,
textAlign: 'center',
x: 60 - w / 2,
y: textY,
},
});
if(cfg.depth>0){ //为0是为根部节点
if(cfg.shouldCapi){
group.addShape('rect', {
attrs: {
...labelCfg.style,
x: -60.5,
y: -34,
width: 121,
radius: [2, 2, 0, 0],
height: 16,
fill: "#128BED",
},
});
}
/**认缴金额信息**/
group.addShape('text', {
attrs: {
fill: '#ffffff',
fontSize: 10,
text:cfg.shouldCapi ? '认缴' + ' '+ cfg.shouldCapi +'万元' : "",
textAlign: 'left',
x: -58,
y: -21,
},
});
/**持股比例信息**/
group.addShape('text', {
attrs: {
fill: '#128BED',
fontSize: 10,
text: cfg.leftText + ' '+cfg.percent,
textAlign: 'left',
x: -58,
y: 32,
},
});
}
}
return keyShape;
},
update: undefined,
},
'rect',
);
// const lineDash = [4, 2, 1, 2];
G6.registerEdge('flow-line', {
draw(cfg, group) {
const startPoint = cfg.startPoint;
const endPoint = cfg.endPoint;
const {style} = cfg;
let isEnt;
if(cfg.targetNode._cfg.model.showDirection === "in"){
isEnt = true
}
if(isEnt){
const shape = group.addShape('path', {
attrs: {
stroke: style.stroke,
endArrow: style.reverseArrow,
path: [
['M', startPoint.x, startPoint.y],
['L', endPoint.x / 2 + (1 / 2) * startPoint.x, startPoint.y],
['L', endPoint.x / 2 + (1 / 2) * startPoint.x, endPoint.y],
['L', endPoint.x -10, endPoint.y],
],
},
});
return shape;
}
const shape = group.addShape('path', {
attrs: {
stroke: style.stroke,
endArrow: style.endArrow,
path: [
['M', startPoint.x + 60, startPoint.y],
['L', endPoint.x / 2 + (1 / 2) * startPoint.x, startPoint.y],
['L', endPoint.x / 2 + (1 / 2) * startPoint.x, endPoint.y],
['L', endPoint.x - 60, endPoint.y],
],
},
});
return shape;
},
});
//增加节点动画
// lineDash array
const defaultStateStyles = {
hover: {
stroke: '#3d8be6',
lineWidth: 1.6,
},
};
const defaultNodeStyle = {
fill: '#fff',
stroke: '#3d8be6',
radius: 2,
lineWidth: 1,
};
const defaultEdgeStyle = {
stroke: '#d6d6d6',
endArrow: {
path: "M 0,0 L 8, 3 L 8,0 L 8, -3 Z",
fill: '#3d8be6',
stroke: '#3d8be6',
// d: -20,
},
reverseArrow: {
path: 'M 8,0 L 0, 3 L 0,0 L 0, -3 Z',
fill: '#3d8be6',
stroke: '#3d8be6',
d: -60,
}
};
const defaultLayout = {
type: 'compactBox',
direction: 'LR', //V 垂直分布 H 水平分布
getId: function getId(d) {
return d.id;
},
getHeight: function getHeight() {
return 16;
},
getWidth: function getWidth() {
return 70;
},
getVGap: function getVGap() {
return 40;
},
getHGap: function getHGap() {
return 70;
},
};
const defaultLabelCfg = {
style: {
fill: '#000',
fontSize: 11,
},
};
const container = document.getElementById('container');
const width = container.scrollWidth;
const height = document.body.clientHeight -240;
console.log("获取的高度" + height);
const graph = new G6.TreeGraph({
container: 'container',
width,
height,
linkCenter: true,
modes: {
default: ['drag-canvas', 'zoom-canvas'],
},
defaultNode: {
type: 'icon-node',
size: [120, 40],
style: defaultNodeStyle,
labelCfg: defaultLabelCfg,
},
defaultEdge: {
type: 'flow-line',
style: defaultEdgeStyle,
},
nodeStateStyles: defaultStateStyles,
edgeStateStyles: defaultStateStyles,
layout: defaultLayout,
});
graph.data(data);
graph.render();
graph.fitCenter();
graph.on('node:mouseenter', (evt) => {
const node = evt.item;
const edges = node.getEdges();
edges.forEach((edge) => graph.setItemState(edge, 'running', true));
});
//
graph.on('node:mouseleave', (evt) => {
const node = evt.item;
const edges = node.getEdges();
edges.forEach((edge) => graph.setItemState(edge, 'running', false));
});
graph.on('node:click', async (evt) => {
let {item, target} = evt;
let targetType = target.get('type');
const name = target.get('name');
const model = item.getModel();
if(targetType === 'marker'){
if (target.attr('symbol') === EXPAND_ICON) { //判断点击为'+'号
if (name === 'collapse-icon') {
if (!model.children) {
model.children = [];
}
let params = {
type: model.showDirection,
name: model.name
};
let result = await PlantformService.getInvestRelationSearch(params);
if (result.message.code === 0) {
if (result.data && result.data.children) {
result.data.children.forEach((item, index) => {
//beInvestFlag type为in时判断 beInvestFlag 是否有子节点
if (model.showDirection === 'in') {
if (item.properties.beInvestFlag === "true") {
item.hasChildren = true
} else {
item.hasChildren = false
}
} else if (model.showDirection === 'out') {
if (item.properties.investFlag === "true") {
item.hasChildren = true
} else {
item.hasChildren = false
}
}
item.name = item.properties.name;
item.shouldCapi = item.properties.shouldCapi;
item.oldId = item.id; //保留原本id,以防查询使用
let date = new Date().getTime();
const reserveId = `${date}${Math.random()}`
item.id = reserveId
// item.percent = (item.properties.stockPercent.substring(0, 4)) * 100 + "%";
item.percent = accMul(item.properties.stockPercent.substring(0, 6),100) + "%";
item.showDirection = params.type;
item.leftText = '股比'
});
model.children = result.data.children;
}
}
const icon = item.get('group').find(element => element.get('name') === 'collapse-icon');
model.collapsed = false;
icon.attr('symbol', COLLAPSE_ICON);
graph.focusItem(model.id);
graph.updateChild(model, model.id);
}
} else if (target.attr('symbol') === COLLAPSE_ICON) {
model.children = [];
const icon = item.get('group').find(element => element.get('name') === 'collapse-icon');
model.collapsed = true;
icon.attr('symbol', EXPAND_ICON);
graph.focusItem(model.id);
graph.updateChild(model, model.id);
}
}else if (targetType === 'text'){ // 点击节点
alert(model.name)
}
});
if (typeof window !== 'undefined')
window.onresize = () => {
if (!graph || graph.get('destroyed')) return;
if (!container || !container.scrollWidth || !container.scrollHeight) return;
graph.changeSize(container.scrollWidth, container.scrollHeight);
};
},
关于AntV-G6+VUE实现股权图谱
最新推荐文章于 2023-07-20 16:05:15 发布