refactoring van de cmap structuren bijna compleet
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
|
||||
/** Render references from the active diagram to concepts linked from other CMaps. */
|
||||
export class CmapBoundaryReferenceView {
|
||||
constructor({ canvas, zoomFactor, mapTitle, surfaceElement, itemCenter, onOpenReference }) {
|
||||
this.canvas = canvas;
|
||||
this.zoomFactor = zoomFactor;
|
||||
this.mapTitle = mapTitle || "";
|
||||
this.surfaceElement = surfaceElement;
|
||||
this.itemCenter = itemCenter;
|
||||
this.onOpenReference = onOpenReference;
|
||||
this.layer = null;
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (this.layer) this.layer.remove();
|
||||
this.layer = null;
|
||||
}
|
||||
|
||||
render(references = []) {
|
||||
this.clear();
|
||||
if (!references.length) return;
|
||||
const surface = this.surfaceElement();
|
||||
if (!surface) return;
|
||||
|
||||
const layer = document.createElement("div");
|
||||
layer.className = "rw-cmap-boundary-layer";
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
svg.classList.add("rw-cmap-boundary-lines");
|
||||
const definitions = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
||||
const marker = document.createElementNS("http://www.w3.org/2000/svg", "marker");
|
||||
marker.setAttribute("id", "rw-cmap-boundary-arrow");
|
||||
marker.setAttribute("viewBox", "0 0 10 10");
|
||||
marker.setAttribute("refX", "9");
|
||||
marker.setAttribute("refY", "5");
|
||||
marker.setAttribute("markerWidth", "7");
|
||||
marker.setAttribute("markerHeight", "7");
|
||||
marker.setAttribute("orient", "auto-start-reverse");
|
||||
const arrow = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
arrow.setAttribute("d", "M 0 0 L 10 5 L 0 10 z");
|
||||
arrow.setAttribute("fill", "#808080");
|
||||
marker.append(arrow);
|
||||
definitions.append(marker);
|
||||
svg.append(definitions);
|
||||
layer.append(svg);
|
||||
surface.append(layer);
|
||||
this.layer = layer;
|
||||
|
||||
const factor = this.zoomFactor();
|
||||
const viewLeft = this.canvas.scrollLeft / factor;
|
||||
const viewTop = this.canvas.scrollTop / factor;
|
||||
const viewWidth = this.canvas.clientWidth / factor;
|
||||
const viewHeight = this.canvas.clientHeight / factor;
|
||||
const buttonWidth = 190;
|
||||
const occupied = { left: [], right: [] };
|
||||
const reserveY = (side, desired) => {
|
||||
let y = Math.max(viewTop + 12, Math.min(desired, viewTop + viewHeight - 40));
|
||||
while (occupied[side].some((used) => Math.abs(used - y) < 34)) y += 34;
|
||||
if (y > viewTop + viewHeight - 40) y = viewTop + 12;
|
||||
occupied[side].push(y);
|
||||
return y;
|
||||
};
|
||||
|
||||
for (const reference of references) {
|
||||
const inside = this.itemCenter(reference.insideRecord);
|
||||
const side = inside.x < viewLeft + (viewWidth / 2) ? "left" : "right";
|
||||
const x = side === "left" ? viewLeft + 12 : viewLeft + viewWidth - buttonWidth - 12;
|
||||
const y = reserveY(side, inside.y - 15);
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = `rw-cmap-boundary-reference rw-cmap-boundary-reference-${side}`;
|
||||
button.style.transform = `translate(${x}px, ${y}px)`;
|
||||
button.style.width = `${buttonWidth}px`;
|
||||
if (reference.linkingPhraseLabel) {
|
||||
button.append(document.createTextNode(reference.linkingPhraseLabel));
|
||||
button.append(document.createTextNode(" →"));
|
||||
button.append(document.createElement("br"));
|
||||
}
|
||||
button.append(document.createTextNode(reference.label));
|
||||
if (this.mapTitle) {
|
||||
button.append(document.createElement("br"));
|
||||
const mapLabel = document.createElement("small");
|
||||
const mapName = document.createElement("em");
|
||||
mapName.textContent = `(${this.mapTitle})`;
|
||||
mapLabel.append(mapName);
|
||||
button.append(mapLabel);
|
||||
}
|
||||
button.title = "Open the concept map containing this connection";
|
||||
button.addEventListener("click", () => {
|
||||
if (this.onOpenReference) this.onOpenReference(reference);
|
||||
});
|
||||
layer.append(button);
|
||||
|
||||
const boundaryX = side === "left" ? x + buttonWidth : x;
|
||||
const boundaryY = y + 15;
|
||||
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
const startX = reference.sourceInside ? inside.x : boundaryX;
|
||||
const startY = reference.sourceInside ? inside.y : boundaryY;
|
||||
const endX = reference.sourceInside ? boundaryX : inside.x;
|
||||
const endY = reference.sourceInside ? boundaryY : inside.y;
|
||||
path.setAttribute("d", `M ${startX} ${startY} L ${endX} ${endY}`);
|
||||
path.setAttribute("fill", "none");
|
||||
path.setAttribute("stroke", "#808080");
|
||||
path.setAttribute("stroke-width", String(reference.connector.lineWidth || 2));
|
||||
if (reference.connector.hasArrow) path.setAttribute("marker-end", "url(#rw-cmap-boundary-arrow)");
|
||||
svg.append(path);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user