From 1bd675f9ef36d863dcfdc51a05748c90e74fe877 Mon Sep 17 00:00:00 2001 From: nflnkr Date: Sun, 31 Dec 2023 13:36:30 +0300 Subject: [PATCH] cs fixed zoom & fit graph to root node --- .../Questions/BranchingMap/CsComponent.tsx | 25 +- .../Questions/BranchingMap/hooks/usePopper.ts | 323 +++++++++--------- 2 files changed, 181 insertions(+), 167 deletions(-) diff --git a/src/pages/Questions/BranchingMap/CsComponent.tsx b/src/pages/Questions/BranchingMap/CsComponent.tsx index 87900d79..ce30b5b7 100644 --- a/src/pages/Questions/BranchingMap/CsComponent.tsx +++ b/src/pages/Questions/BranchingMap/CsComponent.tsx @@ -95,6 +95,23 @@ function CsComponent({ gearsContainer, }); + function fitGraphToRootNode() { + const cy = cyRef.current; + if (!cy) return; + + const rootNode = cy.nodes().filter((n) => n.data("root"))[0]; + if (!rootNode) throw new Error("Root node not found"); + + const height = cy.height(); + const position = rootNode.position(); + const shift = rootNode.width() / 2; + + cy.pan({ + x: position.x + shift, + y: position.y + height / 2, + }); + } + useLayoutEffect(() => { const cy = cyRef?.current; if (desireToOpenABranchingModal) { @@ -301,7 +318,7 @@ function CsComponent({ // cy.data('changed', true) const elecs = eles?.layout(layoutOptions).run(); cy?.on("add", () => cy.data("changed", true)); - cy?.fit(); + fitGraphToRootNode(); //cy?.layout().run() firstRender.current = false; } @@ -335,9 +352,7 @@ function CsComponent({ fontSize: "16px", }} variant="text" - onClick={() => { - cyRef.current?.fit(); - }} + onClick={fitGraphToRootNode} > Выровнять @@ -358,6 +373,8 @@ function CsComponent({ cyRef.current = cy; }} autoungrabify={true} + zoom={0.6} + zoomingEnabled={false} /> diff --git a/src/pages/Questions/BranchingMap/hooks/usePopper.ts b/src/pages/Questions/BranchingMap/hooks/usePopper.ts index c3800c76..4f69a6ee 100644 --- a/src/pages/Questions/BranchingMap/hooks/usePopper.ts +++ b/src/pages/Questions/BranchingMap/hooks/usePopper.ts @@ -104,157 +104,153 @@ export const usePopper = ({ container.append(layoutsContainer.current); } - const ext = cy.extent(); - const nodesInView = cy.nodes().filter((n) => { - const bb = n.boundingBox(); - return ( - bb.x2 > ext.x1 && bb.x1 < ext.x2 && bb.y2 > ext.y1 && bb.y1 < ext.y2 - ); - }); - cy?.removeAllListeners(); - nodesInView.toArray()?.forEach((item) => { - const node = item as NodeSingularWithPopper; + cy + .nodes() + .toArray() + ?.forEach((item) => { + const node = item as NodeSingularWithPopper; - const layoutsPopper = node.popper({ - popper: { - placement: "left", - modifiers: [{ name: "flip", options: { boundary: node } }], - }, - content: ([item]) => { - const itemId = item.id(); - const itemElement = layoutsContainer.current?.querySelector( - `.popper-layout[data-id='${itemId}']`, - ); - if (itemElement) { - return itemElement; - } - - const layoutElement = document.createElement("div"); - layoutElement.style.zIndex = "0"; - layoutElement.classList.add("popper-layout"); - layoutElement.setAttribute("data-id", item.id()); - layoutElement.addEventListener("mouseup", () => { - //Узнаём грани, идущие от этой ноды - setModalQuestionParentContentId(item.id()); - setOpenedModalQuestions(true); - }); - layoutsContainer.current?.appendChild(layoutElement); - - return layoutElement; - }, - }); - - const plusesPopper = node.popper({ - popper: { - placement: "right", - modifiers: [{ name: "flip", options: { boundary: node } }], - }, - content: ([item]) => { - const itemId = item.id(); - const itemElement = plusesContainer.current?.querySelector( - `.popper-plus[data-id='${itemId}']`, - ); - if (itemElement) { - return itemElement; - } - - const plusElement = document.createElement("div"); - plusElement.classList.add("popper-plus"); - plusElement.setAttribute("data-id", item.id()); - plusElement.style.zIndex = "1"; - plusElement.addEventListener("mouseup", () => { - setStartCreate(node.id()); - }); - - plusesContainer.current?.appendChild(plusElement); - - return plusElement; - }, - }); - - const crossesPopper = node.popper({ - popper: { - placement: "top-end", - modifiers: [{ name: "flip", options: { boundary: node } }], - }, - content: ([item]) => { - const itemId = item.id(); - const itemElement = crossesContainer.current?.querySelector( - `.popper-cross[data-id='${itemId}']`, - ); - if (itemElement) { - return itemElement; - } - - const crossElement = document.createElement("div"); - crossElement.classList.add("popper-cross"); - crossElement.setAttribute("data-id", item.id()); - crossElement.style.zIndex = "2"; - crossesContainer.current?.appendChild(crossElement); - crossElement.addEventListener("mouseup", () => { - setStartRemove(node.id()); - }); - - return crossElement; - }, - }); - let gearsPopper: Popper | null = null; - if (node.data().root !== true) { - console.log(node.data("parentType")); - const parentQuestion = getQuestionByContentId(node.data("parentType")); - - gearsPopper = node.popper({ + const layoutsPopper = node.popper({ popper: { placement: "left", modifiers: [{ name: "flip", options: { boundary: node } }], }, content: ([item]) => { const itemId = item.id(); - - const itemElement = gearsContainer.current?.querySelector( - `.popper-gear[data-id='${itemId}']`, + const itemElement = layoutsContainer.current?.querySelector( + `.popper-layout[data-id='${itemId}']`, ); if (itemElement) { return itemElement; } - const gearElement = document.createElement("div"); - gearElement.classList.add("popper-gear"); - gearElement.setAttribute("data-id", item.id()); - gearElement.style.zIndex = "1"; - gearsContainer.current?.appendChild(gearElement); - gearElement.addEventListener("mouseup", () => { - updateOpenedModalSettingsId(item.id()); + const layoutElement = document.createElement("div"); + layoutElement.style.zIndex = "0"; + layoutElement.classList.add("popper-layout"); + layoutElement.setAttribute("data-id", item.id()); + layoutElement.addEventListener("mouseup", () => { + //Узнаём грани, идущие от этой ноды + setModalQuestionParentContentId(item.id()); + setOpenedModalQuestions(true); }); + layoutsContainer.current?.appendChild(layoutElement); - console.log("собираюсь анализировать папашу"); - console.log("Тип папаши ", parentQuestion.type); - if ( - parentQuestion?.type === "date" || - parentQuestion?.type === "text" || - parentQuestion?.type === "number" || - parentQuestion?.type === "page" - ) { - console.log("Шестерня должна быть невидимая"); - console.log("Тип папаши ", parentQuestion.type); - gearElement.classList.add("popper-gear-none"); - } - - return gearElement; + return layoutElement; }, }); - } - const update = async () => { - await plusesPopper.update(); - await crossesPopper.update(); - await gearsPopper?.update(); - await layoutsPopper.update(); - }; - const onZoom = (event: AbstractEventObject) => { - const zoom = event.cy.zoom(); + const plusesPopper = node.popper({ + popper: { + placement: "right", + modifiers: [{ name: "flip", options: { boundary: node } }], + }, + content: ([item]) => { + const itemId = item.id(); + const itemElement = plusesContainer.current?.querySelector( + `.popper-plus[data-id='${itemId}']`, + ); + if (itemElement) { + return itemElement; + } + + const plusElement = document.createElement("div"); + plusElement.classList.add("popper-plus"); + plusElement.setAttribute("data-id", item.id()); + plusElement.style.zIndex = "1"; + plusElement.addEventListener("mouseup", () => { + setStartCreate(node.id()); + }); + + plusesContainer.current?.appendChild(plusElement); + + return plusElement; + }, + }); + + const crossesPopper = node.popper({ + popper: { + placement: "top-end", + modifiers: [{ name: "flip", options: { boundary: node } }], + }, + content: ([item]) => { + const itemId = item.id(); + const itemElement = crossesContainer.current?.querySelector( + `.popper-cross[data-id='${itemId}']`, + ); + if (itemElement) { + return itemElement; + } + + const crossElement = document.createElement("div"); + crossElement.classList.add("popper-cross"); + crossElement.setAttribute("data-id", item.id()); + crossElement.style.zIndex = "2"; + crossesContainer.current?.appendChild(crossElement); + crossElement.addEventListener("mouseup", () => { + setStartRemove(node.id()); + }); + + return crossElement; + }, + }); + let gearsPopper: Popper | null = null; + if (node.data().root !== true) { + console.log(node.data("parentType")); + const parentQuestion = getQuestionByContentId( + node.data("parentType"), + ); + + gearsPopper = node.popper({ + popper: { + placement: "left", + modifiers: [{ name: "flip", options: { boundary: node } }], + }, + content: ([item]) => { + const itemId = item.id(); + + const itemElement = gearsContainer.current?.querySelector( + `.popper-gear[data-id='${itemId}']`, + ); + if (itemElement) { + return itemElement; + } + + const gearElement = document.createElement("div"); + gearElement.classList.add("popper-gear"); + gearElement.setAttribute("data-id", item.id()); + gearElement.style.zIndex = "1"; + gearsContainer.current?.appendChild(gearElement); + gearElement.addEventListener("mouseup", () => { + updateOpenedModalSettingsId(item.id()); + }); + + console.log("собираюсь анализировать папашу"); + console.log("Тип папаши ", parentQuestion.type); + if ( + parentQuestion?.type === "date" || + parentQuestion?.type === "text" || + parentQuestion?.type === "number" || + parentQuestion?.type === "page" + ) { + console.log("Шестерня должна быть невидимая"); + console.log("Тип папаши ", parentQuestion.type); + gearElement.classList.add("popper-gear-none"); + } + + return gearElement; + }, + }); + } + const update = async () => { + await plusesPopper.update(); + await crossesPopper.update(); + await gearsPopper?.update(); + await layoutsPopper.update(); + }; + + const zoom = cy.zoom(); //update(); @@ -319,45 +315,46 @@ export const usePopper = ({ element.style.width = `${60 * zoom}px`; element.style.height = `${40 * zoom}px`; }); - }; - //node?.on("position", update); - let pressed = false; - let hide = false; - cy?.on("mousedown", () => { - pressed = true; - }); - cy?.on("mouseup", () => { - pressed = false; - hide = false; + //node?.on("position", update); + let pressed = false; + let hide = false; + cy?.on("mousedown", () => { + pressed = true; + }); + cy?.on("mouseup", () => { + pressed = false; + hide = false; - const gc = gearsContainer.current; - if (gc) gc.style.display = "block"; - const pc = plusesContainer.current; - const xc = crossesContainer.current; - const lc = layoutsContainer.current; - if (pc) pc.style.display = "block"; - if (xc) xc.style.display = "block"; - if (lc) lc.style.display = "block"; - update(); - }); - - cy?.on("mousemove", () => { - if (pressed && !hide) { - hide = true; const gc = gearsContainer.current; - if (gc) gc.style.display = "none"; + if (gc) gc.style.display = "block"; const pc = plusesContainer.current; const xc = crossesContainer.current; const lc = layoutsContainer.current; - if (pc) pc.style.display = "none"; - if (xc) xc.style.display = "none"; + if (pc) pc.style.display = "block"; + if (xc) xc.style.display = "block"; if (lc) lc.style.display = "block"; - } - }); + update(); + }); - cy?.on("zoom render", onZoom); - }); + cy?.on("mousemove", () => { + if (pressed && !hide) { + hide = true; + const gc = gearsContainer.current; + if (gc) gc.style.display = "none"; + const pc = plusesContainer.current; + const xc = crossesContainer.current; + const lc = layoutsContainer.current; + if (pc) pc.style.display = "none"; + if (xc) xc.style.display = "none"; + if (lc) lc.style.display = "block"; + } + }); + + cy.on("render", () => { + update(); + }); + }); }; const readyLO = (event: LayoutEventObject) => {