frontPanel/src/pages/Questions/BranchingMap/CsComponent.tsx

868 lines
29 KiB
TypeScript
Raw Normal View History

2023-12-04 13:33:43 +00:00
import { useEffect, useLayoutEffect, useRef, useState } from "react";
2023-11-29 15:45:15 +00:00
import Cytoscape from "cytoscape";
import { Button } from "@mui/material";
2023-11-29 15:45:15 +00:00
import CytoscapeComponent from "react-cytoscapejs";
import popper from "cytoscape-popper";
import { useCurrentQuiz } from "@root/quizes/hooks";
2023-12-20 10:46:38 +00:00
import { updateRootContentId } from "@root/quizes/actions";
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
2023-11-29 15:45:15 +00:00
import { useQuestionsStore } from "@root/questions/store";
2023-12-20 10:46:38 +00:00
import {
deleteQuestion,
updateQuestion,
getQuestionByContentId,
clearRuleForAll,
createFrontResult,
} from "@root/questions/actions";
import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
import { cleardragQuestionContentId } from "@root/uiTools/actions";
import { withErrorBoundary } from "react-error-boundary";
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
import { useRemoveNode } from "./hooks/useRemoveNode";
import { usePopper } from "./hooks/usePopper";
2023-11-29 15:45:15 +00:00
import { storeToNodes } from "./helper";
2023-12-20 10:46:38 +00:00
import { stylesheet } from "./stylesheet";
2023-11-29 15:45:15 +00:00
import "./styles.css";
import type {
Stylesheet,
Core,
NodeSingular,
AbstractEventObject,
ElementDefinition,
2023-12-20 10:46:38 +00:00
LayoutEventObject,
2023-11-29 15:45:15 +00:00
} from "cytoscape";
import { enqueueSnackbar } from "notistack";
import { useUiTools } from "@root/uiTools/store";
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type PopperItem = {
// id: () => string;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type Modifier = {
// name: string;
// options: unknown;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type PopperConfig = {
// popper: {
// placement: string;
// modifiers?: Modifier[];
// };
// content: (items: PopperItem[]) => void;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type Popper = {
// update: () => Promise<void>;
// setOptions: (modifiers: { modifiers?: Modifier[] }) => void;
// };
2023-11-29 15:45:15 +00:00
2023-12-20 10:46:38 +00:00
// type NodeSingularWithPopper = NodeSingular & {
// popper: (config: PopperConfig) => Popper;
// };
2023-11-29 15:45:15 +00:00
Cytoscape.use(popper);
2023-12-20 10:46:38 +00:00
type CsComponentProps = {
modalQuestionParentContentId: string;
modalQuestionTargetContentId: string;
setOpenedModalQuestions: (open: boolean) => void;
setModalQuestionParentContentId: (id: string) => void;
setModalQuestionTargetContentId: (id: string) => void;
2023-12-20 10:46:38 +00:00
};
function CsComponent({
modalQuestionParentContentId,
modalQuestionTargetContentId,
setOpenedModalQuestions,
setModalQuestionParentContentId,
2023-12-20 10:46:38 +00:00
setModalQuestionTargetContentId,
}: CsComponentProps) {
2023-11-29 15:45:15 +00:00
const quiz = useCurrentQuiz();
2023-12-20 10:46:38 +00:00
const { dragQuestionContentId, desireToOpenABranchingModal } = useUiTools();
const trashQuestions = useQuestionsStore().questions;
const questions = trashQuestions.filter(
(question) => question.type !== "result" && question.type !== null
);
2023-11-29 15:45:15 +00:00
const [startCreate, setStartCreate] = useState("");
const [startRemove, setStartRemove] = useState("");
const cyRef = useRef<Core | null>(null);
2023-12-01 08:12:59 +00:00
const layoutsContainer = useRef<HTMLDivElement | null>(null);
2023-11-29 15:45:15 +00:00
const plusesContainer = useRef<HTMLDivElement | null>(null);
const crossesContainer = useRef<HTMLDivElement | null>(null);
const gearsContainer = useRef<HTMLDivElement | null>(null);
2023-12-20 10:46:38 +00:00
// const { layoutOptions } = usePopper({
// layoutsContainer,
// plusesContainer,
// crossesContainer,
// gearsContainer,
// setModalQuestionParentContentId,
// setOpenedModalQuestions,
// setStartCreate,
// setStartRemove,
// });
const layoutOptions = {};
const removeNode = () => {};
// const { removeNode } = useRemoveNode({
// cyRef,
// layoutOptions,
// layoutsContainer,
// plusesContainer,
// crossesContainer,
// gearsContainer,
// });
useLayoutEffect(() => {
2023-12-20 10:46:38 +00:00
const cy = cyRef?.current;
if (desireToOpenABranchingModal) {
setTimeout(() => {
2023-12-20 10:46:38 +00:00
cy?.getElementById(desireToOpenABranchingModal)?.data(
"eroticeyeblink",
true
);
}, 250);
} else {
2023-12-20 10:46:38 +00:00
cy?.elements().data("eroticeyeblink", false);
}
2023-12-20 10:46:38 +00:00
}, [desireToOpenABranchingModal]);
useLayoutEffect(() => {
2023-12-20 10:46:38 +00:00
updateOpenedModalSettingsId();
// updateRootContentId(quiz.id, "")
// clearRuleForAll()
}, []);
useEffect(() => {
2023-12-20 10:46:38 +00:00
if (
modalQuestionTargetContentId.length !== 0 &&
modalQuestionParentContentId.length !== 0
) {
addNode({
parentNodeContentId: modalQuestionParentContentId,
targetNodeContentId: modalQuestionTargetContentId,
});
}
2023-12-01 08:12:59 +00:00
2023-12-20 10:46:38 +00:00
setModalQuestionParentContentId("");
setModalQuestionTargetContentId("");
}, [modalQuestionTargetContentId]);
const addNode = ({
parentNodeContentId,
targetNodeContentId,
}: {
parentNodeContentId: string;
targetNodeContentId?: string;
}) => {
//запрещаем работу родителя-ребенка если это один и тот же вопрос
2023-12-20 10:46:38 +00:00
if (parentNodeContentId === targetNodeContentId) return;
2023-12-20 10:46:38 +00:00
const cy = cyRef?.current;
const parentNodeChildren = cy?.$(
'edge[source = "' + parentNodeContentId + '"]'
)?.length;
//если есть инфо о выбранном вопросе из модалки - берём родителя из инфо модалки. Иначе из значения дропа
2023-12-20 10:46:38 +00:00
const targetQuestion = {
...getQuestionByContentId(targetNodeContentId || dragQuestionContentId),
} as AnyTypedQuizQuestion;
if (
Object.keys(targetQuestion).length !== 0 &&
parentNodeContentId &&
parentNodeChildren !== undefined
) {
clearDataAfterAddNode({
parentNodeContentId,
targetQuestion,
parentNodeChildren,
});
cy?.data("changed", true);
if (quiz) {
createFrontResult(quiz.backendId, targetQuestion.content.id);
}
const es = cy?.add([
2023-12-01 08:12:59 +00:00
{
data: {
id: targetQuestion.content.id,
2023-12-20 10:46:38 +00:00
label:
targetQuestion.title === "" || targetQuestion.title === " "
? "noname"
: targetQuestion.title,
},
2023-12-01 08:12:59 +00:00
},
{
data: {
source: parentNodeContentId,
2023-12-20 10:46:38 +00:00
target: targetQuestion.content.id,
},
},
]);
cy?.layout(layoutOptions).run();
console.log(es);
cy?.center(es);
} else {
2023-12-20 10:46:38 +00:00
enqueueSnackbar("Добавляемый вопрос не найден");
}
2023-12-20 10:46:38 +00:00
};
2023-12-20 10:46:38 +00:00
const clearDataAfterAddNode = ({
parentNodeContentId,
targetQuestion,
parentNodeChildren,
}: {
parentNodeContentId: string;
targetQuestion: AnyTypedQuizQuestion;
parentNodeChildren: number;
}) => {
const parentQuestion = {
...getQuestionByContentId(parentNodeContentId),
} as AnyTypedQuizQuestion;
//смотрим не добавлен ли родителю result. Если да - убираем его. Веточкам result не нужен
trashQuestions.forEach((targetQuestion) => {
2023-12-20 10:46:38 +00:00
if (
targetQuestion.type === "result" &&
targetQuestion.content.rule.parentId === parentQuestion.content.id
) {
console.log("deleteQ", targetQuestion.id);
deleteQuestion(targetQuestion.id);
}
2023-12-20 10:46:38 +00:00
});
//предупреждаем добавленный вопрос о том, кто его родитель
2023-12-20 10:46:38 +00:00
updateQuestion(targetQuestion.content.id, (question) => {
question.content.rule.parentId = parentNodeContentId;
question.content.rule.main = [];
});
//предупреждаем родителя о новом потомке (если он ещё не знает о нём)
2023-12-20 10:46:38 +00:00
if (
!parentQuestion.content.rule.children.includes(targetQuestion.content.id)
)
updateQuestion(parentNodeContentId, (question) => {
question.content.rule.children = [
...question.content.rule.children,
targetQuestion.content.id,
];
});
//Если детей больше 1 - предупреждаем стор вопросов об открытии модалки ветвления
if (parentQuestion.content.rule.children >= 1) {
2023-12-20 10:46:38 +00:00
updateOpenedModalSettingsId(targetQuestion.content.id);
}
2023-12-20 10:46:38 +00:00
};
2023-12-20 10:46:38 +00:00
// const removeNode = ({ targetNodeContentId }: { targetNodeContentId: string }) => {
// console.log("старт удаление")
// const deleteNodes: string[] = []
// const deleteEdges: any = []
// const cy = cyRef?.current
// const findChildrenToDelete = (node) => {
// //Узнаём грани, идущие от этой ноды
// cy?.$('edge[source = "' + node.id() + '"]')?.toArray().forEach((edge) => {
// const edgeData = edge.data()
// //записываем id грани для дальнейшего удаления
// deleteEdges.push(edge)
// //ищем ноду на конце грани, записываем её ID для дальнейшего удаления
// const targetNode = cy?.$("#" + edgeData.target)
// deleteNodes.push(targetNode.data().id)
// //вызываем функцию для анализа потомков уже у этой ноды
// findChildrenToDelete(targetNode)
// })
// }
// findChildrenToDelete(cy?.getElementById(targetNodeContentId))
// const targetQuestion = getQuestionByContentId(targetNodeContentId)
// if (targetQuestion.content.rule.parentId === "root" && quiz) {
// updateRootContentId(quiz?.id, "")
// updateQuestion(targetNodeContentId, question => {
// question.content.rule.parentId = ""
// question.content.rule.main = []
// question.content.rule.children = []
// question.content.rule.default = ""
// })
// trashQuestions.forEach(q => {
// if (q.type === "result") {
// deleteQuestion(q.id);
// }
// });
// clearRuleForAll()
// } else {
// const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
// if (targetNodeContentId && parentQuestionContentId) {
// if (cy?.edges(`[source="${parentQuestionContentId}"]`).length === 0)
// createFrontResult(quiz.backendId, parentQuestionContentId)
// clearDataAfterRemoveNode({ targetQuestionContentId: targetNodeContentId, parentQuestionContentId })
// cy?.remove(cy?.$('#' + targetNodeContentId)).layout(lyopts).run()
// }
// }
// //После всех манипуляций удаляем грани и ноды из CS Чистим rule потомков на беке
// deleteNodes.forEach((nodeId) => {//Ноды
// cy?.remove(cy?.$("#" + nodeId))
// removeButtons(nodeId)
// updateQuestion(nodeId, question => {
// question.content.rule.parentId = ""
// question.content.rule.main = []
// question.content.rule.default = ""
// question.content.rule.children = []
// })
// })
// deleteEdges.forEach((edge: any) => {//Грани
// cy?.remove(edge)
// })
// removeButtons(targetNodeContentId)
// cy?.data('changed', true)
// cy?.layout(lyopts).run()
// //удаляем result всех потомков
// trashQuestions.forEach((qr) => {
// if (qr.type === "result") {
// if (deleteNodes.includes(qr.content.rule.parentId) || qr.content.rule.parentId === targetQuestion.content.id) {
// deleteQuestion(qr.id);
// }
// }
// })
// }
// const clearDataAfterRemoveNode = ({ targetQuestionContentId, parentQuestionContentId }: { targetQuestionContentId: string, parentQuestionContentId: string }) => {
// updateQuestion(targetQuestionContentId, question => {
// question.content.rule.parentId = ""
// question.content.rule.children = []
// question.content.rule.main = []
// question.content.rule.default = ""
// })
// //чистим rule родителя
// const parentQuestion = getQuestionByContentId(parentQuestionContentId)
// const newRule = {}
// const newChildren = [...parentQuestion.content.rule.children]
// newChildren.splice(parentQuestion.content.rule.children.indexOf(targetQuestionContentId), 1);
// newRule.main = parentQuestion.content.rule.main.filter((data) => data.next !== targetQuestionContentId) //удаляем условия перехода от родителя к этому вопросу
// newRule.parentId = parentQuestion.content.rule.parentId
// newRule.default = parentQuestion.content.rule.default === targetQuestionContentId ? "" : parentQuestion.content.rule.default
// newRule.children = newChildren
// updateQuestion(parentQuestionContentId, (PQ) => {
// PQ.content.rule = newRule
// })
// }
2023-11-29 15:45:15 +00:00
useEffect(() => {
if (startCreate) {
addNode({ parentNodeContentId: startCreate });
2023-12-20 10:46:38 +00:00
cleardragQuestionContentId();
2023-11-29 15:45:15 +00:00
setStartCreate("");
}
}, [startCreate]);
useEffect(() => {
if (startRemove) {
2023-12-20 10:46:38 +00:00
removeNode(startRemove);
2023-11-29 15:45:15 +00:00
setStartRemove("");
}
}, [startRemove]);
2023-12-20 10:46:38 +00:00
// const readyLO = (e) => {
// if (e.cy.data('firstNode') === 'nonroot') {
// e.cy.data('firstNode', 'root')
// e.cy.nodes().sort((a, b) => (a.data('root') ? 1 : -1)).layout(lyopts).run()
// } else {
// e.cy.data('changed', false)
// e.cy.removeData('firstNode')
// }
// //удаляем иконки
// e.cy.nodes().forEach((ele: any) => {
// const data = ele.data()
// data.id && removeButtons(data.id);
// })
// initialPopperIcons(e)
// }
// const lyopts = {
// name: 'preset',
// positions: (e) => {
// if (!e.cy().data('changed')) {
// return e.data('oldPos')
// }
// const id = e.id()
// const incomming = e.cy().edges(`[target="${id}"]`)
// const layer = 0
// e.removeData('lastChild')
// if (incomming.length === 0) {
// if (e.cy().data('firstNode') === undefined)
// e.cy().data('firstNode', 'root')
// e.data('root', true)
// const children = e.cy().edges(`[source="${id}"]`).targets()
// e.data('layer', layer)
// e.data('children', children.length)
// const queue = []
// children.forEach(n => {
// queue.push({ task: n, layer: layer + 1 })
// })
// while (queue.length) {
// const task = queue.pop()
// task.task.data('layer', task.layer)
// task.task.removeData('subtreeWidth')
// const children = e.cy().edges(`[source="${task.task.id()}"]`).targets()
// task.task.data('children', children.length)
// if (children.length !== 0) {
// children.forEach(n => queue.push({ task: n, layer: task.layer + 1 }))
// }
// }
// queue.push({ parent: e, children: children })
// while (queue.length) {
// const task = queue.pop()
// if (task.children.length === 0) {
// task.parent.data('subtreeWidth', task.parent.height() + 50)
// continue
// }
// const unprocessed = task?.children.filter(e => {
// return (e.data('subtreeWidth') === undefined)
// })
// if (unprocessed.length !== 0) {
// queue.push(task)
// unprocessed.forEach(t => {
// queue.push({ parent: t, children: t.cy().edges(`[source="${t.id()}"]`).targets() })
// })
// continue
// }
// task?.parent.data('subtreeWidth', task.children.reduce((p, n) => p + n.data('subtreeWidth'), 0))
// }
// const pos = { x: 0, y: 0 }
// e.data('oldPos', pos)
// queue.push({ task: children, parent: e })
// while (queue.length) {
// const task = queue.pop()
// const oldPos = task.parent.data('oldPos')
// let yoffset = oldPos.y - task.parent.data('subtreeWidth') / 2
// task.task.forEach(n => {
// const width = n.data('subtreeWidth')
// n.data('oldPos', { x: 250 * n.data('layer'), y: yoffset + width / 2 })
// yoffset += width
// queue.push({ task: n.cy().edges(`[source="${n.id()}"]`).targets(), parent: n })
// })
// }
// e.cy().data('changed', false)
// return pos
// } else {
// const opos = e.data('oldPos')
// if (opos) {
// return opos
// }
// }
// }, // map of (node id) => (position obj); or function(node){ return somPos; }
// zoom: undefined, // the zoom level to set (prob want fit = false if set)
// pan: true, // the pan level to set (prob want fit = false if set)
// fit: false, // whether to fit to viewport
// padding: 30, // padding on fit
// animate: false, // whether to transition the node positions
// animationDuration: 500, // duration of animation in ms if enabled
// animationEasing: undefined, // easing of animation if enabled
// animateFilter: function (node, i) { return false; }, // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts
// ready: readyLO, // callback on layoutready
// transform: function (node, position) { return position; } // transform a given node position. Useful for changing flow direction in discrete layouts
// }
useEffect(() => {
2023-12-20 10:46:38 +00:00
document
.querySelector("#root")
?.addEventListener("mouseup", cleardragQuestionContentId);
const cy = cyRef.current;
2023-12-20 10:46:38 +00:00
const eles = cy?.add(
storeToNodes(
questions.filter(
(question) => question.type && question.type !== "result"
) as AnyTypedQuizQuestion[]
)
);
cy?.data("changed", true);
// cy.data('changed', true)
2023-12-20 10:46:38 +00:00
const elecs = eles?.layout(layoutOptions).run();
cy?.on("add", () => cy.data("changed", true));
cy?.fit();
//cy?.layout().run()
2023-11-29 15:45:15 +00:00
return () => {
2023-12-20 10:46:38 +00:00
document
.querySelector("#root")
?.removeEventListener("mouseup", cleardragQuestionContentId);
2023-12-01 08:12:59 +00:00
layoutsContainer.current?.remove();
2023-11-29 15:45:15 +00:00
plusesContainer.current?.remove();
crossesContainer.current?.remove();
gearsContainer.current?.remove();
};
}, []);
2023-12-20 10:46:38 +00:00
// const removeButtons = (id: string) => {
// layoutsContainer.current
// ?.querySelector(`.popper-layout[data-id='${id}']`)
// ?.remove();
// plusesContainer.current
// ?.querySelector(`.popper-plus[data-id='${id}']`)
// ?.remove();
// crossesContainer.current
// ?.querySelector(`.popper-cross[data-id='${id}']`)
// ?.remove();
// gearsContainer.current
// ?.querySelector(`.popper-gear[data-id='${id}']`)
// ?.remove();
// };
// const initialPopperIcons = ({ cy }: LayoutEventObject) => {
// const container =
// (document.body.querySelector(
// ".__________cytoscape_container"
// ) as HTMLDivElement) || null;
// if (!container) {
// return;
// }
// container.style.overflow = "hidden";
// if (!plusesContainer.current) {
// plusesContainer.current = document.createElement("div");
// plusesContainer.current.setAttribute("id", "popper-pluses");
// container.append(plusesContainer.current);
// }
// if (!crossesContainer.current) {
// crossesContainer.current = document.createElement("div");
// crossesContainer.current.setAttribute("id", "popper-crosses");
// container.append(crossesContainer.current);
// }
// if (!gearsContainer.current) {
// gearsContainer.current = document.createElement("div");
// gearsContainer.current.setAttribute("id", "popper-gears");
// container.append(gearsContainer.current);
// }
// if (!layoutsContainer.current) {
// layoutsContainer.current = document.createElement("div");
// layoutsContainer.current.setAttribute("id", "popper-layouts");
// 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
// );
// });
// nodesInView.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) {
// 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", (e) => {
// console.log("up");
// updateOpenedModalSettingsId(item.id());
// });
// return gearElement;
// },
// });
// }
// const update = async () => {
// await plusesPopper.update();
// await crossesPopper.update();
// await gearsPopper?.update();
// await layoutsPopper.update();
// };
// const onZoom = (event: AbstractEventObject) => {
// const zoom = event.cy.zoom();
// //update();
// crossesPopper.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [-5 * zoom, -30 * zoom] } },
// ],
// });
// layoutsPopper.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [0, -130 * zoom] } },
// ],
// });
// plusesPopper.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [0, 0 * zoom] } },
// ],
// });
// gearsPopper?.setOptions({
// modifiers: [
// { name: "flip", options: { boundary: node } },
// { name: "offset", options: { offset: [0, 0] } },
// ],
// });
// layoutsContainer.current
// ?.querySelectorAll("#popper-layouts > .popper-layout")
// .forEach((item) => {
// const element = item as HTMLDivElement;
// element.style.width = `${130 * zoom}px`;
// element.style.height = `${130 * zoom}px`;
// });
// plusesContainer.current
// ?.querySelectorAll("#popper-pluses > .popper-plus")
// .forEach((item) => {
// const element = item as HTMLDivElement;
// element.style.width = `${40 * zoom}px`;
// element.style.height = `${40 * zoom}px`;
// element.style.fontSize = `${40 * zoom}px`;
// element.style.borderRadius = `${6 * zoom}px`;
// });
// crossesContainer.current
// ?.querySelectorAll("#popper-crosses > .popper-cross")
// .forEach((item) => {
// const element = item as HTMLDivElement;
// element.style.width = `${24 * zoom}px`;
// element.style.height = `${24 * zoom}px`;
// element.style.fontSize = `${24 * zoom}px`;
// element.style.borderRadius = `${6 * zoom}px`;
// });
// gearsContainer?.current
// ?.querySelectorAll("#popper-gears > .popper-gear")
// .forEach((item) => {
// const element = item as HTMLDivElement;
// 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;
// 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";
// 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("zoom render", onZoom);
// });
// };
2023-11-29 15:45:15 +00:00
return (
<>
<Button
sx={{
mb: "20px",
height: "27px",
color: "#7E2AEA",
textDecoration: "underline",
fontSize: "16px",
}}
variant="text"
onClick={() => {
2023-12-20 10:46:38 +00:00
cyRef.current?.fit();
}}
>
Выровнять
</Button>
<CytoscapeComponent
wheelSensitivity={0.1}
elements={[]}
// elements={createGraphElements(tree, quiz)}
style={{ height: "480px", background: "#F2F3F7" }}
stylesheet={stylesheet}
2023-12-20 10:46:38 +00:00
layout={layoutOptions}
cy={(cy) => {
cyRef.current = cy;
}}
autoungrabify={true}
/>
{/* <button onClick={() => {
console.log("NODES____________________________")
cyRef.current?.elements().forEach((ele: any) => {
console.log(ele.data())
})
}}>nodes</button>
<button onClick={() => {
console.log("ELEMENTS____________________________")
2023-12-04 07:50:55 +00:00
console.log(questions)
}}>elements</button> */}
</>
2023-11-29 15:45:15 +00:00
);
2023-12-20 10:46:38 +00:00
}
function Clear() {
const quiz = useCurrentQuiz();
2023-12-20 10:46:38 +00:00
if (quiz) {
updateRootContentId(quiz.id, "");
}
clearRuleForAll();
return <></>;
}
export default withErrorBoundary(CsComponent, {
fallback: <Clear />,
onError: (error, info) => {
2023-12-20 10:46:38 +00:00
enqueueSnackbar("Дерево порвалось");
console.log(info);
console.log(error);
},
});