public inbox for [email protected]  
help / color / mirror / Atom feed
[pgAdmin][RM6197] Incomplete ERD image downloaded.
2+ messages / 2 participants
[nested] [flat]

* [pgAdmin][RM6197] Incomplete ERD image downloaded.
@ 2021-02-11 10:45  Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 2+ messages in thread

From: Aditya Toshniwal @ 2021-02-11 10:45 UTC (permalink / raw)
  To: pgadmin-hackers

Hi Hackers,

Attached patch will improve and fix things except, the links are partially
rendered in case of SVG overflow. That needs to be fixed in html2canvas
library. Ref - https://github.com/niklasvh/html2canvas/issues/1486. In
addition, safari seems to be distorting the link paths.
Considering the majority of users are on Chrome and Firefox, the fix will
help most users until issues for Safari are fixed.

Please review.

-- 
Thanks,
Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] RM6197.patch (8.2K, 3-RM6197.patch)
  download | inline diff:
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
index 3935af360..23b592149 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
@@ -53,6 +53,8 @@ export default class ERDCore {
     let model = new ERDModel();
     if(data) {
       model.deserializeModel(data, this.engine);
+      this.fireEvent(model.getOptions(), 'offsetUpdated', true);
+      this.fireEvent(model.getOptions(), 'zoomUpdated', true);
     }
 
     const registerNodeEvents = (node) => {
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
index 5451e868f..ff8a9c798 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
@@ -87,22 +87,12 @@ export default class BodyWidget extends React.Component {
     this.noteNode = null;
     this.keyboardActionObj = null;
 
-    this.onLoadDiagram = this.onLoadDiagram.bind(this);
-    this.onSaveDiagram = this.onSaveDiagram.bind(this);
-    this.onSaveAsDiagram = this.onSaveAsDiagram.bind(this);
-    this.onSQLClick = this.onSQLClick.bind(this);
-    this.onImageClick = this.onImageClick.bind(this);
-    this.onAddNewNode = this.onAddNewNode.bind(this);
-    this.onEditNode = this.onEditNode.bind(this);
-    this.onCloneNode = this.onCloneNode.bind(this);
-    this.onDeleteNode = this.onDeleteNode.bind(this);
-    this.onNoteClick = this.onNoteClick.bind(this);
-    this.onNoteClose = this.onNoteClose.bind(this);
-    this.onOneToManyClick = this.onOneToManyClick.bind(this);
-    this.onManyToManyClick = this.onManyToManyClick.bind(this);
-    this.onAutoDistribute = this.onAutoDistribute.bind(this);
-    this.onDetailsToggle = this.onDetailsToggle.bind(this);
-    this.onHelpClick = this.onHelpClick.bind(this);
+    _.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSaveAsDiagram', 'onSQLClick',
+      'onImageClick', 'onAddNewNode', 'onEditNode', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
+      'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
+      'onDetailsToggle', 'onHelpClick'
+    ]);
+
     this.diagram.zoomToFit = this.diagram.zoomToFit.bind(this.diagram);
     this.diagram.zoomIn = this.diagram.zoomIn.bind(this.diagram);
     this.diagram.zoomOut = this.diagram.zoomOut.bind(this.diagram);
@@ -552,6 +542,30 @@ export default class BodyWidget extends React.Component {
   onImageClick() {
     this.setLoading(gettext('Preparing the image...'));
 
+    /* Move the diagram temporarily to align it to top-left of the canvas so that when
+     * taking the snapshot all the nodes are covered. Once the image is taken, repaint
+     * the canvas back to original state.
+     * Code referred from - zoomToFitNodes function.
+     */
+    let nodesRect = this.diagram.getEngine().getBoundingNodesRect(this.diagram.getModel().getNodes(), 10);
+    let canvasRect = this.canvasEle.getBoundingClientRect();
+    let canvasTopLeftPoint = {
+        x: canvasRect.left,
+        y: canvasRect.top
+    };
+    let nodeLayerTopLeftPoint = {
+        x: canvasTopLeftPoint.x + this.diagram.getModel().getOffsetX(),
+        y: canvasTopLeftPoint.y + this.diagram.getModel().getOffsetY()
+    };
+    let nodesRectTopLeftPoint = {
+        x: nodeLayerTopLeftPoint.x + nodesRect.getTopLeft().x,
+        y: nodeLayerTopLeftPoint.y + nodesRect.getTopLeft().y
+    };
+    let prevTransform = this.canvasEle.querySelector('div').style.transform;
+    this.canvasEle.childNodes.forEach((ele)=>{
+      ele.style.transform = `translate(${nodeLayerTopLeftPoint.x - nodesRectTopLeftPoint.x}px, ${nodeLayerTopLeftPoint.y - nodesRectTopLeftPoint.y}px) scale(1.0)`;
+    });
+
     /* Change the styles for suiting html2canvas */
     this.canvasEle.classList.add('html2canvas-reset');
     this.canvasEle.style.width = this.canvasEle.scrollWidth + 'px';
@@ -567,10 +581,16 @@ export default class BodyWidget extends React.Component {
           'font'
       ];
       let svgElems = Array.from(targetElem.getElementsByTagName("svg"));
-      for (let svgElement of svgElems) {
-          svgElement.setAttribute('width', svgElement.clientWidth);
-          svgElement.setAttribute('height', svgElement.clientHeight);
-          recurseElementChildren(svgElement);
+      for (let svgEle of svgElems) {
+          svgEle.setAttribute('width', svgEle.clientWidth);
+          svgEle.setAttribute('height', svgEle.clientHeight);
+          /* Wrap the SVG in a div tag so that transforms are consistent with html */
+          let wrap = document.createElement('div');
+          wrap.setAttribute('style', svgEle.getAttribute('style'));
+          svgEle.setAttribute('style', null);
+          svgEle.parentNode.appendChild(wrap);
+          wrap.appendChild(svgEle);
+          recurseElementChildren(svgEle);
       }
       function recurseElementChildren(node) {
           if (!node.style)
@@ -586,40 +606,45 @@ export default class BodyWidget extends React.Component {
       }
     }
 
-    html2canvas(this.canvasEle, {
-      width: this.canvasEle.scrollWidth + 10,
-      height: this.canvasEle.scrollHeight + 10,
-      scrollX: 0,
-      scrollY: 0,
-      useCORS: true,
-      allowTaint: true,
-      backgroundColor: window.getComputedStyle(this.canvasEle).backgroundColor,
-      onclone: (clonedEle)=>{
-        setSvgInlineStyles(clonedEle);
-        return clonedEle;
-      },
-    }).then((canvas)=>{
-      let link = document.createElement('a');
-      link.setAttribute('href', canvas.toDataURL('image/png'));
-      link.setAttribute('download', this.getCurrentProjectName() + '.png');
-      link.click();
-      link.remove();
-    }).catch((err)=>{
-      console.error(err);
-      let msg = gettext('Unknown error. Check console logs');
-      if(err.name) {
-        msg = `${err.name}: ${err.message}`;
-      }
-      this.props.alertify.alert()
-        .set('title', gettext('Error'))
-        .set('message', msg).show();
-    }).then(()=>{
-      /* Revert back to the original CSS styles */
-      this.canvasEle.classList.remove('html2canvas-reset');
-      this.canvasEle.style.width = '';
-      this.canvasEle.style.height = '';
-      this.setLoading(null);
-    });
+    setTimeout(()=>{
+      html2canvas(this.canvasEle, {
+        width: this.canvasEle.scrollWidth + 10,
+        height: this.canvasEle.scrollHeight + 10,
+        scrollX: 0,
+        scrollY: 0,
+        useCORS: true,
+        allowTaint: true,
+        backgroundColor: window.getComputedStyle(this.canvasEle).backgroundColor,
+        onclone: (clonedEle)=>{
+          setSvgInlineStyles(clonedEle);
+          return clonedEle;
+        },
+      }).then((canvas)=>{
+        let link = document.createElement('a');
+        link.setAttribute('href', canvas.toDataURL('image/png'));
+        link.setAttribute('download', this.getCurrentProjectName() + '.png');
+        link.click();
+        link.remove();
+      }).catch((err)=>{
+        console.error(err);
+        let msg = gettext('Unknown error. Check console logs');
+        if(err.name) {
+          msg = `${err.name}: ${err.message}`;
+        }
+        this.props.alertify.alert()
+          .set('title', gettext('Error'))
+          .set('message', msg).show();
+      }).then(()=>{
+        /* Revert back to the original CSS styles */
+        this.canvasEle.classList.remove('html2canvas-reset');
+        this.canvasEle.style.width = '';
+        this.canvasEle.style.height = '';
+        this.canvasEle.childNodes.forEach((ele)=>{
+          ele.style.transform = prevTransform;
+        });
+        this.setLoading(null);
+      });
+    }, 1000);
   }
 
   onOneToManyClick() {
diff --git a/web/pgadmin/tools/erd/static/scss/_erd.scss b/web/pgadmin/tools/erd/static/scss/_erd.scss
index a54df1284..f48d65b4c 100644
--- a/web/pgadmin/tools/erd/static/scss/_erd.scss
+++ b/web/pgadmin/tools/erd/static/scss/_erd.scss
@@ -74,10 +74,6 @@
   .html2canvas-reset {
     background-image: none !important;
     overflow: auto !important;
-
-    & > svg, & > div {
-      transform: none !important;
-    }
   }
 
   .diagram-canvas{


^ permalink  raw  reply  [nested|flat] 2+ messages in thread

* Re: [pgAdmin][RM6197] Incomplete ERD image downloaded.
@ 2021-02-15 09:55  Akshay Joshi <[email protected]>
  parent: Aditya Toshniwal <[email protected]>
  0 siblings, 0 replies; 2+ messages in thread

From: Akshay Joshi @ 2021-02-15 09:55 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Thanks, patch applied.

On Thu, Feb 11, 2021 at 4:16 PM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached patch will improve and fix things except, the links are partially
> rendered in case of SVG overflow. That needs to be fixed in html2canvas
> library. Ref - https://github.com/niklasvh/html2canvas/issues/1486. In
> addition, safari seems to be distorting the link paths.
> Considering the majority of users are on Chrome and Firefox, the fix will
> help most users until issues for Safari are fixed.
>
> Please review.
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 2+ messages in thread


end of thread, other threads:[~2021-02-15 09:55 UTC | newest]

Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-02-11 10:45 [pgAdmin][RM6197] Incomplete ERD image downloaded. Aditya Toshniwal <[email protected]>
2021-02-15 09:55 ` Akshay Joshi <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox