You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by kb...@apache.org on 2020/04/17 12:53:27 UTC

[atlas] branch branch-2.0 updated: ATLAS-3732 : UI: Lineage graph improvement and lib version updated

This is an automated email from the ASF dual-hosted git repository.

kbhatt pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new ee891f1  ATLAS-3732 : UI: Lineage graph improvement and lib version updated
ee891f1 is described below

commit ee891f1f1ef0275e4f07a4d2b1ffad676c30eb2c
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Fri Apr 17 15:24:41 2020 +0530

    ATLAS-3732 : UI: Lineage graph improvement and lib version updated
    
    (cherry picked from commit ff1a9dc2fcc6d45e2965848379bdca8e605cdd12)
---
 dashboardv2/package-lock.json                      | 460 ++++++++++----
 dashboardv2/package.json                           |   4 +-
 dashboardv2/public/css/scss/graph.scss             |  10 +
 dashboardv2/public/css/scss/theme.scss             |   3 +-
 dashboardv2/public/js/main.js                      |   2 +-
 .../public/js/views/graph/LineageLayoutView.js     | 682 ++++++++------------
 dashboardv2/public/js/views/graph/LineageUtils.js  | 252 +++++++-
 dashboardv3/package-lock.json                      | 449 +++++++++----
 dashboardv3/package.json                           |   2 +-
 dashboardv3/public/css/scss/graph.scss             |  10 +
 dashboardv3/public/css/scss/theme.scss             |   3 +-
 dashboardv3/public/js/main.js                      |   2 +-
 .../public/js/views/graph/LineageLayoutView.js     | 697 ++++++++-------------
 dashboardv3/public/js/views/graph/LineageUtils.js  | 252 +++++++-
 14 files changed, 1713 insertions(+), 1115 deletions(-)

diff --git a/dashboardv2/package-lock.json b/dashboardv2/package-lock.json
index 32f9549..afc9fb3 100644
--- a/dashboardv2/package-lock.json
+++ b/dashboardv2/package-lock.json
@@ -512,13 +512,9 @@
       }
     },
     "commander": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
-      "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
-      "dev": true,
-      "requires": {
-        "graceful-readlink": ">= 1.0.0"
-      }
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
     },
     "concat-map": {
       "version": "0.0.1",
@@ -625,6 +621,202 @@
       "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
       "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g="
     },
+    "d3-array": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
+      "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
+    },
+    "d3-axis": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz",
+      "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
+    },
+    "d3-brush": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz",
+      "integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
+    "d3-chord": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz",
+      "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==",
+      "requires": {
+        "d3-array": "1",
+        "d3-path": "1"
+      }
+    },
+    "d3-collection": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz",
+      "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A=="
+    },
+    "d3-color": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
+      "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
+    },
+    "d3-contour": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz",
+      "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==",
+      "requires": {
+        "d3-array": "^1.1.1"
+      }
+    },
+    "d3-dispatch": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
+      "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
+    },
+    "d3-drag": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
+      "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-selection": "1"
+      }
+    },
+    "d3-dsv": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz",
+      "integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==",
+      "requires": {
+        "commander": "2",
+        "iconv-lite": "0.4",
+        "rw": "1"
+      }
+    },
+    "d3-ease": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz",
+      "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ=="
+    },
+    "d3-fetch": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz",
+      "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==",
+      "requires": {
+        "d3-dsv": "1"
+      }
+    },
+    "d3-force": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz",
+      "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==",
+      "requires": {
+        "d3-collection": "1",
+        "d3-dispatch": "1",
+        "d3-quadtree": "1",
+        "d3-timer": "1"
+      }
+    },
+    "d3-format": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz",
+      "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw=="
+    },
+    "d3-geo": {
+      "version": "1.11.9",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.9.tgz",
+      "integrity": "sha512-9edcH6J3s/Aa3KJITWqFJbyB/8q3mMlA9Fi7z6yy+FAYMnRaxmC7jBhUnsINxVWD14GmqX3DK8uk7nV6/Ekt4A==",
+      "requires": {
+        "d3-array": "1"
+      }
+    },
+    "d3-hierarchy": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
+      "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
+    },
+    "d3-interpolate": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
+      "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
+      "requires": {
+        "d3-color": "1"
+      }
+    },
+    "d3-path": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+    },
+    "d3-polygon": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz",
+      "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ=="
+    },
+    "d3-quadtree": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz",
+      "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
+    },
+    "d3-random": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz",
+      "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ=="
+    },
+    "d3-scale": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz",
+      "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==",
+      "requires": {
+        "d3-array": "^1.2.0",
+        "d3-collection": "1",
+        "d3-format": "1",
+        "d3-interpolate": "1",
+        "d3-time": "1",
+        "d3-time-format": "2"
+      }
+    },
+    "d3-scale-chromatic": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz",
+      "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==",
+      "requires": {
+        "d3-color": "1",
+        "d3-interpolate": "1"
+      }
+    },
+    "d3-selection": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.1.tgz",
+      "integrity": "sha512-BTIbRjv/m5rcVTfBs4AMBLKs4x8XaaLkwm28KWu9S2vKNqXkXt2AH2Qf0sdPZHjFxcWg/YL53zcqAz+3g4/7PA=="
+    },
+    "d3-shape": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+      "requires": {
+        "d3-path": "1"
+      }
+    },
+    "d3-time": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
+      "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
+    },
+    "d3-time-format": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
+      "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
+      "requires": {
+        "d3-time": "1"
+      }
+    },
+    "d3-timer": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
+      "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
+    },
     "d3-tip": {
       "version": "0.6.8",
       "resolved": "https://registry.npmjs.org/d3-tip/-/d3-tip-0.6.8.tgz",
@@ -633,24 +825,94 @@
         "d3": "^3.5.5"
       }
     },
+    "d3-transition": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz",
+      "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==",
+      "requires": {
+        "d3-color": "1",
+        "d3-dispatch": "1",
+        "d3-ease": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "^1.1.0",
+        "d3-timer": "1"
+      }
+    },
+    "d3-voronoi": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
+      "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
+    },
+    "d3-zoom": {
+      "version": "1.8.3",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
+      "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
     "dagre": {
-      "version": "0.7.4",
-      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.7.4.tgz",
-      "integrity": "sha1-3nLw50pVDOEc5jjwoTb+1xI5gCI=",
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
       "requires": {
-        "graphlib": "^1.0.5",
-        "lodash": "^3.10.0"
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
       }
     },
     "dagre-d3": {
-      "version": "0.4.17",
-      "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.4.17.tgz",
-      "integrity": "sha1-lTMYDQC6n/KLBM7hJ+k1ktnGChw=",
-      "requires": {
-        "d3": "^3.3.8",
-        "dagre": "^0.7.3",
-        "graphlib": "^1.0.5",
-        "lodash": "^3.10.0"
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.6.4.tgz",
+      "integrity": "sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==",
+      "requires": {
+        "d3": "^5.14",
+        "dagre": "^0.8.5",
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "d3": {
+          "version": "5.15.1",
+          "resolved": "https://registry.npmjs.org/d3/-/d3-5.15.1.tgz",
+          "integrity": "sha512-Xu9gT6Lm0jH3wWJJSRomFwqnGGi3YAfWIfxNFl4++YVgYOjo3F8V2idAG3nJBgpZOkD0/RHPZX6F4k6tzgOvYw==",
+          "requires": {
+            "d3-array": "1",
+            "d3-axis": "1",
+            "d3-brush": "1",
+            "d3-chord": "1",
+            "d3-collection": "1",
+            "d3-color": "1",
+            "d3-contour": "1",
+            "d3-dispatch": "1",
+            "d3-drag": "1",
+            "d3-dsv": "1",
+            "d3-ease": "1",
+            "d3-fetch": "1",
+            "d3-force": "1",
+            "d3-format": "1",
+            "d3-geo": "1",
+            "d3-hierarchy": "1",
+            "d3-interpolate": "1",
+            "d3-path": "1",
+            "d3-polygon": "1",
+            "d3-quadtree": "1",
+            "d3-random": "1",
+            "d3-scale": "2",
+            "d3-scale-chromatic": "1",
+            "d3-selection": "1",
+            "d3-shape": "1",
+            "d3-time": "1",
+            "d3-time-format": "2",
+            "d3-timer": "1",
+            "d3-transition": "1",
+            "d3-voronoi": "1",
+            "d3-zoom": "1"
+          }
+        }
       }
     },
     "dashdash": {
@@ -709,9 +971,9 @@
       "dev": true
     },
     "depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
       "dev": true
     },
     "destroy": {
@@ -750,9 +1012,9 @@
       }
     },
     "dropzone": {
-      "version": "5.5.1",
-      "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.5.1.tgz",
-      "integrity": "sha512-3VduRWLxx9hbVr42QieQN25mx/I61/mRdUSuxAmDGdDqZIN8qtP7tcKMa3KfpJjuGjOJGYYUzzeq6eGDnkzesA=="
+      "version": "5.7.0",
+      "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.7.0.tgz",
+      "integrity": "sha512-kOltiZXH5cO/72I22JjE+w6BoT6uaVLfWdFMsi1PMKFkU6BZWpqRwjnsRm0o6ANGTBuZar5Piu7m/CbKqRPiYg=="
     },
     "ecc-jsbn": {
       "version": "0.1.2",
@@ -1070,12 +1332,6 @@
             "once": "^1.3.0",
             "path-is-absolute": "^1.0.0"
           }
-        },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
         }
       }
     },
@@ -1092,11 +1348,11 @@
       "dev": true
     },
     "graphlib": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-1.0.7.tgz",
-      "integrity": "sha1-DKst8P/mq+BwsmJb+h7bbslnuLE=",
+      "version": "2.1.8",
+      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
       "requires": {
-        "lodash": "^3.10.0"
+        "lodash": "^4.17.15"
       }
     },
     "grunt": {
@@ -1356,12 +1612,6 @@
           "requires": {
             "lodash": "^4.17.14"
           }
-        },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
         }
       }
     },
@@ -1381,14 +1631,6 @@
         "grunt-legacy-log-utils": "~2.0.0",
         "hooker": "~0.2.3",
         "lodash": "~4.17.5"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-legacy-log-utils": {
@@ -1399,14 +1641,6 @@
       "requires": {
         "chalk": "~2.4.1",
         "lodash": "~4.17.10"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-legacy-util": {
@@ -1422,14 +1656,6 @@
         "lodash": "~4.17.10",
         "underscore.string": "~3.3.4",
         "which": "~1.3.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-middleware-proxy": {
@@ -1535,6 +1761,17 @@
         "param-case": "2.1.x",
         "relateurl": "0.2.x",
         "uglify-js": "2.7.x"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.9.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+          "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+          "dev": true,
+          "requires": {
+            "graceful-readlink": ">= 1.0.0"
+          }
+        }
       }
     },
     "http-errors": {
@@ -1549,6 +1786,12 @@
         "statuses": ">= 1.4.0 < 2"
       },
       "dependencies": {
+        "depd": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+          "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+          "dev": true
+        },
         "inherits": {
           "version": "2.0.3",
           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
@@ -1584,7 +1827,6 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
       "requires": {
         "safer-buffer": ">= 2.1.2 < 3"
       }
@@ -1852,9 +2094,9 @@
       }
     },
     "lodash": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-      "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
     },
     "longest": {
       "version": "1.0.1",
@@ -1993,20 +2235,12 @@
       "dev": true
     },
     "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
       "dev": true,
       "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        }
+        "minimist": "^1.2.5"
       }
     },
     "moment": {
@@ -2023,16 +2257,16 @@
       }
     },
     "morgan": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
-      "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
+      "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
       "dev": true,
       "requires": {
-        "basic-auth": "~2.0.0",
+        "basic-auth": "~2.0.1",
         "debug": "2.6.9",
-        "depd": "~1.1.2",
+        "depd": "~2.0.0",
         "on-finished": "~2.3.0",
-        "on-headers": "~1.0.1"
+        "on-headers": "~1.0.2"
       }
     },
     "ms": {
@@ -2155,12 +2389,6 @@
             "supports-color": "^2.0.0"
           }
         },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        },
         "supports-color": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@@ -2456,9 +2684,9 @@
       "dev": true
     },
     "psl": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
-      "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
       "dev": true
     },
     "punycode": {
@@ -2468,9 +2696,9 @@
       "dev": true
     },
     "qs": {
-      "version": "6.9.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
-      "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==",
+      "version": "6.9.3",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz",
+      "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==",
       "dev": true
     },
     "range-parser": {
@@ -2628,9 +2856,9 @@
       "integrity": "sha1-ExOHM2E/xEV7fhJH6Mt1HfeqVCk="
     },
     "resolve": {
-      "version": "1.15.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
-      "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
+      "version": "1.16.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz",
+      "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==",
       "dev": true,
       "requires": {
         "path-parse": "^1.0.6"
@@ -2685,6 +2913,11 @@
         }
       }
     },
+    "rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
+    },
     "rx": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
