UNPKG

@argdown/map-views

Version:

Browser-based map views for Argdown data using dagre-d3 and viz.js

124 lines 4.65 kB
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