2020-11-19 15:10:28 +08:00
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
import {
|
|
|
|
|
EyeOutlined,
|
|
|
|
|
EyeInvisibleOutlined,
|
|
|
|
|
NodeIndexOutlined,
|
|
|
|
|
DisconnectOutlined,
|
|
|
|
|
TagOutlined,
|
|
|
|
|
SearchOutlined,
|
|
|
|
|
HighlightOutlined
|
|
|
|
|
} from '@ant-design/icons';
|
|
|
|
|
|
2020-11-21 13:38:09 +08:00
|
|
|
|
const isBrowser = typeof window !== 'undefined';
|
|
|
|
|
const G6 = isBrowser ? require('../../dist/g6.min.js') : null;
|
|
|
|
|
const insertCss = isBrowser ? require('insert-css') : null;
|
2020-11-25 11:57:37 +08:00
|
|
|
|
const modifyCSS = isBrowser ? require('@antv/dom-util/lib/modify-css').default : null;
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 13:38:09 +08:00
|
|
|
|
if (isBrowser) {
|
|
|
|
|
insertCss(`
|
2020-11-19 15:10:28 +08:00
|
|
|
|
#canvas-menu {
|
|
|
|
|
position: absolute;
|
|
|
|
|
z-index: 2;
|
|
|
|
|
left: 16px;
|
|
|
|
|
top: 80px;
|
|
|
|
|
width: fit-content;
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
background-color: rgba(54, 59, 64, 0);
|
|
|
|
|
border-radius: 24px;
|
|
|
|
|
box-shadow: 0 5px 18px 0 rgba(0, 0, 0, 0);
|
|
|
|
|
font-family: PingFangSC-Semibold;
|
|
|
|
|
transition: all 0.2s linear;
|
|
|
|
|
}
|
|
|
|
|
#canvas-menu:hover {
|
|
|
|
|
background-color: rgba(54, 59, 64, 1);
|
|
|
|
|
box-shadow: 0 5px 18px 0 rgba(0, 0, 0, 0.6);
|
|
|
|
|
}
|
|
|
|
|
.icon-span {
|
|
|
|
|
padding-left: 8px;
|
|
|
|
|
padding-right: 8px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
#search-node-input {
|
|
|
|
|
background-color: rgba(60, 60, 60, 0.95);
|
|
|
|
|
border-radius: 21px;
|
|
|
|
|
width: 100px;
|
|
|
|
|
border-color: rgba(80, 80, 80, 0.95);
|
|
|
|
|
border-style: solid;
|
|
|
|
|
color: rgba(255, 255, 255, 0.85);
|
|
|
|
|
}
|
|
|
|
|
#submit-button {
|
|
|
|
|
background-color: rgba(82, 115, 224, 0.2);
|
|
|
|
|
border-radius: 21px;
|
|
|
|
|
border-color: rgb(82, 115, 224);
|
|
|
|
|
border-style: solid;
|
|
|
|
|
color: rgba(152, 165, 254, 1);
|
|
|
|
|
margin-left: 4px;
|
|
|
|
|
}
|
|
|
|
|
.menu-tip {
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: calc(30% + 32px);
|
|
|
|
|
width: fit-content;
|
|
|
|
|
height: 40px;
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
top: 80px;
|
|
|
|
|
padding-left: 16px;
|
|
|
|
|
padding-right: 16px;
|
|
|
|
|
background-color: rgba(54, 59, 64, 0.5);
|
|
|
|
|
color: rgba(255, 255, 255, 0.65);
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
transition: all 0.2s linear;
|
|
|
|
|
font-family: PingFangSC-Semibold;
|
|
|
|
|
}
|
|
|
|
|
#g6-canavs-menu-item-tip {
|
|
|
|
|
position: absolute;
|
|
|
|
|
background-color: rgba(0,0,0, 0.65);
|
|
|
|
|
padding: 10px;
|
|
|
|
|
box-shadow: rgba(0, 0, 0, 0.6) 0px 0px 10px;
|
|
|
|
|
width: fit-content;
|
|
|
|
|
color: #fff;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
height: fit-content;
|
|
|
|
|
font-family: PingFangSC-Semibold;
|
|
|
|
|
transition: all 0.2s linear;
|
|
|
|
|
}
|
|
|
|
|
`);
|
2020-11-21 13:38:09 +08:00
|
|
|
|
}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
let fishEye = null;
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const CanvasMenu: React.FC<{
|
2020-11-19 15:10:28 +08:00
|
|
|
|
graph: any;
|
|
|
|
|
clickFisheyeIcon: (onlyDisable?: boolean) => void;
|
|
|
|
|
clickLassoIcon: (onlyDisable?: boolean) => void;
|
|
|
|
|
fisheyeEnabled: boolean;
|
|
|
|
|
lassoEnabled: boolean;
|
|
|
|
|
edgeLabelVisible: boolean;
|
|
|
|
|
setEdgeLabelVisible: (vis: boolean) => void;
|
|
|
|
|
searchNode: (id: string) => boolean;
|
|
|
|
|
handleFindPath: () => void;
|
|
|
|
|
stopLayout: () => void;
|
2020-11-21 00:41:45 +08:00
|
|
|
|
}> = ({
|
2020-11-19 15:10:28 +08:00
|
|
|
|
graph,
|
|
|
|
|
clickFisheyeIcon,
|
|
|
|
|
clickLassoIcon,
|
|
|
|
|
fisheyeEnabled,
|
|
|
|
|
lassoEnabled,
|
|
|
|
|
stopLayout,
|
|
|
|
|
edgeLabelVisible,
|
|
|
|
|
setEdgeLabelVisible,
|
|
|
|
|
searchNode,
|
|
|
|
|
handleFindPath
|
|
|
|
|
}) => {
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const { t } = useTranslation();
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// menu tip, 例如 “按下 ESC 退出鱼眼”
|
|
|
|
|
const [menuTip, setMenuTip] = useState({
|
|
|
|
|
text: '',
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
2020-11-19 15:10:28 +08:00
|
|
|
|
});
|
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// menu item tip
|
|
|
|
|
const [menuItemTip, setMenuItemTip] = useState({
|
2020-11-19 15:10:28 +08:00
|
|
|
|
text: '',
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const [enableSearch, setEnableSearch] = useState(false);
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const [enableSelectPathEnd, setEnableSelectPathEnd] = useState(false);
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const clickEdgeLabelController = () => {
|
|
|
|
|
setEdgeLabelVisible(!edgeLabelVisible);
|
|
|
|
|
}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const handleEnableSearch = () => {
|
2020-11-19 15:10:28 +08:00
|
|
|
|
// 关闭 lasso 框选
|
|
|
|
|
if (lassoEnabled) clickLassoIcon(true)
|
|
|
|
|
// 关闭选择路径端点
|
|
|
|
|
if (enableSelectPathEnd) setEnableSelectPathEnd(false);
|
|
|
|
|
// 关闭搜索节点框
|
|
|
|
|
if (enableSearch) setEnableSearch(false);
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 关闭 fisheye
|
|
|
|
|
if (fisheyeEnabled && fishEye) {
|
|
|
|
|
graph.removePlugin(fishEye);
|
|
|
|
|
clickFisheyeIcon(true);
|
|
|
|
|
}
|
|
|
|
|
setEnableSearch(old => {
|
|
|
|
|
if (old) {
|
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: '',
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: t('输入需要搜索的节点 ID,并点击 Submit 按钮'),
|
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// 放大
|
|
|
|
|
const handleZoomOut = () => {
|
|
|
|
|
if (!graph || graph.destroyed) return;
|
|
|
|
|
const current = graph.getZoom();
|
|
|
|
|
const canvas = graph.get('canvas');
|
|
|
|
|
const point = canvas.getPointByClient(canvas.get('width') / 2, canvas.get('height') / 2);
|
|
|
|
|
const pixelRatio = canvas.get('pixelRatio') || 1;
|
|
|
|
|
const ratio = 1 + 0.05 * 5;
|
|
|
|
|
if (ratio * current > 5) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
graph.zoom(ratio, { x: point.x / pixelRatio, y: point.y / pixelRatio });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 缩小
|
|
|
|
|
const handleZoomIn = () => {
|
|
|
|
|
if (!graph || graph.destroyed) return;
|
|
|
|
|
|
|
|
|
|
const current = graph.getZoom();
|
|
|
|
|
const canvas = graph.get('canvas');
|
|
|
|
|
const point = canvas.getPointByClient(canvas.get('width') / 2, canvas.get('height') / 2);
|
|
|
|
|
const pixelRatio = canvas.get('pixelRatio') || 1;
|
|
|
|
|
const ratio = 1 - 0.05 * 5;
|
|
|
|
|
if (ratio * current < 0.3) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
graph.zoom(ratio, { x: point.x / pixelRatio, y: point.y / pixelRatio });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleFitViw = () => {
|
|
|
|
|
if (!graph || graph.destroyed) return;
|
|
|
|
|
graph.fitView(16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleSearchNode = () => {
|
|
|
|
|
const value = (document.getElementById('search-node-input') as HTMLInputElement).value;
|
|
|
|
|
const found = searchNode(value);
|
|
|
|
|
if (!found) setMenuTip({
|
|
|
|
|
text: t('没有找到该节点'),
|
2020-11-19 15:10:28 +08:00
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
2020-11-21 00:41:45 +08:00
|
|
|
|
}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const showItemTip = (e, text) => {
|
|
|
|
|
const { clientX: x, clientY: y } = e;
|
|
|
|
|
setMenuItemTip({
|
|
|
|
|
text,
|
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
|
|
|
|
const tipDom = document.getElementById('g6-canavs-menu-item-tip')
|
|
|
|
|
modifyCSS(tipDom, {
|
|
|
|
|
top: `${124}px`,
|
|
|
|
|
left: `${x - 20}px`,
|
|
|
|
|
zIndex: 100,
|
2020-11-19 15:10:28 +08:00
|
|
|
|
});
|
2020-11-21 00:41:45 +08:00
|
|
|
|
};
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
const hideItemTip = () => {
|
|
|
|
|
setMenuItemTip({
|
|
|
|
|
text: '',
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
const tipDom = document.getElementById('g6-canavs-menu-item-tip')
|
|
|
|
|
modifyCSS(tipDom, {
|
|
|
|
|
zIndex: -100,
|
|
|
|
|
});
|
2020-11-19 15:10:28 +08:00
|
|
|
|
}
|
2020-11-21 00:41:45 +08:00
|
|
|
|
/**
|
|
|
|
|
* 打开或关闭鱼眼放大功能
|
|
|
|
|
*/
|
|
|
|
|
const toggleFishEye = () => {
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
if (!graph || graph.destroyed) return;
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 设置鼠标样式为默认
|
|
|
|
|
graph.get('canvas').setCursor('default');
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 关闭 FishEye
|
2020-11-19 15:10:28 +08:00
|
|
|
|
if (fisheyeEnabled && fishEye) {
|
|
|
|
|
graph.removePlugin(fishEye);
|
2020-11-21 00:41:45 +08:00
|
|
|
|
graph.setMode('default')
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: t('按下 Esc 键退出鱼眼放大镜'),
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// 停止布局
|
|
|
|
|
stopLayout();
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 关闭 lasso 框选
|
|
|
|
|
if (lassoEnabled) clickLassoIcon(true)
|
|
|
|
|
// 关闭选择路径端点
|
|
|
|
|
if (enableSelectPathEnd) setEnableSelectPathEnd(false);
|
|
|
|
|
// 关闭搜索节点框
|
|
|
|
|
if (enableSearch) setEnableSearch(false);
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: t('按下 Esc 键退出鱼眼放大镜'),
|
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 将交互模式切换到鱼眼只读模式,即不能缩放画布、框选节点、拉索选择节点等可能和鱼眼有冲突的操作
|
|
|
|
|
graph.setMode('fisheyeMode');
|
|
|
|
|
// 开启 FishEye
|
|
|
|
|
fishEye = new G6.Fisheye({
|
|
|
|
|
r: 249,
|
|
|
|
|
scaleRByWheel: true,
|
|
|
|
|
minR: 100,
|
|
|
|
|
maxR: 500
|
|
|
|
|
// showLabel: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
graph.addPlugin(fishEye);
|
|
|
|
|
}
|
|
|
|
|
clickFisheyeIcon();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 开启 lasso select 功能
|
|
|
|
|
const enabledLassoSelect = () => {
|
|
|
|
|
if (!graph || graph.destroyed) return;
|
|
|
|
|
clickLassoIcon();
|
|
|
|
|
if (!lassoEnabled) {
|
|
|
|
|
graph.setMode('lassoSelect');
|
|
|
|
|
|
|
|
|
|
// 设置鼠标样式为十字形
|
|
|
|
|
graph.get('canvas').setCursor('crosshair');
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
|
|
|
|
// 关闭 fisheye
|
2020-11-21 00:41:45 +08:00
|
|
|
|
if (fisheyeEnabled && fishEye) {
|
2020-11-19 15:10:28 +08:00
|
|
|
|
graph.removePlugin(fishEye);
|
|
|
|
|
clickFisheyeIcon(true);
|
|
|
|
|
}
|
2020-11-21 00:41:45 +08:00
|
|
|
|
// 关闭选择路径端点
|
|
|
|
|
if (enableSelectPathEnd) setEnableSelectPathEnd(false);
|
2020-11-19 15:10:28 +08:00
|
|
|
|
// 关闭搜索节点框
|
|
|
|
|
if (enableSearch) setEnableSearch(false);
|
|
|
|
|
|
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
2020-11-21 00:41:45 +08:00
|
|
|
|
text: t('按下 Esc 键退出拉索选择模式'),
|
2020-11-19 15:10:28 +08:00
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
2020-11-21 00:41:45 +08:00
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
graph.setMode('default');
|
|
|
|
|
|
|
|
|
|
// 设置鼠标样式为默认
|
|
|
|
|
graph.get('canvas').setCursor('default');
|
|
|
|
|
|
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: t('按下 Esc 键退出拉索选择模式'),
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
2020-11-19 15:10:28 +08:00
|
|
|
|
}
|
2020-11-21 00:41:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 开启选择两个节点显示最短路径
|
|
|
|
|
const handleEnableSelectPathEnd = () => {
|
|
|
|
|
setEnableSelectPathEnd(old => {
|
|
|
|
|
if (!old) {
|
|
|
|
|
graph.setMode('default');
|
|
|
|
|
// 关闭 fisheye
|
|
|
|
|
if (fishEye) {
|
|
|
|
|
graph.removePlugin(fishEye);
|
|
|
|
|
clickFisheyeIcon(true);
|
|
|
|
|
}
|
|
|
|
|
// 关闭 lasso 框选
|
|
|
|
|
if (lassoEnabled) clickLassoIcon(true)
|
|
|
|
|
|
|
|
|
|
// 关闭搜索节点框
|
|
|
|
|
if (enableSearch) setEnableSearch(false);
|
|
|
|
|
|
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: t('按住 SHIFT 键并点选两个节点作为路径起终点'),
|
|
|
|
|
display: 'block',
|
|
|
|
|
opacity: 1
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
|
|
|
|
text: '',
|
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const escListener = e => {
|
|
|
|
|
if (!graph || graph.destroyed) return;
|
|
|
|
|
if (e.key !== 'Escape') return;
|
|
|
|
|
if (fishEye) {
|
|
|
|
|
graph.removePlugin(fishEye);
|
|
|
|
|
clickFisheyeIcon(true);
|
|
|
|
|
}
|
|
|
|
|
// 关闭 lasso 框选
|
|
|
|
|
graph.setMode('default');
|
|
|
|
|
// 关闭搜索节点框
|
|
|
|
|
setEnableSearch(false);
|
|
|
|
|
// 关闭选择路径端点
|
|
|
|
|
setEnableSelectPathEnd(false);
|
|
|
|
|
|
|
|
|
|
// 设置鼠标样式为默认
|
|
|
|
|
graph.get('canvas').setCursor('default');
|
|
|
|
|
clickLassoIcon(true);
|
|
|
|
|
|
2020-11-19 15:10:28 +08:00
|
|
|
|
// 设置 menuTip
|
|
|
|
|
setMenuTip({
|
2020-11-21 00:41:45 +08:00
|
|
|
|
text: t('按下 Esc 键退出当前模式'),
|
2020-11-19 15:10:28 +08:00
|
|
|
|
display: 'none',
|
|
|
|
|
opacity: 0
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-21 00:41:45 +08:00
|
|
|
|
useEffect(() => {
|
2020-11-21 11:56:53 +08:00
|
|
|
|
if (typeof window !== 'undefined') {
|
2020-11-21 01:08:19 +08:00
|
|
|
|
window.addEventListener("keydown", escListener.bind(this));
|
|
|
|
|
return window.removeEventListener("keydown", escListener.bind(this));
|
|
|
|
|
}
|
2020-11-21 00:41:45 +08:00
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const iconStyle = {
|
|
|
|
|
disable: { color: 'rgba(255, 255, 255, 0.85)' },
|
|
|
|
|
enable: { color: 'rgba(82, 115, 224, 1)' },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<div id='canvas-menu'>
|
|
|
|
|
<div className='icon-container'>
|
|
|
|
|
<span className='icon-span'
|
|
|
|
|
style={{ backgroundColor: 'rgba(0, 0, 0, 0)' }}
|
|
|
|
|
onClick={clickEdgeLabelController}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, edgeLabelVisible ? t('隐藏边标签') : t('显示边标签'))}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
{edgeLabelVisible ? <DisconnectOutlined style={iconStyle.enable} /> : <TagOutlined style={iconStyle.disable} />}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
</span>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<span className='icon-span'
|
|
|
|
|
onClick={toggleFishEye}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, fisheyeEnabled ? t('关闭鱼眼放大镜') : t('打开鱼眼放大镜'))}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
{fisheyeEnabled ? <EyeInvisibleOutlined style={iconStyle.enable} /> : <EyeOutlined style={iconStyle.disable} />}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
</span>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<span className='icon-span'
|
|
|
|
|
onClick={enabledLassoSelect}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, lassoEnabled ? t('关闭拉索选择模式') : t('打开拉索选择模式'))}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<HighlightOutlined style={lassoEnabled ? iconStyle.enable : iconStyle.disable} />
|
2020-11-19 15:10:28 +08:00
|
|
|
|
</span>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<span className='icon-span'
|
|
|
|
|
onClick={handleEnableSelectPathEnd}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('搜索最短路径'))}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<NodeIndexOutlined style={enableSelectPathEnd ? iconStyle.enable : iconStyle.disable} />
|
2020-11-19 15:10:28 +08:00
|
|
|
|
</span>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<span className='icon-span' style={{ width: 'fit-content', ...iconStyle.disable }} >
|
|
|
|
|
<span className='zoom-icon'
|
|
|
|
|
onClick={handleZoomIn}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('缩小'))}
|
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
|
|
|
|
-
|
|
|
|
|
</span>
|
|
|
|
|
<span className='zoom-icon'
|
|
|
|
|
onClick={handleFitViw}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('图内容适配容器,快捷键:ctrl + 1'))}
|
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
style={{ paddingLeft: '8px', paddingRight: '8px' }}
|
|
|
|
|
>
|
|
|
|
|
FIT
|
|
|
|
|
</span>
|
|
|
|
|
<span className='zoom-icon'
|
|
|
|
|
onClick={handleZoomOut}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('放大'))}
|
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
|
|
|
|
+
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span className='icon-span'
|
|
|
|
|
onClick={handleEnableSearch}
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('输入 ID 搜索节点'))}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<SearchOutlined style={enableSearch ? iconStyle.enable : iconStyle.disable} />
|
|
|
|
|
</span>
|
|
|
|
|
{enableSearch &&
|
|
|
|
|
<span
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('输入需要搜索的节点 ID,并点击 Submit 按钮'))}
|
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
|
|
|
|
<input type="text" id="search-node-input" />
|
|
|
|
|
<button id="submit-button" onClick={handleSearchNode}>Submit</button>
|
|
|
|
|
</span>
|
|
|
|
|
}
|
|
|
|
|
{enableSelectPathEnd &&
|
|
|
|
|
<span
|
|
|
|
|
onMouseEnter={e => showItemTip(e, t('选择有且仅有两个节点作为端点,并点击 Find Path 按钮'))}
|
|
|
|
|
onMouseLeave={hideItemTip}
|
|
|
|
|
>
|
|
|
|
|
<button id="submit-button" onClick={handleFindPath}>Find Path</button>
|
|
|
|
|
</span>}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='menu-tip' style={{ opacity: menuTip.opacity }}>
|
|
|
|
|
{menuTip.text}
|
2020-11-19 15:10:28 +08:00
|
|
|
|
</div>
|
2020-11-21 00:41:45 +08:00
|
|
|
|
<div id='g6-canavs-menu-item-tip' style={{ opacity: menuItemTip.opacity }}>
|
|
|
|
|
{menuItemTip.text}
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
2020-11-19 15:10:28 +08:00
|
|
|
|
|
|
|
|
|
export default CanvasMenu;
|