mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 13:47:09 +00:00
[improvement][semantic-fe] Added an editing component to set filtering rules for Q&A. Now, the SQL editor will be accompanied by a list for display and control, to resolve ambiguity when using comma-separated values.
[improvement][semantic-fe] Improved validation logic and prompt copywriting for data source/dimension/metric editing and creation. [improvement][semantic-fe] Improved user experience for visual modeling. Now, when using the legend to control the display/hide of data sources and their associated metric dimensions, the canvas will be re-layout based on the activated data source in the legend. Co-authored-by: tristanliu <tristanliu@tencent.com>
This commit is contained in:
@@ -1,80 +1,139 @@
|
||||
import { ISemantic, IDataSource } from '../data';
|
||||
import { SemanticNodeType } from '../enum';
|
||||
|
||||
export const typeConfigs = {
|
||||
datasource: {
|
||||
type: 'circle',
|
||||
size: 5,
|
||||
style: {
|
||||
fill: '#5B8FF9',
|
||||
},
|
||||
size: 10,
|
||||
},
|
||||
dimension: {
|
||||
type: 'circle',
|
||||
size: 20,
|
||||
style: {
|
||||
fill: '#5AD8A6',
|
||||
},
|
||||
},
|
||||
metric: {
|
||||
type: 'rect',
|
||||
size: [10, 10],
|
||||
style: {
|
||||
fill: '#5D7092',
|
||||
},
|
||||
},
|
||||
// eType1: {
|
||||
// type: 'line',
|
||||
// style: {
|
||||
// width: 20,
|
||||
// stroke: '#F6BD16',
|
||||
// },
|
||||
// },
|
||||
// eType2: {
|
||||
// type: 'cubic',
|
||||
// },
|
||||
// eType3: {
|
||||
// type: 'quadratic',
|
||||
// style: {
|
||||
// width: 25,
|
||||
// stroke: '#6F5EF9',
|
||||
// },
|
||||
// },
|
||||
};
|
||||
export const legendData = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'type1',
|
||||
label: 'node-type1',
|
||||
order: 4,
|
||||
...typeConfigs.datasource,
|
||||
|
||||
export const getDimensionChildren = (
|
||||
dimensions: ISemantic.IDimensionItem[],
|
||||
dataSourceNodeId: string,
|
||||
) => {
|
||||
const dimensionChildrenList = dimensions.reduce(
|
||||
(dimensionChildren: any[], dimension: ISemantic.IDimensionItem) => {
|
||||
const { id } = dimension;
|
||||
dimensionChildren.push({
|
||||
...dimension,
|
||||
nodeType: SemanticNodeType.DIMENSION,
|
||||
legendType: dataSourceNodeId,
|
||||
id: `${SemanticNodeType.DIMENSION}-${id}`,
|
||||
uid: id,
|
||||
style: {
|
||||
lineWidth: 2,
|
||||
fill: '#f0f7ff',
|
||||
stroke: '#a6ccff',
|
||||
},
|
||||
});
|
||||
return dimensionChildren;
|
||||
},
|
||||
{
|
||||
id: 'type2',
|
||||
label: 'node-type2',
|
||||
order: 0,
|
||||
...typeConfigs.dimension,
|
||||
},
|
||||
{
|
||||
id: 'type3',
|
||||
label: 'node-type3',
|
||||
order: 2,
|
||||
...typeConfigs.metric,
|
||||
},
|
||||
],
|
||||
// edges: [
|
||||
// {
|
||||
// id: 'eType1',
|
||||
// label: 'edge-type1',
|
||||
// order: 2,
|
||||
// ...typeConfigs.eType1,
|
||||
// },
|
||||
// {
|
||||
// id: 'eType2',
|
||||
// label: 'edge-type2',
|
||||
// ...typeConfigs.eType2,
|
||||
// },
|
||||
// {
|
||||
// id: 'eType3',
|
||||
// label: 'edge-type3',
|
||||
// ...typeConfigs.eType3,
|
||||
// },
|
||||
// ],
|
||||
[],
|
||||
);
|
||||
return dimensionChildrenList;
|
||||
};
|
||||
|
||||
export const getMetricChildren = (metrics: ISemantic.IMetricItem[], dataSourceNodeId: string) => {
|
||||
const metricsChildrenList = metrics.reduce(
|
||||
(metricsChildren: any[], metric: ISemantic.IMetricItem) => {
|
||||
const { id } = metric;
|
||||
metricsChildren.push({
|
||||
...metric,
|
||||
nodeType: SemanticNodeType.METRIC,
|
||||
legendType: dataSourceNodeId,
|
||||
id: `${SemanticNodeType.METRIC}-${id}`,
|
||||
uid: id,
|
||||
style: {
|
||||
lineWidth: 2,
|
||||
fill: '#f0f7ff',
|
||||
stroke: '#a6ccff',
|
||||
},
|
||||
});
|
||||
return metricsChildren;
|
||||
},
|
||||
[],
|
||||
);
|
||||
return metricsChildrenList;
|
||||
};
|
||||
|
||||
export const formatterRelationData = (
|
||||
dataSourceList: IDataSource.IDataSourceItem[],
|
||||
type: SemanticNodeType = SemanticNodeType.DIMENSION,
|
||||
) => {
|
||||
const relationData = dataSourceList.reduce((relationList: any[], item: any) => {
|
||||
const { datasource, dimensions, metrics } = item;
|
||||
const { id } = datasource;
|
||||
const dataSourceNodeId = `${SemanticNodeType.DATASOURCE}-${id}`;
|
||||
let childrenList = [];
|
||||
if (type === SemanticNodeType.METRIC) {
|
||||
childrenList = getMetricChildren(metrics, dataSourceNodeId);
|
||||
}
|
||||
if (type === SemanticNodeType.DIMENSION) {
|
||||
childrenList = getDimensionChildren(dimensions, 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,
|
||||
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;
|
||||
}, []);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user