Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document how to use a layout #73

Open
dcsan opened this issue Jul 26, 2024 · 8 comments
Open

document how to use a layout #73

dcsan opened this issue Jul 26, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@dcsan
Copy link

dcsan commented Jul 26, 2024

I'm trying to create a graph with my own data rather than the sample static data, but the docs are very hard to follow.
trying to use an auto-layout.

this page doesn't really help
https://sim51.github.io/react-sigma/docs/api#layout-modules

eg const {positions, assign} = useLayoutCircular(...);

what do i pass to this? how do i use it?

the nearest example I can find is this:

https://github.com/sim51/react-sigma/blob/e6528da2c1fa6f11413366f05bd6fd547f940f03/packages/storybook/stories/LayoutFA2.tsx

but it depends on a multitude of other parts. first error:

Error: Sigma: could not find a valid position (x, y) for node "apple". All your nodes must have a number "x" and "y". Maybe your forgot to apply a layout or your "nodeReducer" is not returning the correct data?

so I think I need to implement some type of reducer?

I found some code here:
https://github.com/sim51/react-sigma/blob/main/packages/storybook/stories/common/SampleGraph.tsx#L7

but it's a lot to conform to extract that reducer to use.
functions seem to be missing eg:

const graph = sigma.getGraph(); // Property getGraph does not exist on type

so i need to find some interfaces maybe from
https://github.com/sim51/react-sigma/blob/main/packages/storybook/stories/MultiDirectedGraph.tsx#L11

there must be a simpler way to use a layout with a graph?

@dcsan dcsan added the enhancement New feature or request label Jul 26, 2024
@dcsan
Copy link
Author

dcsan commented Jul 26, 2024

actually even adding random values I still get an error

Error: Sigma: could not find a valid position (x, y) for node "apple silicon". All your nodes must have a number "x" and "y". Maybe your forgot to apply a layout or your "nodeReducer" is not returning the correct data?

where the data clearly does have an x and y

{
    "options": {
        "type": "mixed",
        "multi": false,
        "allowSelfLoops": true
    },
    "attributes": {},
    "nodes": [
        {
            "key": "apple silicon",
            "x": 0.2415696726063068,
            "y": 0.027308567567481346
        },

...

    "edges": [
        {
            "key": "geid_125_0",
            "source": "apple silicon",
            "target": "industry-leading neural engines",
            "attributes": {
                "type": "integrates",
                "weight": 1
            }
        },

 ... // etc

}
/**
 * https://github.com/sim51/react-sigma/blob/e6528da2c1fa6f11413366f05bd6fd547f940f03/packages/storybook/stories/LayoutFA2.tsx
 */

import { CSSProperties, useEffect } from "react";
import { SigmaContainer, useLoadGraph } from "@react-sigma/core";
import "@react-sigma/core/lib/react-sigma.min.css";

// import { useDispatch, useSelector } from "react-redux";
// import { selectStory, selectChapter, setStory } from "../../redux/semSlice"

import { SemData } from "../../types/sharedTypes/SemTypes";
import Graph from "graphology";
import { useLoaderData } from "react-router-dom";

const sigmaStyle: CSSProperties = {
  right: '0px',
  top: '0px',
  position: "absolute",
  height: "500px",
  width: "500px"
};

// Component that load the graph
export const LoadGraph = () => {
  // const dispatch = useDispatch()
  const semData = useLoaderData() as SemData
  const story = semData
  // const story = useSelector(selectStory)
  // if (semData) {
  //   dispatch(setStory(semData))
  // }
  // const story: SemData | undefined = useSelector(selectStory)
  // if (!story?.graph) return null;

  const loadGraph = useLoadGraph();
  useEffect(() => {
    console.log('LoadGraph / story', story)

    const graphData = { ...story?.graph } // unfreeze
    console.log('graphData', graphData)

    const graph = new Graph();

    graphData.nodes.forEach((node) => {
      const n = ({ ...node, x: Math.random(), y: Math.random() });
      console.log('n', n)
      graph.addNode(n);
    })
    console.log('graph.json', graph.toJSON())

    loadGraph(graph);
  }, [story, loadGraph]);
  return null;
};



// Component that display the graph
export const SemGraphBase = () => {

  return (
    <SigmaContainer style={sigmaStyle}>
      <LoadGraph />
    </SigmaContainer>
  );
};

@dcsan
Copy link
Author

dcsan commented Jul 29, 2024

@sim51
Copy link
Owner

sim51 commented Jul 30, 2024

Layout hooks doesn't need parameters, they directly used the graph of the sigma instance.
The best example is this one : https://github.com/sim51/react-sigma/blob/main/packages/storybook/stories/LayoutCircular.tsx

If I take your example, it becomes something like that :


// Component that load the graph
export const LoadGraph = () => {
  // Hook for the layout
  const { positions, assign } = useLayoutCircular();
  // Hook to load the graph
  const loadGraph = useLoadGraph();

  const semData = useLoaderData() as SemData
  const story = semData


  useEffect(() => {
    console.log('LoadGraph / story', story)

    const graphData = { ...story?.graph } // unfreeze
    const graph = new Graph();
    graphData.nodes.forEach((node) => {
      const n = ({ ...node, x: Math.random(), y: Math.random() });
      graph.addNode(n);
    })
    // Load the graph in sigma
    loadGraph(graph);
    // Apply the layout
    assign();

  }, [story, loadGraph]);
  
  return null;
};

@sim51
Copy link
Owner

sim51 commented Jul 30, 2024

BTW, you don't use the graph.addNode correctly.
Check the graphology doc about it : https://graphology.github.io/mutation.html#addnode

You should replace your code by this :

  graphData.nodes.forEach((node) => {
      const n = ({ ...node, x: Math.random(), y: Math.random() });
      graph.addNode(n.key, n);
    })

@dcsan
Copy link
Author

dcsan commented Jul 31, 2024

great thanks for your help.

re data format / addNode, yes i found that in the end. I'm using graphology to generate the data and storing it but i guess the client loader doesn't load the graph.toJSON() format, i have to walk through and add each node.

re animation
So the circularLayout is for a static 'one shot' layout.
the non-obvious part is that you can just call assign() with no params, and some magic modifies the positions, I guess using the context api?

the docs show there are some unknown ... params passed?
perhaps this is only for layouts that need animations?

const { positions, assign } = useLayoutForce(...);

When I try to switch to useLayoutForce there is no layout applied. So I guess "it depends" which layout.

I guess this type of layout needs the core and an animation worker, and perhaps another nested component?
which I can't see any example or clear docs for.

Would you have an example using a forceLayout or any of those?

@dcsan
Copy link
Author

dcsan commented Jul 31, 2024

nvm I got it to work something like this:

const Fa2: FC = () => {
  const { start, kill } = useWorkerLayoutForceAtlas2({ settings: { slowDown: 10 } });

  useEffect(() => {
    // start FA2
    start();

    // Kill FA2 on unmount
    return () => {
      kill();
    };
  }, [start, kill]);

  return null;
};


// Component that display the graph
export const SemGraphBase = () => {

  return (
    <SigmaContainer style={sigmaStyle}>
      <LoadGraph />
      <Fa2 />
    </SigmaContainer>
  );
};

now i just need to find the other details like directional edges, stopping the animation etc.

@sim51
Copy link
Owner

sim51 commented Jul 31, 2024

@DanielRuf
Copy link

import { useLayoutCircular } from "@react-sigma/layout-circular"; is also missing at https://sim51.github.io/react-sigma/docs/api/#none-iterative-layouts

sim51 added a commit that referenced this issue Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants