doragera commited on
Commit
d6db5a1
·
1 Parent(s): acc4157

molecule visualizing, requests->httpx, support multiple molecules

Browse files
lynxkite-app/web/package-lock.json CHANGED
@@ -18,11 +18,13 @@
18
  "@syncedstore/react": "^0.6.0",
19
  "@types/node": "^22.10.1",
20
  "@xyflow/react": "^12.3.5",
 
21
  "axios": "^1.8.2",
22
  "daisyui": "^4.12.20",
23
  "echarts": "^5.5.1",
24
  "fuse.js": "^7.0.0",
25
  "json-schema-to-typescript": "^15.0.3",
 
26
  "react": "^18.3.1",
27
  "react-dom": "^18.3.1",
28
  "react-markdown": "^9.0.1",
@@ -2366,6 +2368,22 @@
2366
  "d3-zoom": "^3.0.0"
2367
  }
2368
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2369
  "node_modules/abstract-leveldown": {
2370
  "version": "6.2.3",
2371
  "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
@@ -4187,6 +4205,12 @@
4187
  "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
4188
  "license": "MIT"
4189
  },
 
 
 
 
 
 
4190
  "node_modules/is-alphabetical": {
4191
  "version": "2.0.1",
4192
  "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -5465,8 +5489,7 @@
5465
  "version": "0.52.2",
5466
  "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
5467
  "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
5468
- "license": "MIT",
5469
- "peer": true
5470
  },
5471
  "node_modules/ms": {
5472
  "version": "2.1.3",
@@ -5518,6 +5541,15 @@
5518
  "dev": true,
5519
  "license": "MIT"
5520
  },
 
 
 
 
 
 
 
 
 
5521
  "node_modules/no-case": {
5522
  "version": "3.0.4",
5523
  "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -5649,6 +5681,12 @@
5649
  "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==",
5650
  "license": "MIT"
5651
  },
 
 
 
 
 
 
5652
  "node_modules/parent-module": {
5653
  "version": "1.0.1",
5654
  "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -7107,6 +7145,21 @@
7107
  "browserslist": ">= 4.21.0"
7108
  }
7109
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7110
  "node_modules/uri-js": {
7111
  "version": "4.4.1",
7112
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
 
18
  "@syncedstore/react": "^0.6.0",
19
  "@types/node": "^22.10.1",
20
  "@xyflow/react": "^12.3.5",
21
+ "3dmol": "^2.4.2",
22
  "axios": "^1.8.2",
23
  "daisyui": "^4.12.20",
24
  "echarts": "^5.5.1",
25
  "fuse.js": "^7.0.0",
26
  "json-schema-to-typescript": "^15.0.3",
27
+ "monaco-editor": "^0.52.2",
28
  "react": "^18.3.1",
29
  "react-dom": "^18.3.1",
30
  "react-markdown": "^9.0.1",
 
2368
  "d3-zoom": "^3.0.0"
2369
  }
2370
  },
2371
+ "node_modules/3dmol": {
2372
+ "version": "2.4.2",
2373
+ "resolved": "https://registry.npmjs.org/3dmol/-/3dmol-2.4.2.tgz",
2374
+ "integrity": "sha512-7R6uFaF5++s9EpO+R0a3bs6igi5idI+sgrVhtozaZlOGHg6oourYkAlAwYxWRaeBGlNcAd+oEIhbhJYhNxGyZA==",
2375
+ "license": "BSD-3-Clause",
2376
+ "dependencies": {
2377
+ "iobuffer": "^5.3.1",
2378
+ "netcdfjs": "^3.0.0",
2379
+ "pako": "^2.1.0",
2380
+ "upng-js": "^2.1.0"
2381
+ },
2382
+ "engines": {
2383
+ "node": ">=16.16.0",
2384
+ "npm": ">=8.11"
2385
+ }
2386
+ },
2387
  "node_modules/abstract-leveldown": {
2388
  "version": "6.2.3",
2389
  "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
 
4205
  "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
4206
  "license": "MIT"
4207
  },
