首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从mxGraph输出SVG文件

从mxGraph输出SVG文件
EN

Stack Overflow用户
提问于 2020-12-15 23:39:56
回答 2查看 804关注 0票数 0

我和我的团队正在研究如何使用mxGraph以编程方式生成图表。我们已经创建了一个图表,并将其保存为XML文件。我们如何从那里转到SVG文件?

我了解到mxGraph本机使用SVG文件作为显示,它可以编写带有XML编码的SVG文件,以便在diagrams.net中重新打开它们。如何让mxGraph将我们的图形放在SVG画布上,然后将其序列化到磁盘上?

代码语言:javascript
复制
// from https://stackoverflow.com/a/57829704
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM();
const fs = require('fs');

global.window = dom.window;
global.document = window.document;
global.XMLSerializer = window.XMLSerializer;
global.navigator = window.navigator;

const mxgraph = require("mxgraph")({
    mxImageBasePath: "./src/images",
    mxBasePath: "./src"
});


const {mxGraph, mxCodec, mxUtils, mxConstants, mxSvgCanvas2D} = mxgraph;

function makeHelloWorld() {
  // Extracted from https://github.com/jgraph/mxgraph/blob/master/javascript/examples/helloworld.html
  const graph = new mxGraph();

  // Gets the default parent for inserting new cells. This
  // is normally the first child of the root (ie. layer 0).
  var parent = graph.getDefaultParent();

  // Adds cells to the model in a single step
  graph.getModel().beginUpdate();
  try {
    var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
    var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
    var e1 = graph.insertEdge(parent, null, '', v1, v2);
  } finally {
    // Updates the display
    graph.getModel().endUpdate();
  }
  return graph;
}

const helloWorldGraph = makeHelloWorld();

function graphToXML(graph) {
    var encoder = new mxCodec();
    var result = encoder.encode(graph.getModel());
    return mxUtils.getXml(result);
}

const xml = graphToXML(helloWorldGraph);

fs.writeFileSync('./graph.xml', xml);

到目前为止,所有东西都可以工作--我们可以输出一个XML文件。现在我们必须从那里到一个SVG。

我创建了一个SVG画布,如下所示:

代码语言:javascript
复制
function createSvgCanvas(graph) {
    const svgDoc = mxUtils.createXmlDocument();
    const root = (svgDoc.createElementNS != null) ? svgDoc.createElementNS(mxConstants.NS_SVG, 'svg') : svgDoc.createElement('svg');
    if (svgDoc.createElementNS == null) {
        root.setAttribute('xmlns', mxConstants.NS_SVG);
        root.setAttribute('xmlns:xlink', mxConstants.NS_XLINK);
    } else {
        root.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', mxConstants.NS_XLINK);
    }
    const bounds = graph.getGraphBounds();
    root.setAttribute('width', (bounds.x + bounds.width + 4) + 'px');
    root.setAttribute('height', (bounds.y + bounds.height + 4) + 'px');
    root.setAttribute('version', '1.1');
    svgDoc.appendChild(root);
    const svgCanvas = new mxSvgCanvas2D(root);
    return svgCanvas;
}

问题是:

  1. 新画布是为图形调整大小的,但它还没有图形。
  2. 我需要弄清楚如何将SVG画布转换为磁盘上的SVG文件。

编辑:我在程序的末尾添加了以下内容:

代码语言:javascript
复制
const canvas = createSvgCanvas(helloWorldGraph);
const imgExport = new mxImageExport();
imgExport.drawState(helloWorldGraph.getView().getState(helloWorldGraph.model.root), canvas); // adapted from https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxImageExport-js.html

const xml2 = mxUtils.getXml(canvas)

const svgString = '<?xml version="1.0" encoding="UTF-8"?>\n'
+ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
+ xml2
fs.writeFileSync('./graph.svg', svgString);

这让我得到了"Uncaught :未能在‘XMLSerializer’上执行'serializeToString‘:参数1不是’Node‘类型的。“我尝试过一些东西,但是我对mxGraph还不太熟悉,无法从我的画布中获得它所需要的节点。

EN

回答 2

Stack Overflow用户

发布于 2020-12-18 11:50:29

关于第1点,您可以查看draw.io代码,它提供了有关如何设置画布的详细信息。

但是这段代码打算在浏览器中使用,所以在依赖于JSDOM的脚本中运行时可能会出现问题。

您必须使用mxImageExport来使用画布。然后包装所产生的节点以生成svg字符串(在下面的svgRoot中是由自定义代码生成并由mxImageExport更新的元素)

代码语言:javascript
复制
'<?xml version="1.0" encoding="UTF-8"?>\n'
 + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
 + mxUtils.getXml(svgRoot)

对于脚本中的第2点,一旦有了svg字符串,就可以将它直接写入文件中,就像在xml文件中存储mx图模型一样。

对于浏览器中的第2点,可以使用Anchor元素(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes)的下载和href属性。

第一,生成一个href数据,其中包含用第1点生成的svg字符串的编码值。

代码语言:javascript
复制
'data:image/svg+xml' + encodeURIComponent(svg)

然后用这个href数据创建锚,并在单击按钮时触发它。关于https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server的更多细节

票数 1
EN

Stack Overflow用户

发布于 2020-12-31 02:35:49

要从XML生成SVG文件,您可以从http://get.diagrams.net下载桌面版本的http://get.diagrams.net并在命令行上运行它。

命令行标志的文档可以找到这里或运行draw.io --help

代码语言:javascript
复制
/Applications/draw.io.app/Contents/MacOS/draw.io -x -f svg graph.xml

但是,以这种方式生成的SVG文件缺少嵌入的XML数据,因此可以在diagrams.net中重新打开它们。可以使用regex或其他方法重新插入此数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65315250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档