+ );
return (
-
- {data && (data.tables.length !== 0 || data.relations.length !== 0) ? (
- // todo 刷新没用,可以去掉api
- {}} />
- ) : (
-
- )}
-
+
+
+ item.columns.map((column) => ({
+ id: item.id + column.name,
+ combo: item.id,
+ data: { name: column.name }
+ }))
+ ),
+ edges: data.relations.map((item) => ({
+ source: item.srcTableId + item.srcTableColName,
+ target: item.tgtTableId + item.tgtTableColName
+ })),
+ combos: data.tables.map((item) => ({ id: item.id }))
+ },
+ combo: {
+ type: 'circle-combo-with-extra-button',
+ style: {
+ labelText: (d) => tablesMap[d.id]
+ }
+ },
+ node: {
+ type: 'react',
+ style: {
+ size: [240, 20],
+ component: (data: { data: { name: string } }) => (
+
+ {data.data.name}
+
+ ),
+ port: true,
+ ports: [{ placement: 'right' }, { placement: 'left' }]
+ }
+ },
+ edge: {
+ type: 'cubic-horizontal',
+ style: {
+ endArrow: true,
+ endArrowType: 'vee'
+ }
+ },
+ layout: {
+ type: 'combo-combined',
+ innerLayout: new GridLayout({ cols: 1, condense: true }),
+ outerLayout: new DagreLayout({
+ rankdir: 'LR',
+ edgeLabelSpace: false,
+ nodesep: 5,
+ ranksep: 50
+ })
+ },
+ behaviors: [
+ 'focus-element',
+ 'drag-canvas',
+ 'zoom-canvas',
+ {
+ type: 'hover-activate',
+ enable: (event: any) => event.targetType === 'node',
+ degree: 1, // 👈🏻 Activate relations.
+ state: 'highlight',
+ inactiveState: 'dim',
+ onHover: (event: any) => {
+ event.view.setCursor('pointer');
+ },
+ onHoverEnd: (event: any) => {
+ event.view.setCursor('default');
+ }
+ }
+ ],
+ plugins: [
+ {
+ key: 'grid-line',
+ type: 'grid-line',
+ follow: false,
+ size: 40,
+ stroke: 'var(--border-color)',
+ borderStroke: 'var(--border-color)'
+ },
+ {
+ type: 'toolbar',
+ position: 'right-top',
+ onClick: (item: string) => {
+ const graph = graphRef.current;
+ switch (item) {
+ // 放大
+ case 'zoom-in':
+ graph?.zoomTo(graph?.getZoom() + 0.2);
+ break;
+ case 'zoom-out':
+ graph?.zoomBy(0.5);
+ break;
+ case 'auto-fit':
+ graph?.fitView();
+ break;
+ }
+ },
+ getItems: () => {
+ return [
+ { id: 'zoom-in', value: 'zoom-in' },
+ { id: 'zoom-out', value: 'zoom-out' },
+ { id: 'auto-fit', value: 'auto-fit' }
+ ];
+ },
+ style: {
+ backgroundColor: 'var(--btn-background-color)'
+ }
+ },
+ { key: 'background', type: 'background', background: 'var(--primary-color)' }
+ ],
+ transforms: ['process-parallel-edges'],
+ autoFit: 'view'
+ }}
+ />
+
);
-};
+});
diff --git a/dinky-web/src/pages/DataStudio/Toolbar/Service/LineageNew/index.tsx b/dinky-web/src/pages/DataStudio/Toolbar/Service/LineageNew/index.tsx
deleted file mode 100644
index 69e3f68e2b..0000000000
--- a/dinky-web/src/pages/DataStudio/Toolbar/Service/LineageNew/index.tsx
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { Circle, Group, Path } from '@antv/g';
-import {
- ExtensionCategory,
- Graph,
- PathArray,
- RectCombo,
- RectComboStyleProps,
- register
-} from '@antv/g6';
-import { memo, useContext, useEffect, useRef } from 'react';
-import { Flex } from 'antd';
-import { ReactNode } from '@antv/g6-extension-react';
-import { Graphin } from '@antv/graphin';
-import { DagreLayout, GridLayout } from '@antv/layout';
-import { LineageDetailInfo } from '@/types/DevOps/data';
-import { DataStudioContext } from '@/pages/DataStudio/DataStudioContext';
-
-const collapse = (x: number, y: number, r: number) => {
- return [
- ['M', x - r, y],
- ['a', r, r, 0, 1, 0, r * 2, 0],
- ['a', r, r, 0, 1, 0, -r * 2, 0],
- ['M', x - r + 4, y],
- ['L', x + r - 4, y]
- ] as PathArray;
-};
-
-const expand = (x: number, y: number, r: number) => {
- return [
- ['M', x - r, y],
- ['a', r, r, 0, 1, 0, r * 2, 0],
- ['a', r, r, 0, 1, 0, -r * 2, 0],
- ['M', x - r + 4, y],
- ['L', x - r + 2 * r - 4, y],
- ['M', x - r + r, y - r + 4],
- ['L', x, y + r - 4]
- ] as PathArray;
-};
-
-class RectComboWithExtraButton extends RectCombo {
- render(attributes: Required, container: Group) {
- super.render(attributes, container);
- this.drawButton(attributes);
- }
-
- drawButton(attributes: Required) {
- const { collapsed } = attributes;
- const [, height] = this.getKeySize(attributes);
- const btnR = 8;
- const y = -(height / 2 + btnR);
- const d = collapsed ? expand(0, y, btnR) : collapse(0, y, btnR);
-
- const hitArea = this.upsert(
- 'hit-area',
- Circle,
- { cy: y, r: 10, fill: '#fff', cursor: 'pointer' },
- this
- );
- this.upsert('button', Path, { stroke: '#3d81f7', d, cursor: 'pointer' }, hitArea!!);
- }
-
- onCreate() {
- this.shapeMap['hit-area'].addEventListener('click', () => {
- const id = this.id;
- const collapsed = !this.attributes.collapsed;
- const { graph } = this.attributes.context!!;
- if (collapsed) graph.collapseElement(id);
- else graph.expandElement(id);
- });
- }
-}
-
-register(ExtensionCategory.COMBO, 'circle-combo-with-extra-button', RectComboWithExtraButton);
-
-register(ExtensionCategory.NODE, 'react', ReactNode);
-export const LineageNew = memo((props: { data: LineageDetailInfo }) => {
- const { data } = props;
- const { theme } = useContext(DataStudioContext);
- const graphRef = useRef(null);
- const containerRef = useRef(null);
-
- useEffect(() => {
- // 监控布局宽度高度变化,重新计算树的高度
- const element = containerRef.current!!;
- const observer = new ResizeObserver((entries) => {
- if (
- graphRef.current &&
- entries?.length === 1 &&
- entries[0].contentRect.width > 0 &&
- entries[0].contentRect.height > 0
- ) {
- graphRef.current?.setSize(entries[0].contentRect.width, entries[0].contentRect.height);
- }
- });
- observer.observe(element);
- return () => observer.unobserve(element);
- }, []);
- // 把data.tables 的id ,name转成map
- const tablesMap = data.tables.reduce(
- (acc, item) => {
- acc[item.id] = item.name;
- return acc;
- },
- {} as Record
- );
- return (
-
-
- item.columns.map((column) => ({
- id: item.id + column.name,
- combo: item.id,
- data: { name: column.name }
- }))
- ),
- edges: data.relations.map((item) => ({
- source: item.srcTableId + item.srcTableColName,
- target: item.tgtTableId + item.tgtTableColName
- })),
- combos: data.tables.map((item) => ({ id: item.id }))
- },
- combo: {
- type: 'circle-combo-with-extra-button',
- style: {
- labelText: (d) => tablesMap[d.id]
- }
- },
- node: {
- type: 'react',
- style: {
- size: [240, 20],
- component: (data: { data: { name: string } }) => (
-
- {data.data.name}
-
- ),
- port: true,
- ports: [{ placement: 'right' }, { placement: 'left' }]
- }
- },
- edge: {
- type: 'cubic-horizontal',
- style: {
- endArrow: true,
- endArrowType: 'vee'
- }
- },
- layout: {
- type: 'combo-combined',
- innerLayout: new GridLayout({ cols: 1, condense: true }),
- outerLayout: new DagreLayout({
- rankdir: 'LR',
- edgeLabelSpace: false,
- nodesep: 5,
- ranksep: 50
- })
- },
- behaviors: [
- 'focus-element',
- 'drag-canvas',
- 'zoom-canvas',
- {
- type: 'hover-activate',
- enable: (event: any) => event.targetType === 'node',
- degree: 1, // 👈🏻 Activate relations.
- state: 'highlight',
- inactiveState: 'dim',
- onHover: (event: any) => {
- event.view.setCursor('pointer');
- },
- onHoverEnd: (event: any) => {
- event.view.setCursor('default');
- }
- }
- ],
- plugins: [
- {
- key: 'grid-line',
- type: 'grid-line',
- follow: false,
- size: 40,
- stroke: 'var(--border-color)',
- borderStroke: 'var(--border-color)'
- },
- {
- type: 'toolbar',
- position: 'right-top',
- onClick: (item: string) => {
- const graph = graphRef.current;
- switch (item) {
- // 放大
- case 'zoom-in':
- graph?.zoomTo(graph?.getZoom() + 0.2);
- break;
- case 'zoom-out':
- graph?.zoomBy(0.5);
- break;
- case 'auto-fit':
- graph?.fitView();
- break;
- }
- },
- getItems: () => {
- return [
- { id: 'zoom-in', value: 'zoom-in' },
- { id: 'zoom-out', value: 'zoom-out' },
- { id: 'auto-fit', value: 'auto-fit' }
- ];
- },
- style: {
- backgroundColor: 'var(--btn-background-color)'
- }
- },
- { key: 'background', type: 'background', background: 'var(--primary-color)' }
- ],
- transforms: ['process-parallel-edges'],
- autoFit: 'view'
- }}
- />
-
- );
-});
diff --git a/dinky-web/src/pages/DataStudio/Toolbar/Service/index.tsx b/dinky-web/src/pages/DataStudio/Toolbar/Service/index.tsx
index 95ea1af17e..def92262ec 100644
--- a/dinky-web/src/pages/DataStudio/Toolbar/Service/index.tsx
+++ b/dinky-web/src/pages/DataStudio/Toolbar/Service/index.tsx
@@ -17,7 +17,6 @@
*
*/
-import { connect } from '@@/exports';
import { CenterTab, DataStudioState } from '@/pages/DataStudio/model';
import { mapDispatchToProps } from '@/pages/DataStudio/DvaFunction';
import { Flex, Tabs, TabsProps, TreeDataNode } from 'antd';
@@ -49,11 +48,12 @@ import { getTabIcon } from '@/pages/DataStudio/function';
import { DIALECT } from '@/services/constants';
import { TableData } from '@/pages/DataStudio/Toolbar/Service/TableData';
import { isSql } from '@/pages/DataStudio/utils';
-import { LineageNew } from '@/pages/DataStudio/Toolbar/Service/LineageNew';
import { useAsyncEffect } from 'ahooks';
import { sleep } from '@antfu/utils';
import { l } from '@/utils/intl';
import { assert } from '@/pages/DataStudio/utils';
+import { connect } from '@umijs/max';
+import { Lineage } from '@/pages/DataStudio/Toolbar/Service/Lineage';
const Service = (props: { showDesc: boolean; tabs: CenterTab[]; action: any }) => {
const {
@@ -97,7 +97,7 @@ const Service = (props: { showDesc: boolean; tabs: CenterTab[]; action: any }) =
key: actionType,
label: l('menu.datastudio.lineage'),
icon: ,
- children:
+ children:
}
};
}, [actionType, params?.data]);
diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobLineage/index.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobLineage/index.tsx
index 1f980a10aa..15eea331f6 100644
--- a/dinky-web/src/pages/DevOps/JobDetail/JobLineage/index.tsx
+++ b/dinky-web/src/pages/DevOps/JobDetail/JobLineage/index.tsx
@@ -17,17 +17,15 @@
*
*/
-import LineageGraph from '@/components/LineageGraph';
import { queryDataByParams } from '@/services/BusinessCrud';
import { API_CONSTANTS } from '@/services/endpoints';
import { LineageDetailInfo } from '@/types/DevOps/data';
import { l } from '@/utils/intl';
-import { connect } from '@umijs/max';
import { Card, Result } from 'antd';
import React, { useEffect } from 'react';
-import 'react-lineage-dag/dist/index.css';
+import { Lineage } from '@/pages/DataStudio/Toolbar/Service/Lineage';
-const JobLineage: React.FC = (props) => {
+const JobLineage = (props: { jobDetail: { id: number } }) => {
const {
jobDetail: { id: jobInstanceId }
} = props;
@@ -48,9 +46,13 @@ const JobLineage: React.FC = (props) => {
return (
<>
-
+
{lineageData && (lineageData.tables.length !== 0 || lineageData.relations.length !== 0) ? (
-
+
) : (
)}