Browse Source

chore: 模型演化优化

pull/82/head
cp3hnu 1 year ago
parent
commit
0bbfa01286
4 changed files with 110 additions and 64 deletions
  1. +1
    -1
      react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx
  2. +6
    -39
      react-ui/src/pages/Model/components/ModelEvolution/index.tsx
  3. +2
    -2
      react-ui/src/pages/Model/components/ModelEvolution/utils.tsx
  4. +101
    -22
      react-ui/src/pages/Model/components/NodeTooltips/index.tsx

+ 1
- 1
react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx View File

@@ -33,7 +33,7 @@ const ResourceIntro = ({ resourceType }: ResourceIntroProps) => {
useEffect(() => {
getModelByDetail();
getVersionList();
}, []);
}, [resourceId]);

// 获取详情
const getModelByDetail = async () => {


+ 6
- 39
react-ui/src/pages/Model/components/ModelEvolution/index.tsx View File

@@ -5,21 +5,13 @@ import themes from '@/styles/theme.less';
import { to } from '@/utils/promise';
import G6, { G6GraphEvent, Graph } from '@antv/g6';
// @ts-ignore
import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceIntro';
import { Flex, Select } from 'antd';
import { useEffect, useRef, useState } from 'react';
import GraphLegend from '../GraphLegend';
import NodeTooltips from '../NodeTooltips';
import styles from './index.less';
import type { ModelDepsData, ProjectDependency, TrainDataset } from './utils';
import {
NodeType,
getGraphData,
nodeFontSize,
nodeHeight,
nodeWidth,
normalizeTreeData,
} from './utils';
import { getGraphData, nodeFontSize, nodeHeight, nodeWidth, normalizeTreeData } from './utils';

type modeModelEvolutionProps = {
resourceId: number;
@@ -80,7 +72,7 @@ function ModelEvolution({
width: graphRef.current!.clientWidth,
height: graphRef.current!.clientHeight,
fitView: true,
fitViewPadding: [100, 100, 100, 100],
fitViewPadding: 200,
minZoom: 0.5,
maxZoom: 5,
defaultNode: {
@@ -172,36 +164,7 @@ function ModelEvolution({
const nodeItem = e.item;
const model = nodeItem.getModel() as ModelDepsData | ProjectDependency | TrainDataset;
const { model_type } = model;
const { origin } = location;
let url: string = '';
switch (model_type) {
case NodeType.children:
case NodeType.parent: {
const { current_model_id, version } = model;
url = `${origin}/dataset/model/${current_model_id}?tab=${ResourceInfoTabKeys.Evolution}&version=${version}`;
break;
}
case NodeType.project: {
const { url: projectUrl } = model;
url = projectUrl;
break;
}
case NodeType.trainDataset:
case NodeType.testDataset: {
const { dataset_id, dataset_version } = model;
url = `${origin}/dataset/dataset/${dataset_id}?tab=${ResourceInfoTabKeys.Version}&version=${dataset_version}`;
break;
}
case NodeType.current: {
// TODO: 隐藏数据集和项目
break;
}
default:
break;
}

if (url) {
window.open(url, '_blank');
}
});

@@ -234,6 +197,8 @@ function ModelEvolution({
graph.data(graphData);
graph.render();
graph.fitView();
setShowNodeTooltip(false);
setEnterTooltip(false);
} else {
clearGraphData();
}
@@ -266,9 +231,11 @@ function ModelEvolution({
<div className={styles['model-evolution__graph']} id="canvas" ref={graphRef}></div>
{(showNodeTooltip || enterTooltip) && (
<NodeTooltips
resourceId={resourceId}
x={nodeTooltipX}
y={nodeTooltipY}
data={hoverNodeData!}
onVersionChange={onVersionChange}
onMouseEnter={handleTooltipsMouseEnter}
onMouseLeave={handleTooltipsMouseLeave}
/>


+ 2
- 2
react-ui/src/pages/Model/components/ModelEvolution/utils.tsx View File

@@ -3,8 +3,8 @@ import { EdgeConfig, GraphData, LayoutConfig, NodeConfig, TreeGraphData, Util }
// @ts-ignore
import Hierarchy from '@antv/hierarchy';

export const nodeWidth = 110;
export const nodeHeight = 50;
export const nodeWidth = 90;
export const nodeHeight = 40;
export const vGap = nodeHeight + 20;
export const hGap = nodeWidth;
export const ellipseWidth = nodeWidth;


+ 101
- 22
react-ui/src/pages/Model/components/NodeTooltips/index.tsx View File

@@ -1,20 +1,35 @@
import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceIntro';
import { formatDate } from '@/utils/date';
import { useNavigate } from '@umijs/max';
import { ModelDepsData, NodeType, ProjectDependency, TrainDataset } from '../ModelEvolution/utils';
import styles from './index.less';

type NodeTooltipsProps = {
data?: ModelDepsData | ProjectDependency | TrainDataset;
x: number;
y: number;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
type ModelInfoProps = {
resourceId: number;
data: ModelDepsData;
onVersionChange: (version: string) => void;
};

function ModelInfo({ data }: { data: ModelDepsData }) {
function ModelInfo({ resourceId, data, onVersionChange }: ModelInfoProps) {
const navigate = useNavigate();

const gotoExperimentPage = () => {
if (data.train_task?.ins_id) {
const { origin } = location;
window.open(`${origin}/pipeline/experiment/144/${data.train_task.ins_id}`, '_blank');
const url = `${origin}/pipeline/experiment/${data.workflow_id}/${data.train_task.ins_id}`;
window.open(url, '_blank');
}
};

const gotoModelPage = () => {
if (data.model_type === NodeType.current) {
return;
}
if (data.current_model_id === resourceId) {
onVersionChange?.(data.version);
} else {
const path = `/dataset/model/${data.current_model_id}?tab=${ResourceInfoTabKeys.Evolution}&version=${data.version}`;
navigate(path);
}
};

@@ -24,9 +39,18 @@ function ModelInfo({ data }: { data: ModelDepsData }) {
<div>
<div className={styles['node-tooltips__row']}>
<span className={styles['node-tooltips__row__title']}>模型名称:</span>
<span className={styles['node-tooltips__row__value']}>
{data.model_version_dependcy_vo.name || '--'}
</span>
{data.model_type === NodeType.current ? (
<span className={styles['node-tooltips__row__value']}>
{data.model_version_dependcy_vo?.name || '--'}
</span>
) : (
<ValueLink
value={data.model_version_dependcy_vo?.name}
className={styles['node-tooltips__row__link']}
nullClassName={styles['node-tooltips__row__value']}
onClick={gotoModelPage}
></ValueLink>
)}
</div>
<div className={styles['node-tooltips__row']}>
<span className={styles['node-tooltips__row__title']}>模型版本:</span>
@@ -61,13 +85,12 @@ function ModelInfo({ data }: { data: ModelDepsData }) {
<div>
<div className={styles['node-tooltips__row']}>
<span className={styles['node-tooltips__row__title']}>训练任务:</span>
{data.train_task?.name ? (
<a className={styles['node-tooltips__row__link']} onClick={gotoExperimentPage}>
{data.train_task?.name}
</a>
) : (
'--'
)}
<ValueLink
value={data.train_task?.name}
className={styles['node-tooltips__row__link']}
nullClassName={styles['node-tooltips__row__value']}
onClick={gotoExperimentPage}
></ValueLink>
</div>
</div>
</>
@@ -75,13 +98,24 @@ function ModelInfo({ data }: { data: ModelDepsData }) {
}

function DatasetInfo({ data }: { data: TrainDataset }) {
const gotoDatasetPage = () => {
const { origin } = location;
const url = `${origin}/dataset/dataset/${data.dataset_id}?tab=${ResourceInfoTabKeys.Version}&version=${data.dataset_version}`;
window.open(url, '_blank');
};

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>
<ValueLink
value={data.dataset_name}
className={styles['node-tooltips__row__link']}
nullClassName={styles['node-tooltips__row__value']}
onClick={gotoDatasetPage}
></ValueLink>
</div>
<div className={styles['node-tooltips__row']}>
<span className={styles['node-tooltips__row__title']}>数据集版本:</span>
@@ -95,13 +129,23 @@ function DatasetInfo({ data }: { data: TrainDataset }) {
}

function ProjectInfo({ data }: { data: ProjectDependency }) {
const gotoProjectPage = () => {
const { url } = data;
window.open(url, '_blank');
};

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>
<ValueLink
value={data.name}
className={styles['node-tooltips__row__link']}
nullClassName={styles['node-tooltips__row__value']}
onClick={gotoProjectPage}
></ValueLink>
</div>
<div className={styles['node-tooltips__row']}>
<span className={styles['node-tooltips__row__title']}>项目分支:</span>
@@ -116,7 +160,42 @@ function ProjectInfo({ data }: { data: ProjectDependency }) {
);
}

function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsProps) {
type ValueLinkProps = {
value: string | undefined;
onClick?: () => void;
className?: string;
nullClassName?: string;
};

const ValueLink = ({ value, onClick, className, nullClassName }: ValueLinkProps) => {
return value ? (
<a className={className} onClick={onClick}>
{value}
</a>
) : (
<span className={nullClassName}>--</span>
);
};

type NodeTooltipsProps = {
resourceId: number;
data: ModelDepsData | ProjectDependency | TrainDataset;
x: number;
y: number;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
onVersionChange: (version: string) => void;
};

function NodeTooltips({
resourceId,
data,
x,
y,
onMouseEnter,
onMouseLeave,
onVersionChange,
}: NodeTooltipsProps) {
if (!data) return null;
let Component = null;
const { model_type } = data;
@@ -129,7 +208,7 @@ function NodeTooltips({ data, x, y, onMouseEnter, onMouseLeave }: NodeTooltipsPr
model_type === NodeType.parent ||
model_type === NodeType.current
) {
Component = <ModelInfo data={data} />;
Component = <ModelInfo resourceId={resourceId} data={data} onVersionChange={onVersionChange} />;
}
return (
<div


Loading…
Cancel
Save