UNPKG

@linkurious/ogma-react

Version:

A light adaptation of Ogma for React application

561 lines (560 loc) 15.7 kB
import U, { createContext as K, useContext as V, memo as j, forwardRef as E, useRef as x, useState as f, useImperativeHandle as C, useEffect as l, useLayoutEffect as Y, useCallback as J } from "react"; import Q from "@linkurious/ogma"; import { renderToString as I } from "react-dom/server"; import { createPortal as _ } from "react-dom"; const W = K(null), y = () => { const e = V(W); if (!e) throw new Error("useOgma must be used within an OgmaProvider"); return e.ogma; }; function q(e, n) { Object.keys(e).forEach((o) => { const t = e[o]; t && n(o, t); }); } function X(e) { return e.startsWith("on") && e.length > 2 ? e[2].toLowerCase() + e.substring(3) : null; } const M = {}, Z = (e, n) => { const { options: o = M, children: t, graph: r, onReady: s, theme: a, className: d = "ogma-container" } = e, c = x({}), [i, b] = f(!1), [u, O] = f(), [L, S] = f(null), [v, H] = f(), [G, g] = f(M), [w, N] = f(); return C(n, () => u, [u]), l(() => { if (!L) return; const h = new Q({ container: L, graph: r, options: o }); a && (N(a), h.styles.setTheme(a)), O(h), b(!0), s && s(h); }, [L]), Y(() => { const h = () => u == null ? void 0 : u.view.forceResize(); return h(), window.addEventListener("resize", h), () => window.removeEventListener("resize", h); }, []), l(() => { u && (r && r !== v && (H(r), u.setGraph(r)), o && G !== o && (g(o), u.setOptions(o))); }, [r, o]), l(() => { u && a && a !== w && (N(a), u.styles.setTheme(a)); }, [a]), l(() => { if (!u) return; const h = {}; Object.keys(e).forEach((m) => { if (!m.startsWith("on")) return; const P = X(m), z = e[m]; P && typeof z == "function" && (h[P] = z); }), q(c.current, (m, T) => { h[m] || (u.events.off(T), delete c.current[m]); }), q(h, (m, T) => { const P = c.current[m]; P && P !== T && u.events.off(P), (!P || P !== T) && (u.events.on(m, T), c.current[m] = T); }); }, [e]), /* @__PURE__ */ U.createElement( "div", { style: { width: "100%", height: "100%" }, className: d, ref: (h) => S(h) }, u && /* @__PURE__ */ U.createElement( W.Provider, { value: { ogma: u } }, i && t ) ); }, He = j(E(Z)); function Ge(e, n, o) { return J(n, o || []); } const p = E( ({ selector: e, attributes: n }, o) => { const t = y(), [r, s] = f(); return C(o, () => r, [r]), l(() => { const a = e ? t.styles.addNodeRule(e, n) : t.styles.addNodeRule(n); return s(a), () => { a.destroy(), s(void 0); }; }, [e, n]), null; } ), ee = ({ attributes: e, fullOverwrite: n }) => { const o = y(); return l(() => (o.styles.setHoveredNodeAttributes(e, n), () => { o.styles.setHoveredNodeAttributes(null); }), [e, n]), null; }, te = ({ attributes: e, fullOverwrite: n }) => { const o = y(); return l(() => (o.styles.setSelectedNodeAttributes(e, n), () => { o.styles.setSelectedNodeAttributes(null); }), [e, n]), null; }, Re = Object.assign(p, { Hovered: ee, Selected: te }), ne = E( ({ selector: e, attributes: n }, o) => { const t = y(), [r, s] = f(); return C(o, () => r, [r]), l(() => { const a = e ? t.styles.addEdgeRule(e, n) : t.styles.addEdgeRule(n); return s(a), () => { a.destroy(), s(void 0); }; }, [e, n]), null; } ), oe = ({ attributes: e, fullOverwrite: n }) => { const o = y(); return l(() => (o.styles.setHoveredEdgeAttributes(e, n), () => { o.styles.setHoveredEdgeAttributes(null); }), [e, n]), null; }, se = ({ attributes: e, fullOverwrite: n }) => { const o = y(); return l(() => (o.styles.setSelectedEdgeAttributes(e, n), () => { o.styles.setSelectedEdgeAttributes(null); }), [e, n]), null; }, $e = Object.assign(ne, { Hovered: oe, Selected: se }), re = ({ name: e, edgeAttributes: n, edgeDependencies: o, edgeOutput: t, nodeAttributes: r, nodeDependencies: s, nodeOutput: a }, d) => { const c = y(), [i, b] = f( null ); return C(d, () => i, [ i ]), l(() => { const u = { edgeAttributes: n, edgeDependencies: o, edgeOutput: t, nodeAttributes: r, nodeDependencies: s, nodeOutput: a }; async function O() { const L = c.styles.createClass({ name: e, ...u }); await c.view.afterNextFrame(), b(L); } return O(), () => { async function L() { const S = c.styles.getClass(e); S && await S.destroy(), b(null); } L(); }; }, []), l(() => { i && i.update({ edgeAttributes: n, edgeDependencies: o, edgeOutput: t, nodeAttributes: r, nodeDependencies: s, nodeOutput: a }); }, [ n, o, t, r, s, a ]), null; }, ie = (e, n) => e.name === n.name && e.edgeAttributes === n.edgeAttributes && e.edgeDependencies === n.edgeDependencies && e.edgeOutput === n.edgeOutput && e.nodeAttributes === n.nodeAttributes && e.nodeDependencies === n.nodeDependencies && e.nodeOutput === n.nodeOutput, Ae = j(E(re), ie); function R(e, n, o) { n === e.isEnabled() && (n ? e.disable(o) : e.enable(o)); } function $(e, n, o) { const t = ({ target: i }) => { i === n && e.onEnabled && e.onEnabled(n); }, r = ({ target: i }) => { i === n && e.onDisabled && e.onDisabled(n); }, s = ({ target: i }) => { i === n && e.onUpdated && e.onUpdated(n); }, a = ({ target: i, index: b }) => { i === n && e.onSetIndex && e.onSetIndex(n, b); }, d = ({ target: i }) => { i === n && (e.onDestroyed && e.onDestroyed(n), o.events.off(t).off(r).off(s).off(a).off(d)); }; return o.events.on("transformationEnabled", t).on("transformationDisabled", r).on("transformationDestroyed", d).on("transformationSetIndex", a).on("transformationRefresh", s), () => { o.events.off(t).off(r).off(s).off(a).off(d); }; } function le(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addNodeGrouping({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled]), l(() => { t == null || t.setOptions(e); }, [ e.groupIdFunction, e.groupSelfLoopEdges, e.edgeGenerator, e.nodeGenerator, e.groupEdges, e.padding, e.selector, e.showContents, e.separateEdgesByDirection ]), null; } const Fe = E(le); function ae(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addEdgeGrouping({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled]), l(() => { t == null || t.setOptions(e); }, [ e.selector, e.generator, e.groupIdFunction, e.separateEdgesByDirection ]), null; } const De = E(ae); function de(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addNodeCollapsing({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled]), l(() => { t == null || t.setOptions(e); }, [e.edgeGenerator, e.selector]), null; } const ke = E(de); function ce(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addNeighborMerging({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled]), l(() => { t == null || t.setOptions(e); }, [e.dataFunction, e.selector]), null; } const Ie = E(ce); function ue(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addNeighborGeneration({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled]), l(() => { t == null || t.setOptions(e); }, [ e.edgeGenerator, e.nodeGenerator, e.neighborIdFunction, e.selector ]), null; } const _e = E(ue); function fe(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addEdgeFilter({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled, e.duration]), l(() => { t == null || t.setOptions(e); }, [e.criteria]), null; } const ze = E(fe); function ge(e, n) { const o = y(), [t, r] = f(); return C(n, () => t, [t]), l(() => { const s = o.transformations.addNodeFilter({ ...e, enabled: !e.disabled }); return $(e, s, o), r(s), () => { s.destroy(), r(void 0); }; }, []), l(() => { t && R(t, !!e.disabled, e.duration); }, [e.disabled, e.duration]), l(() => { t == null || t.setOptions(e); }, [e.criteria]), null; } const Ue = E(ge); function B(e, n, o, t) { return typeof o == "string" ? o : typeof o == "function" ? I(o(e, n)) : I(t); } function A(e, n) { return typeof e == "function" ? e(n) : e; } const F = (e, n) => `${e} ${e}--${n}`; function me(e = "&times;", n) { if (e) { const o = typeof e == "string" ? e : I(e); return `<div class=${n}>${o}</div>`; } return ""; } function ye(e, n, o, t) { const { width: r, height: s } = t.view.getSize(), { x: a, y: d } = t.view.graphToScreenCoordinates(e); let c = n; const { width: i, height: b } = o; return n === "left" && a - i < 0 ? c = "right" : n === "right" && a + i > r ? c = "left" : n === "bottom" && d + b > s ? c = "top" : n === "top" && d - b < 0 && (c = "bottom"), c === "right" || c === "left" ? d + b / 2 > s ? c = "top" : d - b / 2 < 0 && (c = "bottom") : a + i / 2 > r ? c = "left" : a - i / 2 < 0 && (c = "right"), c; } function he() { } const D = { x: -9999, y: -9999 }, be = "ogma-popup--content", ve = "ogma-popup--close", Ee = "ogma-popup--body", Ce = "ogma-popup", Se = ({ content: e, position: n, children: o, isOpen: t = !0, closeButton: r, onClose: s = he, placement: a = "top", popupClass: d = Ce, closeButtonClass: c = ve, contentClass: i = be, popupBodyClass: b = Ee, size: u, closeOnEsc: O = !0 }, L) => { const S = y(), [v, H] = f(null); if (C(L, () => v, [v]), l(() => { let g = null, w = null, N = null; if (t) { const h = A(n, S) || D; if (g = S.layers.addOverlay({ position: h || D, element: `<div class="${F(d, a)}"/> <div class="${b}"> ${me(r, c)} <div class="${i} "></div> </div> </div>`, size: u || { width: "auto", height: "auto" }, scaled: !1 }), N = (m) => { const T = g == null ? void 0 : g.element.querySelector( `.${c}` ); m.target && T.contains(m.target) && (m.stopPropagation(), m.preventDefault(), s()); }, w = ({ code: m }) => { m === 27 && s(); }, O && S.events.on("keyup", w), g.element.addEventListener("click", N), H(g), e && !o) { const m = g.element.querySelector( `.${i}` ), T = B(S, h, e, o); m && (m.innerHTML = T); } H(g); } return () => { g && (N && g.element.removeEventListener("click", N), w && S.events.off(w), g.destroy(), H(null)); }; }, [t, S]), l(() => { if (v && v.element) { const g = A(n, S) || D; if (v.setPosition(g), v.element.className = F(d, a), e && !o) { const w = v.element.querySelector(`.${i}`); w && (w.innerHTML = typeof e == "string" ? e : ""); } t ? v.show() : v.hide(); } }, [v, n, t, a, d, e, o]), !v || !t) return null; const G = v.element.querySelector(`.${i}`); return G && o ? _(o, G) : null; }, qe = E(Se), we = ({ tooltipClass: e = "ogma-tooltip", placement: n = "right", position: o, size: t = { width: "auto", height: "auto" }, children: r, content: s, visible: a = !0 }, d) => { const c = y(), [i, b] = f(), [u, O] = f(), [L, S] = f(""), [v, H] = f(), G = x(0); return C(d, () => i, [i]), l(() => { const w = `<div class="${F(e, n)}"><div class="${e}--content" /></div>`, N = { x: -9999, y: -9999 }; O(N); const h = c.layers.addOverlay({ position: N, element: w, scaled: !1, size: t }); return b(h), () => { h.destroy(); }; }, []), l(() => { const g = B(c, u, s, r); if (i) { g !== L && (i.element.firstElementChild.innerHTML = g, S(g), H({ width: i.element.offsetWidth, height: i.element.offsetHeight })); const w = A(o, c); u !== w && O(w), a ? i.show() : i.hide(); } return G.current = requestAnimationFrame(() => { i && i.element && u && v && (i.element.className = F( e, ye(u, n, v, c) ), i.setPosition(u)); }), () => cancelAnimationFrame(G.current); }, [r, s, o, a]), null; }, Me = E(we), Le = ({ noClear: e = !1, isStatic: n = !1, render: o, index: t, visible: r = !0 }, s) => { const a = y(), [d, c] = f(null); return C(s, () => d, [d]), l(() => { const i = a.layers.addCanvasLayer( o, { isStatic: n, noClear: e }, t ); return c(i), () => { i && (i.destroy(), c(null)); }; }, []), l(() => { d && (t !== void 0 && isFinite(t) && d.moveTo(t), r ? d.show() : d.hide()); }, [d, t, r]), null; }, je = E(Le), k = { x: -9999, y: -9999 }, xe = E( ({ position: e, children: n, className: o = "", size: t, scaled: r }, s) => { const a = y(), [d, c] = f(null); return C(s, () => d, [d]), l(() => { const i = A(e, a) || k, b = document.createElement("div"); b.className = o; const u = a.layers.addOverlay({ position: i || k, element: b, size: t || { width: "auto", height: "auto" }, scaled: r }); return c(u), () => { d && (d.destroy(), c(null)); }; }, []), l(() => { if (d) { const i = A(e, a) || k; o && (d.element.className = o), d.setPosition(i); } }, [e, o]), d ? _(n, d.element) : null; } ), We = E( ({ children: e, className: n = "", index: o }, t) => { const r = y(), [s, a] = f(null); return C(t, () => s, [s]), l(() => { const d = document.createElement("div"); d.className = n; const c = r.layers.addLayer(d, o); return a(c), () => { s && (s.destroy(), a(null)); }; }, []), l(() => { s && (s.element.className = n); }, [n]), s ? _(e, s.element) : null; } ); function Be({ enabled: e = !1, ...n }) { const o = y(); return l(() => { e ? o.geo.enable(n) : o.geo.disable(); }, [e]), null; } export { je as CanvasLayer, ze as EdgeFilter, De as EdgeGrouping, $e as EdgeStyle, $e as EdgeStyleRule, Be as Geo, We as Layer, _e as NeighborGeneration, Ie as NeighborMerging, ke as NodeCollapsing, de as NodeCollapsingComponent, Ue as NodeFilter, Fe as NodeGrouping, Re as NodeStyle, Re as NodeStyleRule, He as Ogma, xe as Overlay, qe as Popup, Ae as StyleClass, Me as Tooltip, q as forEachEventHandler, X as getEventNameFromProp, Ge as useEvent, y as useOgma }; //# sourceMappingURL=index.mjs.map