/**
* Export mxFile as Vsdx file
*/
function VsdxExport(editorUi)
{
var that = this;
var vsdxCanvas = new mxVsdxCanvas2D();
var idsMap = {};
var idsCounter = 1;
/**
* Fill the required files in vsdx format which are constants in our exporter
* @param zip JSZip of vsdx file
* @param pageCount The number of pages in the mxFile
*/
function createVsdxSkeleton(zip, pageCount)
{
var files = {
"[Content_Types].xml": "",
"_rels/.rels" : "",
"docProps/app.xml" : "Microsoft Visio15.0000",
"docProps/core.xml" : "en-US",
"docProps/custom.xml" : "",
"visio/document.xml": "9658473410000 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ",
"visio/windows.xml" : "",
"visio/_rels/document.xml.rels" : "",
"visio/masters/_rels/masters.xml.rels" : '',
"visio/masters/masters.xml" : " | | | | | | | | | | | | | | | | ",
"visio/masters/master1.xml" : " | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "
};
for (var id in files)
{
if (pageCount > 1 && id == that.CONTENT_TYPES_XML)
{
//Add the remaining pages
var doc = mxUtils.parseXml(files[id]);
var root = doc.documentElement;
var children = root.children;
var page1 = null;
for (var i = 0; i < children.length; i++)
{
var child = children[i];
if ("/visio/pages/page1.xml" == child.getAttribute(that.PART_NAME))
{
page1 = child;
}
}
for (var i = 2; i <= pageCount; i++)
{
var newPage = page1.cloneNode();
newPage.setAttribute(that.PART_NAME, "/visio/pages/page" + i + ".xml");
root.appendChild(newPage);
}
writeXmlDoc2Zip(zip, id, doc, true);
}
else
{
zip.file(id, files[id]);
}
}
};
function createElt(doc, ns, name)
{
return (doc.createElementNS != null) ? doc.createElementNS(ns, name) : doc.createElement(name);
};
function getCellVsdxId(cellId)
{
var vsdxId = idsMap[cellId];
if (vsdxId == null)
{
vsdxId = idsCounter++;
idsMap[cellId] = vsdxId;
}
return vsdxId;
};
function getGraphAttributes(graph)
{
var attr = {};
try
{
//This doesn't work when pageView is off
// // Computes the horizontal and vertical page count
// var bounds = graph.getGraphBounds();
// var sc = graph.view.scale;
// var bgBounds = graph.view.getBackgroundPageBounds();
//
// var x0 = Math.round((bounds.x - bgBounds.x) / sc);
// var y0 = Math.round((bounds.y - bgBounds.y) / sc);
//
// var hpages = Math.max(1, Math.ceil((bounds.width / sc + x0) / graph.pageFormat.width));
// var vpages = Math.max(1, Math.ceil((bounds.height / sc + y0) / graph.pageFormat.height));
// Computes the horizontal and vertical page count
var bounds = graph.getGraphBounds().clone();
var sc = graph.view.scale;
var tr = graph.view.translate;
var x0 = Math.round(bounds.x / sc) - tr.x;
var y0 = Math.round(bounds.y / sc) - tr.y;
// Store the available page area
var availableWidth = graph.pageFormat.width;
var availableHeight = graph.pageFormat.height;
if (x0 < 0)
{
x0 += Math.ceil((tr.x - bounds.x / sc) / availableWidth) * availableWidth;
}
if (y0 < 0)
{
y0 += Math.ceil((tr.y - bounds.y / sc) / availableHeight) * availableHeight;
}
var hpages = Math.max(1, Math.ceil((bounds.width / sc + x0) / availableWidth));
var vpages = Math.max(1, Math.ceil((bounds.height / sc + y0) / availableHeight));
attr['gridEnabled'] = graph.gridEnabled;
attr['gridSize'] = graph.gridSize;
attr['guidesEnabled'] = graph.graphHandler.guidesEnabled
attr['pageVisible'] = graph.pageVisible;
attr['pageScale'] = graph.pageScale;
attr['pageWidth'] = graph.pageFormat.width * hpages;
attr['pageHeight'] = graph.pageFormat.height * vpages;
attr['backgroundClr'] = graph.background;
attr['mathEnabled'] = graph.mathEnabled;
attr['shadowVisible'] = graph.shadowVisible;
}
catch(e)
{
//nothing
}
return attr;
};
function createCellElemScaled(name, val, xmlDoc, formula)
{
return createCellElem(name, val / that.CONVERSION_FACTOR, xmlDoc, formula);
};
function createCellElem(name, val, xmlDoc, formula)
{
var cell = createElt(xmlDoc, that.XMLNS, "Cell");
cell.setAttribute("N", name);
cell.setAttribute("V", val);
if (formula) cell.setAttribute("F", formula);
return cell;
};
function createRow(type, index, x, y, xmlDoc)
{
var row = createElt(xmlDoc, that.XMLNS, "Row");
row.setAttribute("T", type);
row.setAttribute("IX", index);
row.appendChild(createCellElemScaled("X", x, xmlDoc));
row.appendChild(createCellElemScaled("Y", y, xmlDoc));
return row;
};
function applyMxCellStyle(state, shape, xmlDoc)
{
var fillClr = state.style[mxConstants.STYLE_FILLCOLOR];
if (!fillClr || fillClr == "none")
{
shape.appendChild(createCellElem("FillPattern", 0, xmlDoc));
}
else
{
shape.appendChild(createCellElem("FillForegnd", fillClr, xmlDoc));
var gradClr = state.style[mxConstants.STYLE_GRADIENTCOLOR];
if (gradClr && gradClr != "none")
{
shape.appendChild(createCellElem("FillBkgnd", gradClr, xmlDoc));
var gradDir = state.style[mxConstants.STYLE_GRADIENT_DIRECTION];
var dir = 28;
if (gradDir)
{
switch(gradDir)
{
case mxConstants.DIRECTION_EAST:
dir = 25;
break
case mxConstants.DIRECTION_WEST:
dir = 27;
break
case mxConstants.DIRECTION_NORTH:
dir = 30;
break
}
}
shape.appendChild(createCellElem("FillPattern", dir, xmlDoc));
}
}
var strokeClr = state.style[mxConstants.STYLE_STROKECOLOR];
if (!strokeClr || strokeClr == "none")
shape.appendChild(createCellElem("LinePattern", 0, xmlDoc));
else
shape.appendChild(createCellElem("LineColor", strokeClr, xmlDoc));
var strokeW = state.style[mxConstants.STYLE_STROKEWIDTH];
if (strokeW) shape.appendChild(createCellElemScaled("LineWeight", strokeW, xmlDoc));
var opacity = state.style[mxConstants.STYLE_OPACITY];
var fillOpaq;
var strkOpaq;
if (opacity)
{
fillOpaq = opacity;
strkOpaq = opacity;
}
else
{
fillOpaq = state.style[mxConstants.STYLE_FILL_OPACITY];
strkOpaq = state.style[mxConstants.STYLE_STROKE_OPACITY];
}
if (fillOpaq) shape.appendChild(createCellElem("FillForegndTrans", 1 - parseInt(fillOpaq)/100.0, xmlDoc));
if (strkOpaq) shape.appendChild(createCellElem("LineColorTrans", 1 - parseInt(strkOpaq)/100.0, xmlDoc));
var isDashed = state.style[mxConstants.STYLE_DASHED];
if (isDashed == 1)
{
var dashPatrn = state.style[mxConstants.STYLE_DASH_PATTERN];
var pattern = 9
if (dashPatrn)
{
//We only support the patterns of draw.io UI
switch(dashPatrn)
{
case "1 1":
pattern = 10;
break;
case "1 2":
pattern = 3;
break;
case "1 4":
pattern = 17;
break;
}
}
shape.appendChild(createCellElem("LinePattern", pattern, xmlDoc));
}
var hasShadow = state.style[mxConstants.STYLE_SHADOW];
if (hasShadow == 1)
{
shape.appendChild(createCellElem("ShdwPattern", 1, xmlDoc));
shape.appendChild(createCellElem("ShdwForegnd", '#000000', xmlDoc));
shape.appendChild(createCellElem("ShdwForegndTrans", 0.6, xmlDoc));
shape.appendChild(createCellElem("ShapeShdwType", 1, xmlDoc));
shape.appendChild(createCellElem("ShapeShdwOffsetX", '0.02946278254943948', xmlDoc));
shape.appendChild(createCellElem("ShapeShdwOffsetY", '-0.02946278254943948', xmlDoc));
shape.appendChild(createCellElem("ShapeShdwScaleFactor", '1', xmlDoc));
shape.appendChild(createCellElem("ShapeShdwBlur", '0.05555555555555555', xmlDoc));
shape.appendChild(createCellElem("ShapeShdwShow", 2, xmlDoc));
}
//Probably we don't need margins as the canvas get the modified position?
/*
var topMargin = state.style[mxConstants.STYLE_SPACING_TOP];
if (topMargin) shape.appendChild(createCellElemScaled("TopMargin", parseFloat(topMargin) * 2 + 2.8 , xmlDoc));
/* //Defines label bottom spacing
double bottomMargin = getBottomSpacing() * 100/100;
if (bottomMargin != 0)
{
styleMap.put(mxConstants.STYLE_SPACING_BOTTOM, Double.toString(bottomMargin));
}
//Defines label left spacing
double leftMargin = getLeftSpacing() * 100/100;
if (leftMargin != 0)
{
styleMap.put(mxConstants.STYLE_SPACING_LEFT, Double.toString(leftMargin));
}
//Defines label right spacing
double rightMargin = getRightSpacing() * 100/100;
if(rightMargin !=0)
{
styleMap.put(mxConstants.STYLE_SPACING_RIGHT, Double.toString(rightMargin));
}*/
//Direction is not clear that we need it
/*
var direction = state.style[mxConstants.STYLE_DIRECTION];
if (direction != mxConstants.DIRECTION_EAST)
{
styleMap.put(mxConstants.STYLE_DIRECTION, direction);
}
*/
var flibX = state.style[mxConstants.STYLE_FLIPH];
if (flibX == 1) shape.appendChild(createCellElem("FlipX", 1, xmlDoc));
var flibY = state.style[mxConstants.STYLE_FLIPV];
if (flibY == 1) shape.appendChild(createCellElem("FlipY", 1, xmlDoc));
var rounded = state.style[mxConstants.STYLE_ROUNDED];
if (rounded == 1) shape.appendChild(createCellElemScaled("Rounding", state.cell.geometry.width*0.1, xmlDoc));
//TODO for some reason, visio doesn't show the label (text) background color!
//May be we need mxSvgCanvas2D.prototype.addTextBackground = function(node, str, x, y, w, h, align, valign, overflow)
var lbkgnd = state.style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR];
if (lbkgnd) shape.appendChild(createCellElem("TextBkgnd", lbkgnd, xmlDoc));
};
function createShape(id, geo, layerIndex, xmlDoc, parentHeight, isChild)
{
var shape = createElt(xmlDoc, that.XMLNS, "Shape");
shape.setAttribute("ID", id);
shape.setAttribute("NameU", "Shape" + id);
shape.setAttribute("LineStyle", "0");
shape.setAttribute("FillStyle", "0");
shape.setAttribute("TextStyle", "0");
var hw = geo.width/2, hh = geo.height/2;
shape.appendChild(createCellElemScaled("PinX", geo.x + hw + (isChild? 0 : vsdxCanvas.shiftX), xmlDoc));
shape.appendChild(createCellElemScaled("PinY", parentHeight - geo.y - hh - (isChild? 0 : vsdxCanvas.shiftY), xmlDoc));
shape.appendChild(createCellElemScaled("Width", geo.width, xmlDoc));
shape.appendChild(createCellElemScaled("Height", geo.height, xmlDoc));
shape.appendChild(createCellElemScaled("LocPinX", hw, xmlDoc));
shape.appendChild(createCellElemScaled("LocPinY", hh, xmlDoc));
shape.appendChild(createCellElem("LayerMember", layerIndex + "", xmlDoc));
return shape;
};
function getArrowType(arrow, isFilled)
{
isFilled = isFilled == null? "1" : isFilled;
arrow = arrow == null? "none" : arrow;
var key = arrow + "|" + isFilled;
var type = that.ARROWS_MAP[key];
if (type != null)
return type;
else
return 1;
};
function getArrowSize(size)
{
if (size == null) return 2;
if (size <=2)
return 0;
else if (size <= 3)
return 1;
else if (size <= 5)
return 2;
else if (size <= 7)
return 3;
else if (size <= 9)
return 4;
else if (size <= 22)
return 5;
else
return 6;
};
function createEdge(cell, layerIndex, graph, xmlDoc, parentHeight, isChild)
{
var state = graph.view.getState(cell, true);
if (state == null || state.absolutePoints == null || state.cellBounds == null)
{
return null;
}
var shape = createElt(xmlDoc, that.XMLNS, "Shape");
var vsdxId = getCellVsdxId(cell.id);
shape.setAttribute("ID", vsdxId);
shape.setAttribute("NameU", "Dynamic connector." + vsdxId);
shape.setAttribute("Name", "Dynamic connector." + vsdxId);
shape.setAttribute("Type", "Shape");
shape.setAttribute("Master", "4"); //Dynamic Connector Master
var s = vsdxCanvas.state;
var points = state.absolutePoints;
var bounds = state.cellBounds;
var hw = bounds.width/2, hh = bounds.height/2;
shape.appendChild(createCellElemScaled("PinX", bounds.x + hw + (isChild? 0 : vsdxCanvas.shiftX), xmlDoc));
shape.appendChild(createCellElemScaled("PinY", parentHeight - bounds.y - hh - (isChild? 0 : vsdxCanvas.shiftY), xmlDoc));
shape.appendChild(createCellElemScaled("Width", bounds.width, xmlDoc));
shape.appendChild(createCellElemScaled("Height", bounds.height, xmlDoc));
shape.appendChild(createCellElemScaled("LocPinX", hw, xmlDoc));
shape.appendChild(createCellElemScaled("LocPinY", hh, xmlDoc));
vsdxCanvas.newEdge(shape, state, xmlDoc);
var calcVsdxPoint = function(p, noHeight, withoutShift)
{
var x = p.x, y = p.y;
x = x * s.scale - bounds.x + s.dx + (withoutShift || isChild? 0 : vsdxCanvas.shiftX);
y = (noHeight? 0 : bounds.height) - y * s.scale + bounds.y - s.dy - (withoutShift || isChild? 0 : vsdxCanvas.shiftY);
return {x: x, y: y};
};
var p0 = calcVsdxPoint(points[0], true);
//Formula is used to make the edge dynamic
shape.appendChild(createCellElemScaled("BeginX", bounds.x + p0.x, xmlDoc, "_WALKGLUE(BegTrigger,EndTrigger,WalkPreference)"));
shape.appendChild(createCellElemScaled("BeginY", parentHeight - bounds.y + p0.y, xmlDoc, "_WALKGLUE(BegTrigger,EndTrigger,WalkPreference)"));
var pe = calcVsdxPoint(points[points.length - 1], true);
//Formula is used to make the edge dynamic
shape.appendChild(createCellElemScaled("EndX", bounds.x + pe.x, xmlDoc, "_WALKGLUE(EndTrigger,BegTrigger,WalkPreference)"));
shape.appendChild(createCellElemScaled("EndY", parentHeight - bounds.y + pe.y, xmlDoc, "_WALKGLUE(EndTrigger,BegTrigger,WalkPreference)"));
//Formula is used to make the edge dynamic (specify source id and target id)
shape.appendChild(createCellElem("BegTrigger", "2", xmlDoc, cell.source? "_XFTRIGGER(Sheet."+ getCellVsdxId(cell.source.id) +"!EventXFMod)" : null));
shape.appendChild(createCellElem("EndTrigger", "2", xmlDoc, cell.target? "_XFTRIGGER(Sheet."+ getCellVsdxId(cell.target.id) +"!EventXFMod)" : null));
shape.appendChild(createCellElem("ConFixedCode", "6", xmlDoc));
shape.appendChild(createCellElem("LayerMember", layerIndex + "", xmlDoc));
applyMxCellStyle(state, shape, xmlDoc);
//Edge special styles
var startFill = state.style[mxConstants.STYLE_STARTFILL];
var startArrow = state.style[mxConstants.STYLE_STARTARROW];
var startSize = state.style[mxConstants.STYLE_STARTSIZE];
var type = getArrowType(startArrow, startFill);
shape.appendChild(createCellElem("BeginArrow", type, xmlDoc));
shape.appendChild(createCellElem("BeginArrowSize", getArrowSize(startSize), xmlDoc));
var endFill = state.style[mxConstants.STYLE_ENDFILL];
var endArrow = state.style[mxConstants.STYLE_ENDARROW];
var endSize = state.style[mxConstants.STYLE_ENDSIZE];
var type = getArrowType(endArrow, endFill);
shape.appendChild(createCellElem("EndArrow", type, xmlDoc));
shape.appendChild(createCellElem("EndArrowSize", getArrowSize(endSize), xmlDoc));
//Draw text first to have its shape cell elements before visio geo.
if (state.text != null && state.text.checkBounds())
{
vsdxCanvas.save();
state.text.paint(vsdxCanvas);
vsdxCanvas.restore();
}
var geoSec = createElt(xmlDoc, that.XMLNS, "Section");
geoSec.setAttribute("N", "Geometry");
geoSec.setAttribute("IX", "0");
for (var i = 0; i < points.length; i++)
{
var p = calcVsdxPoint(points[i], false, true);
geoSec.appendChild(createRow(i==0 ? "MoveTo" : "LineTo", (i + 1), p.x, p.y, xmlDoc));
}
geoSec.appendChild(createCellElem("NoFill", "1", xmlDoc));
geoSec.appendChild(createCellElem("NoLine", "0", xmlDoc));
shape.appendChild(geoSec);
return shape;
};
function convertMxCell2Shape(cell, layerIndex, graph, xmlDoc, parentHeight, parentGeo, isChild)
{
var geo = cell.geometry, origGeo = geo;
if (geo != null)
{
try
{
//fix relative geo coordinates
if (geo.relative && parentGeo)
{
origGeo = geo.clone();
geo.x *= parentGeo.width;
geo.y *= parentGeo.height;
if (cell.vertex && geo.offset != null)
{
geo.x += geo.offset.x;
geo.y += geo.offset.y;
}
geo.relative = 0;
}
var vsdxId = getCellVsdxId(cell.id);
if (!cell.treatAsSingle && cell.getChildCount() > 0) //Group
{
//Create group shape as an empty shape with no geo
var shape = createShape(vsdxId + "10000", geo, layerIndex, xmlDoc, parentHeight, isChild);
shape.setAttribute("Type", "Group");
//Create group shape
var gShapes = createElt(xmlDoc, that.XMLNS, "Shapes");
//translate the canvas using the group coordinates
vsdxCanvas.save();
vsdxCanvas.translate(-geo.x, -geo.y);
//Draw the actual group shape as a child (so change its geo coord to 0,0).
// In mxGraph group shape can have styles and stencil
var newGeo = geo.clone();
newGeo.x = 0;
newGeo.y = 0;
cell.setGeometry(newGeo);
cell.treatAsSingle = true;
var subShape = convertMxCell2Shape(cell, layerIndex, graph, xmlDoc, geo.height, geo, true);
delete cell.treatAsSingle;
cell.setGeometry(geo);
if (subShape != null)
{
gShapes.appendChild(subShape);
}
//add group children
for (var i = 0; i < cell.getChildCount(); i++)
{
var child = cell.children[i];
var subShape = convertMxCell2Shape(child, layerIndex, graph, xmlDoc, geo.height, geo, true);
if (subShape != null)
{
gShapes.appendChild(subShape);
}
}
shape.appendChild(gShapes);
//restore the canvas to before group translation
vsdxCanvas.restore();
return shape;
}
else if (cell.vertex)
{
var shape = createShape(vsdxId, geo, layerIndex, xmlDoc, parentHeight, isChild);
var state = graph.view.getState(cell, true);
applyMxCellStyle(state, shape, xmlDoc);
vsdxCanvas.newShape(shape, state, xmlDoc);
//Draw text first to have its shape cell elements before visio geo.
if (state.text != null && state.text.checkBounds())
{
vsdxCanvas.save();
state.text.paint(vsdxCanvas);
vsdxCanvas.restore();
}
if (state.shape != null && state.shape.checkBounds())
{
vsdxCanvas.save();
state.shape.paint(vsdxCanvas);
vsdxCanvas.restore();
}
shape.appendChild(vsdxCanvas.getShapeGeo());
vsdxCanvas.endShape();
shape.setAttribute("Type", vsdxCanvas.getShapeType());
return shape;
}
else
{
return createEdge(cell, layerIndex, graph, xmlDoc, parentHeight, isChild);
}
}
finally
{
cell.geometry = origGeo;
}
}
else
{
return null;
}
};
function convertMxModel2Page(graph, modelAttrib)
{
var xmlDoc = mxUtils.createXmlDocument();
var root = createElt(xmlDoc, that.XMLNS, "PageContents");
root.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', that.XMLNS);
root.setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:r", that.XMLNS_R);
var shapes = createElt(xmlDoc, that.XMLNS, "Shapes");
root.appendChild(shapes);
var model = graph.model;
var t = graph.view.translate;
var s = graph.view.scale;
var bounds = graph.getGraphBounds();
vsdxCanvas.shiftX = 0; vsdxCanvas.shiftY = 0;
//-ve pages
if (bounds.x / s < t.x || bounds.y / s < t.y)
{
vsdxCanvas.shiftX = Math.ceil((t.x - bounds.x / s) / graph.pageFormat.width) * graph.pageFormat.width;
vsdxCanvas.shiftY = Math.ceil((t.y - bounds.y / s) / graph.pageFormat.height) * graph.pageFormat.height;
}
vsdxCanvas.save();
vsdxCanvas.translate(-t.x, -t.y);
vsdxCanvas.scale(1 / s);
vsdxCanvas.newPage();
var layers = graph.model.getChildCells(graph.model.root);
var layerIdsMaps = {};
for (var k = 0; k < layers.length; k++)
{
layerIdsMaps[layers[k].id] = k;
}
for (var id in model.cells)
{
var cell = model.cells[id];
//top-most cells
var layerIndex = cell.parent != null? layerIdsMaps[cell.parent.id] : null;
if (layerIndex != null)
{
var shape = convertMxCell2Shape(cell, layerIndex, graph, xmlDoc, modelAttrib.pageHeight);
if (shape != null)
shapes.appendChild(shape);
}
}
var connects = createElt(xmlDoc, that.XMLNS, "Connects");
root.appendChild(connects);
//Second pass to add edges (connections)
for (var id in model.cells)
{
var cell = model.cells[id];
if (cell.edge)
{
if (cell.source)
{
var connect = createElt(xmlDoc, that.XMLNS, "Connect");
connect.setAttribute("FromSheet", getCellVsdxId(cell.id));
connect.setAttribute("FromCell", "BeginX");
connect.setAttribute("ToSheet", getCellVsdxId(cell.source.id));
connects.appendChild(connect);
}
if (cell.target)
{
var connect = createElt(xmlDoc, that.XMLNS, "Connect");
connect.setAttribute("FromSheet", getCellVsdxId(cell.id));
connect.setAttribute("FromCell", "EndX");
connect.setAttribute("ToSheet", getCellVsdxId(cell.target.id));
connects.appendChild(connect);
}
}
}
xmlDoc.appendChild(root);
vsdxCanvas.restore();
return xmlDoc;
};
function writeXmlDoc2Zip(zip, name, xmlDoc, noHeader)
{
zip.file(name, (noHeader? "" : "") + mxUtils.getXml(xmlDoc, '\n'));
};
function addPagesXML(zip, pages, pageLayers, modelsAttr)
{
var pagesXmlDoc = mxUtils.createXmlDocument();
var pagesRelsXmlDoc = mxUtils.createXmlDocument();
var pagesRoot = createElt(pagesXmlDoc, that.XMLNS, "Pages");
pagesRoot.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', that.XMLNS);
pagesRoot.setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:r", that.XMLNS_R);
var pagesRelsRoot = createElt(pagesRelsXmlDoc, that.RELS_XMLNS, "Relationships");
var i = 1;
for (var name in pages)
{
var pageName = "page" + i + ".xml";
var pageE = createElt(pagesXmlDoc, that.XMLNS, "Page");
pageE.setAttribute("ID", i-1);
pageE.setAttribute("NameU", name);
pageE.setAttribute("Name", name);
var pageSheet = createElt(pagesXmlDoc, that.XMLNS, "PageSheet");
var modelAttr = modelsAttr[name];
pageSheet.appendChild(createCellElemScaled("PageWidth", modelAttr['pageWidth'], pagesXmlDoc));
pageSheet.appendChild(createCellElemScaled("PageHeight", modelAttr['pageHeight'], pagesXmlDoc));
pageSheet.appendChild(createCellElem("PageScale", modelAttr['pageScale'], pagesXmlDoc));
pageSheet.appendChild(createCellElem("DrawingScale", 1, pagesXmlDoc));
var relE = createElt(pagesXmlDoc, that.XMLNS,"Rel");
relE.setAttributeNS(that.XMLNS_R, "r:id", "rId" + i);
//Add Layers
var layerSec = createElt(pagesXmlDoc, that.XMLNS, "Section");
layerSec.setAttribute("N", "Layer");
var layers = pageLayers[name];
for (var k = 0; k < layers.length; k++)
{
var layerRow = createElt(pagesXmlDoc, that.XMLNS, "Row");
layerRow.setAttribute("IX", k + "");
layerSec.appendChild(layerRow)
layerRow.appendChild(createCellElem("Name", layers[k].name, pagesXmlDoc));
layerRow.appendChild(createCellElem("Color", '255', pagesXmlDoc));
layerRow.appendChild(createCellElem("Status", '0', pagesXmlDoc));
layerRow.appendChild(createCellElem("Visible", layers[k].visible? '1' : '0', pagesXmlDoc));
layerRow.appendChild(createCellElem("Print", '1', pagesXmlDoc));
layerRow.appendChild(createCellElem("Active", '0', pagesXmlDoc));
layerRow.appendChild(createCellElem("Lock", layers[k].locked? '1' : '0', pagesXmlDoc));
layerRow.appendChild(createCellElem("Snap", '1', pagesXmlDoc));
layerRow.appendChild(createCellElem("Glue", '1', pagesXmlDoc));
layerRow.appendChild(createCellElem("NameUniv", layers[k].name, pagesXmlDoc));
layerRow.appendChild(createCellElem("ColorTrans", '0', pagesXmlDoc));
}
pageSheet.appendChild(layerSec);
pageE.appendChild(pageSheet);
pageE.appendChild(relE);
pagesRoot.appendChild(pageE);
var relationship = createElt(pagesRelsXmlDoc, that.RELS_XMLNS, "Relationship");
relationship.setAttribute("Id", "rId" + i);
relationship.setAttribute("Type", that.PAGES_TYPE);
relationship.setAttribute("Target", pageName);
pagesRelsRoot.appendChild(relationship);
//Note:Each page rels is created with the skeleton as they are constants
//write the page docs
var xmlDoc = pages[name];
writeXmlDoc2Zip(zip, that.VISIO_PAGES + pageName, xmlDoc);
i++;
}
pagesXmlDoc.appendChild(pagesRoot);
pagesRelsXmlDoc.appendChild(pagesRelsRoot);
writeXmlDoc2Zip(zip, that.VISIO_PAGES + "pages.xml", pagesXmlDoc);
writeXmlDoc2Zip(zip, that.VISIO_PAGES + "_rels/pages.xml.rels", pagesRelsXmlDoc);
}
function addImagesRels(zip, pIndex)
{
//create a new page rels file
var fId = that.VISIO_PAGES_RELS + "page" + pIndex + ".xml.rels";
var pageRelDoc = mxUtils.createXmlDocument();
var relationships = createElt(pageRelDoc, that.RELS_XMLNS, "Relationships");
//Add master relationship (rId1)
var relationship = createElt(pageRelDoc, that.RELS_XMLNS, "Relationship");
relationship.setAttribute("Type", "http://schemas.microsoft.com/visio/2010/relationships/master");
relationship.setAttribute("Id", "rId1");
relationship.setAttribute("Target", "../masters/master1.xml");
relationships.appendChild(relationship);
var imgs = vsdxCanvas.images;
//create rels of image files
if (imgs.length > 0)
{
for (var i = 0; i < imgs.length; i++)
{
var relationship = createElt(pageRelDoc, that.RELS_XMLNS, "Relationship");
relationship.setAttribute("Type", that.XMLNS_R + "/image");
relationship.setAttribute("Id", "rId" + (i+2));
relationship.setAttribute("Target", "../media/" + imgs[i]);
relationships.appendChild(relationship);
}
}
pageRelDoc.appendChild(relationships);
writeXmlDoc2Zip(zip, fId, pageRelDoc);
};
/**
*
* Convert current Editor UI pages into a vdsx file
* @return true if successful, false otherwise
*/
this.exportCurrentDiagrams = function (currentPageOnly)
{
try
{
if (editorUi.spinner.spin(document.body, mxResources.get('exporting')))
{
var zip = new JSZip();
//init class global variables
vsdxCanvas.init(zip);
idsMap = {};
idsCounter = 1;
var pages = {};
var pageLayers = {};
var modelsAttr = {};
var pagesCount = editorUi.pages != null? editorUi.pages.length : 1;
function collectLayers(graph, diagramName)
{
var layers = graph.model.getChildCells(graph.model.root);
pageLayers[diagramName] = [];
for (var k = 0; k < layers.length; k++)
{
//KNOWN We don't export invisible layers, we may support it later but we need to have a full cell state for invisible cells
if (layers[k].visible)
{
pageLayers[diagramName].push({
name: layers[k].value || 'Background',
visible: layers[k].visible,
locked: layers[k].style && layers[k].style.indexOf('locked=1') >= 0
});
}
}
};
if (editorUi.pages != null)
{
function exportPage(page)
{
var diagramName = page.getName();
var graph = editorUi.editor.graph;
//Handles dark mode
var temp = null;
if (graph.themes != null && graph.defaultThemeName == 'darkTheme')
{
temp = graph.stylesheet;
graph.stylesheet = graph.getDefaultStylesheet();
graph.refresh();
}
try
{
var modelAttrib = getGraphAttributes(graph);
pages[diagramName] = convertMxModel2Page(graph, modelAttrib);
collectLayers(graph, diagramName);
addImagesRels(zip, i+1);
modelsAttr[diagramName] = modelAttrib;
}
finally
{
if (temp != null)
{
graph.stylesheet = temp;
graph.refresh();
}
}
};
var selectedCells = editorUi.editor.graph.getSelectionCells();
var currentPage = editorUi.currentPage;
if (currentPageOnly)
{
exportPage(currentPage);
}
else
{
for (var i=0; i < editorUi.pages.length; i++)
{
var page = editorUi.pages[i];
if (editorUi.currentPage != page)
{
editorUi.selectPage(page, true);
}
exportPage(page);
}
if (currentPage != editorUi.currentPage)
{
editorUi.selectPage(currentPage, true);
}
editorUi.editor.graph.setSelectionCells(selectedCells);
}
}
else
{
var graph = editorUi.editor.graph;
var modelAttrib = getGraphAttributes(graph);
var diagramName = "Page1";
pages[diagramName] = convertMxModel2Page(graph, modelAttrib);
collectLayers(graph, diagramName);
addImagesRels(zip, 1);
modelsAttr[diagramName] = modelAttrib;
}
createVsdxSkeleton(zip, pagesCount);
addPagesXML(zip, pages, pageLayers, modelsAttr);
var createZipFile = function()
{
zip.generateAsync({type:"base64"}).then(
function(content)
{
editorUi.spinner.stop();
var basename = editorUi.getBaseFilename();
editorUi.saveData(basename + ".vsdx", 'vsdx', content,
'application/vnd.visio2013', true);
}
);
};
if (vsdxCanvas.filesLoading > 0)
{
// wait until all media files are loaded
vsdxCanvas.onFilesLoaded = createZipFile;
}
else
{
createZipFile();
}
}
return true;
}
catch(e)
{
console.log(e);
editorUi.spinner.stop();
return false;
}
};
}
VsdxExport.prototype.CONVERSION_FACTOR = 40 * 2.54; //screenCoordinatesPerCm (40) x CENTIMETERS_PER_INCHES (2.54)
VsdxExport.prototype.PAGES_TYPE = "http://schemas.microsoft.com/visio/2010/relationships/page";
VsdxExport.prototype.RELS_XMLNS = "http://schemas.openxmlformats.org/package/2006/relationships";
VsdxExport.prototype.XML_SPACE = "preserve";
VsdxExport.prototype.XMLNS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
VsdxExport.prototype.XMLNS = "http://schemas.microsoft.com/office/visio/2012/main";
VsdxExport.prototype.VISIO_PAGES = "visio/pages/";
VsdxExport.prototype.PREFEX = "com/mxgraph/io/vsdx/resources/export/";
VsdxExport.prototype.VSDX_ENC = "ISO-8859-1";
VsdxExport.prototype.PART_NAME = "PartName";
VsdxExport.prototype.CONTENT_TYPES_XML = "[Content_Types].xml";
VsdxExport.prototype.VISIO_PAGES_RELS = "visio/pages/_rels/";
VsdxExport.prototype.ARROWS_MAP = {
"none|1": 0, "none|0": 0, "open|1": 1, "open|0": 1, "block|1": 4, "block|0": 14, "classic|1": 5, "classic|0": 17,
"oval|1": 10, "oval|0": 20, "diamond|1": 11, "diamond|0": 22, "blockThin|1": 2, "blockThin|0": 15, "dash|1": 23, "dash|0": 23,
"ERone|1": 24, "ERone|0": 24, "ERmandOne|1": 25, "ERmandOne|0": 25, "ERmany|1": 27, "ERmany|0": 27, "ERoneToMany|1": 28, "ERoneToMany|0": 28,
"ERzeroToMany|1": 29, "ERzeroToMany|0": 29, "ERzeroToOne|1": 30, "ERzeroToOne|0": 30, "openAsync|1": 9, "openAsync|0": 9
};