iVis-at-Bilkent / cytoscape.js-fcose

fCoSE: a fast Compound Spring Embedder
MIT License
134 stars 25 forks source link

If quality is proof, mount () will not work #24

Open YusaNazuna opened 3 years ago

YusaNazuna commented 3 years ago
export const layout = {
  name: "fcose",
  quality: "proof",
  randomize: false,
  animate: true
};

With the above settings, the graph is not laid out correctly when mount() is used. It will only display a straight line graph. As far as I've verified, quality=proof only works when the initial option is container.

Works pettern

app.tsx

import React, { useState, useEffect } from "react";
import cytoscape from "cytoscape";
import fcose from "cytoscape-fcose";
import { ThemeProvider } from "styled-components";
import { GlobalStyle, theme } from "@/themes/global-style";
import { CytoscapeComponent } from "@/components/cytoscape";
import { nodes, edges, style, layout } from "@/data";

export default function App() {
  const options = {
    container: document.getElementById("cy"),
    elements: { nodes, edges },
    style,
    ready: function () {
      this.layout(layout).run();
    },
  };
  cytoscape.use(fcose);
  const cy = cytoscape(options as any);

  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
    </ThemeProvider>
  );
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Cytoscape</title>
  </head>
  <body>
    <div id="app" style="width: 100vw; height: 100vh"></div>
    <div id="cy" style="width: 100vw; height: 100vh"></div>
  </body>
</html>

Not works pettern

app.tsx

import React, { useState, useEffect } from "react";
import cytoscape from "cytoscape";
import fcose from "cytoscape-fcose";
import { ThemeProvider } from "styled-components";
import { GlobalStyle, theme } from "@/themes/global-style";
import { CytoscapeComponent } from "@/components/cytoscape";
import { nodes, edges, style, layout } from "@/data";

export default function App() {
  const options = {
    elements: { nodes, edges },
    style,
  };
  cytoscape.use(fcose);
  const cy = cytoscape(options as any);

  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <CytoscapeComponent cy={cy} />
    </ThemeProvider>
  );
}

cytoscape.tsx

import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { layout, style } from "@/data";

const Root = styled.div`
  width: 100vw;
  height: 100vh;
  background: ${(props) => props.theme.colors.background};
`;
export const CytoscapeComponent = ({ cy }) => {
  useEffect(() => {
    const container = document.getElementById("cy");
    cy.mount(container);
    cy.ready(function () {
      this.layout(layout).run();
    });
  }, []);

  return (
    <>
      <Root id="cy" />
    </>
  );
};

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Cytoscape</title>
  </head>
  <body>
    <div id="app" style="width: 100vw; height: 100vh"></div>
  </body>
</html>

Can you confirm this issue?

hasanbalci commented 3 years ago

@YusaNazuna I will look into the layout after mount() in detail. However, considering the cue you gave "It will only display a straight line graph.", this generally happens when all nodes are at the same position (on top of each other) before layout and randomize: false is used. In such a case, using a randomized layout (positioning nodes randomly) is a more logical option to obtain a good layout. If this is the case, I mean, all nodes are at the same position after you mount the container, I suggest using randomize: true.

YusaNazuna commented 3 years ago

@hasanbalci Thanks for checking it out for me. The node and edge data I prepared doesn't have any position data. But if I follow your demo.html and do not use mount(), the graph is not straight. I'm puzzled by this phenomenon. There's a reason why I don't want it to be randomize:true. The reason I don't want to set it to randomize:true is because I want to increase or decrease the distance between each edge by referring to the weight and other parameters in the data. Conversely, if there is a way to adjust edge distances with randomize:true, I can use the mount() specification without modifying it this time.