Skip to content

Commit

Permalink
feat: 添加全局 namespace 定义
Browse files Browse the repository at this point in the history
  • Loading branch information
谢新根 committed Jan 18, 2024
1 parent 30681d5 commit c898da9
Show file tree
Hide file tree
Showing 14 changed files with 1,521 additions and 1,486 deletions.
589 changes: 294 additions & 295 deletions docs/_assets/materials.ts

Large diffs are not rendered by default.

527 changes: 267 additions & 260 deletions src/Editor/index.tsx

Large diffs are not rendered by default.

301 changes: 152 additions & 149 deletions src/Preview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,180 +1,183 @@
import TopologyContext from '@/contexts/topology';
import X6ReactPortalProvider from '@/contexts/x6-react-portal';
import useGraph from '@/hooks/useGraph';
import type { Topology } from '@/types/global.d';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
import { Graph, Model } from '@antv/x6';
import { useSize } from 'ahooks';
import { Button, Layout, Space } from 'antd';
import classNames from 'classnames';
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState,
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState,
} from 'react';

import classNames from 'classnames';
import { Button, Layout, Space } from 'antd';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
import { useSize } from 'ahooks';
import { GRAPH_ZOOM } from '@/constants';
import TopologyContext from '@/contexts/topology';
import X6ReactPortalProvider from '@/contexts/x6-react-portal';
import useGraph from '@/hooks/useGraph';
import '@/index.less';
import EventBus from '@/utils/event-bus';

export type EditorProps = {
iconMap: Record<string, Topology.TopologyIconProp>;
value?: Model.FromJSONData;
style?: React.CSSProperties;
className?: string;
iconMap: Record<string, Topology.TopologyIconProp>;
value?: Model.FromJSONData;
style?: React.CSSProperties;
className?: string;
};

export type EditorRef = {
getInstance: () => Graph;
getInstance: () => Graph;
};

const zoomFitPadding = 14;

