Merge branch 'dev' into 'main'

cs fixed zoom & fit graph to root node

See merge request frontend/squiz!103
This commit is contained in:
Nastya 2023-12-31 12:19:46 +00:00
commit 278c068ebc
2 changed files with 181 additions and 167 deletions

@ -95,6 +95,23 @@ function CsComponent({
gearsContainer, 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(() => { useLayoutEffect(() => {
const cy = cyRef?.current; const cy = cyRef?.current;
if (desireToOpenABranchingModal) { if (desireToOpenABranchingModal) {
@ -301,7 +318,7 @@ function CsComponent({
// cy.data('changed', true) // cy.data('changed', true)
const elecs = eles?.layout(layoutOptions).run(); const elecs = eles?.layout(layoutOptions).run();
cy?.on("add", () => cy.data("changed", true)); cy?.on("add", () => cy.data("changed", true));
cy?.fit(); fitGraphToRootNode();
//cy?.layout().run() //cy?.layout().run()
firstRender.current = false; firstRender.current = false;
} }
@ -335,9 +352,7 @@ function CsComponent({
fontSize: "16px", fontSize: "16px",
}} }}
variant="text" variant="text"
onClick={() => { onClick={fitGraphToRootNode}
cyRef.current?.fit();
}}
> >
Выровнять Выровнять
</Button> </Button>
@ -358,6 +373,8 @@ function CsComponent({
cyRef.current = cy; cyRef.current = cy;
}} }}
autoungrabify={true} autoungrabify={true}
zoom={0.6}
zoomingEnabled={false}
/> />
<DeleteNodeModal removeNode={removeNode} /> <DeleteNodeModal removeNode={removeNode} />
</> </>

@ -104,157 +104,153 @@ export const usePopper = ({
container.append(layoutsContainer.current); 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(); cy?.removeAllListeners();
nodesInView.toArray()?.forEach((item) => { cy
const node = item as NodeSingularWithPopper; .nodes()
.toArray()
?.forEach((item) => {
const node = item as NodeSingularWithPopper;
const layoutsPopper = node.popper({ 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({
popper: { popper: {
placement: "left", placement: "left",
modifiers: [{ name: "flip", options: { boundary: node } }], modifiers: [{ name: "flip", options: { boundary: node } }],
}, },
content: ([item]) => { content: ([item]) => {
const itemId = item.id(); const itemId = item.id();
const itemElement = layoutsContainer.current?.querySelector(
const itemElement = gearsContainer.current?.querySelector( `.popper-layout[data-id='${itemId}']`,
`.popper-gear[data-id='${itemId}']`,
); );
if (itemElement) { if (itemElement) {
return itemElement; return itemElement;
} }
const gearElement = document.createElement("div"); const layoutElement = document.createElement("div");
gearElement.classList.add("popper-gear"); layoutElement.style.zIndex = "0";
gearElement.setAttribute("data-id", item.id()); layoutElement.classList.add("popper-layout");
gearElement.style.zIndex = "1"; layoutElement.setAttribute("data-id", item.id());
gearsContainer.current?.appendChild(gearElement); layoutElement.addEventListener("mouseup", () => {
gearElement.addEventListener("mouseup", () => { //Узнаём грани, идущие от этой ноды
updateOpenedModalSettingsId(item.id()); setModalQuestionParentContentId(item.id());
setOpenedModalQuestions(true);
}); });
layoutsContainer.current?.appendChild(layoutElement);
console.log("собираюсь анализировать папашу"); return layoutElement;
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 onZoom = (event: AbstractEventObject) => { const plusesPopper = node.popper({
const zoom = event.cy.zoom(); 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(); //update();
@ -319,45 +315,46 @@ export const usePopper = ({
element.style.width = `${60 * zoom}px`; element.style.width = `${60 * zoom}px`;
element.style.height = `${40 * zoom}px`; element.style.height = `${40 * zoom}px`;
}); });
};
//node?.on("position", update); //node?.on("position", update);
let pressed = false; let pressed = false;
let hide = false; let hide = false;
cy?.on("mousedown", () => { cy?.on("mousedown", () => {
pressed = true; pressed = true;
}); });
cy?.on("mouseup", () => { cy?.on("mouseup", () => {
pressed = false; pressed = false;
hide = 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; const gc = gearsContainer.current;
if (gc) gc.style.display = "none"; if (gc) gc.style.display = "block";
const pc = plusesContainer.current; const pc = plusesContainer.current;
const xc = crossesContainer.current; const xc = crossesContainer.current;
const lc = layoutsContainer.current; const lc = layoutsContainer.current;
if (pc) pc.style.display = "none"; if (pc) pc.style.display = "block";
if (xc) xc.style.display = "none"; if (xc) xc.style.display = "block";
if (lc) lc.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) => { const readyLO = (event: LayoutEventObject) => {