LineageLayoutView.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. define([ "require", "backbone", "hbs!tmpl/graph/LineageLayoutView_tmpl", "collection/VLineageList", "models/VEntity", "utils/Utils", "LineageHelper", "d3", "dagreD3", "d3-tip", "utils/Enums", "utils/UrlLinks", "utils/Globals", "utils/CommonViewFunction", "platform", "jquery-ui" ], function(require, Backbone, LineageLayoutViewtmpl, VLineageList, VEntity, Utils, LineageHelper, d3, dagreD3, d3Tip, Enums, UrlLinks, Globals, CommonViewFunction, platform) {
  2. "use strict";
  3. var LineageLayoutView = Backbone.Marionette.LayoutView.extend({
  4. _viewName: "LineageLayoutView",
  5. template: LineageLayoutViewtmpl,
  6. className: "resizeGraph",
  7. regions: {},
  8. ui: {
  9. graph: ".graph",
  10. checkHideProcess: "[data-id='checkHideProcess']",
  11. checkDeletedEntity: "[data-id='checkDeletedEntity']",
  12. selectDepth: 'select[data-id="selectDepth"]',
  13. filterToggler: '[data-id="filter-toggler"]',
  14. settingToggler: '[data-id="setting-toggler"]',
  15. searchToggler: '[data-id="search-toggler"]',
  16. boxClose: '[data-id="box-close"]',
  17. lineageFullscreenToggler: '[data-id="fullScreen-toggler"]',
  18. filterBox: ".filter-box",
  19. searchBox: ".search-box",
  20. settingBox: ".setting-box",
  21. lineageTypeSearch: '[data-id="typeSearch"]',
  22. searchNode: '[data-id="searchNode"]',
  23. nodeDetailTable: '[data-id="nodeDetailTable"]',
  24. showOnlyHoverPath: '[data-id="showOnlyHoverPath"]',
  25. showTooltip: '[data-id="showTooltip"]',
  26. saveSvg: '[data-id="saveSvg"]',
  27. resetLineage: '[data-id="resetLineage"]',
  28. onZoomIn: '[data-id="zoom-in"]',
  29. labelFullName: '[data-id="labelFullName"]',
  30. onZoomOut: '[data-id="zoom-out"]'
  31. },
  32. templateHelpers: function() {
  33. return {
  34. width: "100%",
  35. height: "100%"
  36. };
  37. },
  38. events: function() {
  39. var events = {};
  40. return events["click " + this.ui.checkHideProcess] = "onCheckUnwantedEntity", events["click " + this.ui.checkDeletedEntity] = "onCheckUnwantedEntity",
  41. events["change " + this.ui.selectDepth] = "onSelectDepthChange", events["click " + this.ui.filterToggler] = "onClickFilterToggler",
  42. events["click " + this.ui.boxClose] = "toggleBoxPanel", events["click " + this.ui.settingToggler] = "onClickSettingToggler",
  43. events["click " + this.ui.lineageFullscreenToggler] = "onClickLineageFullscreenToggler",
  44. events["click " + this.ui.searchToggler] = "onClickSearchToggler", events["click " + this.ui.saveSvg] = "onClickSaveSvg",
  45. events["click " + this.ui.resetLineage] = "onClickResetLineage", events["click " + this.ui.onZoomIn] = "onClickZoomIn",
  46. events["click " + this.ui.onZoomOut] = "onClickZoomOut", events["change " + this.ui.labelFullName] = "onClickLabelFullName",
  47. events;
  48. },
  49. initialize: function(options) {
  50. _.extend(this, _.pick(options, "processCheck", "guid", "entity", "entityName", "entityDefCollection", "actionCallBack", "fetchCollection", "attributeDefs")),
  51. this.collection = new VLineageList(), this.typeMap = {}, this.apiGuid = {}, this.edgeCall,
  52. this.filterObj = {
  53. isProcessHideCheck: !1,
  54. isDeletedEntityHideCheck: !1,
  55. depthCount: ""
  56. }, this.searchNodeObj = {
  57. selectedNode: ""
  58. }, this.labelFullText = !1;
  59. },
  60. onRender: function() {
  61. this.ui.searchToggler.prop("disabled", !0), this.$graphButtonsEl = this.$(".graph-button-group button, select[data-id='selectDepth']"),
  62. this.fetchGraphData(), this.layoutRendered && this.layoutRendered(), this.processCheck && this.hideCheckForProcess(),
  63. this.ui.selectDepth.select2({
  64. data: _.sortBy([ 3, 6, 9, 12, 15, 18, 21 ]),
  65. tags: !0,
  66. dropdownCssClass: "number-input",
  67. multiple: !1
  68. });
  69. },
  70. onShow: function() {
  71. this.$(".fontLoader").show();
  72. },
  73. onClickLineageFullscreenToggler: function(e) {
  74. var icon = $(e.currentTarget).find("i"), panel = $(e.target).parents(".tab-pane").first();
  75. icon.toggleClass("fa-expand fa-compress"), icon.hasClass("fa-expand") ? icon.parent("button").attr("data-original-title", "Full Screen") : icon.parent("button").attr("data-original-title", "Default View"),
  76. panel.toggleClass("fullscreen-mode");
  77. var node = this.$("svg").parent()[0].getBoundingClientRect();
  78. this.LineageHelperRef.updateOptions({
  79. width: node.width,
  80. height: node.height
  81. }), this.calculateLineageDetailPanelHeight();
  82. },
  83. onCheckUnwantedEntity: function(e) {
  84. "checkHideProcess" === $(e.target).data("id") ? this.filterObj.isProcessHideCheck = e.target.checked : this.filterObj.isDeletedEntityHideCheck = e.target.checked,
  85. this.LineageHelperRef.refresh();
  86. },
  87. toggleBoxPanel: function(options) {
  88. var el = options && options.el;
  89. options && options.nodeDetailToggler, options.currentTarget;
  90. this.$el.find(".show-box-panel").removeClass("show-box-panel"), el && el.addClass && el.addClass("show-box-panel"),
  91. this.$("circle.node-detail-highlight").removeClass("node-detail-highlight");
  92. },
  93. toggleLoader: function(element) {
  94. element.hasClass("fa-camera") ? element.removeClass("fa-camera").addClass("fa-spin-custom fa-refresh") : element.removeClass("fa-spin-custom fa-refresh").addClass("fa-camera");
  95. },
  96. toggleDisableState: function(options) {
  97. var el = options.el, disabled = options.disabled;
  98. el && el.prop && (disabled ? el.prop("disabled", disabled) : el.prop("disabled", !el.prop("disabled")));
  99. },
  100. onClickNodeToggler: function(options) {
  101. this.toggleBoxPanel({
  102. el: this.$(".lineage-node-detail"),
  103. nodeDetailToggler: !0
  104. });
  105. },
  106. onClickFilterToggler: function() {
  107. this.toggleBoxPanel({
  108. el: this.ui.filterBox
  109. });
  110. },
  111. onClickSettingToggler: function() {
  112. this.toggleBoxPanel({
  113. el: this.ui.settingBox
  114. });
  115. },
  116. onClickSearchToggler: function() {
  117. this.toggleBoxPanel({
  118. el: this.ui.searchBox
  119. });
  120. },
  121. onSelectDepthChange: function(e, options) {
  122. this.filterObj.depthCount = e.currentTarget.value, this.fetchGraphData({
  123. queryParam: {
  124. depth: this.filterObj.depthCount
  125. },
  126. legends: !1
  127. });
  128. },
  129. onClickResetLineage: function() {
  130. this.LineageHelperRef.refresh(), this.searchNodeObj.selectedNode = "", this.ui.lineageTypeSearch.data({
  131. refresh: !0
  132. }).val("").trigger("change"), this.ui.labelFullName.prop("checked", !1), this.labelFullText = !1;
  133. },
  134. onClickSaveSvg: function(e, a) {
  135. var that = this;
  136. return that.lineageRelationshipLength >= 1e3 ? void Utils.notifyInfo({
  137. content: "There was an error in downloading lineage: Lineage exceeds display parameters!"
  138. }) : void this.LineageHelperRef.exportLineage();
  139. },
  140. onClickZoomIn: function() {
  141. this.LineageHelperRef.zoomIn();
  142. },
  143. onClickZoomOut: function() {
  144. this.LineageHelperRef.zoomOut();
  145. },
  146. onClickLabelFullName: function() {
  147. this.labelFullText = !this.labelFullText, this.LineageHelperRef.displayFullName({
  148. bLabelFullText: this.labelFullText
  149. });
  150. },
  151. fetchGraphData: function(options) {
  152. var that = this, queryParam = options && options.queryParam || {};
  153. this.$(".fontLoader").show(), this.$("svg>g").hide(), this.toggleDisableState({
  154. el: that.$graphButtonsEl,
  155. disabled: !0
  156. }), this.collection.getLineage(this.guid, {
  157. queryParam: queryParam,
  158. success: function(data) {
  159. if (!that.isDestroyed) {
  160. data.legends = !options || options.legends;
  161. var relationsReverse = data.relations ? data.relations.reverse() : null, lineageMaxRelationCount = 9e3;
  162. relationsReverse.length > lineageMaxRelationCount && (data.relations = relationsReverse.splice(relationsReverse.length - lineageMaxRelationCount, relationsReverse.length - 1),
  163. Utils.notifyInfo({
  164. content: "Lineage exceeds display parameters and hence only upto 9000 relationships from this lineage can be displayed"
  165. })), that.lineageRelationshipLength = data.relations.length, that.createGraph(data),
  166. that.renderLineageTypeSearch(data);
  167. }
  168. },
  169. cust_error: function(model, response) {
  170. that.noLineage();
  171. },
  172. complete: function() {
  173. that.$(".fontLoader").hide(), that.$("svg>g").show();
  174. }
  175. });
  176. },
  177. createGraph: function(data) {
  178. var that = this;
  179. $(".resizeGraph").css("height", this.$(".svg").height() + "px"), this.LineageHelperRef = new LineageHelper.default({
  180. entityDefCollection: this.entityDefCollection.fullCollection.toJSON(),
  181. data: data,
  182. el: this.$(".svg")[0],
  183. legendsEl: this.$(".legends")[0],
  184. legends: data.legends,
  185. getFilterObj: function() {
  186. return {
  187. isProcessHideCheck: that.filterObj.isProcessHideCheck,
  188. isDeletedEntityHideCheck: that.filterObj.isDeletedEntityHideCheck
  189. };
  190. },
  191. isShowHoverPath: function() {
  192. return that.ui.showOnlyHoverPath.prop("checked");
  193. },
  194. isShowTooltip: function() {
  195. return that.ui.showTooltip.prop("checked");
  196. },
  197. onPathClick: function(d) {
  198. if (console.log("Path Clicked"), d.pathRelationObj) {
  199. var relationshipId = d.pathRelationObj.relationshipId;
  200. require([ "views/graph/PropagationPropertyModal" ], function(PropagationPropertyModal) {
  201. new PropagationPropertyModal({
  202. edgeInfo: d.pathRelationObj,
  203. relationshipId: relationshipId,
  204. lineageData: data,
  205. apiGuid: that.apiGuid,
  206. detailPageFetchCollection: that.fetchCollection
  207. });
  208. });
  209. }
  210. },
  211. onNodeClick: function(d) {
  212. that.onClickNodeToggler(), that.updateRelationshipDetails({
  213. guid: d.clickedData
  214. }), that.calculateLineageDetailPanelHeight();
  215. },
  216. onLabelClick: function(d) {
  217. var guid = d.clickedData;
  218. that.guid == guid ? Utils.notifyInfo({
  219. html: !0,
  220. content: "You are already on <b>" + that.entityName + "</b> detail page."
  221. }) : Utils.setUrl({
  222. url: "#!/detailPage/" + guid + "?tabActive=lineage",
  223. mergeBrowserUrl: !1,
  224. trigger: !0
  225. });
  226. },
  227. beforeRender: function() {
  228. that.$(".fontLoader").show(), that.toggleDisableState({
  229. el: that.$graphButtonsEl,
  230. disabled: !0
  231. });
  232. },
  233. afterRender: function() {
  234. that.$(".fontLoader").hide(), data.relations.length && that.toggleDisableState({
  235. el: that.$graphButtonsEl,
  236. disabled: !1
  237. });
  238. }
  239. });
  240. },
  241. noLineage: function() {
  242. this.$(".fontLoader").hide(), this.$(".depth-container").hide(), this.$("svg").html('<text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">No lineage data found</text>'),
  243. this.actionCallBack && this.actionCallBack();
  244. },
  245. hideCheckForProcess: function() {
  246. this.$(".hideProcessContainer").hide();
  247. },
  248. renderLineageTypeSearch: function(data) {
  249. var that = this;
  250. return new Promise(function(resolve, reject) {
  251. try {
  252. var typeStr = "<option></option>";
  253. _.isEmpty(data) || _.each(data.guidEntityMap, function(obj, index) {
  254. var nodeData = that.LineageHelperRef.getNode(obj.guid);
  255. (that.filterObj.isProcessHideCheck || that.filterObj.isDeletedEntityHideCheck) && nodeData && (nodeData.isProcess || nodeData.isDeleted) || (typeStr += '<option value="' + obj.guid + '">' + obj.displayText + "</option>");
  256. }), that.ui.lineageTypeSearch.html(typeStr), that.initilizelineageTypeSearch(),
  257. resolve();
  258. } catch (e) {
  259. console.log(e), reject(e);
  260. }
  261. });
  262. },
  263. initilizelineageTypeSearch: function() {
  264. var that = this;
  265. this.ui.lineageTypeSearch.select2({
  266. closeOnSelect: !0,
  267. placeholder: "Select Node"
  268. }).on("change.select2", function(e) {
  269. if (e.stopPropagation(), e.stopImmediatePropagation(), that.ui.lineageTypeSearch.data("refresh")) that.ui.lineageTypeSearch.data("refresh", !1); else {
  270. var selectedNode = $('[data-id="typeSearch"]').val();
  271. that.searchNodeObj.selectedNode = selectedNode, that.LineageHelperRef.searchNode({
  272. guid: selectedNode
  273. });
  274. }
  275. }), this.searchNodeObj.selectedNode && (this.ui.lineageTypeSearch.val(this.searchNodeObj.selectedNode),
  276. this.ui.lineageTypeSearch.trigger("change.select2"));
  277. },
  278. updateRelationshipDetails: function(options) {
  279. var that = this, guid = options.guid, initialData = that.LineageHelperRef.getNode(guid);
  280. if (void 0 !== initialData) {
  281. var typeName = initialData.typeName || guid, attributeDefs = initialData && initialData.entityDef ? initialData.entityDef.attributeDefs : null;
  282. this.$("[data-id='typeName']").text(typeName), this.entityModel = new VEntity({});
  283. var config = {
  284. guid: "guid",
  285. typeName: "typeName",
  286. name: "name",
  287. qualifiedName: "qualifiedName",
  288. owner: "owner",
  289. createTime: "createTime",
  290. status: "status",
  291. classificationNames: "classifications",
  292. meanings: "term"
  293. }, data = {};
  294. _.each(config, function(valKey, key) {
  295. var val = initialData[key];
  296. _.isUndefined(val) && initialData.attributes && initialData.attributes[key] && (val = initialData.attributes[key]),
  297. val && (data[valKey] = val);
  298. }), this.ui.nodeDetailTable.html(CommonViewFunction.propertyTable({
  299. scope: this,
  300. valueObject: data,
  301. attributeDefs: attributeDefs,
  302. sortBy: !1
  303. }));
  304. }
  305. },
  306. calculateLineageDetailPanelHeight: function() {
  307. var $parentContainer = $("#tab-lineage .resizeGraph"), $panel = $parentContainer.find(".fix-box"), $parentHeight = $parentContainer.find(".fix-box, tbody").removeAttr("style").height() - 48, $tBody = $panel.find("tbody"), panelHeight = $tBody.height() + 100;
  308. $parentHeight < panelHeight && (panelHeight = $parentHeight), $panel.css("height", panelHeight + "px"),
  309. $tBody.css("height", "100%");
  310. }
  311. });
  312. return LineageLayoutView;
  313. });