File size: 1,836 Bytes
84a2044
342bc0e
 
05c6778
84a2044
05c6778
 
 
 
 
 
c6246d1
 
05c6778
c6246d1
 
 
 
 
 
 
05c6778
c6246d1
05c6778
c6246d1
 
05c6778
c6246d1
 
 
 
 
 
 
 
05c6778
c6246d1
05c6778
 
 
 
 
 
 
 
 
 
 
 
 
 
84a2044
05c6778
 
 
 
 
 
 
 
 
3e1ec11
05c6778
 
 
 
 
342bc0e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React, { useEffect, type CSSProperties } from "react";
import LynxKiteNode from "./LynxKiteNode";
import { NodeWithParams } from "./NodeWithParams";

const NodeWithMolecule = (props: any) => {
  const containerRef = React.useRef<HTMLDivElement>(null);
  const viewerRef = React.useRef<any>(null);

  useEffect(() => {
    const config = props.data?.display?.value;
    if (!config || !containerRef.current) return;
    async function run() {
      const $3Dmol = await import("3dmol");

      try {
        // Initialize viewer only once
        if (!viewerRef.current) {
          viewerRef.current = $3Dmol.createViewer(containerRef.current, {
            backgroundColor: "white",
          });
        }

        const viewer = viewerRef.current;

        // Clear previous models
        viewer.clear();

        // Add new model and style it
        viewer.addModel(config.data, config.format);
        viewer.setStyle({}, { stick: {} });
        viewer.zoomTo();
        viewer.render();
      } catch (error) {
        console.error("Error rendering 3D molecule:", error);
      }
    }
    run();
    const resizeObserver = new ResizeObserver(() => {
      viewerRef.current?.resize();
    });

    const observed = containerRef.current;
    resizeObserver.observe(observed);
    return () => {
      resizeObserver.unobserve(observed);
      if (viewerRef.current) {
        viewerRef.current.clear();
      }
    };
  }, [props.data?.display?.value]);

  const vizStyle: CSSProperties = {
    flex: 1,
    minHeight: "300px",
    border: "1px solid #ddd",
    borderRadius: "4px",
    overflow: "hidden",
    position: "relative",
  };

  return (
    <NodeWithParams collapsed {...props}>
      <div style={vizStyle} ref={containerRef} />
    </NodeWithParams>
  );
};

export default LynxKiteNode(NodeWithMolecule);