blob: c3023ded515753a145e78b8e4df7adae058a7c61 [file] [log] [blame]
/**
* 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 implicitely 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;
}());