4208
+ "node_modules/iobuffer": {
4209
+ "version": "5.4.0",
4210
+ "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz",
4211
+ "integrity": "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==",
4212
+ "license": "MIT"
4213
+ },
4214
  "node_modules/is-alphabetical": {
4215
  "version": "2.0.1",
4216
  "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
 
5489
  "version": "0.52.2",
5490
  "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
5491
  "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
5492
+ "license": "MIT"
 
5493
  },
5494
  "node_modules/ms": {
5495
  "version": "2.1.3",
 
5541
  "dev": true,
5542
  "license": "MIT"
5543
  },
5544
+ "node_modules/netcdfjs": {
5545
+ "version": "3.0.0",
5546
+ "resolved": "https://registry.npmjs.org/netcdfjs/-/netcdfjs-3.0.0.tgz",
5547
+ "integrity": "sha512-LOvT8KkC308qtpUkcBPiCMBtii7ZQCN6LxcVheWgyUeZ6DQWcpSRFV9dcVXLj/2eHZ/bre9tV5HTH4Sf93vrFw==",
5548
+ "license": "MIT",
5549
+ "dependencies": {
5550
+ "iobuffer": "^5.3.2"
5551
+ }
5552
+ },
5553
  "node_modules/no-case": {
5554
  "version": "3.0.4",
5555
  "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
 
5681
  "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==",
5682
  "license": "MIT"
5683
  },
5684
+ "node_modules/pako": {
5685
+ "version": "2.1.0",
5686
+ "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
5687
+ "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
5688
+ "license": "(MIT AND Zlib)"
5689
+ },
5690
  "node_modules/parent-module": {
5691
  "version": "1.0.1",
5692
  "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
 
7145
  "browserslist": ">= 4.21.0"
7146
  }
7147
  },
7148
+ "node_modules/upng-js": {
7149
+ "version": "2.1.0",
7150
+ "resolved": "https://registry.npmjs.org/upng-js/-/upng-js-2.1.0.tgz",
7151
+ "integrity": "sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==",
7152
+ "license": "MIT",
7153
+ "dependencies": {
7154
+ "pako": "^1.0.5"
7155
+ }
7156
+ },
7157
+ "node_modules/upng-js/node_modules/pako": {
7158
+ "version": "1.0.11",
7159
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
7160
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
7161
+ "license": "(MIT AND Zlib)"
7162
+ },
7163
  "node_modules/uri-js": {
7164
  "version": "4.4.1",
7165
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
lynxkite-app/web/package.json CHANGED
@@ -21,11 +21,13 @@
21
  "@syncedstore/react": "^0.6.0",
22
  "@types/node": "^22.10.1",
23
  "@xyflow/react": "^12.3.5",
 
24
  "axios": "^1.8.2",
25
  "daisyui": "^4.12.20",
26
  "echarts": "^5.5.1",
27
  "fuse.js": "^7.0.0",
28
  "json-schema-to-typescript": "^15.0.3",
 
29
  "react": "^18.3.1",
30
  "react-dom": "^18.3.1",
31
  "react-markdown": "^9.0.1",
 
21
  "@syncedstore/react": "^0.6.0",
22
  "@types/node": "^22.10.1",
23
  "@xyflow/react": "^12.3.5",
24
+ "3dmol": "^2.4.2",
25
  "axios": "^1.8.2",
26
  "daisyui": "^4.12.20",
27
  "echarts": "^5.5.1",
28
  "fuse.js": "^7.0.0",
29
  "json-schema-to-typescript": "^15.0.3",
30
+ "monaco-editor": "^0.52.2",
31
  "react": "^18.3.1",
32
  "react-dom": "^18.3.1",
33
  "react-markdown": "^9.0.1",
lynxkite-app/web/src/workspace/Workspace.tsx CHANGED
@@ -36,6 +36,7 @@ import NodeSearch, { type OpsOp, type Catalog, type Catalogs } from "./NodeSearc
36
  import NodeWithGraphCreationView from "./nodes/GraphCreationNode.tsx";
37
  import NodeWithImage from "./nodes/NodeWithImage.tsx";
38
  import NodeWithParams from "./nodes/NodeWithParams";
 
39
  import NodeWithTableView from "./nodes/NodeWithTableView.tsx";
40
  import NodeWithVisualization from "./nodes/NodeWithVisualization.tsx";
41
 
@@ -173,6 +174,7 @@ function LynxKiteFlow() {
173
  image: NodeWithImage,
174
  table_view: NodeWithTableView,
175
  graph_creation_view: NodeWithGraphCreationView,
 
176
  }),
