blob: bfba27ec2249c5f5b97eb51a81bd81ce4c1e8141 [file] [log] [blame]
/**
* Copyright (c) 2006-2015, JGraph Ltd
* Copyright (c) 2006-2015, Gaudenz Alder
*/
/**
* 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);
}
}
};