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