@argdown/map-views
Version:
Browser-based map views for Argdown data using dagre-d3 and viz.js
124 lines • 4.65 kB
JavaScript
import Viz from "@aduh95/viz.js";
import { select } from "d3-selection";
import "d3-transition";
import { ZoomManager } from "./ZoomManager";
import { mergeDefaults, isObject } from "@argdown/core";
export var GraphvizEngine;
(function (GraphvizEngine) {
GraphvizEngine["CIRCO"] = "circo";
GraphvizEngine["DOT"] = "dot";
GraphvizEngine["FDP"] = "fdp";
GraphvizEngine["NEATO"] = "neato";
GraphvizEngine["OSAGE"] = "osage";
GraphvizEngine["TWOPI"] = "twopi";
})(GraphvizEngine || (GraphvizEngine = {}));
export const vizJsDefaultSettings = {};
export class VizJsMap {
constructor(svgContainer, renderSync, config, onZoomChanged, onSelectionChanged) {
if (!renderSync && config) {
this.vizJsConfig = config;
this.viz = new Viz(this.vizJsConfig);
}
else if (renderSync) {
this.renderSync = renderSync;
}
this.svgContainer = svgContainer;
this.zoomManager = new ZoomManager(onZoomChanged, true);
this.onSelectionChanged = onSelectionChanged;
}
async renderAsync(dot, options) {
if (this.viz === undefined && this.vizJsConfig) {
this.viz = new Viz(this.vizJsConfig);
}
return this.viz.renderString(dot, options);
}
async render(props) {
const settings = isObject(props.settings) ? props.settings : {};
mergeDefaults(settings, vizJsDefaultSettings);
let svgString = "";
if (this.renderSync) {
svgString = this.renderSync(props.dot, settings);
}
else {
svgString = await this.renderAsync(props.dot, settings);
}
if (settings.removeProlog) {
svgString = svgString.replace(/<\?[ ]*xml[\S ]+?\?>[\s]*<\![ ]*DOCTYPE[\S\s]+?\.dtd\"[ ]*>/, "");
}
if (settings.images) {
for (let image of settings.images) {
if (image.dataUrl) {
const stringToReplace = new RegExp(image.path, "g");
svgString = svgString.replace(stringToReplace, image.dataUrl);
}
}
}
this.svgContainer.innerHTML = svgString;
const svg = select(this.svgContainer).select("svg");
svg.attr("class", "map-svg");
svg.attr("width", "100%");
svg.attr("height", "100%");
svg.attr("viewBox", null);
const svgGraph = svg.select("g");
const groupNode = svgGraph.node();
const bBox = groupNode.getBBox();
const width = bBox.width;
const height = bBox.height;
this.zoomManager.init(svg, svgGraph, width, height);
if (!props.scale || !props.position) {
this.zoomManager.showAllAndCenterMap();
}
else {
this.zoomManager.setZoom(props.position.x || 0, props.position.y || 0, props.scale, 0);
}
svgGraph.attr("height", this.zoomManager.state.size.height * this.zoomManager.state.scale + 40);
if (props.selectedNode) {
this.selectNode(props.selectedNode);
}
}
getNodeWithArgdownId(id) {
const nodes = this.zoomManager
.svgGraph.selectAll("g.node")
.nodes();
const self = this;
return nodes.find(n => self.getArgdownId(n) === id);
}
getArgdownId(node) {
const title = select(node)
.select("title")
.node();
if (title) {
return title.textContent || "";
}
return "";
}
deselectNode() {
this._deselectNode();
if (this.onSelectionChanged) {
this.onSelectionChanged(null);
}
}
_deselectNode() {
if (this.selectedElement) {
this.selectedElement.classList.remove("selected");
const path = this.selectedElement.getElementsByTagName("path")[0];
path.setAttribute("stroke-width", this.selectedElementStrokeWidth || "");
}
this.selectedElement = null;
}
selectNode(id) {
this._deselectNode();
this.selectedElement = this.getNodeWithArgdownId(id);
if (this.selectedElement) {
const path = this.selectedElement.getElementsByTagName("path")[0];
this.selectedElement.classList.add("selected");
this.selectedElementStrokeWidth = path.getAttribute("stroke-width") || "";
path.setAttribute("stroke-width", "8");
this.zoomManager.moveToElement(this.selectedElement);
if (this.onSelectionChanged) {
this.onSelectionChanged(id);
}
}
}
}
//# sourceMappingURL=VizJsMap.js.map