@@ -2705,8 +2938,7 @@
     "safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
     "sass-graph": {
       "version": "2.2.4",
@@ -2737,12 +2969,6 @@
             "wrap-ansi": "^2.0.0"
           }
         },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        },
         "yargs": {
           "version": "7.1.0",
           "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
@@ -2823,6 +3049,12 @@
         "statuses": "~1.5.0"
       },
       "dependencies": {
+        "depd": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+          "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+          "dev": true
+        },
         "http-errors": {
           "version": "1.7.3",
           "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
@@ -2890,9 +3122,9 @@
       "dev": true
     },
     "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
     },
     "source-map": {
diff --git a/dashboardv2/package.json b/dashboardv2/package.json
index be5902d..e0809d3 100644
--- a/dashboardv2/package.json
+++ b/dashboardv2/package.json
@@ -32,8 +32,8 @@
     "bootstrap-daterangepicker": "2.1.25",
     "d3": "3.5.17",
     "d3-tip": "0.6.8",
-    "dagre-d3": "0.4.17",
-    "dropzone": "5.5.1",
+    "dagre-d3": "0.6.4",
+    "dropzone": "5.7.0",
     "font-awesome": "4.7.0",
     "jQuery-QueryBuilder": "2.4.3",
     "jquery": "3.3.1",
diff --git a/dashboardv2/public/css/scss/graph.scss b/dashboardv2/public/css/scss/graph.scss
index 4cb61ee..d68af45 100644
--- a/dashboardv2/public/css/scss/graph.scss
+++ b/dashboardv2/public/css/scss/graph.scss
@@ -48,6 +48,16 @@
 
     .label {
         fill: $color_suva_gray_approx;
+
+        &.highlight {
+            cursor: pointer;
+            fill: $color_havelock_blue_approx;
+            text-decoration: underline;
+
+            tspan {
+                font-weight: 400;
+            }
+        }
     }
 
     circle {
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index 0b4f835..a4fc184 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -576,7 +576,8 @@ td.searchTableName:hover {
             }
         }
 
-        image {
+        image,
+        circle {
             opacity: 0.2;
             //animation: blink 2.5s infinite;
         }
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 0fd5f80..9361a7b 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -42,7 +42,7 @@ require.config({
      * @default 7 seconds
      * @type {Number}
      */
-    'waitSeconds': 30,
+    'waitSeconds': 0,
 
     'shim': {
         'backbone': {
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 0f99ca5..737de8e 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -109,7 +109,6 @@ define(['require',
                     selectedNode: ''
                 }
             },
-
             initializeGraph: function() {
                 this.g = {};
                 this.g = new dagreD3.graphlib.Graph()
@@ -129,17 +128,15 @@ define(['require',
             },
             onRender: function() {
                 var that = this;
+                this.ui.searchToggler.prop("disabled", true);
+                this.$graphButtonsEl = this.$(".graph-button-group button,select[data-id='selectDepth']")
                 this.fetchGraphData();
-
-
                 if (platform.name === "IE") {
                     this.$('svg').css('opacity', '0');
 
                 }
-
                 if (platform.name === "Microsoft Edge" || platform.name === "IE") {
                     $(that.ui.saveSvg).hide();
-
                 }
                 if (this.layoutRendered) {
                     this.layoutRendered();
@@ -177,15 +174,22 @@ define(['require',
                 panel.toggleClass('fullscreen-mode');
             },
             onCheckUnwantedEntity: function(e) {
-                var data = $.extend(true, {}, this.lineageData);
-                //this.fromToNodeData = {};
+                var that = this;
                 this.initializeGraph();
                 if ($(e.target).data("id") === "checkHideProcess") {
                     this.filterObj.isProcessHideCheck = e.target.checked;
                 } else {
                     this.filterObj.isDeletedEntityHideCheck = e.target.checked;
                 }
-                this.generateData({ "relationshipMap": this.relationshipMap, "guidEntityMap": this.guidEntityMap });
+                that.toggleDisableState({
+                    "el": that.$graphButtonsEl
+                });
+                this.generateData(this.lineageData).then(function() {
+                    that.createGraph();
+                    that.toggleDisableState({
+                        "el": that.$graphButtonsEl
+                    });
+                });
             },
             toggleBoxPanel: function(options) {
                 var el = options && options.el,
@@ -214,11 +218,9 @@ define(['require',
                 this.filterObj.depthCount = e.currentTarget.value;
                 this.fetchGraphData({ queryParam: { 'depth': this.filterObj.depthCount } });
             },
-
             fetchGraphData: function(options) {
                 var that = this,
                     queryParam = options && options.queryParam || {};
-                this.fromToNodeData = {};
                 this.$('.fontLoader').show();
                 this.$('svg>g').hide();
                 this.toggleDisableState({
@@ -232,16 +234,18 @@ define(['require',
                         }
                         if (data.relations.length) {
                             that.lineageData = $.extend(true, {}, data);
-                            that.relationshipMap = that.crateLineageRelationshipHashMap(data);
-                            that.guidEntityMap = $.extend(true, {}, data.guidEntityMap);
-                            that.generateData({ "relationshipMap": that.relationshipMap, "guidEntityMap": that.guidEntityMap });
-                            that.toggleDisableState({
-                                "el": that.$(".graph-button-group button,select[data-id='selectDepth']")
+                            that.generateData(that.lineageData).then(function(graphObj) {
+                                that.createGraph();
+                                that.toggleDisableState({
+                                    "el": that.$graphButtonsEl
+                                });
+                            });
+                            that.renderLineageTypeSearch().then(function() {
+                                that.ui.searchToggler.prop("disabled", false);
                             });
                         } else {
                             that.noLineage();
                             that.hideCheckForProcess();
-
                         }
                     },
                     cust_error: function(model, response) {
@@ -286,7 +290,6 @@ define(['require',
                 var returnObj = {
                     isProcess: (isProcessHideCheck && node.isProcess),
                     isDeleted: (isDeletedEntityHideCheck && node.isDeleted)
-
                 };
                 returnObj["update"] = returnObj.isProcess || returnObj.isDeleted;
                 return returnObj;
@@ -317,177 +320,184 @@ define(['require',
                 }
                 return serviceType;
             },
-            crateLineageRelationshipHashMap: function(data) {
-                var that = this,
-                    relations = data && data.relations,
-                    guidEntityMap = data && data.guidEntityMap,
-                    makeNodeData = function(relationObj) {
-                        var obj = $.extend(true, {
-                            shape: "img",
-                            label: relationObj.displayText.trunc(18),
-                            toolTipLabel: relationObj.displayText,
-                            id: relationObj.guid,
-                            isLineage: true,
-                            isIncomplete: relationObj.isIncomplete,
-                            entityDef: this.getEntityDef(relationObj.typeName)
-                        }, relationObj);
-                        obj["serviceType"] = this.getServiceType({ typeName: relationObj.typeName, entityDef: obj.entityDef });
-                        obj["superTypes"] = this.getNestedSuperTypes({ entityDef: obj.entityDef });
-                        obj['isProcess'] = this.isProcess(obj);
-                        obj['isDeleted'] = this.isDeleted(obj);
-                        return obj;
-                    }.bind(this),
-                    newHashMap = {};
-                _.each(relations, function(obj) {
-                    if (!that.fromToNodeData[obj.fromEntityId]) {
-                        that.fromToNodeData[obj.fromEntityId] = makeNodeData(guidEntityMap[obj.fromEntityId]);
-                    }
-                    if (!that.fromToNodeData[obj.toEntityId]) {
-                        that.fromToNodeData[obj.toEntityId] = makeNodeData(guidEntityMap[obj.toEntityId]);
-                    }
-                    if (newHashMap[obj.fromEntityId]) {
-                        newHashMap[obj.fromEntityId].push(obj.toEntityId);
-                    } else {
-                        newHashMap[obj.fromEntityId] = [obj.toEntityId];
-                    }
-                });
-                return newHashMap;
-            },
             generateData: function(options) {
-                var that = this,
-                    relationshipMap = options && $.extend(true, {}, options.relationshipMap) || {},
-                    guidEntityMap = options && options.guidEntityMap || {},
-                    styleObj = {
-                        fill: 'none',
-                        stroke: '#ffb203',
-                        width: 3
-                    },
-                    getStyleObjStr = function(styleObj) {
-                        return 'fill:' + styleObj.fill + ';stroke:' + styleObj.stroke + ';stroke-width:' + styleObj.width;
-                    },
-                    filterRelationshipMap = relationshipMap,
-                    isHideFilterOn = this.filterObj.isProcessHideCheck || this.filterObj.isDeletedEntityHideCheck,
-                    getNewToNodeRelationship = function(toNodeGuid) {
-                        if (toNodeGuid && relationshipMap[toNodeGuid]) {
-                            var newRelationship = [];
-                            _.each(relationshipMap[toNodeGuid], function(guid) {
-                                var nodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[guid]);
-                                if (nodeToBeUpdated.update) {
-                                    var newRelation = getNewToNodeRelationship(guid);
-                                    if (newRelation) {
-                                        newRelationship = newRelationship.concat(newRelation);
+                return new Promise(function(resolve, reject) {
+                    try {
+                        var that = this,
+                            relations = options && options.relations || {},
+                            guidEntityMap = options && options.guidEntityMap || {},
+                            isHideFilterOn = this.filterObj.isProcessHideCheck || this.filterObj.isDeletedEntityHideCheck,
+                            newHashMap = {},
+                            styleObj = {
+                                fill: 'none',
+                                stroke: '#ffb203',
+                                width: 3
+                            },
+                            makeNodeData = function(relationObj) {
+                                if (relationObj) {
+                                    if (relationObj.updatedValues) {
+                                        return relationObj;
+                                    }
+                                    var obj = _.extend(relationObj, {
+                                        shape: "img",
+                                        updatedValues: true,
+                                        label: relationObj.displayText.trunc(18),
+                                        toolTipLabel: relationObj.displayText,
+                                        id: relationObj.guid,
+                                        isLineage: true,
+                                        isIncomplete: relationObj.isIncomplete,
+                                        entityDef: that.getEntityDef(relationObj.typeName)
+                                    });
+                                    obj["serviceType"] = that.getServiceType({ typeName: relationObj.typeName, entityDef: obj.entityDef });
+                                    obj["superTypes"] = that.getNestedSuperTypes({ entityDef: obj.entityDef });
+                                    obj['isProcess'] = that.isProcess(obj);
+                                    obj['isDeleted'] = that.isDeleted(obj);
+                                    return obj;
+                                }
+                            },
+                            crateLineageRelationshipHashMap = function(data) {
+                                var that = this,
+                                    relations = data && data.relations,
+                                    newHashMap = {};
+                                _.each(relations, function(obj) {
+                                    if (newHashMap[obj.fromEntityId]) {
+                                        newHashMap[obj.fromEntityId].push(obj.toEntityId);
+                                    } else {
+                                        newHashMap[obj.fromEntityId] = [obj.toEntityId];
                                     }
+                                });
+                                return newHashMap;
+                            },
+                            getStyleObjStr = function(styleObj) {
+                                return 'fill:' + styleObj.fill + ';stroke:' + styleObj.stroke + ';stroke-width:' + styleObj.width;
+                            },
+                            getNewToNodeRelationship = function(toNodeGuid) {
+                                if (toNodeGuid && relationshipMap[toNodeGuid]) {
+                                    var newRelationship = [];
+                                    _.each(relationshipMap[toNodeGuid], function(guid) {
+                                        var nodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[guid]));
+                                        if (nodeToBeUpdated.update) {
+                                            var newRelation = getNewToNodeRelationship(guid);
+                                            if (newRelation) {
+                                                newRelationship = newRelationship.concat(newRelation);
+                                            }
+                                        } else {
+                                            newRelationship.push(guid);
+                                        }
+                                    });
+                                    return newRelationship;
                                 } else {
-                                    newRelationship.push(guid);
+                                    return null;
                                 }
-                            });
-                            return newRelationship;
-                        } else {
-                            return null;
-                        }
-                    },
-                    getToNodeRelation = function(toNodes, fromNodeToBeUpdated) {
-                        var toNodeRelationship = [];
-                        _.each(toNodes, function(toNodeGuid) {
-                            var toNodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[toNodeGuid]);
-                            if (toNodeToBeUpdated.update) {
-                                // To node need to updated
-                                if (pendingFromRelationship[toNodeGuid]) {
-                                    toNodeRelationship = toNodeRelationship.concat(pendingFromRelationship[toNodeGuid]);
+                            },
+                            getToNodeRelation = function(toNodes, fromNodeToBeUpdated) {
+                                var toNodeRelationship = [];
+                                _.each(toNodes, function(toNodeGuid) {
+                                    var toNodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[toNodeGuid]));
+                                    if (toNodeToBeUpdated.update) {
+                                        // To node need to updated
+                                        if (pendingFromRelationship[toNodeGuid]) {
+                                            toNodeRelationship = toNodeRelationship.concat(pendingFromRelationship[toNodeGuid]);
+                                        } else {
+                                            var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid);
+                                            if (newToNodeRelationship) {
+                                                toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
+                                            }
+                                        }
+                                    } else {
+                                        //when bothe node not to be updated.
+                                        toNodeRelationship.push(toNodeGuid);
+                                    }
+                                });
+                                return toNodeRelationship;
+                            },
+                            setNode = function(guid) {
+                                if (!that.g._nodes[guid]) {
+                                    var nodeData = makeNodeData(guidEntityMap[guid]);
+                                    that.g.setNode(guid, nodeData);
+                                    return nodeData;
                                 } else {
-                                    var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid);
-                                    if (newToNodeRelationship) {
-                                        toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
+                                    return that.g._nodes[guid];
+                                }
+                            },
+                            setEdge = function(fromNodeGuid, toNodeGuid) {
+                                that.g.setEdge(fromNodeGuid, toNodeGuid, {
+                                    "arrowhead": 'arrowPoint',
+                                    "curve": LineageUtils.BezierCurve,
+                                    "style": getStyleObjStr(styleObj),
+                                    "styleObj": styleObj
+                                });
+                            },
+                            setGraphData = function(fromEntityId, toEntityId) {
+                                setNode(fromEntityId);
+                                setNode(toEntityId);
+                                setEdge(fromEntityId, toEntityId);
+                            },
+                            pendingFromRelationship = {};
+                        if (isHideFilterOn) {
+                            var relationshipMap = crateLineageRelationshipHashMap(options)
+                            _.each(relationshipMap, function(toNodes, fromNodeGuid) {
+                                var fromNodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[fromNodeGuid])),
+                                    toNodeList = getToNodeRelation(toNodes, fromNodeToBeUpdated);
+                                if (fromNodeToBeUpdated.update) {
+                                    if (pendingFromRelationship[fromNodeGuid]) {
+                                        pendingFromRelationship[fromNodeGuid] = pendingFromRelationship[fromNodeGuid].concat(toNodeList);
+                                    } else {
+                                        pendingFromRelationship[fromNodeGuid] = toNodeList;
                                     }
+                                } else {
+                                    _.each(toNodeList, function(toNodeGuid) {
+                                        setGraphData(fromNodeGuid, toNodeGuid);
+                                    });
                                 }
-                            } else {
-                                //when bothe node not to be updated.
-                                toNodeRelationship.push(toNodeGuid);
-                            }
-                        });
-                        return toNodeRelationship;
-                    },
-                    pendingFromRelationship = {};
-                if (isHideFilterOn) {
-                    filterRelationshipMap = {};
-                    _.each(relationshipMap, function(toNodes, fromNodeGuid) {
-                        var fromNodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[fromNodeGuid]),
-                            toNodeList = getToNodeRelation(toNodes, fromNodeToBeUpdated);
-                        if (fromNodeToBeUpdated.update) {
-                            if (pendingFromRelationship[fromNodeGuid]) {
-                                pendingFromRelationship[fromNodeGuid] = pendingFromRelationship[fromNodeGuid].concat(toNodeList);
-                            } else {
-                                pendingFromRelationship[fromNodeGuid] = toNodeList;
-                            }
+                            })
                         } else {
-                            if (filterRelationshipMap[fromNodeGuid]) {
-                                filterRelationshipMap[fromNodeGuid] = filterRelationshipMap[fromNodeGuid].concat(toNodeList);
-                            } else {
-                                filterRelationshipMap[fromNodeGuid] = toNodeList;
+                            _.each(relations, function(obj) {
+                                setGraphData(obj.fromEntityId, obj.toEntityId);
+                            });
+                        }
+                        if (this.g._nodes[this.guid]) {
+                            if (this.g._nodes[this.guid]) {
+                                this.g._nodes[this.guid]['isLineage'] = false;
                             }
+                            this.findImpactNodeAndUpdateData({ "guid": this.guid, "getStyleObjStr": getStyleObjStr });
                         }
-                    })
-                }
-
-                _.each(filterRelationshipMap, function(toNodesList, fromNodeGuid) {
-                    if (!that.g._nodes[fromNodeGuid]) {
-                        that.g.setNode(fromNodeGuid, that.fromToNodeData[fromNodeGuid]);
+                        resolve(this.g);
+                    } catch (e) {
+                        reject(e)
                     }
-                    _.each(toNodesList, function(toNodeGuid) {
-                        if (!that.g._nodes[toNodeGuid]) {
-                            that.g.setNode(toNodeGuid, that.fromToNodeData[toNodeGuid]);
-                        }
-                        that.g.setEdge(fromNodeGuid, toNodeGuid, {
-                            "arrowhead": 'arrowPoint',
-                            "lineInterpolate": 'basis',
-                            "style": getStyleObjStr(styleObj),
-                            'styleObj': styleObj
-                        });
-                    })
-                })
-
-                //if no relations found
-                if (_.isEmpty(filterRelationshipMap)) {
-                    this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No relations to display</text>');
-                }
-
-                if (this.fromToNodeData[this.guid]) {
-                    this.fromToNodeData[this.guid]['isLineage'] = false;
-                    this.findImpactNodeAndUpdateData({ "relationshipMap": filterRelationshipMap, "guid": this.guid, "getStyleObjStr": getStyleObjStr });
-                }
-                this.renderLineageTypeSearch();
-                this.createGraph();
+                }.bind(this));
             },
             findImpactNodeAndUpdateData: function(options) {
                 var that = this,
-                    relationshipMap = options.relationshipMap,
-                    fromNodeGuid = options.guid,
+                    guid = options.guid,
                     getStyleObjStr = options.getStyleObjStr,
-                    toNodeList = relationshipMap[fromNodeGuid];
-                if (toNodeList && toNodeList.length) {
-                    if (!relationshipMap[fromNodeGuid]["traversed"]) {
-                        relationshipMap[fromNodeGuid]["traversed"] = true;
-                        _.each(toNodeList, function(toNodeGuid) {
-                            that.fromToNodeData[toNodeGuid]['isLineage'] = false;
-                            var styleObj = {
-                                fill: 'none',
-                                stroke: '#fb4200',
-                                width: 3
+                    traversedMap = {},
+                    styleObj = {
+                        fill: 'none',
+                        stroke: '#fb4200',
+                        width: 3
+                    },
+                    traversed = function(toNodeList, fromNodeGuid) {
+                        if (!_.isEmpty(toNodeList)) {
+                            if (!traversedMap[fromNodeGuid]) {
+                                traversedMap[fromNodeGuid] = true;
+                                _.each(toNodeList, function(val, toNodeGuid) {
+                                    if (that.g._nodes[toNodeGuid]) {
+                                        that.g._nodes[toNodeGuid]['isLineage'] = false;
+                                    }
+                                    that.g.setEdge(fromNodeGuid, toNodeGuid, {
+                                        "arrowhead": 'arrowPoint',
+                                        "curve": LineageUtils.BezierCurve,
+                                        "style": getStyleObjStr(styleObj),
+                                        'styleObj': styleObj
+                                    });
+                                    traversed(that.g._sucs[toNodeGuid], toNodeGuid);
+                                });
                             }
-                            that.g.setEdge(fromNodeGuid, toNodeGuid, {
-                                "arrowhead": 'arrowPoint',
-                                "lineInterpolate": 'basis',
-                                "style": getStyleObjStr(styleObj),
-                                'styleObj': styleObj
-                            });
-                            that.findImpactNodeAndUpdateData({
-                                "relationshipMap": relationshipMap,
-                                "guid": toNodeGuid,
-                                "getStyleObjStr": getStyleObjStr
-                            });
-                        });
-                    }
-                }
+                        }
+                    };
+                traversed(this.g._sucs[guid], guid)
             },
             zoomed: function(that) {
                 this.$('svg').find('>g').attr("transform",
@@ -513,6 +523,10 @@ define(['require',
                 });
             },
             createGraph: function() {
+                if (_.isEmpty(this.g._nodes)) {
+                    this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No relations to display</text>');
+                    return;
+                }
                 var that = this,
                     width = this.$('svg').width(),
                     height = this.$('svg').height(),
@@ -529,111 +543,12 @@ define(['require',
                 // Create the renderer
                 var render = new dagreD3.render();
                 // Add our custom arrow (a hollow-point)
-                render.arrows().arrowPoint = function normal(parent, id, edge, type) {
-                    var parentNode = parent && parent[0] && parent[0][0] && parent[0][0].parentNode ? parent[0][0].parentNode : parent;
-                    d3.select(parentNode).select('path.path').attr('marker-end', "url(#" + id + ")");
-                    var marker = parent.append("marker")
-                        .attr("id", id)
-                        .attr("viewBox", "0 0 10 10")
-                        .attr("refX", 8)
-                        .attr("refY", 5)
-                        .attr("markerUnits", "strokeWidth")
-                        .attr("markerWidth", 4)
-                        .attr("markerHeight", 4)
-                        .attr("orient", "auto");
-
-                    var path = marker.append("path")
-                        .attr("d", "M 0 0 L 10 5 L 0 10 z")
-                        .style("fill", edge.styleObj.stroke);
-                    dagreD3.util.applyStyle(path, edge[type + "Style"]);
+                render.arrows().arrowPoint = function(parent, id, edge, type) {
+                    return LineageUtils.arrowPointRender(parent, id, edge, type, { guid: that.guid, dagreD3: dagreD3 });
                 };
-                render.shapes().img = function circle(parent, bbox, node) {
-                    //var r = Math.max(bbox.width, bbox.height) / 2,
-                    if (node.id == that.guid) {
-                        var currentNode = true
-                    }
-                    var shapeSvg = parent.append('circle')
-                        .attr('fill', 'url(#img_' + node.id + ')')
-                        .attr('r', '24px')
-                        .attr('data-stroke', node.id)
-                        .attr('stroke-width', "2px")
-                        .attr("class", "nodeImage " + (currentNode ? "currentNode" : (node.isProcess ? "process" : "node")));
-                    if (currentNode) {
-                        shapeSvg.attr("stroke", "#fb4200")
-                    }
-                    if (node.isIncomplete === true) {
-                        parent.attr("class", "node isIncomplete show");
-                    } else {
-                        parent.attr("class", "node isIncomplete");
-                    }
-
-                    parent.insert("defs")
-                        .append("pattern")
-                        .attr("x", "0%")
-                        .attr("y", "0%")
-                        .attr("patternUnits", "objectBoundingBox")
-                        .attr("id", "img_" + node.id)
-                        .attr("width", "100%")
-                        .attr("height", "100%")
-                        .append('image')
-                        .attr("href", function(d) {
-                            var that = this;
-                            if (node) {
-                                var imageIconPath = Utils.getEntityIconPath({ entityData: node });
-
-                                var getImageData = function(options) {
-                                    var imagePath = options.imagePath,
-                                        ajaxOptions = {
-                                            "url": imagePath,
-                                            "method": "get",
-                                            "cache": true
-                                        }
-
-                                    if (platform.name !== "IE") {
-                                        ajaxOptions["mimeType"] = "text/plain; charset=x-user-defined";
-                                    }
-                                    shapeSvg.attr("data-iconpath", imagePath);
-                                    $.ajax(ajaxOptions)
-                                        .always(function(data, status, xhr) {
-                                            if (data.status == 404) {
-                                                getImageData({
-                                                    "imagePath": Utils.getEntityIconPath({ entityData: node, errorUrl: imagePath })
-                                                });
-                                            } else if (data) {
-                                                if (platform.name !== "IE") {
-                                                    imageObject[imageIconPath] = 'data:image/png;base64,' + LineageUtils.base64Encode({ "data": data });
-                                                } else {
-                                                    imageObject[imageIconPath] = imagePath;
-                                                }
-                                                d3.select(that).attr("xlink:href", imageObject[imageIconPath]);
-                                                if (imageIconPath !== shapeSvg.attr("data-iconpath")) {
-                                                    shapeSvg.attr("data-iconpathorigin", imageIconPath);
-                                                }
-                                            }
-                                        });
-                                }
-                                getImageData({
-                                    "imagePath": imageIconPath
-                                });
-                            }
-                        })
-                        .attr("x", "4")
-                        .attr("y", currentNode ? "3" : "4").attr("width", "40")
-                        .attr("height", "40");
-
-                    parent.insert("foreignObject")
-                        .attr("x", "-25")
-                        .attr("y", "-25")
-                        .attr("width", "50")
-                        .attr("height", "50")
-                        .append("xhtml:div")
-                        .insert("i")
-                        .attr("class", "fa fa-hourglass-half");
-
-                    node.intersect = function(point) {
-                        return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
-                    };
-                    return shapeSvg;
+                // Render custom img inside shape
+                render.shapes().img = function(parent, bbox, node) {
+                    return LineageUtils.imgShapeRender(parent, bbox, node, { guid: that.guid, dagreD3: dagreD3, imageObject: imageObject, $defs: that.svg.select('defs') });
                 };
                 // Set up an SVG group so that we can translate the final graph.
                 if (this.$("svg").find('.output').length) {
@@ -643,6 +558,8 @@ define(['require',
                     .attr("viewBox", "0 0 " + width + " " + height)
                     .attr("enable-background", "new 0 0 " + width + " " + height),
                     svgGroup = svg.append("g");
+                // Append defs
+                svg.append("defs");
                 var zoom = this.zoom = d3.behavior.zoom()
                     .center([width / 2, height / 2])
                     .scaleExtent([0.01, 50])
@@ -702,8 +619,29 @@ define(['require',
                 // .on("wheel.zoom", null);
                 //change text postion 
                 svgGroup.selectAll("g.nodes g.label")
-                    .attr("transform", "translate(2,-35)");
-                var waitForDoubleClick = null;
+                    .attr("transform", "translate(2,-35)")
+                    .on('mouseenter', function(d) {
+                        d3.select(this).classed("highlight", true);
+                    })
+                    .on('mouseleave', function(d) {
+                        d3.select(this).classed("highlight", false);
+                    })
+                    .on('click', function(d) {
+                        d3.event.preventDefault();
+                        tooltip.hide(d);
+                        if (that.guid == d) {
+                            Utils.notifyInfo({
+                                html: true,
+                                content: "You are already on " + "<b>" + that.entityName + "</b> detail page."
+                            });
+                        } else {
+                            Utils.setUrl({
+                                url: '#!/detailPage/' + d + '?tabActive=lineage',
+                                mergeBrowserUrl: false,
+                                trigger: true
+                            });
+                        }
+                    });
                 svgGroup.selectAll("g.nodes g.node")
                     .on('mouseenter', function(d) {
                         that.activeNode = true;
@@ -773,33 +711,10 @@ define(['require',
                         var el = this;
                         if (d3.event.defaultPrevented) return; // ignore drag
                         d3.event.preventDefault();
-
-                        if (waitForDoubleClick != null) {
-                            clearTimeout(waitForDoubleClick)
-                            waitForDoubleClick = null;
-                            tooltip.hide(d);
-                            if (that.guid == d) {
-                                Utils.notifyInfo({
-                                    html: true,
-                                    content: "You are already on " + "<b>" + that.entityName + "</b> detail page."
-                                });
-                            } else {
-                                Utils.setUrl({
-                                    url: '#!/detailPage/' + d + '?tabActive=lineage',
-                                    mergeBrowserUrl: false,
-                                    trigger: true
-                                });
-                            }
-                        } else {
-                            var currentEvent = d3.event
-                            waitForDoubleClick = setTimeout(function() {
-                                tooltip.hide(d);
-                                that.onClickNodeToggler({ obj: d });
-                                $(el).find('circle').addClass('node-detail-highlight');
-                                that.updateRelationshipDetails({ guid: d });
-                                waitForDoubleClick = null;
-                            }, 170)
-                        }
+                        tooltip.hide(d);
+                        that.onClickNodeToggler({ obj: d });
+                        $(el).find('circle').addClass('node-detail-highlight');
+                        that.updateRelationshipDetails({ guid: d });
                     });
 
                 svgGroup.selectAll("g.edgePath path.path").on('click', function(d) {
@@ -853,27 +768,32 @@ define(['require',
                 }).init();
             },
             renderLineageTypeSearch: function() {
-                var that = this,
-                    lineageData = $.extend(true, {}, this.lineageData),
-                    data = [],
-                    typeStr = '<option></option>';
-                if (!_.isEmpty(lineageData)) {
-                    _.each(lineageData.guidEntityMap, function(obj, index) {
-                        var nodeData = that.fromToNodeData[obj.guid];
-                        if (that.filterObj.isProcessHideCheck && nodeData && nodeData.isProcess) {
-                            return;
-                        } else if (that.filterObj.isDeletedEntityHideCheck && nodeData && nodeData.isDeleted) {
-                            return
+                var that = this;
+                return new Promise(function(resolve, reject) {
+                    try {
+                        var data = [],
+                            typeStr = '<option></option>';
+                        if (!_.isEmpty(that.lineageData)) {
+                            _.each(that.lineageData.guidEntityMap, function(obj, index) {
+                                var nodeData = that.g._nodes[obj.guid];
+                                if ((that.filterObj.isProcessHideCheck || that.filterObj.isDeletedEntityHideCheck) && nodeData && (nodeData.isProcess || nodeData.isDeleted)) {
+                                    return;
+                                }
+                                typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
+                            });
                         }
-                        typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
-                    });
-                }
-                this.ui.lineageTypeSearch.html(typeStr);
-                this.initilizelineageTypeSearch();
+                        that.ui.lineageTypeSearch.html(typeStr);
+                        that.initilizelineageTypeSearch();
+                        resolve();
+                    } catch (e) {
+                        console.log(e);
+                        reject(e);
+                    }
+                })
             },
             initilizelineageTypeSearch: function() {
                 var that = this;
-                that.ui.lineageTypeSearch.select2({
+                this.ui.lineageTypeSearch.select2({
                     closeOnSelect: true,
                     placeholder: 'Select Node'
                 }).on('change.select2', function(e) {
@@ -915,19 +835,18 @@ define(['require',
                             return false;
                         }
                     });
-
                 });
-                if (that.searchNodeObj.selectedNode) {
-                    that.ui.lineageTypeSearch.val(that.searchNodeObj.selectedNode);
-                    that.ui.lineageTypeSearch.trigger("change.select2");
+                if (this.searchNodeObj.selectedNode) {
+                    this.ui.lineageTypeSearch.val(this.searchNodeObj.selectedNode);
+                    this.ui.lineageTypeSearch.trigger("change.select2");
                 }
             },
             updateRelationshipDetails: function(options) {
                 var that = this,
                     guid = options.guid,
-                    initialData = that.guidEntityMap[guid],
+                    initialData = that.g._nodes[guid],
                     typeName = initialData.typeName || guid,
-                    attributeDefs = that.g._nodes[guid] && that.g._nodes[guid].entityDef ? that.g._nodes[guid].entityDef.attributeDefs : null;
+                    attributeDefs = initialData && initialData.entityDef ? initialData.entityDef.attributeDefs : null;
                 this.$("[data-id='typeName']").text(typeName);
                 this.entityModel = new VEntity({});
                 var config = {
@@ -959,109 +878,28 @@ define(['require',
                 }));
             },
             onClickSaveSvg: function(e, a) {
-                var that = this;
-                var loaderTargetDiv = $(e.currentTarget).find('>i');
-
+                var that = this,
+                    loaderTargetDiv = $(e.currentTarget).find('>i');
                 if (loaderTargetDiv.hasClass('fa-refresh')) {
                     Utils.notifyWarn({
                         content: "Please wait while the lineage gets downloaded"
                     });
                     return false; // return if the lineage is not loaded.
                 }
-
-
-                that.toggleLoader(loaderTargetDiv);
+                this.toggleLoader(loaderTargetDiv);
                 Utils.notifyInfo({
                     content: "Lineage will be downloaded in a moment."
                 });
-                setTimeout(function() {
-                    var svg = that.$('svg')[0],
-                        svgClone = svg.cloneNode(true),
-                        scaleFactor = 1,
-                        svgWidth = that.$('svg').width(),
-                        svgHeight = that.$('svg').height();
-                    if (platform.name === "Firefox") {
-                        svgClone.setAttribute('width', svgWidth);
-                        svgClone.setAttribute('height', svgHeight);
-                    }
-                    $('.hidden-svg').html(svgClone);
-                    $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
-                    $(svgClone).find("foreignObject").remove();
-                    var canvasOffset = { x: 150, y: 150 },
-                        setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
-                        setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
-                        xAxis = svgClone.getBBox().x,
-                        yAxis = svgClone.getBBox().y;
-                    svgClone.attributes.viewBox.value = xAxis + "," + yAxis + "," + setWidth + "," + setHeight;
-
-                    var createCanvas = document.createElement('canvas');
-                    createCanvas.id = "canvas";
-                    createCanvas.style.display = 'none';
-
-                    var body = $('body').append(createCanvas),
-                        canvas = $('canvas')[0];
-                    canvas.width = (svgClone.getBBox().width * scaleFactor) + canvasOffset.x;
-                    canvas.height = (svgClone.getBBox().height * scaleFactor) + canvasOffset.y;
-
-                    var ctx = canvas.getContext('2d'),
-                        data = (new XMLSerializer()).serializeToString(svgClone),
-                        DOMURL = window.URL || window.webkitURL || window;
-
-                    ctx.fillStyle = "#FFFFFF";
-                    ctx.fillRect(0, 0, canvas.width, canvas.height);
-                    ctx.strokeRect(0, 0, canvas.width, canvas.height);
-                    ctx.restore();
-
-                    var img = new Image(canvas.width, canvas.height);
-                    var svgBlob = new Blob([data], { type: 'image/svg+xml;base64' });
-                    if (platform.name === "Safari") {
-                        svgBlob = new Blob([data], { type: 'image/svg+xml' });
-                    }
-                    var url = DOMURL.createObjectURL(svgBlob);
-
-                    img.onload = function() {
-                        try {
-                            var a = document.createElement("a"),
-                                entityAttributes = that.entity && that.entity.attributes;
-                            a.download = ((entityAttributes && (entityAttributes.qualifiedName || entityAttributes.name) || "lineage_export") + ".png");
-                            document.body.appendChild(a);
-                            ctx.drawImage(img, 50, 50, canvas.width, canvas.height);
-                            canvas.toBlob(function(blob) {
-                                if (!blob) {
-                                    Utils.notifyError({
-                                        content: "There was an error in downloading Lineage!"
-                                    });
-                                    that.toggleLoader(loaderTargetDiv);
-                                    return;
-                                }
-                                a.href = DOMURL.createObjectURL(blob);
-                                if (blob.size > 10000000) {
-                                    Utils.notifyWarn({
-                                        content: "The Image size is huge, please open the image in a browser!"
-                                    });
-                                }
-                                a.click();
-                                that.toggleLoader(loaderTargetDiv);
-                                if (platform.name === 'Safari') {
-                                    LineageUtils.refreshGraphForSafari({
-                                        edgeEl: that.$('svg g.node')
-                                    });
-                                }
-                            }, 'image/png');
-                            $('.hidden-svg').html('');
-                            createCanvas.remove();
-
-                        } catch (err) {
-                            Utils.notifyError({
-                                content: "There was an error in downloading Lineage!"
-                            });
-                            that.toggleLoader(loaderTargetDiv);
-                        }
-
-                    };
-                    img.src = url;
-
-                }, 0)
+                var entityAttributes = that.entity && that.entity.attributes;
+                LineageUtils.SaveSvg(e, {
+                    svg: that.$('svg')[0],
+                    svgWidth: that.$('svg').width(),
+                    svgHeight: that.$('svg').height(),
+                    toggleLoader: function() {
+                        that.toggleLoader(loaderTargetDiv);
+                    },
+                    downloadFileName: ((entityAttributes && (entityAttributes.qualifiedName || entityAttributes.name) || "lineage_export") + ".png")
+                })
             },
             toggleLoader: function(element) {
                 if ((element).hasClass('fa-camera')) {
diff --git a/dashboardv2/public/js/views/graph/LineageUtils.js b/dashboardv2/public/js/views/graph/LineageUtils.js
index e1363a5..ed66782 100644
--- a/dashboardv2/public/js/views/graph/LineageUtils.js
+++ b/dashboardv2/public/js/views/graph/LineageUtils.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-define(['require'], function(require) {
+define(['require', 'utils/Utils'], function(require, Utils) {
     'use strict';
-    var LinegaeUtils = {};
-    LinegaeUtils.DragNode = function(options) {
+    var LineageUtils = {};
+    LineageUtils.DragNode = function(options) {
         var that = this,
             g = options.g,
             svg = options.svg,
@@ -99,7 +99,7 @@ define(['require'], function(require) {
                         }
                     }
                 });
-                LinegaeUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
+                LineageUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
             },
             translateEdge: function(e, dx, dy) {
                 e.points.forEach(function(p) {
@@ -158,7 +158,7 @@ define(['require'], function(require) {
             },
         }
     }
-    LinegaeUtils.refreshGraphForSafari = function(options) {
+    LineageUtils.refreshGraphForSafari = function(options) {
         var edgePathEl = options.edgeEl,
             IEGraphRenderDone = 0;
         edgePathEl.each(function(argument) {
@@ -169,7 +169,7 @@ define(['require'], function(require) {
             }, 500);
         });
     }
-    LinegaeUtils.refreshGraphForIE = function(options) {
+    LineageUtils.refreshGraphForIE = function(options) {
         var edgePathEl = options.edgeEl,
             IEGraphRenderDone = 0;
         edgePathEl.each(function(argument) {
@@ -187,7 +187,7 @@ define(['require'], function(require) {
             }, 1000);
         });
     }
-    LinegaeUtils.centerNode = function(options) {
+    LineageUtils.centerNode = function(options) {
         var nodeID = options.guid,
             svg = options.svg,
             g = options.g,
@@ -232,12 +232,12 @@ define(['require'], function(require) {
                 zoom.scale(scale);
                 afterCenterZoomed({ newScale: scale, newTranslate: [xa, ya] });
                 if (platform.name === "IE") {
-                    LinegaeUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
+                    LineageUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
                 }
             }
         }
     }
-    LinegaeUtils.onHoverFade = function(options) {
+    LineageUtils.onHoverFade = function(options) {
         var opacity = options.opacity,
             d = options.selectedNode,
             nodesToHighlight = options.highlight,
@@ -271,7 +271,7 @@ define(['require'], function(require) {
         }
 
     }
-    LinegaeUtils.base64Encode = function(options) {
+    LineageUtils.base64Encode = function(options) {
         var str = options.data,
             CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
             out = "",
@@ -302,5 +302,235 @@ define(['require'], function(require) {
         }
         return out;
     }
-    return LinegaeUtils;
+    LineageUtils.imgShapeRender = function(parent, bbox, node, viewOptions) {
+        var LineageUtilsRef = this,
+            imageIconPath = Utils.getEntityIconPath({ entityData: node }),
+            imgName = imageIconPath.split("/").pop(),
+            viewGuid = viewOptions.guid,
+            dagreD3 = viewOptions.dagreD3,
+            imageObject = viewOptions.imageObject,
+            $defs = viewOptions.$defs;
+        if (node.isDeleted) {
+            imgName = "deleted_" + imgName;
+        }
+        if (node.id == viewGuid) {
+            var currentNode = true
+        }
+        var shapeSvg = parent.append('circle')
+            .attr('fill', 'url(#img_' + imgName + ')')
+            .attr('r', '24px')
+            .attr('data-stroke', node.id)
+            .attr('stroke-width', "2px")
+            .attr("class", "nodeImage " + (currentNode ? "currentNode" : (node.isProcess ? "process" : "node")));
+        if (currentNode) {
+            shapeSvg.attr("stroke", "#fb4200")
+        }
+
+        if (node.isIncomplete === true) {
+            parent.attr("class", "node isIncomplete show");
+            parent.insert("foreignObject")
+                .attr("x", "-25")
+                .attr("y", "-25")
+                .attr("width", "50")
+                .attr("height", "50")
+                .append("xhtml:div")
+                .insert("i")
+                .attr("class", "fa fa-hourglass-half");
+        }
+
+        if ($defs.select('pattern[id="img_' + imgName + '"]').empty()) {
+            var $pattern = $defs.append("pattern")
+                .attr("x", "0%")
+                .attr("y", "0%")
+                .attr("patternUnits", "objectBoundingBox")
+                .attr("id", "img_" + imgName)
+                .attr("width", "100%")
+                .attr("height", "100%")
+                .append('image')
+                .attr("href", function(d) {
+                    var that = this;
+                    if (node) {
+                        var getImageData = function(options) {
+                            var imagePath = options.imagePath,
+                                ajaxOptions = {
+                                    "url": imagePath,
+                                    "method": "get",
+                                    "cache": true
+                                }
+
+                            if (platform.name !== "IE") {
+                                ajaxOptions["mimeType"] = "text/plain; charset=x-user-defined";
+                            }
+                            shapeSvg.attr("data-iconpath", imagePath);
+                            $.ajax(ajaxOptions)
+                                .always(function(data, status, xhr) {
+                                    if (data.status == 404) {
+                                        getImageData({
+                                            "imagePath": Utils.getEntityIconPath({ entityData: node, errorUrl: imagePath })
+                                        });
+                                    } else if (data) {
+                                        if (platform.name !== "IE") {
+                                            imageObject[imageIconPath] = 'data:image/png;base64,' + LineageUtilsRef.base64Encode({ "data": data });
+                                        } else {
+                                            imageObject[imageIconPath] = imagePath;
+                                        }
+                                        d3.select(that).attr("xlink:href", imageObject[imageIconPath]);
+                                        if (imageIconPath !== shapeSvg.attr("data-iconpath")) {
+                                            shapeSvg.attr("data-iconpathorigin", imageIconPath);
+                                        }
+                                    }
+                                });
+                        }
+                        getImageData({
+                            "imagePath": imageIconPath
+                        });
+                    }
+                })
+                .attr("x", "4")
+                .attr("y", currentNode ? "3" : "4").attr("width", "40")
+                .attr("height", "40");
+
+        }
+
+        node.intersect = function(point) {
+            return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
+        };
+        return shapeSvg;
+    }
+    LineageUtils.arrowPointRender = function(parent, id, edge, type, viewOptions) {
+        var node = parent.node(),
+            parentNode = node ? node.parentNode : parent,
+            dagreD3 = viewOptions.dagreD3;
+        d3.select(parentNode).select('path.path').attr('marker-end', "url(#" + id + ")");
+        var marker = parent.append("marker")
+            .attr("id", id)
+            .attr("viewBox", "0 0 10 10")
+            .attr("refX", 8)
+            .attr("refY", 5)
+            .attr("markerUnits", "strokeWidth")
+            .attr("markerWidth", 4)
+            .attr("markerHeight", 4)
+            .attr("orient", "auto");
+
+        var path = marker.append("path")
+            .attr("d", "M 0 0 L 10 5 L 0 10 z")
+            .style("fill", edge.styleObj.stroke);
+        dagreD3.util.applyStyle(path, edge[type + "Style"]);
+    }
+    LineageUtils.BezierCurve = function(context) {
+        return {
+            lineStart: function() {
+                this.data = [];
+            },
+            point: function(x, y) {
+                this.data.push([x, y]);
+            },
+            lineEnd: function() {
+                var x0 = this.data[0][0],
+                    y0 = this.data[0][1],
+                    cp1x = this.data[1][0],
+                    cp1y = this.data[1][1],
+                    cp2Obj = this.data[this.data.length - 2],
+                    cp2x = cp2Obj[0],
+                    cp2y = cp2Obj[1],
+                    axisObj = this.data[this.data.length - 1],
+                    x1 = axisObj[0],
+                    y1 = axisObj[1];
+                context.moveTo(x0, y0);
+                context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x1, y1);
+            }
+        }
+    }
+    LineageUtils.SaveSvg = function(e, viewOptions) {
+        var that = this,
+            svg = viewOptions.svg,
+            svgWidth = viewOptions.svgWidth,
+            svgHeight = viewOptions.svgHeight,
+            downloadFileName = viewOptions.downloadFileName,
+            toggleLoader = viewOptions.toggleLoader,
+            svgClone = svg.cloneNode(true),
+            scaleFactor = 1;
+        setTimeout(function() {
+            if (platform.name === "Firefox") {
+                svgClone.setAttribute('width', svgWidth);
+                svgClone.setAttribute('height', svgHeight);
+            }
+            $('.hidden-svg').html(svgClone);
+            $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
+            $(svgClone).find("foreignObject").remove();
+            var canvasOffset = { x: 150, y: 150 },
+                setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
+                setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
+                xAxis = svgClone.getBBox().x,
+                yAxis = svgClone.getBBox().y;
+            svgClone.attributes.viewBox.value = xAxis + "," + yAxis + "," + setWidth + "," + setHeight;
+
+            var createCanvas = document.createElement('canvas');
+            createCanvas.id = "canvas";
+            createCanvas.style.display = 'none';
+
+            var body = $('body').append(createCanvas),
+                canvas = $('canvas')[0];
+            canvas.width = (svgClone.getBBox().width * scaleFactor) + canvasOffset.x;
+            canvas.height = (svgClone.getBBox().height * scaleFactor) + canvasOffset.y;
+
+            var ctx = canvas.getContext('2d'),
+                data = (new XMLSerializer()).serializeToString(svgClone),
+                DOMURL = window.URL || window.webkitURL || window;
+
+            ctx.fillStyle = "#FFFFFF";
+            ctx.fillRect(0, 0, canvas.width, canvas.height);
+            ctx.strokeRect(0, 0, canvas.width, canvas.height);
+            ctx.restore();
+
+            var img = new Image(canvas.width, canvas.height);
+            var svgBlob = new Blob([data], { type: 'image/svg+xml;base64' });
+            if (platform.name === "Safari") {
+                svgBlob = new Blob([data], { type: 'image/svg+xml' });
+            }
+            var url = DOMURL.createObjectURL(svgBlob);
+
+            img.onload = function() {
+                try {
+                    var a = document.createElement("a");
+                    a.download = downloadFileName;
+                    document.body.appendChild(a);
+                    ctx.drawImage(img, 50, 50, canvas.width, canvas.height);
+                    canvas.toBlob(function(blob) {
+                        if (!blob) {
+                            Utils.notifyError({
+                                content: "There was an error in downloading Lineage!"
+                            });
+                            toggleLoader();
+                            return;
+                        }
+                        a.href = DOMURL.createObjectURL(blob);
+                        if (blob.size > 10000000) {
+                            Utils.notifyWarn({
+                                content: "The Image size is huge, please open the image in a browser!"
+                            });
+                        }
+                        a.click();
+                        toggleLoader();
+                        if (platform.name === 'Safari') {
+                            that.refreshGraphForSafari({
+                                edgeEl: that.$('svg g.node')
+                            });
+                        }
+                    }, 'image/png');
+                    $('.hidden-svg').html('');
+                    createCanvas.remove();
+
+                } catch (err) {
+                    Utils.notifyError({
+                        content: "There was an error in downloading Lineage!"
+                    });
+                    toggleLoader();
+                }
+
+            };
+            img.src = url;
+        }, 0);
+    }
+    return LineageUtils;
 });
\ No newline at end of file
diff --git a/dashboardv3/package-lock.json b/dashboardv3/package-lock.json
index 7ec8506..a9c0764 100644
--- a/dashboardv3/package-lock.json
+++ b/dashboardv3/package-lock.json
@@ -515,7 +515,6 @@
       "version": "2.9.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
       "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
-      "dev": true,
       "requires": {
         "graceful-readlink": ">= 1.0.0"
       }
@@ -625,6 +624,202 @@
       "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
       "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g="
     },
+    "d3-array": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
+      "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
+    },
+    "d3-axis": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz",
+      "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
+    },
+    "d3-brush": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz",
+      "integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
+    "d3-chord": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz",
+      "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==",
+      "requires": {
+        "d3-array": "1",
+        "d3-path": "1"
+      }
+    },
+    "d3-collection": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz",
+      "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A=="
+    },
+    "d3-color": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
+      "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
+    },
+    "d3-contour": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz",
+      "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==",
+      "requires": {
+        "d3-array": "^1.1.1"
+      }
+    },
+    "d3-dispatch": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
+      "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
+    },
+    "d3-drag": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
+      "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-selection": "1"
+      }
+    },
+    "d3-dsv": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz",
+      "integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==",
+      "requires": {
+        "commander": "2",
+        "iconv-lite": "0.4",
+        "rw": "1"
+      }
+    },
+    "d3-ease": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz",
+      "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ=="
+    },
+    "d3-fetch": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz",
+      "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==",
+      "requires": {
+        "d3-dsv": "1"
+      }
+    },
+    "d3-force": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz",
+      "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==",
+      "requires": {
+        "d3-collection": "1",
+        "d3-dispatch": "1",
+        "d3-quadtree": "1",
+        "d3-timer": "1"
+      }
+    },
+    "d3-format": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz",
+      "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw=="
+    },
+    "d3-geo": {
+      "version": "1.11.9",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.9.tgz",
+      "integrity": "sha512-9edcH6J3s/Aa3KJITWqFJbyB/8q3mMlA9Fi7z6yy+FAYMnRaxmC7jBhUnsINxVWD14GmqX3DK8uk7nV6/Ekt4A==",
+      "requires": {
+        "d3-array": "1"
+      }
+    },
+    "d3-hierarchy": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
+      "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
+    },
+    "d3-interpolate": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
+      "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
+      "requires": {
+        "d3-color": "1"
+      }
+    },
+    "d3-path": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+    },
+    "d3-polygon": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz",
+      "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ=="
+    },
+    "d3-quadtree": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz",
+      "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
+    },
+    "d3-random": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz",
+      "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ=="
+    },
+    "d3-scale": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz",
+      "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==",
+      "requires": {
+        "d3-array": "^1.2.0",
+        "d3-collection": "1",
+        "d3-format": "1",
+        "d3-interpolate": "1",
+        "d3-time": "1",
+        "d3-time-format": "2"
+      }
+    },
+    "d3-scale-chromatic": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz",
+      "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==",
+      "requires": {
+        "d3-color": "1",
+        "d3-interpolate": "1"
+      }
+    },
+    "d3-selection": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.1.tgz",
+      "integrity": "sha512-BTIbRjv/m5rcVTfBs4AMBLKs4x8XaaLkwm28KWu9S2vKNqXkXt2AH2Qf0sdPZHjFxcWg/YL53zcqAz+3g4/7PA=="
+    },
+    "d3-shape": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+      "requires": {
+        "d3-path": "1"
+      }
+    },
+    "d3-time": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
+      "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
+    },
+    "d3-time-format": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
+      "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
+      "requires": {
+        "d3-time": "1"
+      }
+    },
+    "d3-timer": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
+      "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
+    },
     "d3-tip": {
       "version": "0.6.8",
       "resolved": "https://registry.npmjs.org/d3-tip/-/d3-tip-0.6.8.tgz",
@@ -633,24 +828,94 @@
         "d3": "^3.5.5"
       }
     },
+    "d3-transition": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz",
+      "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==",
+      "requires": {
+        "d3-color": "1",
+        "d3-dispatch": "1",
+        "d3-ease": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "^1.1.0",
+        "d3-timer": "1"
+      }
+    },
+    "d3-voronoi": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
+      "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
+    },
+    "d3-zoom": {
+      "version": "1.8.3",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
+      "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
+      "requires": {
+        "d3-dispatch": "1",
+        "d3-drag": "1",
+        "d3-interpolate": "1",
+        "d3-selection": "1",
+        "d3-transition": "1"
+      }
+    },
     "dagre": {
-      "version": "0.7.4",
-      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.7.4.tgz",
-      "integrity": "sha1-3nLw50pVDOEc5jjwoTb+1xI5gCI=",
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
       "requires": {
-        "graphlib": "^1.0.5",
-        "lodash": "^3.10.0"
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
       }
     },
     "dagre-d3": {
-      "version": "0.4.17",
-      "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.4.17.tgz",
-      "integrity": "sha1-lTMYDQC6n/KLBM7hJ+k1ktnGChw=",
-      "requires": {
-        "d3": "^3.3.8",
-        "dagre": "^0.7.3",
-        "graphlib": "^1.0.5",
-        "lodash": "^3.10.0"
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.6.4.tgz",
+      "integrity": "sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==",
+      "requires": {
+        "d3": "^5.14",
+        "dagre": "^0.8.5",
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "d3": {
+          "version": "5.15.1",
+          "resolved": "https://registry.npmjs.org/d3/-/d3-5.15.1.tgz",
+          "integrity": "sha512-Xu9gT6Lm0jH3wWJJSRomFwqnGGi3YAfWIfxNFl4++YVgYOjo3F8V2idAG3nJBgpZOkD0/RHPZX6F4k6tzgOvYw==",
+          "requires": {
+            "d3-array": "1",
+            "d3-axis": "1",
+            "d3-brush": "1",
+            "d3-chord": "1",
+            "d3-collection": "1",
+            "d3-color": "1",
+            "d3-contour": "1",
+            "d3-dispatch": "1",
+            "d3-drag": "1",
+            "d3-dsv": "1",
+            "d3-ease": "1",
+            "d3-fetch": "1",
+            "d3-force": "1",
+            "d3-format": "1",
+            "d3-geo": "1",
+            "d3-hierarchy": "1",
+            "d3-interpolate": "1",
+            "d3-path": "1",
+            "d3-polygon": "1",
+            "d3-quadtree": "1",
+            "d3-random": "1",
+            "d3-scale": "2",
+            "d3-scale-chromatic": "1",
+            "d3-selection": "1",
+            "d3-shape": "1",
+            "d3-time": "1",
+            "d3-time-format": "2",
+            "d3-timer": "1",
+            "d3-transition": "1",
+            "d3-voronoi": "1",
+            "d3-zoom": "1"
+          }
+        }
       }
     },
     "dashdash": {
@@ -709,9 +974,9 @@
       "dev": true
     },
     "depd": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
       "dev": true
     },
     "destroy": {
@@ -1070,12 +1335,6 @@
             "once": "^1.3.0",
             "path-is-absolute": "^1.0.0"
           }
-        },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
         }
       }
     },
@@ -1088,15 +1347,14 @@
     "graceful-readlink": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
-      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
-      "dev": true
+      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
     },
     "graphlib": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-1.0.7.tgz",
-      "integrity": "sha1-DKst8P/mq+BwsmJb+h7bbslnuLE=",
+      "version": "2.1.8",
+      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
       "requires": {
-        "lodash": "^3.10.0"
+        "lodash": "^4.17.15"
       }
     },
     "grunt": {
@@ -1356,12 +1614,6 @@
           "requires": {
             "lodash": "^4.17.14"
           }
-        },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
         }
       }
     },
@@ -1381,14 +1633,6 @@
         "grunt-legacy-log-utils": "~2.0.0",
         "hooker": "~0.2.3",
         "lodash": "~4.17.5"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-legacy-log-utils": {
@@ -1399,14 +1643,6 @@
       "requires": {
         "chalk": "~2.4.1",
         "lodash": "~4.17.10"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-legacy-util": {
@@ -1422,14 +1658,6 @@
         "lodash": "~4.17.10",
         "underscore.string": "~3.3.4",
         "which": "~1.3.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        }
       }
     },
     "grunt-middleware-proxy": {
@@ -1549,6 +1777,12 @@
         "statuses": ">= 1.4.0 < 2"
       },
       "dependencies": {
+        "depd": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+          "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+          "dev": true
+        },
         "inherits": {
           "version": "2.0.3",
           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
@@ -1584,15 +1818,14 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
       "requires": {
         "safer-buffer": ">= 2.1.2 < 3"
       }
     },
     "in-publish": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
-      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
+      "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==",
       "dev": true
     },
     "indent-string": {
@@ -1860,9 +2093,9 @@
       }
     },
     "lodash": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-      "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
     },
     "longest": {
       "version": "1.0.1",
@@ -1995,26 +2228,18 @@
       }
     },
     "minimist": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
       "dev": true
     },
     "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
       "dev": true,
       "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        }
