OutlineProvider.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { assign } from 'min-dash';
  2. import {
  3. attr as svgAttr,
  4. create as svgCreate
  5. } from 'tiny-svg';
  6. import {
  7. is,
  8. isAny
  9. } from '../../util/ModelUtil';
  10. import { isLabel } from '../../util/LabelUtil';
  11. import {
  12. DATA_OBJECT_REFERENCE_OUTLINE_PATH,
  13. DATA_STORE_REFERENCE_OUTLINE_PATH,
  14. DATA_OBJECT_REFERENCE_STANDARD_SIZE,
  15. DATA_STORE_REFERENCE_STANDARD_SIZE,
  16. createPath
  17. } from './OutlineUtil';
  18. const DEFAULT_OFFSET = 5;
  19. /**
  20. * BPMN-specific outline provider.
  21. *
  22. * @implements {BaseOutlineProvider}
  23. *
  24. * @param {Outline} outline
  25. * @param {Styles} styles
  26. */
  27. export default function OutlineProvider(outline, styles) {
  28. this._styles = styles;
  29. outline.registerProvider(this);
  30. }
  31. OutlineProvider.$inject = [
  32. 'outline',
  33. 'styles'
  34. ];
  35. /**
  36. * Returns outline for a given element.
  37. *
  38. * @param {Element} element
  39. *
  40. * @return {Outline}
  41. */
  42. OutlineProvider.prototype.getOutline = function(element) {
  43. const OUTLINE_STYLE = this._styles.cls('djs-outline', [ 'no-fill' ]);
  44. var outline;
  45. if (isLabel(element)) {
  46. return;
  47. }
  48. if (is(element, 'bpmn:Gateway')) {
  49. outline = svgCreate('rect');
  50. assign(outline.style, {
  51. 'transform-box': 'fill-box',
  52. 'transform': 'rotate(45deg)',
  53. 'transform-origin': 'center'
  54. });
  55. svgAttr(outline, assign({
  56. x: 2,
  57. y: 2,
  58. rx: 4,
  59. width: element.width - 4,
  60. height: element.height - 4,
  61. }, OUTLINE_STYLE));
  62. } else if (isAny(element, [ 'bpmn:Task', 'bpmn:SubProcess', 'bpmn:Group' ])) {
  63. outline = svgCreate('rect');
  64. svgAttr(outline, assign({
  65. x: -DEFAULT_OFFSET,
  66. y: -DEFAULT_OFFSET,
  67. rx: 14,
  68. width: element.width + DEFAULT_OFFSET * 2,
  69. height: element.height + DEFAULT_OFFSET * 2
  70. }, OUTLINE_STYLE));
  71. } else if (is(element, 'bpmn:EndEvent')) {
  72. outline = svgCreate('circle');
  73. // Extra 1px offset needed due to increased stroke-width of end event
  74. // which makes it bigger than other events.
  75. svgAttr(outline, assign({
  76. cx: element.width / 2,
  77. cy: element.height / 2,
  78. r: element.width / 2 + DEFAULT_OFFSET + 1
  79. }, OUTLINE_STYLE));
  80. } else if (is(element, 'bpmn:Event')) {
  81. outline = svgCreate('circle');
  82. svgAttr(outline, assign({
  83. cx: element.width / 2,
  84. cy: element.height / 2,
  85. r: element.width / 2 + DEFAULT_OFFSET
  86. }, OUTLINE_STYLE));
  87. } else if (is(element, 'bpmn:DataObjectReference') && isStandardSize(element, 'bpmn:DataObjectReference')) {
  88. outline = createPath(
  89. DATA_OBJECT_REFERENCE_OUTLINE_PATH,
  90. { x: -6, y: -6 },
  91. OUTLINE_STYLE
  92. );
  93. } else if (is(element, 'bpmn:DataStoreReference') && isStandardSize(element, 'bpmn:DataStoreReference')) {
  94. outline = createPath(
  95. DATA_STORE_REFERENCE_OUTLINE_PATH,
  96. { x: -6, y: -6 },
  97. OUTLINE_STYLE
  98. );
  99. }
  100. return outline;
  101. };
  102. /**
  103. * Updates the outline for a given element.
  104. * Returns true if the update for the given element was handled by this provider.
  105. *
  106. * @param {Element} element
  107. * @param {Outline} outline
  108. * @returns {boolean}
  109. */
  110. OutlineProvider.prototype.updateOutline = function(element, outline) {
  111. if (isLabel(element)) {
  112. return;
  113. }
  114. if (isAny(element, [ 'bpmn:SubProcess', 'bpmn:Group' ])) {
  115. svgAttr(outline, {
  116. width: element.width + DEFAULT_OFFSET * 2,
  117. height: element.height + DEFAULT_OFFSET * 2
  118. });
  119. return true;
  120. } else if (isAny(element, [
  121. 'bpmn:Event',
  122. 'bpmn:Gateway',
  123. 'bpmn:DataStoreReference',
  124. 'bpmn:DataObjectReference'
  125. ])) {
  126. return true;
  127. }
  128. return false;
  129. };
  130. // helpers //////////
  131. function isStandardSize(element, type) {
  132. var standardSize;
  133. if (type === 'bpmn:DataObjectReference') {
  134. standardSize = DATA_OBJECT_REFERENCE_STANDARD_SIZE;
  135. } else if (type === 'bpmn:DataStoreReference') {
  136. standardSize = DATA_STORE_REFERENCE_STANDARD_SIZE;
  137. }
  138. return element.width === standardSize.width
  139. && element.height === standardSize.height;
  140. }