File size: 1,910 Bytes
1107514
d6db5a1
 
1107514
d6db5a1
 
 
 
 
 
1797f18
 
d6db5a1
1797f18
 
 
 
 
 
 
d6db5a1
1797f18
d6db5a1
1797f18
 
d6db5a1
1797f18
 
 
 
 
 
 
 
d6db5a1
1797f18
d6db5a1
 
 
 
 
 
 
 
 
 
 
 
 
 
1107514
 
 
 
 
 
 
d6db5a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1107514
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
70
71
72
73
74
import React, { useEffect, type CSSProperties } from "react";
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 nodeStyle: CSSProperties = {
    display: "flex",
    flexDirection: "column",
    height: "100%",
  };

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

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

export default NodeWithMolecule;