Skip to content

Commit

Permalink
[Optimize][Web]Optimize some page layouts, update web dependencies, a…
Browse files Browse the repository at this point in the history
…nd fix some bugs (DataLinkDC#3809)

Co-authored-by: zackyoungh <zackyoungh@users.noreply.github.com>
  • Loading branch information
zackyoungh and zackyoungh authored Sep 15, 2024
1 parent 131ded5 commit c8b89c5
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions dinky-admin/src/main/resources/mapper/JobInstanceMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@
and dh.type = #{param.type}
</if>
<if test='param.taskId!=null and param.taskId!=""'>
and a.task_id in
<foreach collection="param.taskId" item="taskId" separator="," open="(" close=")" index="">
#{taskId}
</foreach>
and a.task_id = #{param.taskId}
</if>
<if test='param.step!=null and param.step!=""'>
and a.step = #{param.step}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.dinky.metadata.result.JdbcSelectResult;
import org.dinky.utils.JsonUtils;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -52,9 +53,17 @@ public interface Driver extends AutoCloseable {
static Optional<Driver> get(String type) {
Asserts.checkNotNull(type, "数据源Type配置不能为空");
ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class);
for (Driver driver : drivers) {
if (driver.canHandle(type)) {
return Optional.of(driver);
Iterator<Driver> driversIterator = drivers.iterator();

// There may be an issue where the class can't be found, so the exception needs to be caught
while (driversIterator.hasNext()) {
try {
Driver driver = driversIterator.next();
if (driver.canHandle(type)) {
return Optional.of(driver);
}
} catch (Throwable t) {
// Do nothing
}
}
return Optional.empty();
Expand Down Expand Up @@ -233,7 +242,7 @@ static Driver build(String connector, String url, String username, String passwo
* 得到分割表
*
* @param tableRegList 表正则列表
* @param splitConfig 分库配置
* @param splitConfig 分库配置
* @return {@link Set}<{@link Table}>
*/
default Set<Table> getSplitTables(List<String> tableRegList, Map<String, String> splitConfig) {
Expand Down
14 changes: 7 additions & 7 deletions dinky-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
],
"dependencies": {
"@andrewray/react-multi-split-pane": "^0.3.5",
"@ant-design/charts": "^2.1.1",
"@ant-design/charts": "^2.2.1",
"@ant-design/icons": "^5.3.7",
"@ant-design/pro-components": "^2.7.10",
"@ant-design/pro-layout": "^7.19.8",
"@ant-design/pro-table": "^3.16.6",
"@ant-design/pro-components": "^2.7.18",
"@ant-design/pro-layout": "^7.20.1",
"@ant-design/pro-table": "^3.17.2",
"@ant-design/use-emotion-css": "^1.0.4",
"@antv/g2": "^5.2.0",
"@antv/g2": "^5.2.5",
"@antv/layout": "0.3.25",
"@antv/x6": "^2.18.1",
"@antv/x6-plugin-selection": "^2.2.2",
Expand All @@ -52,9 +52,9 @@
"@umijs/route-utils": "^4.0.1",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"antd": "^5.18.2",
"antd": "^5.20.6",
"antd-style": "^3.6.2",
"butterfly-dag": "^4.3.28",
"butterfly-dag": "^4.3.29",
"classnames": "^2.5.1",
"dayjs": "^1.11.11",
"echarts": "^5.5.0",
Expand Down
12 changes: 6 additions & 6 deletions dinky-web/src/components/Flink/FlinkDag/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Platform } from '@antv/x6';
import { Options } from '@antv/x6/lib/graph/options';
import Connecting = Options.Connecting;
import Manual = Options.Manual;
import { Cell } from '@antv/x6/src/model/cell';

export const edgeConfig = {
markup: [
Expand Down Expand Up @@ -76,7 +77,7 @@ export const portConfig = {
attrs: {
circle: {
r: 4,
magnet: true,
magnet: false,
stroke: 'transparent',
strokeWidth: 1,
fill: 'transparent'
Expand All @@ -88,14 +89,14 @@ export const portConfig = {
position: {
name: 'right',
args: {
dx: -32
dx: 10
}
},

attrs: {
circle: {
r: 4,
magnet: true,
magnet: false,
stroke: 'transparent',
strokeWidth: 1,
fill: 'transparent'
Expand Down Expand Up @@ -153,18 +154,17 @@ export const graphConfig: Partial<Manual> = {
modifiers: 'ctrl',
factor: 1.1,
maxScale: 1.5,
minScale: 0.5
minScale: 0.1
},
connecting: graphConnectConfig
};

export const layoutConfig: DagreLayoutOptions = {
type: 'dagre',
rankdir: 'LR',
align: 'UL',
ranksep: 120,
nodesep: 40,
controlPoints: true
controlPoints: false
};

export const zoomOptions = {
Expand Down
143 changes: 137 additions & 6 deletions dinky-web/src/components/Flink/FlinkDag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ import { getDataByParamsReturnResult } from '@/services/BusinessCrud';
import { API_CONSTANTS } from '@/services/endpoints';
import { Jobs } from '@/types/DevOps/data';
import { DagreLayout } from '@antv/layout';
import { Edge, Graph } from '@antv/x6';
import { Edge, Graph, Node } from '@antv/x6';
import { Rectangle } from '@antv/x6-geometry';
import { Selection } from '@antv/x6-plugin-selection';
import { register } from '@antv/x6-react-shape';
import { Drawer, Select, Slider, Table, Tabs, TabsProps, Tag, Typography } from 'antd';
import { useEffect, useRef, useState } from 'react';
import './index.css';
import dagre from 'dagre';

export type DagProps = {
job: Jobs.Job;
Expand Down Expand Up @@ -191,7 +192,7 @@ const FlinkDag = (props: DagProps) => {
const initGraph = (flinkData: any) => {
register({
shape: 'data-processing-dag-node',
width: 270,
width: 240,
height: 140,
component: onlyPlan ? DagPlanNode : DagDataNode,
ports: portConfig
Expand Down Expand Up @@ -223,12 +224,140 @@ const FlinkDag = (props: DagProps) => {
// Automatically zoom to fit
graph.zoomToFit(zoomOptions);
graph.on('scale', ({ sx }) => setZoom(sx));
graph.centerContent();
graph?.zoomTo(zoom);
updateDag(job?.vertices, graph);
initListen(graph);
layout(graph);
graph.centerContent();
return graph;
};
const getMaxListLength = (listOfLists: any[]) => {
return listOfLists.reduce((maxLength, currentList) => {
return Math.max(maxLength, currentList.length);
}, 0);
};
const calculateGraphMetrics = (graph: Graph) => {
const nodes = graph.getNodes();
const edges = graph.getEdges();

let maxWidth = getMaxListLength(Object.values(graph.model.outgoings));
let maxDepth = 0;

const nodeDepths = new Map<string, number>();

const calculateDepth = (node: Node, depth: number) => {
if (nodeDepths.has(node.id)) {
return nodeDepths.get(node.id)!;
}
nodeDepths.set(node.id, depth);

const outgoingEdges = edges.filter((edge) => edge.getSourceCellId() === node.id);
outgoingEdges.forEach((edge) => {
const targetNode = graph.getCellById(edge.getTargetCellId()) as Node;
calculateDepth(targetNode, depth + 1);
});

return depth;
};

nodes.forEach((node) => {
if (!nodeDepths.has(node.id)) {
calculateDepth(node, 1);
}
});

const calculatePathLength = (node: Node, length: number) => {
const outgoingEdges = edges.filter((edge) => edge.getSourceCellId() === node.id);
if (outgoingEdges.length === 0) {
maxDepth = Math.max(maxDepth, length);
return;
}
outgoingEdges.forEach((edge) => {
const targetNode = graph.getCellById(edge.getTargetCellId()) as Node;
calculatePathLength(targetNode, length + 1);
});
};

nodes.forEach((node) => {
calculatePathLength(node, 1);
});

return { maxWidth, maxDepth };
};

// 自动布局
function layout(graph: Graph) {
const { maxDepth, maxWidth } = calculateGraphMetrics(graph);
// 布局方向
let dir: string = 'LR';
let ranksep = 200;
let nodesep = 40;

if (maxDepth < maxWidth) {
dir = 'TB';
ranksep = 40;
nodesep = 40;
}

const nodes = graph.getNodes();
const edges = graph.getEdges();
const g = new dagre.graphlib.Graph();
g.setGraph({ ...layoutConfig, ranksep, nodesep, rankdir: dir });
g.setDefaultEdgeLabel(() => ({}));

nodes.forEach((node) => {
g.setNode(node.id, { width: 240, height: 140 });
});

edges.forEach((edge) => {
const source = edge.getSource();
const target = edge.getTarget();
g.setEdge(source.cell, target.cell);
});

dagre.layout(g);

g.nodes().forEach((id) => {
const node = graph.getCellById(id) as Node;
if (node) {
const pos = g.node(id);
node.position(pos.x, pos.y);
}
});

edges.forEach((edge) => {
const source = edge.getSourceNode()!;
const target = edge.getTargetNode()!;
const sourceBBox = source.getBBox();
const targetBBox = target.getBBox();

if ((dir === 'LR' || dir === 'RL') && sourceBBox.y !== targetBBox.y) {
const gap =
dir === 'LR'
? targetBBox.x - sourceBBox.x - sourceBBox.width
: -sourceBBox.x + targetBBox.x + targetBBox.width;
const fix = dir === 'LR' ? sourceBBox.width : 0;
const x = sourceBBox.x + fix + gap / 2;
edge.setVertices([
{ x, y: sourceBBox.center.y },
{ x, y: targetBBox.center.y }
]);
} else if ((dir === 'TB' || dir === 'BT') && sourceBBox.x !== targetBBox.x) {
const gap =
dir === 'TB'
? targetBBox.y - sourceBBox.y - sourceBBox.height
: -sourceBBox.y + targetBBox.y + targetBBox.height;
const fix = dir === 'TB' ? sourceBBox.height : 0;
const y = sourceBBox.y + fix + gap / 2;
edge.setVertices([
{ x: sourceBBox.center.x, y },
{ x: targetBBox.center.x, y }
]);
} else {
edge.setVertices([]);
}
});
}

useEffect(() => {
const flinkData = buildDag(job?.plan);
Expand Down Expand Up @@ -266,7 +395,7 @@ const FlinkDag = (props: DagProps) => {
<Slider
vertical
value={zoom}
min={0.5}
min={0.1}
max={1.5}
tooltip={{ open: false }}
step={0.01}
Expand All @@ -275,8 +404,10 @@ const FlinkDag = (props: DagProps) => {
</div>
<div style={{ height: '100%', width: '100%' }} ref={container} />
<Drawer
headerStyle={{ paddingBlock: 5 }}
bodyStyle={{ paddingBlock: 5 }}
styles={{
header: { paddingBlock: 5 },
body: { paddingBlock: 5 }
}}
open={open}
getContainer={false}
width={'65%'}
Expand Down
4 changes: 2 additions & 2 deletions dinky-web/src/components/JobTags/StatusTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ const StatusTag = (props: StatusTagProps) => {
case JOB_STATUS.INITIALIZING:
return {
icon: <ClockCircleOutlined />,
color: 'default',
color: 'blue',
text: 'INITIALIZING'
};
case JOB_STATUS.RESTARTING:
return {
icon: <ClockCircleOutlined />,
color: 'default',
color: '#13c2c2',
text: 'RESTARTING'
};
case JOB_STATUS.CREATED:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const JobConfigTab = (props: JobProps) => {
<JobDesc jobDetail={jobDetail} />
<ProCard
style={{
height: '40vh'
height: '60vh'
}}
>
{job ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ export type VerticesTableListItem = {
* Renders the JobConfigTab component.
*
* @param {JobProps} props - The component props containing the job detail.
* @returns {JSX.Element} - The rendered JobConfigTab component.
*/
const FlinkTable = (props: JobProps): JSX.Element => {
const FlinkTable = (props: JobProps) => {
const { jobDetail } = props;

const columns: ProColumns<VerticesTableListItem>[] = [
Expand Down Expand Up @@ -142,11 +141,12 @@ const FlinkTable = (props: JobProps): JSX.Element => {
<>
<ProCard>
<ProTable
key={jobDetail?.id.toString()}
defaultSize={'small'}
columns={columns}
style={{ width: '100%', height: '30vh' }}
dataSource={jobDetail?.jobDataDto?.job?.vertices}
rowKey='name'
rowKey={jobDetail?.id.toString()}
pagination={{
defaultPageSize: 10,
showSizeChanger: true,
Expand Down
1 change: 1 addition & 0 deletions dinky-web/src/pages/DevOps/JobDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const JobDetail = (props: any) => {

return (
<PageContainer
key={id}
loading={!data}
title={jobInfoDetail?.instance?.name}
subTitle={<JobLifeCycleTag status={jobInfoDetail?.instance?.step} />}
Expand Down

0 comments on commit c8b89c5

Please sign in to comment.