bpmn-js/lib/draw/PathMap.js

479 lines
18 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Map containing SVG paths needed by BpmnRenderer.
*/
function PathMap() {
/**
* Contains a map of path elements
*
* <h1>Path definition</h1>
* A parameterized path is defined like this:
* <pre>
* 'GATEWAY_PARALLEL': {
* d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
'-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
* 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 = {
'EVENT_MESSAGE': {
d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
height: 36,
width: 36,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'EVENT_SIGNAL': {
d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
height: 36,
width: 36,
heightElements: [18],
widthElements: [10, 20]
},
'EVENT_ESCALATION': {
d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z',
height: 36,
width: 36,
heightElements: [20, 7],
widthElements: [8]
},
'EVENT_CONDITIONAL': {
d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' +
'M {e.x2},{e.y3} l {e.x0},0 ' +
'M {e.x2},{e.y4} l {e.x0},0 ' +
'M {e.x2},{e.y5} l {e.x0},0 ' +
'M {e.x2},{e.y6} l {e.x0},0 ' +
'M {e.x2},{e.y7} l {e.x0},0 ' +
'M {e.x2},{e.y8} l {e.x0},0 ',
height: 36,
width: 36,
heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
widthElements: [10.5, 14.5, 12.5]
},
'EVENT_LINK': {
d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
height: 36,
width: 36,
heightElements: [4.4375, 6.75, 7.8125],
widthElements: [9.84375, 13.5]
},
'EVENT_ERROR': {
d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
height: 36,
width: 36,
heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
},
'EVENT_CANCEL_45': {
d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
'0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
height: 36,
width: 36,
heightElements: [4.75, 8.5],
widthElements: [4.75, 8.5]
},
'EVENT_COMPENSATION': {
d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
height: 36,
width: 36,
heightElements: [6.5, 13, 0.4, 6.1],
widthElements: [9, 9.3, 8.7]
},
'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_MULTIPLE': {
d:'m {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
height: 36,
width: 36,
heightElements: [6.28099, 12.56199],
widthElements: [3.1405, 9.42149, 12.56198]
},
'EVENT_PARALLEL_MULTIPLE': {
d:'m {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
'-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
height: 36,
width: 36,
heightElements: [2.56228, 7.68683],
widthElements: [2.56228, 7.68683]
},
'GATEWAY_EXCLUSIVE': {
d:'m {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' +
'{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' +
'{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
height: 17.5,
width: 17.5,
heightElements: [8.5, 6.5312, -6.5312, -8.5],
widthElements: [6.5, -6.5, 3, -3, 5, -5]
},
'GATEWAY_PARALLEL': {
d:'m {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
'0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
height: 30,
width: 30,
heightElements: [5, 12.5],
widthElements: [5, 12.5]
},
'GATEWAY_EVENT_BASED': {
d:'m {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
height: 11,
width: 11,
heightElements: [-6, 6, 12, -12],
widthElements: [9, -3, -12]
},
'GATEWAY_COMPLEX': {
d:'m {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' +
'{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' +
'{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' +
'-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
height: 17.125,
width: 17.125,
heightElements: [4.875, 3.4375, 2.125, 3],
widthElements: [3.4375, 2.125, 4.875, 3]
},
'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]
},
'DATA_OBJECT_COLLECTION_PATH': {
d:'m {mx}, {my} ' +
'm 0 15 l 0 -15 ' +
'm 4 15 l 0 -15 ' +
'm 4 15 l 0 -15 ',
height: 61,
width: 51,
heightElements: [12],
widthElements: [1, 6, 12, 15]
},
'DATA_ARROW': {
d:'m 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
height: 61,
width: 51,
heightElements: [],
widthElements: []
},
'DATA_STORE': {
d:'m {mx},{my} ' +
'l 0,{e.y2} ' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
'l 0,-{e.y2} ' +
'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
'm -{e.x2},{e.y0}' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' +
'm -{e.x2},{e.y0}' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0',
height: 61,
width: 61,
heightElements: [7, 10, 45],
widthElements: [2, 58, 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]
},
'MARKER_SUB_PROCESS': {
d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_PARALLEL': {
d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_SEQUENTIAL': {
d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_COMPENSATION': {
d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
height: 10,
width: 21,
heightElements: [],
widthElements: []
},
'MARKER_LOOP': {
d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' +
'-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' +
'0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' +
'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
height: 13.9,
width: 13.7,
heightElements: [],
widthElements: []
},
'MARKER_ADHOC': {
d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' +
'3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' +
'1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' +
'-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' +
'-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
height: 4,
width: 15,
heightElements: [],
widthElements: []
},
'TASK_TYPE_SEND': {
d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
height: 14,
width: 21,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'TASK_TYPE_SCRIPT': {
d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' +
'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' +
'm -7,-12 l 5,0 ' +
'm -4.5,3 l 4.5,0 ' +
'm -3,3 l 5,0' +
'm -4,3 l 5,0',
height: 15,
width: 12.6,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'TASK_TYPE_USER_1': {
d: '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'
},
'TASK_TYPE_USER_2': {
d: '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 '
},
'TASK_TYPE_USER_3': {
d: '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'
},
'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_INSTANTIATING_SEND': {
d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
},
'TASK_TYPE_SERVICE': {
d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' +
'0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' +
'-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' +
'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' +
'-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' +
'-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' +
'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' +
'-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' +
'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' +
'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' +
'0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' +
'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' +
'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
'0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
'0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
},
'TASK_TYPE_SERVICE_FILL': {
d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
'0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
'0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 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'
},
'MESSAGE_FLOW_MARKER': {
d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
}
};
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, gateways) 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);
});
}