You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by kb...@apache.org on 2020/10/13 13:23:30 UTC
[atlas] 01/02: ATLAS-3954: UI: Type system property table
improvement
This is an automated email from the ASF dual-hosted git repository.
kbhatt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
commit 3c0b2746d0065b1d95b4511c46a8655d4167096e
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Mon Oct 12 15:49:09 2020 +0530
ATLAS-3954: UI: Type system property table improvement
---
dashboardv2/public/css/scss/common.scss | 10 +
dashboardv2/public/css/scss/graph.scss | 36 +++-
dashboardv2/public/css/scss/table.scss | 28 +++
.../js/external_lib/atlas-lineage/dist/index.js | 2 +-
.../atlas-lineage/src/Utils/LineageUtils.js | 8 +-
.../js/external_lib/atlas-lineage/src/index.js | 78 +++++--
.../AdministratorLayoutView_tmpl.html | 2 +-
.../detail_page/DetailPageLayoutView_tmpl.html | 2 +-
.../js/templates/graph/LineageLayoutView_tmpl.html | 24 +--
.../templates/graph/TypeSystemTreeView_tmpl.html | 67 +++++-
dashboardv2/public/js/utils/CommonViewFunction.js | 29 ++-
.../public/js/views/graph/LineageLayoutView.js | 35 +--
.../public/js/views/graph/TypeSystemTreeView.js | 234 ++++++++++++---------
dashboardv3/public/css/scss/common.scss | 10 +
dashboardv3/public/css/scss/graph.scss | 36 +++-
dashboardv3/public/css/scss/table.scss | 29 +++
.../js/external_lib/atlas-lineage/dist/index.js | 2 +-
.../atlas-lineage/src/Utils/LineageUtils.js | 8 +-
.../js/external_lib/atlas-lineage/src/index.js | 78 +++++--
.../AdministratorLayoutView_tmpl.html | 2 +-
.../detail_page/DetailPageLayoutView_tmpl.html | 2 +-
.../js/templates/graph/LineageLayoutView_tmpl.html | 24 +--
.../templates/graph/TypeSystemTreeView_tmpl.html | 67 +++++-
dashboardv3/public/js/utils/CommonViewFunction.js | 29 ++-
.../public/js/views/graph/LineageLayoutView.js | 35 +--
.../public/js/views/graph/TypeSystemTreeView.js | 234 ++++++++++++---------
26 files changed, 789 insertions(+), 322 deletions(-)
diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index b51a6f2..e93eef1 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -180,6 +180,11 @@ pre {
.json-string {
color: olive;
+
+ &.cursor {
+ cursor: pointer;
+ text-decoration: underline;
+ }
}
}
@@ -191,6 +196,11 @@ pre {
.panel-body .memory-details {
pre {
&.code-block {
+ &.fixed-height {
+ max-height: 112px;
+ overflow: auto;
+ }
+
&.shrink {
height: 144px;
diff --git a/dashboardv2/public/css/scss/graph.scss b/dashboardv2/public/css/scss/graph.scss
index 971cf60..cd5e220 100644
--- a/dashboardv2/public/css/scss/graph.scss
+++ b/dashboardv2/public/css/scss/graph.scss
@@ -193,7 +193,7 @@ span#zoom_in {
width: 100%;
right: 0;
padding: 0 !important;
- z-index: 9999;
+ z-index: 99;
overflow: hidden !important;
background: white;
@@ -266,4 +266,38 @@ span#zoom_in {
box-shadow: 0px 0px 3px 1px #80808080;
}
+}
+
+
+.box-panel.fix-box {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ height: 100vh;
+ max-height: 100vh;
+ z-index: 999;
+ bottom: 0;
+ width: 400px;
+ overflow: auto;
+ border-radius: 0px;
+ margin: 0 !important;
+
+ &.slide-from-left.size-lg {
+ left: -413px;
+
+ &.show-box-panel {
+ left: 0;
+ margin: 0 !important;
+ }
+ }
+
+ .body {
+ tbody {
+ overflow: auto;
+ height: calc(100vh - 48px);
+ position: absolute;
+ padding-bottom: 15px;
+ }
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/table.scss b/dashboardv2/public/css/scss/table.scss
index 519d083..3db8a4c 100644
--- a/dashboardv2/public/css/scss/table.scss
+++ b/dashboardv2/public/css/scss/table.scss
@@ -41,6 +41,7 @@ tr.empty {
}
.entity-detail-table,
+.type-node-details,
.relationship-detail-table {
position: relative;
@@ -66,6 +67,26 @@ tr.empty {
}
}
+.type-node-details {
+ .header {
+ .pretty.p-switch .state:before {
+ border: 1px solid white;
+ }
+
+ .pretty.p-switch .state label:after {
+ background-color: white !important;
+ }
+
+ .pretty.p-switch.p-fill input:checked~.state label:after {
+ background-color: #4a90e2 !important;
+ }
+
+ .pretty.p-switch.p-fill input:checked~.state.p-primary:before {
+ background-color: white !important;
+ }
+ }
+}
+
.backgrid {
td {
white-space: normal;
@@ -98,6 +119,13 @@ tr.empty {
}
}
}
+
+ .debuggging-table-header {
+ padding-right: 0px !important;
+ button{
+ float: right;
+ }
+ }
}
.backgrid-paginator ul {
diff --git a/dashboardv2/public/js/external_lib/atlas-lineage/dist/index.js b/dashboardv2/public/js/external_lib/atlas-lineage/dist/index.js
index c2f68bb..e82cb48 100644
--- a/dashboardv2/public/js/external_lib/atlas-lineage/dist/index.js
+++ b/dashboardv2/public/js/external_lib/atlas-lineage/dist/index.js
@@ -1 +1 @@
-!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("platform"),require("dagreD3")):"function"==typeof define&&define.amd?define(["platform","dagreD3"],e):"object"==typeof exports?exports.LineageHelper=e(require("platform"),require("dagreD3")):t.LineageHelper=e(t.platform,t.dagreD3)}(window,(function(t,e){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i. [...]
\ No newline at end of file
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("platform"),require("dagreD3")):"function"==typeof define&&define.amd?define(["platform","dagreD3"],e):"object"==typeof exports?exports.LineageHelper=e(require("platform"),require("dagreD3")):t.LineageHelper=e(t.platform,t.dagreD3)}(window,(function(t,e){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i. [...]
\ No newline at end of file
diff --git a/dashboardv2/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js b/dashboardv2/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
index 7c482b3..55f363e 100644
--- a/dashboardv2/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
+++ b/dashboardv2/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
@@ -374,7 +374,7 @@ const LineageUtils = {
reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(file);
},
- imgShapeRender: function (parent, bbox, node, { dagreD3, defsEl, imgBasePath, guid }) {
+ imgShapeRender: function (parent, bbox, node, { dagreD3, defsEl, imgBasePath, guid, isRankdirToBottom }) {
var that = this,
viewGuid = guid,
imageIconPath = this.getEntityIconPath({ entityData: node, imgBasePath }),
@@ -391,7 +391,7 @@ const LineageUtils = {
var shapeSvg = parent
.append("circle")
.attr("fill", "url(#img_" + imgName + ")")
- .attr("r", "24px")
+ .attr("r", isRankdirToBottom ? "30px" : "24px")
.attr("data-stroke", node.id)
.attr("stroke-width", "2px")
.attr("class", "nodeImage " + (currentNode ? "currentNode" : node.isProcess ? "process" : "node"));
@@ -478,8 +478,8 @@ const LineageUtils = {
});
}
})
- .attr("x", "4")
- .attr("y", currentNode ? "3" : "4")
+ .attr("x", isRankdirToBottom ? "11" : "4")
+ .attr("y", isRankdirToBottom ? "20" : currentNode ? "3" : "4")
.attr("width", "40")
.attr("height", "40");
}
diff --git a/dashboardv2/public/js/external_lib/atlas-lineage/src/index.js b/dashboardv2/public/js/external_lib/atlas-lineage/src/index.js
index 1ac517a..3ceb3d9 100644
--- a/dashboardv2/public/js/external_lib/atlas-lineage/src/index.js
+++ b/dashboardv2/public/js/external_lib/atlas-lineage/src/index.js
@@ -26,6 +26,7 @@ import "./styles/style.scss";
export default class LineageHelper {
constructor(options) {
+ this.options = {};
this._updateOptions(options);
const { el, manualTrigger = false } = this.options;
if (el === undefined) {
@@ -33,6 +34,7 @@ export default class LineageHelper {
}
this.initReturnObj = {
init: (arg) => this.init(arg),
+ updateOptions: (options) => this._updateAllOptions(options),
createGraph: (opt = {}) => this._createGraph(this.options, this.graphOptions, opt),
clear: (arg) => this.clear(arg),
refresh: (arg) => this.refresh(arg),
@@ -78,12 +80,27 @@ export default class LineageHelper {
return this.initReturnObj;
}
/**
+ * [updateAllOptions]
+ * @param {[type]}
+ * @return {[type]}
+ */
+ _updateAllOptions(options) {
+ Object.assign(this.options, options);
+ var svgRect = this.svg.node().getBoundingClientRect();
+ this.graphOptions.width = this.options.width || svgRect.width;
+ this.graphOptions.height = this.options.height || svgRect.height;
+ const { svg, width, height, guid } = this.graphOptions;
+ const { fitToScreen } = this.options;
+ svg.select("g").node().removeAttribute("transform");
+ svg.attr("viewBox", "0 0 " + width + " " + height).attr("enable-background", "new 0 0 " + width + " " + height);
+ this.centerAlign({ fitToScreen, guid });
+ }
+ /**
* [updateOptions get the options from user and appedn add it in this,option context]
* @param {[Object]} options [lib options from user]
* @return {[null]} [null]
*/
_updateOptions(options) {
- this.options = {};
Object.assign(this.options, { filterObj: { isProcessHideCheck: false, isDeletedEntityHideCheck: false } }, options);
}
/**
@@ -200,7 +217,7 @@ export default class LineageHelper {
if (node && node.attributes) {
downloadFileName = `${node.attributes.qualifiedName || node.attributes.name || "lineage_export"}.png`;
} else {
- downloadFileName = "lineage_export.png";
+ downloadFileName = "export.png";
}
}
@@ -258,6 +275,7 @@ export default class LineageHelper {
this.svg = select(el);
if (!(el instanceof SVGElement)) {
+ this.svg.selectAll("*").remove();
this.svg = this.svg
.append("svg")
.attr("xmlns", "http://www.w3.org/2000/svg")
@@ -385,7 +403,19 @@ export default class LineageHelper {
* @return {[type]} [description]
*/
_createGraph(
- { data = {}, imgBasePath, isShowTooltip, isShowHoverPath, onLabelClick, onPathClick, onNodeClick, zoom, fitToScreen },
+ {
+ data = {},
+ imgBasePath,
+ isShowTooltip,
+ isShowHoverPath,
+ onLabelClick,
+ onPathClick,
+ onNodeClick,
+ zoom,
+ fitToScreen,
+ getToolTipContent,
+ toolTipTitle
+ },
graphOptions,
{ refresh }
) {
@@ -393,7 +423,8 @@ export default class LineageHelper {
this.options.beforeRender();
}
const that = this,
- { svg, g, width, height } = graphOptions;
+ { svg, g, width, height } = graphOptions,
+ isRankdirToBottom = this.options.dagreOptions && this.options.dagreOptions.rankdir === "tb";
if (svg instanceof selection === false) {
throw new Error("svg is not initialized or something went wrong while creatig graph instance");
@@ -428,6 +459,7 @@ export default class LineageHelper {
render.shapes().img = function () {
return LineageUtils.imgShapeRender(...arguments, {
...graphOptions,
+ isRankdirToBottom: isRankdirToBottom,
imgBasePath: that._getValueFromUser(imgBasePath),
defsEl
});
@@ -437,19 +469,26 @@ export default class LineageHelper {
.attr("class", "d3-tip")
.offset([10, 0])
.html((d) => {
- var value = g.node(d);
- var htmlStr = "";
- if (value.id !== this.guid) {
- htmlStr = "<h5 style='text-align: center;'>" + (value.isLineage ? "Lineage" : "Impact") + "</h5>";
- }
- htmlStr += "<h5 class='text-center'><span style='color:#359f89'>" + value.toolTipLabel + "</span></h5> ";
- if (value.typeName) {
- htmlStr += "<h5 class='text-center'><span>(" + value.typeName + ")</span></h5> ";
- }
- if (value.queryText) {
- htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
+ if (getToolTipContent && typeof getToolTipContent === "function") {
+ return getToolTipContent(d, g.node(d));
+ } else {
+ var value = g.node(d);
+ var htmlStr = "";
+ if (toolTipTitle) {
+ htmlStr = "<h5 style='text-align: center;'>" + toolTipTitle + "</h5>";
+ } else if (value.id !== this.guid) {
+ htmlStr = "<h5 style='text-align: center;'>" + (value.isLineage ? "Lineage" : "Impact") + "</h5>";
+ }
+
+ htmlStr += "<h5 class='text-center'><span style='color:#359f89'>" + value.toolTipLabel + "</span></h5> ";
+ if (value.typeName) {
+ htmlStr += "<h5 class='text-center'><span>(" + value.typeName + ")</span></h5> ";
+ }
+ if (value.queryText) {
+ htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
+ }
+ return "<div class='tip-inner-scroll'>" + htmlStr + "</div>";
}
- return "<div class='tip-inner-scroll'>" + htmlStr + "</div>";
});
svg.call(tooltip);
@@ -463,7 +502,12 @@ export default class LineageHelper {
//change text postion
svgGroupEl
.selectAll("g.nodes g.label")
- .attr("transform", "translate(2,-35)")
+ .attr("transform", () => {
+ if (isRankdirToBottom) {
+ return "translate(2,-20)";
+ }
+ return "translate(2,-35)";
+ })
.on("mouseenter", function (d) {
event.preventDefault();
select(this).classed("highlight", true);
diff --git a/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html b/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
index f9ca214..85bf9ba 100644
--- a/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
@@ -37,7 +37,7 @@
<div id="r_adminTableLayoutView">
</div>
</div>
- <div id="tab-typeSystem" role="typeSystem" class="tab-pane animated fadeIn" style="position: relative;">
+ <div id="tab-typeSystem" role="typeSystem" class="tab-pane" style="position: relative;">
<div id="r_typeSystemTreeLayoutView">
</div>
</div>
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index 824dbdc..5854dd7 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -91,7 +91,7 @@
</div>
</div>
</div>
- <div id="tab-lineage" role="lineage" class="tab-pane animated fadeIn">
+ <div id="tab-lineage" role="lineage" class="tab-pane">
<div id="r_lineageLayoutView" class="animated position-relative" align="center">
<div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
diff --git a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
index 8e6e6b2..f6f61e2 100644
--- a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -124,22 +124,22 @@
</button>
</div>
</div>
- <div class="box-panel size-lg node-details slide-from-left lineage-node-detail">
- <div class="header clearfix">
- <h4><span data-id="typeName"></span></h4>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- </div>
- <div class="body">
- <table class="table bold-key">
- <tbody data-id="nodeDetailTable"></tbody>
- </table>
- </div>
- </div>
<div class="fontLoader">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
<div class="legends pull-left" style="height: 25px; padding: 2px;"></div>
<div class="svg" style="height: 100%; width: 100%"></div>
</div>
+<div class="box-panel size-lg slide-from-left lineage-node-detail fix-box">
+ <div class="header clearfix">
+ <h4><span data-id="typeName"></span></h4>
+ <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ </div>
+ <div class="body">
+ <table class="table bold-key">
+ <tbody data-id="nodeDetailTable"></tbody>
+ </table>
+ </div>
+</div>
<div class="hidden-svg"></div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/graph/TypeSystemTreeView_tmpl.html b/dashboardv2/public/js/templates/graph/TypeSystemTreeView_tmpl.html
index 5340de4..005c061 100644
--- a/dashboardv2/public/js/templates/graph/TypeSystemTreeView_tmpl.html
+++ b/dashboardv2/public/js/templates/graph/TypeSystemTreeView_tmpl.html
@@ -15,16 +15,30 @@
* limitations under the License.
-->
<div id="typeSystemTreeViewPage" data-id="typeSystemTreeViewPage" class="systemTypeTree" style="height: calc(100vh - 180px); width: 100%; position: relative;overflow: hidden;">
- <div class="box-panel size-lg node-details slide-from-left lineage-node-detail">
+ <div class="box-panel size-lg type-node-details fix-box slide-from-left lineage-node-detail">
<div class="header clearfix">
- <h4><span data-id="typeName"></span></h4>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ <div class="typeDetailHeader">
+ <h4 style="padding-right: 67px;"><span data-id="typeName"></span></h4>
+ <div class="pretty p-switch p-fill" style="position: absolute;top: 13px;right: 32px;">
+ <input type="checkbox" data-id="noValueToggle" title="Show empty values" />
+ <div class="state p-primary">
+ <label></label>
+ </div>
+ </div>
+ <span data-id="box-close" class="btn btn-sm btn-close "><i class="fa fa-close"></i></span>
+ </div>
+ <div class="typeAttrDetailHeader" style="display: none;">
+ <span data-id="box-back" class="btn btn-sm btn-close" style="left: 0px; right: auto;"><i class="fa fa-angle-left"></i></span>
+ <h4 style="padding-left: 27px;"><span data-id="typeAttrDetailHeader"></span></h4>
+ </div>
</div>
<div class="body">
<table class="table bold-key">
- <tbody data-id="nodeDetailTable"></tbody>
+ <tbody data-id="nodeDetailTable" class="hide-empty-value"></tbody>
</table>
+ <div data-id="attribute-table" style="height: calc(100vh - 60px);display: none">
+ <pre class="code-block" style="height: 100%"></pre>
+ </div>
</div>
</div>
<div class="fontLoader">
@@ -49,7 +63,6 @@
<div class="body">
<div class="col-sm-12 no-padding">
<div class="srchType clearfix">
- <label class="srchTitle">Search Lineage Entity: </label>
<div class="">
<div class="col-sm-12 no-padding temFilter">
<select data-id="typeSearch"></select>
@@ -59,28 +72,62 @@
</div>
</div>
</div>
+ <div class="box-panel setting-box">
+ <div class="header clearfix">
+ <h4>Settings</h4>
+ <span data-id="box-close" class="btn btn-sm btn-close"><i class="fa fa-close"></i></span>
+ </div>
+ <div class="body">
+ <div class="showOnlyHoverPath form-group text-left col-sm-12">
+ <div class="pretty p-switch p-fill">
+ <input type="checkbox" checked class="pull-left" data-id="showOnlyHoverPath" value="" />
+ <div class="state p-primary">
+ <label>On hover show current path</label>
+ </div>
+ </div>
+ </div>
+ <div class="showTooltip form-group text-left col-sm-12">
+ <div class="pretty p-switch p-fill">
+ <input type="checkbox" class="pull-left" data-id="showTooltip" value="" />
+ <div class="state p-primary">
+ <label>Show node details on hover</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
<div class="graph-button-group pull-right">
<div>
- <button data-id="reset" class="btn btn-action btn-gray btn-sm" title="Realign Lineage">
+ <button data-id="reset" class="btn btn-action btn-gray btn-sm" title="Reset">
<i class="fa fa-retweet"></i>
</button>
</div>
<div>
+ <button data-id="saveSvg" class="btn btn-action btn-gray btn-sm" title="Export to PNG">
+ <i class="fa fa-camera"></i>
+ </button>
+ </div>
+ <div>
+ <button type="button" data-id="setting-toggler" title="Settings" class="btn btn-action btn-gray btn-sm">
+ <i class="fa fa-gear"></i>
+ </button>
+ </div>
+ <div>
<button type="button" data-id="filter-toggler" title="Filter" class="btn btn-action btn-gray btn-sm"><i class="fa fa-filter"></i></button>
</div>
<div>
<button type="button" data-id="search-toggler" title="Search" class="btn btn-action btn-gray btn-sm"><i class="fa fa-search"></i></button>
</div>
<div class="btn-group">
- <button type="button" class="btn btn-action btn-gray btn-sm lineageZoomButton" title="Zoom In" data-id="zoom-in">
+ <button type="button" class="btn btn-action btn-gray btn-sm" title="Zoom In" data-id="zoom-in">
<i class="fa fa-search-plus"></i>
</button>
- <button type="button" class="btn btn-action btn-gray btn-sm lineageZoomButton" title="Zoom Out" data-id="zoom-out">
+ <button type="button" class="btn btn-action btn-gray btn-sm" title="Zoom Out" data-id="zoom-out">
<i class="fa fa-search-minus"></i>
</button>
</div>
<div>
- <button type="button" data-id="fullScreen-toggler" title="Full screen" class="btn btn-action btn-gray btn-sm fullscreen_lineage">
+ <button type="button" data-id="fullScreen-toggler" title="Full screen" class="btn btn-action btn-gray btn-sm">
<i class="fa fa-expand"></i>
</button>
</div>
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index b116681..4fcb0fc 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -79,6 +79,8 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
sortBy = options.sortBy,
valueObject = options.valueObject,
extractJSON = options.extractJSON,
+ getArrayOfStringElement = options.getArrayOfStringElement,
+ getArrayOfStringFormat = options.getArrayOfStringFormat,
isTable = _.isUndefined(options.isTable) ? true : options.isTable,
attributeDefs = options.attributeDefs,
formatIntVal = options.formatIntVal,
@@ -108,6 +110,9 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
return "N/A";
},
getValue = function(val, key) {
+ if (options && options.getValue) {
+ val = options.getValue(val, key);
+ }
if (!_.isUndefined(val) && !_.isNull(val)) {
if ((_.isNumber(val) || !_.isNaN(parseInt(val))) && formatIntVal) {
return numberFormat(val);
@@ -185,7 +190,12 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (_.isString(inputOutputField) || _.isBoolean(inputOutputField) || _.isNumber(inputOutputField)) {
var tempVarfor$check = inputOutputField.toString();
if (tempVarfor$check.indexOf("$") == -1) {
- valueOfArray.push('<span class="json-string">' + getValue(inputOutputField, key) + '</span>');
+ var tmpVal = getValue(inputOutputField, key)
+ if (getArrayOfStringElement) {
+ valueOfArray.push(getArrayOfStringElement(tmpVal, key));
+ } else {
+ valueOfArray.push('<span class="json-string">' + tmpVal + '</span>');
+ }
}
} else if (_.isObject(inputOutputField) && !id) {
var attributesList = inputOutputField;
@@ -251,7 +261,11 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
}
if (valueOfArray.length) {
- subLink = valueOfArray.join(', ');
+ if (getArrayOfStringFormat) {
+ subLink = getArrayOfStringFormat(valueOfArray, key);
+ } else {
+ subLink = valueOfArray.join(', ');
+ }
}
return subLink === "" ? getEmptyString(key) : subLink;
}
@@ -297,12 +311,17 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (_.isObject(valueObject[key]) && !_.isEmpty(valueObject[key])) {
var matchedLinkString = val.match(/href|value-loader\w*/g),
matchedJson = val.match(/json-value|json-string\w*/g),
+ matchedKey = val.match(/json-key\w*/g),
isMatchLinkStringIsSingle = matchedLinkString && matchedLinkString.length <= 5,
isMatchJSONStringIsSingle = matchedJson && matchedJson.length == 1,
expandCollapseButton = "";
- if ((matchedJson && !isMatchJSONStringIsSingle) || (matchedLinkString && !isMatchLinkStringIsSingle)) {
- expandCollapseButton = '<button class="expand-collapse-button"><i class="fa"></i></button>';
- htmlTag = '<pre class="shrink code-block ' + (isMatchJSONStringIsSingle ? 'fixed-height' : '') + '">' + expandCollapseButton + '<code>' + val + '</code></pre>';
+ if ((matchedJson) || (matchedLinkString)) {
+ var className = "code-block fixed-height";
+ if (!isMatchJSONStringIsSingle) {
+ className += " shrink";
+ expandCollapseButton = '<button class="expand-collapse-button"><i class="fa"></i></button>';
+ }
+ htmlTag = '<pre class="' + className + '">' + expandCollapseButton + '<code>' + val + '</code></pre>';
}
}
table += '<tr class="' + appendClass + '"><td>' + (_.escape(key) + listCount) + '</td><td>' + htmlTag + '</td></tr>';
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 5d0b70b..aa26580 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -134,13 +134,13 @@ define(['require',
},
onShow: function() {
this.$('.fontLoader').show();
- this.$el.resizable({
- handles: ' s',
- minHeight: 375,
- stop: function(event, ui) {
- ui.element.height(($(this).height()));
- },
- });
+ // this.$el.resizable({
+ // handles: ' s',
+ // minHeight: 375,
+ // stop: function(event, ui) {
+ // ui.element.height(($(this).height()));
+ // },
+ // });
},
onClickLineageFullscreenToggler: function(e) {
var icon = $(e.currentTarget).find('i'),
@@ -152,6 +152,11 @@ define(['require',
icon.parent('button').attr("data-original-title", "Default View");
}
panel.toggleClass('fullscreen-mode');
+ var node = this.$("svg").parent()[0].getBoundingClientRect();
+ this.LineageHelperRef.updateOptions({
+ width: node.width,
+ height: node.height
+ });
},
onCheckUnwantedEntity: function(e) {
var that = this;
@@ -210,6 +215,8 @@ define(['require',
},
onClickResetLineage: function() {
this.LineageHelperRef.refresh();
+ this.searchNodeObj.selectedNode = "";
+ this.ui.lineageTypeSearch.data({ refresh: true }).val("").trigger("change");
},
onClickSaveSvg: function(e, a) {
this.LineageHelperRef.exportLineage();
@@ -249,10 +256,6 @@ define(['require',
})
},
createGraph: function(data) {
- // 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;
$('.resizeGraph').css("height", this.$('.svg').height() + "px");
@@ -364,9 +367,13 @@ define(['require',
}).on('change.select2', function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="typeSearch"]').val();
- that.searchNodeObj.selectedNode = selectedNode;
- that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.lineageTypeSearch.data("refresh")) {
+ var selectedNode = $('[data-id="typeSearch"]').val();
+ that.searchNodeObj.selectedNode = selectedNode;
+ that.LineageHelperRef.searchNode({ guid: selectedNode });
+ } else {
+ that.ui.lineageTypeSearch.data("refresh", false);
+ }
});
if (this.searchNodeObj.selectedNode) {
this.ui.lineageTypeSearch.val(this.searchNodeObj.selectedNode);
diff --git a/dashboardv2/public/js/views/graph/TypeSystemTreeView.js b/dashboardv2/public/js/views/graph/TypeSystemTreeView.js
index 3095bca..90734a4 100644
--- a/dashboardv2/public/js/views/graph/TypeSystemTreeView.js
+++ b/dashboardv2/public/js/views/graph/TypeSystemTreeView.js
@@ -55,16 +55,23 @@ define([
typeSystemTreeViewPage: "[data-id='typeSystemTreeViewPage']",
boxClose: '[data-id="box-close"]',
nodeDetailTable: '[data-id="nodeDetailTable"]',
+ attributeTable: '[data-id="attribute-table"]',
typeSearch: '[data-id="typeSearch"]',
filterServiceType: '[data-id="filterServiceType"]',
onZoomIn: '[data-id="zoom-in"]',
onZoomOut: '[data-id="zoom-out"]',
filterBox: ".filter-box",
searchBox: ".search-box",
+ settingBox: '.setting-box',
filterToggler: '[data-id="filter-toggler"]',
+ settingToggler: '[data-id="setting-toggler"]',
searchToggler: '[data-id="search-toggler"]',
reset: '[data-id="reset"]',
- fullscreenToggler: '[data-id="fullScreen-toggler"]'
+ fullscreenToggler: '[data-id="fullScreen-toggler"]',
+ noValueToggle: "[data-id='noValueToggle']",
+ showOnlyHoverPath: '[data-id="showOnlyHoverPath"]',
+ showTooltip: '[data-id="showTooltip"]',
+ saveSvg: '[data-id="saveSvg"]',
},
/** ui events hash */
events: function() {
@@ -73,9 +80,19 @@ define([
events["click " + this.ui.onZoomIn] = "onClickZoomIn";
events["click " + this.ui.onZoomOut] = "onClickZoomOut";
events["click " + this.ui.filterToggler] = "onClickFilterToggler";
+ events["click " + this.ui.settingToggler] = 'onClickSettingToggler';
events["click " + this.ui.searchToggler] = "onClickSearchToggler";
+ events["click " + this.ui.saveSvg] = 'onClickSaveSvg';
events["click " + this.ui.fullscreenToggler] = "onClickFullscreenToggler";
events["click " + this.ui.reset] = "onClickReset";
+ events["click " + this.ui.noValueToggle] = function() {
+ this.showAllProperties = !this.showAllProperties;
+ this.ui.noValueToggle.attr("data-original-title", (this.showAllProperties ? "Hide" : "Show") + " empty values");
+ Utils.togglePropertyRelationshipTableEmptyValues({
+ "inputType": this.ui.noValueToggle,
+ "tableEl": this.ui.nodeDetailTable
+ });
+ };
return events;
},
@@ -90,7 +107,35 @@ define([
this.initializeGraph();
this.fetchGraphData();
},
- onRender: function() {},
+ onRender: function() {
+ var that = this;
+ this.$el.on("click", "code li[data-def]", function() {
+ if (that.selectedDetailNode) {
+ var dataObj = $(this).data(),
+ defObj = that.selectedDetailNode[dataObj.def],
+ newData = null;
+ if (dataObj.def === "businessAttributes") {
+ newData = defObj[dataObj.attribute];
+ } else {
+ newData = _.filter(defObj, { name: dataObj.attribute });
+ }
+ that.ui.attributeTable.find("pre").html('<code style="max-height: 100%">' + Utils.JSONPrettyPrint(newData, function(val) {
+ return val;
+ }) + '</code>');
+ that.$el.find('[data-id="typeAttrDetailHeader"]').text(dataObj.def);
+ that.ui.nodeDetailTable.hide("slide", { direction: "right" }, 400);
+ that.ui.attributeTable.show("slide", { direction: "left" }, 400);
+ that.$el.find(".typeDetailHeader").hide();
+ that.$el.find(".typeAttrDetailHeader").show()
+ }
+ });
+ this.$el.on("click", "span[data-id='box-back']", function() {
+ that.ui.nodeDetailTable.show("slide", { direction: "right" }, 400);
+ that.ui.attributeTable.hide("slide", { direction: "left" }, 400);
+ that.$el.find(".typeDetailHeader").show();
+ that.$el.find(".typeAttrDetailHeader").hide()
+ })
+ },
fetchGraphData: function(options) {
var that = this;
var entityTypeDef = that.entityDefCollection.fullCollection.toJSON();
@@ -101,7 +146,7 @@ define([
}
if (entityTypeDef.length) {
that.generateData($.extend(true, {}, { data: entityTypeDef }, options)).then(function(graphObj) {
- that.createGraph();
+ that.createGraph(options);
});
}
},
@@ -161,91 +206,56 @@ define([
if (options.data) {
if (options.filter) {
- var pendingSubList = {},
- pendingSuperList = {},
- temp = {},
- doneList = {},
- traveseSubSuper = function(obj, ignoreSubTypes) {
- var fromEntityId = obj.guid;
- if (!ignoreSubTypes && obj.subTypes.length) {
- _.each(obj.subTypes, function(subType) {
- var tempObj = doneList[subType] || temp[subType];
- if (tempObj) {
+ // filter
+ var pendingSuperList = {},
+ outOfFilterData = {},
+ doneList = {};
+
+ var linkParents = function(obj) {
+ if (obj && obj.superTypes.length) {
+ _.each(obj.superTypes, function(superType) {
+ var fromEntityId = obj.guid;
+ var tempObj = doneList[superType] || outOfFilterData[superType];
+ if (tempObj) {
+ if (!doneList[superType]) {
setNode(tempObj.guid, tempObj);
- setEdge(fromEntityId, tempObj.guid);
- } else {
- if (pendingSubList[subType]) {
- pendingSubList[subType].push(fromEntityId);
- } else {
- pendingSubList[subType] = [fromEntityId];
- }
}
- });
- }
- if (obj.superTypes.length) {
- _.each(obj.superTypes, function(superType) {
- var tempObj = doneList[superType] || temp[superType];
- if (tempObj) {
- setNode(tempObj.guid, tempObj);
- setEdge(tempObj.guid, fromEntityId);
- if (tempObj.superTypes.length) {
- traveseSubSuper(tempObj, true);
- }
+ setEdge(tempObj.guid, fromEntityId);
+ linkParents(tempObj);
+ } else {
+ if (pendingSuperList[superType]) {
+ pendingSuperList[superType].push(fromEntityId);
} else {
- if (pendingSuperList[superType]) {
- pendingSuperList[superType].push(fromEntityId);
- } else {
- pendingSuperList[superType] = [fromEntityId];
- }
+ pendingSuperList[superType] = [fromEntityId];
}
- });
- }
- };
+ }
+ });
+ }
+ }
_.each(options.data, function(obj) {
var fromEntityId = obj.guid;
+ if (pendingSuperList[obj.name]) {
+ doneList[obj.name] = obj;
+ setNode(fromEntityId, obj);
+ _.map(pendingSuperList[obj.name], function(guid) {
+ setEdge(fromEntityId, guid);
+ });
+ delete pendingSuperList[obj.name];
+ linkParents(obj);
+ }
if (obj.serviceType === options.filter) {
doneList[obj.name] = obj;
setNode(fromEntityId, obj);
- if (pendingSubList[obj.name]) {
- _.map(pendingSubList[obj.name], function(guid) {
- setEdge(guid, fromEntityId);
- });
- delete pendingSubList[obj.name];
- }
- if (pendingSuperList[obj.name]) {
- _.map(pendingSuperList[obj.name], function(guid) {
- setEdge(fromEntityId, guid);
- });
- delete pendingSuperList[obj.name];
- }
- traveseSubSuper(obj);
- } else {
- if (pendingSubList[obj.name]) {
- setNode(fromEntityId, obj);
- doneList[obj.name] = obj;
- _.map(pendingSubList[obj.name], function(guid) {
- setEdge(guid, fromEntityId);
- });
- delete pendingSubList[obj.name];
- }
- if (pendingSuperList[obj.name]) {
- var fromEntityId = obj.guid;
- setNode(fromEntityId, obj);
- doneList[obj.name] = obj;
- _.map(pendingSuperList[obj.name], function(guid) {
- setEdge(fromEntityId, guid);
- });
- delete pendingSuperList[obj.name];
- }
- if (!doneList[obj.name]) {
- temp[obj.name] = obj;
- }
+ linkParents(obj);
+ } else if (!doneList[obj.name] && !outOfFilterData[obj.name]) {
+ outOfFilterData[obj.name] = obj;
}
});
- pendingSubList = null;
pendingSuperList = null;
doneList = null;
+ outOfFilterData = null;
} else {
+ // Without filter
var pendingList = {},
doneList = {};
@@ -308,11 +318,19 @@ define([
onClickFilterToggler: function() {
this.toggleBoxPanel({ el: this.ui.filterBox });
},
+ onClickSettingToggler: function() {
+ this.toggleBoxPanel({ el: this.ui.settingBox });
+ },
onClickSearchToggler: function() {
this.toggleBoxPanel({ el: this.ui.searchBox });
},
onClickReset: function() {
this.fetchGraphData({ refresh: true });
+ this.ui.typeSearch.data({ refresh: true }).val("").trigger("change");
+ this.ui.filterServiceType.data({ refresh: true }).val("").trigger("change");
+ },
+ onClickSaveSvg: function(e, a) {
+ this.LineageHelperRef.exportLineage({ downloadFileName: "TypeSystemView" });
},
onClickFullscreenToggler: function(e) {
var icon = $(e.currentTarget).find("i"),
@@ -324,42 +342,65 @@ define([
icon.parent("button").attr("data-original-title", "Default View");
}
panel.toggleClass("fullscreen-mode");
+ var node = this.$("svg.main").parent()[0].getBoundingClientRect();
+ this.LineageHelperRef.updateOptions({
+ width: node.width,
+ height: node.height
+ });
},
updateDetails: function(data) {
this.$("[data-id='typeName']").text(Utils.getName(data));
- delete data.id;
+
+ this.selectedDetailNode = {};
+ this.selectedDetailNode.atttributes = data.attributeDefs;
+ this.selectedDetailNode.businessAttributes = data.businessAttributeDefs;
+ this.selectedDetailNode.relationshipAttributes = data.relationshipAttributeDefs;
//atttributes
data["atttributes"] = (data.attributeDefs || []).map(function(obj) {
return obj.name;
});
- delete data.attributeDefs;
//businessAttributes
data["businessAttributes"] = _.keys(data.businessAttributeDefs);
- delete data.businessAttributeDefs;
//relationshipAttributes
data["relationshipAttributes"] = (data.relationshipAttributeDefs || []).map(function(obj) {
return obj.name;
});
- delete data.relationshipAttributeDefs;
-
- console.log(data);
this.ui.nodeDetailTable.html(
CommonViewFunction.propertyTable({
scope: this,
guidHyperLink: false,
+ getValue: function(val, key) {
+ if (key && key.toLowerCase().indexOf("time") > 0) {
+ return Utils.formatDate({ date: val });
+ } else {
+ return val;
+ }
+ },
+ getArrayOfStringElement: function(val, key) {
+ var def = null,
+ classname = "json-string";
+ if (key === "atttributes" || key === "businessAttributes" || key === "relationshipAttributes") {
+ def = key;
+ classname += " cursor";
+ }
+ return "<li class='" + classname + "' " + (def ? 'data-def="' + def + '" data-attribute="' + val + '"' : '') + ">" + val + "</li>"
+ },
+ getArrayOfStringFormat: function(valueArray) {
+ return valueArray.join("");
+ },
getEmptyString: function(key) {
if (key === "subTypes" || key === "superTypes" || key === "atttributes" || key === "relationshipAttributes") {
return "[]";
}
return "N/A";
},
- valueObject: _.omit(data, ["isLineage", "isIncomplete", "label", "shape", "toolTipLabel", "updatedValues"]),
+ valueObject: _.omit(data, ["id", "attributeDefs", "relationshipAttributeDefs", "businessAttributeDefs", "isLineage", "isIncomplete", "label", "shape", "toolTipLabel", "updatedValues"]),
sortBy: true
})
);
},
- createGraph: function(refresh) {
+ createGraph: function(opt) {
this.LineageHelperRef.createGraph();
},
filterData: function(value) {
@@ -377,12 +418,14 @@ define([
setDataManually: true,
width: node.width,
height: node.height,
- isShowHoverPath: true,
zoom: true,
fitToScreen: true,
dagreOptions: {
rankdir: "tb"
},
+ toolTipTitle: "Type",
+ isShowHoverPath: function() { return that.ui.showOnlyHoverPath.prop('checked') },
+ isShowTooltip: function() { return that.ui.showTooltip.prop('checked') },
onNodeClick: function(d) {
that.onClickNodeToggler();
that.updateDetails(that.LineageHelperRef.getNode(d.clickedData, true));
@@ -425,14 +468,17 @@ define([
this.ui.typeSearch
.select2({
closeOnSelect: true,
- placeholder: "Select Node"
+ placeholder: "Select Type"
})
.on("change.select2", function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="typeSearch"]').val();
- //that.searchNodeObj.selectedNode = selectedNode;
- that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.typeSearch.data("refresh")) {
+ var selectedNode = $('[data-id="typeSearch"]').val();
+ that.LineageHelperRef.searchNode({ guid: selectedNode });
+ } else {
+ that.ui.typeSearch.data("refresh", false);
+ }
});
if (!this.ui.filterServiceType.data("select2")) {
this.ui.filterServiceType
@@ -443,15 +489,13 @@ define([
.on("change.select2", function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="filterServiceType"]').val();
- that.filterData(selectedNode);
- //that.searchNodeObj.selectedNode = selectedNode;
- //that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.filterServiceType.data("refresh")) {
+ var selectedNode = $('[data-id="filterServiceType"]').val();
+ that.filterData(selectedNode);
+ } else {
+ that.ui.filterServiceType.data("refresh", false);
+ }
});
- // if (this.searchNodeObj.selectedNode) {
- // this.ui.typeSearch.val(this.searchNodeObj.selectedNode);
- // this.ui.typeSearch.trigger("change.select2");
- // }
}
}
});
diff --git a/dashboardv3/public/css/scss/common.scss b/dashboardv3/public/css/scss/common.scss
index 008dca0..c620838 100644
--- a/dashboardv3/public/css/scss/common.scss
+++ b/dashboardv3/public/css/scss/common.scss
@@ -180,6 +180,11 @@ pre {
.json-string {
color: olive;
+
+ &.cursor {
+ cursor: pointer;
+ text-decoration: underline;
+ }
}
}
@@ -191,6 +196,11 @@ pre {
.panel-body .memory-details {
pre {
&.code-block {
+ &.fixed-height {
+ max-height: 112px;
+ overflow: auto;
+ }
+
&.shrink {
height: 144px;
diff --git a/dashboardv3/public/css/scss/graph.scss b/dashboardv3/public/css/scss/graph.scss
index abfa42c..69d451b 100644
--- a/dashboardv3/public/css/scss/graph.scss
+++ b/dashboardv3/public/css/scss/graph.scss
@@ -197,7 +197,7 @@ span#zoom_in {
width: 100%;
right: 0;
padding: 0 !important;
- z-index: 9999;
+ z-index: 99;
overflow: hidden !important;
background: white;
@@ -277,4 +277,38 @@ span#zoom_in {
box-shadow: 0px 0px 3px 1px #80808080;
}
+}
+
+
+.box-panel.fix-box {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ height: 100vh;
+ max-height: 100vh;
+ z-index: 999;
+ bottom: 0;
+ width: 400px;
+ overflow: auto;
+ border-radius: 0px;
+ margin: 0 !important;
+
+ &.slide-from-left.size-lg {
+ left: -413px;
+
+ &.show-box-panel {
+ left: 0;
+ margin: 0 !important;
+ }
+ }
+
+ .body {
+ tbody {
+ overflow: auto;
+ height: calc(100vh - 48px);
+ position: absolute;
+ padding-bottom: 15px;
+ }
+ }
}
\ No newline at end of file
diff --git a/dashboardv3/public/css/scss/table.scss b/dashboardv3/public/css/scss/table.scss
index 519d083..6b78edf 100644
--- a/dashboardv3/public/css/scss/table.scss
+++ b/dashboardv3/public/css/scss/table.scss
@@ -41,6 +41,7 @@ tr.empty {
}
.entity-detail-table,
+.type-node-details,
.relationship-detail-table {
position: relative;
@@ -66,6 +67,26 @@ tr.empty {
}
}
+.type-node-details {
+ .header {
+ .pretty.p-switch .state:before {
+ border: 1px solid white;
+ }
+
+ .pretty.p-switch .state label:after {
+ background-color: white !important;
+ }
+
+ .pretty.p-switch.p-fill input:checked~.state label:after {
+ background-color: #4a90e2 !important;
+ }
+
+ .pretty.p-switch.p-fill input:checked~.state.p-primary:before {
+ background-color: white !important;
+ }
+ }
+}
+
.backgrid {
td {
white-space: normal;
@@ -98,6 +119,14 @@ tr.empty {
}
}
}
+
+ .debuggging-table-header {
+ padding-right: 0px !important;
+
+ button {
+ float: right;
+ }
+ }
}
.backgrid-paginator ul {
diff --git a/dashboardv3/public/js/external_lib/atlas-lineage/dist/index.js b/dashboardv3/public/js/external_lib/atlas-lineage/dist/index.js
index c2f68bb..e82cb48 100644
--- a/dashboardv3/public/js/external_lib/atlas-lineage/dist/index.js
+++ b/dashboardv3/public/js/external_lib/atlas-lineage/dist/index.js
@@ -1 +1 @@
-!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("platform"),require("dagreD3")):"function"==typeof define&&define.amd?define(["platform","dagreD3"],e):"object"==typeof exports?exports.LineageHelper=e(require("platform"),require("dagreD3")):t.LineageHelper=e(t.platform,t.dagreD3)}(window,(function(t,e){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i. [...]
\ No newline at end of file
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("platform"),require("dagreD3")):"function"==typeof define&&define.amd?define(["platform","dagreD3"],e):"object"==typeof exports?exports.LineageHelper=e(require("platform"),require("dagreD3")):t.LineageHelper=e(t.platform,t.dagreD3)}(window,(function(t,e){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i. [...]
\ No newline at end of file
diff --git a/dashboardv3/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js b/dashboardv3/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
index 7c482b3..55f363e 100644
--- a/dashboardv3/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
+++ b/dashboardv3/public/js/external_lib/atlas-lineage/src/Utils/LineageUtils.js
@@ -374,7 +374,7 @@ const LineageUtils = {
reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(file);
},
- imgShapeRender: function (parent, bbox, node, { dagreD3, defsEl, imgBasePath, guid }) {
+ imgShapeRender: function (parent, bbox, node, { dagreD3, defsEl, imgBasePath, guid, isRankdirToBottom }) {
var that = this,
viewGuid = guid,
imageIconPath = this.getEntityIconPath({ entityData: node, imgBasePath }),
@@ -391,7 +391,7 @@ const LineageUtils = {
var shapeSvg = parent
.append("circle")
.attr("fill", "url(#img_" + imgName + ")")
- .attr("r", "24px")
+ .attr("r", isRankdirToBottom ? "30px" : "24px")
.attr("data-stroke", node.id)
.attr("stroke-width", "2px")
.attr("class", "nodeImage " + (currentNode ? "currentNode" : node.isProcess ? "process" : "node"));
@@ -478,8 +478,8 @@ const LineageUtils = {
});
}
})
- .attr("x", "4")
- .attr("y", currentNode ? "3" : "4")
+ .attr("x", isRankdirToBottom ? "11" : "4")
+ .attr("y", isRankdirToBottom ? "20" : currentNode ? "3" : "4")
.attr("width", "40")
.attr("height", "40");
}
diff --git a/dashboardv3/public/js/external_lib/atlas-lineage/src/index.js b/dashboardv3/public/js/external_lib/atlas-lineage/src/index.js
index 1ac517a..3ceb3d9 100644
--- a/dashboardv3/public/js/external_lib/atlas-lineage/src/index.js
+++ b/dashboardv3/public/js/external_lib/atlas-lineage/src/index.js
@@ -26,6 +26,7 @@ import "./styles/style.scss";
export default class LineageHelper {
constructor(options) {
+ this.options = {};
this._updateOptions(options);
const { el, manualTrigger = false } = this.options;
if (el === undefined) {
@@ -33,6 +34,7 @@ export default class LineageHelper {
}
this.initReturnObj = {
init: (arg) => this.init(arg),
+ updateOptions: (options) => this._updateAllOptions(options),
createGraph: (opt = {}) => this._createGraph(this.options, this.graphOptions, opt),
clear: (arg) => this.clear(arg),
refresh: (arg) => this.refresh(arg),
@@ -78,12 +80,27 @@ export default class LineageHelper {
return this.initReturnObj;
}
/**
+ * [updateAllOptions]
+ * @param {[type]}
+ * @return {[type]}
+ */
+ _updateAllOptions(options) {
+ Object.assign(this.options, options);
+ var svgRect = this.svg.node().getBoundingClientRect();
+ this.graphOptions.width = this.options.width || svgRect.width;
+ this.graphOptions.height = this.options.height || svgRect.height;
+ const { svg, width, height, guid } = this.graphOptions;
+ const { fitToScreen } = this.options;
+ svg.select("g").node().removeAttribute("transform");
+ svg.attr("viewBox", "0 0 " + width + " " + height).attr("enable-background", "new 0 0 " + width + " " + height);
+ this.centerAlign({ fitToScreen, guid });
+ }
+ /**
* [updateOptions get the options from user and appedn add it in this,option context]
* @param {[Object]} options [lib options from user]
* @return {[null]} [null]
*/
_updateOptions(options) {
- this.options = {};
Object.assign(this.options, { filterObj: { isProcessHideCheck: false, isDeletedEntityHideCheck: false } }, options);
}
/**
@@ -200,7 +217,7 @@ export default class LineageHelper {
if (node && node.attributes) {
downloadFileName = `${node.attributes.qualifiedName || node.attributes.name || "lineage_export"}.png`;
} else {
- downloadFileName = "lineage_export.png";
+ downloadFileName = "export.png";
}
}
@@ -258,6 +275,7 @@ export default class LineageHelper {
this.svg = select(el);
if (!(el instanceof SVGElement)) {
+ this.svg.selectAll("*").remove();
this.svg = this.svg
.append("svg")
.attr("xmlns", "http://www.w3.org/2000/svg")
@@ -385,7 +403,19 @@ export default class LineageHelper {
* @return {[type]} [description]
*/
_createGraph(
- { data = {}, imgBasePath, isShowTooltip, isShowHoverPath, onLabelClick, onPathClick, onNodeClick, zoom, fitToScreen },
+ {
+ data = {},
+ imgBasePath,
+ isShowTooltip,
+ isShowHoverPath,
+ onLabelClick,
+ onPathClick,
+ onNodeClick,
+ zoom,
+ fitToScreen,
+ getToolTipContent,
+ toolTipTitle
+ },
graphOptions,
{ refresh }
) {
@@ -393,7 +423,8 @@ export default class LineageHelper {
this.options.beforeRender();
}
const that = this,
- { svg, g, width, height } = graphOptions;
+ { svg, g, width, height } = graphOptions,
+ isRankdirToBottom = this.options.dagreOptions && this.options.dagreOptions.rankdir === "tb";
if (svg instanceof selection === false) {
throw new Error("svg is not initialized or something went wrong while creatig graph instance");
@@ -428,6 +459,7 @@ export default class LineageHelper {
render.shapes().img = function () {
return LineageUtils.imgShapeRender(...arguments, {
...graphOptions,
+ isRankdirToBottom: isRankdirToBottom,
imgBasePath: that._getValueFromUser(imgBasePath),
defsEl
});
@@ -437,19 +469,26 @@ export default class LineageHelper {
.attr("class", "d3-tip")
.offset([10, 0])
.html((d) => {
- var value = g.node(d);
- var htmlStr = "";
- if (value.id !== this.guid) {
- htmlStr = "<h5 style='text-align: center;'>" + (value.isLineage ? "Lineage" : "Impact") + "</h5>";
- }
- htmlStr += "<h5 class='text-center'><span style='color:#359f89'>" + value.toolTipLabel + "</span></h5> ";
- if (value.typeName) {
- htmlStr += "<h5 class='text-center'><span>(" + value.typeName + ")</span></h5> ";
- }
- if (value.queryText) {
- htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
+ if (getToolTipContent && typeof getToolTipContent === "function") {
+ return getToolTipContent(d, g.node(d));
+ } else {
+ var value = g.node(d);
+ var htmlStr = "";
+ if (toolTipTitle) {
+ htmlStr = "<h5 style='text-align: center;'>" + toolTipTitle + "</h5>";
+ } else if (value.id !== this.guid) {
+ htmlStr = "<h5 style='text-align: center;'>" + (value.isLineage ? "Lineage" : "Impact") + "</h5>";
+ }
+
+ htmlStr += "<h5 class='text-center'><span style='color:#359f89'>" + value.toolTipLabel + "</span></h5> ";
+ if (value.typeName) {
+ htmlStr += "<h5 class='text-center'><span>(" + value.typeName + ")</span></h5> ";
+ }
+ if (value.queryText) {
+ htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
+ }
+ return "<div class='tip-inner-scroll'>" + htmlStr + "</div>";
}
- return "<div class='tip-inner-scroll'>" + htmlStr + "</div>";
});
svg.call(tooltip);
@@ -463,7 +502,12 @@ export default class LineageHelper {
//change text postion
svgGroupEl
.selectAll("g.nodes g.label")
- .attr("transform", "translate(2,-35)")
+ .attr("transform", () => {
+ if (isRankdirToBottom) {
+ return "translate(2,-20)";
+ }
+ return "translate(2,-35)";
+ })
.on("mouseenter", function (d) {
event.preventDefault();
select(this).classed("highlight", true);
diff --git a/dashboardv3/public/js/templates/administrator/AdministratorLayoutView_tmpl.html b/dashboardv3/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
index f9ca214..85bf9ba 100644
--- a/dashboardv3/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
@@ -37,7 +37,7 @@
<div id="r_adminTableLayoutView">
</div>
</div>
- <div id="tab-typeSystem" role="typeSystem" class="tab-pane animated fadeIn" style="position: relative;">
+ <div id="tab-typeSystem" role="typeSystem" class="tab-pane" style="position: relative;">
<div id="r_typeSystemTreeLayoutView">
</div>
</div>
diff --git a/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index 17a8d10..18fc1f9 100644
--- a/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -94,7 +94,7 @@
</div>
</div>
</div>
- <div id="tab-lineage" role="lineage" class="tab-pane animated fadeIn">
+ <div id="tab-lineage" role="lineage" class="tab-pane">
<div id="r_lineageLayoutView" class="animated position-relative" align="center">
<div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
diff --git a/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html b/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
index 8e6e6b2..f6f61e2 100644
--- a/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -124,22 +124,22 @@
</button>
</div>
</div>
- <div class="box-panel size-lg node-details slide-from-left lineage-node-detail">
- <div class="header clearfix">
- <h4><span data-id="typeName"></span></h4>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- </div>
- <div class="body">
- <table class="table bold-key">
- <tbody data-id="nodeDetailTable"></tbody>
- </table>
- </div>
- </div>
<div class="fontLoader">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
<div class="legends pull-left" style="height: 25px; padding: 2px;"></div>
<div class="svg" style="height: 100%; width: 100%"></div>
</div>
+<div class="box-panel size-lg slide-from-left lineage-node-detail fix-box">
+ <div class="header clearfix">
+ <h4><span data-id="typeName"></span></h4>
+ <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ </div>
+ <div class="body">
+ <table class="table bold-key">
+ <tbody data-id="nodeDetailTable"></tbody>
+ </table>
+ </div>
+</div>
<div class="hidden-svg"></div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/graph/TypeSystemTreeView_tmpl.html b/dashboardv3/public/js/templates/graph/TypeSystemTreeView_tmpl.html
index 5340de4..005c061 100644
--- a/dashboardv3/public/js/templates/graph/TypeSystemTreeView_tmpl.html
+++ b/dashboardv3/public/js/templates/graph/TypeSystemTreeView_tmpl.html
@@ -15,16 +15,30 @@
* limitations under the License.
-->
<div id="typeSystemTreeViewPage" data-id="typeSystemTreeViewPage" class="systemTypeTree" style="height: calc(100vh - 180px); width: 100%; position: relative;overflow: hidden;">
- <div class="box-panel size-lg node-details slide-from-left lineage-node-detail">
+ <div class="box-panel size-lg type-node-details fix-box slide-from-left lineage-node-detail">
<div class="header clearfix">
- <h4><span data-id="typeName"></span></h4>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
- <span data-id="box-close" class="btn btn-sm btn-close lineage-node-detail-close"><i class="fa fa-close"></i></span>
+ <div class="typeDetailHeader">
+ <h4 style="padding-right: 67px;"><span data-id="typeName"></span></h4>
+ <div class="pretty p-switch p-fill" style="position: absolute;top: 13px;right: 32px;">
+ <input type="checkbox" data-id="noValueToggle" title="Show empty values" />
+ <div class="state p-primary">
+ <label></label>
+ </div>
+ </div>
+ <span data-id="box-close" class="btn btn-sm btn-close "><i class="fa fa-close"></i></span>
+ </div>
+ <div class="typeAttrDetailHeader" style="display: none;">
+ <span data-id="box-back" class="btn btn-sm btn-close" style="left: 0px; right: auto;"><i class="fa fa-angle-left"></i></span>
+ <h4 style="padding-left: 27px;"><span data-id="typeAttrDetailHeader"></span></h4>
+ </div>
</div>
<div class="body">
<table class="table bold-key">
- <tbody data-id="nodeDetailTable"></tbody>
+ <tbody data-id="nodeDetailTable" class="hide-empty-value"></tbody>
</table>
+ <div data-id="attribute-table" style="height: calc(100vh - 60px);display: none">
+ <pre class="code-block" style="height: 100%"></pre>
+ </div>
</div>
</div>
<div class="fontLoader">
@@ -49,7 +63,6 @@
<div class="body">
<div class="col-sm-12 no-padding">
<div class="srchType clearfix">
- <label class="srchTitle">Search Lineage Entity: </label>
<div class="">
<div class="col-sm-12 no-padding temFilter">
<select data-id="typeSearch"></select>
@@ -59,28 +72,62 @@
</div>
</div>
</div>
+ <div class="box-panel setting-box">
+ <div class="header clearfix">
+ <h4>Settings</h4>
+ <span data-id="box-close" class="btn btn-sm btn-close"><i class="fa fa-close"></i></span>
+ </div>
+ <div class="body">
+ <div class="showOnlyHoverPath form-group text-left col-sm-12">
+ <div class="pretty p-switch p-fill">
+ <input type="checkbox" checked class="pull-left" data-id="showOnlyHoverPath" value="" />
+ <div class="state p-primary">
+ <label>On hover show current path</label>
+ </div>
+ </div>
+ </div>
+ <div class="showTooltip form-group text-left col-sm-12">
+ <div class="pretty p-switch p-fill">
+ <input type="checkbox" class="pull-left" data-id="showTooltip" value="" />
+ <div class="state p-primary">
+ <label>Show node details on hover</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
<div class="graph-button-group pull-right">
<div>
- <button data-id="reset" class="btn btn-action btn-gray btn-sm" title="Realign Lineage">
+ <button data-id="reset" class="btn btn-action btn-gray btn-sm" title="Reset">
<i class="fa fa-retweet"></i>
</button>
</div>
<div>
+ <button data-id="saveSvg" class="btn btn-action btn-gray btn-sm" title="Export to PNG">
+ <i class="fa fa-camera"></i>
+ </button>
+ </div>
+ <div>
+ <button type="button" data-id="setting-toggler" title="Settings" class="btn btn-action btn-gray btn-sm">
+ <i class="fa fa-gear"></i>
+ </button>
+ </div>
+ <div>
<button type="button" data-id="filter-toggler" title="Filter" class="btn btn-action btn-gray btn-sm"><i class="fa fa-filter"></i></button>
</div>
<div>
<button type="button" data-id="search-toggler" title="Search" class="btn btn-action btn-gray btn-sm"><i class="fa fa-search"></i></button>
</div>
<div class="btn-group">
- <button type="button" class="btn btn-action btn-gray btn-sm lineageZoomButton" title="Zoom In" data-id="zoom-in">
+ <button type="button" class="btn btn-action btn-gray btn-sm" title="Zoom In" data-id="zoom-in">
<i class="fa fa-search-plus"></i>
</button>
- <button type="button" class="btn btn-action btn-gray btn-sm lineageZoomButton" title="Zoom Out" data-id="zoom-out">
+ <button type="button" class="btn btn-action btn-gray btn-sm" title="Zoom Out" data-id="zoom-out">
<i class="fa fa-search-minus"></i>
</button>
</div>
<div>
- <button type="button" data-id="fullScreen-toggler" title="Full screen" class="btn btn-action btn-gray btn-sm fullscreen_lineage">
+ <button type="button" data-id="fullScreen-toggler" title="Full screen" class="btn btn-action btn-gray btn-sm">
<i class="fa fa-expand"></i>
</button>
</div>
diff --git a/dashboardv3/public/js/utils/CommonViewFunction.js b/dashboardv3/public/js/utils/CommonViewFunction.js
index 40d489e..2573a60 100644
--- a/dashboardv3/public/js/utils/CommonViewFunction.js
+++ b/dashboardv3/public/js/utils/CommonViewFunction.js
@@ -79,6 +79,8 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
sortBy = options.sortBy,
valueObject = options.valueObject,
extractJSON = options.extractJSON,
+ getArrayOfStringElement = options.getArrayOfStringElement,
+ getArrayOfStringFormat = options.getArrayOfStringFormat,
isTable = _.isUndefined(options.isTable) ? true : options.isTable,
attributeDefs = options.attributeDefs,
formatIntVal = options.formatIntVal,
@@ -108,6 +110,9 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
return "N/A";
},
getValue = function(val, key) {
+ if (options && options.getValue) {
+ val = options.getValue(val, key);
+ }
if (!_.isUndefined(val) && !_.isNull(val)) {
if ((_.isNumber(val) || !_.isNaN(parseInt(val))) && formatIntVal) {
return numberFormat(val);
@@ -185,7 +190,12 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (_.isString(inputOutputField) || _.isBoolean(inputOutputField) || _.isNumber(inputOutputField)) {
var tempVarfor$check = inputOutputField.toString();
if (tempVarfor$check.indexOf("$") == -1) {
- valueOfArray.push('<span class="json-string">' + getValue(inputOutputField, key) + '</span>');
+ var tmpVal = getValue(inputOutputField, key)
+ if (getArrayOfStringElement) {
+ valueOfArray.push(getArrayOfStringElement(tmpVal, key));
+ } else {
+ valueOfArray.push('<span class="json-string">' + tmpVal + '</span>');
+ }
}
} else if (_.isObject(inputOutputField) && !id) {
var attributesList = inputOutputField;
@@ -251,7 +261,11 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
}
if (valueOfArray.length) {
- subLink = valueOfArray.join(', ');
+ if (getArrayOfStringFormat) {
+ subLink = getArrayOfStringFormat(valueOfArray, key);
+ } else {
+ subLink = valueOfArray.join(', ');
+ }
}
return subLink === "" ? getEmptyString(key) : subLink;
}
@@ -297,12 +311,17 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (_.isObject(valueObject[key]) && !_.isEmpty(valueObject[key])) {
var matchedLinkString = val.match(/href|value-loader\w*/g),
matchedJson = val.match(/json-value|json-string\w*/g),
+ matchedKey = val.match(/json-key\w*/g),
isMatchLinkStringIsSingle = matchedLinkString && matchedLinkString.length <= 5,
isMatchJSONStringIsSingle = matchedJson && matchedJson.length == 1,
expandCollapseButton = "";
- if ((matchedJson && !isMatchJSONStringIsSingle) || (matchedLinkString && !isMatchLinkStringIsSingle)) {
- expandCollapseButton = '<button class="expand-collapse-button"><i class="fa"></i></button>';
- htmlTag = '<pre class="shrink code-block ' + (isMatchJSONStringIsSingle ? 'fixed-height' : '') + '">' + expandCollapseButton + '<code>' + val + '</code></pre>';
+ if ((matchedJson) || (matchedLinkString)) {
+ var className = "code-block fixed-height";
+ if (!isMatchJSONStringIsSingle) {
+ className += " shrink";
+ expandCollapseButton = '<button class="expand-collapse-button"><i class="fa"></i></button>';
+ }
+ htmlTag = '<pre class="' + className + '">' + expandCollapseButton + '<code>' + val + '</code></pre>';
}
}
table += '<tr class="' + appendClass + '"><td>' + (_.escape(key) + listCount) + '</td><td>' + htmlTag + '</td></tr>';
diff --git a/dashboardv3/public/js/views/graph/LineageLayoutView.js b/dashboardv3/public/js/views/graph/LineageLayoutView.js
index 5d0b70b..aa26580 100644
--- a/dashboardv3/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv3/public/js/views/graph/LineageLayoutView.js
@@ -134,13 +134,13 @@ define(['require',
},
onShow: function() {
this.$('.fontLoader').show();
- this.$el.resizable({
- handles: ' s',
- minHeight: 375,
- stop: function(event, ui) {
- ui.element.height(($(this).height()));
- },
- });
+ // this.$el.resizable({
+ // handles: ' s',
+ // minHeight: 375,
+ // stop: function(event, ui) {
+ // ui.element.height(($(this).height()));
+ // },
+ // });
},
onClickLineageFullscreenToggler: function(e) {
var icon = $(e.currentTarget).find('i'),
@@ -152,6 +152,11 @@ define(['require',
icon.parent('button').attr("data-original-title", "Default View");
}
panel.toggleClass('fullscreen-mode');
+ var node = this.$("svg").parent()[0].getBoundingClientRect();
+ this.LineageHelperRef.updateOptions({
+ width: node.width,
+ height: node.height
+ });
},
onCheckUnwantedEntity: function(e) {
var that = this;
@@ -210,6 +215,8 @@ define(['require',
},
onClickResetLineage: function() {
this.LineageHelperRef.refresh();
+ this.searchNodeObj.selectedNode = "";
+ this.ui.lineageTypeSearch.data({ refresh: true }).val("").trigger("change");
},
onClickSaveSvg: function(e, a) {
this.LineageHelperRef.exportLineage();
@@ -249,10 +256,6 @@ define(['require',
})
},
createGraph: function(data) {
- // 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;
$('.resizeGraph').css("height", this.$('.svg').height() + "px");
@@ -364,9 +367,13 @@ define(['require',
}).on('change.select2', function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="typeSearch"]').val();
- that.searchNodeObj.selectedNode = selectedNode;
- that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.lineageTypeSearch.data("refresh")) {
+ var selectedNode = $('[data-id="typeSearch"]').val();
+ that.searchNodeObj.selectedNode = selectedNode;
+ that.LineageHelperRef.searchNode({ guid: selectedNode });
+ } else {
+ that.ui.lineageTypeSearch.data("refresh", false);
+ }
});
if (this.searchNodeObj.selectedNode) {
this.ui.lineageTypeSearch.val(this.searchNodeObj.selectedNode);
diff --git a/dashboardv3/public/js/views/graph/TypeSystemTreeView.js b/dashboardv3/public/js/views/graph/TypeSystemTreeView.js
index 3095bca..90734a4 100644
--- a/dashboardv3/public/js/views/graph/TypeSystemTreeView.js
+++ b/dashboardv3/public/js/views/graph/TypeSystemTreeView.js
@@ -55,16 +55,23 @@ define([
typeSystemTreeViewPage: "[data-id='typeSystemTreeViewPage']",
boxClose: '[data-id="box-close"]',
nodeDetailTable: '[data-id="nodeDetailTable"]',
+ attributeTable: '[data-id="attribute-table"]',
typeSearch: '[data-id="typeSearch"]',
filterServiceType: '[data-id="filterServiceType"]',
onZoomIn: '[data-id="zoom-in"]',
onZoomOut: '[data-id="zoom-out"]',
filterBox: ".filter-box",
searchBox: ".search-box",
+ settingBox: '.setting-box',
filterToggler: '[data-id="filter-toggler"]',
+ settingToggler: '[data-id="setting-toggler"]',
searchToggler: '[data-id="search-toggler"]',
reset: '[data-id="reset"]',
- fullscreenToggler: '[data-id="fullScreen-toggler"]'
+ fullscreenToggler: '[data-id="fullScreen-toggler"]',
+ noValueToggle: "[data-id='noValueToggle']",
+ showOnlyHoverPath: '[data-id="showOnlyHoverPath"]',
+ showTooltip: '[data-id="showTooltip"]',
+ saveSvg: '[data-id="saveSvg"]',
},
/** ui events hash */
events: function() {
@@ -73,9 +80,19 @@ define([
events["click " + this.ui.onZoomIn] = "onClickZoomIn";
events["click " + this.ui.onZoomOut] = "onClickZoomOut";
events["click " + this.ui.filterToggler] = "onClickFilterToggler";
+ events["click " + this.ui.settingToggler] = 'onClickSettingToggler';
events["click " + this.ui.searchToggler] = "onClickSearchToggler";
+ events["click " + this.ui.saveSvg] = 'onClickSaveSvg';
events["click " + this.ui.fullscreenToggler] = "onClickFullscreenToggler";
events["click " + this.ui.reset] = "onClickReset";
+ events["click " + this.ui.noValueToggle] = function() {
+ this.showAllProperties = !this.showAllProperties;
+ this.ui.noValueToggle.attr("data-original-title", (this.showAllProperties ? "Hide" : "Show") + " empty values");
+ Utils.togglePropertyRelationshipTableEmptyValues({
+ "inputType": this.ui.noValueToggle,
+ "tableEl": this.ui.nodeDetailTable
+ });
+ };
return events;
},
@@ -90,7 +107,35 @@ define([
this.initializeGraph();
this.fetchGraphData();
},
- onRender: function() {},
+ onRender: function() {
+ var that = this;
+ this.$el.on("click", "code li[data-def]", function() {
+ if (that.selectedDetailNode) {
+ var dataObj = $(this).data(),
+ defObj = that.selectedDetailNode[dataObj.def],
+ newData = null;
+ if (dataObj.def === "businessAttributes") {
+ newData = defObj[dataObj.attribute];
+ } else {
+ newData = _.filter(defObj, { name: dataObj.attribute });
+ }
+ that.ui.attributeTable.find("pre").html('<code style="max-height: 100%">' + Utils.JSONPrettyPrint(newData, function(val) {
+ return val;
+ }) + '</code>');
+ that.$el.find('[data-id="typeAttrDetailHeader"]').text(dataObj.def);
+ that.ui.nodeDetailTable.hide("slide", { direction: "right" }, 400);
+ that.ui.attributeTable.show("slide", { direction: "left" }, 400);
+ that.$el.find(".typeDetailHeader").hide();
+ that.$el.find(".typeAttrDetailHeader").show()
+ }
+ });
+ this.$el.on("click", "span[data-id='box-back']", function() {
+ that.ui.nodeDetailTable.show("slide", { direction: "right" }, 400);
+ that.ui.attributeTable.hide("slide", { direction: "left" }, 400);
+ that.$el.find(".typeDetailHeader").show();
+ that.$el.find(".typeAttrDetailHeader").hide()
+ })
+ },
fetchGraphData: function(options) {
var that = this;
var entityTypeDef = that.entityDefCollection.fullCollection.toJSON();
@@ -101,7 +146,7 @@ define([
}
if (entityTypeDef.length) {
that.generateData($.extend(true, {}, { data: entityTypeDef }, options)).then(function(graphObj) {
- that.createGraph();
+ that.createGraph(options);
});
}
},
@@ -161,91 +206,56 @@ define([
if (options.data) {
if (options.filter) {
- var pendingSubList = {},
- pendingSuperList = {},
- temp = {},
- doneList = {},
- traveseSubSuper = function(obj, ignoreSubTypes) {
- var fromEntityId = obj.guid;
- if (!ignoreSubTypes && obj.subTypes.length) {
- _.each(obj.subTypes, function(subType) {
- var tempObj = doneList[subType] || temp[subType];
- if (tempObj) {
+ // filter
+ var pendingSuperList = {},
+ outOfFilterData = {},
+ doneList = {};
+
+ var linkParents = function(obj) {
+ if (obj && obj.superTypes.length) {
+ _.each(obj.superTypes, function(superType) {
+ var fromEntityId = obj.guid;
+ var tempObj = doneList[superType] || outOfFilterData[superType];
+ if (tempObj) {
+ if (!doneList[superType]) {
setNode(tempObj.guid, tempObj);
- setEdge(fromEntityId, tempObj.guid);
- } else {
- if (pendingSubList[subType]) {
- pendingSubList[subType].push(fromEntityId);
- } else {
- pendingSubList[subType] = [fromEntityId];
- }
}
- });
- }
- if (obj.superTypes.length) {
- _.each(obj.superTypes, function(superType) {
- var tempObj = doneList[superType] || temp[superType];
- if (tempObj) {
- setNode(tempObj.guid, tempObj);
- setEdge(tempObj.guid, fromEntityId);
- if (tempObj.superTypes.length) {
- traveseSubSuper(tempObj, true);
- }
+ setEdge(tempObj.guid, fromEntityId);
+ linkParents(tempObj);
+ } else {
+ if (pendingSuperList[superType]) {
+ pendingSuperList[superType].push(fromEntityId);
} else {
- if (pendingSuperList[superType]) {
- pendingSuperList[superType].push(fromEntityId);
- } else {
- pendingSuperList[superType] = [fromEntityId];
- }
+ pendingSuperList[superType] = [fromEntityId];
}
- });
- }
- };
+ }
+ });
+ }
+ }
_.each(options.data, function(obj) {
var fromEntityId = obj.guid;
+ if (pendingSuperList[obj.name]) {
+ doneList[obj.name] = obj;
+ setNode(fromEntityId, obj);
+ _.map(pendingSuperList[obj.name], function(guid) {
+ setEdge(fromEntityId, guid);
+ });
+ delete pendingSuperList[obj.name];
+ linkParents(obj);
+ }
if (obj.serviceType === options.filter) {
doneList[obj.name] = obj;
setNode(fromEntityId, obj);
- if (pendingSubList[obj.name]) {
- _.map(pendingSubList[obj.name], function(guid) {
- setEdge(guid, fromEntityId);
- });
- delete pendingSubList[obj.name];
- }
- if (pendingSuperList[obj.name]) {
- _.map(pendingSuperList[obj.name], function(guid) {
- setEdge(fromEntityId, guid);
- });
- delete pendingSuperList[obj.name];
- }
- traveseSubSuper(obj);
- } else {
- if (pendingSubList[obj.name]) {
- setNode(fromEntityId, obj);
- doneList[obj.name] = obj;
- _.map(pendingSubList[obj.name], function(guid) {
- setEdge(guid, fromEntityId);
- });
- delete pendingSubList[obj.name];
- }
- if (pendingSuperList[obj.name]) {
- var fromEntityId = obj.guid;
- setNode(fromEntityId, obj);
- doneList[obj.name] = obj;
- _.map(pendingSuperList[obj.name], function(guid) {
- setEdge(fromEntityId, guid);
- });
- delete pendingSuperList[obj.name];
- }
- if (!doneList[obj.name]) {
- temp[obj.name] = obj;
- }
+ linkParents(obj);
+ } else if (!doneList[obj.name] && !outOfFilterData[obj.name]) {
+ outOfFilterData[obj.name] = obj;
}
});
- pendingSubList = null;
pendingSuperList = null;
doneList = null;
+ outOfFilterData = null;
} else {
+ // Without filter
var pendingList = {},
doneList = {};
@@ -308,11 +318,19 @@ define([
onClickFilterToggler: function() {
this.toggleBoxPanel({ el: this.ui.filterBox });
},
+ onClickSettingToggler: function() {
+ this.toggleBoxPanel({ el: this.ui.settingBox });
+ },
onClickSearchToggler: function() {
this.toggleBoxPanel({ el: this.ui.searchBox });
},
onClickReset: function() {
this.fetchGraphData({ refresh: true });
+ this.ui.typeSearch.data({ refresh: true }).val("").trigger("change");
+ this.ui.filterServiceType.data({ refresh: true }).val("").trigger("change");
+ },
+ onClickSaveSvg: function(e, a) {
+ this.LineageHelperRef.exportLineage({ downloadFileName: "TypeSystemView" });
},
onClickFullscreenToggler: function(e) {
var icon = $(e.currentTarget).find("i"),
@@ -324,42 +342,65 @@ define([
icon.parent("button").attr("data-original-title", "Default View");
}
panel.toggleClass("fullscreen-mode");
+ var node = this.$("svg.main").parent()[0].getBoundingClientRect();
+ this.LineageHelperRef.updateOptions({
+ width: node.width,
+ height: node.height
+ });
},
updateDetails: function(data) {
this.$("[data-id='typeName']").text(Utils.getName(data));
- delete data.id;
+
+ this.selectedDetailNode = {};
+ this.selectedDetailNode.atttributes = data.attributeDefs;
+ this.selectedDetailNode.businessAttributes = data.businessAttributeDefs;
+ this.selectedDetailNode.relationshipAttributes = data.relationshipAttributeDefs;
//atttributes
data["atttributes"] = (data.attributeDefs || []).map(function(obj) {
return obj.name;
});
- delete data.attributeDefs;
//businessAttributes
data["businessAttributes"] = _.keys(data.businessAttributeDefs);
- delete data.businessAttributeDefs;
//relationshipAttributes
data["relationshipAttributes"] = (data.relationshipAttributeDefs || []).map(function(obj) {
return obj.name;
});
- delete data.relationshipAttributeDefs;
-
- console.log(data);
this.ui.nodeDetailTable.html(
CommonViewFunction.propertyTable({
scope: this,
guidHyperLink: false,
+ getValue: function(val, key) {
+ if (key && key.toLowerCase().indexOf("time") > 0) {
+ return Utils.formatDate({ date: val });
+ } else {
+ return val;
+ }
+ },
+ getArrayOfStringElement: function(val, key) {
+ var def = null,
+ classname = "json-string";
+ if (key === "atttributes" || key === "businessAttributes" || key === "relationshipAttributes") {
+ def = key;
+ classname += " cursor";
+ }
+ return "<li class='" + classname + "' " + (def ? 'data-def="' + def + '" data-attribute="' + val + '"' : '') + ">" + val + "</li>"
+ },
+ getArrayOfStringFormat: function(valueArray) {
+ return valueArray.join("");
+ },
getEmptyString: function(key) {
if (key === "subTypes" || key === "superTypes" || key === "atttributes" || key === "relationshipAttributes") {
return "[]";
}
return "N/A";
},
- valueObject: _.omit(data, ["isLineage", "isIncomplete", "label", "shape", "toolTipLabel", "updatedValues"]),
+ valueObject: _.omit(data, ["id", "attributeDefs", "relationshipAttributeDefs", "businessAttributeDefs", "isLineage", "isIncomplete", "label", "shape", "toolTipLabel", "updatedValues"]),
sortBy: true
})
);
},
- createGraph: function(refresh) {
+ createGraph: function(opt) {
this.LineageHelperRef.createGraph();
},
filterData: function(value) {
@@ -377,12 +418,14 @@ define([
setDataManually: true,
width: node.width,
height: node.height,
- isShowHoverPath: true,
zoom: true,
fitToScreen: true,
dagreOptions: {
rankdir: "tb"
},
+ toolTipTitle: "Type",
+ isShowHoverPath: function() { return that.ui.showOnlyHoverPath.prop('checked') },
+ isShowTooltip: function() { return that.ui.showTooltip.prop('checked') },
onNodeClick: function(d) {
that.onClickNodeToggler();
that.updateDetails(that.LineageHelperRef.getNode(d.clickedData, true));
@@ -425,14 +468,17 @@ define([
this.ui.typeSearch
.select2({
closeOnSelect: true,
- placeholder: "Select Node"
+ placeholder: "Select Type"
})
.on("change.select2", function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="typeSearch"]').val();
- //that.searchNodeObj.selectedNode = selectedNode;
- that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.typeSearch.data("refresh")) {
+ var selectedNode = $('[data-id="typeSearch"]').val();
+ that.LineageHelperRef.searchNode({ guid: selectedNode });
+ } else {
+ that.ui.typeSearch.data("refresh", false);
+ }
});
if (!this.ui.filterServiceType.data("select2")) {
this.ui.filterServiceType
@@ -443,15 +489,13 @@ define([
.on("change.select2", function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
- var selectedNode = $('[data-id="filterServiceType"]').val();
- that.filterData(selectedNode);
- //that.searchNodeObj.selectedNode = selectedNode;
- //that.LineageHelperRef.searchNode({ guid: selectedNode });
+ if (!that.ui.filterServiceType.data("refresh")) {
+ var selectedNode = $('[data-id="filterServiceType"]').val();
+ that.filterData(selectedNode);
+ } else {
+ that.ui.filterServiceType.data("refresh", false);
+ }
});
- // if (this.searchNodeObj.selectedNode) {
- // this.ui.typeSearch.val(this.searchNodeObj.selectedNode);
- // this.ui.typeSearch.trigger("change.select2");
- // }
}
}
});