Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions imports/cyto/elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export function useCytoElements(ml, _links, cy, spaceId) {
const [showTypes, setShowTypes] = useShowTypes();
const [showFocus, setShowFocus] = useShowFocus();
const [insertingCyto, setInsertingCyto] = useInsertingCytoStore();
const oldElements = useRef([]);
const deep = useDeep();

const links = _links;
Expand Down Expand Up @@ -52,12 +51,7 @@ export function useCytoElements(ml, _links, cy, spaceId) {
return value !== null && typeof value !== 'undefined' && !Number.isNaN(value) && value !== '';
}

const has_focus = !!focus?.value?.value?.x;
const existed = !!oldElements.current.find((oldLink) => oldLink.id === link.id)


// const parent = link?._applies?.find(q => q.includes('query-'));

const element = {
id: link.id,
data: {
Expand All @@ -78,8 +72,8 @@ export function useCytoElements(ml, _links, cy, spaceId) {
...(focus ? ['focused'] : ['unfocused']),
].join(' '),

...(has_focus ? {
position: !existed ? focus?.value?.value : {},
...(focus?.value?.value?.x ? {
position: focus?.value?.value?.x ? focus?.value?.value : {},
locked: !!focus,
} : {}),
focused: !!focus,
Expand Down Expand Up @@ -194,7 +188,6 @@ export function useCytoElements(ml, _links, cy, spaceId) {
}
}

oldElements.current = elements;
// console.timeEnd('useCytoElements');

return {
Expand Down
19 changes: 10 additions & 9 deletions imports/cyto/graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import dagre from 'cytoscape-dagre';
import { useDeep } from '@deep-foundation/deeplinks/imports/client';
import cola from 'cytoscape-cola';
// import COSEBilkent from 'cytoscape-cose-bilkent';
import d3Force from 'cytoscape-d3-force';
import deepd3Force from 'cytoscape-deep-d3-force';
// import d3Force from 'cytoscape-d3-force';
// import fcose from 'cytoscape-fcose';
// import euler from 'cytoscape-euler';
// import elk from 'cytoscape-elk';
Expand All @@ -21,7 +20,7 @@ import edgehandles from 'cytoscape-edgehandles';
import { Text, useToast } from '@chakra-ui/react';
import dynamic from 'next/dynamic';
import pckg from '../../package.json';
import { useContainer, useCytoViewport, useFocusMethods, useInsertingCytoStore, useLayout, useRefAutofill, useShowExtra, useShowTypes, useSpaceId, useLayoutAnimation } from '../hooks';
import { useContainer, useCytoViewport, useFocusMethods, useInsertingCytoStore, useLayout, useRefAutofill, useShowExtra, useShowTypes, useSpaceId } from '../hooks';
import { Refstater } from '../refstater';
import { CytoDropZone } from './drop-zone';
import { CytoEditor } from './editor';
Expand All @@ -43,14 +42,13 @@ cytoscape.use(cola);
// cytoscape.use(klay);
// cytoscape.use(elk);
// cytoscape.use(euler);
cytoscape.use(d3Force);
cytoscape.use(deepd3Force);
// cytoscape.use(d3Force);
// cytoscape.use(fcose);
cytoscape.use(cxtmenu);
cytoscape.use(edgeConnections);
cytoscape.use(edgehandles);

export function useCytoFocusMethods(cy) {
export function useCytoFocusMethods(cy, relayoutDebounced) {
const { focus, unfocus } = useFocusMethods();
const lockingRef = useRef<any>({});
return {
Expand All @@ -64,8 +62,10 @@ export function useCytoFocusMethods(cy) {
const locking = lockingRef.current;
if (id) {
locking[id] = true;
el.position(position);
el.lock();
const focused = await focus(id, position);
relayoutDebounced();
return focused;
}
}
Expand All @@ -82,6 +82,7 @@ export function useCytoFocusMethods(cy) {
el.unlock();
locking[id] = false;
unfocus(id);
relayoutDebounced();
}
}
}
Expand Down Expand Up @@ -112,12 +113,12 @@ export default function CytoGraph({
const { elements, reactElements } = useCytoElements(deep.minilinks, links, cy, spaceId);
const elementsRef = useRefAutofill(elements);

const { onLoaded } = useCyInitializer({
const { onLoaded, relayoutDebounced } = useCyInitializer({
elementsRef, elements, reactElements, cyRef, setCy, ehRef, cytoViewportRef
});

const { layout, setLayout } = useLayout();
const [ layoutAnimation ] = useLayoutAnimation();

const stylesheets = useCytoStylesheets();

const returning = (<>
Expand All @@ -132,7 +133,7 @@ export default function CytoGraph({
if (!cy) onLoaded(_cy);
}}
elements={elements}
layout={layout({elementsRef: elementsRef.current, cy, isAnimate: layoutAnimation, deep})}
layout={layout(elementsRef.current, cy)}
stylesheet={stylesheets}
panningEnabled={true}
pan={cytoViewportRef?.current?.value?.pan}
Expand Down
47 changes: 26 additions & 21 deletions imports/cyto/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -595,27 +595,30 @@ export function useCyInitializer({

const { linkReactElements, toggleLinkReactElement } = useLinkReactElements(elements, reactElements, cyRef.current, ml);

const relayout = useCallback(() => {
if (cyRef.current && cyRef.current.elements) {
const elements = cyRef.current.elements();
try {
elements.layout(layout(elementsRef.current, cyRef.current)).run();
} catch(error) {
console.log('relayout error', error);
}
}
}, [cyRef.current, layout]);
const relayoutDebounced = useDebounceCallback(relayout, 500);
const globalAny:any = global;
globalAny.relayoutDebounced = relayoutDebounced;

// const relayout = useCallback(() => {
// if (cyRef.current && cyRef.current.elements) {
// const elements = cyRef.current.elements();
// try {
// elements.layout(layout(elementsRef.current, cyRef.current)).run();
// } catch(error) {
// console.log('relayout error', error);
// }
// }
// }, [cyRef.current, layout]);
// const relayoutDebounced = useDebounceCallback(relayout, 500);
// const globalAny:any = global;
// globalAny.relayoutDebounced = relayoutDebounced;


// const globalAny:any = global;
// globalAny.relayoutDebounced = relayoutDebounced;

useEffect(() => {
if (!refDragStartedEvent.current) {
relayoutDebounced();
}
}, [extra, layout, showTypes]);
useMinilinksHandle(ml, (event, oldLink, newLink) => {
relayoutDebounced();
});

const { focus, unfocus, lockingRef } = useCytoFocusMethods(cyRef.current);
const { focus, unfocus, lockingRef } = useCytoFocusMethods(cyRef.current, relayoutDebounced);
const { startInsertingOfType, startUpdatingLink, openInsertCard, insertLink, drawendInserting, insertingCyto, insertingCytoRef } = useLinkInserting(elements, reactElements, focus, cyRef, ehRef);

const onLoaded = (ncy) => {
Expand Down Expand Up @@ -654,7 +657,7 @@ export function useCyInitializer({
ncy.$(`node, edge`).not(`#${id},#${id}-from,#${id}-to,#${id}-type`).removeClass('hover');
ncy.$(`#${id},#${id}-from,#${id}-to,#${id}-type`).not(`.unhoverable`).addClass('hover');
}
if (node.locked()) {
if (node.locked) {
node.unlock();
node.mouseHoverDragging = true;
}
Expand Down Expand Up @@ -896,7 +899,8 @@ export function useCyInitializer({
const node = ncy.$(`node#${newLink.to_id}`);
if (!node.mouseHoverDragging) {
node.unlock();
// node.position(newLink?.value?.value);
node.position(newLink?.value?.value);
relayoutDebounced();
node.lock();
}
}
Expand Down Expand Up @@ -943,5 +947,6 @@ export function useCyInitializer({
};
return {
onLoaded,
relayoutDebounced,
};
}
79 changes: 6 additions & 73 deletions imports/cyto/layouts.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const layoutColaPreset = ({isAnimate=false}) => ({
export const layoutColaPreset = () => ({
name: 'cola',
animate: isAnimate, // whether to show the layout as it's running
animate: false, // whether to show the layout as it's running
refresh: 10, // number of ticks per frame; higher is faster but more jerky
maxSimulationTime: 100, // max length in ms to run the layout
ungrabifyWhileSimulating: false, // so you can't drag nodes during layout
Expand All @@ -15,30 +15,18 @@ export const layoutColaPreset = ({isAnimate=false}) => ({

// positioning options
randomize: false, // use random node positions at beginning of layout
avoidOverlap: true, // if true, prevents overlap of node bounding boxes
handleDisconnected: true, // if true, avoids disconnected components from overlapping
avoidOverlap: false, // if true, prevents overlap of node bounding boxes
handleDisconnected: false, // if true, avoids disconnected components from overlapping
convergenceThreshold: 0.01, // when the alpha value (system energy) falls below this value, the layout stops
nodeSpacing: function( node ){ return 10; }, // extra spacing around nodes
// nodeSpacing: function( node ){ return 50; }, // extra spacing around nodes
flow: undefined, // use DAG/tree flow layout if specified, e.g. { axis: 'y', minSeparation: 30 }
alignment: undefined, // relative alignment constraints on nodes, e.g. {vertical: [[{node: node1, offset: 0}, {node: node2, offset: 5}]], horizontal: [[{node: node3}, {node: node4}], [{node: node5}, {node: node6}]]}
gapInequalities: undefined, // list of inequality constraints for the gap between the nodes, e.g. [{"axis":"y", "left":node1, "right":node2, "gap":25}]
centerGraph: true, // adjusts the node positions initially to center the graph (pass false if you want to start the layout from the current position)

// different methods of specifying edge length
// each can be a constant numerical value or a function like `function( edge ){ return 2; }`
edgeLength: function( edge ) {
const baseLength = 30; // base edge length
const extraLength = 10; // additional length of the edge to take into account the density of connections
const sourceNode = edge.source();
const targetNode = edge.target();

// Calculate the number of connected edges for source nodes and target nodes
const sourceConnectedEdges = sourceNode.connectedEdges().length;
const targetConnectedEdges = targetNode.connectedEdges().length;

// Increase edge length based on the number of connected edges
return baseLength + (sourceConnectedEdges + targetConnectedEdges) * extraLength;
},
edgeLength: undefined, // sets edge length directly in simulation
edgeSymDiffLength: undefined, // symmetric diff edge length in simulation
edgeJaccardLength: undefined, // jaccard edge length in simulation

Expand All @@ -47,61 +35,6 @@ export const layoutColaPreset = ({isAnimate=false}) => ({
userConstIter: undefined, // initial layout iterations with user-specified constraints
allConstIter: undefined, // initial layout iterations with all constraints including non-overlap
});

export const layoutD3ForcePreset = ({isAnimate=false, cy, deep}) => ({
deep: ()=>deep,
name: 'deep-d3-force',
animate: isAnimate, // whether to show the layout as it's running; special 'end' value makes the layout animate like a discrete layout
maxIterations: 0, // max iterations before the layout will bail out
maxSimulationTime: 0, // max length in ms to run the layout
ungrabifyWhileSimulating: false, // so you can't drag nodes during layout
fixedAfterDragging: false, // fixed node after dragging
fit: false, // on every layout reposition of nodes, fit the viewport
padding: 30, // padding around the simulation
boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
/**d3-force API**/
alpha: 0.8, // sets the current alpha to the specified number in the range [0,1]
alphaMin: 0.001, // sets the minimum alpha to the specified number in the range [0,1]
alphaDecay: 0.5, // sets the alpha decay rate to the specified number in the range [0,1]
alphaTarget: 0.1, // sets the current target alpha to the specified number in the range [0,1]
velocityDecay: 0.6, // sets the velocity decay factor to the specified number in the range [0,1]
// collideRadius: 1, // sets the radius accessor to the specified number or function
// collideStrength: 0.7, // sets the force strength to the specified number in the range [0,1]
// collideIterations: 1, // sets the number of iterations per application to the specified number
linkId: function id(d) {
return d.id;
}, // sets the node id accessor to the specified function
linkDistance: 100, // sets the distance accessor to the specified number or function
// linkStrength: function strength(link) {
// const sourceNode = cy.getElementById(link.source.id);
// const targetNode = cy.getElementById(link.target.id);
// return 1 / Math.min(sourceNode.degree(), targetNode.degree());
// }, // sets the strength accessor to the specified number or function
// linkIterations: 1, // sets the number of iterations per application to the specified number
manyBodyStrength: -2000, // sets the strength accessor to the specified number or function
// manyBodyTheta: 0.9, // sets the Barnes–Hut approximation criterion to the specified number
// manyBodyDistanceMin: 1, // sets the minimum distance between nodes over which this force is considered
// manyBodyDistanceMax: Infinity, // sets the maximum distance between nodes over which this force is considered
xStrength: 0.09, // sets the strength accessor to the specified number or function
xX: 0, // sets the x-coordinate accessor to the specified number or function
yStrength: 0.09, // sets the strength accessor to the specified number or function
yY: 0, // sets the y-coordinate accessor to the specified number or function
// radialStrength: 0.05, // sets the strength accessor to the specified number or function
// radialRadius: [40],// sets the circle radius to the specified number or function
// radialX: 0, // sets the x-coordinate of the circle center to the specified number
// radialY: 0, // sets the y-coordinate of the circle center to the specified number
// layout event callbacks
ready: function(){}, // on layoutready
stop: function(){}, // on layoutstop
tick: function(progress) {}, // on every iteration
// positioning options
randomize: false, // use random node positions at beginning of layout
// infinite layout options
infinite: true // overrides all other options for a forces-all-the-time mode
});


export const layouts = {
'cola': layoutColaPreset,
'deep-d3-force': layoutD3ForcePreset,
};
Loading