UNPKG

markmap-view

Version:
763 lines (762 loc) 26.6 kB
import { Hook as et, getId as nt, debounce as rt, addClass as it, walkTree as X, childSelector as b, noop as R } from "markmap-common"; import { loadCSS as ce, loadJS as he } from "markmap-common"; import { scaleOrdinal as N, schemeCategory10 as st, linkHorizontal as ot, zoomTransform as j, select as at, zoom as lt, min as T, max as _, zoomIdentity as ct, minIndex as ht } from "d3"; const P = typeof navigator < "u" && navigator.userAgent.includes("Macintosh"), dt = N(st), W = { autoFit: !1, color: (e) => { var t; return dt(`${((t = e.state) == null ? void 0 : t.path) || ""}`); }, duration: 500, embedGlobalCSS: !0, fitRatio: 0.95, maxInitialScale: 2, maxWidth: 0, nodeMinHeight: 16, paddingX: 8, scrollForPan: P, spacingHorizontal: 80, spacingVertical: 5, initialExpandLevel: -1, zoom: !0, pan: !0, toggleRecursively: !1 }; function se(e) { const t = {}, n = { ...e }, { color: r, colorFreezeLevel: s } = n; if ((r == null ? void 0 : r.length) === 1) { const i = r[0]; t.color = () => i; } else if (r != null && r.length) { const i = N(r); t.color = (a) => i(`${a.state.path}`); } if (s) { const i = t.color || W.color; t.color = (a) => (a = { ...a, state: { ...a.state, path: a.state.path.split(".").slice(0, s).join(".") } }, i(a)); } return [ "duration", "fitRatio", "initialExpandLevel", "maxInitialScale", "maxWidth", "nodeMinHeight", "paddingX", "spacingHorizontal", "spacingVertical" ].forEach((i) => { const a = n[i]; typeof a == "number" && (t[i] = a); }), ["zoom", "pan"].forEach((i) => { const a = n[i]; a != null && (t[i] = !!a); }), t; } function pt(e) { let t = 0; for (let n = 0; n < e.length; n++) t = (t << 5) - t + e.charCodeAt(n) | 0; return (t >>> 0).toString(36); } function ut(e) { var t = 0, n = e.children, r = n && n.length; if (!r) t = 1; else for (; --r >= 0; ) t += n[r].value; e.value = t; } function mt() { return this.eachAfter(ut); } function gt(e) { var t = this, n, r = [t], s, l, c; do for (n = r.reverse(), r = []; t = n.pop(); ) if (e(t), s = t.children, s) for (l = 0, c = s.length; l < c; ++l) r.push(s[l]); while (r.length); return this; } function ft(e) { for (var t = this, n = [t], r, s; t = n.pop(); ) if (e(t), r = t.children, r) for (s = r.length - 1; s >= 0; --s) n.push(r[s]); return this; } function xt(e) { for (var t = this, n = [t], r = [], s, l, c; t = n.pop(); ) if (r.push(t), s = t.children, s) for (l = 0, c = s.length; l < c; ++l) n.push(s[l]); for (; t = r.pop(); ) e(t); return this; } function yt(e) { return this.eachAfter(function(t) { for (var n = +e(t.data) || 0, r = t.children, s = r && r.length; --s >= 0; ) n += r[s].value; t.value = n; }); } function kt(e) { return this.eachBefore(function(t) { t.children && t.children.sort(e); }); } function vt(e) { for (var t = this, n = bt(t, e), r = [t]; t !== n; ) t = t.parent, r.push(t); for (var s = r.length; e !== n; ) r.splice(s, 0, e), e = e.parent; return r; } function bt(e, t) { if (e === t) return e; var n = e.ancestors(), r = t.ancestors(), s = null; for (e = n.pop(), t = r.pop(); e === t; ) s = e, e = n.pop(), t = r.pop(); return s; } function zt() { for (var e = this, t = [e]; e = e.parent; ) t.push(e); return t; } function St() { var e = []; return this.each(function(t) { e.push(t); }), e; } function Et() { var e = []; return this.eachBefore(function(t) { t.children || e.push(t); }), e; } function Ct() { var e = this, t = []; return e.each(function(n) { n !== e && t.push({ source: n.parent, target: n }); }), t; } function O(e, t) { var n = new E(e), r = +e.value && (n.value = e.value), s, l = [n], c, i, a, d; for (t == null && (t = Xt); s = l.pop(); ) if (r && (s.value = +s.data.value), (i = t(s.data)) && (d = i.length)) for (s.children = new Array(d), a = d - 1; a >= 0; --a) l.push(c = s.children[a] = new E(i[a])), c.parent = s, c.depth = s.depth + 1; return n.eachBefore(jt); } function wt() { return O(this).eachBefore(Rt); } function Xt(e) { return e.children; } function Rt(e) { e.data = e.data.data; } function jt(e) { var t = 0; do e.height = t; while ((e = e.parent) && e.height < ++t); } function E(e) { this.data = e, this.depth = this.height = 0, this.parent = null; } E.prototype = O.prototype = { constructor: E, count: mt, each: gt, eachAfter: xt, eachBefore: ft, sum: yt, sort: kt, path: vt, ancestors: zt, descendants: St, leaves: Et, links: Ct, copy: wt }; const Mt = "d3-flextree", Bt = "2.1.2", Ot = "build/d3-flextree.js", $t = "index", At = { name: "Chris Maloney", url: "http://chrismaloney.org" }, Ft = "Flexible tree layout algorithm that allows for variable node sizes.", Dt = ["d3", "d3-module", "layout", "tree", "hierarchy", "d3-hierarchy", "plugin", "d3-plugin", "infovis", "visualization", "2d"], Tt = "https://github.com/klortho/d3-flextree", _t = "WTFPL", Ht = { type: "git", url: "https://github.com/klortho/d3-flextree.git" }, Lt = { clean: "rm -rf build demo test", "build:demo": "rollup -c --environment BUILD:demo", "build:dev": "rollup -c --environment BUILD:dev", "build:prod": "rollup -c --environment BUILD:prod", "build:test": "rollup -c --environment BUILD:test", build: "rollup -c", lint: "eslint index.js src", "test:main": "node test/bundle.js", "test:browser": "node test/browser-tests.js", test: "npm-run-all test:*", prepare: "npm-run-all clean build lint test" }, Nt = { "d3-hierarchy": "^1.1.5" }, Pt = { "babel-plugin-external-helpers": "^6.22.0", "babel-preset-es2015-rollup": "^3.0.0", d3: "^4.13.0", "d3-selection-multi": "^1.0.1", eslint: "^4.19.1", jsdom: "^11.6.2", "npm-run-all": "^4.1.2", rollup: "^0.55.3", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-copy": "^0.2.3", "rollup-plugin-json": "^2.3.0", "rollup-plugin-node-resolve": "^3.0.2", "rollup-plugin-uglify": "^3.0.0", "uglify-es": "^3.3.9" }, Wt = { name: Mt, version: Bt, main: Ot, module: $t, "jsnext:main": "index", author: At, description: Ft, keywords: Dt, homepage: Tt, license: _t, repository: Ht, scripts: Lt, dependencies: Nt, devDependencies: Pt }, { version: It } = Wt, Kt = Object.freeze({ children: (e) => e.children, nodeSize: (e) => e.data.size, spacing: 0 }); function K(e) { const t = Object.assign({}, Kt, e); function n(i) { const a = t[i]; return typeof a == "function" ? a : () => a; } function r(i) { const a = c(l(), i, (d) => d.children); return a.update(), a.data; } function s() { const i = n("nodeSize"), a = n("spacing"); return class I extends O.prototype.constructor { constructor(h) { super(h); } copy() { const h = c(this.constructor, this, (p) => p.children); return h.each((p) => p.data = p.data.data), h; } get size() { return i(this); } spacing(h) { return a(this, h); } get nodes() { return this.descendants(); } get xSize() { return this.size[0]; } get ySize() { return this.size[1]; } get top() { return this.y; } get bottom() { return this.y + this.ySize; } get left() { return this.x - this.xSize / 2; } get right() { return this.x + this.xSize / 2; } get root() { const h = this.ancestors(); return h[h.length - 1]; } get numChildren() { return this.hasChildren ? this.children.length : 0; } get hasChildren() { return !this.noChildren; } get noChildren() { return this.children === null; } get firstChild() { return this.hasChildren ? this.children[0] : null; } get lastChild() { return this.hasChildren ? this.children[this.numChildren - 1] : null; } get extents() { return (this.children || []).reduce( (h, p) => I.maxExtents(h, p.extents), this.nodeExtents ); } get nodeExtents() { return { top: this.top, bottom: this.bottom, left: this.left, right: this.right }; } static maxExtents(h, p) { return { top: Math.min(h.top, p.top), bottom: Math.max(h.bottom, p.bottom), left: Math.min(h.left, p.left), right: Math.max(h.right, p.right) }; } }; } function l() { const i = s(), a = n("nodeSize"), d = n("spacing"); return class extends i { constructor(h) { super(h), Object.assign(this, { x: 0, y: 0, relX: 0, prelim: 0, shift: 0, change: 0, lExt: this, lExtRelX: 0, lThr: null, rExt: this, rExtRelX: 0, rThr: null }); } get size() { return a(this.data); } spacing(h) { return d(this.data, h.data); } get x() { return this.data.x; } set x(h) { this.data.x = h; } get y() { return this.data.y; } set y(h) { this.data.y = h; } update() { return G(this), U(this), this; } }; } function c(i, a, d) { const h = (p, u) => { const g = new i(p); Object.assign(g, { parent: u, depth: u === null ? 0 : u.depth + 1, height: 0, length: 1 }); const f = d(p) || []; return g.children = f.length === 0 ? null : f.map((x) => h(x, g)), g.children && Object.assign(g, g.children.reduce( (x, v) => ({ height: Math.max(x.height, v.height + 1), length: x.length + v.length }), g )), g; }; return h(a, null); } return Object.assign(r, { nodeSize(i) { return arguments.length ? (t.nodeSize = i, r) : t.nodeSize; }, spacing(i) { return arguments.length ? (t.spacing = i, r) : t.spacing; }, children(i) { return arguments.length ? (t.children = i, r) : t.children; }, hierarchy(i, a) { const d = typeof a > "u" ? t.children : a; return c(s(), i, d); }, dump(i) { const a = n("nodeSize"), d = (h) => (p) => { const u = h + " ", g = h + " ", { x: f, y: x } = p, v = a(p), k = p.children || [], z = k.length === 0 ? " " : `,${u}children: [${g}${k.map(d(g)).join(g)}${u}],${h}`; return `{ size: [${v.join(", ")}],${u}x: ${f}, y: ${x}${z}},`; }; return d(` `)(i); } }), r; } K.version = It; const G = (e, t = 0) => (e.y = t, (e.children || []).reduce((n, r) => { const [s, l] = n; G(r, e.y + e.ySize); const c = (s === 0 ? r.lExt : r.rExt).bottom; s !== 0 && Ut(e, s, l); const i = ee(c, s, l); return [s + 1, i]; }, [0, null]), Gt(e), te(e), e), U = (e, t, n) => { typeof t > "u" && (t = -e.relX - e.prelim, n = 0); const r = t + e.relX; return e.relX = r + e.prelim - n, e.prelim = 0, e.x = n + e.relX, (e.children || []).forEach((s) => U(s, r, e.x)), e; }, Gt = (e) => { (e.children || []).reduce((t, n) => { const [r, s] = t, l = r + n.shift, c = s + l + n.change; return n.relX += c, [l, c]; }, [0, 0]); }, Ut = (e, t, n) => { const r = e.children[t - 1], s = e.children[t]; let l = r, c = r.relX, i = s, a = s.relX, d = !0; for (; l && i; ) { l.bottom > n.lowY && (n = n.next); const h = c + l.prelim - (a + i.prelim) + l.xSize / 2 + i.xSize / 2 + l.spacing(i); (h > 0 || h < 0 && d) && (a += h, Vt(s, h), Yt(e, t, n.index, h)), d = !1; const p = l.bottom, u = i.bottom; p <= u && (l = qt(l), l && (c += l.relX)), p >= u && (i = Zt(i), i && (a += i.relX)); } !l && i ? Jt(e, t, i, a) : l && !i && Qt(e, t, l, c); }, Vt = (e, t) => { e.relX += t, e.lExtRelX += t, e.rExtRelX += t; }, Yt = (e, t, n, r) => { const s = e.children[t], l = t - n; if (l > 1) { const c = r / l; e.children[n + 1].shift += c, s.shift -= c, s.change -= r - c; } }, Zt = (e) => e.hasChildren ? e.firstChild : e.lThr, qt = (e) => e.hasChildren ? e.lastChild : e.rThr, Jt = (e, t, n, r) => { const s = e.firstChild, l = s.lExt, c = e.children[t]; l.lThr = n; const i = r - n.relX - s.lExtRelX; l.relX += i, l.prelim -= i, s.lExt = c.lExt, s.lExtRelX = c.lExtRelX; }, Qt = (e, t, n, r) => { const s = e.children[t], l = s.rExt, c = e.children[t - 1]; l.rThr = n; const i = r - n.relX - s.rExtRelX; l.relX += i, l.prelim -= i, s.rExt = c.rExt, s.rExtRelX = c.rExtRelX; }, te = (e) => { if (e.hasChildren) { const t = e.firstChild, n = e.lastChild, r = (t.prelim + t.relX - t.xSize / 2 + n.relX + n.prelim + n.xSize / 2) / 2; Object.assign(e, { prelim: r, lExt: t.lExt, lExtRelX: t.lExtRelX, rExt: n.rExt, rExtRelX: n.rExtRelX }); } }, ee = (e, t, n) => { for (; n !== null && e >= n.lowY; ) n = n.next; return { lowY: e, index: t, next: n }; }, V = ".markmap{--markmap-max-width: 9999px;--markmap-a-color: #0097e6;--markmap-a-hover-color: #00a8ff;--markmap-code-bg: #f0f0f0;--markmap-code-color: #555;--markmap-highlight-bg: #ffeaa7;--markmap-table-border: 1px solid currentColor;--markmap-font: 300 16px/20px sans-serif;--markmap-circle-open-bg: #fff;--markmap-text-color: #333;font:var(--markmap-font);color:var(--markmap-text-color)}.markmap-link{fill:none}.markmap-node>circle{cursor:pointer}.markmap-foreign{display:inline-block}.markmap-foreign p{margin:0}.markmap-foreign a{color:var(--markmap-a-color)}.markmap-foreign a:hover{color:var(--markmap-a-hover-color)}.markmap-foreign code{padding:.25em;font-size:calc(1em - 2px);color:var(--markmap-code-color);background-color:var(--markmap-code-bg);border-radius:2px}.markmap-foreign pre{margin:0}.markmap-foreign pre>code{display:block}.markmap-foreign del{text-decoration:line-through}.markmap-foreign em{font-style:italic}.markmap-foreign strong{font-weight:700}.markmap-foreign mark{background:var(--markmap-highlight-bg)}.markmap-foreign table,.markmap-foreign th,.markmap-foreign td{border-collapse:collapse;border:var(--markmap-table-border)}.markmap-foreign img{display:inline-block}.markmap-foreign svg{fill:currentColor}.markmap-foreign>div{width:var(--markmap-max-width);text-align:left}.markmap-foreign>div>div{display:inline-block}.markmap-dark .markmap{--markmap-code-bg: #1a1b26;--markmap-code-color: #ddd;--markmap-circle-open-bg: #444;--markmap-text-color: #eee}", oe = V, M = ot(); function H(e) { return Math.max(4 - 2 * e.state.depth, 1.5); } function L(e, t) { const n = ht(e, t); return e[n]; } function B(e) { e.stopPropagation(); } const ne = new et(); class Y { constructor(t, n) { this.options = W, this.revokers = [], this.handleZoom = (r) => { const { transform: s } = r; this.g.attr("transform", s); }, this.handlePan = (r) => { r.preventDefault(); const s = j(this.svg.node()), l = s.translate( -r.deltaX / s.k, -r.deltaY / s.k ); this.svg.call(this.zoom.transform, l); }, this.handleClick = (r, s) => { let l = this.options.toggleRecursively; (P ? r.metaKey : r.ctrlKey) && (l = !l), this.toggleNode(s, l); }, this.svg = t.datum ? t : at(t), this.styleNode = this.svg.append("style"), this.zoom = lt().filter((r) => this.options.scrollForPan && r.type === "wheel" ? r.ctrlKey && !r.button : (!r.ctrlKey || r.type === "wheel") && !r.button).on("zoom", this.handleZoom), this.setOptions(n), this.state = { id: this.options.id || this.svg.attr("id") || nt(), rect: { x1: 0, y1: 0, x2: 0, y2: 0 } }, this.g = this.svg.append("g"), this.observer = new ResizeObserver( rt(() => { this.renderData(); }, 100) ), this.revokers.push( ne.tap(() => { this.setData(); }) ); } getStyleContent() { const { style: t } = this.options, { id: n } = this.state, r = typeof t == "function" ? t(n) : ""; return [this.options.embedGlobalCSS && V, r].filter(Boolean).join(` `); } updateStyle() { this.svg.attr( "class", it(this.svg.attr("class"), "markmap", this.state.id) ); const t = this.getStyleContent(); this.styleNode.text(t); } async toggleNode(t, n = !1) { var s, l; const r = (s = t.payload) != null && s.fold ? 0 : 1; n ? X(t, (c, i) => { c.payload = { ...c.payload, fold: r }, i(); }) : t.payload = { ...t.payload, fold: (l = t.payload) != null && l.fold ? 0 : 1 }, await this.renderData(t); } _initializeData(t) { let n = 0; const { color: r, initialExpandLevel: s } = this.options; let l = 0, c = 0; X(t, (i, a, d) => { var p, u, g, f; c += 1, i.children = (p = i.children) == null ? void 0 : p.map((x) => ({ ...x })), n += 1, i.state = { ...i.state, depth: c, id: n, rect: { x: 0, y: 0, width: 0, height: 0 }, size: [0, 0] }, i.state.key = [(u = d == null ? void 0 : d.state) == null ? void 0 : u.id, i.state.id].filter(Boolean).join(".") + pt(i.content), i.state.path = [(g = d == null ? void 0 : d.state) == null ? void 0 : g.path, i.state.id].filter(Boolean).join("."), r(i); const h = ((f = i.payload) == null ? void 0 : f.fold) === 2; h ? l += 1 : (l || s >= 0 && i.state.depth >= s) && (i.payload = { ...i.payload, fold: 1 }), a(), h && (l -= 1), c -= 1; }); } _relayout() { if (!this.state.data) return; this.g.selectAll(b("g")).selectAll( b("foreignObject") ).each(function(i) { var h; const a = (h = this.firstChild) == null ? void 0 : h.firstChild, d = [a.scrollWidth, a.scrollHeight]; i.state.size = d; }); const { spacingHorizontal: t, paddingX: n, spacingVertical: r } = this.options, s = K({}).children((i) => { var a; if (!((a = i.payload) != null && a.fold)) return i.children; }).nodeSize((i) => { const [a, d] = i.data.state.size; return [d, a + (a ? n * 2 : 0) + t]; }).spacing((i, a) => i.parent === a.parent ? r : r * 2), l = s.hierarchy(this.state.data); s(l); const c = l.descendants(); c.forEach((i) => { const a = i.data; a.state.rect = { x: i.y, y: i.x, width: i.ySize - t, height: i.xSize }; }), this.state.rect = { x1: T(c, (i) => i.data.state.rect.x) || 0, y1: T(c, (i) => i.data.state.rect.y) || 0, x2: _( c, (i) => i.data.state.rect.x + i.data.state.rect.width ) || 0, y2: _( c, (i) => i.data.state.rect.y + i.data.state.rect.height ) || 0 }; } setOptions(t) { this.options = { ...this.options, ...t }, this.options.zoom ? this.svg.call(this.zoom) : this.svg.on(".zoom", null), this.options.pan ? this.svg.on("wheel", this.handlePan) : this.svg.on("wheel", null); } async setData(t, n) { n && this.setOptions(n), t && (this.state.data = t), this.state.data && (this._initializeData(this.state.data), this.updateStyle(), await this.renderData()); } async renderData(t) { const { paddingX: n, autoFit: r, color: s, maxWidth: l } = this.options; if (!this.state.data) return; const c = []; X(this.state.data, (o, m) => { var y; (y = o.payload) != null && y.fold || m(), c.push(o); }); const a = (t || this.state.data).state.rect, d = this.g.selectAll(b("g")).data(c, (o) => o.state.key), h = d.enter().append("g").attr("data-depth", (o) => o.state.depth).attr("data-path", (o) => o.state.path), p = d.exit(), u = d.merge(h).attr( "class", (o) => { var m; return ["markmap-node", ((m = o.payload) == null ? void 0 : m.fold) && "markmap-fold"].filter(Boolean).join(" "); } ), g = u.selectAll(b("line")).data( (o) => [o], (o) => o.state.key ), f = g.enter().append("line"), x = p.selectAll( b("line") ), v = g.merge(f), k = u.selectAll( b("circle") ).data( (o) => { var m; return (m = o.children) != null && m.length ? [o] : []; }, (o) => o.state.key ).join( (o) => o.append("circle").attr("stroke-width", "1.5").attr("r", 0).on("click", (m, y) => this.handleClick(m, y)).on("mousedown", B), (o) => o, (o) => o.remove() ), z = this.observer, $ = u.selectAll(b("foreignObject")).data( (o) => [o], (o) => o.state.key ), C = $.enter().append("foreignObject").attr("class", "markmap-foreign").attr("x", n).attr("y", 0).style("opacity", 0).on("mousedown", B).on("dblclick", B); C.append("xhtml:div").append("xhtml:div").html((o) => o.content).attr("xmlns", "http://www.w3.org/1999/xhtml"), C.each(function() { var m; const o = (m = this.firstChild) == null ? void 0 : m.firstChild; z.observe(o); }); const A = p.selectAll( b("foreignObject") ); A.each(function() { var m; const o = (m = this.firstChild) == null ? void 0 : m.firstChild; z.unobserve(o); }); const F = C.merge($), Z = c.flatMap( (o) => { var m; return (m = o.payload) != null && m.fold ? [] : o.children.map((y) => ({ source: o, target: y })); } ), w = this.g.selectAll(b("path")).data(Z, (o) => o.target.state.key), q = w.exit(), D = w.enter().insert("path", "g").attr("class", "markmap-link").attr("data-depth", (o) => o.target.state.depth).attr("data-path", (o) => o.target.state.path), J = D.merge(w); this.svg.style( "--markmap-max-width", l ? `${l}px` : null ), await new Promise(requestAnimationFrame), this._relayout(), this.transition(p).attr("transform", (o) => { const m = a.x + a.width - o.state.rect.width, y = a.y + a.height / 2 - o.state.rect.height; return `translate(${m},${y})`; }).remove(), h.attr( "transform", (o) => `translate(${a.x + a.width - o.state.rect.width},${a.y + a.height / 2 - o.state.rect.height})` ), this.transition(u).attr( "transform", (o) => `translate(${o.state.rect.x},${o.state.rect.y - o.state.rect.height / 2})` ), this.transition(x).attr("x1", (o) => o.state.rect.width).attr("x2", (o) => o.state.rect.width), f.attr("x1", (o) => o.state.rect.width).attr("x2", (o) => o.state.rect.width), v.attr("y1", (o) => o.state.rect.height).attr("y2", (o) => o.state.rect.height).attr("stroke", (o) => s(o)), this.transition(v).attr("x1", -1).attr("x2", (o) => o.state.rect.width + 2).attr("stroke-width", H), k.attr("cx", (o) => o.state.rect.width).attr("cy", (o) => o.state.rect.height).attr("stroke", (o) => s(o)).attr( "fill", (o) => { var m; return (m = o.payload) != null && m.fold && o.children ? s(o) : "var(--markmap-circle-open-bg)"; } ), this.transition(k).attr("r", 6), this.transition(A).style("opacity", 0), F.attr("width", (o) => Math.max(0, o.state.rect.width - n * 2)).attr("height", (o) => o.state.rect.height), this.transition(F).style("opacity", 1); const S = [ a.x + a.width, a.y + a.height / 2 ]; this.transition(q).attr("d", M({ source: S, target: S })).remove(), D.attr( "d", M({ source: S, target: S }) ), this.transition(J).attr("stroke", (o) => s(o.target)).attr("stroke-width", (o) => H(o.target)).attr("d", (o) => { const m = o.source, y = o.target, Q = [ m.state.rect.x + m.state.rect.width, m.state.rect.y + m.state.rect.height / 2 ], tt = [ y.state.rect.x, y.state.rect.y + y.state.rect.height / 2 ]; return M({ source: Q, target: tt }); }), r && this.fit(); } transition(t) { const { duration: n } = this.options; return t.transition().duration(n); } /** * Fit the content to the viewport. */ async fit(t = this.options.maxInitialScale) { const n = this.svg.node(), { width: r, height: s } = n.getBoundingClientRect(), { fitRatio: l } = this.options, { x1: c, y1: i, x2: a, y2: d } = this.state.rect, h = a - c, p = d - i, u = Math.min( r / h * l, s / p * l, t ), g = ct.translate( (r - h * u) / 2 - c * u, (s - p * u) / 2 - i * u ).scale(u); return this.transition(this.svg).call(this.zoom.transform, g).end().catch(R); } findElement(t) { let n; return this.g.selectAll(b("g")).each(function(s) { s === t && (n = { data: s, g: this }); }), n; } /** * Pan the content to make the provided node visible in the viewport. */ async ensureView(t, n) { var v; const r = (v = this.findElement(t)) == null ? void 0 : v.data; if (!r) return; const s = this.svg.node(), l = s.getBoundingClientRect(), c = j(s), [i, a] = [ r.state.rect.x, r.state.rect.x + r.state.rect.width + 2 ].map((k) => k * c.k + c.x), [d, h] = [ r.state.rect.y - r.state.rect.height / 2, r.state.rect.y + r.state.rect.height / 2 ].map((k) => k * c.k + c.y), p = { left: 0, right: 0, top: 0, bottom: 0, ...n }, u = [p.left - i, l.width - p.right - a], g = [p.top - d, l.height - p.bottom - h], f = u[0] * u[1] > 0 ? L(u, Math.abs) / c.k : 0, x = g[0] * g[1] > 0 ? L(g, Math.abs) / c.k : 0; if (f || x) { const k = c.translate(f, x); return this.transition(this.svg).call(this.zoom.transform, k).end().catch(R); } } /** * Scale content with it pinned at the center of the viewport. */ async rescale(t) { const n = this.svg.node(), { width: r, height: s } = n.getBoundingClientRect(), l = r / 2, c = s / 2, i = j(n), a = i.translate( (l - i.x) * (1 - t) / i.k, (c - i.y) * (1 - t) / i.k ).scale(t); return this.transition(this.svg).call(this.zoom.transform, a).end().catch(R); } destroy() { this.svg.on(".zoom", null), this.svg.html(null), this.revokers.forEach((t) => { t(); }); } static create(t, n, r = null) { const s = new Y(t, n); return r && s.setData(r).then(() => { s.fit(); }), s; } } export { Y as Markmap, dt as defaultColorFn, W as defaultOptions, se as deriveOptions, oe as globalCSS, P as isMacintosh, ce as loadCSS, he as loadJS, ne as refreshHook, pt as simpleHash };