105 lines
3.1 KiB
JavaScript
105 lines
3.1 KiB
JavaScript
let container, containerRect;
|
|
let svg;
|
|
let hasLoaded = false;
|
|
console.log(document.readyState);
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
container = document.getElementById("svg-container");
|
|
containerRect = container.getBoundingClientRect();
|
|
svg = document.getElementById("svg");
|
|
svg.addEventListener("load", onLoad);
|
|
// Sometimes the load event just doesn't fire in Safari (race between loading the script and svg?)
|
|
// So, as a fallback:
|
|
setTimeout(() => {
|
|
if (!hasLoaded) {
|
|
try {
|
|
onLoad();
|
|
} catch (e) {
|
|
console.error("Still failed to load after delay", e);
|
|
}
|
|
}
|
|
}, 100);
|
|
});
|
|
|
|
let origWidth, origHeight;
|
|
function onLoad() {
|
|
hasLoaded = true;
|
|
const svgDoc = svg.getSVGDocument();
|
|
const el = svgDoc.getElementById("node1");
|
|
origWidth = svgDoc.rootElement.width.baseVal.valueInSpecifiedUnits;
|
|
origHeight = svgDoc.rootElement.height.baseVal.valueInSpecifiedUnits;
|
|
scale = Math.pow(0.8, 3);
|
|
updateSVG(1);
|
|
const rect = el.getBoundingClientRect();
|
|
container.scrollTo(
|
|
rect.x - (containerRect.width - rect.width) / 2,
|
|
rect.y - (containerRect.height - rect.height) / 2,
|
|
);
|
|
|
|
svgDoc.addEventListener("click", selectNode);
|
|
}
|
|
|
|
function selectNode(e) {
|
|
const node = findNodeParent(e.target);
|
|
if (node) {
|
|
const id = [...node.classList].find((x) => x !== "node");
|
|
const style = svg.contentDocument.getElementById("node-style");
|
|
style.innerHTML = `
|
|
.${id} text,
|
|
.${id} polygon {
|
|
fill: red;
|
|
}
|
|
.${id} ellipse,
|
|
.${id} path,
|
|
.${id} polygon {
|
|
stroke: red;
|
|
}`;
|
|
|
|
const title = node.querySelector("a").getAttribute("xlink:title");
|
|
const label = document.getElementById("svg-label");
|
|
label.innerText = title;
|
|
label.innerHTML += "<br>";
|
|
}
|
|
}
|
|
|
|
function findNodeParent(e) {
|
|
if (e.classList && e.classList.contains("node")) {
|
|
return e;
|
|
} else if (e.parentElement) {
|
|
return findNodeParent(e.parentElement);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
let scale = 1;
|
|
function updateSVG(oldScale) {
|
|
const oldRect = svg.getBoundingClientRect();
|
|
const unscaledTop = -oldRect.top / oldScale;
|
|
const unscaledLeft = -oldRect.left / oldScale;
|
|
|
|
const graph = svg.contentDocument.getElementById("graph0");
|
|
graph.transform.baseVal[0].setScale(scale, scale);
|
|
const root = svg.contentDocument.rootElement;
|
|
const scaledWidth = origWidth * scale;
|
|
const scaledHeight = origHeight * scale;
|
|
root.setAttribute("width", `${scaledWidth}pt`);
|
|
root.setAttribute("height", `${scaledHeight}pt`);
|
|
root.setAttribute("viewBox", `0 0 ${scaledWidth} ${scaledHeight}`);
|
|
|
|
container.scrollTo(unscaledLeft * scale, unscaledTop * scale);
|
|
}
|
|
|
|
document.getElementById("zoom-in").addEventListener("click", (e) => {
|
|
e.preventDefault();
|
|
const oldScale = scale;
|
|
scale *= 1.25;
|
|
updateSVG(oldScale);
|
|
});
|
|
|
|
document.getElementById("zoom-out").addEventListener("click", (e) => {
|
|
e.preventDefault();
|
|
const oldScale = scale;
|
|
scale *= 0.8;
|
|
updateSVG(oldScale);
|
|
});
|