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