177
  [],
178
  );
 
36
  import NodeWithGraphCreationView from "./nodes/GraphCreationNode.tsx";
37
  import NodeWithImage from "./nodes/NodeWithImage.tsx";
38
  import NodeWithParams from "./nodes/NodeWithParams";
39
+ import NodeWithPy3Dmol from "./nodes/NodeWithPy3DMol.tsx";
40
  import NodeWithTableView from "./nodes/NodeWithTableView.tsx";
41
  import NodeWithVisualization from "./nodes/NodeWithVisualization.tsx";
42
 
 
174
  image: NodeWithImage,
175
  table_view: NodeWithTableView,
176
  graph_creation_view: NodeWithGraphCreationView,
177
+ py3dmol: NodeWithPy3Dmol,
178
  }),
179
  [],
180
  );
lynxkite-app/web/src/workspace/nodes/NodeWithPy3DMol.tsx ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect } from "react";
2
+ import NodeWithParams from "./NodeWithParams";
3
+ const $3Dmol = await import("3dmol");
4
+
5
+ const NodeWithPy3Dmol = (props: any) => {
6
+ const containerRef = React.useRef<HTMLDivElement>(null);
7
+ const viewerRef = React.useRef<any>(null);
8
+
9
+ useEffect(() => {
10
+ const config = props.data?.display?.value;
11
+ if (!config || !containerRef.current) return;
12
+
13
+ try {
14
+ // Initialize viewer only once
15
+ if (!viewerRef.current) {
16
+ viewerRef.current = $3Dmol.createViewer(containerRef.current, {
17
+ backgroundColor: "white",
18
+ });
19
+ }
20
+
21
+ const viewer = viewerRef.current;
22
+
23
+ // Clear previous models
24
+ viewer.clear();
25
+
26
+ // Add new model and style it
27
+ viewer.addModel(config.data, config.format);
28
+ viewer.setStyle({}, { stick: {} });
29
+ viewer.zoomTo();
30
+ viewer.render();
31
+ } catch (error) {
32
+ console.error("Error rendering 3D molecule:", error);
33
+ }
34
+
35
+ const resizeObserver = new ResizeObserver(() => {
36
+ viewerRef.current?.resize();
37
+ });
38
+
39
+ const observed = containerRef.current;
40
+ resizeObserver.observe(observed);
41
+
42
+ return () => {
43
+ resizeObserver.unobserve(observed);
44
+ if (viewerRef.current) {
45
+ viewerRef.current.clear();
46
+ }
47
+ };
48
+ }, [props.data?.display?.value]);
49
+
50
+ const nodeStyle = { display: "flex", flexDirection: "column", height: "100%" };
51
+ const vizStyle = {
52
+ flex: 1,
53
+ minHeight: "300px",
54
+ border: "1px solid #ddd",
55
+ borderRadius: "4px",
56
+ overflow: "hidden",
57
+ position: "relative",
58
+ };
59
+
60
+ return (
61
+ <NodeWithParams nodeStyle={nodeStyle} collapsed {...props}>
62
+ <div style={vizStyle} ref={containerRef} />
63
+ </NodeWithParams>
64
+ );
65
+ };
66
+
67
+ export default NodeWithPy3Dmol;
lynxkite-core/src/lynxkite/core/ops.py CHANGED
@@ -180,6 +180,7 @@ class Op(BaseConfig):
180
  "table_view",
181
  "graph_creation_view",
182
  "image",
 
183
  ]:
184
  # If the operation is some kind of visualization, we use the output as the
185
  # value to display by default.
 
180
  "table_view",
181
  "graph_creation_view",
182
  "image",
183
+ "py3dmol",
184
  ]:
185
  # If the operation is some kind of visualization, we use the output as the
186
  # value to display by default.