Search code examples
typescriptreact-domsigma.js

In SigmaJs i get "Uncaught TypeError: Cannot read properties of undefined (reading 'process')" error


I started out from the demo project that can be found on the offical SigmaJs github repo: https://github.com/jacomyal/sigma.js The error is the following:

Uncaught TypeError: Cannot read properties of undefined (reading 'process') sigma.js:626
at Sigma.process (sigma.js:626:1)
at Sigma._refresh (sigma.js:704:1)
at sigma.js:726:1

I can see it in the browser's console, the solution compiles just fine with "npm start".

I'm trying to create a solution with SigmaJs which can load data from a Neo4j database and then render the nodes and edges. I was able to get the data from the db, parse it in the form which this is able to process. The graph object gets all the nodes and edges. On the UI clusters and tags are swapped with mine. The only thing (in my ipinion) that isn't working as of now is the nodes are not shown.

They get the hidden value of true somewhere for some reason.

The node has a label and tags as well, but those are sensitive data.

I couldn't manage to figure it out. In SigmaJs/demo/src/views/Root.tsx there is a part which i don't know how to change or rather to what to change for. I don't use images, but i get same error with or without this line:

<div id="app-root" className={showContents ? "show-contents" : ""}>
      <SigmaContainer
        graphOptions={{ type: "directed" }}
        initialSettings={{
          nodeProgramClasses: { image: getNodeProgramImage() }, <----------------
          labelRenderer: drawLabel,
          defaultNodeType: "image", <-------- This line i got rid of.
          defaultEdgeType: "arrow",
          labelDensity: 0.07,
          labelGridCellSize: 60,
          labelRenderedSizeThreshold: 15,
          labelFont: "Lato, sans-serif",
          zIndex: true,
        }}
        className="react-sigma"
      >
        <GraphSettingsController hoveredNode={hoveredNode} />
        <GraphEventsController setHoveredNode={setHoveredNode} />
        <GraphDataController dataset={dataset} filters={filtersState} />
        {dataReady && (
          <>
            <div className="controls">
              <div className="ico">
                <button
                  type="button"
                  className="show-contents"
                  onClick={() => setShowContents(true)}
                  title="Show caption and description"
                >
                  <BiBookContent />
                </button>
              </div>
              <FullScreenControl
                className="ico"
                customEnterFullScreen={<BsArrowsFullscreen />}
                customExitFullScreen={<BsFullscreenExit />}
              />
              <ZoomControl
                className="ico"
                customZoomIn={<BsZoomIn />}
                customZoomOut={<BsZoomOut />}
                customZoomCenter={<BiRadioCircleMarked />}
              />
            </div>
            <div className="contents">
              <div className="ico">
                <button
                  type="button"
                  className="ico hide-contents"
                  onClick={() => setShowContents(false)}
                  title="Show caption and description"
                >
                  <GrClose />
                </button>
              </div>
              <GraphTitle filters={filtersState} />
              <div className="panels">
                <SearchField filters={filtersState} />
                <DescriptionPanel />
                <ClustersPanel
                  clusters={dataset.clusters}
                  filters={filtersState}
                  setClusters={(clusters) =>
                    setFiltersState((filters) => ({
                      ...filters,
                      clusters,
                    }))
                  }
                  toggleCluster={(cluster) => {
                    setFiltersState((filters) => ({
                      ...filters,
                      clusters: filters.clusters[cluster]
                        ? omit(filters.clusters, cluster)
                        : { ...filters.clusters, [cluster]: true },
                    }));
                  }}
                />
                <TagsPanel
                  tags={dataset.tags}
                  filters={filtersState}
                  setTags={(tags) =>
                    setFiltersState((filters) => ({
                      ...filters,
                      tags,
                    }))
                  }
                  toggleTag={(tag) => {
                    setFiltersState((filters) => ({
                      ...filters,
                      tags: filters.tags[tag] ? omit(filters.tags, tag) : { ...filters.tags, [tag]: true },
                    }));
                  }}
                />
              </div>
            </div>
          </>
        )}
      </SigmaContainer>
    </div>

Solution

  • Thank you Tomaž Bratanič!! After some investigation on the repository which is in the comment section, i found my problems.
    The nodes weren't shown because they got a hidden value of true. That happens in https://github.com/jacomyal/sigma.js/blob/main/demo/src/views/GraphDataController.tsx

    graph.forEachNode((node, { cluster, tag }) =>
          graph.setNodeAttribute(node, "hidden", ---> !clusters[cluster] || !tags[tag]), <---
        );
    

    The part between the arrows is responsible for this value. In my case the cluster which the node has is a list, so i had to implement a function for it like so:

    function isTagHidden(id: string): boolean {
        let ishidden = false;
        const { tags } = filters; <-- containts records of clusters and tags
        let node = graph.getNodeAttributes(id);
        node.tags.forEach((key: string) => {
          if (tags[key]) {
            ishidden = true;
          }
        });
        return ishidden;
      }
    

    Another similar function for the clusters.

    As for the main problem which the title refers to, it was simple missplace of code. In the root file there is a variable which starts the animation.

    if (!dataset) return null;    
    requestAnimationFrame(() => setDataReady(true));
    

    I'm using async methods so it does matter where do i put this line or else I'm giving an empty dataset and there is no wonder why it is undefined. So i placed it after a check and everything works fine!

    I hope i was clear and this helps if you engage with sigma.js.