mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 12:07:42 +00:00
198 lines
5.3 KiB
TypeScript
198 lines
5.3 KiB
TypeScript
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;
|
||
};
|