Is there a utility function to insert add a
element to el in JSComponent
and wait for it to be fully integrated before trying to use it?
and wait for it to be fully integrated before trying to use it?
Below what I am trying to do, but const board = JXG.JSXGraph.initBoard(el.id, {}
gives me errors no matter what I tried!
import panel as pn
from panel.custom import JSComponent
# Define the JSXGraph Custom Component
class JSXGraphComponent(JSComponent):
_esm = """
import jsxgraph from 'https://cdn.jsdelivr.net/npm/jsxgraph@1.4.6/+esm';
export function render({model, el}) {
// Ensure the container element has proper dimensions and ID
el.style.width = model.width + 'px';
el.style.height = model.height + 'px';
el.style.border = '1px solid black';
if (!el.id) {
el.id = 'jsxgraph-container-' + Math.random().toString(36).substr(2, 9);
}
// Wait for DOM to render before initializing JSXGraph
requestAnimationFrame(() => {
if (!el.parentElement) return; // Ensure container exists
// Initialize JSXGraph board
const board = JXG.JSXGraph.initBoard(el.id, {
boundingbox: [-5, 5, 5, -5],
showCopyright: false,
showNavigation: false,
keepAspectRatio: true,
axis: true
});
// Add points and arrows
const p = board.create('point', [-3, -3], { name: '\\\\(p\\\\)' });
const q = board.create('point', [0, 2], { name: '\\\\(q\\\\)' });
const r = board.create('point', [3, -3], { name: '\\\\(r\\\\)' });
board.create('arrow', [p, q], {
withLabel: true,
name: '\\\\(\\\\vec{pq}\\\\)',
label: { position: 'top' },
lastArrow: { type: 4, size: 8 }
});
board.create('arrow', [q, r], {
withLabel: true,
name: '\\\\(\\\\vec{qr}\\\\)',
label: { position: 'top' },
lastArrow: { type: 4, size: 8 }
});
board.create('arrow', [p, r], {
withLabel: true,
name: '\\\\(\\\\vec{pr}\\\\)',
label: { position: 'top' },
lastArrow: { type: 4, size: 8 }
});
// Cleanup logic
model._board = board;
});
return () => {
if (model._board) {
JXG.JSXGraph.freeBoard(model._board);
model._board = null;
}
};
}
"""
# Create the component instance
jsxgraph = JSXGraphComponent(width=500, height=500)
# Serve using Panel
pn.Column("# JSXGraph Embedded in Panel", jsxgraph).servable()