前后台处理得到 前台图片 draw.io/ mxgraph
1、action.js

this.addAction('export...', function() {//ui.showDialog(new ExportDialog(ui).container, 300, 296, true, true);var fileNameStr = window.location.search;//获取 href 属性中跟在问号后面的部分var fileNamePath = decodeURIComponent(fileNameStr, "utf-8");  var fileName=fileNamePath.substring(fileNamePath.indexOf('=')+1,fileNamePath.length);editorUi.exportImage(1, false, true, false, true, "0", false, false, null, false, null, null, "diagram",fileName,"exportPng")});

2、editorUI.js

/**0* Handling for canvas export.*/
EditorUi.prototype.exportImage = function(scale, transparentBackground, ignoreSelection, addShadow,editable, border, noCrop, currentPage, format, grid, dpi, keepTheme, exportType,name,exportType)
{format = (format != null) ? format : 'png';var selectionEmpty = this.editor.graph.isSelectionEmpty();ignoreSelection = (ignoreSelection != null) ? ignoreSelection : selectionEmpty;// Caches imagesif (this.thumbImageCache == null){this.thumbImageCache = new Object();}this.editor.exportToCanvas(mxUtils.bind(this, function(canvas){//base64编码格式的url数据var data = this.createImageDataUri(canvas, (editable) ? this.getFileData(true, null,null, null, ignoreSelection, currentPage) : null,format, dpi);if(exportType!=null&&exportType=="exportPng"){//导出PNGvar req = new mxXmlRequest(EXPORT_URL, 'format=' + format +'&fileName=' + encodeURIComponent(name) +'&pngUrlData=' + encodeURIComponent(data)  +'&dpi=' + dpi);req.simulate(document, '_blank');this.hideDialog();//关闭当前到处的弹出窗口} else if(exportType!=null&&exportType=="exportDoc"){//导出DOCvar req = new mxXmlRequest('../exportDoc', 'fileName=' + encodeURIComponent(name) +'&xmlData='+encodeURIComponent(this.editor.getGraphXml().outerHTML)+'&pngUrlData='+encodeURIComponent(data));req.simulate(document, '_blank');} else if(exportType!=null&&exportType=="exportZip"){//导出Zipvar req = new mxXmlRequest('../exportZip', 'fileName=' + encodeURIComponent(name) +'&xmlData='+encodeURIComponent(this.editor.getGraphXml().outerHTML)+'&pngUrlData='+encodeURIComponent(data));req.simulate(document, '_blank');}}), null, this.thumbImageCache, null, mxUtils.bind(this, function(e){this.handleError(e);}), null, ignoreSelection, scale || 1, transparentBackground, addShadow,null, null, border, noCrop, grid, keepTheme, exportType);
};
/**1* */
EditorUi.prototype.createImageDataUri = function(canvas, xml, format, dpi)
{var data = canvas.toDataURL('image/' + format);// Checks for valid outputif (data != null && data.length > 6){if (xml != null){data = Editor.writeGraphModelToPng(data, 'tEXt', 'mxfile', encodeURIComponent(xml));}if (dpi > 0){data = Editor.writeGraphModelToPng(data, 'pHYs', 'dpi', dpi);}}else{throw {message: mxResources.get('unknownError')};}return data;
};
 /**3 lyq * Translates this point by the given vector.* * @param {number} dx X-coordinate of the translation.* @param {number} dy Y-coordinate of the translation.*/EditorUi.prototype.getFileData = function(forceXml, forceSvg, forceHtml, embeddedCallback, ignoreSelection,currentPage, node, compact, file, uncompressed){ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;currentPage = (currentPage != null) ? currentPage : false;var graph = this.editor.graph;// Forces compression of embedded XMLif (forceSvg || (!forceXml && file != null && /(\.svg)$/i.test(file.getTitle()))){uncompressed = false;var darkTheme = graph.themes != null && graph.defaultThemeName == 'darkTheme';// Exports SVG for first page while other page is visible by creating a graph// LATER: Add caching for the graph or SVG while not on first page// Dark mode requires a refresh that would destroy all handlers// LATER: Use dark theme here to bypass refreshif (darkTheme || (this.pages != null && this.currentPage != this.pages[0])){var graphGetGlobalVariable = graph.getGlobalVariable;graph = this.createTemporaryGraph(graph.getStylesheet());var page = this.pages[0];graph.getGlobalVariable = function(name){if (name == 'page'){return page.getName();}else if (name == 'pagenumber'){return 1;}return graphGetGlobalVariable.apply(this, arguments);};document.body.appendChild(graph.container);graph.model.setRoot(page.root);}}node = (node != null) ? node : this.getXmlFileData(ignoreSelection, currentPage, uncompressed);file = (file != null) ? file : this.getCurrentFile();var result = this.createFileData(node, graph, file, window.location.href,forceXml, forceSvg, forceHtml, embeddedCallback, ignoreSelection, compact,uncompressed);// Removes temporary graph from DOMif (graph != this.editor.graph){graph.container.parentNode.removeChild(graph.container);}return result;};
/**2* Translates this point by the given vector.* * @param {number} dx X-coordinate of the translation.* @param {number} dy Y-coordinate of the translation.*/
EditorUi.prototype.getXmlFileData = function(ignoreSelection, currentPage, uncompressed)
{ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;currentPage = (currentPage != null) ? currentPage : false;uncompressed = (uncompressed != null) ? uncompressed : !Editor.compressXml;// Generats graph model XML node for single page exportvar node = this.editor.getGraphXml(ignoreSelection);if (ignoreSelection && this.fileNode != null && this.currentPage != null){// Updates current page XML if selection is ignoredEditorUi.removeChildNodes(this.currentPage.node);mxUtils.setTextContent(this.currentPage.node, Graph.compressNode(node));// Creates a clone of the file node for processingnode = this.fileNode.cloneNode(false);// Appends the node of the page and applies compressionfunction appendPage(pageNode){var models = pageNode.getElementsByTagName('mxGraphModel');var modelNode = (models.length > 0) ? models[0] : null;var clone = pageNode;if (modelNode == null && uncompressed){var text = mxUtils.trim(mxUtils.getTextContent(pageNode));clone = pageNode.cloneNode(false);if (text.length > 0){var tmp = Graph.decompress(text);if (tmp != null && tmp.length > 0){clone.appendChild(mxUtils.parseXml(tmp).documentElement);}}}else if (modelNode != null && !uncompressed){clone = pageNode.cloneNode(false);mxUtils.setTextContent(clone, Graph.compressNode(modelNode));}else{clone = pageNode.cloneNode(true);}node.appendChild(clone);};if (currentPage){appendPage(this.currentPage.node);}else{// Restores order of pagesfor (var i = 0; i < this.pages.length; i++){if (this.currentPage != this.pages[i]){if (this.pages[i].needsUpdate){var enc = new mxCodec(mxUtils.createXmlDocument());var temp = enc.encode(new mxGraphModel(this.pages[i].root));this.editor.graph.saveViewState(this.pages[i].viewState, temp);EditorUi.removeChildNodes(this.pages[i].node);mxUtils.setTextContent(this.pages[i].node, Graph.compressNode(temp));// Marks the page as up-to-datedelete this.pages[i].needsUpdate;}}appendPage(this.pages[i].node);}}}return node;
};
 /**3* Translates this point by the given vector.* * @param {number} dx X-coordinate of the translation.* @param {number} dy Y-coordinate of the translation.*/EditorUi.prototype.getCurrentFile = function(){return this.currentFile;};/**5* Same as above but using the new embed code.*/EditorUi.prototype.getHtml2 = function(xml, graph, title, editLink, redirect){var js = window.DRAWIO_VIEWER_URL || EditorUi.drawHost + '/js/viewer-static.min.js';// Makes XHTML compatibleif (redirect != null){redirect = redirect.replace(/&/g, '&amp;');}var data = {highlight: '#0000ff', nav: this.editor.graph.foldingEnabled, resize: true,xml: Graph.zapGremlins(xml), toolbar: 'pages zoom layers lightbox'};if (this.pages != null && this.currentPage != null){data.page = mxUtils.indexOf(this.pages, this.currentPage);}var style = 'max-width:100%;border:1px solid transparent;';return ((redirect == null) ? '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->\n' : '') +'<!DOCTYPE html>\n<html' + ((redirect != null) ? ' xmlns="http://www.w3.org/1999/xhtml">' : '>') +'\n<head>\n' + ((redirect == null) ? ((title != null) ? '<title>' + mxUtils.htmlEntities(title) +'</title>\n' : '') : '<title>diagrams.net</title>\n') +((redirect != null) ? '<meta http-equiv="refresh" content="0;URL=\'' + redirect + '\'"/>\n' : '') +'<meta charset="utf-8"/>\n</head>\n<body>' +'\n<div class="mxgraph" style="' + style + '" data-mxgraph="' + mxUtils.htmlEntities(JSON.stringify(data)) + '"></div>\n' +((redirect == null) ? '<script type="text/javascript" src="' + js + '"></script>' :'<a style="position:absolute;top:50%;left:50%;margin-top:-128px;margin-left:-64px;" ' +'href="' + redirect + '" target="_blank"><img border="0" ' +'src="' + EditorUi.drawHost + '/images/drawlogo128.png"/></a>') +'\n</body>\n</html>\n';};/**6* Returns the SVG of the diagram with embedded XML. If a callback function is* used, the images are converted to data URIs.*/EditorUi.prototype.getEmbeddedSvg = function(xml, graph, url, noHeader, callback, ignoreSelection,redirect, embedImages, background, scale, border, shadow, keepTheme){embedImages = (embedImages != null) ? embedImages : true;var bg = (background != null) ? background : graph.background;if (bg == mxConstants.NONE){bg = null;}// Sets or disables alternate text for foreignObjects. Disabling is needed// because PhantomJS seems to ignore switch statements and paint all text.var svgRoot = graph.getSvg(bg, scale, border, null, null, ignoreSelection,null, null, null, graph.shadowVisible || shadow, null, keepTheme);if (graph.shadowVisible || shadow){graph.addSvgShadow(svgRoot);}if (xml != null){svgRoot.setAttribute('content', xml);}if (url != null){svgRoot.setAttribute('resource', url);}// LATER: Click on SVG content to start editing
//      if (redirect != null)
//      {
//          // TODO: Ignore anchor tag source for click event
//          svgRoot.setAttribute('style', 'cursor:pointer;');
//          svgRoot.setAttribute('onclick', 'window.location.href=\'' + redirect + '\';');
//      }if (callback != null){this.embedFonts(svgRoot, mxUtils.bind(this, function(svgRoot){if (embedImages){this.editor.convertImages(svgRoot, mxUtils.bind(this, function(svgRoot){callback(((!noHeader) ? '<?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));}));}else{callback(((!noHeader) ? '<?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));}}));}else{return ((!noHeader) ? '<?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);}};/**4* Translates this point by the given vector.* * @param {number} dx X-coordinate of the translation.* @param {number} dy Y-coordinate of the translation.*/EditorUi.prototype.createFileData = function(node, graph, file, url, forceXml, forceSvg, forceHtml,embeddedCallback, ignoreSelection, compact, uncompressed){graph = (graph != null) ? graph : this.editor.graph;forceXml = (forceXml != null) ? forceXml : false;ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;var editLink = null;var redirect = null;if (file == null || file.getMode() == App.MODE_DEVICE || file.getMode() == App.MODE_BROWSER){editLink = '_blank';}else{editLink = url;redirect = editLink;}if (node == null){return '';}else{var fileNode = node;// Ignores case for possible HTML or XML nodesif (fileNode.nodeName.toLowerCase() != 'mxfile'){if (uncompressed){var diagramNode = node.ownerDocument.createElement('diagram');diagramNode.setAttribute('id', Editor.guid());diagramNode.appendChild(node);fileNode = node.ownerDocument.createElement('mxfile');fileNode.appendChild(diagramNode);}else{// Removes control chars in input for correct roundtrip checkvar text = Graph.zapGremlins(mxUtils.getXml(node));var data = Graph.compress(text);// Fallback to plain XML for invalid compression// TODO: Remove this fallback with active pagesif (Graph.decompress(data) != text){return text;}else{var diagramNode = node.ownerDocument.createElement('diagram');diagramNode.setAttribute('id', Editor.guid());mxUtils.setTextContent(diagramNode, data);fileNode = node.ownerDocument.createElement('mxfile');fileNode.appendChild(diagramNode);}}}if (!compact){// Removes old metadatafileNode.removeAttribute('userAgent');fileNode.removeAttribute('version');fileNode.removeAttribute('editor');fileNode.removeAttribute('pages');fileNode.removeAttribute('type');if (mxClient.IS_CHROMEAPP){fileNode.setAttribute('host', 'Chrome');}else if (EditorUi.isElectronApp){fileNode.setAttribute('host', 'Electron');}else{fileNode.setAttribute('host', window.location.hostname);}// Adds new metadatafileNode.setAttribute('modified', new Date().toISOString());fileNode.setAttribute('agent', navigator.appVersion);fileNode.setAttribute('version', EditorUi.VERSION);fileNode.setAttribute('etag', Editor.guid());var md = (file != null) ? file.getMode() : this.mode;if (md != null){fileNode.setAttribute('type', md);}if (fileNode.getElementsByTagName('diagram').length > 1 && this.pages != null){fileNode.setAttribute('pages', this.pages.length);}}else{fileNode = fileNode.cloneNode(true);fileNode.removeAttribute('modified');fileNode.removeAttribute('host');fileNode.removeAttribute('agent');fileNode.removeAttribute('etag');fileNode.removeAttribute('userAgent');fileNode.removeAttribute('version');fileNode.removeAttribute('editor');fileNode.removeAttribute('type');}var xml = (uncompressed) ? mxUtils.getPrettyXml(fileNode) : mxUtils.getXml(fileNode);// Writes the file as an embedded HTML fileif (!forceSvg && !forceXml && (forceHtml || (file != null && /(\.html)$/i.test(file.getTitle())))){xml = this.getHtml2(mxUtils.getXml(fileNode), graph, (file != null) ? file.getTitle() : null, editLink, redirect);}// Maps the XML data to the content attribute in the SVG node else if (forceSvg || (!forceXml && file != null && /(\.svg)$/i.test(file.getTitle()))){if (file != null && (file.getMode() == App.MODE_DEVICE || file.getMode() == App.MODE_BROWSER)){url = null;}xml = this.getEmbeddedSvg(xml, graph, url, null, embeddedCallback, ignoreSelection, redirect);}return xml;}};

3、editor.js

/** 1* Adds the given text to the compressed or non-compressed text chunk.*/Editor.writeGraphModelToPng = function(data, type, key, value, error){var base64 = data.substring(data.indexOf(',') + 1);var f = (window.atob) ? atob(base64) : Base64.decode(base64, true);var pos = 0;function fread(d, count){var start = pos;pos += count;return d.substring(start, pos);};// Reads unsigned long 32 bit big endianfunction _freadint(d){var bytes = fread(d, 4);return bytes.charCodeAt(3) + (bytes.charCodeAt(2) << 8) +(bytes.charCodeAt(1) << 16) + (bytes.charCodeAt(0) << 24);};function writeInt(num){return String.fromCharCode((num >> 24) & 0x000000ff, (num >> 16) & 0x000000ff,(num >> 8) & 0x000000ff, num & 0x000000ff);};// Checks signatureif (fread(f,8) != String.fromCharCode(137) + 'PNG' + String.fromCharCode(13, 10, 26, 10)){if (error != null){error();}return;}// Reads header chunkfread(f,4);if (fread(f,4) != 'IHDR'){if (error != null){error();}return;}fread(f, 17);var result = f.substring(0, pos);do{var n = _freadint(f);var chunk = fread(f,4);if (chunk == 'IDAT'){result = f.substring(0, pos - 8);if (type == 'pHYs' && key == 'dpi'){var dpm = Math.round(value / 0.0254); //One inch is equal to exactly 0.0254 meters.var chunkData = writeInt(dpm) + writeInt(dpm) + String.fromCharCode(1);}else{var chunkData = key + String.fromCharCode(0) +((type == 'zTXt') ? String.fromCharCode(0) : '') + value;}var crc = 0xffffffff;crc = Editor.updateCRC(crc, type, 0, 4);crc = Editor.updateCRC(crc, chunkData, 0, chunkData.length);result += writeInt(chunkData.length) + type + chunkData + writeInt(crc ^ 0xffffffff);result += f.substring(pos - 8, f.length);break;}result += f.substring(pos - 8, pos - 4 + n);fread(f,n);fread(f,4);}while (n);return 'data:image/png;base64,' + ((window.btoa) ? btoa(result) : Base64.encode(result, true));};
/**2 **/
Editor.prototype.exportToCanvas = function(callback, width, imageCache, background, error, limitHeight,ignoreSelection, scale, transparentBackground, addShadow, converter, graph, border, noCrop, grid,keepTheme, exportType, cells)
{limitHeight = (limitHeight != null) ? limitHeight : true;ignoreSelection = (ignoreSelection != null) ? ignoreSelection : true;graph = (graph != null) ? graph : this.graph;border = (border != null) ? border : 0;var bg = (transparentBackground) ? null : graph.background;if (bg == mxConstants.NONE){bg = null;}if (bg == null){bg = background;}// Handles special case where background is null but transparent is falseif (bg == null && transparentBackground == false){bg = (keepTheme) ? this.graph.defaultPageBackgroundColor : '#ffffff';}var temp_a= graph.getSvg(null, null, border, noCrop, null, ignoreSelection,null, null, null, addShadow, null, keepTheme, exportType, cells);this.convertImages(temp_a ,mxUtils.bind(this, function(svgRoot){try{var img = new Image();img.onload = mxUtils.bind(this, function(){try{var canvas = document.createElement('canvas');var w = parseInt(svgRoot.getAttribute('width'));var h = parseInt(svgRoot.getAttribute('height'));scale = (scale != null) ? scale : 1;if (width != null){scale = (!limitHeight) ? width / w : Math.min(1, Math.min((width * 3) / (h * 4), width / w));}scale = this.getMaxCanvasScale(w, h, scale);w = Math.ceil(scale * w);h = Math.ceil(scale * h);canvas.setAttribute('width', w);canvas.setAttribute('height', h);var ctx = canvas.getContext('2d');if (bg != null){ctx.beginPath();ctx.rect(0, 0, w, h);ctx.fillStyle = bg;ctx.fill();}if (scale != 1){ctx.scale(scale, scale);}function drawImage(){// Workaround for broken data URI images in Safari on first exportif (mxClient.IS_SF){                   window.setTimeout(function(){ctx.drawImage(img, 0, 0);callback(canvas, svgRoot);}, 0);}else{ctx.drawImage(img, 0, 0);callback(canvas, svgRoot);}};if (grid){var view = graph.view;var curViewScale = view.scale;view.scale = 1; //Reset the scale temporary to generate unscaled grid image which is then scaledvar gridImage = btoa(unescape(encodeURIComponent(view.createSvgGrid(view.gridColor))));view.scale = curViewScale;gridImage = 'data:image/svg+xml;base64,' + gridImage;var phase = graph.gridSize * view.gridSteps * scale;var b = graph.getGraphBounds();var tx = view.translate.x * curViewScale;var ty = view.translate.y * curViewScale;var x0 = tx + (b.x - tx) / curViewScale - border;var y0 = ty + (b.y - ty) / curViewScale - border;var background = new Image();background.onload = function(){try{var x = -Math.round(phase - mxUtils.mod((tx - x0) * scale, phase));var y = -Math.round(phase - mxUtils.mod((ty - y0) * scale, phase));for (var i = x; i < w; i += phase){for (var j = y; j < h; j += phase){ctx.drawImage(background, i / scale, j / scale); }}drawImage();}catch (e){if (error != null){error(e);}}};background.onerror = function(e){if (error != null){error(e);}};background.src = gridImage;}else{drawImage();}}catch (e){if (error != null){error(e);}}});img.onerror = function(e){//console.log('img', e, img.src);if (error != null){error(e);}};if (addShadow){this.graph.addSvgShadow(svgRoot);}if (this.graph.mathEnabled){this.addMathCss(svgRoot);}var done = mxUtils.bind(this, function(){try{if (this.resolvedFontCss != null){this.addFontCss(svgRoot, this.resolvedFontCss);}img.src = Editor.createSvgDataUri(mxUtils.getXml(svgRoot));}catch (e){if (error != null){error(e);}}});this.embedExtFonts(mxUtils.bind(this, function(extFontsEmbeddedCss){try{if (extFontsEmbeddedCss != null){this.addFontCss(svgRoot, extFontsEmbeddedCss);}this.loadFonts(done);}catch (e){if (error != null){error(e);}}}));}catch (e){//console.log('src', e, img.src);if (error != null){error(e);}}}), imageCache, converter);
};
Editor.crcTable = [];
for (var g = 0; 256 > g; g++)for (var f = g, m = 0; 8 > m; m++)f = 1 == (f & 1) ? 3988292384 ^ f >>> 1 : f >>> 1,Editor.crcTable[g] = f;
Editor.updateCRC = function(a, b, e, c) {for (var d = 0; d < c; d++)a = Editor.crcTable[(a ^ b.charCodeAt(e + d)) & 255] ^ a >>> 8;return a
}
;
差不多的就是这些把,要是使用的时候那个方法没定义自己去draw.io 的项目源码种去找把, 文件就是diagramly目录下的 Editor.js \EditorUI.js ;主要就是在 ui.exportImage(1, false, true, false, true, "0", false, false, null, false, null, null, "diagram",fileName,"exportPng")

前后台处理得到 前台图片 draw.io/ mxgraph相关推荐

  1. draw.io 绘图软件导出png 图片的几个技巧

    前言 使用 draw.io,一般会导出图片,常用的格式是 png 格式,不过默认配置导出的图片,多少让人看不惯,经过简单的尝试,解决了如下几个问题 导出图片背景黑色问题 默认背景是黑色的,所以导出也是 ...

  2. 一个非常好用的,在线画图软件。开源的在线画流程图软件,超级棒。draw.io

    前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/83689187 未经博主允许不得转载. 博主地址是:http://blog ...

  3. 在线图表编辑工具 draw.io 10.6.2 版本发布

    draw.io 10.6.2 版本已发布,更新内容如下: 添加通用布局菜单项 另外,几天前发布的 10.6.1 版本更新内容如下: 修复 CSV import 的问题 为模板和 AWS 组添加 poi ...

  4. 因为有了这个画图工具集,老师同学都说我画的图有特色(Processon,draw.io,Xmind)

    在日常的写作以及做笔记等的过程之中,少不了要画图,但是在word.ppt里画图效率都不会太高,还不容易修改, 结合我这么久以来的画图工具,特别推出下面三个工具,让你从此在画图的时候减少麻烦. 一,Pr ...

  5. VUE3 实现前台图片标注添加矩形框、图片放大、缩小、鼠标滚轮缩放

    VUE3 实现前台图片标注 功能包括: 鼠标左键拖动添加矩形框标记区域,鼠标点击已绘制的矩形: 选中矩形,并绘制不同选中效果: 鼠标在已绘制的矩形中按住左键拖动,选中并移动矩形:选中矩形后鼠标在选中矩 ...

  6. 使用画图工具draw.io的嵌入模式实现uml图绘制功能的尝试(1)

    使用画图工具draw.io的嵌入模式实现uml图绘制功能的尝试(2) 使用画图工具draw.io的嵌入模式实现uml图绘制功能的尝试(3) 正在编写的本科毕设项目中要求实现绘制UML图的需求,我搜索了 ...

  7. 推荐一个开源免费的绘图软件 Draw.io 可导出矢量图

    问题描述 关于绘图,微软的 Visio 是一个不错的选择,但是不支持 mac 下使用,不支持 linux 桌面系统,而且是一个收费的软件. 推荐一个免费的软件,官网地址为 draw.io,先不急着下载 ...

  8. 给大家介绍下,这是我的流程图软件 —— draw.io

    前言 之前推了一篇文章<十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!>,很多小伙伴都比较好奇在文章中的图是用的什么画图软件?看那么明显的手绘风格,当然是手画的啦!(开玩 ...

  9. draw.io插件在vscode中一体化导出高质量图片

    ''' Author: zzx Date: 2022-07-30 15:52:15 LastEditors: zdl LastEditTime: 2022-07-30 16:03:20 FilePat ...

最新文章

  1. git管理大项目或者大文件
  2. Python工具 | 9个用来爬取网络站点的 Python 库
  3. docker 安装vim
  4. java明星养成游戏_#IT明星不是梦#Java14不得不知的5个新功能
  5. 中序遍历的非递归算法
  6. C语言如何返回格式化日期时间(格式化时间)?(将日期和时间以字符串格式输出)ctime()、asctime()、localtime()、strftime()
  7. C++SEG TREE线段树的实现算法(附完整源码)
  8. java 把URL中的中文转换成utf-8编码
  9. java上传和下载文件代码_JavaWeb中上传和下载文件实例代码
  10. POJ1274 The Perfect Stall(二分图)
  11. 0258资源网正版模板emlog资源网/娱乐网模板
  12. Docker之数据卷和数据卷容器
  13. MySoft.Data入门篇:编写业务逻辑
  14. SSRF 服务器端请求伪造
  15. 计算机应用基础第四版答案周南岳,计算机应用基础周南岳答案.docx
  16. Linux中文显示:解决Windows传到linux文件中文乱码
  17. LaTeX 文字带边框
  18. 1400张正方形图片合集压缩包图片分辨率330*330
  19. 《写给女人》--[美]桃乐丝·卡耐基
  20. android数字转汉字,【原创】最精简的中文数字和阿拉伯数字互相转换函数

热门文章

  1. Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)
  2. Material studio 中如何构建方形晶胞
  3. ip地址转换成16进制long
  4. Mac电脑怎么关闭键盘的重复按键功能?
  5. IronPython团队宣言
  6. 【听歌】Happy programmer's Day
  7. 51单片机实现万年历
  8. mapreduce 论文 - 阅读笔记
  9. Fuchsia编译与真机安装
  10. 图解SQL面试题:经典30题,数据分析人求职必考,强烈推荐收藏