UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

1,048 lines (1,033 loc) 73.9 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/collections'), require('rxjs'), require('rxjs/operators'), require('@angular/common'), require('@angular/core'), require('ng-zorro-antd/core/no-animation'), require('ng-zorro-antd/icon'), require('ng-zorro-antd/spin'), require('d3-shape'), require('d3-drag'), require('d3-selection'), require('d3-zoom'), require('@angular/animations'), require('ng-zorro-antd/core/util'), require('d3-transition'), require('dagre-compound'), require('ng-zorro-antd/core/polyfill')) : typeof define === 'function' && define.amd ? define('ng-zorro-antd/graph', ['exports', '@angular/cdk/collections', 'rxjs', 'rxjs/operators', '@angular/common', '@angular/core', 'ng-zorro-antd/core/no-animation', 'ng-zorro-antd/icon', 'ng-zorro-antd/spin', 'd3-shape', 'd3-drag', 'd3-selection', 'd3-zoom', '@angular/animations', 'ng-zorro-antd/core/util', 'd3-transition', 'dagre-compound', 'ng-zorro-antd/core/polyfill'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global['ng-zorro-antd'] = global['ng-zorro-antd'] || {}, global['ng-zorro-antd'].graph = {}), global.ng.cdk.collections, global.rxjs, global.rxjs.operators, global.ng.common, global.ng.core, global['ng-zorro-antd'].core['no-animation'], global['ng-zorro-antd'].icon, global['ng-zorro-antd'].spin, global.d3Shape, global.d3Drag, global.d3Selection, global.d3Zoom, global.ng.animations, global['ng-zorro-antd'].core.util, global.d3Transition, global.dagreCompound, global['ng-zorro-antd'].core.polyfill)); }(this, (function (exports, collections, rxjs, operators, common, core, noAnimation, icon, spin, d3Shape, d3Drag, d3Selection, d3Zoom, animations, util, d3Transition, dagreCompound, polyfill) { 'use strict'; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ function nzTypeDefinition() { return function (item) { return item; }; } var NZ_GRAPH_LAYOUT_SETTING = { graph: { meta: { nodeSep: 50, rankSep: 50, edgeSep: 5 } }, subScene: { meta: { paddingTop: 20, paddingBottom: 20, paddingLeft: 20, paddingRight: 20, labelHeight: 20 } }, nodeSize: { meta: { width: 50, maxLabelWidth: 0, height: 50 }, node: { width: 50, height: 50, labelOffset: 10, maxLabelWidth: 40 }, bridge: { width: 5, height: 5, radius: 2, labelOffset: 0 } } }; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); }; } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function (o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); }) : (function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } ; var __setModuleDefault = Object.create ? (function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function (o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, privateMap) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return privateMap.get(receiver); } function __classPrivateFieldSet(receiver, privateMap, value) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to set private field on non-instance"); } privateMap.set(receiver, value); return value; } var NzGraphData = /** @class */ (function () { function NzGraphData(source) { var _a; this._data = new rxjs.BehaviorSubject({}); /** A selection model with multi-selection to track expansion status. */ this.expansionModel = new collections.SelectionModel(true); if (source) { (_a = this.expansionModel) === null || _a === void 0 ? void 0 : _a.clear(); this.dataSource = source; this._data.next(source); } } /** Toggles one single data node's expanded/collapsed state. */ NzGraphData.prototype.toggle = function (nodeName) { this.expansionModel.toggle(nodeName); }; /** Expands one single data node. */ NzGraphData.prototype.expand = function (nodeName) { this.expansionModel.select(nodeName); }; /** Collapses one single data node. */ NzGraphData.prototype.collapse = function (nodeName) { this.expansionModel.deselect(nodeName); }; /** Whether a given data node is expanded or not. Returns true if the data node is expanded. */ NzGraphData.prototype.isExpanded = function (nodeName) { return this.expansionModel.isSelected(nodeName); }; /** Collapse all dataNodes in the tree. */ NzGraphData.prototype.collapseAll = function () { this.expansionModel.clear(); }; NzGraphData.prototype.expandAll = function () { var _b; (_b = this.expansionModel).select.apply(_b, __spread(Object.keys(this._data.value.compound || {}))); }; NzGraphData.prototype.setData = function (data) { var _a; (_a = this.expansionModel) === null || _a === void 0 ? void 0 : _a.clear(); this.dataSource = data; this._data.next(data); }; NzGraphData.prototype.connect = function () { var _this = this; var changes = [this._data, this.expansionModel.changed]; return rxjs.merge.apply(void 0, __spread(changes)).pipe(operators.map(function () { return _this._data.value; })); }; NzGraphData.prototype.disconnect = function () { // do nothing for now }; return NzGraphData; }()); /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphDefsComponent = /** @class */ (function () { function NzGraphDefsComponent() { } return NzGraphDefsComponent; }()); NzGraphDefsComponent.decorators = [ { type: core.Component, args: [{ selector: 'svg:defs[nz-graph-defs]', template: "\n <svg:marker\n class=\"nz-graph-edge-marker\"\n id=\"edge-end-arrow\"\n viewBox=\"1 0 20 20\"\n refX=\"8\"\n refY=\"3.5\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n orient=\"auto\"\n >\n <svg:polygon points=\"0 0, 10 3.5, 0 7\"></svg:polygon>\n </svg:marker>\n " },] } ]; NzGraphDefsComponent.ctorParameters = function () { return []; }; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphEdgeComponent = /** @class */ (function () { function NzGraphEdgeComponent(elementRef, ngZone, cdr) { this.elementRef = elementRef; this.ngZone = ngZone; this.cdr = cdr; this.line = d3Shape.line() .x(function (d) { return d.x; }) .y(function (d) { return d.y; }) .curve(d3Shape.curveBasis); this.el = this.elementRef.nativeElement; } Object.defineProperty(NzGraphEdgeComponent.prototype, "id", { get: function () { var _a; return ((_a = this.edge) === null || _a === void 0 ? void 0 : _a.id) || this.edge.v + "--" + this.edge.w; }, enumerable: false, configurable: true }); NzGraphEdgeComponent.prototype.ngOnInit = function () { this.initElementStyle(); }; NzGraphEdgeComponent.prototype.ngOnChanges = function (changes) { var _this = this; var edge = changes.edge, customTemplate = changes.customTemplate; if (edge) { this.ngZone.onStable.pipe(operators.take(1)).subscribe(function () { // Update path element if customTemplate set if (customTemplate) { _this.initElementStyle(); } _this.setLine(); _this.cdr.markForCheck(); }); } }; NzGraphEdgeComponent.prototype.initElementStyle = function () { this.path = this.el.querySelector('path'); this.setElementData(); }; NzGraphEdgeComponent.prototype.setLine = function () { this.setPath(this.line(this.edge.points)); }; NzGraphEdgeComponent.prototype.setPath = function (d) { this.path.setAttribute('d', d); }; NzGraphEdgeComponent.prototype.setElementData = function () { if (!this.path) { return; } this.path.setAttribute('id', this.id); this.path.setAttribute('data-edge', this.id); this.path.setAttribute('data-v', "" + this.edge.v); this.path.setAttribute('data-w', "" + this.edge.w); }; return NzGraphEdgeComponent; }()); NzGraphEdgeComponent.decorators = [ { type: core.Component, args: [{ selector: '[nz-graph-edge]', template: "\n <ng-container *ngIf=\"customTemplate\" [ngTemplateOutlet]=\"customTemplate\" [ngTemplateOutletContext]=\"{ $implicit: edge }\"></ng-container>\n <svg:g *ngIf=\"!customTemplate\">\n <path class=\"nz-graph-edge-line\" [attr.marker-end]=\"'url(#edge-end-arrow)'\"></path>\n <svg:text class=\"nz-graph-edge-text\" text-anchor=\"middle\" dy=\"10\" *ngIf=\"edge.label\">\n <textPath [attr.href]=\"'#' + id\" startOffset=\"50%\">{{ edge.label }}</textPath>\n </svg:text>\n </svg:g>\n ", changeDetection: core.ChangeDetectionStrategy.OnPush },] } ]; NzGraphEdgeComponent.ctorParameters = function () { return [ { type: core.ElementRef }, { type: core.NgZone }, { type: core.ChangeDetectorRef } ]; }; NzGraphEdgeComponent.propDecorators = { edge: [{ type: core.Input }], customTemplate: [{ type: core.Input }] }; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphEdgeDirective = /** @class */ (function () { function NzGraphEdgeDirective() { } return NzGraphEdgeDirective; }()); NzGraphEdgeDirective.decorators = [ { type: core.Directive, args: [{ selector: '[nzGraphEdge]', exportAs: 'nzGraphEdge' },] } ]; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphGroupNodeDirective = /** @class */ (function () { function NzGraphGroupNodeDirective() { } return NzGraphGroupNodeDirective; }()); NzGraphGroupNodeDirective.decorators = [ { type: core.Directive, args: [{ selector: '[nzGraphGroupNode]', exportAs: 'nzGraphGroupNode' },] } ]; var FRAC_VIEWPOINT_AREA = 0.8; var Minimap = /** @class */ (function () { function Minimap(svg, zoomG, mainZoom, minimap, maxWidth, labelPadding) { var _this = this; this.svg = svg; this.labelPadding = labelPadding; this.zoomG = zoomG; this.mainZoom = mainZoom; this.maxWidth = maxWidth; var minimapElement = d3Selection.select(minimap); var minimapSvgElement = minimapElement.select('svg'); var viewpointElement = minimapSvgElement.select('rect'); this.canvas = minimapElement.select('canvas.viewport').node(); this.canvasRect = this.canvas.getBoundingClientRect(); var handleEvent = function (event) { var minimapOffset = _this.minimapOffset(); var width = Number(viewpointElement.attr('width')); var height = Number(viewpointElement.attr('height')); var clickCoords = d3Selection.pointer(event, minimapSvgElement.node()); _this.viewpointCoord.x = clickCoords[0] - width / 2 - minimapOffset.x; _this.viewpointCoord.y = clickCoords[1] - height / 2 - minimapOffset.y; _this.updateViewpoint(); }; this.viewpointCoord = { x: 0, y: 0 }; var dragEvent = d3Drag.drag().subject(Object).on('drag', handleEvent); viewpointElement.datum(this.viewpointCoord).call(dragEvent); // Make the minimap clickable. minimapSvgElement.on('click', function (event) { if (event.defaultPrevented) { // This click was part of a drag event, so suppress it. return; } handleEvent(event); }); this.viewpoint = viewpointElement.node(); this.minimapSvg = minimapSvgElement.node(); this.minimap = minimap; this.canvasBuffer = minimapElement.select('canvas.buffer').node(); this.update(); } Minimap.prototype.minimapOffset = function () { return { x: (this.canvasRect.width - this.minimapSize.width) / 2, y: (this.canvasRect.height - this.minimapSize.height) / 2 }; }; Minimap.prototype.updateViewpoint = function () { // Update the coordinates of the viewpoint rectangle. d3Selection.select(this.viewpoint).attr('x', this.viewpointCoord.x).attr('y', this.viewpointCoord.y); // Update the translation vector of the main svg to reflect the // new viewpoint. var mainX = (-this.viewpointCoord.x * this.scaleMain) / this.scaleMinimap; var mainY = (-this.viewpointCoord.y * this.scaleMain) / this.scaleMinimap; d3Selection.select(this.svg).call(this.mainZoom.transform, d3Zoom.zoomIdentity.translate(mainX, mainY).scale(this.scaleMain)); }; Minimap.prototype.update = function () { var e_1, _a, e_2, _b; var _this = this; var sceneSize = null; try { // Get the size of the entire scene. sceneSize = this.zoomG.getBBox(); if (sceneSize.width === 0) { // There is no scene anymore. We have been detached from the dom. return; } } catch (e) { // Firefox produced NS_ERROR_FAILURE if we have been // detached from the dom. return; } var svgSelection = d3Selection.select(this.svg); // Read all the style rules in the document and embed them into the svg. // The svg needs to be self contained, i.e. all the style rules need to be // embedded so the canvas output matches the origin. var stylesText = ''; try { for (var _c = __values(new Array(document.styleSheets.length).keys()), _d = _c.next(); !_d.done; _d = _c.next()) { var k = _d.value; try { var cssRules = document.styleSheets[k].cssRules || document.styleSheets[k].rules; if (cssRules == null) { continue; } try { for (var _e = (e_2 = void 0, __values(new Array(cssRules.length).keys())), _f = _e.next(); !_f.done; _f = _e.next()) { var i = _f.value; // Remove tf-* selectors from the styles. stylesText += cssRules[i].cssText.replace(/ ?tf-[\w-]+ ?/g, '') + '\n'; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_2) throw e_2.error; } } } catch (e) { if (e.name !== 'SecurityError') { throw e; } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } } // Temporarily add the css rules to the main svg. var svgStyle = svgSelection.append('style'); svgStyle.text(stylesText); // Temporarily remove the zoom/pan transform from the main svg since we // want the minimap to show a zoomed-out and centered view. var zoomGSelection = d3Selection.select(this.zoomG); var zoomTransform = zoomGSelection.attr('transform'); zoomGSelection.attr('transform', null); // Since we add padding, account for that here. sceneSize.height += this.labelPadding * 2; sceneSize.width += this.labelPadding * 2; // Temporarily assign an explicit width/height to the main svg, since // it doesn't have one (uses flex-box), but we need it for the canvas // to work. svgSelection.attr('width', sceneSize.width).attr('height', sceneSize.height); // Since the content inside the svg changed (e.g. a node was expanded), // the aspect ratio have also changed. Thus, we need to update the scale // factor of the minimap. The scale factor is determined such that both // the width and height of the minimap are <= maximum specified w/h. this.scaleMinimap = this.maxWidth / Math.max(sceneSize.width, sceneSize.height); this.minimapSize = { width: sceneSize.width * this.scaleMinimap, height: sceneSize.height * this.scaleMinimap }; var minimapOffset = this.minimapOffset(); // Update the size of the minimap's svg, the buffer canvas and the // viewpoint rect. d3Selection.select(this.minimapSvg).attr(this.minimapSize); d3Selection.select(this.canvasBuffer).attr(this.minimapSize); if (this.translate != null && this.zoom != null) { // Update the viewpoint rectangle shape since the aspect ratio of the // map has changed. requestAnimationFrame(function () { return _this.zoom(); }); } // Serialize the main svg to a string which will be used as the rendering // content for the canvas. var svgXml = new XMLSerializer().serializeToString(this.svg); // Now that the svg is serialized for rendering, remove the temporarily // assigned styles, explicit width and height and bring back the pan/zoom // transform. svgStyle.remove(); svgSelection.attr('width', '100%').attr('height', '100%'); zoomGSelection.attr('transform', zoomTransform); var image = new Image(); image.onload = function () { // Draw the svg content onto the buffer canvas. var context = _this.canvasBuffer.getContext('2d'); context.clearRect(0, 0, _this.canvasBuffer.width, _this.canvasBuffer.height); context.drawImage(image, minimapOffset.x, minimapOffset.y, _this.minimapSize.width, _this.minimapSize.height); requestAnimationFrame(function () { var _a; // Hide the old canvas and show the new buffer canvas. d3Selection.select(_this.canvasBuffer).style('display', 'block'); d3Selection.select(_this.canvas).style('display', 'none'); // Swap the two canvases. _a = __read([_this.canvasBuffer, _this.canvas], 2), _this.canvas = _a[0], _this.canvasBuffer = _a[1]; }); }; image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgXml); }; /** * Handles changes in zooming/panning. Should be called from the main svg * to notify that a zoom/pan was performed and this minimap will update it's * viewpoint rectangle. * @param transform */ Minimap.prototype.zoom = function (transform) { if (this.scaleMinimap == null) { // Scene is not ready yet. return; } // Update the new translate and scale params, only if specified. if (transform) { this.translate = [transform.x, transform.y]; this.scaleMain = transform.k; } // Update the location of the viewpoint rectangle. var svgRect = this.svg.getBoundingClientRect(); var minimapOffset = this.minimapOffset(); var viewpointSelection = d3Selection.select(this.viewpoint); this.viewpointCoord.x = (-this.translate[0] * this.scaleMinimap) / this.scaleMain; this.viewpointCoord.y = (-this.translate[1] * this.scaleMinimap) / this.scaleMain; var viewpointWidth = (svgRect.width * this.scaleMinimap) / this.scaleMain; var viewpointHeight = (svgRect.height * this.scaleMinimap) / this.scaleMain; viewpointSelection .attr('x', this.viewpointCoord.x + minimapOffset.x) .attr('y', this.viewpointCoord.y + minimapOffset.y) .attr('width', viewpointWidth) .attr('height', viewpointHeight); // Show/hide the minimap depending on the viewpoint area as fraction of the // whole minimap. var mapWidth = this.minimapSize.width; var mapHeight = this.minimapSize.height; var x = this.viewpointCoord.x; var y = this.viewpointCoord.y; var w = Math.min(Math.max(0, x + viewpointWidth), mapWidth) - Math.min(Math.max(0, x), mapWidth); var h = Math.min(Math.max(0, y + viewpointHeight), mapHeight) - Math.min(Math.max(0, y), mapHeight); var fracIntersect = (w * h) / (mapWidth * mapHeight); if (fracIntersect < FRAC_VIEWPOINT_AREA) { this.minimap.classList.remove('hidden'); } else { this.minimap.classList.add('hidden'); } }; return Minimap; }()); /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphMinimapComponent = /** @class */ (function () { function NzGraphMinimapComponent(elementRef) { this.elementRef = elementRef; } NzGraphMinimapComponent.prototype.ngOnInit = function () { }; NzGraphMinimapComponent.prototype.init = function (containerEle, zoomBehavior) { var svgEle = containerEle.nativeElement.querySelector('svg'); var zoomEle = containerEle.nativeElement.querySelector('svg > g'); this.minimap = new Minimap(svgEle, zoomEle, zoomBehavior, this.elementRef.nativeElement, 150, 0); }; NzGraphMinimapComponent.prototype.zoom = function (transform) { if (this.minimap) { this.minimap.zoom(transform); } }; NzGraphMinimapComponent.prototype.update = function () { if (this.minimap) { this.minimap.update(); } }; return NzGraphMinimapComponent; }()); NzGraphMinimapComponent.decorators = [ { type: core.Component, args: [{ selector: 'nz-graph-minimap', template: "\n <svg>\n <defs>\n <filter id=\"minimapDropShadow\" x=\"-20%\" y=\"-20%\" width=\"150%\" height=\"150%\">\n <feOffset result=\"offOut\" in=\"SourceGraphic\" dx=\"1\" dy=\"1\"></feOffset>\n <feColorMatrix\n result=\"matrixOut\"\n in=\"offOut\"\n type=\"matrix\"\n values=\"0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.1 0 0 0 0 0 0.5 0\"\n ></feColorMatrix>\n <feGaussianBlur result=\"blurOut\" in=\"matrixOut\" stdDeviation=\"2\"></feGaussianBlur>\n <feBlend in=\"SourceGraphic\" in2=\"blurOut\" mode=\"normal\"></feBlend>\n </filter>\n </defs>\n <rect></rect>\n </svg>\n <canvas class=\"viewport\"></canvas>\n <!-- Additional canvas to use as buffer to avoid flickering between updates -->\n <canvas class=\"buffer\"></canvas>\n ", changeDetection: core.ChangeDetectionStrategy.OnPush, host: { '[class.nz-graph-minimap]': 'true' } },] } ]; NzGraphMinimapComponent.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphNodeComponent = /** @class */ (function () { function NzGraphNodeComponent(el, builder, renderer2) { this.el = el; this.builder = builder; this.renderer2 = renderer2; this.nodeClick = new core.EventEmitter(); this.animationInfo = null; this.initialState = true; this.animationPlayer = null; } NzGraphNodeComponent.prototype.triggerClick = function (event) { event.preventDefault(); this.nodeClick.emit(this.node); }; NzGraphNodeComponent.prototype.makeAnimation = function () { var _this = this; var cur = this.getAnimationInfo(); if (this.animationPlayer) { this.animationPlayer.destroy(); } var animationFactory; var pre = Object.assign({}, this.animationInfo); if (this.initialState) { animationFactory = this.builder.build([ animations.style({ transform: "translate(" + cur.x + "px, " + cur.y + "px)" }), animations.query('g', [ animations.style({ width: cur.width + "px", height: cur.height + "px" }) ]) ]); this.initialState = false; } else { animationFactory = this.builder.build([ animations.style({ transform: "translate(" + pre.x + "px, " + pre.y + "px)" }), animations.query('g', [ animations.style({ width: pre.width + "px", height: pre.height + "px" }) ]), animations.group([ animations.query('g', [ animations.animate('150ms ease-out', animations.style({ width: cur.width + "px", height: cur.height + "px" })) ]), animations.animate('150ms ease-out', animations.style({ transform: "translate(" + cur.x + "px, " + cur.y + "px)" })) ]) ]); } this.animationInfo = cur; this.animationPlayer = animationFactory.create(this.el.nativeElement); this.animationPlayer.play(); var done$ = new rxjs.Subject(); this.animationPlayer.onDone(function () { // Need this for canvas for now. _this.renderer2.setAttribute(_this.el.nativeElement, 'transform', "translate(" + cur.x + ", " + cur.y + ")"); done$.next(); done$.complete(); }); return done$.asObservable(); }; NzGraphNodeComponent.prototype.makeNoAnimation = function () { var cur = this.getAnimationInfo(); // Need this for canvas for now. this.renderer2.setAttribute(this.el.nativeElement, 'transform', "translate(" + cur.x + ", " + cur.y + ")"); }; NzGraphNodeComponent.prototype.getAnimationInfo = function () { var _a = this.nodeTransform(), x = _a.x, y = _a.y; return { width: this.node.width, height: this.node.height, x: x, y: y }; }; NzGraphNodeComponent.prototype.nodeTransform = function () { var x = this.computeCXPositionOfNodeShape() - this.node.width / 2; var y = this.node.y - this.node.height / 2; return { x: x, y: y }; }; NzGraphNodeComponent.prototype.computeCXPositionOfNodeShape = function () { if (this.node.expanded) { return this.node.x; } return this.node.x - this.node.width / 2 + this.node.coreBox.width / 2; }; return NzGraphNodeComponent; }()); NzGraphNodeComponent.decorators = [ { type: core.Component, args: [{ selector: '[nz-graph-node]', template: "\n <svg:g>\n <ng-container\n *ngIf=\"customTemplate\"\n [ngTemplateOutlet]=\"customTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: node }\"\n ></ng-container>\n <ng-container *ngIf=\"!customTemplate\">\n <svg:rect class=\"nz-graph-node-rect\" [attr.width]=\"node.width\" [attr.height]=\"node.height\"></svg:rect>\n <svg:text x=\"10\" y=\"20\">{{ node.id || node.name }}</svg:text>\n </ng-container>\n </svg:g>\n ", changeDetection: core.ChangeDetectionStrategy.OnPush, host: { '[id]': 'node.id || node.name', '[class.nz-graph-node-expanded]': 'node.expanded', '[class.nz-graph-group-node]': 'node.type===0', '[class.nz-graph-base-node]': 'node.type===1', '(click)': 'triggerClick($event)' } },] } ]; NzGraphNodeComponent.ctorParameters = function () { return [ { type: core.ElementRef }, { type: animations.AnimationBuilder }, { type: core.Renderer2 } ]; }; NzGraphNodeComponent.propDecorators = { node: [{ type: core.Input }], noAnimation: [{ type: core.Input }], customTemplate: [{ type: core.Input }], nodeClick: [{ type: core.Output }] }; __decorate([ util.InputBoolean(), __metadata("design:type", Boolean) ], NzGraphNodeComponent.prototype, "noAnimation", void 0); /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ var NzGraphNodeDirective = /** @class */ (function () { function NzGraphNodeDirective() { } return NzGraphNodeDirective; }()); NzGraphNodeDirective.decorators = [ { type: core.Directive, args: [{ selector: '[nzGraphNode]', exportAs: 'nzGraphNode' },] } ]; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** * Calculate position and scale * @param containerEle * @param targetEle * @param scale: if scale is set, skip calculate scale value */ var calculateTransform = function (containerEle, targetEle, scale) { var containerEleSize = containerEle.getBoundingClientRect(); var targetEleSize = targetEle.getBBox(); if (!targetEleSize.width) { // There is no g element anymore. return null; } // TODO // leave some place when re-scale var scaleUnit = (containerEleSize.width - 48) / containerEleSize.width; var k = scale || Math.min(containerEleSize.width / targetEleSize.width, containerEleSize.height / targetEleSize.height, 1) * scaleUnit; var x = (containerEleSize.width - targetEleSize.width * k) / 2; var y = (containerEleSize.height - targetEleSize.height * k) / 2; return { x: x, y: y, k: k }; }; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ Selection.bind('transition', d3Transition.transition); var NzGraphZoomDirective = /** @class */ (function () { function NzGraphZoomDirective(element, cdr) { this.element = element; this.cdr = cdr; this.nzMinZoom = 0.1; this.nzMaxZoom = 10; this.nzTransformEvent = new core.EventEmitter(); this.nzZoomChange = new core.EventEmitter(); this.destroy$ = new rxjs.Subject(); } NzGraphZoomDirective.prototype.ngAfterViewInit = function () { this.bind(); }; NzGraphZoomDirective.prototype.ngOnDestroy = function () { this.unbind(); this.destroy$.next(); this.destroy$.complete(); }; NzGraphZoomDirective.prototype.bind = function () { var _this = this; this.svgElement = this.element.nativeElement.querySelector('svg'); this.gZoomElement = this.element.nativeElement.querySelector('svg > g'); var _b = this.element.nativeElement.getBoundingClientRect(), width = _b.width, height = _b.height; this.svgSelection = d3Selection.select(this.svgElement); this.zoomBehavior = d3Zoom.zoom() .extent([ [0, 0], [width, height] ]) .scaleExtent([this.nzMinZoom, this.nzMaxZoom]) .on('zoom', function (e) { _this.zoomed(e); }); this.svgSelection.call(this.zoomBehavior, d3Zoom.zoomIdentity.translate(0, 0).scale(this.nzZoom || 1)); // Init with nzZoom this.reScale(0, this.nzZoom); }; NzGraphZoomDirective.prototype.unbind = function () { var _a; // Destroy listener (_a = this.svgSelection) === null || _a === void 0 ? void 0 : _a.interrupt().selectAll('*').interrupt(); if (this.zoomBehavior) { this.zoomBehavior.on('end', null).on('zoom', null); } }; // Methods NzGraphZoomDirective.prototype.fitCenter = function (duration) { if (duration === void 0) { duration = 0; } this.reScale(duration); }; NzGraphZoomDirective.prototype.focus = function (id, duration) { if (duration === void 0) { duration = 0; } // Make sure this node is under SVG container if (!this.svgElement.getElementById("" + id)) { return; } var node = this.svgElement.getElementById("" + id); var svgRect = this.svgElement.getBoundingClientRect(); var position = this.getRelativePositionInfo(node); var svgTransform = d3Zoom.zoomTransform(this.svgElement); var centerX = (position.topLeft.x + position.bottomRight.x) / 2; var centerY = (position.topLeft.y + position.bottomRight.y) / 2; var dx = svgRect.left + svgRect.width / 2 - centerX; var dy = svgRect.top + svgRect.height / 2 - centerY; this.svgSelection .transition() .duration(duration) .call(thi