Browse Source

👉🏼will need to wrap this cytoscape swizzle later

windhamdavid 2 years ago
parent
commit
96d5c734c2
1 changed files with 112 additions and 0 deletions
  1. 112 0
      src/theme/cytoscape.js

+ 112 - 0
src/theme/cytoscape.js

@@ -0,0 +1,112 @@
+import React, {useState} from 'react';
+import {useRouter} from 'next/router'
+import CytoscapeComponent from "react-cytoscapejs";
+
+
+const layout = {
+    name: 'circle',
+    fit: true, // whether to fit the viewport to the graph
+    padding: 32, // the padding on fit
+    boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
+    avoidOverlap: true, // prevents node overlap, may overflow boundingBox and radius if not enough space
+    nodeDimensionsIncludeLabels: false, // Excludes the label when calculating node bounding boxes for the layout algorithm
+    spacingFactor: 0.9, // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
+    radius: 150, // the radius of the circle
+    startAngle: -2 / 4 * Math.PI, // where nodes start in radians
+    //sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)
+    clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
+    sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
+    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
+    transform: function (node, position) {
+        return position;
+    } // transform a given node position. Useful for changing flow direction in discrete layouts
+};
+
+const styleSheet = [{
+    selector: "node",
+    style: {
+        "background-color": "#666",
+        "font-size": "12px",
+        "width": "20px",
+        "height": "20px",
+        "label":"data(label)"
+    }
+}, {
+    selector: "label",
+    style: {"font-size": "12px"},
+},
+    {
+        selector: 'edge',
+        style: {
+            'width': 2,
+            "height": 200,
+            'line-color': '#b2b2b2',
+            'target-arrow-color': '#ccc',
+            // 'target-arrow-shape': 'triangle',
+            'curve-style': 'straight'
+        }
+    }];
+
+function Graph({graph}) {
+
+    const [width, setWidth] = useState("300px");
+    const [height, setHeight] = useState("300px");
+    const [graphData, setGraphData] = useState({
+        nodes: graph.nodes,
+        edges: graph.edges
+    });
+
+    let myCyRef;
+    const router = useRouter()
+    //TODO: Listen to query change/ graphdata change to update state of this component
+    // Can use this: https://github.com/vercel/next.js/discussions/12661
+
+    return (
+        <>
+            <div className="right-bar-container">
+                <h3>Interactive Graph</h3>
+                <div
+                    style={{
+                        border: "1px solid #ddd",
+                        backgroundColor: "#f5f6fe",
+                        borderRadius:"8px"
+                    }}
+                >
+                    <CytoscapeComponent
+                        elements={CytoscapeComponent.normalizeElements(graphData)}
+                        // pan={{ x: 200, y: 200 }}
+                        style={{width: width, height: height}}
+                        zoomingEnabled={true}
+                        maxZoom={2}
+                        minZoom={0.5}
+                        autounselectify={false}
+                        boxSelectionEnabled={true}
+                        layout={layout}
+                        stylesheet={styleSheet}
+                        cy={cy => {
+                            myCyRef = cy;
+
+                            console.log("EVT", cy);
+
+                            cy.on("tap", "node", evt => {
+                                var node = evt.target;
+                                let nodeData = node.data();
+                                if (typeof nodeData.id === 'string') {
+                                    const path = '/note/' + node.data().id
+                                    router.push(path)
+                                }
+                            });
+                        }}
+                    />
+                </div>
+            </div>
+        </>
+    );
+}
+
+export default Graph;