You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2019/02/27 20:55:28 UTC
[atlas] branch branch-1.0 updated: ATLAS-3059: UI : Lineage data
structure change to support hide deleted and hide process entities to
gather
This is an automated email from the ASF dual-hosted git repository.
sarath pushed a commit to branch branch-1.0
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/branch-1.0 by this push:
new b21d218 ATLAS-3059: UI : Lineage data structure change to support hide deleted and hide process entities to gather
b21d218 is described below
commit b21d2185cde6ce26ec01d1246c1d3fc5c7cefbd6
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Wed Feb 27 12:54:42 2019 -0800
ATLAS-3059: UI : Lineage data structure change to support hide deleted and hide process entities to gather
Signed-off-by: Sarath Subramanian <ss...@hortonworks.com>
(cherry picked from commit 1cb155a2548f7f415132d229043f9f6bdce755c2)
---
dashboardv2/public/css/scss/graph.scss | 24 +-
dashboardv2/public/css/scss/relationship.scss | 4 +-
.../js/templates/graph/LineageLayoutView_tmpl.html | 39 +-
.../public/js/views/graph/LineageLayoutView.js | 517 +++++++++++++--------
4 files changed, 385 insertions(+), 199 deletions(-)
diff --git a/dashboardv2/public/css/scss/graph.scss b/dashboardv2/public/css/scss/graph.scss
index 4a9fd57..3c4be1e 100644
--- a/dashboardv2/public/css/scss/graph.scss
+++ b/dashboardv2/public/css/scss/graph.scss
@@ -34,6 +34,8 @@
font-family: $font_1;
}
+ transition: opacity 0.3s linear;
+
rect {
stroke: $color_mountain_mist_approx;
fill: $white;
@@ -279,8 +281,7 @@ g.type-TK>rect {
.zoom-button-group {}
}
-.lineage-fltr-panel,
-.lineage-search-panel {
+.box-panel {
position: absolute;
top: 45px;
border: 1px solid #ccc;
@@ -417,7 +418,8 @@ g.type-TK>rect {
}
.show-filter-panel,
-.show-search-panel {
+.show-search-panel,
+.show-box-panel {
right: 0px !important;
}
@@ -501,4 +503,20 @@ span#zoom_in {
.wobble {
animation: zoominoutsinglefeatured 1s 5;
+}
+
+.hover {
+
+ g.node {
+ opacity: 0.1 !important;
+ }
+
+ g.edgePath {
+ opacity: 0 !important;
+ }
+
+ g.node.hover-active,
+ g.edgePath.hover-active-node {
+ opacity: 1 !important;
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/relationship.scss b/dashboardv2/public/css/scss/relationship.scss
index e41fe58..c1112c5 100644
--- a/dashboardv2/public/css/scss/relationship.scss
+++ b/dashboardv2/public/css/scss/relationship.scss
@@ -16,11 +16,13 @@
* limitations under the License.
*/
-.relationship-box {
+.relationship-box,
+.lineage-box {
position: absolute;
height: 100%;
width: 100%;
overflow: hidden;
+
.relatioship-link {
fill: none;
stroke-width: 1.5px;
diff --git a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
index 3adc8ad..c27ff8c 100644
--- a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -16,10 +16,10 @@
-->
<!-- <div class="graph-toolbar clearfix"></div> -->
<div class="white-bg no-padding lineage-box">
- <div class="lineage-fltr-panel">
+ <div class="box-panel filter-box">
<div class="header clearfix">
<h4>Filters</h4>
- <span data-id="fltr-togler" style="margin: 7px" class="btn btn-action btn-sm fltr-togler"><i class="fa fa-close"></i></span>
+ <span data-id="box-close" style="margin: 7px" class="btn btn-action btn-sm fltr-togler"><i class="fa fa-close"></i></span>
</div>
<div class="body">
<div class="hideProcessContainer form-group text-left col-sm-12">
@@ -46,10 +46,10 @@
</div>
</div>
</div>
- <div class="lineage-search-panel">
+ <div class="box-panel search-box">
<div class="header clearfix">
<h4>Search</h4>
- <span data-id="search-togler" style="margin: 7px" class="btn btn-action btn-sm fltr-togler"><i class="fa fa-close"></i></span>
+ <span data-id="box-close" style="margin: 7px" class="btn btn-action btn-sm fltr-togler"><i class="fa fa-close"></i></span>
</div>
<div class="body">
<div class="col-sm-12 no-padding">
@@ -64,12 +64,39 @@
</div>
</div>
</div>
+ <div class="box-panel setting-box">
+ <div class="header clearfix">
+ <h4>Settings</h4>
+ <span data-id="box-close" style="margin: 7px" class="btn btn-action btn-sm fltr-togler"><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 type="button" data-id="fltr-togler" class="btn btn-action btn-gray btn-sm"><i class="fa fa-filter"></i></button>
+ <button type="button" data-id="setting-toggler" class="btn btn-action btn-gray btn-sm"><i class="fa fa-gear"></i></button>
+ </div>
+ <div>
+ <button type="button" data-id="filter-toggler" class="btn btn-action btn-gray btn-sm"><i class="fa fa-filter"></i></button>
</div>
<div>
- <button type="button" data-id="search-togler" class="btn btn-action btn-gray btn-sm"><i class="fa fa-search"></i></button>
+ <button type="button" data-id="search-toggler" class="btn btn-action btn-gray btn-sm"><i class="fa fa-search"></i></button>
</div>
<div>
<button type="button" data-id="fullScreen-toggler" class="btn btn-action btn-gray btn-sm fullscreen_lineage"><i class="fa fa-expand"></i></button>
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 5a7262b..e98a6fa 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -49,15 +49,20 @@ define(['require',
checkHideProcess: "[data-id='checkHideProcess']",
checkDeletedEntity: "[data-id='checkDeletedEntity']",
selectDepth: 'select[data-id="selectDepth"]',
- fltrTogler: '[data-id="fltr-togler"]',
- lineageFilterPanel: '.lineage-fltr-panel',
+ filterToggler: '[data-id="filter-toggler"]',
+ settingToggler: '[data-id="setting-toggler"]',
+ searchToggler: '[data-id="search-toggler"]',
+ boxClose: '[data-id="box-close"]',
lineageFullscreenToggler: '[data-id="fullScreen-toggler"]',
- searchTogler: '[data-id="search-togler"]',
- lineageSearchPanel: '.lineage-search-panel',
+ filterBox: '.filter-box',
+ searchBox: '.search-box',
+ settingBox: '.setting-box',
lineageTypeSearch: '[data-id="typeSearch"]',
lineageDetailClose: '[data-id="close"]',
searchNode: '[data-id="searchNode"]',
- nodeEntityList: '[data-id="entityList"]'
+ nodeEntityList: '[data-id="entityList"]',
+ showOnlyHoverPath: '[data-id="showOnlyHoverPath"]',
+ showTooltip: '[data-id="showTooltip"]'
},
templateHelpers: function() {
return {
@@ -71,9 +76,11 @@ define(['require',
events["click " + this.ui.checkHideProcess] = 'onCheckUnwantedEntity';
events["click " + this.ui.checkDeletedEntity] = 'onCheckUnwantedEntity';
events['change ' + this.ui.selectDepth] = 'onSelectDepthChange';
- events["click " + this.ui.fltrTogler] = 'onClickFiltrTogler';
+ events["click " + this.ui.filterToggler] = 'onClickFilterToggler';
+ events["click " + this.ui.boxClose] = 'toggleBoxPanel';
+ events["click " + this.ui.settingToggler] = 'onClickSettingToggler';
events["click " + this.ui.lineageFullscreenToggler] = 'onClickLineageFullscreenToggler';
- events["click " + this.ui.searchTogler] = 'onClickSearchTogler';
+ events["click " + this.ui.searchToggler] = 'onClickSearchToggler';
events["click " + this.ui.lineageDetailClose] = function() {
this.toggleLineageInfomationSlider({ close: true });
};
@@ -119,7 +126,6 @@ define(['require',
return {};
});
},
-
onRender: function() {
var that = this;
this.fetchGraphData();
@@ -158,32 +164,30 @@ define(['require',
},
onCheckUnwantedEntity: function(e) {
var data = $.extend(true, {}, this.lineageData);
- this.fromToObj = {};
+ //this.fromToNodeData = {};
this.initializeGraph();
if ($(e.target).data("id") === "checkHideProcess") {
this.filterObj.isProcessHideCheck = e.target.checked;
} else {
this.filterObj.isDeletedEntityHideCheck = e.target.checked;
}
- this.generateData(data.relations, data.guidEntityMap);
- },
- onClickFiltrTogler: function() {
- var lineageFilterPanel = this.ui.lineageFilterPanel;
- var lineageSearchPanel = this.ui.lineageSearchPanel;
- $(lineageFilterPanel).toggleClass("show-filter-panel");
- if (lineageSearchPanel.hasClass('show-search-panel')) {
- $(this.ui.lineageSearchPanel).toggleClass("show-search-panel")
- }
+ this.generateData({ "relationshipMap": this.relationshipMap, "guidEntityMap": this.guidEntityMap });
},
- onClickSearchTogler: function() {
- var lineageSearchPanel = this.ui.lineageSearchPanel;
- var lineageFilterPanel = this.ui.lineageFilterPanel;
- $(lineageSearchPanel).toggleClass("show-search-panel");
- if (lineageFilterPanel.hasClass('show-filter-panel')) {
- $(this.ui.lineageFilterPanel).toggleClass("show-filter-panel");
-
+ toggleBoxPanel: function(el) {
+ this.$el.find('.show-box-panel').removeClass('show-box-panel');
+ if (el && el.addClass) {
+ el.addClass('show-box-panel');
}
},
+ onClickFilterToggler: function() {
+ this.toggleBoxPanel(this.ui.filterBox);
+ },
+ onClickSettingToggler: function() {
+ this.toggleBoxPanel(this.ui.settingBox);
+ },
+ onClickSearchToggler: function() {
+ this.toggleBoxPanel(this.ui.searchBox);
+ },
onSelectDepthChange: function(e, options) {
this.initializeGraph();
this.filterObj.depthCount = e.currentTarget.value;
@@ -193,7 +197,7 @@ define(['require',
fetchGraphData: function(options) {
var that = this,
queryParam = options && options.queryParam || {};
- this.fromToObj = {};
+ this.fromToNodeData = {};
this.$('.fontLoader').show();
this.$('svg>g').hide();
this.collection.getLineage(this.guid, {
@@ -201,8 +205,13 @@ define(['require',
queryParam: queryParam,
success: function(data) {
if (data.relations.length) {
- that.lineageData = $.extend(true, {}, data)
- that.generateData(data.relations, data.guidEntityMap);
+ that.lineageData = $.extend(true, {}, data);
+ that.relationshipMap = that.crateLineageRelationshipHashMap(data);
+ that.guidEntityMap = $.extend(true, {}, data.guidEntityMap);
+ if (that.lineageData) {
+ that.renderLineageTypeSearch();
+ }
+ that.generateData({ "relationshipMap": that.relationshipMap, "guidEntityMap": that.guidEntityMap });
} else {
that.noLineage();
that.hideCheckForProcess();
@@ -221,7 +230,6 @@ define(['require',
noLineage: function() {
this.$('.fontLoader').hide();
this.$('.depth-container').hide();
- //this.$('svg').height('100');
this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No lineage data found</text>');
if (this.actionCallBack) {
this.actionCallBack();
@@ -230,168 +238,227 @@ define(['require',
hideCheckForProcess: function() {
this.$('.hideProcessContainer').hide();
},
- generateData: function(relations, guidEntityMap) {
- var that = this;
-
- function isProcess(node) {
- if (_.isUndefined(node) || node.typeName == "Process") {
- return true;
- }
- var entityDef = that.entityDefCollection.fullCollection.find({ name: node.typeName });
- return _.contains(Utils.getNestedSuperTypes({ data: entityDef.toJSON(), collection: that.entityDefCollection }), "Process")
+ isProcess: function(node) {
+ var typeName = node.typeName,
+ superTypes = node.superTypes,
+ entityDef = node.entityDef;
+ if (typeName == "Process") {
+ return true;
}
-
- function isDeleted(node) {
- if (_.isUndefined(node)) {
- return
- }
- return Enums.entityStateReadOnly[node.status];
+ return _.contains(superTypes, "Process");
+ },
+ isDeleted: function(node) {
+ if (_.isUndefined(node)) {
+ return
}
+ return Enums.entityStateReadOnly[node.status];
+ },
+ isNodeToBeUpdated: function(node) {
+ var isProcessHideCheck = this.filterObj.isProcessHideCheck,
+ isDeletedEntityHideCheck = this.filterObj.isDeletedEntityHideCheck
+ var returnObj = {
+ isProcess: (isProcessHideCheck && node.isProcess),
+ isDeleted: (isDeletedEntityHideCheck && node.isDeleted)
- function isNodeToBeUpdated(node) {
- var isProcessHideCheck = that.filterObj.isProcessHideCheck,
- isDeletedEntityHideCheck = that.filterObj.isDeletedEntityHideCheck
- var returnObj = {
- isProcess: (isProcessHideCheck && isProcess(node)),
- isDeleted: (isDeletedEntityHideCheck && isDeleted(node))
-
- };
- returnObj["update"] = returnObj.isProcess || returnObj.isDeleted;
- return returnObj;
+ };
+ returnObj["update"] = returnObj.isProcess || returnObj.isDeleted;
+ return returnObj;
+ },
+ getNestedSuperTypes: function(options) {
+ var entityDef = options.entityDef;
+ return Utils.getNestedSuperTypes({ data: entityDef.toJSON(), collection: this.entityDefCollection })
+ },
+ getEntityDef: function(typeName) {
+ var entityDef = null;
+ if (typeName) {
+ entityDef = this.entityDefCollection.fullCollection.find({ name: typeName });
}
-
- function getServiceType(typeName) {
- var serviceType = null;
- if (typeName) {
- var entityDef = that.entityDefCollection.fullCollection.find({ name: typeName });
- if (entityDef) {
- serviceType = entityDef.get("serviceType") || null;
- }
+ return entityDef;
+ },
+ getServiceType: function(options) {
+ if (!options) {
+ return;
+ }
+ var typeName = options.typeName,
+ entityDef = options.entityDef,
+ serviceType = null;
+ if (typeName) {
+ if (entityDef) {
+ serviceType = entityDef.get("serviceType") || null;
}
- return serviceType;
}
-
- function makeNodeObj(relationObj) {
- var obj = {};
- obj['shape'] = "img";
- obj['typeName'] = relationObj.typeName
- obj['label'] = relationObj.displayText.trunc(18);
- obj['toolTipLabel'] = relationObj.displayText;
- obj['id'] = relationObj.guid;
- obj['isLineage'] = true;
- obj['queryText'] = relationObj.queryText;
- obj['serviceType'] = getServiceType(relationObj.typeName);
- if (relationObj.status) {
- obj['status'] = relationObj.status;
+ 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,
+ 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.filterObj.isProcessHideCheck) {
- obj['isProcess'] = relationObj.isProcess;
+ if (!that.fromToNodeData[obj.toEntityId]) {
+ that.fromToNodeData[obj.toEntityId] = makeNodeData(guidEntityMap[obj.toEntityId]);
+ }
+ if (newHashMap[obj.fromEntityId]) {
+ newHashMap[obj.fromEntityId].push(obj.toEntityId);
} else {
- obj['isProcess'] = isProcess(relationObj);
+ newHashMap[obj.fromEntityId] = [obj.toEntityId];
}
-
- return obj;
- }
-
- var newRelations = [],
- finalRelations = relations,
- isHideFilterOn = this.filterObj.isProcessHideCheck || this.filterObj.isDeletedEntityHideCheck;
- if (isHideFilterOn) {
- _.each(relations, function(obj, index, relationArr) {
- var toNodeToBeUpdated = isNodeToBeUpdated(guidEntityMap[obj.toEntityId]);
- var fromNodeToBeUpdated = isNodeToBeUpdated(guidEntityMap[obj.fromEntityId]);
- if (toNodeToBeUpdated.update) {
- if (that.filterObj.isProcessHideCheck) {
- //We have already checked entity is process or not inside isNodeToBeUpdated();
- guidEntityMap[obj.toEntityId]["isProcess"] = true;
- }
- _.filter(relationArr, function(flrObj) {
- if (flrObj.fromEntityId === obj.toEntityId) {
- if (that.filterObj.isDeletedEntityHideCheck && isDeleted(guidEntityMap[flrObj.toEntityId])) {
- return;
+ });
+ 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);
}
- newRelations.push({
- fromEntityId: obj.fromEntityId,
- toEntityId: flrObj.toEntityId
- });
- }
- })
- } else if (fromNodeToBeUpdated.update) {
- if (that.filterObj.isProcessHideCheck) {
- //We have already checked entity is process or not inside isNodeToBeUpdated();
- guidEntityMap[obj.fromEntityId]["isProcess"] = true;
- }
-
- _.filter(relationArr, function(flrObj) {
- if (that.filterObj.isDeletedEntityHideCheck && isDeleted(guidEntityMap[flrObj.fromEntityId])) {
- return;
+ } else {
+ newRelationship.push(guid);
}
- if (flrObj.toEntityId === obj.fromEntityId) {
- newRelations.push({
- fromEntityId: flrObj.fromEntityId,
- toEntityId: obj.toEntityId
- });
+ });
+ 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]);
+ } else {
+ var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid);
+ if (newToNodeRelationship) {
+ toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
+ }
}
- })
+ } 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 {
- newRelations.push(obj);
+ if (filterRelationshipMap[fromNodeGuid]) {
+ filterRelationshipMap[fromNodeGuid] = filterRelationshipMap[fromNodeGuid].concat(toNodeList);
+ } else {
+ filterRelationshipMap[fromNodeGuid] = toNodeList;
+ }
}
- });
- finalRelations = newRelations;
+ })
}
- _.each(finalRelations, function(obj, index) {
- if (!that.fromToObj[obj.fromEntityId]) {
- that.fromToObj[obj.fromEntityId] = makeNodeObj(guidEntityMap[obj.fromEntityId]);
- that.g.setNode(obj.fromEntityId, that.fromToObj[obj.fromEntityId]);
- }
- if (!that.fromToObj[obj.toEntityId]) {
- that.fromToObj[obj.toEntityId] = makeNodeObj(guidEntityMap[obj.toEntityId]);
- that.g.setNode(obj.toEntityId, that.fromToObj[obj.toEntityId]);
- }
- var styleObj = {
- fill: 'none',
- stroke: '#ffb203',
- width: 3
+ _.each(filterRelationshipMap, function(toNodesList, fromNodeGuid) {
+ if (!that.g._nodes[fromNodeGuid]) {
+ that.g.setNode(fromNodeGuid, that.fromToNodeData[fromNodeGuid]);
}
- that.g.setEdge(obj.fromEntityId, obj.toEntityId, { 'arrowhead': "arrowPoint", lineInterpolate: 'basis', "style": "fill:" + styleObj.fill + ";stroke:" + styleObj.stroke + ";stroke-width:" + styleObj.width + "", 'styleObj': styleObj });
- });
+ _.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 (!finalRelations.length) {
+ if (_.isEmpty(filterRelationshipMap)) {
this.$('svg').html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No relations to display</text>');
- } else {
- this.$('svg').html('<text></text>');
}
- if (this.fromToObj[this.guid]) {
- this.fromToObj[this.guid]['isLineage'] = false;
- this.checkForLineageOrImpactFlag(finalRelations, this.guid);
+ if (this.fromToNodeData[this.guid]) {
+ this.fromToNodeData[this.guid]['isLineage'] = false;
+ this.findImpactNodeAndUpdateData({ "relationshipMap": filterRelationshipMap, "guid": this.guid, "getStyleObjStr": getStyleObjStr });
}
if (this.asyncFetchCounter == 0) {
this.createGraph();
}
- if (this.lineageData) {
- this.renderLineageTypeSearch();
- this.lineageTypeSearch()
- }
},
- checkForLineageOrImpactFlag: function(relations, guid) {
+ findImpactNodeAndUpdateData: function(options) {
var that = this,
- nodeFound = _.where(relations, { 'fromEntityId': guid });
- if (nodeFound.length) {
- _.each(nodeFound, function(node) {
- if (!node["traversed"]) {
- node["traversed"] = true;
- that.fromToObj[node.toEntityId]['isLineage'] = false;
+ relationshipMap = options.relationshipMap,
+ fromNodeGuid = 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
}
- that.g.setEdge(node.fromEntityId, node.toEntityId, { 'arrowhead': "arrowPoint", lineInterpolate: 'basis', "style": "fill:" + styleObj.fill + ";stroke:" + styleObj.stroke + ";stroke-width:" + styleObj.width + "", 'styleObj': styleObj });
- that.checkForLineageOrImpactFlag(relations, node.toEntityId);
- }
- });
+ that.g.setEdge(fromNodeGuid, toNodeGuid, {
+ "arrowhead": 'arrowPoint',
+ "lineInterpolate": 'basis',
+ "style": getStyleObjStr(styleObj),
+ 'styleObj': styleObj
+ });
+ that.findImpactNodeAndUpdateData({
+ "relationshipMap": relationshipMap,
+ "guid": toNodeGuid,
+ "getStyleObjStr": getStyleObjStr
+ });
+ });
+ }
}
},
toggleInformationSlider: function(options) {
@@ -404,12 +471,22 @@ define(['require',
},
centerNode: function(nodeID) {
var zoom = function() {
- svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
- },
- matrix = this.$('svg').find("g.nodes").find('>g#' + nodeID).attr('transform').replace(/[^0-9\-.,]/g, '').split(','),
- x = matrix[0],
- y = matrix[1],
- viewerWidth = this.$('svg').width(),
+ svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
+ };
+ var selectedNode = this.$('svg').find("g.nodes").find('>g#' + nodeID);
+
+ if (selectedNode.length > 0) {
+ selectedNode = selectedNode;
+ var matrix = selectedNode.attr('transform').replace(/[^0-9\-.,]/g, '').split(','),
+ x = matrix[0],
+ y = matrix[1];
+ } else {
+ selectedNode = this.$('svg').find("g.nodes").find('g').eq(1);
+ var x = this.g.graph().width / 2,
+ y = this.g.graph().height / 2;
+
+ }
+ var viewerWidth = this.$('svg').width(),
viewerHeight = this.$('svg').height(),
gBBox = d3.select('g').node().getBBox(),
zoomListener = d3.behavior.zoom().scaleExtent([0.01, 50]).on("zoom", zoom),
@@ -577,8 +654,39 @@ define(['require',
svg.on("dblclick.zoom", null)
// .on("wheel.zoom", null);
//change text postion
+
+ function isConnected(a, b, o) {
+ //console.log(a, b, o);
+ if (a === o || (b && b.length && b.indexOf(o) != -1)) {
+ return true;
+ }
+ }
+
+ function fade(opacity, d, nodesToHighlight) {
+ var node = svg.selectAll('.node');
+ var path = svg.selectAll('.edgePath');
+ node.classed("hover-active", function(selectedNode, i, nodes) {
+ if (isConnected(d, nodesToHighlight, selectedNode)) {
+ return true;
+ } else {
+ return false;
+ }
+ });
+ path.classed('hover-active-node', function(c) {
+ var _thisOpacity = c.v === d || c.w === d ? 1 : 0;
+ if (_thisOpacity) {
+ return true;
+ } else {
+ return false;
+ }
+
+ });
+
+ }
+ //Highlight on click
svgGroup.selectAll("g.nodes g.label")
.attr("transform", "translate(2,-35)");
+ var waitForDoubleClick = null;
svgGroup.selectAll("g.nodes g.node")
.on('mouseenter', function(d) {
that.activeNode = true;
@@ -604,38 +712,68 @@ define(['require',
} else if ((currentELWidth.top) < 400) {
direction = ((currentELWidth.left) < 50) ? 'se' : 's';
}
- tooltip.direction(direction).show(d)
+ if (that.ui.showTooltip.prop('checked')) {
+ tooltip.direction(direction).show(d);
+ }
+
+ if (!that.ui.showOnlyHoverPath.prop('checked')) {
+ return;
+ }
+ that.$('svg').addClass('hover');
+ var nextNode = that.g.successors(d),
+ previousNode = that.g.predecessors(d),
+ nodesToHighlight = nextNode.concat(previousNode);
+ fade(0.3, d, nodesToHighlight);
})
- .on('dblclick', function(d) {
- tooltip.hide(d);
- Utils.setUrl({
- url: '#!/detailPage/' + d + '?tabActive=lineage',
- mergeBrowserUrl: false,
- trigger: true
- });
- }).on('mouseleave', function(d) {
+ .on('mouseleave', function(d) {
that.activeNode = false;
var nodeEL = this;
setTimeout(function(argument) {
if (!(that.activeTip || that.activeNode)) {
$(nodeEL).removeClass('active');
- tooltip.hide(d);
+ if (that.ui.showTooltip.prop('checked')) {
+ tooltip.hide(d);
+ }
}
- }, 400)
- }).on('click', function(d) {
+ }, 400);
+ if (!that.ui.showOnlyHoverPath.prop('checked')) {
+ return;
+ }
+ that.$('svg').removeClass('hover');
+ fade(1, d);
+ })
+ .on('click', function(d) {
if (d3.event.defaultPrevented) return; // ignore drag
- that.toggleLineageInfomationSlider({ open: true, obj: d });
- svgGroup.selectAll('[data-stroke]').attr('stroke', 'none');
- svgGroup.selectAll('[data-stroke]').attr('stroke', function(c) {
- if (c == d) {
- return "#316132";
- } else {
- return 'none';
- }
- })
- that.updateRelationshipDetails({ obj: d });
-
+ d3.event.preventDefault();
+
+ if (waitForDoubleClick != null) {
+ clearTimeout(waitForDoubleClick)
+ waitForDoubleClick = null;
+ tooltip.hide(d);
+ Utils.setUrl({
+ url: '#!/detailPage/' + d + '?tabActive=lineage',
+ mergeBrowserUrl: false,
+ trigger: true
+ });
+ } else {
+ var currentEvent = d3.event
+ waitForDoubleClick = setTimeout(function() {
+ tooltip.hide(d);
+ that.toggleLineageInfomationSlider({ open: true, obj: d });
+ svgGroup.selectAll('[data-stroke]').attr('stroke', 'none');
+ svgGroup.selectAll('[data-stroke]').attr('stroke', function(c) {
+ if (c == d) {
+ return "#316132";
+ } else {
+ return 'none';
+ }
+ })
+ that.updateRelationshipDetails({ obj: d });
+ waitForDoubleClick = null;
+ }, 150)
+ }
});
+
svgGroup.selectAll("g.edgePath path.path").on('click', function(d) {
var data = { obj: _.find(that.lineageData.relations, { "fromEntityId": d.v, "toEntityId": d.w }) },
relationshipId = data.obj.relationshipId;
@@ -692,8 +830,9 @@ define(['require',
});
}
that.ui.lineageTypeSearch.html(typeStr);
+ this.initilizelineageTypeSearch()
},
- lineageTypeSearch: function() {
+ initilizelineageTypeSearch: function() {
var that = this;
that.ui.lineageTypeSearch.select2({
closeOnSelect: true,