diff --git a/src/pages/Questions/BranchingMap/CsComponent.tsx b/src/pages/Questions/BranchingMap/CsComponent.tsx index 9fa21802..6eb4bbf2 100644 --- a/src/pages/Questions/BranchingMap/CsComponent.tsx +++ b/src/pages/Questions/BranchingMap/CsComponent.tsx @@ -141,7 +141,134 @@ export const CsComponent = () => { useEffect(() => { document.querySelector("#root")?.addEventListener("mouseup", clearDragQuestionId); const cy = cyRef.current; - cy?.add(storeToNodes(questions)) + //cy?.add(storeToNodes(questions)) + cy?.add( + [ + { + "data": { + "id": "1", + "label": "2" + } + }, + { + "data": { + "id": "1 2", + "label": "Вы идёте в школу" + } + }, + { + "data": { + "id": "1 3", + "label": "1" + } + }, + { + "data": { + "id": "1 2 4", + "label": "3" + } + }, + { + "data": { + "id": "1 2 6", + "label": "5" + } + }, + { + "data": { + "id": "1 3 5", + "label": "4" + } + }, + { + "data": { + "id": "1 3 7", + "label": "6" + } + }, + { + "data": { + "id": "1 2 6 9867874", + "label": "7" + } + }, + { + "data": { + "id": "1 2 6 7398789", + "label": "8" + } + }, + { + "data": { + "id": "1 2 6 9484789", + "label": "11" + } + }, + { + "data": { + "source": "1", + "target": "1 2", + "id": "c4881f18-03cf-4ed1-bbc4-1741007f11c5" + } + }, + { + "data": { + "source": "1", + "target": "1 3", + "id": "3cc5a94a-0192-4ea2-bdc6-ce1a157b76d4" + } + }, + { + "data": { + "source": "1 2", + "target": "1 2 4", + "id": "1baf1bc6-eb40-4c81-b137-27cdd3a15e60" + } + }, + { + "data": { + "source": "1 2", + "target": "1 2 6", + "id": "78af38cc-7609-401c-bbff-ebdb3f67ec14" + } + }, + { + "data": { + "source": "1 3", + "target": "1 3 5", + "id": "a1c80f9f-7c4b-455c-8ba9-ef5dce5522b5" + } + }, + { + "data": { + "source": "1 3", + "target": "1 3 7", + "id": "85ed3ee9-fdd1-4874-8e36-484db46bf1c5" + } + }, + { + "data": { + "source": "1 2 6", + "target": "1 2 6 9867874", + "id": "f139548a-abca-412b-9935-740f219a938d" + } + }, + { + "data": { + "source": "1 2 6", + "target": "1 2 6 7398789", + "id": "ec8dd60c-df49-447f-b85a-4ae00cde1ae9" + } + }, + { + "data": { + "source": "1 2 6", + "target": "1 2 6 9484789", + "id": "9b5ecc61-d0ca-4872-a2a4-4fd72835345e" + } + } + ] + ) return () => { document.querySelector("#root")?.removeEventListener("mouseup", clearDragQuestionId); @@ -374,19 +501,72 @@ export const CsComponent = () => { name: 'preset', positions: (e) => { - console.log(e) - return {x:0,y:0} + const id = e.id() + const incomming = e.cy().edges(`[target="${id}"]`) + const layer = 0 + e.removeData('lastChild') + + if (incomming.length === 0) { + const children = e.cy().edges(`[source="${id}"]`) + e.data('layer', layer) + e.data('children', children.targets().length) + const queue = [] + children.forEach(n => { + queue.push({task: n.target(), layer: layer+1}) + }) + while (queue.length) { + const task = queue.pop() + task.task.data('layer', task.layer) + const children = e.cy().edges(`[source="${task.task.id()}"]`) + task.task.data('children', children.targets().length) + if (children.length !== 0) { + children.forEach(n => queue.push({task: n.target(), layer: task.layer+1})) + } + } + queue.push({parent: e, children:children.targets()}) + while (queue.length) { + const task = queue.pop() + if (task.children.length === 0) { + task.parent.data('subtreeWidth', task.parent.height()) + continue + } + const unprocessed = task?.children.filter(e => e.data('subtreeWidth') === undefined) + if (unprocessed.length !== 0) { + 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)) + } + return {x:200*e.data('layer'),y:0} + } else { + const parent = e.cy().edges(`[target="${e.id()}"]`)[0].source() + // console.log(e.data('subtreeWidth'), e.id(),(parent.data('children')-1) ) + const wing = parent.data('subtreeWidth')/2 + const lastOffset = parent.data('lastChild') + const step = wing*2/(parent.data('children')-1) + if (e.data('layer') === 1) + console.log(e.data('subtreeWidth'), e.id(),(parent.data('children')-1), step, wing, e.data('layer'), parent.id(), lastOffset) + //e.removeData('subtreeWidth') + //console.log('poss', e.id(), 'children', parent.data('children'),'lo', lastOffset, 'v', wing) + if (lastOffset !== undefined) { + parent.data('lastChild', lastOffset+step) + return {x:200*e.data('layer'),y: lastOffset+step} + } else { + parent.data('lastChild',parent.position().y - wing) + return {x:200*e.data('layer'),y: parent.position().y - wing} + } + } }, // 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: undefined, // the pan level to set (prob want fit = false if set) - fit: true, // whether to fit to viewport + 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 true; }, // 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: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop + ready: (e) => console.log('ready',e), // callback on layoutready + stop: (e) => console.log('stop',e), // callback on layoutstop transform: function (node, position ){ return position; } // transform a given node position. Useful for changing flow direction in discrete layouts }} stylesheet={stylesheet}