UNPKG

cmmn-js

Version:
336 lines (299 loc) 10.9 kB
'use strict'; /** * Map containing SVG paths needed by CmmnRenderer. */ function PathMap() { var PATH_USER_TYPE_1 = 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' + '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' + '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' + 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' + 'm -8,6 l 0,5.5 m 11,0 l 0,-5'; var PATH_USER_TYPE_2 = 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' + '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005'; var PATH_USER_TYPE_3 = 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' + '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' + '-4.20799998,3.36699999 -4.20699998,4.34799999 z'; /** * Contains a map of path elements * * <h1>Path definition</h1> * A parameterized path is defined like this: * <pre> * 'EVENT_TIMER_WH': { * d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ', * height: 17.5, * width: 17.5, * heightElements: [2.5, 7.5], * widthElements: [2.5, 7.5] * } * </pre> * <p>It's important to specify a correct <b>height and width</b> for the path as the scaling * is based on the ratio between the specified height and width in this object and the * height and width that is set as scale target (Note x,y coordinates will be scaled with * individual ratios).</p> * <p>The '<b>heightElements</b>' and '<b>widthElements</b>' array must contain the values that will be scaled. * The scaling is based on the computed ratios. * Coordinates on the y axis should be in the <b>heightElement</b>'s array, they will be scaled using * the computed ratio coefficient. * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets. * <ul> * <li>The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....</li> * <li>The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....</li> * </ul> * The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index. * </p> */ this.pathMap = { // TASK DECORATOR 'TASK_TYPE_FOLDER': { d: 'm {mx},{my} l18,0 l0,12 l-18,0 l0,-12 m 2,0 l3,-4 l5,0 l3,4' }, 'TASK_TYPE_CHEVRON': { d: 'm {mx},{my} l15,0 l6,6 l-6,6 l-15,0 l6,-6 l-6,-6' }, 'TASK_TYPE_USER_1': { d: PATH_USER_TYPE_1 }, 'TASK_TYPE_USER_2': { d: PATH_USER_TYPE_2 }, 'TASK_TYPE_USER_3': { d: PATH_USER_TYPE_3 }, 'TASK_TYPE_MANUAL': { d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' + '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' + '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' + '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' + '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' + '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' + '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' + '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' + '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' + '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' + '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' + '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z' }, 'TASK_TYPE_BUSINESS_RULE_HEADER': { d: 'm {mx},{my} 0,4 20,0 0,-4 z' }, 'TASK_TYPE_BUSINESS_RULE_MAIN': { d: 'm {mx},{my} 0,12 20,0 0,-12 z' + 'm 0,8 l 20,0 ' + 'm -13,-4 l 0,8' }, // EVENT LISTENER DECORATOR 'EVENT_TIMER_WH': { d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 2], widthElements: [3, 7] }, 'EVENT_TIMER_LINE': { d: 'M {mx},{my} ' + 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 3], widthElements: [0, 0] }, 'EVENT_USER_1': { d: PATH_USER_TYPE_1, height: 36, width: 36, heightElements: [], widthElements: [] }, 'EVENT_USER_2': { d: PATH_USER_TYPE_2, height: 36, width: 36, heightElements: [], widthElements: [] }, 'EVENT_USER_3': { d: PATH_USER_TYPE_3, height: 36, width: 36, heightElements: [], widthElements: [] }, // MARKERS 'MARKER_STAGE_EXPANDED': { d: 'm{mx},{my} m 2,7 l 10,0', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_STAGE_COLLAPSED': { d: 'm{mx},{my} m 2,7 l 10,0 m -5,-5 l 0,10', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_REQUIRED': { d: 'm{mx},{my} l 0,9 m 0,2 l0,3', height: 14, width: 3, heightElements: [], widthElements: [] }, 'MARKER_MANUAL_ACTIVATION': { d: 'm{mx}, {my} l 14,7 l -14,7 l 0,-14 z', height: 14, width: 14, heightElements: [], widthElements: [] }, 'MARKER_REPEATABLE': { d: 'm{mx},{my} m 3,0 l 0,14 m 6,-14 l 0,14 m -10,-10 l 14,0 m -14,6 l 14,0', height: 14, width: 14, heightElements: [], widthElements: [] }, 'MARKER_PLANNING_TABLE_EXPANDED': { d: 'm{mx},{my} m 0,12 l 30,0 m -20,-12 l 0, 24 m 10, -24 l 0, 24 m -10, -6 l 10,0', height: 24, width: 30, heightElements: [], widthElements: [] }, 'MARKER_PLANNING_TABLE_COLLAPSED': { d: 'm{mx},{my} m 0,12 l 30,0 m -20,-12 l 0, 24 m 10, -24 l 0, 24 m -10, -6 l 10,0 m -5, -6 l 0,12', height: 10, width: 10, heightElements: [], widthElements: [] }, 'DATA_OBJECT_PATH': { d:'m 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0', height: 61, width: 51, heightElements: [10, 50, 60], widthElements: [10, 40, 50, 60] }, 'TEXT_ANNOTATION': { d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0', height: 30, width: 10, heightElements: [30], widthElements: [10] } }; this.getRawPath = function getRawPath(pathId) { return this.pathMap[pathId].d; }; /** * Scales the path to the given height and width. * <h1>Use case</h1> * <p>Use case is to scale the content of elements (event) based * on the element bounding box's size. * </p> * <h1>Why not transform</h1> * <p>Scaling a path with transform() will also scale the stroke and IE does not support * the option 'non-scaling-stroke' to prevent this. * Also there are use cases where only some parts of a path should be * scaled.</p> * * @param {String} pathId The ID of the path. * @param {Object} param <p> * Example param object scales the path to 60% size of the container (data.width, data.height). * <pre> * { * xScaleFactor: 0.6, * yScaleFactor:0.6, * containerWidth: data.width, * containerHeight: data.height, * position: { * mx: 0.46, * my: 0.2, * } * } * </pre> * <ul> * <li>targetpathwidth = xScaleFactor * containerWidth</li> * <li>targetpathheight = yScaleFactor * containerHeight</li> * <li>Position is used to set the starting coordinate of the path. M is computed: * <ul> * <li>position.x * containerWidth</li> * <li>position.y * containerHeight</li> * </ul> * Center of the container <pre> position: { * mx: 0.5, * my: 0.5, * }</pre> * Upper left corner of the container * <pre> position: { * mx: 0.0, * my: 0.0, * }</pre> * </li> * </ul> * </p> * */ this.getScaledPath = function getScaledPath(pathId, param) { var rawPath = this.pathMap[pathId]; // positioning // compute the start point of the path var mx, my; if (param.abspos) { mx = param.abspos.x; my = param.abspos.y; } else { mx = param.containerWidth * param.position.mx; my = param.containerHeight * param.position.my; } var coordinates = {}; // map for the scaled coordinates if (param.position) { // path var heightRatio = (param.containerHeight / rawPath.height) * param.yScaleFactor; var widthRatio = (param.containerWidth / rawPath.width) * param.xScaleFactor; // Apply height ratio for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) { coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio; } // Apply width ratio for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) { coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio; } } // Apply value to raw path var path = format( rawPath.d, { mx: mx, my: my, e: coordinates } ); return path; }; } module.exports = PathMap; // helpers ///////////////// // copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js var tokenRegex = /\{([^}]+)\}/g, objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties function replacer(all, key, obj) { var res = obj; key.replace(objNotationRegex, function(all, name, quote, quotedName, isFunc) { name = name || quotedName; if (res) { if (name in res) { res = res[name]; } typeof res == 'function' && isFunc && (res = res()); } }); res = (res == null || res == obj ? all : res) + ''; return res; } function format(str, obj) { return String(str).replace(tokenRegex, function(all, key) { return replacer(all, key, obj); }); }