Skip to content

Commit

Permalink
WIP: upgrade to sigma v3
Browse files Browse the repository at this point in the history
  • Loading branch information
sim51 committed Mar 22, 2024
1 parent f8db8b8 commit bdd3307
Show file tree
Hide file tree
Showing 62 changed files with 15,460 additions and 39,709 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 20

- name: Install
run: npm install
Expand Down
6 changes: 5 additions & 1 deletion project/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
]
],
"rules": {
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
"react/react-in-jsx-scope": "off"
}
}
54,421 changes: 15,133 additions & 39,288 deletions project/package-lock.json

Large diffs are not rendered by default.

50 changes: 26 additions & 24 deletions project/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@react-sigma/root",
"version": "3.4.0",
"version": "4.0.0",
"description": "React Sigma",
"author": "Benoit Simard",
"license": "MIT",
Expand All @@ -24,7 +24,7 @@
"lint": "esw . --ext .ts --ext .tsx",
"tsc": "tsc -b --preserveWatchOutput",
"compile": "npm run clean && npm run lint && npm run tsc",
"build": "npm run compile && npm run build --workspaces --if-present",
"build": "npm run compile && npm run build -w @react-sigma/core -w @react-sigma/layout-core -w @react-sigma/layout-circlepack -w @react-sigma/layout-circular -w @react-sigma/layout-force -w @react-sigma/layout-forceatlas2 -w @react-sigma/layout-noverlap -w @react-sigma/layout-random -w @react-sigma/examples",
"test": "npm run test --workspaces --if-present",
"start": "concurrently -n lint,compile,core,layout-core,layout-circlepack,layout-circular,layout-force,layout-forceatlas2,layout-noverlap,layout-random,examples 'npm run lint -- --watch' 'npm run tsc -- --watch' 'npm run start --workspace=@react-sigma/core' 'npm run start --workspace=@react-sigma/layout-core' 'npm run start --workspace=@react-sigma/layout-circlepack' 'npm run start --workspace=@react-sigma/layout-circular' 'npm run start --workspace=@react-sigma/layout-force' 'npm run start --workspace=@react-sigma/layout-forceatlas2' 'npm run start --workspace=@react-sigma/layout-noverlap' 'npm run start --workspace=@react-sigma/layout-random' 'npm run start --workspace=@react-sigma/examples'",
"lerna:changed": "lerna changed",
Expand All @@ -33,30 +33,32 @@
"lerna:publish": "lerna publish --no-private"
},
"devDependencies": {
"@rbnlffl/rollup-plugin-eslint": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.2",
"@rollup/plugin-url": "^7.0.0",
"@svgr/rollup": "^6.2.1",
"@types/lodash": "4.14.185",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"concurrently": "^7.2.1",
"eslint": "^8.24.0",
"eslint-config-next": "^12.3.1",
"eslint-plugin-react": "^7.31.8",
"@rollup/plugin-typescript": "^11.1.6",
"@rollup/plugin-url": "^8.0.2",
"@rollup/plugin-eslint": "^9.0.5",
"@rollup/plugin-terser": "^0.4.4",
"@svgr/rollup": "^8.1.0",
"@types/lodash": "4.14.202",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-watch": "^8.0.0",
"lerna": "^5.5.2",
"nodemon": "^2.0.20",
"rimraf": "^3.0.2",
"rollup": "^2.74.1",
"rollup-plugin-import-css": "^3.0.3",
"rollup-plugin-terser": "^7.0.2",
"tslib": "^2.4.0",
"typescript": "^4.6.4"
"lerna": "^8.1.2",
"nodemon": "^3.1.0",
"rimraf": "^5.0.5",
"rollup": "^4.12.0",
"rollup-plugin-import-css": "^3.5.0",
"tslib": "^2.6.2",
"typescript": "^5.3.3"
},
"dependencies": {
"graphology": "^0.25.1",
"graphology-types": "^0.24.5",
"sigma": "^2.4.0"
"graphology": "^0.25.4",
"graphology-types": "^0.24.7",
"sigma": "3.0.0-beta.14"
}
}
21 changes: 8 additions & 13 deletions project/packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@react-sigma/core",
"version": "3.4.2",
"private": false,
"version": "4.0.0",
"description": "React Sigma",
"author": "Benoit Simard",
"license": "MIT",
Expand All @@ -18,6 +17,7 @@
"graph",
"graphology"
],
"type": "module",
"main": "./lib/react-sigma_core.umd.min.js",
"module": "./lib/react-sigma_core.esm.min.js",
"typings": "./lib/index.d.ts",
Expand All @@ -36,23 +36,18 @@
"build": "npm run lint && npm run compile && npm run assets && rollup -c",
"start": "nodemon --watch src -e ts,tsx,css --exec npm run build"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"devDependencies": {
"@types/node": "^18.7.18",
"@types/react": "^18.0.9",
"@types/react-dom": "^18.0.5",
"@types/node": "^20.11.20",
"@types/react": "^18.2.58",
"@types/react-dom": "^18.2.19",
"copyfiles": "^2.4.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"peerDependencies": {
"graphology": "^0.25.1",
"lodash": "^4.17.21",
"react": "^17.0.0 || ^18.0.0",
"sigma": "^2.4.0"
},
"gitHead": "5b4c6d2ab9c4d5dbf70b5108f678ee3f6f22ed17"
"react": "^18.0.0",
"sigma": "3.0.0-beta.14"
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { terser } from "rollup-plugin-terser";
import svgr from "@svgr/rollup";
import terser from "@rollup/plugin-terser";
import url from "@rollup/plugin-url";
import css from "rollup-plugin-import-css";
import typescript from "@rollup/plugin-typescript";
import eslint from "@rbnlffl/rollup-plugin-eslint";
import eslint from "@rollup/plugin-eslint";
import svgr from "@svgr/rollup";
import css from "rollup-plugin-import-css";

