summaryrefslogtreecommitdiff
path: root/src/js/layout/mxEdgeLabelLayout.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/layout/mxEdgeLabelLayout.js')
-rw-r--r--src/js/layout/mxEdgeLabelLayout.js165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/js/layout/mxEdgeLabelLayout.js b/src/js/layout/mxEdgeLabelLayout.js
new file mode 100644
index 0000000..2bfb3c2
--- /dev/null
+++ b/src/js/layout/mxEdgeLabelLayout.js
@@ -0,0 +1,165 @@
+/**
+ * $Id: mxEdgeLabelLayout.js,v 1.8 2010-01-04 11:18:25 gaudenz Exp $
+ * Copyright (c) 2006-2010, JGraph Ltd
+ */
+/**
+ * Class: mxEdgeLabelLayout
+ *
+ * Extends <mxGraphLayout> to implement an edge label layout. This layout
+ * makes use of cell states, which means the graph must be validated in
+ * a graph view (so that the label bounds are available) before this layout
+ * can be executed.
+ *
+ * Example:
+ *
+ * (code)
+ * var layout = new mxEdgeLabelLayout(graph);
+ * layout.execute(graph.getDefaultParent());
+ * (end)
+ *
+ * Constructor: mxEdgeLabelLayout
+ *
+ * Constructs a new edge label layout.
+ *
+ * Arguments:
+ *
+ * graph - <mxGraph> that contains the cells.
+ */
+function mxEdgeLabelLayout(graph, radius)
+{
+ mxGraphLayout.call(this, graph);
+};
+
+/**
+ * Extends mxGraphLayout.
+ */
+mxEdgeLabelLayout.prototype = new mxGraphLayout();
+mxEdgeLabelLayout.prototype.constructor = mxEdgeLabelLayout;
+
+/**
+ * Function: execute
+ *
+ * Implements <mxGraphLayout.execute>.
+ */
+mxEdgeLabelLayout.prototype.execute = function(parent)
+{
+ var view = this.graph.view;
+ var model = this.graph.getModel();
+
+ // Gets all vertices and edges inside the parent
+ var edges = [];
+ var vertices = [];
+ var childCount = model.getChildCount(parent);
+
+ for (var i = 0; i < childCount; i++)
+ {
+ var cell = model.getChildAt(parent, i);
+ var state = view.getState(cell);
+
+ if (state != null)
+ {
+ if (!this.isVertexIgnored(cell))
+ {
+ vertices.push(state);
+ }
+ else if (!this.isEdgeIgnored(cell))
+ {
+ edges.push(state);
+ }
+ }
+ }
+
+ this.placeLabels(vertices, edges);
+};
+
+/**
+ * Function: placeLabels
+ *
+ * Places the labels of the given edges.
+ */
+mxEdgeLabelLayout.prototype.placeLabels = function(v, e)
+{
+ var model = this.graph.getModel();
+
+ // Moves the vertices to build a circle. Makes sure the
+ // radius is large enough for the vertices to not
+ // overlap
+ model.beginUpdate();
+ try
+ {
+ for (var i = 0; i < e.length; i++)
+ {
+ var edge = e[i];
+
+ if (edge != null && edge.text != null &&
+ edge.text.boundingBox != null)
+ {
+ for (var j = 0; j < v.length; j++)
+ {
+ var vertex = v[j];
+
+ if (vertex != null)
+ {
+ this.avoid(edge, vertex);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ model.endUpdate();
+ }
+};
+
+/**
+ * Function: avoid
+ *
+ * Places the labels of the given edges.
+ */
+mxEdgeLabelLayout.prototype.avoid = function(edge, vertex)
+{
+ var model = this.graph.getModel();
+ var labRect = edge.text.boundingBox;
+
+ if (mxUtils.intersects(labRect, vertex))
+ {
+ var dy1 = -labRect.y - labRect.height + vertex.y;
+ var dy2 = -labRect.y + vertex.y + vertex.height;
+
+ var dy = (Math.abs(dy1) < Math.abs(dy2)) ? dy1 : dy2;
+
+ var dx1 = -labRect.x - labRect.width + vertex.x;
+ var dx2 = -labRect.x + vertex.x + vertex.width;
+
+ var dx = (Math.abs(dx1) < Math.abs(dx2)) ? dx1 : dx2;
+
+ if (Math.abs(dx) < Math.abs(dy))
+ {
+ dy = 0;
+ }
+ else
+ {
+ dx = 0;
+ }
+
+ var g = model.getGeometry(edge.cell);
+
+ if (g != null)
+ {
+ g = g.clone();
+
+ if (g.offset != null)
+ {
+ g.offset.x += dx;
+ g.offset.y += dy;
+ }
+ else
+ {
+ g.offset = new mxPoint(dx, dy);
+ }
+
+ model.setGeometry(edge.cell, g);
+ }
+ }
+};