Spaces:
Running
Running
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;
|