/** @type {import("rollup").RollupOptions} */
export default {
input: "src/index.ts",
output: [
{
file: "lib/react-sigma_core.esm.min.js",
format: "esm",
plugins: [terser()],
sourcemap: true,
},
{
file: "lib/react-sigma_core.umd.min.js",
format: "umd",
name: "@react-sigma/core",
plugins: [terser()],
sourcemap: true,
},
],
plugins: [
css({ output: "react-sigma.min.css", minify: true }),
url(),
svgr({ icon: true }),
eslint({ filterExclude: "./src/assets/**" }),
eslint({ exclude: "./src/assets/**" }),
typescript({ tsconfig: "./tsconfig.json", outputToFilesystem: true }),
terser(),
],
external: ["sigma", "graphology", "lodash", "react", "react-dom"],
};

37 changes: 18 additions & 19 deletions project/packages/core/src/components/SigmaContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,25 @@ import React, {
} from "react";
import { isEqual } from "lodash";
import Graph from "graphology";
import { GraphOptions } from "graphology-types";
import { Sigma } from "sigma";
import { Settings } from "sigma/settings";

import { SigmaProvider } from "../hooks/context";

type GraphConstructor<G extends Graph> = new (options?: GraphOptions) => G;
export type GraphType<G extends Graph> = G | GraphConstructor<G>;
import { GraphType } from "../types";
import { Attributes } from "graphology-types";

