new-graph-visualization / assets /info_bridge.js
anurag-raapid's picture
Upload app, Docker, staging parquet only (no venv)
4b988e0 verified
Raw
History Blame Contribute Delete
1.81 kB
/**
* Reliable node/edge inspector: wire Cytoscape mouseover + tap to inspector-focus-store.
* Complements dash-cytoscape props (clearOnUnhover=false) for fewer missed hovers.
*/
(function () {
function isLiveCy(cy) {
return cy && typeof cy.destroyed === "function" && !cy.destroyed();
}
function cyOf(el) {
if (!el) return null;
if (isLiveCy(el._cytoscape)) return el._cytoscape;
// cytoscape.js registers the live instance on its container as _cyreg.cy
if (el._cyreg && isLiveCy(el._cyreg.cy)) return el._cyreg.cy;
return null;
}
function findCy(host) {
if (!host) return null;
let cy = cyOf(host);
if (cy) return cy;
for (const el of host.querySelectorAll("div")) {
cy = cyOf(el);
if (cy) return cy;
}
return null;
}
function setInspector(data) {
if (
window.dash_clientside &&
typeof window.dash_clientside.set_props === "function"
) {
window.dash_clientside.set_props("inspector-focus-store", { data: data });
}
}
function wireGraph(host) {
const cy = findCy(host);
if (!cy) return false;
if (host.__infoBridgeCy === cy) return true;
host.__infoBridgeCy = cy;
cy.on("mouseover", "node, edge", (evt) => {
if (evt.target === cy) return;
setInspector(evt.target.data());
});
cy.on("tap", "node, edge", (evt) => {
if (evt.target === cy) return;
setInspector(evt.target.data());
});
return true;
}
function boot() {
const host = document.getElementById("graph");
if (!host) return;
if (!wireGraph(host)) {
host.__infoBridgeCy = null;
}
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot);
} else {
boot();
}
setInterval(boot, 800);
})();