const Editor: React.ForwardRefRenderFunction<EditorRef, EditorProps> = (
props,
ref,
props,
ref,
) => {
const graphContainerRef = useRef<any>();
const eventBusRef = useRef<EventBus>(new EventBus());
const [zoom, setZoom] = useState(1);
const graphContainerSize = useSize(graphContainerRef);
const graphContainerRef = useRef<any>();
const eventBusRef = useRef<EventBus>(new EventBus());
const [zoom, setZoom] = useState(1);
const graphContainerSize = useSize(graphContainerRef);

const [graphInstance] = useGraph(graphContainerRef, eventBusRef.current, {
graphOption: {
width: graphContainerSize?.width,
height: graphContainerSize?.height,
// autoResize: true,
grid: false,
embedding: false,
interacting: false,
panning: true,
},
pluginOption: {
transform: false,
selection: false,
snapline: false,
keyboard: false,
clipboard: false,
history: false,
scroller: false,
},
keyBoardEvent: false,
graphEvent: false,
});

const handleZoomToFit = () => {
if (!graphInstance) {
return;
}
graphInstance.zoomToFit({
padding: zoomFitPadding,
const [graphInstance] = useGraph(graphContainerRef, eventBusRef.current, {
graphOption: {
width: graphContainerSize?.width,
height: graphContainerSize?.height,
// autoResize: true,
grid: false,
embedding: false,
interacting: false,
panning: true,
},
pluginOption: {
transform: false,
selection: false,
snapline: false,
keyboard: false,
clipboard: false,
history: false,
scroller: false,
},
keyBoardEvent: false,
graphEvent: false,
});
};

useEffect(() => {
if (graphInstance) {
graphInstance.resize(
graphContainerSize?.width,
graphContainerSize?.height,
);
graphInstance.zoomToFit({
padding: zoomFitPadding,
});
}
}, [graphInstance, graphContainerSize]);
const handleZoomToFit = () => {
if (!graphInstance) {
return;
}
graphInstance.zoomToFit({
padding: zoomFitPadding,
});
};

useEffect(() => {
if (graphInstance) {
if (props.value) {
graphInstance.fromJSON(props.value);
} else {
graphInstance.clearCells();
}
}
}, [graphInstance, props.value]);
useEffect(() => {
if (graphInstance) {
graphInstance.resize(
graphContainerSize?.width,
graphContainerSize?.height,
);
graphInstance.zoomToFit({
padding: zoomFitPadding,
});
}
}, [graphInstance, graphContainerSize]);

useEffect(() => {
if (!graphInstance) {
return;
}
graphInstance.on('scale', () => {
const zoom = graphInstance.zoom();
let zoomValue = Math.min(zoom, GRAPH_ZOOM.max);
zoomValue = Math.max(zoomValue, GRAPH_ZOOM.min);
setZoom(Math.max(zoomValue));
});
}, [graphInstance]);
useEffect(() => {
if (graphInstance) {
if (props.value) {
graphInstance.fromJSON(props.value);
} else {
graphInstance.clearCells();
}
}
}, [graphInstance, props.value]);

useImperativeHandle(ref, () => ({
getInstance: () => graphInstance as Graph,
}));
useEffect(() => {
if (!graphInstance) {
return;
}
graphInstance.on('scale', () => {
const zoom = graphInstance.zoom();
let zoomValue = Math.min(zoom, GRAPH_ZOOM.max);
zoomValue = Math.max(zoomValue, GRAPH_ZOOM.min);
setZoom(Math.max(zoomValue));
});
}, [graphInstance]);

const handleChangeZoom = (zoom: number, absolute = false) => {
if (!graphInstance) {
return;
}
graphInstance.zoom(zoom, {
minScale: GRAPH_ZOOM.min,
maxScale: GRAPH_ZOOM.max,
absolute,
});
};
useImperativeHandle(ref, () => ({
getInstance: () => graphInstance as Graph,
}));

const handleChangeZoom = (zoom: number, absolute = false) => {
if (!graphInstance) {
return;
}
graphInstance.zoom(zoom, {
minScale: GRAPH_ZOOM.min,
maxScale: GRAPH_ZOOM.max,
absolute,
});
};

const zoomText = Math.floor(zoom * 100) + '%';
const zoomText = Math.floor(zoom * 100) + '%';

return (
<TopologyContext.Provider
value={{
graph: graphInstance,
iconMap: props.iconMap,
eventBus: eventBusRef.current,
}}
>
<X6ReactPortalProvider />
<Layout
style={props.style}
className={classNames(
'topology-designable',
'topology-designable-preview',
props.className,
)}
>
<Layout.Content
style={{ overflow: 'initial' }}
className="topology-designable-content"
return (
<TopologyContext.Provider
value={{
graph: graphInstance,
iconMap: props.iconMap,
eventBus: eventBusRef.current,
}}
>
<div className="canvas" style={{ width: '100%', height: '100%' }}>
<div className="preview-zoom">
<Space.Compact size="small" block>
<Button
icon={<MinusOutlined />}
onClick={() => handleChangeZoom(-0.1)}
/>
<Button
title={`单击切换到自适应\n双击切换到100%`}
onClick={handleZoomToFit}
onDoubleClick={() => handleChangeZoom(1, true)}
<X6ReactPortalProvider />
<Layout
style={props.style}
className={classNames(
'topology-designable',
'topology-designable-preview',
props.className,
)}
>
<Layout.Content
style={{ overflow: 'initial' }}
className="topology-designable-content"
>
{zoomText}
</Button>
<Button
icon={<PlusOutlined />}
onClick={() => handleChangeZoom(0.1)}
/>
</Space.Compact>
</div>
<div
className="editor editor-preview"
style={{ height: '100%' }}
ref={graphContainerRef}
></div>
</div>
</Layout.Content>
</Layout>
</TopologyContext.Provider>
);
<div
className="canvas"
style={{ width: '100%', height: '100%' }}
>
<div className="preview-zoom">
<Space.Compact size="small" block>
<Button
icon={<MinusOutlined />}
onClick={() => handleChangeZoom(-0.1)}
/>
<Button
title={`单击切换到自适应\n双击切换到100%`}
onClick={handleZoomToFit}
onDoubleClick={() =>
handleChangeZoom(1, true)
}
>
{zoomText}
</Button>
<Button
icon={<PlusOutlined />}
onClick={() => handleChangeZoom(0.1)}
/>
</Space.Compact>
</div>
<div
className="editor editor-preview"
style={{ height: '100%' }}
ref={graphContainerRef}
></div>
</div>
</Layout.Content>
</Layout>
</TopologyContext.Provider>
);
};

export default forwardRef(Editor);
Loading

0 comments on commit c898da9

Please sign in to comment.