123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import React from "react";
- import styled from "styled-components";
- import {
- TransformWrapper,
- TransformComponent,
- ReactZoomPanPinchRef,
- } from "react-zoom-pan-pinch";
- import { Canvas } from "reaflow";
- import { getEdgeNodes } from "./helpers";
- import { CustomNode } from "./CustomNode";
- import { useLoading } from "src/hooks/useLoading";
- import { useConfig } from "src/hocs/config";
- import { Tools } from "../Editor/Tools";
- import { ConfigActionType } from "src/reducer/reducer";
- const StyledLiveEditor = styled.div`
- position: relative;
- `;
- const StyledEditorWrapper = styled.div`
- position: absolute;
- `;
- const StyledControls = styled.div`
- position: fixed;
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-template-rows: 1fr 1fr;
- gap: 8px;
- bottom: 8px;
- right: 8px;
- opacity: 0.9;
- button:hover {
- opacity: 0.7;
- }
- `;
- const wheelOptions = {
- step: 0.4,
- };
- export const LiveEditor: React.FC = React.memo(function LiveEditor() {
- const {
- states: { json, settings },
- dispatch,
- } = useConfig();
- const pageLoaded = useLoading();
- const wrapperRef = React.useRef<ReactZoomPanPinchRef | null>(null);
- const [data, setData] = React.useState({
- nodes: [],
- edges: [],
- });
- React.useEffect(() => {
- const { nodes, edges } = getEdgeNodes(json, settings.expand);
- setData({ nodes, edges });
- }, [json, settings.expand]);
- React.useEffect(() => {
- const wrapperRect = wrapperRef.current?.instance.wrapperComponent;
- const node = document.querySelector(
- `span[data-key*='${settings.searchNode}' i]`
- );
- document
- .querySelector("foreignObject.searched")
- ?.classList.remove("searched");
- if (wrapperRect && node && node.parentElement) {
- const newScale = 1;
- const x = Number(node.getAttribute("data-x"));
- const y = Number(node.getAttribute("data-y"));
- const newPositionX =
- (wrapperRect.offsetLeft - x) * newScale +
- node.getBoundingClientRect().width;
- const newPositionY =
- (wrapperRect.offsetTop - y) * newScale +
- node.getBoundingClientRect().height;
- node.parentElement.parentElement
- ?.closest("foreignObject")
- ?.classList.toggle("searched");
- wrapperRef.current?.setTransform(newPositionX, newPositionY, newScale);
- }
- }, [settings.searchNode]);
- const onCanvasClick = () => {
- const input = document.querySelector("input:focus") as HTMLInputElement;
- if (input) input.blur();
- };
- const onInit = (ref: ReactZoomPanPinchRef) =>
- dispatch({
- type: ConfigActionType.SET_ZOOM_PAN_PICNH_REF,
- payload: ref,
- });
- if (pageLoaded)
- return (
- <StyledLiveEditor>
- <Tools />
- <StyledEditorWrapper>
- <TransformWrapper
- maxScale={1.8}
- minScale={0.4}
- initialScale={0.8}
- ref={wrapperRef}
- limitToBounds={false}
- wheel={wheelOptions}
- onInit={onInit}
- >
- <TransformComponent>
- <Canvas
- nodes={data.nodes}
- node={CustomNode}
- edges={data.edges}
- maxWidth={20000}
- maxHeight={20000}
- center={false}
- zoomable={false}
- fit={true}
- direction={settings.layout}
- readonly
- key={settings.layout}
- onCanvasClick={onCanvasClick}
- />
- </TransformComponent>
- </TransformWrapper>
- </StyledEditorWrapper>
- </StyledLiveEditor>
- );
- return null;
- });
|