@syncfusion/ej2-diagrams
Version:
Feature-rich diagram control to create diagrams like flow charts, organizational charts, mind maps, and BPMN diagrams. Its rich feature set includes built-in shapes, editing, serializing, exporting, printing, overview, data binding, and automatic layouts.
888 lines (887 loc) • 40.9 kB
JavaScript
import { Rect } from '../primitives/rect';
import { RealAction, ScrollActions } from '../enum/enum';
import { identityMatrix, scaleMatrix, translateMatrix, transformPointByMatrix, multiplyMatrix } from '../primitives/matrix';
import { updateRuler } from '../ruler/ruler';
import { canZoom, canPan, canVitualize } from './../utility/constraints-util';
/**
*/
var DiagramScroller = /** @class */ (function () {
function DiagramScroller(diagram) {
/** @private */
this.transform = { tx: 0, ty: 0, scale: 1 };
/** @private */
this.oldCollectionObjects = [];
/** @private */
this.removeCollection = [];
this.vPortWidth = 0;
this.vPortHeight = 0;
this.currentZoomFActor = 1;
this.hOffset = 0;
this.vOffset = 0;
this.scrolled = false;
this.hScrollSize = 0;
this.vScrollSize = 0;
this.diagram = diagram;
this.objects = [];
this.transform = diagram.scroller ? diagram.scroller.transform : { tx: 0, ty: 0, scale: 1 };
this.vPortWidth = diagram.scrollSettings.viewPortWidth;
this.vPortHeight = diagram.scrollSettings.viewPortHeight;
this.currentZoomFActor = diagram.scrollSettings.currentZoom;
this.hOffset = diagram.scrollSettings.horizontalOffset;
this.vOffset = diagram.scrollSettings.verticalOffset;
}
Object.defineProperty(DiagramScroller.prototype, "viewPortHeight", {
/**
* verticalOffset method \
*
* @returns { number } verticalOffset method .\
*
* @private
*/
get: function () {
return this.vPortHeight;
},
/**
* verticalOffset method \
*
* @returns { void } verticalOffset method .\
* @param {number} offset - provide the hOffset value.
*
* @private
*/
set: function (offset) {
this.vPortHeight = offset;
this.diagram.scrollSettings.viewPortHeight = offset;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DiagramScroller.prototype, "currentZoom", {
/**
* verticalOffset method \
*
* @returns { number } verticalOffset method .\
*
* @private
*/
get: function () {
return this.currentZoomFActor || 1;
},
/**
* verticalOffset method \
*
* @returns { void } verticalOffset method .\
* @param {number} offset - provide the hOffset value.
*
* @private
*/
set: function (offset) {
this.currentZoomFActor = offset;
this.diagram.scrollSettings.currentZoom = offset;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DiagramScroller.prototype, "viewPortWidth", {
/**
* verticalOffset method \
*
* @returns { number } verticalOffset method .\
*
* @private
*/
get: function () {
return this.vPortWidth;
},
/**
* verticalOffset method \
*
* @returns { void } verticalOffset method .\
* @param {number} offset - provide the hOffset value.
*
* @private
*/
set: function (offset) {
this.vPortWidth = offset;
this.diagram.scrollSettings.viewPortWidth = offset;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DiagramScroller.prototype, "horizontalOffset", {
/**
* verticalOffset method \
*
* @returns { number } verticalOffset method .\
*
* @private
*/
get: function () {
return this.hOffset;
},
/**
* verticalOffset method \
*
* @returns { void } verticalOffset method .\
* @param {number} offset - provide the hOffset value.
*
* @private
*/
set: function (offset) {
this.hOffset = offset;
if (Math.abs(this.hOffset - this.diagram.scrollSettings.horizontalOffset) > 1) {
this.diagram.realActions = this.diagram.realActions | RealAction.hScrollbarMoved;
this.scrolled = true;
}
this.diagram.scrollSettings.horizontalOffset = offset;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DiagramScroller.prototype, "verticalOffset", {
/**
* verticalOffset method \
*
* @returns { number } verticalOffset method .\
*
* @private
*/
get: function () {
return this.vOffset;
},
/**
* verticalOffset method \
*
* @returns { void } verticalOffset method .\
* @param {number} offset - provide the hOffset value.
*
* @private
*/
set: function (offset) {
this.vOffset = offset;
if (Math.abs(this.vOffset - this.diagram.scrollSettings.verticalOffset) > 1) {
this.diagram.realActions = this.diagram.realActions | RealAction.vScrollbarMoved;
this.scrolled = true;
}
this.diagram.scrollSettings.verticalOffset = offset;
},
enumerable: true,
configurable: true
});
// Method added to get bounds value if diagram is loaded from negative axis.
// SF-359118 implemented for this ticket requirement.
DiagramScroller.prototype.getBounds = function () {
var pageBounds;
var postion = this.diagram.spatialSearch.getPageBounds(0, 0);
if ((postion.x < 0 || postion.y < 0) && !this.diagram.pageSettings.multiplePage) {
pageBounds = this.getPageBounds(undefined, undefined, true, true);
}
else {
pageBounds = this.getPageBounds(undefined, undefined, true);
}
return pageBounds;
};
/**
* updateScrollOffsets method \
*
* @returns { void } updateScrollOffsets method .\
* @param {number} hOffset - provide the hOffset value.
* @param {number} vOffset - provide the vOffset value.
*
* @private
*/
DiagramScroller.prototype.updateScrollOffsets = function (hOffset, vOffset) {
var offsetX = 0;
var offsetY = 0;
var pageBounds = this.getBounds();
pageBounds.x *= this.currentZoom;
pageBounds.y *= this.currentZoom;
pageBounds.width *= this.currentZoom;
pageBounds.height *= this.currentZoom;
offsetX = Math.max(0, hOffset - pageBounds.left);
offsetY = Math.max(0, vOffset - pageBounds.top);
if (hOffset !== undefined && vOffset !== undefined) {
this.horizontalOffset = offsetX;
this.verticalOffset = offsetY;
this.diagram.setOffset(offsetX, offsetY);
}
else {
this.diagram.setOffset(-this.horizontalOffset - pageBounds.x, -this.verticalOffset - pageBounds.y);
}
this.transform = {
tx: Math.max(this.horizontalOffset, -pageBounds.left) / this.currentZoom, ty: Math.max(this.verticalOffset, -pageBounds.top) / this.currentZoom,
scale: this.currentZoom
};
};
/**
* setScrollOffset method \
*
* @returns { void } setScrollOffset method .\
* @param {number} hOffset - provide the hOffset value.
* @param {number} vOffset - provide the vOffset value.
*
* @private
*/
DiagramScroller.prototype.setScrollOffset = function (hOffset, vOffset) {
this.scrolled = false;
var pageBounds = this.getBounds();
pageBounds.x *= this.currentZoom;
pageBounds.y *= this.currentZoom;
pageBounds.width *= this.currentZoom;
pageBounds.height *= this.currentZoom;
var x = -pageBounds.left;
var y = -pageBounds.top;
var newX = x - hOffset;
if (newX !== this.horizontalOffset) {
if (x < this.horizontalOffset) {
if (this.horizontalOffset > newX) {
this.horizontalOffset -= hOffset;
}
else {
this.horizontalOffset = newX;
}
}
else {
this.horizontalOffset = newX;
}
}
//vertical offset
var newY = y - vOffset;
if (newY !== this.verticalOffset) {
if (y < this.verticalOffset) {
if (this.verticalOffset > newY) {
this.verticalOffset -= vOffset;
}
else {
this.verticalOffset = newY;
}
}
else {
this.verticalOffset = newY;
}
}
this.transform = {
tx: Math.max(this.horizontalOffset, -pageBounds.left) / this.currentZoom, ty: Math.max(this.verticalOffset, -pageBounds.top) / this.currentZoom,
scale: this.currentZoom
};
this.setSize();
};
/**
* getObjects \
*
* @returns { string[] } To get page pageBounds.\
* @param {string[]} coll1 - provide the source value.
* @param {string[]} coll2 - provide the source value.
* @private
*/
DiagramScroller.prototype.getObjects = function (coll1, coll2) {
var objects = [];
// Convert coll2 array into a Set for fast lookup
var coll2Set = new Set(coll2);
// Loop through each index in coll1
for (var i = 0; i < coll1.length; i++) {
// Use parseInt for index access (as required)
if (!coll2Set.has(coll1[parseInt(i.toString(), 10)])) {
objects.push(coll1[parseInt(i.toString(), 10)]);
}
}
// Return items from coll1 that are not present in coll2
return objects;
};
/**
* virtualizeElements \
*
* @returns { void } To get page pageBounds.\
*
* @private
*/
DiagramScroller.prototype.virtualizeElements = function () {
var viewWidth = this.viewPortWidth / this.currentZoom;
var viewHeight = this.viewPortHeight / this.currentZoom;
var oObjects = this.diagram.spatialSearch.findObjects(new Rect(-this.horizontalOffset / this.currentZoom, -this.verticalOffset / this.currentZoom, viewWidth, viewHeight));
var oObjectsID = [];
var renderOrder = [];
for (var j = 0; j < oObjects.length; j++) {
var bpmnShape = oObjects[parseInt(j.toString(), 10)].shape;
if (bpmnShape.type === 'Bpmn' && bpmnShape && bpmnShape.activity && bpmnShape.activity.subProcess && bpmnShape.activity.subProcess.processes && bpmnShape.activity.subProcess.processes.length > 0) {
for (var k = 0; k < bpmnShape.activity.subProcess.processes.length; k++) {
renderOrder.push(bpmnShape.activity.subProcess.processes[parseInt(k.toString(), 10)]);
}
renderOrder.push(oObjects[parseInt(j.toString(), 10)].id);
}
else if (oObjects[parseInt(j.toString(), 10)].processId === '' || oObjects[parseInt(j.toString(), 10)].processId === undefined) {
renderOrder.push(oObjects[parseInt(j.toString(), 10)].id);
}
}
oObjectsID = renderOrder;
var zindexOrder = [];
for (var j = 0; j < oObjects.length; j++) {
var items = oObjects[parseInt(j.toString(), 10)].shape;
if (items.type === 'Bpmn' && items && items.activity && items.activity.subProcess && items.activity.subProcess.processes && items.activity.subProcess.processes.length > 0) {
zindexOrder.push(oObjects[parseInt(j.toString(), 10)].id);
for (var t = 0; t < items.activity.subProcess.processes.length; t++) {
zindexOrder.push(items.activity.subProcess.processes[parseInt(t.toString(), 10)]);
}
}
else if (oObjects[parseInt(j.toString(), 10)].processId === '' || oObjects[parseInt(j.toString(), 10)].processId === undefined) {
zindexOrder.push(oObjects[parseInt(j.toString(), 10)].id);
}
}
// Create a plain object to store zindexOrder indices for quick lookup
var zindexLookup = {};
// Populate the lookup object
for (var k = 0; k < zindexOrder.length; k++) {
zindexLookup[zindexOrder[parseInt(k.toString(), 10)]] = k;
}
this.diagram.protectPropertyChange(true);
// Iterate over oObjects and set the zIndex using the lookup object
for (var j = 0; j < oObjects.length; j++) {
var objId = oObjects[parseInt(j.toString(), 10)].id;
if (objId in zindexLookup) {
oObjects[parseInt(j.toString(), 10)].zIndex = zindexLookup["" + objId];
}
}
this.diagram.protectPropertyChange(false);
var newObjects = this.getObjects(oObjectsID, this.oldCollectionObjects);
if (this.oldCollectionObjects.length === 0) {
this.oldCollectionObjects = oObjectsID;
}
var removeObjects = this.getObjects(this.oldCollectionObjects, oObjectsID);
this.diagram.updateVirtualObjects(newObjects, false, removeObjects);
this.oldCollectionObjects = oObjectsID;
};
/**
* setSize \
*
* @returns { void } To get page pageBounds.\
* @param {PointModel} newOffset - provide the newOffset value.
*
* @private
*/
DiagramScroller.prototype.setSize = function (newOffset) {
var pageBounds = this.getPageBounds(undefined, undefined, true);
pageBounds.x *= this.currentZoom;
pageBounds.y *= this.currentZoom;
pageBounds.width *= this.currentZoom;
pageBounds.height *= this.currentZoom;
var x = Math.min(pageBounds.x, -this.horizontalOffset);
var y = Math.min(pageBounds.y, -this.verticalOffset);
var difX = -this.horizontalOffset + this.viewPortWidth - pageBounds.right;
var difY = -this.verticalOffset + this.viewPortHeight - pageBounds.bottom;
var hScrollSize = this.scrollerWidth;
var vScrollSize = this.scrollerWidth;
if (-this.verticalOffset <= pageBounds.y && -this.verticalOffset + this.viewPortHeight >= pageBounds.bottom) {
vScrollSize = 0;
}
if (-this.horizontalOffset <= pageBounds.x && -this.horizontalOffset + this.viewPortWidth >= pageBounds.right) {
hScrollSize = 0;
}
this.hScrollSize = hScrollSize;
this.vScrollSize = vScrollSize;
var oldWidth = this.diagramWidth;
var oldHeight = this.diagramHeight;
this.diagramWidth = Math.max(pageBounds.right, -this.horizontalOffset + this.viewPortWidth - vScrollSize) - x;
this.diagramHeight = Math.max(pageBounds.bottom, -this.verticalOffset + this.viewPortHeight - hScrollSize) - y;
if ((oldWidth !== this.diagramWidth || oldHeight !== this.diagramHeight) && this.diagram.scrollSettings.scrollLimit !== 'Diagram') {
this.diagram.setSize(this.diagramWidth, this.diagramHeight);
}
if (this.diagram.scrollSettings.scrollLimit === 'Diagram') {
if ((oldWidth !== this.diagramWidth || oldHeight !== this.diagramHeight || this.currentZoom !== 1)
&& ((!this.diagram.diagramActions || !newOffset) || (this.diagram.diagramActions && newOffset &&
((this.verticalOffset !== 0 || this.verticalOffset === newOffset.y) &&
(this.horizontalOffset !== 0 || this.horizontalOffset === newOffset.x))))) {
if ((this.diagram.scrollActions & ScrollActions.Interaction) && newOffset) {
this.transform = {
tx: Math.max(newOffset.x, -(pageBounds.left / this.currentZoom)) / this.currentZoom,
ty: Math.max(newOffset.y, -(pageBounds.top / this.currentZoom)) / this.currentZoom,
scale: this.currentZoom
};
this.horizontalOffset = newOffset.x;
this.verticalOffset = newOffset.y;
}
this.diagram.setSize(this.diagramWidth, this.diagramHeight);
if ((!(this.diagram.scrollActions & ScrollActions.PropertyChange)) && newOffset) {
this.horizontalOffset = newOffset.x;
this.verticalOffset = newOffset.y;
this.transform = {
tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
scale: this.currentZoom
};
}
}
else if (newOffset && oldWidth === this.diagramWidth && oldHeight === this.diagramHeight &&
((this.diagram.diagramCanvas.scrollHeight > this.viewPortHeight &&
newOffset.y < 0 && this.horizontalOffset === newOffset.x && this.verticalOffset === 0) ||
(this.diagram.diagramCanvas.scrollWidth > this.viewPortWidth &&
newOffset.x < 0 && this.verticalOffset === newOffset.y && this.horizontalOffset === 0))) {
this.verticalOffset = newOffset.y;
this.horizontalOffset = newOffset.x;
this.transform = {
tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
scale: this.currentZoom
};
}
}
this.diagram.transformLayers();
this.diagram.element.style.overflow = 'hidden';
};
/**
* setViewPortSize \
*
* @returns { void } To get page pageBounds.\
* @param {number} width - provide the factor value.
* @param {number} height - provide the factor value.
*
* @private
*/
DiagramScroller.prototype.setViewPortSize = function (width, height) {
this.viewPortWidth = width;
this.viewPortHeight = height;
};
/**
* To get page pageBounds \
*
* @returns { Rect } To get page pageBounds.\
* @param {boolean} boundingRect - provide the factor value.
* @param {DiagramRegions} region - provide the factor value.
* @param {boolean} hasPadding - provide the factor value.
* @param {boolean} isnegativeRegion - provide the isnegativeRegion value.
*
* @private
*/
DiagramScroller.prototype.getPageBounds = function (boundingRect, region, hasPadding, isnegativeRegion) {
var rect = new Rect();
var temp = 0;
var pageBounds;
if (region !== 'Content' && !isnegativeRegion && this.diagram.pageSettings.width !== null && this.diagram.pageSettings.height !== null) {
var width = this.diagram.pageSettings.width;
var height = this.diagram.pageSettings.height;
var negwidth = 0;
var negheight = 0;
if (this.diagram.pageSettings.multiplePage) {
rect = this.diagram.spatialSearch.getPageBounds(0, 0);
if (rect.right > width) {
var x = Math.ceil(rect.right / width);
width = width * x;
}
if (rect.bottom > height) {
var x = Math.ceil(rect.bottom / height);
height = height * x;
}
if (rect.left < 0 && Math.abs(rect.left) > negwidth) {
var x = Math.ceil(Math.abs(rect.left) / this.diagram.pageSettings.width);
negwidth = this.diagram.pageSettings.width * x;
}
if (rect.top < 0 && Math.abs(rect.top) > negheight) {
var x = Math.ceil(Math.abs(rect.top) / this.diagram.pageSettings.height);
negheight = this.diagram.pageSettings.height * x;
}
}
pageBounds = new Rect((-negwidth), (-negheight), width + negwidth, height + negheight);
}
else {
var origin_1 = boundingRect ? undefined : 0;
pageBounds = this.diagram.spatialSearch.getPageBounds(origin_1, origin_1);
}
if (hasPadding) {
var scrollpadding = this.diagram.scrollSettings.padding;
pageBounds.x -= scrollpadding.left;
pageBounds.y -= scrollpadding.top;
pageBounds.width += (scrollpadding.left + scrollpadding.right);
pageBounds.height += (scrollpadding.top + scrollpadding.bottom);
}
return pageBounds;
};
/**
* To get page break when PageBreak is set as true \
*
* @returns { Segment[] } To get page break when PageBreak is set as true.\
* @param {Rect} pageBounds - provide the factor value.
*
* @private
*/
DiagramScroller.prototype.getPageBreak = function (pageBounds) {
var i = 0;
var j = 0;
var v = -1;
var collection = [];
var x1 = 0;
var x2 = 0;
var y1 = 0;
var y2 = 0;
var left = this.diagram.pageSettings.margin.left;
var right = this.diagram.pageSettings.margin.right;
var top = this.diagram.pageSettings.margin.top;
var bottom = this.diagram.pageSettings.margin.bottom;
var widthCount = 1;
var heightCount = 1;
var segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
while (pageBounds.width > i) {
i = i + (this.diagram.pageSettings.width ? this.diagram.pageSettings.width : pageBounds.width);
if (i === this.diagram.pageSettings.width) {
segment = {
x1: pageBounds.left + left, y1: pageBounds.top + top,
x2: pageBounds.left + left, y2: pageBounds.bottom - bottom
};
collection[++v] = segment;
}
if (i < pageBounds.width) {
x1 = pageBounds.topLeft.x + this.diagram.pageSettings.width * widthCount;
y1 = pageBounds.topLeft.y + top;
x2 = pageBounds.bottomLeft.x + this.diagram.pageSettings.width * widthCount;
y2 = pageBounds.bottomLeft.y - bottom;
segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
collection[++v] = segment;
widthCount++;
}
if (pageBounds.width === i) {
segment = {
x1: pageBounds.right - right, y1: pageBounds.top + top,
x2: pageBounds.right - right, y2: pageBounds.bottom - bottom
};
collection[++v] = segment;
}
}
while (pageBounds.height > j) {
j = j + (this.diagram.pageSettings.height ? this.diagram.pageSettings.height : pageBounds.height);
if (j === this.diagram.pageSettings.height) {
segment = {
x1: pageBounds.left + left, y1: pageBounds.top + top,
x2: pageBounds.right - right, y2: pageBounds.top + top
};
collection[++v] = segment;
}
if (j < pageBounds.height) {
x1 = pageBounds.topLeft.x + left;
y1 = pageBounds.topLeft.y + this.diagram.pageSettings.height * heightCount;
x2 = pageBounds.topRight.x - right;
y2 = pageBounds.topRight.y + this.diagram.pageSettings.height * heightCount;
segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
collection[++v] = segment;
heightCount++;
}
if (pageBounds.height === j) {
segment = {
x1: pageBounds.left + left, y1: pageBounds.bottom - bottom,
x2: pageBounds.right - right, y2: pageBounds.bottom - bottom
};
collection[++v] = segment;
}
}
return collection;
};
/**
* zoom method \
*
* @returns { void } zoom method .\
* @param {number} factor - provide the factor value.
* @param {number} deltaX - provide the bounds value.
* @param {number} deltaY - provide the bounds value.
* @param {PointModel} focusPoint - provide the bounds value.
* @param {boolean} isInteractiveZoomPan - provide the isInteractiveZoomPan value.
* @param {boolean} isBringIntoView - provide the isBringIntoView value.
* @param {boolean} isTrackpadScroll - provide the isTrackpadScroll value.
* @param {boolean} canZoomOut - provide the canZoomOut value.
*
* @private
*/
DiagramScroller.prototype.zoom = function (factor, deltaX, deltaY, focusPoint, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll, canZoomOut) {
if (canZoom(this.diagram) && factor !== 1 || (canPan(this.diagram) && factor === 1)) {
var matrix = identityMatrix();
scaleMatrix(matrix, this.currentZoom, this.currentZoom);
translateMatrix(matrix, this.horizontalOffset, this.verticalOffset);
focusPoint = focusPoint || {
x: (this.viewPortWidth / 2 - this.horizontalOffset) / this.currentZoom,
y: (this.viewPortHeight / 2 - this.verticalOffset) / this.currentZoom
};
focusPoint = transformPointByMatrix(matrix, focusPoint);
//Bug 853566: Fit to page is not working when zoom value less than minZoom.
// Removed minZoom calculation to call fitToPage even if currentZoom less than minZoom.
if ((this.currentZoom * factor) <= this.diagram.scrollSettings.maxZoom &&
((this.currentZoom * factor) >= this.diagram.scrollSettings.minZoom || (canZoomOut || factor >= 1))) {
this.currentZoom *= factor;
var pageBounds = this.getPageBounds(undefined, undefined, true);
pageBounds.x *= this.currentZoom;
pageBounds.y *= this.currentZoom;
//target Matrix
var targetMatrix = identityMatrix();
scaleMatrix(targetMatrix, factor, factor, focusPoint.x, focusPoint.y);
translateMatrix(targetMatrix, deltaX || 0, deltaY || 0);
multiplyMatrix(matrix, targetMatrix);
var newOffset = transformPointByMatrix(matrix, { x: 0, y: 0 });
if (factor === 1) {
// EJ2-69238 - add true as an extra parameter to calcuate the horizontal and vertical offset
newOffset = this.applyScrollLimit(newOffset.x, newOffset.y, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll);
}
// Bug 829925: Scroll bar flickers on scrolling the diagram using touchpad.
// The below condition is used to avoid the flickering of the scroll bar on scrolling the diagram using trackpad.
isTrackpadScroll = (-(pageBounds.y) >= newOffset.y && -(pageBounds.x) >= newOffset.x && isTrackpadScroll);
if ((this.diagram.scrollActions & ScrollActions.PropertyChange ||
!(this.diagram.scrollActions & ScrollActions.Interaction)) ||
this.diagram.scrollSettings.scrollLimit !== 'Diagram' || isTrackpadScroll) {
this.transform = {
tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
scale: this.currentZoom
};
this.horizontalOffset = newOffset.x;
this.verticalOffset = newOffset.y;
}
this.setSize(newOffset);
if (this.diagram.mode !== 'SVG' && canVitualize(this.diagram)) {
this.diagram.scroller.virtualizeElements();
}
if (this.diagram.mode !== 'SVG' && !canVitualize(this.diagram)) {
this.diagram.refreshDiagramLayer();
}
this.diagram.setOffset(-this.horizontalOffset - pageBounds.x, -this.verticalOffset - pageBounds.y);
updateRuler(this.diagram);
//Bug 863516: Overview is not synced with diagram content while zoom-out the diagram.
//Updating overview after the page scrolled or zoomed.
if (this.diagram.views && this.diagram.views.overview) {
var overview = this.diagram.views.overview;
var bounds = overview.scrollOverviewRect(overview.parent.scroller.horizontalOffset, overview.parent.scroller.verticalOffset, overview.parent.scroller.currentZoom, true);
overview.updateOverviewrect(-bounds.x, -bounds.y, bounds.width, bounds.height);
overview.updateView(overview);
}
}
}
};
/**
* fitToPage method \
*
* @returns { void } fitToPage method .\
* @param {IFitOptions} options - provide the bounds value.
*
* @private
*/
DiagramScroller.prototype.fitToPage = function (options) {
options = options || {};
var mode = options.mode;
var region = options.region;
var margin = options.margin || {};
var canZoomIn = options.canZoomIn;
var customBounds = options.customBounds;
// Allows fitToPage when the currentZoom less than minZoom.
var canZoomOut = options.canZoomOut;
margin.bottom = margin.bottom || 25;
margin.top = margin.top || 25;
margin.left = margin.left || 25;
margin.right = margin.right || 25;
var bounds = customBounds;
var factor;
var deltaX = -this.horizontalOffset;
var deltaY = -this.verticalOffset;
region = region ? region : 'PageSettings';
//fit mode
if ((region === 'PageSettings' && this.diagram.pageSettings.width && this.diagram.pageSettings.height)
|| (this.diagram.nodes.length > 0 || this.diagram.connectors.length > 0)) {
mode = mode ? mode : 'Page';
if (region !== 'CustomBounds') {
bounds = this.getPageBounds(true, region, true);
}
var scale = { x: 0, y: 0 };
//Bug 853566: Fit to page is not working when zoom value less than minZoom.
// Resetting margin value if the margin value is greater than the viewport size to avoid scale value in negative.
if ((margin.left + margin.right) > this.viewPortWidth) {
if (this.viewPortWidth <= 100) {
margin.left = 5;
margin.right = 5;
}
else {
margin.left = 25;
margin.right = 25;
}
}
if ((margin.top + margin.bottom) > this.viewPortHeight) {
if (this.viewPortHeight <= 100) {
margin.top = 5;
margin.bottom = 5;
}
else {
margin.top = 25;
margin.bottom = 25;
}
}
scale.x = (this.viewPortWidth - (margin.left + margin.right)) / (bounds.width);
scale.y = (this.viewPortHeight - (margin.top + margin.bottom)) / (bounds.height);
if (!canZoomIn && (((bounds.width - this.horizontalOffset) < this.viewPortWidth) &&
(bounds.height - this.verticalOffset) < this.viewPortHeight)) {
scale.x = Math.min(this.currentZoom, scale.x);
scale.y = Math.min(this.currentZoom, scale.y);
}
var zoomFactor = void 0;
var centerX = void 0;
var centerY = void 0;
switch (mode) {
case 'Width':
zoomFactor = scale.x;
factor = zoomFactor / this.currentZoom;
centerX = (this.viewPortWidth - (bounds.width) * zoomFactor) / 2 - bounds.x * zoomFactor;
deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
deltaY -= -this.verticalOffset * factor;
deltaY = region !== 'CustomBounds' ? deltaY : deltaY - this.verticalOffset * factor;
break;
case 'Height':
zoomFactor = scale.y;
factor = (zoomFactor / this.currentZoom);
centerX = ((this.viewPortWidth - (bounds.width) * zoomFactor) / 2) - bounds.x * zoomFactor;
centerY = ((this.viewPortHeight - (bounds.height) * zoomFactor) / 2) - bounds.y * zoomFactor;
deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
deltaY += centerY + (margin.top - margin.bottom) / 2 * zoomFactor;
break;
case 'Page':
zoomFactor = Math.min(scale.x, scale.y);
factor = (zoomFactor / this.currentZoom);
centerX = (this.viewPortWidth - (bounds.width) * zoomFactor) / 2 - bounds.x * zoomFactor;
centerY = (this.viewPortHeight - (bounds.height) * zoomFactor) / 2 - bounds.y * zoomFactor;
deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
deltaY += centerY + (margin.top - margin.bottom) / 2 * zoomFactor;
break;
}
/**
* EJ2-62912 - fit to page is not working properly when call it multiple times.
*/
this.zoom(factor, deltaX, deltaY, { x: 0, y: 0 }, true, undefined, undefined, canZoomOut);
}
else {
factor = 1 / this.currentZoom;
this.zoom(factor, deltaX, deltaY, { x: 0, y: 0 }, true, undefined, undefined, canZoomOut);
}
};
/**
* bringIntoView method \
*
* @returns { void } bringIntoView method .\
* @param {Rect} rect - provide the bounds value.
* @param {boolean} isBringIntoView - provide the isBringIntoView value.
*
* @private
*/
DiagramScroller.prototype.bringIntoView = function (rect, isBringIntoView) {
// EJ2-68130-Bringintoview shows the object outside the viewport
var x = 0;
var y = 0;
var scale = this.currentZoom;
var bounds = rect;
var hoffset = -this.horizontalOffset;
var voffset = -this.verticalOffset;
bounds = new Rect(bounds.x * scale, bounds.y * scale, bounds.width * scale, bounds.height * scale);
var view = new Rect(hoffset, voffset, this.viewPortWidth, this.viewPortHeight);
//To prevent nodes from being cut off in the horizontal and vertical scrollbars when calling the "bring into view" function, a padding value is added.
var nodePadding = 20;
if (!(view.containsRect(bounds))) {
if (bounds.right > (-hoffset + this.viewPortWidth)) {
x = bounds.right - this.viewPortWidth;
x += nodePadding;
}
if (bounds.x < -hoffset) {
x = bounds.x;
}
if (bounds.bottom > (-voffset + this.viewPortHeight)) {
y = bounds.bottom - this.viewPortHeight;
y += nodePadding;
}
if (bounds.y < -voffset) {
y = bounds.y;
}
this.zoom(1, -this.horizontalOffset - x, -this.verticalOffset - y, null, undefined, isBringIntoView);
}
};
/**
* bringToCenter method \
*
* @returns { void } bringToCenter method .\
* @param {Rect} bounds - provide the bounds value.
*
* @private
*/
DiagramScroller.prototype.bringToCenter = function (bounds) {
var scale = this.currentZoom;
var actualbounds = new Rect(bounds.x * scale, bounds.y * scale, bounds.width * scale, bounds.height * scale);
var hoffset = actualbounds.x + actualbounds.width / 2 - this.viewPortWidth / 2;
var voffset = actualbounds.y + actualbounds.height / 2 - this.viewPortHeight / 2;
/**
* In applyScrollLimit method the sign of deltaX and deltaY
* will be changed ,so here we change the sign.
* similarly for bringIntoView.
*/
hoffset *= -1;
voffset *= -1;
this.zoom(1, -this.horizontalOffset - hoffset, -this.verticalOffset - voffset, null);
};
DiagramScroller.prototype.applyScrollLimit = function (hOffset, vOffset, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll) {
/**
* EJ2-60980- ScrollOffset is not updated properly in runtime.
* EJ2-62524 - panning is not working properly in diagram.
* isInteractiveZoomPan is undefined while setting scrollOffset at runtime.
*/
if (this.diagram.scrollSettings.scrollLimit === 'Infinity') {
if (isInteractiveZoomPan === undefined && !isBringIntoView) {
hOffset = -hOffset;
vOffset = -vOffset;
}
}
if (this.diagram.scrollSettings.scrollLimit !== 'Infinity') {
var bounds = void 0;
if (this.diagram.scrollSettings.scrollLimit === 'Limited') {
var scrollableBounds = this.diagram.scrollSettings.scrollableArea;
bounds = new Rect(scrollableBounds.x, scrollableBounds.y, scrollableBounds.width, scrollableBounds.height);
}
// Bug 829925: Scroll bar flickers on scrolling the diagram using touchpad.
// Added below code to get the page bounds based on the scroll.
bounds = bounds || (isTrackpadScroll ? this.getPageBounds(false, undefined, true) : this.getPageBounds(true, undefined, true));
// 939223: Unable to Pan to the Extreme End of the Diagram When Scroll Padding is Applied
var eventHandler = 'eventHandler';
if (this.diagram["" + eventHandler].currentAction === 'Pan' && this.diagram["" + eventHandler].inAction) {
bounds = this.getPageBounds(false, undefined, true);
}
bounds.x *= this.currentZoom;
bounds.y *= this.currentZoom;
bounds.width *= this.currentZoom;
bounds.height *= this.currentZoom;
if (isInteractiveZoomPan !== undefined) {
hOffset *= -1;
vOffset *= -1;
}
// EJ2-69238 - Added below code to multiple the horizontal and vertical offset to bring the node in viewport
if (isBringIntoView) {
hOffset *= -1;
vOffset *= -1;
}
var allowedRight = Math.max(bounds.right, this.viewPortWidth);
if (!isBringIntoView && !(hOffset <= bounds.x && (hOffset + this.viewPortWidth >= bounds.right ||
hOffset >= bounds.right - this.viewPortWidth)
|| hOffset >= bounds.x && (hOffset + this.viewPortWidth <= allowedRight))) {
//not allowed case
if (hOffset >= bounds.x) {
hOffset = Math.max(bounds.x, Math.min(hOffset, hOffset - (hOffset + this.viewPortWidth - this.vScrollSize - allowedRight)));
}
else {
var allowed = bounds.right - this.viewPortWidth;
hOffset = Math.min(allowed, bounds.x);
}
}
var allowedBottom = Math.max(bounds.bottom, this.viewPortHeight);
// EJ2-69238 - Added below code to restrict the min value calculation for vertical offset in bringIntoview scenarion.
if (!isBringIntoView && !(vOffset <= bounds.y && vOffset + this.viewPortHeight >= bounds.bottom
|| vOffset >= bounds.y && vOffset + this.viewPortHeight <= allowedBottom)) {
//not allowed case
if (vOffset >= bounds.y) {
vOffset = Math.max(bounds.y, Math.min(vOffset, vOffset - (vOffset + this.viewPortHeight - this.hScrollSize - allowedBottom)));
}
else {
var allowed = bounds.bottom - this.viewPortHeight;
vOffset = Math.min(bounds.y, allowed);
}
}
hOffset *= -1;
vOffset *= -1;
}
return { x: hOffset, y: vOffset };
};
return DiagramScroller;
}());
export { DiagramScroller };