198 lines
4.9 KiB
JavaScript
198 lines
4.9 KiB
JavaScript
|
/**
|
||
|
* Copyright (c) 2006-2015, JGraph Ltd
|
||
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
||
|
*/
|
||
|
mxCodecRegistry.register(function()
|
||
|
{
|
||
|
/**
|
||
|
* Class: mxGraphViewCodec
|
||
|
*
|
||
|
* Custom encoder for <mxGraphView>s. This class is created
|
||
|
* and registered dynamically at load time and used implicitly via
|
||
|
* <mxCodec> and the <mxCodecRegistry>. This codec only writes views
|
||
|
* into a XML format that can be used to create an image for
|
||
|
* the graph, that is, it contains absolute coordinates with
|
||
|
* computed perimeters, edge styles and cell styles.
|
||
|
*/
|
||
|
var codec = new mxObjectCodec(new mxGraphView());
|
||
|
|
||
|
/**
|
||
|
* Function: encode
|
||
|
*
|
||
|
* Encodes the given <mxGraphView> using <encodeCell>
|
||
|
* starting at the model's root. This returns the
|
||
|
* top-level graph node of the recursive encoding.
|
||
|
*/
|
||
|
codec.encode = function(enc, view)
|
||
|
{
|
||
|
return this.encodeCell(enc, view,
|
||
|
view.graph.getModel().getRoot());
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function: encodeCell
|
||
|
*
|
||
|
* Recursively encodes the specifed cell. Uses layer
|
||
|
* as the default nodename. If the cell's parent is
|
||
|
* null, then graph is used for the nodename. If
|
||
|
* <mxGraphModel.isEdge> returns true for the cell,
|
||
|
* then edge is used for the nodename, else if
|
||
|
* <mxGraphModel.isVertex> returns true for the cell,
|
||
|
* then vertex is used for the nodename.
|
||
|
*
|
||
|
* <mxGraph.getLabel> is used to create the label
|
||
|
* attribute for the cell. For graph nodes and vertices
|
||
|
* the bounds are encoded into x, y, width and height.
|
||
|
* For edges the points are encoded into a points
|
||
|
* attribute as a space-separated list of comma-separated
|
||
|
* coordinate pairs (eg. x0,y0 x1,y1 ... xn,yn). All
|
||
|
* values from the cell style are added as attribute
|
||
|
* values to the node.
|
||
|
*/
|
||
|
codec.encodeCell = function(enc, view, cell)
|
||
|
{
|
||
|
var model = view.graph.getModel();
|
||
|
var state = view.getState(cell);
|
||
|
var parent = model.getParent(cell);
|
||
|
|
||
|
if (parent == null || state != null)
|
||
|
{
|
||
|
var childCount = model.getChildCount(cell);
|
||
|
var geo = view.graph.getCellGeometry(cell);
|
||
|
var name = null;
|
||
|
|
||
|
if (parent == model.getRoot())
|
||
|
{
|
||
|
name = 'layer';
|
||
|
}
|
||
|
else if (parent == null)
|
||
|
{
|
||
|
name = 'graph';
|
||
|
}
|
||
|
else if (model.isEdge(cell))
|
||
|
{
|
||
|
name = 'edge';
|
||
|
}
|
||
|
else if (childCount > 0 && geo != null)
|
||
|
{
|
||
|
name = 'group';
|
||
|
}
|
||
|
else if (model.isVertex(cell))
|
||
|
{
|
||
|
name = 'vertex';
|
||
|
}
|
||
|
|
||
|
if (name != null)
|
||
|
{
|
||
|
var node = enc.document.createElement(name);
|
||
|
var lab = view.graph.getLabel(cell);
|
||
|
|
||
|
if (lab != null)
|
||
|
{
|
||
|
node.setAttribute('label', view.graph.getLabel(cell));
|
||
|
|
||
|
if (view.graph.isHtmlLabel(cell))
|
||
|
{
|
||
|
node.setAttribute('html', true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (parent == null)
|
||
|
{
|
||
|
var bounds = view.getGraphBounds();
|
||
|
|
||
|
if (bounds != null)
|
||
|
{
|
||
|
node.setAttribute('x', Math.round(bounds.x));
|
||
|
node.setAttribute('y', Math.round(bounds.y));
|
||
|
node.setAttribute('width', Math.round(bounds.width));
|
||
|
node.setAttribute('height', Math.round(bounds.height));
|
||
|
}
|
||
|
|
||
|
node.setAttribute('scale', view.scale);
|
||
|
}
|
||
|
else if (state != null && geo != null)
|
||
|
{
|
||
|
// Writes each key, value in the style pair to an attribute
|
||
|
for (var i in state.style)
|
||
|
{
|
||
|
var value = state.style[i];
|
||
|
|
||
|
// Tries to turn objects and functions into strings
|
||
|
if (typeof(value) == 'function' &&
|
||
|
typeof(value) == 'object')
|
||
|
{
|
||
|
value = mxStyleRegistry.getName(value);
|
||
|
}
|
||
|
|
||
|
if (value != null &&
|
||
|
typeof(value) != 'function' &&
|
||
|
typeof(value) != 'object')
|
||
|
{
|
||
|
node.setAttribute(i, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var abs = state.absolutePoints;
|
||
|
|
||
|
// Writes the list of points into one attribute
|
||
|
if (abs != null && abs.length > 0)
|
||
|
{
|
||
|
var pts = Math.round(abs[0].x) + ',' + Math.round(abs[0].y);
|
||
|
|
||
|
for (var i=1; i<abs.length; i++)
|
||
|
{
|
||
|
pts += ' ' + Math.round(abs[i].x) + ',' +
|
||
|
Math.round(abs[i].y);
|
||
|
}
|
||
|
|
||
|
node.setAttribute('points', pts);
|
||
|
}
|
||
|
|
||
|
// Writes the bounds into 4 attributes
|
||
|
else
|
||
|
{
|
||
|
node.setAttribute('x', Math.round(state.x));
|
||
|
node.setAttribute('y', Math.round(state.y));
|
||
|
node.setAttribute('width', Math.round(state.width));
|
||
|
node.setAttribute('height', Math.round(state.height));
|
||
|
}
|
||
|
|
||
|
var offset = state.absoluteOffset;
|
||
|
|
||
|
// Writes the offset into 2 attributes
|
||
|
if (offset != null)
|
||
|
{
|
||
|
if (offset.x != 0)
|
||
|
{
|
||
|
node.setAttribute('dx', Math.round(offset.x));
|
||
|
}
|
||
|
|
||
|
if (offset.y != 0)
|
||
|
{
|
||
|
node.setAttribute('dy', Math.round(offset.y));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (var i=0; i<childCount; i++)
|
||
|
{
|
||
|
var childNode = this.encodeCell(enc,
|
||
|
view, model.getChildAt(cell, i));
|
||
|
|
||
|
if (childNode != null)
|
||
|
{
|
||
|
node.appendChild(childNode);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return node;
|
||
|
};
|
||
|
|
||
|
// Returns the codec into the registry
|
||
|
return codec;
|
||
|
|
||
|
}());
|