/**
* Properties for `SigmaContainer` component
*/
export interface SigmaContainerProps<G extends Graph> {
export interface SigmaContainerProps<N extends Attributes, E extends Attributes, G extends Attributes> {
/**
* Graphology instance or constructor
*/
graph?: GraphType<G>;
graph?: GraphType<N, E, G>;
/**
* Sigma settings
*/
settings?: Partial<Settings>;
settings?: Partial<Settings<N, E, G>>;
/**
* HTML id
*/
Expand All @@ -59,10 +57,13 @@ export interface SigmaContainerProps<G extends Graph> {
*
* @category Component
*/
// eslint-disable-next-line react/display-name
const SigmaContainerComponent = <G extends Graph>(
{ graph, id, className, style, settings, children }: PropsWithChildren<SigmaContainerProps<G>>,
ref: Ref<Sigma<G> | null>,
const SigmaContainerComponent = <
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
>(
{ graph, id, className, style, settings, children }: PropsWithChildren<SigmaContainerProps<N, E, G>>,
ref: Ref<Sigma<N, E, G> | null>,
) => {
// Root HTML element
const rootRef = useRef<HTMLDivElement>(null);
Expand All @@ -71,27 +72,25 @@ const SigmaContainerComponent = <G extends Graph>(
// Common html props for the container
const props = { className: `react-sigma ${className ? className : ""}`, id, style };
// Sigma instance
const [sigma, setSigma] = useState<Sigma<G> | null>(null);
const [sigma, setSigma] = useState<Sigma<N, E, G> | null>(null);
// Sigma settings
const sigmaSettings = useRef<Partial<Settings>>({});
const sigmaSettings = useRef<Partial<Settings<N, E, G>>>({});
if (!isEqual(sigmaSettings.current, settings)) sigmaSettings.current = settings || {};

/**
* When graph or settings changed
* => create sigma
*/
useEffect(() => {
let instance: Sigma<G> | null = null;
let instance: Sigma<N, E, G> | null = null;

if (containerRef.current !== null) {
let sigGraph: G = new Graph() as G;
let sigGraph = new Graph<N, E, G>();
if (graph) {
sigGraph = typeof graph === "function" ? new graph() : graph;
}
instance = new Sigma(sigGraph, containerRef.current, {
allowInvalidContainer: true,
...sigmaSettings.current,
});

instance = new Sigma(sigGraph, containerRef.current, sigmaSettings.current);
if (sigma) instance.getCamera().setState(sigma.getCamera().getState());
}
setSigma(instance);
Expand Down
21 changes: 15 additions & 6 deletions project/packages/core/src/hooks/context.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import Graph from "graphology";
import { Attributes } from "graphology-types";
import { createContext, useContext } from "react";
import Sigma from "sigma/sigma";
import Sigma from "sigma";

export interface SigmaContextInterface<G extends Graph = Graph> {
sigma: Sigma<G>;
export interface SigmaContextInterface<
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
> {
sigma: Sigma<N, E, G>;
container: HTMLElement;
}

Expand All @@ -27,10 +31,15 @@ export const SigmaProvider = SigmaContext.Provider;
*
* @category Hook
*/
export function useSigmaContext<G extends Graph = Graph>(): SigmaContextInterface<G> {
export function useSigmaContext<
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
>(): SigmaContextInterface<N, E, G> {
const context = useContext(SigmaContext);
if (context == null) {
throw new Error("No context provided: useSigmaContext() can only be used in a descendant of <SigmaContainer>");
}
return context as SigmaContextInterface<G>;
// cast context to the one with good generics
return context as unknown as SigmaContextInterface<N, E, G>;
}
6 changes: 2 additions & 4 deletions project/packages/core/src/hooks/useCamera.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback, useRef } from "react";
import { isEqual } from "lodash";
import { AnimateOptions } from "sigma/utils/animate";
import { AnimateOptions } from "sigma/utils";
import { CameraState } from "sigma/types";

import { useSigma } from "./useSigma";
Expand All @@ -16,9 +16,7 @@ type CameraOptions = Partial<AnimateOptions> & { factor?: number };
*
* @category Hook
*/
export function useCamera(
options?: CameraOptions,
): {
export function useCamera(options?: CameraOptions): {
zoomIn: (options?: CameraOptions) => void;
zoomOut: (options?: CameraOptions) => void;
reset: (options?: Partial<AnimateOptions>) => void;
Expand Down
11 changes: 8 additions & 3 deletions project/packages/core/src/hooks/useLoadGraph.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback } from "react";
import Graph from "graphology";
import { Attributes } from "graphology-types";

import { useSigma } from "./useSigma";

Expand All @@ -14,11 +15,15 @@ import { useSigma } from "./useSigma";
*```
* @category Hook
*/
export function useLoadGraph<G extends Graph = Graph>(): (graph: G, clear?: boolean) => void {
const sigma = useSigma<G>();
export function useLoadGraph<
N extends Attributes = Attributes,
E extends Attributes = Attributes,
G extends Attributes = Attributes,
>(): (graph: Graph<N, E, G>, clear?: boolean) => void {
const sigma = useSigma<N, E, G>();

return useCallback(
(graph: G, clear = true) => {
(graph: Graph<N, E, G>, clear = true) => {
if (sigma && graph) {
if (clear && sigma.getGraph().order > 0) sigma.getGraph().clear();
sigma.getGraph().import(graph);
Expand Down
Loading

0 comments on commit bdd3307

Please sign in to comment.