| @@ -113,7 +113,6 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => { | |||||
| children: ( | children: ( | ||||
| <ModelEvolution | <ModelEvolution | ||||
| resourceId={resourceId} | resourceId={resourceId} | ||||
| resourceName={info.name} | |||||
| versionList={versionList} | versionList={versionList} | ||||
| version={version} | version={version} | ||||
| isActive={activeTab === ResourceInfoTabKeys.Evolution} | isActive={activeTab === ResourceInfoTabKeys.Evolution} | ||||
| @@ -3,7 +3,7 @@ import { ResourceVersionData } from '@/pages/Dataset/config'; | |||||
| import { getModelAtlasReq } from '@/services/dataset/index.js'; | import { getModelAtlasReq } from '@/services/dataset/index.js'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import G6, { G6GraphEvent, Graph, Item } from '@antv/g6'; | |||||
| import G6, { G6GraphEvent, Graph } from '@antv/g6'; | |||||
| // @ts-ignore | // @ts-ignore | ||||
| import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceIntro'; | import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceIntro'; | ||||
| import { Flex, Select } from 'antd'; | import { Flex, Select } from 'antd'; | ||||
| @@ -16,7 +16,6 @@ import { NodeType, getGraphData, nodeHeight, nodeWidth, normalizeTreeData } from | |||||
| type modeModelEvolutionProps = { | type modeModelEvolutionProps = { | ||||
| resourceId: number; | resourceId: number; | ||||
| resourceName: string; | |||||
| versionList: ResourceVersionData[]; | versionList: ResourceVersionData[]; | ||||
| version?: string; | version?: string; | ||||
| isActive: boolean; | isActive: boolean; | ||||
| @@ -26,7 +25,6 @@ type modeModelEvolutionProps = { | |||||
| let graph: Graph; | let graph: Graph; | ||||
| function ModelEvolution({ | function ModelEvolution({ | ||||
| resourceId, | resourceId, | ||||
| resourceName, | |||||
| versionList, | versionList, | ||||
| version, | version, | ||||
| isActive, | isActive, | ||||
| @@ -37,7 +35,9 @@ function ModelEvolution({ | |||||
| const [enterTooltip, setEnterTooltip] = useState(false); | const [enterTooltip, setEnterTooltip] = useState(false); | ||||
| const [nodeTooltipX, setNodeToolTipX] = useState(0); | const [nodeTooltipX, setNodeToolTipX] = useState(0); | ||||
| const [nodeTooltipY, setNodeToolTipY] = useState(0); | const [nodeTooltipY, setNodeToolTipY] = useState(0); | ||||
| const [hoverNodeData, setHoverNodeData] = useState<ModelDepsData | undefined>(undefined); | |||||
| const [hoverNodeData, setHoverNodeData] = useState< | |||||
| ModelDepsData | ProjectDependency | TrainDataset | undefined | |||||
| >(undefined); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| initGraph(); | initGraph(); | ||||
| @@ -97,6 +97,7 @@ function ModelEvolution({ | |||||
| fill: '#ffffff', | fill: '#ffffff', | ||||
| fontSize: 8, | fontSize: 8, | ||||
| textAlign: 'center', | textAlign: 'center', | ||||
| cursor: 'pointer', | |||||
| }, | }, | ||||
| }, | }, | ||||
| }, | }, | ||||
| @@ -114,15 +115,14 @@ function ModelEvolution({ | |||||
| default: [ | default: [ | ||||
| 'drag-canvas', | 'drag-canvas', | ||||
| 'zoom-canvas', | 'zoom-canvas', | ||||
| 'drag-node', | |||||
| { | |||||
| type: 'collapse-expand', | |||||
| onChange(item?: Item, collapsed?: boolean) { | |||||
| const data = item!.getModel(); | |||||
| data.collapsed = collapsed; | |||||
| return true; | |||||
| }, | |||||
| }, | |||||
| // { | |||||
| // type: 'collapse-expand', | |||||
| // onChange(item?: Item, collapsed?: boolean) { | |||||
| // const data = item!.getModel(); | |||||
| // data.collapsed = collapsed; | |||||
| // return true; | |||||
| // }, | |||||
| // }, | |||||
| ], | ], | ||||
| }, | }, | ||||
| }); | }); | ||||
| @@ -137,14 +137,7 @@ function ModelEvolution({ | |||||
| graph.setItemState(nodeItem, 'hover', true); | graph.setItemState(nodeItem, 'hover', true); | ||||
| const model = nodeItem.getModel() as ModelDepsData; | const model = nodeItem.getModel() as ModelDepsData; | ||||
| const { x, y, model_type } = model; | |||||
| if ( | |||||
| model_type === NodeType.project || | |||||
| model_type === NodeType.trainDataset || | |||||
| model_type === NodeType.testDataset | |||||
| ) { | |||||
| return; | |||||
| } | |||||
| const { x, y } = model; | |||||
| const point = graph.getCanvasByPoint(x!, y!); | const point = graph.getCanvasByPoint(x!, y!); | ||||
| const zoom = graph.getZoom(); | const zoom = graph.getZoom(); | ||||
| // 更加缩放,调整 tooltip 位置 | // 更加缩放,调整 tooltip 位置 | ||||
| @@ -158,8 +151,7 @@ function ModelEvolution({ | |||||
| setHoverNodeData(model); | setHoverNodeData(model); | ||||
| setNodeToolTipX(point.x + offsetX); | setNodeToolTipX(point.x + offsetX); | ||||
| // 92: 版本选择器的高度,296: tooltip 的高度 | |||||
| setNodeToolTipY(point.y + 92 - 296 - offsetY); | |||||
| setNodeToolTipY(graphRef.current!.clientHeight - point.y + offsetY); | |||||
| setShowNodeTooltip(true); | setShowNodeTooltip(true); | ||||
| }); | }); | ||||
| @@ -225,7 +217,7 @@ function ModelEvolution({ | |||||
| }; | }; | ||||
| const [res] = await to(getModelAtlasReq(params)); | const [res] = await to(getModelAtlasReq(params)); | ||||
| if (res && res.data) { | if (res && res.data) { | ||||
| const data = normalizeTreeData(res.data, resourceName); | |||||
| const data = normalizeTreeData(res.data); | |||||
| const graphData = getGraphData(data); | const graphData = getGraphData(data); | ||||
| graph.data(graphData); | graph.data(graphData); | ||||
| @@ -131,10 +131,7 @@ export function getStyle(model_type: NodeType) { | |||||
| } | } | ||||
| // 将后台返回的数据转换成树形数据 | // 将后台返回的数据转换成树形数据 | ||||
| export function normalizeTreeData( | |||||
| apiData: ModelDepsAPIData, | |||||
| currentNodeName: string, | |||||
| ): ModelDepsData { | |||||
| export function normalizeTreeData(apiData: ModelDepsAPIData): ModelDepsData { | |||||
| // 将 children_models 转换成 children | // 将 children_models 转换成 children | ||||
| let normalizedData = changePropertyName(apiData, { | let normalizedData = changePropertyName(apiData, { | ||||
| children_models: 'children', | children_models: 'children', | ||||
| @@ -142,7 +139,6 @@ export function normalizeTreeData( | |||||
| // 设置当前模型的数据 | // 设置当前模型的数据 | ||||
| normalizedData.model_type = NodeType.current; | normalizedData.model_type = NodeType.current; | ||||
| normalizedData.current_model_name = currentNodeName; | |||||
| normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; | normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; | ||||
| normalizedData.label = getLabel(normalizedData); | normalizedData.label = getLabel(normalizedData); | ||||
| normalizedData.style = getStyle(NodeType.current); | normalizedData.style = getStyle(NodeType.current); | ||||
| @@ -1,6 +1,6 @@ | |||||
| .node-tooltips { | .node-tooltips { | ||||
| position: absolute; | position: absolute; | ||||
| top: -100px; | |||||
| bottom: -100px; | |||||
| left: -300px; | left: -300px; | ||||
| width: 300px; | width: 300px; | ||||
| padding: 10px; | padding: 10px; | ||||
| @@ -43,6 +43,7 @@ | |||||
| min-width: 0; | min-width: 0; | ||||
| color: @text-color; | color: @text-color; | ||||
| font-weight: 500; | font-weight: 500; | ||||
| word-break: break-all; | |||||
| } | } | ||||
| &__link { | &__link { | ||||
| @@ -1,16 +1,16 @@ | |||||
| import { formatDate } from '@/utils/date'; | import { formatDate } from '@/utils/date'; | ||||
| import { ModelDepsData } from '../ModelEvolution/utils'; | |||||
| import { ModelDepsData, NodeType, ProjectDependency, TrainDataset } from '../ModelEvolution/utils'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| type NodeTooltipsProps = { | type NodeTooltipsProps = { | ||||
| data: ModelDepsData; | |||||
| data?: ModelDepsData | ProjectDependency | TrainDataset; | |||||
| x: number; | x: number; | ||||
| y: number; | y: number; | ||||
| onMouseEnter?: () => void; | onMouseEnter?: () => void; | ||||
| onMouseLeave?: () => void; | onMouseLeave?: () => void; | ||||
| }; | }; | ||||
| function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) { | |||||
| function ModelInfo({ data }: { data: ModelDepsData }) { | |||||
| const gotoExperimentPage = () => { | const gotoExperimentPage = () => { | ||||
| if (data.train_task?.ins_id) { | if (data.train_task?.ins_id) { | ||||
| const { origin } = location; | const { origin } = location; | ||||
| @@ -19,21 +19,18 @@ function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsPr | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <div | |||||
| className={styles['node-tooltips']} | |||||
| style={{ left: `${x}px`, top: `${y}px` }} | |||||
| onMouseEnter={onMouseEnter} | |||||
| onMouseLeave={onMouseLeave} | |||||
| > | |||||
| <> | |||||
| <div className={styles['node-tooltips__title']}>模型信息</div> | <div className={styles['node-tooltips__title']}>模型信息</div> | ||||
| <div> | <div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型名称:</span> | <span className={styles['node-tooltips__row__title']}>模型名称:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.current_model_name}</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {data.model_version_dependcy_vo.name || '--'} | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型版本:</span> | <span className={styles['node-tooltips__row__title']}>模型版本:</span> | ||||
| <span className={styles['node-tooltips__row__value']}>{data.version}</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.version || '--'}</span> | |||||
| </div> | </div> | ||||
| <div className={styles['node-tooltips__row']}> | <div className={styles['node-tooltips__row']}> | ||||
| <span className={styles['node-tooltips__row__title']}>模型框架:</span> | <span className={styles['node-tooltips__row__title']}>模型框架:</span> | ||||
| @@ -73,6 +70,71 @@ function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsPr | |||||
| )} | )} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </> | |||||
| ); | |||||
| } | |||||
| function DatasetInfo({ data }: { data: TrainDataset }) { | |||||
| return ( | |||||
| <> | |||||
| <div className={styles['node-tooltips__title']}>数据集信息</div> | |||||
| <div> | |||||
| <div className={styles['node-tooltips__row']}> | |||||
| <span className={styles['node-tooltips__row__title']}>数据集名称:</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.dataset_name || '--'}</span> | |||||
| </div> | |||||
| <div className={styles['node-tooltips__row']}> | |||||
| <span className={styles['node-tooltips__row__title']}>数据集版本:</span> | |||||
| <span className={styles['node-tooltips__row__value']}> | |||||
| {data.dataset_version || '--'} | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </> | |||||
| ); | |||||
| } | |||||
| function ProjectInfo({ data }: { data: ProjectDependency }) { | |||||
| return ( | |||||
| <> | |||||
| <div className={styles['node-tooltips__title']}>项目信息</div> | |||||
| <div> | |||||
| <div className={styles['node-tooltips__row']}> | |||||
| <span className={styles['node-tooltips__row__title']}>项目名称:</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.name || '--'}</span> | |||||
| </div> | |||||
| <div className={styles['node-tooltips__row']}> | |||||
| <span className={styles['node-tooltips__row__title']}>项目分支:</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.branch || '--'}</span> | |||||
| </div> | |||||
| <div className={styles['node-tooltips__row']}> | |||||
| <span className={styles['node-tooltips__row__title']}>项目地址:</span> | |||||
| <span className={styles['node-tooltips__row__value']}>{data.url || '--'}</span> | |||||
| </div> | |||||
| </div> | |||||
| </> | |||||
| ); | |||||
| } | |||||
| function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) { | |||||
| if (!data) return null; | |||||
| let Component; | |||||
| const { model_type } = data; | |||||
| if (model_type === NodeType.testDataset || model_type === NodeType.trainDataset) { | |||||
| Component = <DatasetInfo data={data as TrainDataset} />; | |||||
| } else if (model_type === NodeType.project) { | |||||
| Component = <ProjectInfo data={data as ProjectDependency} />; | |||||
| } else { | |||||
| Component = <ModelInfo data={data as ModelDepsData} />; | |||||
| } | |||||
| return ( | |||||
| <div | |||||
| className={styles['node-tooltips']} | |||||
| style={{ left: `${x}px`, bottom: `${y}px` }} | |||||
| onMouseEnter={onMouseEnter} | |||||
| onMouseLeave={onMouseLeave} | |||||
| > | |||||
| {Component} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||