@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.
715 lines (714 loc) • 22.4 kB
JavaScript
/**
* These utility methods help to process the data and to convert it to desired dimensions
*/
/**
* processPathData method \
*
* @returns {Object[]} processPathData method .\
* @param { string } data - provide the data value.
* @private
*/
export function processPathData(data) {
var collection = [];
var j;
var arrayCollection = parsePathData(data);
if (arrayCollection.length > 0) {
for (var i = 0; i < arrayCollection.length; i++) {
var ob = arrayCollection[parseInt(i.toString(), 10)];
var char = '';
char = ob[0];
switch (char.toLowerCase()) {
case 'm':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, x: ob[parseInt(j.toString(), 10)], y: ob[j + 1] });
j = j + 1;
if (char === 'm') {
char = 'l';
}
else if (char === 'M') {
char = 'L';
}
}
break;
case 'l':
case 't':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, x: ob[parseInt(j.toString(), 10)], y: ob[j + 1] });
j = j + 1;
}
break;
case 'h':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, x: ob[parseInt(j.toString(), 10)] });
}
break;
case 'v':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, y: ob[parseInt(j.toString(), 10)] });
}
break;
case 'z':
collection.push({ command: char });
break;
case 'c':
for (j = 1; j < ob.length; j++) {
collection.push({
command: char, x1: ob[parseInt(j.toString(), 10)], y1: ob[j + 1], x2: ob[j + 2],
y2: ob[j + 3], x: ob[j + 4], y: ob[j + 5]
});
j = j + 5;
}
break;
case 's':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, x2: ob[parseInt(j.toString(), 10)], y2: ob[j + 1], x: ob[j + 2], y: ob[j + 3] });
j = j + 3;
}
break;
case 'q':
for (j = 1; j < ob.length; j++) {
collection.push({ command: char, x1: ob[parseInt(j.toString(), 10)], y1: ob[j + 1], x: ob[j + 2], y: ob[j + 3] });
j = j + 3;
}
break;
case 'a':
for (j = 1; j < ob.length; j++) {
collection.push({
command: char, r1: ob[parseInt(j.toString(), 10)], r2: ob[j + 1], angle: ob[j + 2], largeArc: ob[j + 3],
sweep: ob[j + 4], x: ob[j + 5], y: ob[j + 6]
});
j = j + 6;
}
break;
}
}
}
return collection;
}
/**
* parsePathData method \
*
* @returns {Object[]} parsePathData method .\
* @param { string } data - provide the data value.
* @private
*/
export function parsePathData(data) {
var tokenizer = /([a-z]+)|([+-]?(?:\d+\.?\d*|\.\d+))/gi;
var current = [];
var commands = [];
var match = {};
tokenizer.lastIndex = 0;
var isExponential = false;
match = tokenizer.exec(data);
while (match) {
if (match[1] === 'e') {
//let s1: string = '';
isExponential = true;
}
else if (match[1]) {
if (match[1].toLowerCase() === 'zm') {
if (current.length) {
commands.push(current);
}
commands.push(['Z']);
current = [match[1].substring(1, 2)];
}
else {
if (current.length) {
commands.push(current);
}
current = [match[1]];
}
isExponential = false;
}
else {
if (!current.length) {
current = [];
}
if (!isExponential) {
current.push(Number(match[2]));
}
isExponential = false;
}
match = tokenizer.exec(data);
}
if (current.length) {
commands.push(current);
}
return commands;
}
/**
* getRectanglePath method \
*
* @returns {string} getRectanglePath method .\
* @param { number } cornerRadius - provide the data value.
* @param { number } height - provide the height value.
* @param { number } width - provide the width value.
* @private
*/
export function getRectanglePath(cornerRadius, height, width) {
var x = 0;
var y = 0;
var path = '';
var points = [{ x: x + cornerRadius, y: y }, { x: x + width - cornerRadius, y: y },
{ x: x + width, y: y + cornerRadius }, { x: x + width, y: y + height - cornerRadius },
{ x: x + width - cornerRadius, y: y + height }, { x: x + cornerRadius, y: y + height },
{ x: x, y: y + height - cornerRadius }, { x: x, y: y + cornerRadius }
];
var corners = [{ x: x + width, y: y }, { x: x + width, y: y + height }, { x: x, y: y + height }, { x: x, y: y }];
var corner = 0;
var point2;
var next;
path = 'M' + points[0].x + ' ' + points[0].y;
var i;
for (i = 0; i < points.length; i = i + 2) {
point2 = points[i + 1];
path += 'L' + point2.x + ' ' + point2.y;
next = points[i + 2] || points[0];
path += 'Q' + corners[parseInt(corner.toString(), 10)].x + ' ' + corners[parseInt(corner.toString(), 10)].y + ' ' + next.x + ' ' + next.y;
corner++;
}
return path;
}
/**
* getPolygonPath method \
*
* @returns {string} getPolygonPath method .\
* @param { PointModel[] } collection - provide the data value.
* @private
*/
export function getPolygonPath(collection) {
var path = '';
var seg;
path = 'M' + collection[0].x + ' ' + collection[0].y;
var i;
for (i = 1; i < collection.length; i++) {
seg = collection[parseInt(i.toString(), 10)];
path += 'L' + seg.x + ' ' + seg.y;
}
path += 'Z';
return path;
}
/**
* getFreeHandPath method \
*
* @returns {string} getFreeHandPath method .\
* @param { PointModel[] } collection - provide the data value.
* @private
*/
export function getFreeHandPath(collection) {
var k;
for (k = 0; k < collection.length; k++) {
collection[parseInt(k.toString(), 10)].x = Math.round(collection[parseInt(k.toString(), 10)].x);
collection[parseInt(k.toString(), 10)].y = Math.round(collection[parseInt(k.toString(), 10)].y);
}
var path = '';
var seg;
path = 'M' + collection[0].x + ' ' + collection[0].y;
var i;
for (i = 1; i < collection.length; i++) {
seg = collection[parseInt(i.toString(), 10)];
path += 'L' + seg.x + ' ' + seg.y;
}
return path;
}
/* eslint-disable */
/**
* pathSegmentCollection method \
*
* @returns {string} pathSegmentCollection method .\
* @param { Object[]} collection - provide the collection value.
* @private
*/
export function pathSegmentCollection(collection) {
var x0;
var y0;
var x1;
var y1;
var x2;
var y2;
var x;
var y;
var length;
var i;
var initx;
var inity;
var segments = [];
for (x = 0, y = 0, i = 0, length = collection.length; i < length; ++i) {
var obj = collection[i];
var seg = obj;
var char = '';
char = seg.command;
if ('y1' in seg) {
y1 = seg.y1;
}
if ('y2' in seg) {
y2 = seg.y2;
}
if ('x1' in seg) {
x1 = seg.x1;
}
if ('x2' in seg) {
x2 = seg.x2;
}
if ('x' in seg) {
x = seg.x;
}
if ('y' in seg) {
y = seg.y;
}
var prev = segments[segments.length - 1];
switch (char) {
case 'M':
segments.push({ command: 'M', x: x, y: y });
break;
case 'L':
segments.push({ command: 'L', x0: x0, y0: y0, x: x, y: y });
break;
case 'H':
segments.push({ command: 'L', x0: x0, y0: y0, x: x, y: y0 });
break;
case 'V':
segments.push({ command: 'L', x0: x0, y0: y0, x: x0, y: y });
break;
case 'C':
segments.push({ command: 'C', x0: x0, y0: y0, x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y });
break;
case 'S':
if (prev) {
var ctrl = void 0;
if (prev.command === 'C' || prev.command === 'S') {
ctrl = { x: prev.x2, y: prev.y2 };
}
else {
ctrl = { x: x0, y: y0 };
}
var cpt2 = { x: 2 * x0 - ctrl.x, y: 2 * y0 - ctrl.y };
segments.push({ command: 'C', x0: x0, y0: y0, x1: cpt2.x, y1: cpt2.y, x2: x2, y2: y2, x: x, y: y });
}
break;
case 'Q':
//ctx.quadraticCurveTo(x1, y1, x, y);
segments.push({ command: 'Q', x0: x0, y0: y0, x1: x1, y1: y1, x: x, y: y });
break;
case 'T':
if (prev) {
var ctrl = void 0;
if (prev.command === 'Q') {
ctrl = { x: prev.x1, y: prev.y1 };
}
else {
ctrl = { x: x0, y: y0 };
}
var cpt2 = { x: 2 * x0 - ctrl.x, y: 2 * y0 - ctrl.y };
segments.push({ command: 'Q', x0: x0, y0: y0, x1: cpt2.x, y1: cpt2.y, x: x, y: y });
}
break;
case 'A':
var newSeg = seg;
newSeg.command = 'A';
segments.push(newSeg);
break;
case 'Z':
case 'z':
segments.push({ command: 'Z' });
x = x0;
y = y0;
break;
}
if (char === 'M' || char === 'm') {
initx = x;
inity = y;
}
x0 = x;
y0 = y;
}
return segments;
}
/**
* transformPath method \
*
* @returns {string} transformPath method .\
* @param { Object[]} arr - provide the collection value.
* @param { number} sX - provide the collection value.
* @param { number} sY - provide the collection value.
* @param { boolean} s - provide the collection value.
* @param {number} bX - provide the collection value.
* @param { number} bY - provide the collection value.
* @param { number} iX - provide the collection value.
* @param { number} iY - provide the collection value.
* @private
*/
export function transformPath(arr, sX, sY, s, bX, bY, iX, iY) {
var x0;
var y0;
var x1;
var y1;
var x2;
var y2;
var x;
var y;
var length;
var i;
var newSeg;
for (x = 0, y = 0, i = 0, length = arr.length; i < length; ++i) {
var obj = arr[i];
var seg = obj;
var char = seg.command;
if ('x' in seg) {
x = seg.x;
}
if ('y' in seg) {
y = seg.y;
}
if ('y1' in seg) {
y1 = seg.y1;
}
if ('y2' in seg) {
y2 = seg.y2;
}
if ('x1' in seg) {
x1 = seg.x1;
}
if ('x2' in seg) {
x2 = seg.x2;
}
if (s) {
if (x !== undefined) {
x = scalePathData(x, sX, bX, iX);
}
if (y !== undefined) {
y = scalePathData(y, sY, bY, iY);
}
if (x1 !== undefined) {
x1 = scalePathData(x1, sX, bX, iX);
}
if (y1 !== undefined) {
y1 = scalePathData(y1, sY, bY, iY);
}
if (x2 !== undefined) {
x2 = scalePathData(x2, sX, bX, iX);
}
if (y2 !== undefined) {
y2 = scalePathData(y2, sY, bY, iY);
}
}
else {
if (x !== undefined) {
x = Number((x + sX).toFixed(2));
}
if (y !== undefined) {
y = Number((y + sY).toFixed(2));
}
if (x1 !== undefined) {
x1 = Number((x1 + sX).toFixed(2));
}
if (y1 !== undefined) {
y1 = Number((y1 + sY).toFixed(2));
}
if (x2 !== undefined) {
x2 = Number((x2 + sX).toFixed(2));
}
if (y2 !== undefined) {
y2 = Number((y2 + sY).toFixed(2));
}
}
var scaledPath = { x: x, y: y, x1: x1, y1: y1, x2: x2, y2: y2, r1: seg.r1, r2: seg.r2 };
newSeg = updatedSegment(seg, char, scaledPath, s, sX, sY);
if (newSeg) {
arr[i] = newSeg;
}
// Record the start of a subpath
if (char === 'M' || char === 'm') {
x0 = x;
y0 = y;
}
}
var pathData = getPathString(arr);
return pathData;
}
/**
* updatedSegment method \
*
* @returns {string} updatedSegment method .\
* @param { PathSegment} segment - provide the collection value.
* @param { PathSegment} char - provide the collection value.
* @param { number} obj - provide the collection value.
* @param { boolean} isScale - provide the collection value.
* @param {number} sX - provide the collection value.
* @param { number} sY - provide the collection value.
* @private
*/
export function updatedSegment(segment, char, obj, isScale, sX, sY) {
switch (char) {
case 'M':
segment.x = obj.x;
segment.y = obj.y;
break;
case 'L':
segment.x = obj.x;
segment.y = obj.y;
break;
case 'H':
segment.x = obj.x;
break;
case 'V':
segment.y = obj.y;
break;
case 'C':
segment.x = obj.x;
segment.y = obj.y;
segment.x1 = obj.x1;
segment.y1 = obj.y1;
segment.x2 = obj.x2;
segment.y2 = obj.y2;
break;
case 'S':
segment.x = obj.x;
segment.y = obj.y;
segment.x2 = obj.x2;
segment.y2 = obj.y2;
break;
case 'Q':
segment.x = obj.x;
segment.y = obj.y;
segment.x1 = obj.x1;
segment.y1 = obj.y1;
break;
case 'T':
segment.x = obj.x;
segment.y = obj.y;
break;
case 'A':
var r1 = obj.r1;
var r2 = obj.r2;
if (isScale) {
obj.r1 = r1 = (r1 * sX);
obj.r2 = r2 = (r2 * sY);
}
segment.x = obj.x;
segment.y = obj.y;
segment.r1 = obj.r1;
segment.r2 = obj.r2;
break;
case 'z':
case 'Z':
segment = { command: 'Z' };
break;
}
return segment;
}
/* eslint-enable */
/**
* scalePathData method \
*
* @returns {string} scalePathData method .\
* @param { number} val - provide the val value.
* @param { number} scaleFactor - provide the scaleFactor value.
* @param { number} oldOffset - provide the oldOffset value.
* @param { number} newOffset - provide the newOffset value.
* @private
*/
export function scalePathData(val, scaleFactor, oldOffset, newOffset) {
if (val !== oldOffset) {
if (newOffset !== oldOffset) {
val = (((val * scaleFactor) - (Number(oldOffset) * scaleFactor - Number(oldOffset)))
+ (newOffset - Number(oldOffset)));
}
else {
val = ((Number(val) * scaleFactor) - (Number(oldOffset) * scaleFactor - Number(oldOffset)));
}
}
else {
if (newOffset !== oldOffset) {
val = newOffset;
}
}
return Number(val.toFixed(2));
}
/**
* splitArrayCollection method \
*
* @returns {Object[]} splitArrayCollection method .\
* @param { Object[]} arrayCollection - provide the val value.
* @private
*/
export function splitArrayCollection(arrayCollection) {
var x0;
var y0;
var x1;
var y1;
var x2;
var y2;
var x;
var y;
var length;
var i;
for (x = 0, y = 0, i = 0, length = arrayCollection.length; i < length; ++i) {
var path = arrayCollection[parseInt(i.toString(), 10)];
var seg = path;
var char = seg.command;
if (/[MLHVCSQTA]/.test(char)) {
if ('x' in seg) {
seg.x = x = seg.x;
}
if ('y' in seg) {
seg.y = y = seg.y;
}
}
else {
if ('x1' in seg) {
seg.x1 = x1 = x + seg.x1;
}
if ('x2' in seg) {
seg.x2 = x2 = x + seg.x2;
}
if ('y1' in seg) {
seg.y1 = y1 = y + seg.y1;
}
if ('y2' in seg) {
seg.y2 = y2 = y + seg.y2;
}
if ('x' in seg) {
seg.x = x += seg.x;
}
if ('y' in seg) {
seg.y = y += seg.y;
}
var newSeg = void 0;
switch (char) {
case 'm':
case 'M':
newSeg = { command: 'M', x: x, y: y };
break;
case 'l':
case 'L':
newSeg = { command: 'L', x: x, y: y };
break;
case 'h':
case 'H':
newSeg = { command: 'H', x: x };
break;
case 'v':
case 'V':
newSeg = { command: 'V', y: y };
break;
case 'c':
case 'C':
newSeg = { command: 'C', x: x, y: y, x1: x1, y1: y1, x2: x2, y2: y2 };
break;
case 's':
case 'S':
newSeg = { command: 'S', x: x, y: y, x2: x2, y2: y2 };
break;
case 'q':
case 'Q':
newSeg = { command: 'Q', x: x, y: y, x1: x1, y1: y1 };
break;
case 't':
case 'T':
newSeg = { command: 'T', x: x, y: y };
break;
case 'a':
case 'A':
newSeg = { command: 'A', x: x, y: y };
newSeg.r1 = seg.r1;
newSeg.r2 = seg.r2;
newSeg.angle = seg.angle;
newSeg.largeArc = seg.largeArc;
newSeg.sweep = seg.sweep;
break;
case 'z':
case 'Z':
newSeg = { command: 'Z' };
x = x0;
y = y0;
newSeg = arrayCollection[parseInt(i.toString(), 10)];
break;
}
if (newSeg) {
arrayCollection[parseInt(i.toString(), 10)] = newSeg;
}
}
if (char === 'M' || char === 'm') {
x0 = x;
y0 = y;
}
}
return arrayCollection;
}
/**
* getPathString method \
*
* @returns {string} getPathString method .\
* @param { Object[]} arrayCollection - provide the val value.
* @private
*/
export function getPathString(arrayCollection) {
var getNewString = '';
var i;
for (i = 0; i < arrayCollection.length; i++) {
if (i === 0) {
getNewString += getString(arrayCollection[parseInt(i.toString(), 10)]);
}
else {
getNewString += ' ' + getString(arrayCollection[parseInt(i.toString(), 10)]);
}
}
return getNewString;
}
/* eslint-disable */
/**
* getString method \
*
* @returns {string} getString method .\
* @param { PathSegment} arrayCollection - provide the val value.
* @private
*/
export function getString(obj) {
var string = '';
switch (obj.command) {
case 'Z':
case 'z':
string = obj.command;
break;
case 'M':
case 'm':
case 'L':
case 'l':
string = obj.command + ' ' + obj.x + ' ' + obj.y;
break;
case 'C':
case 'c':
string = obj.command + ' ' + obj.x1 + ' ' + obj.y1 + ' ' + obj.x2 + ' ' + obj.y2 + ' ' + obj.x + ' ' + obj.y;
break;
case 'Q':
case 'q':
string = obj.command + ' ' + obj.x1 + ' ' + obj.y1 + ' ' + obj.x + ' ' + obj.y;
break;
case 'A':
case 'a':
var cmd = obj.command;
var ang = obj.angle;
var l = (obj.largeArc ? '1' : '0');
var s = (obj.sweep ? '1' : '0');
string = cmd + ' ' + obj.r1 + ' ' + obj.r2 + ' ' + ang + ' ' + l + ' ' + s + ' ' + obj.x + ' ' + obj.y;
break;
case 'H':
case 'h':
string = obj.command + ' ' + obj.x;
break;
case 'V':
case 'v':
string = obj.command + ' ' + obj.y;
break;
case 'S':
case 's':
string = obj.command + ' ' + obj.x2 + ' ' + obj.y2 + ' ' + obj.x + ' ' + obj.y;
break;
case 'T':
case 't':
string = obj.command + ' ' + obj.x + ' ' + obj.y;
}
return string;
}