+        "minimist": "^1.2.5"
       }
     },
     "moment": {
@@ -2031,16 +2256,16 @@
       }
     },
     "morgan": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
-      "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
+      "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
       "dev": true,
       "requires": {
-        "basic-auth": "~2.0.0",
+        "basic-auth": "~2.0.1",
         "debug": "2.6.9",
-        "depd": "~1.1.2",
+        "depd": "~2.0.0",
         "on-finished": "~2.3.0",
-        "on-headers": "~1.0.1"
+        "on-headers": "~1.0.2"
       }
     },
     "ms": {
@@ -2163,12 +2388,6 @@
             "supports-color": "^2.0.0"
           }
         },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        },
         "supports-color": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@@ -2464,9 +2683,9 @@
       "dev": true
     },
     "psl": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
-      "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
       "dev": true
     },
     "punycode": {
@@ -2476,9 +2695,9 @@
       "dev": true
     },
     "qs": {
-      "version": "6.9.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
-      "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==",
+      "version": "6.9.3",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz",
+      "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==",
       "dev": true
     },
     "range-parser": {
@@ -2636,9 +2855,9 @@
       "integrity": "sha1-ExOHM2E/xEV7fhJH6Mt1HfeqVCk="
     },
     "resolve": {
-      "version": "1.15.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
-      "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
+      "version": "1.16.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz",
+      "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==",
       "dev": true,
       "requires": {
         "path-parse": "^1.0.6"
@@ -2693,6 +2912,11 @@
         }
       }
     },
