From 7a2783ceed57b6d55ee8dbc1be9b2796fd8530cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Tue, 3 Jul 2018 15:32:09 +0200 Subject: [PATCH 1/5] Adding "Export SVG" button This is a very basic implementation of SVG export. It looks into DOM elements to figure out the positions and dimensions, and then re-creates the tables as plain SVG and . Works fine on both Firefox and Chrome. Known issues: * The positions are incorrect if the browser has some zoom applied. In fact, the display is already incorrect in the browser itself (the SVG paths are not correctly aligned with the elements). * Rounded corners are not supported. Implementing that (properly) would require SVG clipping or some extra tricks. Not worth the extra trouble for now. * The borders are 2-pixel wide because otherwise they would not align to the pixel grid (1-pixel border would cover two half pixels). * There are no translations for other languages. Related issues: * https://github.com/ondras/wwwsqldesigner/issues/131 * https://github.com/ondras/wwwsqldesigner/issues/132 --- index.html | 1 + js/io.js | 124 ++++++++++++++++++++++++++++++++++++++++++++++- locale/en.xml | 1 + locale/pt_BR.xml | 1 + 4 files changed, 126 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 24b98ad..02ba874 100644 --- a/index.html +++ b/index.html @@ -182,6 +182,7 @@
+ diff --git a/js/io.js b/js/io.js index 1a6ef58..7efdeb7 100644 --- a/js/io.js +++ b/js/io.js @@ -9,7 +9,7 @@ SQL.IO = function(owner) { var ids = ["saveload","clientlocalsave", "clientsave", "clientlocalload", "clientlocallist","clientload", "clientsql", "dropboxsave", "dropboxload", "dropboxlist", "quicksave", "serversave", "serverload", - "serverlist", "serverimport"]; + "serverlist", "serverimport", "exportsvg"]; for (var i=0;iLoad from Dropbox List from Dropbox Generate SQL + Export SVG Server backend: Save Quicksave diff --git a/locale/pt_BR.xml b/locale/pt_BR.xml index 3d6df03..1300c67 100644 --- a/locale/pt_BR.xml +++ b/locale/pt_BR.xml @@ -75,6 +75,7 @@ Salvar XML Carregar XML Gerar SQL + Exportar SVG ParĂ¢metros do Servidor: Salvar Carregar From ba6226c8b5e127140985b1902861878271cd5e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Tue, 3 Jul 2018 16:10:28 +0200 Subject: [PATCH 2/5] Adding elements to exported SVG This may help further processing or editing, for whoever opens the SVG file. I've also added some CSS classes and some data attributes to the elements, as those can come handy if someone tries to process the SVG through code. --- js/io.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/js/io.js b/js/io.js index 7efdeb7..01d273f 100644 --- a/js/io.js +++ b/js/io.js @@ -462,22 +462,35 @@ SQL.IO.prototype.exportsvg = function() { for (var i=0;i Date: Wed, 11 Jul 2018 17:21:23 +0200 Subject: [PATCH 3/5] Adding some more classes and attributes to SVG elments Makes it easier to find them through JavaScript or CSS. --- js/io.js | 2 ++ js/relation.js | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/js/io.js b/js/io.js index 01d273f..659194d 100644 --- a/js/io.js +++ b/js/io.js @@ -488,8 +488,10 @@ SQL.IO.prototype.exportsvg = function() { var rect = this.createSVGRectFromDOMElement(row.dom.container); gr.appendChild(rect); var title = this.createSVGTextFromDOMElement(row.dom.title); + title.classList.add("rowtitle"); gr.appendChild(title); var typehint = this.createSVGTextFromDOMElement(row.dom.typehint); + title.classList.add("rowtypehint"); gr.appendChild(typehint); } } diff --git a/js/relation.js b/js/relation.js index db47cdc..945a993 100644 --- a/js/relation.js +++ b/js/relation.js @@ -27,6 +27,11 @@ SQL.Relation = function(owner, row1, row2) { path.setAttribute("stroke", this.color); path.setAttribute("stroke-width", CONFIG.RELATION_THICKNESS); path.setAttribute("fill", "none"); + path.classList.add("relation"); + path.dataset.row1 = row1.getTitle(); + path.dataset.row2 = row2.getTitle(); + path.dataset.table1 = row1.owner.getTitle(); + path.dataset.table2 = row2.owner.getTitle(); this.owner.dom.svg.appendChild(path); this.dom.push(path); } else { From 18888b697d9a6d3d81a4da1034bc2c5d067b3328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Thu, 12 Jul 2018 14:57:43 +0200 Subject: [PATCH 4/5] getBoundingClientRect returns x,y,width,height According to the following links, getBoundingClientRect() method returns a DOMRect, which contains the x, y, width, height attributes. Thus, the code will now avoid using left, top, bottom, right. https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect https://drafts.fxtf.org/geometry-1/#domrect --- js/io.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/io.js b/js/io.js index 659194d..4b9585d 100644 --- a/js/io.js +++ b/js/io.js @@ -383,10 +383,10 @@ SQL.IO.prototype.getBoundingClientRect_relative_to_root = function(dom_elem) { // More testing is needed. var box = dom_elem.getBoundingClientRect(); var ret = { - "left" : box.left + window.scrollX, - "right" : box.right + window.scrollX, - "top" : box.top + window.scrollY, - "bottom": box.bottom + window.scrollY, + "left" : box.x + window.scrollX, + "right" : box.x + box.width + window.scrollX, + "top" : box.y + window.scrollY, + "bottom": box.y + box.height + window.scrollY, "width" : box.width, "height": box.height, }; From f1fd92be5ef9869aebc750919d426fe5c007b22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Thu, 12 Jul 2018 14:59:47 +0200 Subject: [PATCH 5/5] Auto-crop SVG image Much better. Much less empty space. Much more useful. --- js/io.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/js/io.js b/js/io.js index 4b9585d..eaaa448 100644 --- a/js/io.js +++ b/js/io.js @@ -459,9 +459,20 @@ SQL.IO.prototype.exportsvg = function() { svg.setAttribute("xmlns", this.owner.svgNS); svg.setAttribute("xmlns:svg", this.owner.svgNS); + var min_x = null; + var min_y = null; + var max_x = null; + var max_y = null; + for (var i=0;i max_x) max_x = table_box.right; + if (max_y === null || table_box.bottom > max_y) max_y = table_box.bottom; + var gt = document.createElementNS(this.owner.svgNS, "g"); gt.classList.add("table"); gt.dataset.title = t.getTitle(); @@ -496,6 +507,24 @@ SQL.IO.prototype.exportsvg = function() { } } + // Overall SVG dimensions (fit to content). + if (min_x === null || min_y === null || max_x === null || max_y === null) { + min_x = 0; + min_y = 0; + max_x = 3000; + max_y = 3000; + } else { + min_x -= CONFIG.RELATION_SPACING; + min_y -= CONFIG.RELATION_SPACING; + max_x += CONFIG.RELATION_SPACING; + max_y += CONFIG.RELATION_SPACING; + } + var width = max_x - min_x; + var height = max_y - min_y; + svg.setAttribute("width", width); + svg.setAttribute("height", height); + svg.setAttribute("viewBox", min_x + " " + min_y + " " + width + " " + height); + var blob = new Blob([svg.outerHTML], {"type": "image/svg+xml"}); // Trick to cause a file download: