Files
supersonic/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/utils.ts

198 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ISemantic } from '../data';
import { SemanticNodeType } from '../enum';
import { TreeGraphData } from '@antv/g6-core';
export const typeConfigs = {
datasource: {
type: 'circle',
size: 10,
},
};
export const getDimensionChildren = (
dimensions: ISemantic.IDimensionItem[],
dataSourceNodeId: string,
limit: number = 999,
) => {
const dimensionChildrenList = dimensions.reduce(
(dimensionChildren: any[], dimension: ISemantic.IDimensionItem) => {
const { id } = dimension;
dimensionChildren.push({
...dimension,
nodeType: SemanticNodeType.DIMENSION,
legendType: dataSourceNodeId,
id: `${dataSourceNodeId}-${SemanticNodeType.DIMENSION}-${id}`,
uid: id,
style: {
lineWidth: 2,
fill: '#f0f7ff',
stroke: '#a6ccff',
},
});
return dimensionChildren;
},
[],
);
return dimensionChildrenList.slice(0, limit);
};
export const getMetricChildren = (
metrics: ISemantic.IMetricItem[],
dataSourceNodeId: string,
limit: number = 999,
) => {
const metricsChildrenList = metrics.reduce(
(metricsChildren: any[], metric: ISemantic.IMetricItem) => {
const { id } = metric;
metricsChildren.push({
...metric,
nodeType: SemanticNodeType.METRIC,
legendType: dataSourceNodeId,
id: `${dataSourceNodeId}-${SemanticNodeType.METRIC}-${id}`,
uid: id,
style: {
lineWidth: 2,
fill: '#f0f7ff',
stroke: '#a6ccff',
},
});
return metricsChildren;
},
[],
);
return metricsChildrenList.slice(0, limit);
};
export const formatterRelationData = (params: {
dataSourceList: ISemantic.IDomainSchemaRelaList;
limit?: number;
type?: SemanticNodeType;
showDataSourceId?: string[];
}): TreeGraphData[] => {
const { type, dataSourceList, limit, showDataSourceId } = params;
const relationData = dataSourceList.reduce(
(relationList: TreeGraphData[], item: ISemantic.IDomainSchemaRelaItem) => {
const { datasource, dimensions, metrics } = item;
const { id } = datasource;
const dataSourceNodeId = `${SemanticNodeType.DATASOURCE}-${id}`;
let childrenList = [];
if (type === SemanticNodeType.METRIC) {
childrenList = getMetricChildren(metrics, dataSourceNodeId, limit);
}
if (type === SemanticNodeType.DIMENSION) {
childrenList = getDimensionChildren(dimensions, dataSourceNodeId, limit);
}
if (!type) {
const dimensionList = getDimensionChildren(dimensions, dataSourceNodeId, limit);
const metricList = getMetricChildren(metrics, dataSourceNodeId, limit);
childrenList = [...dimensionList, ...metricList];
}
if (!showDataSourceId || showDataSourceId.includes(dataSourceNodeId)) {
relationList.push({
...datasource,
legendType: dataSourceNodeId,
id: dataSourceNodeId,
uid: id,
nodeType: SemanticNodeType.DATASOURCE,
size: 40,
children: [...childrenList],
style: {
lineWidth: 2,
fill: '#BDEFDB',
stroke: '#5AD8A6',
},
});
}
return relationList;
},
[],
);
return relationData;
};
export const loopNodeFindDataSource: any = (node: any) => {
const { model, parent } = node;
if (model?.nodeType === SemanticNodeType.DATASOURCE) {
return model;
}
const parentNode = parent?._cfg;
if (parentNode) {
return loopNodeFindDataSource(parentNode);
}
return false;
};
export const getNodeConfigByType = (nodeData: any, defaultConfig = {}) => {
const { nodeType } = nodeData;
const labelCfg = { style: { fill: '#3c3c3c' } };
switch (nodeType) {
case SemanticNodeType.DATASOURCE: {
return {
...defaultConfig,
labelCfg: { position: 'bottom', ...labelCfg },
};
}
case SemanticNodeType.DIMENSION:
return {
...defaultConfig,
labelCfg: { position: 'right', ...labelCfg },
};
case SemanticNodeType.METRIC:
return {
...defaultConfig,
style: {
lineWidth: 2,
fill: '#fffbe6',
stroke: '#ffe58f',
},
labelCfg: { position: 'right', ...labelCfg },
};
default:
return defaultConfig;
}
};
export const flatGraphDataNode = (graphData: any[]) => {
return graphData.reduce((nodeList: any[], item: any) => {
const { children } = item;
if (Array.isArray(children)) {
nodeList.push(...children);
}
return nodeList;
}, []);
};
interface Node {
label: string;
children?: Node[];
}
export const findNodesByLabel = (query: string, nodes: Node[]): Node[] => {
const result: Node[] = [];
for (const node of nodes) {
let match = false;
let children: Node[] = [];
// 如果节点的label包含查询字符串我们将其标记为匹配
if (node.label.includes(query)) {
match = true;
}
// 我们还需要在子节点中进行搜索
if (node.children) {
children = findNodesByLabel(query, node.children);
if (children.length > 0) {
match = true;
}
}
// 如果节点匹配或者其子节点匹配,我们将其添加到结果中
if (match) {
result.push({ ...node, children });
}
}
return result;
};