mxPartitionLayout.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxPartitionLayout
  7. *
  8. * Extends <mxGraphLayout> for partitioning the parent cell vertically or
  9. * horizontally by filling the complete area with the child cells. A horizontal
  10. * layout partitions the height of the given parent whereas a a non-horizontal
  11. * layout partitions the width. If the parent is a layer (that is, a child of
  12. * the root node), then the current graph size is partitioned. The children do
  13. * not need to be connected for this layout to work.
  14. *
  15. * Example:
  16. *
  17. * (code)
  18. * var layout = new mxPartitionLayout(graph, true, 10, 20);
  19. * layout.execute(graph.getDefaultParent());
  20. * (end)
  21. *
  22. * Constructor: mxPartitionLayout
  23. *
  24. * Constructs a new stack layout layout for the specified graph,
  25. * spacing, orientation and offset.
  26. */
  27. function mxPartitionLayout(graph, horizontal, spacing, border)
  28. {
  29. mxGraphLayout.call(this, graph);
  30. this.horizontal = (horizontal != null) ? horizontal : true;
  31. this.spacing = spacing || 0;
  32. this.border = border || 0;
  33. };
  34. /**
  35. * Extends mxGraphLayout.
  36. */
  37. mxPartitionLayout.prototype = new mxGraphLayout();
  38. mxPartitionLayout.prototype.constructor = mxPartitionLayout;
  39. /**
  40. * Variable: horizontal
  41. *
  42. * Boolean indicating the direction in which the space is partitioned.
  43. * Default is true.
  44. */
  45. mxPartitionLayout.prototype.horizontal = null;
  46. /**
  47. * Variable: spacing
  48. *
  49. * Integer that specifies the absolute spacing in pixels between the
  50. * children. Default is 0.
  51. */
  52. mxPartitionLayout.prototype.spacing = null;
  53. /**
  54. * Variable: border
  55. *
  56. * Integer that specifies the absolute inset in pixels for the parent that
  57. * contains the children. Default is 0.
  58. */
  59. mxPartitionLayout.prototype.border = null;
  60. /**
  61. * Variable: resizeVertices
  62. *
  63. * Boolean that specifies if vertices should be resized. Default is true.
  64. */
  65. mxPartitionLayout.prototype.resizeVertices = true;
  66. /**
  67. * Function: isHorizontal
  68. *
  69. * Returns <horizontal>.
  70. */
  71. mxPartitionLayout.prototype.isHorizontal = function()
  72. {
  73. return this.horizontal;
  74. };
  75. /**
  76. * Function: moveCell
  77. *
  78. * Implements <mxGraphLayout.moveCell>.
  79. */
  80. mxPartitionLayout.prototype.moveCell = function(cell, x, y)
  81. {
  82. var model = this.graph.getModel();
  83. var parent = model.getParent(cell);
  84. if (cell != null &&
  85. parent != null)
  86. {
  87. var i = 0;
  88. var last = 0;
  89. var childCount = model.getChildCount(parent);
  90. // Finds index of the closest swimlane
  91. // TODO: Take into account the orientation
  92. for (i = 0; i < childCount; i++)
  93. {
  94. var child = model.getChildAt(parent, i);
  95. var bounds = this.getVertexBounds(child);
  96. if (bounds != null)
  97. {
  98. var tmp = bounds.x + bounds.width / 2;
  99. if (last < x && tmp > x)
  100. {
  101. break;
  102. }
  103. last = tmp;
  104. }
  105. }
  106. // Changes child order in parent
  107. var idx = parent.getIndex(cell);
  108. idx = Math.max(0, i - ((i > idx) ? 1 : 0));
  109. model.add(parent, cell, idx);
  110. }
  111. };
  112. /**
  113. * Function: execute
  114. *
  115. * Implements <mxGraphLayout.execute>. All children where <isVertexIgnored>
  116. * returns false and <isVertexMovable> returns true are modified.
  117. */
  118. mxPartitionLayout.prototype.execute = function(parent)
  119. {
  120. var horizontal = this.isHorizontal();
  121. var model = this.graph.getModel();
  122. var pgeo = model.getGeometry(parent);
  123. // Handles special case where the parent is either a layer with no
  124. // geometry or the current root of the view in which case the size
  125. // of the graph's container will be used.
  126. if (this.graph.container != null &&
  127. ((pgeo == null &&
  128. model.isLayer(parent)) ||
  129. parent == this.graph.getView().currentRoot))
  130. {
  131. var width = this.graph.container.offsetWidth - 1;
  132. var height = this.graph.container.offsetHeight - 1;
  133. pgeo = new mxRectangle(0, 0, width, height);
  134. }
  135. if (pgeo != null)
  136. {
  137. var children = [];
  138. var childCount = model.getChildCount(parent);
  139. for (var i = 0; i < childCount; i++)
  140. {
  141. var child = model.getChildAt(parent, i);
  142. if (!this.isVertexIgnored(child) &&
  143. this.isVertexMovable(child))
  144. {
  145. children.push(child);
  146. }
  147. }
  148. var n = children.length;
  149. if (n > 0)
  150. {
  151. var x0 = this.border;
  152. var y0 = this.border;
  153. var other = (horizontal) ? pgeo.height : pgeo.width;
  154. other -= 2 * this.border;
  155. var size = (this.graph.isSwimlane(parent)) ?
  156. this.graph.getStartSize(parent) :
  157. new mxRectangle();
  158. other -= (horizontal) ? size.height : size.width;
  159. x0 = x0 + size.width;
  160. y0 = y0 + size.height;
  161. var tmp = this.border + (n - 1) * this.spacing;
  162. var value = (horizontal) ?
  163. ((pgeo.width - x0 - tmp) / n) :
  164. ((pgeo.height - y0 - tmp) / n);
  165. // Avoids negative values, that is values where the sum of the
  166. // spacing plus the border is larger then the available space
  167. if (value > 0)
  168. {
  169. model.beginUpdate();
  170. try
  171. {
  172. for (var i = 0; i < n; i++)
  173. {
  174. var child = children[i];
  175. var geo = model.getGeometry(child);
  176. if (geo != null)
  177. {
  178. geo = geo.clone();
  179. geo.x = x0;
  180. geo.y = y0;
  181. if (horizontal)
  182. {
  183. if (this.resizeVertices)
  184. {
  185. geo.width = value;
  186. geo.height = other;
  187. }
  188. x0 += value + this.spacing;
  189. }
  190. else
  191. {
  192. if (this.resizeVertices)
  193. {
  194. geo.height = value;
  195. geo.width = other;
  196. }
  197. y0 += value + this.spacing;
  198. }
  199. model.setGeometry(child, geo);
  200. }
  201. }
  202. }
  203. finally
  204. {
  205. model.endUpdate();
  206. }
  207. }
  208. }
  209. }
  210. };
  211. __mxOutput.mxPartitionLayout = typeof mxPartitionLayout !== 'undefined' ? mxPartitionLayout : undefined;