+    "rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
+    },
     "rx": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
@@ -2713,8 +2937,7 @@
     "safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
     "sass-graph": {
       "version": "2.2.4",
@@ -2745,12 +2968,6 @@
             "wrap-ansi": "^2.0.0"
           }
         },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        },
         "yargs": {
           "version": "7.1.0",
           "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
@@ -2831,6 +3048,12 @@
         "statuses": "~1.5.0"
       },
       "dependencies": {
+        "depd": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+          "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+          "dev": true
+        },
         "http-errors": {
           "version": "1.7.3",
           "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
@@ -2898,9 +3121,9 @@
       "dev": true
     },
     "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
     },
     "source-map": {
diff --git a/dashboardv3/package.json b/dashboardv3/package.json
index e2d33d5..cab875d 100644
--- a/dashboardv3/package.json
+++ b/dashboardv3/package.json
@@ -32,7 +32,7 @@
     "bootstrap-daterangepicker": "2.1.25",
     "d3": "3.5.17",
     "d3-tip": "0.6.8",
-    "dagre-d3": "0.4.17",
+    "dagre-d3": "0.6.4",
     "dropzone": "5.7.0",
     "font-awesome": "4.7.0",
     "jQuery-QueryBuilder": "2.4.3",
diff --git a/dashboardv3/public/css/scss/graph.scss b/dashboardv3/public/css/scss/graph.scss
index 71e5e57..de05aa8 100644
--- a/dashboardv3/public/css/scss/graph.scss
+++ b/dashboardv3/public/css/scss/graph.scss
@@ -41,6 +41,16 @@
 
     .label {
         fill: $color_suva_gray_approx;
+
+        &.highlight {
+            cursor: pointer;
+            fill: $color_havelock_blue_approx;
+            text-decoration: underline;
+
+            tspan {
+                font-weight: 400;
+            }
+        }
     }
 
     circle {
diff --git a/dashboardv3/public/css/scss/theme.scss b/dashboardv3/public/css/scss/theme.scss
index ef84ca9..7584df5 100644
--- a/dashboardv3/public/css/scss/theme.scss
+++ b/dashboardv3/public/css/scss/theme.scss
@@ -759,7 +759,8 @@ td.searchTableName:hover {
             }
         }
 
-        image {
+        image,
+        circle {
             opacity: 0.2;
             //animation: blink 2.5s infinite;
         }
diff --git a/dashboardv3/public/js/main.js b/dashboardv3/public/js/main.js
index aecebf7..a2f2f7c 100644
--- a/dashboardv3/public/js/main.js
+++ b/dashboardv3/public/js/main.js
@@ -72,7 +72,7 @@ require.config({
      * @default 7 seconds
      * @type {Number}
      */
-    'waitSeconds': 30,
+    'waitSeconds': 0,
 
     'shim': {
         'backbone': {
diff --git a/dashboardv3/public/js/views/graph/LineageLayoutView.js b/dashboardv3/public/js/views/graph/LineageLayoutView.js
index 4e7a45b..737de8e 100644
--- a/dashboardv3/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv3/public/js/views/graph/LineageLayoutView.js
@@ -109,7 +109,6 @@ define(['require',
                     selectedNode: ''
                 }
             },
-
             initializeGraph: function() {
                 this.g = {};
                 this.g = new dagreD3.graphlib.Graph()
@@ -129,17 +128,15 @@ define(['require',
             },
             onRender: function() {
                 var that = this;
+                this.ui.searchToggler.prop("disabled", true);
+                this.$graphButtonsEl = this.$(".graph-button-group button,select[data-id='selectDepth']")
                 this.fetchGraphData();
-
-
                 if (platform.name === "IE") {
                     this.$('svg').css('opacity', '0');
 
                 }
-
                 if (platform.name === "Microsoft Edge" || platform.name === "IE") {
                     $(that.ui.saveSvg).hide();
-
                 }
                 if (this.layoutRendered) {
                     this.layoutRendered();
@@ -175,32 +172,24 @@ define(['require',
                     icon.parent('button').attr("data-original-title", "Default View");
                 }
                 panel.toggleClass('fullscreen-mode');
-                this.slideBarToggle(panel);
-            },
-            slideBarToggle: function(panel) {
-                var sideBarCheck = $(".container-fluid.view-container").hasClass('slide-in'),
-                    sideBarContainer = $(".container-fluid.view-container"),
-                    sideBarWrapper = $("#sidebar-wrapper,#page-wrapper");
-
-                sideBarWrapper.addClass("animate-me");
-                panel.hasClass('fullscreen-mode') ?
-                    sideBarCheck ? null : sideBarContainer.toggleClass("slide-in") :
-                    sideBarCheck ? sideBarContainer.toggleClass("slide-in") : null;
-                $("#sidebar-wrapper,.search-browse-box,#page-wrapper").removeAttr("style");
-                setTimeout(function() {
-                    sideBarWrapper.removeClass("animate-me");
-                }, 301);
             },
             onCheckUnwantedEntity: function(e) {
-                var data = $.extend(true, {}, this.lineageData);
-                //this.fromToNodeData = {};
+                var that = this;
                 this.initializeGraph();
                 if ($(e.target).data("id") === "checkHideProcess") {
                     this.filterObj.isProcessHideCheck = e.target.checked;
                 } else {
                     this.filterObj.isDeletedEntityHideCheck = e.target.checked;
                 }
-                this.generateData({ "relationshipMap": this.relationshipMap, "guidEntityMap": this.guidEntityMap });
+                that.toggleDisableState({
+                    "el": that.$graphButtonsEl
+                });
+                this.generateData(this.lineageData).then(function() {
+                    that.createGraph();
+                    that.toggleDisableState({
+                        "el": that.$graphButtonsEl
+                    });
+                });
             },
             toggleBoxPanel: function(options) {
                 var el = options && options.el,
@@ -229,11 +218,9 @@ define(['require',
                 this.filterObj.depthCount = e.currentTarget.value;
                 this.fetchGraphData({ queryParam: { 'depth': this.filterObj.depthCount } });
             },
-
             fetchGraphData: function(options) {
                 var that = this,
                     queryParam = options && options.queryParam || {};
-                this.fromToNodeData = {};
                 this.$('.fontLoader').show();
                 this.$('svg>g').hide();
                 this.toggleDisableState({
@@ -247,16 +234,18 @@ define(['require',
                         }
                         if (data.relations.length) {
                             that.lineageData = $.extend(true, {}, data);
-                            that.relationshipMap = that.crateLineageRelationshipHashMap(data);
-                            that.guidEntityMap = $.extend(true, {}, data.guidEntityMap);
-                            that.generateData({ "relationshipMap": that.relationshipMap, "guidEntityMap": that.guidEntityMap });
-                            that.toggleDisableState({
-                                "el": that.$(".graph-button-group button,select[data-id='selectDepth']")
+                            that.generateData(that.lineageData).then(function(graphObj) {
+                                that.createGraph();
+                                that.toggleDisableState({
+                                    "el": that.$graphButtonsEl
+                                });
+                            });
+                            that.renderLineageTypeSearch().then(function() {
+                                that.ui.searchToggler.prop("disabled", false);
                             });
                         } else {
                             that.noLineage();
                             that.hideCheckForProcess();
-
                         }
                     },
                     cust_error: function(model, response) {
@@ -301,7 +290,6 @@ define(['require',
                 var returnObj = {
                     isProcess: (isProcessHideCheck && node.isProcess),
                     isDeleted: (isDeletedEntityHideCheck && node.isDeleted)
-
                 };
                 returnObj["update"] = returnObj.isProcess || returnObj.isDeleted;
                 return returnObj;
@@ -332,177 +320,184 @@ define(['require',
                 }
                 return serviceType;
             },
-            crateLineageRelationshipHashMap: function(data) {
-                var that = this,
-                    relations = data && data.relations,
-                    guidEntityMap = data && data.guidEntityMap,
-                    makeNodeData = function(relationObj) {
-                        var obj = $.extend(true, {
-                            shape: "img",
-                            label: relationObj.displayText.trunc(18),
-                            toolTipLabel: relationObj.displayText,
-                            id: relationObj.guid,
-                            isLineage: true,
-                            isIncomplete: relationObj.isIncomplete,
-                            entityDef: this.getEntityDef(relationObj.typeName)
-                        }, relationObj);
-                        obj["serviceType"] = this.getServiceType({ typeName: relationObj.typeName, entityDef: obj.entityDef });
-                        obj["superTypes"] = this.getNestedSuperTypes({ entityDef: obj.entityDef });
-                        obj['isProcess'] = this.isProcess(obj);
-                        obj['isDeleted'] = this.isDeleted(obj);
-                        return obj;
-                    }.bind(this),
-                    newHashMap = {};
-                _.each(relations, function(obj) {
-                    if (!that.fromToNodeData[obj.fromEntityId]) {
-                        that.fromToNodeData[obj.fromEntityId] = makeNodeData(guidEntityMap[obj.fromEntityId]);
-                    }
-                    if (!that.fromToNodeData[obj.toEntityId]) {
-                        that.fromToNodeData[obj.toEntityId] = makeNodeData(guidEntityMap[obj.toEntityId]);
-                    }
-                    if (newHashMap[obj.fromEntityId]) {
-                        newHashMap[obj.fromEntityId].push(obj.toEntityId);
-                    } else {
-                        newHashMap[obj.fromEntityId] = [obj.toEntityId];
-                    }
-                });
-                return newHashMap;
-            },
             generateData: function(options) {
-                var that = this,
-                    relationshipMap = options && $.extend(true, {}, options.relationshipMap) || {},
-                    guidEntityMap = options && options.guidEntityMap || {},
-                    styleObj = {
-                        fill: 'none',
-                        stroke: '#ffb203',
-                        width: 3
-                    },
-                    getStyleObjStr = function(styleObj) {
-                        return 'fill:' + styleObj.fill + ';stroke:' + styleObj.stroke + ';stroke-width:' + styleObj.width;
-                    },
-                    filterRelationshipMap = relationshipMap,
-                    isHideFilterOn = this.filterObj.isProcessHideCheck || this.filterObj.isDeletedEntityHideCheck,
-                    getNewToNodeRelationship = function(toNodeGuid) {
-                        if (toNodeGuid && relationshipMap[toNodeGuid]) {
-                            var newRelationship = [];
-                            _.each(relationshipMap[toNodeGuid], function(guid) {
-                                var nodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[guid]);
-                                if (nodeToBeUpdated.update) {
-                                    var newRelation = getNewToNodeRelationship(guid);
-                                    if (newRelation) {
-                                        newRelationship = newRelationship.concat(newRelation);
+                return new Promise(function(resolve, reject) {
+                    try {
+                        var that = this,
+                            relations = options && options.relations || {},
+                            guidEntityMap = options && options.guidEntityMap || {},
+                            isHideFilterOn = this.filterObj.isProcessHideCheck || this.filterObj.isDeletedEntityHideCheck,
+                            newHashMap = {},
+                            styleObj = {
+                                fill: 'none',
+                                stroke: '#ffb203',
+                                width: 3
+                            },
+                            makeNodeData = function(relationObj) {
+                                if (relationObj) {
+                                    if (relationObj.updatedValues) {
+                                        return relationObj;
                                     }
+                                    var obj = _.extend(relationObj, {
+                                        shape: "img",
+                                        updatedValues: true,
+                                        label: relationObj.displayText.trunc(18),
+                                        toolTipLabel: relationObj.displayText,
+                                        id: relationObj.guid,
+                                        isLineage: true,
+                                        isIncomplete: relationObj.isIncomplete,
+                                        entityDef: that.getEntityDef(relationObj.typeName)
+                                    });
+                                    obj["serviceType"] = that.getServiceType({ typeName: relationObj.typeName, entityDef: obj.entityDef });
+                                    obj["superTypes"] = that.getNestedSuperTypes({ entityDef: obj.entityDef });
+                                    obj['isProcess'] = that.isProcess(obj);
+                                    obj['isDeleted'] = that.isDeleted(obj);
+                                    return obj;
+                                }
+                            },
+                            crateLineageRelationshipHashMap = function(data) {
+                                var that = this,
+                                    relations = data && data.relations,
+                                    newHashMap = {};
+                                _.each(relations, function(obj) {
+                                    if (newHashMap[obj.fromEntityId]) {
+                                        newHashMap[obj.fromEntityId].push(obj.toEntityId);
+                                    } else {
+                                        newHashMap[obj.fromEntityId] = [obj.toEntityId];
+                                    }
+                                });
+                                return newHashMap;
+                            },
+                            getStyleObjStr = function(styleObj) {
+                                return 'fill:' + styleObj.fill + ';stroke:' + styleObj.stroke + ';stroke-width:' + styleObj.width;
+                            },
+                            getNewToNodeRelationship = function(toNodeGuid) {
+                                if (toNodeGuid && relationshipMap[toNodeGuid]) {
+                                    var newRelationship = [];
+                                    _.each(relationshipMap[toNodeGuid], function(guid) {
+                                        var nodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[guid]));
+                                        if (nodeToBeUpdated.update) {
+                                            var newRelation = getNewToNodeRelationship(guid);
+                                            if (newRelation) {
+                                                newRelationship = newRelationship.concat(newRelation);
+                                            }
+                                        } else {
+                                            newRelationship.push(guid);
+                                        }
+                                    });
+                                    return newRelationship;
                                 } else {
-                                    newRelationship.push(guid);
+                                    return null;
                                 }
-                            });
-                            return newRelationship;
-                        } else {
-                            return null;
-                        }
-                    },
-                    getToNodeRelation = function(toNodes, fromNodeToBeUpdated) {
-                        var toNodeRelationship = [];
-                        _.each(toNodes, function(toNodeGuid) {
-                            var toNodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[toNodeGuid]);
-                            if (toNodeToBeUpdated.update) {
-                                // To node need to updated
-                                if (pendingFromRelationship[toNodeGuid]) {
-                                    toNodeRelationship = toNodeRelationship.concat(pendingFromRelationship[toNodeGuid]);
+                            },
+                            getToNodeRelation = function(toNodes, fromNodeToBeUpdated) {
+                                var toNodeRelationship = [];
+                                _.each(toNodes, function(toNodeGuid) {
+                                    var toNodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[toNodeGuid]));
+                                    if (toNodeToBeUpdated.update) {
+                                        // To node need to updated
+                                        if (pendingFromRelationship[toNodeGuid]) {
+                                            toNodeRelationship = toNodeRelationship.concat(pendingFromRelationship[toNodeGuid]);
+                                        } else {
+                                            var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid);
+                                            if (newToNodeRelationship) {
+                                                toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
+                                            }
+                                        }
+                                    } else {
+                                        //when bothe node not to be updated.
+                                        toNodeRelationship.push(toNodeGuid);
+                                    }
+                                });
+                                return toNodeRelationship;
+                            },
+                            setNode = function(guid) {
+                                if (!that.g._nodes[guid]) {
+                                    var nodeData = makeNodeData(guidEntityMap[guid]);
+                                    that.g.setNode(guid, nodeData);
+                                    return nodeData;
                                 } else {
-                                    var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid);
-                                    if (newToNodeRelationship) {
-                                        toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
+                                    return that.g._nodes[guid];
+                                }
+                            },
+                            setEdge = function(fromNodeGuid, toNodeGuid) {
+                                that.g.setEdge(fromNodeGuid, toNodeGuid, {
+                                    "arrowhead": 'arrowPoint',
+                                    "curve": LineageUtils.BezierCurve,
+                                    "style": getStyleObjStr(styleObj),
+                                    "styleObj": styleObj
+                                });
+                            },
+                            setGraphData = function(fromEntityId, toEntityId) {
+                                setNode(fromEntityId);
+                                setNode(toEntityId);
+                                setEdge(fromEntityId, toEntityId);
+                            },
+                            pendingFromRelationship = {};
+                        if (isHideFilterOn) {
+                            var relationshipMap = crateLineageRelationshipHashMap(options)
+                            _.each(relationshipMap, function(toNodes, fromNodeGuid) {
+                                var fromNodeToBeUpdated = that.isNodeToBeUpdated(makeNodeData(guidEntityMap[fromNodeGuid])),
+                                    toNodeList = getToNodeRelation(toNodes, fromNodeToBeUpdated);
+                                if (fromNodeToBeUpdated.update) {
+                                    if (pendingFromRelationship[fromNodeGuid]) {
+                                        pendingFromRelationship[fromNodeGuid] = pendingFromRelationship[fromNodeGuid].concat(toNodeList);
+                                    } else {
+                                        pendingFromRelationship[fromNodeGuid] = toNodeList;
                                     }
+                                } else {
+                                    _.each(toNodeList, function(toNodeGuid) {
+                                        setGraphData(fromNodeGuid, toNodeGuid);
+                                    });
                                 }
-                            } else {
-                                //when bothe node not to be updated.
-                                toNodeRelationship.push(toNodeGuid);
-                            }
-                        });
-                        return toNodeRelationship;
-                    },
-                    pendingFromRelationship = {};
-                if (isHideFilterOn) {
-                    filterRelationshipMap = {};
-                    _.each(relationshipMap, function(toNodes, fromNodeGuid) {
-                        var fromNodeToBeUpdated = that.isNodeToBeUpdated(that.fromToNodeData[fromNodeGuid]),
-                            toNodeList = getToNodeRelation(toNodes, fromNodeToBeUpdated);
-                        if (fromNodeToBeUpdated.update) {
-                            if (pendingFromRelationship[fromNodeGuid]) {
-                                pendingFromRelationship[fromNodeGuid] = pendingFromRelationship[fromNodeGuid].concat(toNodeList);
-                            } else {
-                                pendingFromRelationship[fromNodeGuid] = toNodeList;
-                            }
+                            })
                         } else {
-                            if (filterRelationshipMap[fromNodeGuid]) {
-                                filterRelationshipMap[fromNodeGuid] = filterRelationshipMap[fromNodeGuid].concat(toNodeList);
-                            } else {
-                                filterRelationshipMap[fromNodeGuid] = toNodeList;
+                            _.each(relations, function(obj) {
+                                setGraphData(obj.fromEntityId, obj.toEntityId);
+                            });
+                        }
+                        if (this.g._nodes[this.guid]) {
+                            if (this.g._nodes[this.guid]) {
+                                this.g._nodes[this.guid]['isLineage'] = false;
                             }
+                            this.findImpactNodeAndUpdateData({ "guid": this.guid, "getStyleObjStr": getStyleObjStr });
                         }
-                    })
-                }
-
-                _.each(filterRelationshipMap, function(toNodesList, fromNodeGuid) {
-                    if (!that.g._nodes[fromNodeGuid]) {
-                        that.g.setNode(fromNodeGuid, that.fromToNodeData[fromNodeGuid]);
+                        resolve(this.g);
+                    } catch (e) {
+                        reject(e)
                     }
-                    _.each(toNodesList, function(toNodeGuid) {
-                        if (!that.g._nodes[toNodeGuid]) {
-                            that.g.setNode(toNodeGuid, that.fromToNodeData[toNodeGuid]);
-                        }
-                        that.g.setEdge(fromNodeGuid, toNodeGuid, {
-                            "arrowhead": 'arrowPoint',
-                            "lineInterpolate": 'basis',
-                            "style": getStyleObjStr(styleObj),
-                            'styleObj': styleObj
-                        });
-                    })
-                })
-
-                //if no relations found
-                if (_.isEmpty(filterRelationshipMap)) {
-                    this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No relations to display</text>');
-                }
-
-                if (this.fromToNodeData[this.guid]) {
-                    this.fromToNodeData[this.guid]['isLineage'] = false;
-                    this.findImpactNodeAndUpdateData({ "relationshipMap": filterRelationshipMap, "guid": this.guid, "getStyleObjStr": getStyleObjStr });
-                }
-                this.renderLineageTypeSearch();
-                this.createGraph();
+                }.bind(this));
             },
             findImpactNodeAndUpdateData: function(options) {
                 var that = this,
-                    relationshipMap = options.relationshipMap,
-                    fromNodeGuid = options.guid,
+                    guid = options.guid,
                     getStyleObjStr = options.getStyleObjStr,
-                    toNodeList = relationshipMap[fromNodeGuid];
-                if (toNodeList && toNodeList.length) {
-                    if (!relationshipMap[fromNodeGuid]["traversed"]) {
-                        relationshipMap[fromNodeGuid]["traversed"] = true;
-                        _.each(toNodeList, function(toNodeGuid) {
-                            that.fromToNodeData[toNodeGuid]['isLineage'] = false;
-                            var styleObj = {
-                                fill: 'none',
-                                stroke: '#fb4200',
-                                width: 3
+                    traversedMap = {},
+                    styleObj = {
+                        fill: 'none',
+                        stroke: '#fb4200',
+                        width: 3
+                    },
+                    traversed = function(toNodeList, fromNodeGuid) {
+                        if (!_.isEmpty(toNodeList)) {
+                            if (!traversedMap[fromNodeGuid]) {
+                                traversedMap[fromNodeGuid] = true;
+                                _.each(toNodeList, function(val, toNodeGuid) {
+                                    if (that.g._nodes[toNodeGuid]) {
+                                        that.g._nodes[toNodeGuid]['isLineage'] = false;
+                                    }
+                                    that.g.setEdge(fromNodeGuid, toNodeGuid, {
+                                        "arrowhead": 'arrowPoint',
+                                        "curve": LineageUtils.BezierCurve,
+                                        "style": getStyleObjStr(styleObj),
+                                        'styleObj': styleObj
+                                    });
+                                    traversed(that.g._sucs[toNodeGuid], toNodeGuid);
+                                });
                             }
-                            that.g.setEdge(fromNodeGuid, toNodeGuid, {
-                                "arrowhead": 'arrowPoint',
-                                "lineInterpolate": 'basis',
-                                "style": getStyleObjStr(styleObj),
-                                'styleObj': styleObj
-                            });
-                            that.findImpactNodeAndUpdateData({
-                                "relationshipMap": relationshipMap,
-                                "guid": toNodeGuid,
-                                "getStyleObjStr": getStyleObjStr
-                            });
-                        });
-                    }
-                }
+                        }
+                    };
+                traversed(this.g._sucs[guid], guid)
             },
             zoomed: function(that) {
                 this.$('svg').find('>g').attr("transform",
@@ -528,6 +523,10 @@ define(['require',
                 });
             },
             createGraph: function() {
+                if (_.isEmpty(this.g._nodes)) {
+                    this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No relations to display</text>');
+                    return;
+                }
                 var that = this,
                     width = this.$('svg').width(),
                     height = this.$('svg').height(),
@@ -544,111 +543,12 @@ define(['require',
                 // Create the renderer
                 var render = new dagreD3.render();
                 // Add our custom arrow (a hollow-point)
-                render.arrows().arrowPoint = function normal(parent, id, edge, type) {
-                    var parentNode = parent && parent[0] && parent[0][0] && parent[0][0].parentNode ? parent[0][0].parentNode : parent;
-                    d3.select(parentNode).select('path.path').attr('marker-end', "url(#" + id + ")");
-                    var marker = parent.append("marker")
-                        .attr("id", id)
-                        .attr("viewBox", "0 0 10 10")
-                        .attr("refX", 8)
-                        .attr("refY", 5)
-                        .attr("markerUnits", "strokeWidth")
-                        .attr("markerWidth", 4)
-                        .attr("markerHeight", 4)
-                        .attr("orient", "auto");
-
-                    var path = marker.append("path")
-                        .attr("d", "M 0 0 L 10 5 L 0 10 z")
-                        .style("fill", edge.styleObj.stroke);
-                    dagreD3.util.applyStyle(path, edge[type + "Style"]);
+                render.arrows().arrowPoint = function(parent, id, edge, type) {
+                    return LineageUtils.arrowPointRender(parent, id, edge, type, { guid: that.guid, dagreD3: dagreD3 });
                 };
-                render.shapes().img = function circle(parent, bbox, node) {
-                    //var r = Math.max(bbox.width, bbox.height) / 2,
-                    if (node.id == that.guid) {
-                        var currentNode = true
-                    }
-                    var shapeSvg = parent.append('circle')
-                        .attr('fill', 'url(#img_' + node.id + ')')
-                        .attr('r', '24px')
-                        .attr('data-stroke', node.id)
-                        .attr('stroke-width', "2px")
-                        .attr("class", "nodeImage " + (currentNode ? "currentNode" : (node.isProcess ? "process" : "node")));
-                    if (currentNode) {
-                        shapeSvg.attr("stroke", "#fb4200")
-                    }
-                    if (node.isIncomplete === true) {
-                        parent.attr("class", "node isIncomplete show");
-                    } else {
-                        parent.attr("class", "node isIncomplete");
-                    }
-
-                    parent.insert("defs")
-                        .append("pattern")
-                        .attr("x", "0%")
-                        .attr("y", "0%")
-                        .attr("patternUnits", "objectBoundingBox")
-                        .attr("id", "img_" + node.id)
-                        .attr("width", "100%")
-                        .attr("height", "100%")
-                        .append('image')
-                        .attr("href", function(d) {
-                            var that = this;
-                            if (node) {
-                                var imageIconPath = Utils.getEntityIconPath({ entityData: node });
-
-                                var getImageData = function(options) {
-                                    var imagePath = options.imagePath,
-                                        ajaxOptions = {
-                                            "url": imagePath,
-                                            "method": "get",
-                                            "cache": true
-                                        }
-
-                                    if (platform.name !== "IE") {
-                                        ajaxOptions["mimeType"] = "text/plain; charset=x-user-defined";
-                                    }
-                                    shapeSvg.attr("data-iconpath", imagePath);
-                                    $.ajax(ajaxOptions)
-                                        .always(function(data, status, xhr) {
-                                            if (data.status == 404) {
-                                                getImageData({
-                                                    "imagePath": Utils.getEntityIconPath({ entityData: node, errorUrl: imagePath })
-                                                });
-                                            } else if (data) {
-                                                if (platform.name !== "IE") {
-                                                    imageObject[imageIconPath] = 'data:image/png;base64,' + LineageUtils.base64Encode({ "data": data });
-                                                } else {
-                                                    imageObject[imageIconPath] = imagePath;
-                                                }
-                                                d3.select(that).attr("xlink:href", imageObject[imageIconPath]);
-                                                if (imageIconPath !== shapeSvg.attr("data-iconpath")) {
-                                                    shapeSvg.attr("data-iconpathorigin", imageIconPath);
-                                                }
-                                            }
-                                        });
-                                }
-                                getImageData({
-                                    "imagePath": imageIconPath
-                                });
-                            }
-                        })
-                        .attr("x", "4")
-                        .attr("y", currentNode ? "3" : "4").attr("width", "40")
-                        .attr("height", "40");
-
-                    parent.insert("foreignObject")
-                        .attr("x", "-25")
-                        .attr("y", "-25")
-                        .attr("width", "50")
-                        .attr("height", "50")
-                        .append("xhtml:div")
-                        .insert("i")
-                        .attr("class", "fa fa-hourglass-half");
-
-                    node.intersect = function(point) {
-                        return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
-                    };
-                    return shapeSvg;
+                // Render custom img inside shape
+                render.shapes().img = function(parent, bbox, node) {
+                    return LineageUtils.imgShapeRender(parent, bbox, node, { guid: that.guid, dagreD3: dagreD3, imageObject: imageObject, $defs: that.svg.select('defs') });
                 };
                 // Set up an SVG group so that we can translate the final graph.
                 if (this.$("svg").find('.output').length) {
@@ -658,6 +558,8 @@ define(['require',
                     .attr("viewBox", "0 0 " + width + " " + height)
                     .attr("enable-background", "new 0 0 " + width + " " + height),
                     svgGroup = svg.append("g");
+                // Append defs
+                svg.append("defs");
                 var zoom = this.zoom = d3.behavior.zoom()
                     .center([width / 2, height / 2])
                     .scaleExtent([0.01, 50])
@@ -717,8 +619,29 @@ define(['require',
                 // .on("wheel.zoom", null);
                 //change text postion 
                 svgGroup.selectAll("g.nodes g.label")
-                    .attr("transform", "translate(2,-35)");
-                var waitForDoubleClick = null;
+                    .attr("transform", "translate(2,-35)")
+                    .on('mouseenter', function(d) {
+                        d3.select(this).classed("highlight", true);
+                    })
+                    .on('mouseleave', function(d) {
+                        d3.select(this).classed("highlight", false);
+                    })
+                    .on('click', function(d) {
+                        d3.event.preventDefault();
+                        tooltip.hide(d);
+                        if (that.guid == d) {
+                            Utils.notifyInfo({
+                                html: true,
+                                content: "You are already on " + "<b>" + that.entityName + "</b> detail page."
+                            });
+                        } else {
+                            Utils.setUrl({
+                                url: '#!/detailPage/' + d + '?tabActive=lineage',
+                                mergeBrowserUrl: false,
+                                trigger: true
+                            });
+                        }
+                    });
                 svgGroup.selectAll("g.nodes g.node")
                     .on('mouseenter', function(d) {
                         that.activeNode = true;
@@ -788,33 +711,10 @@ define(['require',
                         var el = this;
                         if (d3.event.defaultPrevented) return; // ignore drag
                         d3.event.preventDefault();
-
-                        if (waitForDoubleClick != null) {
-                            clearTimeout(waitForDoubleClick)
-                            waitForDoubleClick = null;
-                            tooltip.hide(d);
-                            if (that.guid == d) {
-                                Utils.notifyInfo({
-                                    html: true,
-                                    content: "You are already on " + "<b>" + that.entityName + "</b> detail page."
-                                });
-                            } else {
-                                Utils.setUrl({
-                                    url: '#!/detailPage/' + d + '?tabActive=lineage',
-                                    mergeBrowserUrl: false,
-                                    trigger: true
-                                });
-                            }
-                        } else {
-                            var currentEvent = d3.event
-                            waitForDoubleClick = setTimeout(function() {
-                                tooltip.hide(d);
-                                that.onClickNodeToggler({ obj: d });
-                                $(el).find('circle').addClass('node-detail-highlight');
-                                that.updateRelationshipDetails({ guid: d });
-                                waitForDoubleClick = null;
-                            }, 170)
-                        }
+                        tooltip.hide(d);
+                        that.onClickNodeToggler({ obj: d });
+                        $(el).find('circle').addClass('node-detail-highlight');
+                        that.updateRelationshipDetails({ guid: d });
                     });
 
                 svgGroup.selectAll("g.edgePath path.path").on('click', function(d) {
@@ -868,27 +768,32 @@ define(['require',
                 }).init();
             },
             renderLineageTypeSearch: function() {
-                var that = this,
-                    lineageData = $.extend(true, {}, this.lineageData),
-                    data = [],
-                    typeStr = '<option></option>';
-                if (!_.isEmpty(lineageData)) {
-                    _.each(lineageData.guidEntityMap, function(obj, index) {
-                        var nodeData = that.fromToNodeData[obj.guid];
-                        if (that.filterObj.isProcessHideCheck && nodeData && nodeData.isProcess) {
-                            return;
-                        } else if (that.filterObj.isDeletedEntityHideCheck && nodeData && nodeData.isDeleted) {
-                            return
+                var that = this;
+                return new Promise(function(resolve, reject) {
+                    try {
+                        var data = [],
+                            typeStr = '<option></option>';
+                        if (!_.isEmpty(that.lineageData)) {
+                            _.each(that.lineageData.guidEntityMap, function(obj, index) {
+                                var nodeData = that.g._nodes[obj.guid];
+                                if ((that.filterObj.isProcessHideCheck || that.filterObj.isDeletedEntityHideCheck) && nodeData && (nodeData.isProcess || nodeData.isDeleted)) {
+                                    return;
+                                }
+                                typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
+                            });
                         }
-                        typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
-                    });
-                }
-                this.ui.lineageTypeSearch.html(typeStr);
-                this.initilizelineageTypeSearch();
+                        that.ui.lineageTypeSearch.html(typeStr);
+                        that.initilizelineageTypeSearch();
+                        resolve();
+                    } catch (e) {
+                        console.log(e);
+                        reject(e);
+                    }
+                })
             },
             initilizelineageTypeSearch: function() {
                 var that = this;
-                that.ui.lineageTypeSearch.select2({
+                this.ui.lineageTypeSearch.select2({
                     closeOnSelect: true,
                     placeholder: 'Select Node'
                 }).on('change.select2', function(e) {
@@ -930,19 +835,18 @@ define(['require',
                             return false;
                         }
                     });
-
                 });
-                if (that.searchNodeObj.selectedNode) {
-                    that.ui.lineageTypeSearch.val(that.searchNodeObj.selectedNode);
-                    that.ui.lineageTypeSearch.trigger("change.select2");
+                if (this.searchNodeObj.selectedNode) {
+                    this.ui.lineageTypeSearch.val(this.searchNodeObj.selectedNode);
+                    this.ui.lineageTypeSearch.trigger("change.select2");
                 }
             },
             updateRelationshipDetails: function(options) {
                 var that = this,
                     guid = options.guid,
-                    initialData = that.guidEntityMap[guid],
+                    initialData = that.g._nodes[guid],
                     typeName = initialData.typeName || guid,
-                    attributeDefs = that.g._nodes[guid] && that.g._nodes[guid].entityDef ? that.g._nodes[guid].entityDef.attributeDefs : null;
+                    attributeDefs = initialData && initialData.entityDef ? initialData.entityDef.attributeDefs : null;
                 this.$("[data-id='typeName']").text(typeName);
                 this.entityModel = new VEntity({});
                 var config = {
@@ -974,109 +878,28 @@ define(['require',
                 }));
             },
             onClickSaveSvg: function(e, a) {
-                var that = this;
-                var loaderTargetDiv = $(e.currentTarget).find('>i');
-
+                var that = this,
+                    loaderTargetDiv = $(e.currentTarget).find('>i');
                 if (loaderTargetDiv.hasClass('fa-refresh')) {
                     Utils.notifyWarn({
                         content: "Please wait while the lineage gets downloaded"
                     });
                     return false; // return if the lineage is not loaded.
                 }
-
-
-                that.toggleLoader(loaderTargetDiv);
+                this.toggleLoader(loaderTargetDiv);
                 Utils.notifyInfo({
                     content: "Lineage will be downloaded in a moment."
                 });
-                setTimeout(function() {
-                    var svg = that.$('svg')[0],
-                        svgClone = svg.cloneNode(true),
-                        scaleFactor = 1,
-                        svgWidth = that.$('svg').width(),
-                        svgHeight = that.$('svg').height();
-                    if (platform.name === "Firefox") {
-                        svgClone.setAttribute('width', svgWidth);
-                        svgClone.setAttribute('height', svgHeight);
-                    }
-                    $('.hidden-svg').html(svgClone);
-                    $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
-                    $(svgClone).find("foreignObject").remove();
-                    var canvasOffset = { x: 150, y: 150 },
-                        setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
-                        setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
-                        xAxis = svgClone.getBBox().x,
-                        yAxis = svgClone.getBBox().y;
-                    svgClone.attributes.viewBox.value = xAxis + "," + yAxis + "," + setWidth + "," + setHeight;
-
-                    var createCanvas = document.createElement('canvas');
-                    createCanvas.id = "canvas";
-                    createCanvas.style.display = 'none';
-
-                    var body = $('body').append(createCanvas),
-                        canvas = $('canvas')[0];
-                    canvas.width = (svgClone.getBBox().width * scaleFactor) + canvasOffset.x;
-                    canvas.height = (svgClone.getBBox().height * scaleFactor) + canvasOffset.y;
-
-                    var ctx = canvas.getContext('2d'),
-                        data = (new XMLSerializer()).serializeToString(svgClone),
-                        DOMURL = window.URL || window.webkitURL || window;
-
-                    ctx.fillStyle = "#FFFFFF";
-                    ctx.fillRect(0, 0, canvas.width, canvas.height);
-                    ctx.strokeRect(0, 0, canvas.width, canvas.height);
-                    ctx.restore();
-
-                    var img = new Image(canvas.width, canvas.height);
-                    var svgBlob = new Blob([data], { type: 'image/svg+xml;base64' });
-                    if (platform.name === "Safari") {
-                        svgBlob = new Blob([data], { type: 'image/svg+xml' });
-                    }
-                    var url = DOMURL.createObjectURL(svgBlob);
-
-                    img.onload = function() {
-                        try {
-                            var a = document.createElement("a"),
-                                entityAttributes = that.entity && that.entity.attributes;
-                            a.download = ((entityAttributes && (entityAttributes.qualifiedName || entityAttributes.name) || "lineage_export") + ".png");
-                            document.body.appendChild(a);
-                            ctx.drawImage(img, 50, 50, canvas.width, canvas.height);
-                            canvas.toBlob(function(blob) {
-                                if (!blob) {
-                                    Utils.notifyError({
-                                        content: "There was an error in downloading Lineage!"
-                                    });
-                                    that.toggleLoader(loaderTargetDiv);
-                                    return;
-                                }
-                                a.href = DOMURL.createObjectURL(blob);
-                                if (blob.size > 10000000) {
-                                    Utils.notifyWarn({
-                                        content: "The Image size is huge, please open the image in a browser!"
-                                    });
-                                }
-                                a.click();
-                                that.toggleLoader(loaderTargetDiv);
-                                if (platform.name === 'Safari') {
-                                    LineageUtils.refreshGraphForSafari({
-                                        edgeEl: that.$('svg g.node')
-                                    });
-                                }
-                            }, 'image/png');
-                            $('.hidden-svg').html('');
-                            createCanvas.remove();
-
-                        } catch (err) {
-                            Utils.notifyError({
-                                content: "There was an error in downloading Lineage!"
-                            });
-                            that.toggleLoader(loaderTargetDiv);
-                        }
-
-                    };
-                    img.src = url;
-
-                }, 0)
+                var entityAttributes = that.entity && that.entity.attributes;
+                LineageUtils.SaveSvg(e, {
+                    svg: that.$('svg')[0],
+                    svgWidth: that.$('svg').width(),
+                    svgHeight: that.$('svg').height(),
+                    toggleLoader: function() {
+                        that.toggleLoader(loaderTargetDiv);
+                    },
+                    downloadFileName: ((entityAttributes && (entityAttributes.qualifiedName || entityAttributes.name) || "lineage_export") + ".png")
+                })
             },
             toggleLoader: function(element) {
                 if ((element).hasClass('fa-camera')) {
diff --git a/dashboardv3/public/js/views/graph/LineageUtils.js b/dashboardv3/public/js/views/graph/LineageUtils.js
index e1363a5..ed66782 100644
--- a/dashboardv3/public/js/views/graph/LineageUtils.js
+++ b/dashboardv3/public/js/views/graph/LineageUtils.js
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-define(['require'], function(require) {
+define(['require', 'utils/Utils'], function(require, Utils) {
     'use strict';
-    var LinegaeUtils = {};
-    LinegaeUtils.DragNode = function(options) {
+    var LineageUtils = {};
+    LineageUtils.DragNode = function(options) {
         var that = this,
             g = options.g,
             svg = options.svg,
@@ -99,7 +99,7 @@ define(['require'], function(require) {
                         }
                     }
                 });
-                LinegaeUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
+                LineageUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
             },
             translateEdge: function(e, dx, dy) {
                 e.points.forEach(function(p) {
@@ -158,7 +158,7 @@ define(['require'], function(require) {
             },
         }
     }
-    LinegaeUtils.refreshGraphForSafari = function(options) {
+    LineageUtils.refreshGraphForSafari = function(options) {
         var edgePathEl = options.edgeEl,
             IEGraphRenderDone = 0;
         edgePathEl.each(function(argument) {
@@ -169,7 +169,7 @@ define(['require'], function(require) {
             }, 500);
         });
     }
-    LinegaeUtils.refreshGraphForIE = function(options) {
+    LineageUtils.refreshGraphForIE = function(options) {
         var edgePathEl = options.edgeEl,
             IEGraphRenderDone = 0;
         edgePathEl.each(function(argument) {
@@ -187,7 +187,7 @@ define(['require'], function(require) {
             }, 1000);
         });
     }
-    LinegaeUtils.centerNode = function(options) {
+    LineageUtils.centerNode = function(options) {
         var nodeID = options.guid,
             svg = options.svg,
             g = options.g,
@@ -232,12 +232,12 @@ define(['require'], function(require) {
                 zoom.scale(scale);
                 afterCenterZoomed({ newScale: scale, newTranslate: [xa, ya] });
                 if (platform.name === "IE") {
-                    LinegaeUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
+                    LineageUtils.refreshGraphForIE({ "edgeEl": edgePathEl })
                 }
             }
         }
     }
-    LinegaeUtils.onHoverFade = function(options) {
+    LineageUtils.onHoverFade = function(options) {
         var opacity = options.opacity,
             d = options.selectedNode,
             nodesToHighlight = options.highlight,
@@ -271,7 +271,7 @@ define(['require'], function(require) {
         }
 
     }
-    LinegaeUtils.base64Encode = function(options) {
+    LineageUtils.base64Encode = function(options) {
         var str = options.data,
             CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
             out = "",
@@ -302,5 +302,235 @@ define(['require'], function(require) {
         }
         return out;
     }
-    return LinegaeUtils;
+    LineageUtils.imgShapeRender = function(parent, bbox, node, viewOptions) {
+        var LineageUtilsRef = this,
+            imageIconPath = Utils.getEntityIconPath({ entityData: node }),
+            imgName = imageIconPath.split("/").pop(),
+            viewGuid = viewOptions.guid,
+            dagreD3 = viewOptions.dagreD3,
+            imageObject = viewOptions.imageObject,
+            $defs = viewOptions.$defs;
+        if (node.isDeleted) {
+            imgName = "deleted_" + imgName;
+        }
+        if (node.id == viewGuid) {
+            var currentNode = true
+        }
+        var shapeSvg = parent.append('circle')
+            .attr('fill', 'url(#img_' + imgName + ')')
+            .attr('r', '24px')
+            .attr('data-stroke', node.id)
+            .attr('stroke-width', "2px")
+            .attr("class", "nodeImage " + (currentNode ? "currentNode" : (node.isProcess ? "process" : "node")));
+        if (currentNode) {
+            shapeSvg.attr("stroke", "#fb4200")
+        }
+
+        if (node.isIncomplete === true) {
+            parent.attr("class", "node isIncomplete show");
+            parent.insert("foreignObject")
+                .attr("x", "-25")
+                .attr("y", "-25")
+                .attr("width", "50")
+                .attr("height", "50")
+                .append("xhtml:div")
+                .insert("i")
+                .attr("class", "fa fa-hourglass-half");
+        }
+
+        if ($defs.select('pattern[id="img_' + imgName + '"]').empty()) {
+            var $pattern = $defs.append("pattern")
+                .attr("x", "0%")
+                .attr("y", "0%")
+                .attr("patternUnits", "objectBoundingBox")
+                .attr("id", "img_" + imgName)
+                .attr("width", "100%")
+                .attr("height", "100%")
+                .append('image')
+                .attr("href", function(d) {
+                    var that = this;
+                    if (node) {
+                        var getImageData = function(options) {
+                            var imagePath = options.imagePath,
+                                ajaxOptions = {
+                                    "url": imagePath,
+                                    "method": "get",
+                                    "cache": true
+                                }
+
+                            if (platform.name !== "IE") {
+                                ajaxOptions["mimeType"] = "text/plain; charset=x-user-defined";
+                            }
+                            shapeSvg.attr("data-iconpath", imagePath);
+                            $.ajax(ajaxOptions)
+                                .always(function(data, status, xhr) {
+                                    if (data.status == 404) {
+                                        getImageData({
+                                            "imagePath": Utils.getEntityIconPath({ entityData: node, errorUrl: imagePath })
+                                        });
+                                    } else if (data) {
+                                        if (platform.name !== "IE") {
+                                            imageObject[imageIconPath] = 'data:image/png;base64,' + LineageUtilsRef.base64Encode({ "data": data });
+                                        } else {
+                                            imageObject[imageIconPath] = imagePath;
+                                        }
+                                        d3.select(that).attr("xlink:href", imageObject[imageIconPath]);
+                                        if (imageIconPath !== shapeSvg.attr("data-iconpath")) {
+                                            shapeSvg.attr("data-iconpathorigin", imageIconPath);
+                                        }
+                                    }
+                                });
+                        }
+                        getImageData({
+                            "imagePath": imageIconPath
+                        });
+                    }
+                })
+                .attr("x", "4")
+                .attr("y", currentNode ? "3" : "4").attr("width", "40")
+                .attr("height", "40");
+
+        }
+
+        node.intersect = function(point) {
+            return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
+        };
+        return shapeSvg;
+    }
+    LineageUtils.arrowPointRender = function(parent, id, edge, type, viewOptions) {
+        var node = parent.node(),
+            parentNode = node ? node.parentNode : parent,
+            dagreD3 = viewOptions.dagreD3;
+        d3.select(parentNode).select('path.path').attr('marker-end', "url(#" + id + ")");
+        var marker = parent.append("marker")
+            .attr("id", id)
+            .attr("viewBox", "0 0 10 10")
+            .attr("refX", 8)
+            .attr("refY", 5)
+            .attr("markerUnits", "strokeWidth")
+            .attr("markerWidth", 4)
+            .attr("markerHeight", 4)
+            .attr("orient", "auto");
+
+        var path = marker.append("path")
+            .attr("d", "M 0 0 L 10 5 L 0 10 z")
+            .style("fill", edge.styleObj.stroke);
+        dagreD3.util.applyStyle(path, edge[type + "Style"]);
+    }
+    LineageUtils.BezierCurve = function(context) {
+        return {
+            lineStart: function() {
+                this.data = [];
+            },
+            point: function(x, y) {
+                this.data.push([x, y]);
+            },
+            lineEnd: function() {
+                var x0 = this.data[0][0],
+                    y0 = this.data[0][1],
+                    cp1x = this.data[1][0],
+                    cp1y = this.data[1][1],
+                    cp2Obj = this.data[this.data.length - 2],
+                    cp2x = cp2Obj[0],
+                    cp2y = cp2Obj[1],
+                    axisObj = this.data[this.data.length - 1],
+                    x1 = axisObj[0],
+                    y1 = axisObj[1];
+                context.moveTo(x0, y0);
+                context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x1, y1);
+            }
+        }
+    }
+    LineageUtils.SaveSvg = function(e, viewOptions) {
+        var that = this,
+            svg = viewOptions.svg,
+            svgWidth = viewOptions.svgWidth,
+            svgHeight = viewOptions.svgHeight,
+            downloadFileName = viewOptions.downloadFileName,
+            toggleLoader = viewOptions.toggleLoader,
+            svgClone = svg.cloneNode(true),
+            scaleFactor = 1;
+        setTimeout(function() {
+            if (platform.name === "Firefox") {
+                svgClone.setAttribute('width', svgWidth);
+                svgClone.setAttribute('height', svgHeight);
+            }
+            $('.hidden-svg').html(svgClone);
+            $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
+            $(svgClone).find("foreignObject").remove();
+            var canvasOffset = { x: 150, y: 150 },
+                setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
+                setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
+                xAxis = svgClone.getBBox().x,
+                yAxis = svgClone.getBBox().y;
+            svgClone.attributes.viewBox.value = xAxis + "," + yAxis + "," + setWidth + "," + setHeight;
+
+            var createCanvas = document.createElement('canvas');
+            createCanvas.id = "canvas";
+            createCanvas.style.display = 'none';
+
+            var body = $('body').append(createCanvas),
+                canvas = $('canvas')[0];
+            canvas.width = (svgClone.getBBox().width * scaleFactor) + canvasOffset.x;
+            canvas.height = (svgClone.getBBox().height * scaleFactor) + canvasOffset.y;
+
+            var ctx = canvas.getContext('2d'),
+                data = (new XMLSerializer()).serializeToString(svgClone),
+                DOMURL = window.URL || window.webkitURL || window;
+
+            ctx.fillStyle = "#FFFFFF";
+            ctx.fillRect(0, 0, canvas.width, canvas.height);
+            ctx.strokeRect(0, 0, canvas.width, canvas.height);
+            ctx.restore();
+
+            var img = new Image(canvas.width, canvas.height);
+            var svgBlob = new Blob([data], { type: 'image/svg+xml;base64' });
+            if (platform.name === "Safari") {
+                svgBlob = new Blob([data], { type: 'image/svg+xml' });
+            }
+            var url = DOMURL.createObjectURL(svgBlob);
+
+            img.onload = function() {
+                try {
+                    var a = document.createElement("a");
+                    a.download = downloadFileName;
+                    document.body.appendChild(a);
+                    ctx.drawImage(img, 50, 50, canvas.width, canvas.height);
+                    canvas.toBlob(function(blob) {
+                        if (!blob) {
+                            Utils.notifyError({
+                                content: "There was an error in downloading Lineage!"
+                            });
+                            toggleLoader();
+                            return;
+                        }
+                        a.href = DOMURL.createObjectURL(blob);
+                        if (blob.size > 10000000) {
+                            Utils.notifyWarn({
+                                content: "The Image size is huge, please open the image in a browser!"
+                            });
+                        }
+                        a.click();
+                        toggleLoader();
+                        if (platform.name === 'Safari') {
+                            that.refreshGraphForSafari({
+                                edgeEl: that.$('svg g.node')
+                            });
+                        }
+                    }, 'image/png');
+                    $('.hidden-svg').html('');
+                    createCanvas.remove();
+
+                } catch (err) {
+                    Utils.notifyError({
+                        content: "There was an error in downloading Lineage!"
+                    });
+                    toggleLoader();
+                }
+
+            };
+            img.src = url;
+        }, 0);
+    }
+    return LineageUtils;
 });
\ No newline at end of file