@kgdata/visualgraph
Version:
visualgraph
438 lines (416 loc) • 11.4 kB
text/typescript
import {
computeNodeSize,
computeNodesWeight,
getNodeWeight,
} from './graphCount';
const strSlice = (str: string = '', maxLen: number) => {
const len = str.length;
if (!str || len <= maxLen) return str;
return str.slice(0, maxLen) + '...';
};
export function formatNodes(
nodes: any[],
config: { size: number; force: number; fontSize: number } = {
fontSize: 16,
force: 30,
size: 40,
},
) {
return nodes.map((item) => {
const label = strSlice(item.name, 6);
return {
...item,
// 为节点是否展开收起初始化字段值
isExpend: item?.isExpend === undefined ? false : item.expend,
label,
color: item.color || '#333',
style: {
label: {
value: label,
offset: [0, 12],
fontSize: config.fontSize,
},
keyshape: {
size: config.size,
stroke: item.color ? item.color : '#333',
fill: item.color ? item.color : '#333',
fillOpacity: 1,
},
},
};
});
}
export function formatLinks(
nodes: any[],
config: {
fontSize: number;
isShow: boolean;
stroke?: string;
isShowLink: boolean;
} = {
stroke: '#111',
fontSize: 0,
isShow: true,
isShowLink: true,
},
) {
return nodes.map((item) => {
const label = strSlice(item.ooName, 6);
return {
...item,
label,
style: {
...(item.style || {}),
label: {
fill: '#111',
value: config?.isShowLink && config?.isShow ? label : '',
fontSize: config.fontSize,
visible: config?.isShowLink,
},
keyshape: {
endArrow: true,
startArrow: item.reverse,
stroke: config.stroke,
opacity: config?.isShow ? 1 : 0,
},
},
};
});
}
// v2.3
// export function formatVisualPostData(nodes: any[]) {
// console.log('nodes:', nodes)
// return nodes.reduce((pre, curr) => {
// const { nodeType, expresses = [], objectId, id } = curr;
// let ret: any[] = [];
// if (nodeType === 'entity') {
// ret = [{ dataType: 'string', isNumber: false, key: 'key', sign: '=', value: curr.originId }];
// }
// expresses.forEach((express: any) => {
// ret.push({
// ...express,
// objectId,
// });
// });
// return {
// ...pre,
// [id]: ret,
// };
// }, {});
// }
export function formatVisualPostData(
nodes: any[],
commentMap: Record<string, any> = {},
) {
const ret: { key: any; nodePropList: any }[] = [];
nodes.forEach((node) => {
const nodeType = node.nodeType;
const typemap =
nodeType === 'visual'
? {
type: '1',
keyType: '1',
}
: {
type: '0',
keyType: '0',
};
const nodeProps =
nodeType === 'visual' && node?.expresses
? node?.expresses.map(
(express: {
dataType: string;
value: any;
id: string;
propId: string;
}) => {
return {
type: '1',
keyType: '2',
// key: node.objectId,
key: express.propId,
...express,
commentList: commentMap[express.id] || [],
value:
express.dataType === 'date'
? express.value.valueOf()
: express.value,
};
},
)
: [];
const item = {
key: node.id,
nodePropList: [
{
...typemap,
key: node.objectId,
},
...nodeProps,
],
};
ret.push(item);
});
return ret;
}
export function formatVisualLinkData(links: any[]) {
const ret: any[] = [];
links.forEach((link) => {
const typemap = {
type: '2',
keyType: '1',
};
const {
source,
target,
dimension = '1',
reverse,
commentOptionsMap,
expresses,
} = link;
Object.keys(commentOptionsMap).forEach((key) => {
const relationCommentDetail = commentOptionsMap[key];
// express - 关系说明
const express = expresses[key] || [];
const visualLink = {
source,
target,
dimension,
reverse,
linkPropList: express.reduce(
(
pre: any,
ex: { propId: any; value: any; dataType: any; compareChar: any },
) => {
const linkProp = {
type: '2',
keyType: '2',
key: ex.propId,
...ex,
};
return [...pre, linkProp];
},
[
{
...typemap,
key: relationCommentDetail.relationId,
// ...relationCommentDetail
},
],
),
};
ret.push(visualLink);
});
});
return ret;
}
export const generateNodeId = () => `node${new Date().getTime()}`;
// import { formatNodes, formatLinks } from "@/utils/graphFns/formatGraphData";
export function getMax(
data: Record<string, { value: number; name: string } | { value: number }>,
) {
let max = 0;
Object.keys(data).forEach((key) => {
if (data[key].value > max) {
max = data[key].value;
}
});
return max;
}
export function getPercent(value: number, max: number) {
return Math.floor((value / max) * 100);
}
export function formatOptions(
list: { ooId: any; ooName: any; name: any; color: string }[],
) {
const ret: { value: any; label: any; color: string | null }[] = [];
const map = {};
list.forEach(
(item: { ooId: any; ooName: any; name: any; color: string | null }) => {
if (!map[item.ooId]) {
map[item.ooId] = true;
ret.push({
...item,
value: item.ooId,
label: item.ooName || item.name,
color: item.color || '#333',
});
}
},
);
return ret;
}
export function formatChecked(list: { ooId: any; ooName: any; name: any }[]) {
return list.map((item) => item.ooId);
}
/**
*
* @param dataSource 数据源
* @param checked 选中项目
* @param optionsLength 选项长度
* @param config 节点、样式配置
* @param closedNodeIds 用于收起的节点
* @returns
*/
export function filterDataSource(
dataSource: any,
checked: { edges: string[]; nodes: string[] },
optionsLength: { nodes: number; edges: number },
config: any,
closedNodeIds: string[] = [],
) {
const nodesCount = dataSource?.nodes?.length || 0;
const edgesCount = dataSource?.edges?.length || 0;
if (nodesCount === 0) {
return dataSource;
}
// 过滤隐藏的节点
const hiddenNodeIds =
checked.nodes.length === 0
? []
: dataSource.nodes
.filter((node: { ooId: string }) => {
return !checked.nodes.includes(node.ooId);
})
.map((node: { id: any }) => node.id);
const hiddenNodes = Array.from(new Set([...hiddenNodeIds, ...closedNodeIds]));
const isVisible = (id: string) => !hiddenNodes.includes(id);
// 有效节点
const activeNodes = dataSource.nodes.filter((node: { ooId: string }) => {
const isFullOrNill =
checked.nodes.length === optionsLength.nodes ||
checked.nodes.length === 0;
return checked.nodes.includes(node.ooId) || isFullOrNill;
});
// 有效边
const activeEdges = !edgesCount
? []
: dataSource.edges.filter(
(edge: {
ooId: string;
ooName: string;
source: string;
target: string;
}) => {
// console.log('edge:', edge);
const isFullOrNill =
checked.edges.length === optionsLength.edges ||
checked.edges.length === 0;
const isActiveEdge =
!hiddenNodes.includes(edge.source) &&
!hiddenNodes.includes(edge.target);
return (
(checked.edges.includes(edge.ooId || edge.ooName) ||
isFullOrNill) &&
isActiveEdge
);
},
);
const nodesWeight = config.isHotAnalysis
? computeNodesWeight(activeEdges)
: {};
const nodes = activeNodes.map(
(node: {
id: string;
name: string;
ooId: string;
ooName: string;
color: string;
isExpend: boolean;
style: { keyshape: any; label: any };
}) => {
const retNode = {
id: node.id,
name: node.name,
ooName: node.ooName,
color: node.color,
ooId: node.ooId,
isExpend: node.isExpend,
style: {
// ...node.style,
keyshape: {
...node.style.keyshape,
visible: isVisible(node.id),
fill: node.color,
stroke: node.color,
fillOpacity: 0.9,
strokeWidth: 0,
strokeOpacity: 0,
size: computeNodeSize(
100,
config.nodes.size,
getNodeWeight(node.id, nodesWeight),
1,
),
},
label: {
...node.style.label,
visible: isVisible(node.id),
fontSize: config.nodes.fontSize,
},
},
// status: {
// normal: {
// keyshape: {
// ...node.style.keyshape,
// visible: isVisible(node.id),
// fill: node.color,
// stroke: node.color,
// fillOpacity: 0.9,
// strokeWidth: 0,
// strokeOpacity: 0,
// size: computeNodeSize(100, config.nodes.size, getNodeWeight(node.id, nodesWeight), 1),
// },
// },
// selected: {
// keyshape: {
// ...node.style.keyshape,
// visible: isVisible(node.id),
// fillOpacity: 0.9,
// strokeWidth: 3,
// size: computeNodeSize(100, config.nodes.size, getNodeWeight(node.id, nodesWeight), 1),
// },
// },
// hover: {}
// }
};
return retNode;
},
);
const edges = activeEdges.map(
(edge: {
id: string;
source: string;
target: string;
ooId: string;
label: string;
ooName: string;
style: { keyshape: any; label: any };
}) => {
return {
id: edge.id,
source: edge.source,
target: edge.target,
label: edge.label || edge.ooName,
ooId: edge.ooId,
ooName: edge.ooName,
style: {
...edge.style,
keyshape: {
...edge.style.keyshape,
visible: config.edges?.isShow,
},
label: {
...edge.style.label,
fontSize: config.edges.fontSize,
value: config.edges?.isShowLink ? edge.label : '',
},
},
};
},
);
return {
edges,
nodes,
};
}