Commit b9642b62 by kevalbhatt Committed by Sarath Subramanian

ATLAS-3030: UI : Allow to search the node in the lineage graph

parent f103e143
......@@ -38,6 +38,12 @@
stroke: $color_mountain_mist_approx;
fill: $white;
stroke-width: 1.5px;
&.serach-rect {
stroke: $color_keppel_approx;
fill: transparent;
stroke-width: 2.5px
}
}
.label {
......@@ -276,6 +282,7 @@ g.type-TK>rect {
.lineage-fltr-panel,
.lineage-search-panel {
position: absolute;
top: 45px;
border: 1px solid #ccc;
width: 250px;
max-height: 99%;
......@@ -445,6 +452,11 @@ span#zoom_in {
position: relative;
width: 100%;
height: 64vh;
overflow: hidden !important;
&.auto-height {
height: auto !important;
}
}
.active.fullscreen-mode {
......@@ -472,3 +484,21 @@ span#zoom_in {
padding: 10px !important;
}
}
@keyframes zoominoutsinglefeatured {
0% {
transform: scale(1, 1);
}
50% {
transform: scale(1.2, 1.2);
}
100% {
transform: scale(1, 1);
}
}
.wobble {
animation: zoominoutsinglefeatured 1s 5;
}
\ No newline at end of file
......@@ -189,6 +189,7 @@ require.config({
require(['App',
'router/Router',
'utils/Helper',
'utils/CommonViewFunction',
'utils/Globals',
'utils/UrlLinks',
......@@ -198,7 +199,7 @@ require(['App',
'bootstrap',
'd3',
'select2'
], function(App, Router, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList) {
], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList) {
var that = this;
this.asyncFetchCounter = 6;
this.entityDefCollection = new VEntityList();
......
......@@ -103,6 +103,7 @@ define([
this.postRouteExecute();
},
preRouteExecute: function() {
$(".tooltip").tooltip("hide");
// console.log("Pre-Route Change Operations can be performed here !!");
},
postRouteExecute: function(name, args) {
......
......@@ -46,11 +46,32 @@
</div>
</div>
</div>
<div class="lineage-search-panel">
<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>
</div>
<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>
</div>
</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>
</div>
<div>
<button type="button" data-id="search-togler" 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>
</div>
<div class="btn-group">
......@@ -61,12 +82,14 @@
<div class="fontLoader">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
<canvas width="960" height="500" style="display:none; position: absolute;"></canvas>
<div class="legends pull-left" style="height: 25px; padding: 2px;">
<span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-circle-o fa-fw" aria-hidden="true"></i>Current Entity</span>
<span style="margin-right: 8px; color:#df9b00;"><i class="fa fa-long-arrow-right fa-fw" aria-hidden="true"></i>Lineage</span>
<span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-long-arrow-right fa-fw" aria-hidden="true"></i>Impact</span>
</div>
<svg width="100%" height="calc(100% - 28px)" viewBox="0 0 854 330" enable-background="new 0 0 854 330" xml:space="preserve"></svg>
<!-- <svg width="100%" height="calc(100% - 28px)" preserveAspectRatio="xMidYMid meet" viewBox="0 0 854 330" enable-background="new 0 0 854 330" xml:space="preserve"></svg> -->
<svg width="{{width}}" height="{{height}}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"></svg>
<div class="lineage-details node-details">
<span data-id="close" style="margin: 7px;position: absolute;right: 0" class="btn btn-action btn-sm fltr-togler"><i class="fa fa-close"></i></span>
<h4 class="title"><span data-id="typeName"></span></h4>
......
......@@ -76,9 +76,21 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Glob
valueObject = options.valueObject,
extractJSON = options.extractJSON,
isTable = _.isUndefined(options.isTable) ? true : options.isTable,
attributeDefs = options.attributeDefs;
attributeDefs = options.attributeDefs,
numberFormat = options.numberFormat;
var table = "",
getValue = function(val) {
if (val && numberFormat) {
if (_.isNumber(val)) {
return numberFormat(val);
} else if (!_.isNaN(parseInt(val))) {
return numberFormat(val);
}
} else {
return val;
}
},
fetchInputOutputValue = function(id, defEntity) {
var that = this;
scope.entityModel.getEntityHeader(id, {
......@@ -95,7 +107,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Glob
id = data.guid;
}
if (value.length > 0) {
scope.$('td div[data-id="' + id + '"]').html('<a href="#!/detailPage/' + id + '">' + value + '</a>');
scope.$('td div[data-id="' + id + '"]').html('<a href="#!/detailPage/' + id + '">' + getValue(value) + '</a>');
} else {
scope.$('td div[data-id="' + id + '"]').html('<a href="#!/detailPage/' + id + '">' + _.escape(id) + '</a>');
}
......@@ -137,7 +149,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Glob
if (_.isString(inputOutputField) || _.isBoolean(inputOutputField) || _.isNumber(inputOutputField)) {
var tempVarfor$check = inputOutputField.toString();
if (tempVarfor$check.indexOf("$") == -1) {
valueOfArray.push('<span class="json-string">' + _.escape(inputOutputField) + '</span>');
valueOfArray.push('<span class="json-string">' + getValue(_.escape(inputOutputField)) + '</span>');
}
} else if (_.isObject(inputOutputField) && !id) {
var attributesList = inputOutputField;
......@@ -233,7 +245,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Glob
val = _.escape(keyValue);
}
if (isTable) {
var htmlTag = '<div class="scroll-y">' + val + '</div>';
var htmlTag = '<div class="scroll-y">' + getValue(val) + '</div>';
if (_.isObject(valueObject[key])) {
var matchedLinkString = val.match(/href|value-loader\w*/g),
matchedJson = val.match(/json-value|json-string\w*/g),
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
define(['require',
'utils/Utils',
'd3',
'marionette'
], function(require, Utils, d3) {
'use strict';
_.mixin({
numberFormatWithComa: function(number) {
return d3.format(',')(number);
},
isEmptyArray: function(val) {
if (val && _.isArray(val)) {
return _.isEmpty(val);
} else {
return false;
}
},
startsWith: function(str, matchStr) {
if (str && matchStr && _.isString(str) && _.isString(matchStr)) {
return str.lastIndexOf(matchStr, 0) === 0
} else {
return;
}
},
isUndefinedNull: function(val) {
if (_.isUndefined(val) || _.isNull(val)) {
return true
} else {
return false;
}
},
trim: function(val) {
if (val && val.trim) {
return val.trim();
} else {
return val;
}
},
isTypePrimitive: function(type) {
if (type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double" || type === "string" || type === "boolean" || type === "date") {
return true;
}
return false;
}
});
var getPopoverEl = function(e) {
return $(e.target).parent().data("bs.popover") || $(e.target).data("bs.popover") || $(e.target).parents('.popover').length;
}
$(document).on('click DOMMouseScroll mousewheel', function(e) {
if (e.originalEvent) {
// Do action if it is triggered by a human.
//e.isImmediatePropagationStopped();
var isPopOverEl = getPopoverEl(e)
if (!isPopOverEl) {
$('.popover').popover('hide');
} else if (isPopOverEl.$tip) {
$('.popover').not(isPopOverEl.$tip).popover('hide');
}
}
});
$('body').on('hidden.bs.popover', function(e) {
$(e.target).data("bs.popover").inState = { click: false, hover: false, focus: false }
});
$('body').on('show.bs.popover', '[data-js="popover"]', function() {
$('.popover').not(this).popover('hide');
});
$('body').on('keypress', 'input.number-input,.number-input .select2-search__field', function(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
});
$('body').on('keypress', 'input.number-input-negative,.number-input-negative .select2-search__field', function(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
if (e.which == 45) {
if (this.value.length) {
return false;
}
} else {
return false;
}
}
});
$('body').on('keypress', 'input.number-input-exponential,.number-input-exponential .select2-search__field', function(e) {
if ((e.which != 8 && e.which != 0) && (e.which < 48 || e.which > 57) && (e.which != 69 && e.which != 101 && e.which != 43 && e.which != 45 && e.which != 46 && e.which != 190)) {
return false;
}
});
$("body").on('click', '.dropdown-menu.dropdown-changetitle li a', function() {
$(this).parents('li').find(".btn:first-child").html($(this).text() + ' <span class="caret"></span>');
});
$("body").on('click', '.btn', function() {
$(this).blur();
});
$.fn.select2.amd.define("ServiceTypeFilterDropdownAdapter", [
"select2/utils",
"select2/dropdown",
"select2/dropdown/attachBody",
"select2/dropdown/attachContainer",
"select2/dropdown/search",
"select2/dropdown/minimumResultsForSearch",
"select2/dropdown/closeOnSelect",
],
function(Utils, Dropdown, AttachBody, AttachContainer, Search, MinimumResultsForSearch, CloseOnSelect) {
// Decorate Dropdown with Search functionalities
var dropdownWithSearch = Utils.Decorate(Utils.Decorate(Dropdown, CloseOnSelect), Search);
dropdownWithSearch.prototype.render = function() {
// Copy and modify default search render method
var $rendered = Dropdown.prototype.render.call(this);
// Add ability for a placeholder in the search box
var placeholder = this.options.get("placeholderForSearch") || "";
var $search = $(
'<span class="select2-search select2-search--dropdown"><div class="row">' +
'<div class="col-md-10"><input class="select2-search__field" placeholder="' + placeholder + '" type="search"' +
' tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off"' +
' spellcheck="false" role="textbox" /></div>' +
'<div class="col-md-2"><button type="button" style="margin-left: -20px" class="btn btn-action btn-sm filter " title="Entity Attribute Filter"><i class="fa fa-filter"></i></button></div>' +
'</div></span>'
);
if (!this.options.options.getFilterBox) {
throw "In order to render the filter options adapter needed getFilterBox function"
}
var $Filter = $('<ul class="type-filter-ul"></ul>');
this.$Filter = $Filter;
this.$Filter.append(this.options.options.getFilterBox());
this.$Filter.hide();
this.$searchContainer = $search;
if ($Filter.find('input[type="checkbox"]:checked').length) {
$search.find('button.filter').addClass('active');
} else {
$search.find('button.filter').removeClass('active');
}
this.$search = $search.find('input');
$rendered.prepend($search);
$rendered.append($Filter);
return $rendered;
};
var oldDropdownWithSearchBindRef = dropdownWithSearch.prototype.bind;
dropdownWithSearch.prototype.bind = function(container, $container) {
var self = this;
oldDropdownWithSearchBindRef.call(this, container, $container);
var self = this;
this.$Filter.on('click', 'li', function() {
var itemCallback = self.options.options.onFilterItemSelect;
itemCallback && itemCallback(this);
})
this.$searchContainer.find('button.filter').click(function() {
container.$dropdown.find('.select2-search').hide(150);
container.$dropdown.find('.select2-results').hide(150);
self.$Filter.html(self.options.options.getFilterBox());
self.$Filter.show();
});
this.$Filter.on('click', 'button.filterDone', function() {
container.$dropdown.find('.select2-search').show(150);
container.$dropdown.find('.select2-results').show(150);
self.$Filter.hide();
var filterSubmitCallback = self.options.options.onFilterSubmit;
filterSubmitCallback && filterSubmitCallback({
filterVal: _.map(self.$Filter.find('input[type="checkbox"]:checked'), function(item) {
return $(item).data('value')
})
});
});
container.$element.on('hideFilter', function() {
container.$dropdown.find('.select2-search').show();
container.$dropdown.find('.select2-results').show();
self.$Filter.hide();
});
}
// Decorate the dropdown+search with necessary containers
var adapter = Utils.Decorate(dropdownWithSearch, AttachContainer);
adapter = Utils.Decorate(adapter, AttachBody);
return adapter;
});
// For placeholder support
if (!('placeholder' in HTMLInputElement.prototype)) {
var originalRender = Backbone.Marionette.LayoutView.prototype.render;
Backbone.Marionette.LayoutView.prototype.render = function() {
originalRender.apply(this, arguments);
this.$('input, textarea').placeholder();
}
}
$('body').on('click', 'pre.code-block .expand-collapse-button', function(e) {
var $el = $(this).parents('.code-block');
if ($el.hasClass('shrink')) {
$el.removeClass('shrink');
} else {
$el.addClass('shrink');
}
});
// For adding tooltip globally
$('body').tooltip({
selector: '[title]',
placement: 'bottom',
container: 'body'
});
})
\ No newline at end of file
......@@ -48,188 +48,6 @@ define(['require', 'utils/Utils', 'marionette', 'backgrid', 'asBreadcrumbs', 'jq
})
]);
}
_.mixin({
isEmptyArray: function(val) {
if (val && _.isArray(val)) {
return _.isEmpty(val);
} else {
return false;
}
},
startsWith: function(str, matchStr) {
if (str && matchStr && _.isString(str) && _.isString(matchStr)) {
return str.lastIndexOf(matchStr, 0) === 0
} else {
return;
}
},
isUndefinedNull: function(val) {
if (_.isUndefined(val) || _.isNull(val)) {
return true
} else {
return false;
}
},
trim: function(val) {
if (val && val.trim) {
return val.trim();
} else {
return val;
}
},
isTypePrimitive: function(type) {
if (type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double" || type === "string" || type === "boolean" || type === "date") {
return true;
}
return false;
}
});
var getPopoverEl = function(e) {
return $(e.target).parent().data("bs.popover") || $(e.target).data("bs.popover") || $(e.target).parents('.popover').length;
}
$(document).on('click DOMMouseScroll mousewheel', function(e) {
if (e.originalEvent) {
// Do action if it is triggered by a human.
//e.isImmediatePropagationStopped();
var isPopOverEl = getPopoverEl(e)
if (!isPopOverEl) {
$('.popover').popover('hide');
} else if (isPopOverEl.$tip) {
$('.popover').not(isPopOverEl.$tip).popover('hide');
}
}
});
$('body').on('hidden.bs.popover', function(e) {
$(e.target).data("bs.popover").inState = { click: false, hover: false, focus: false }
});
$('body').on('show.bs.popover', '[data-js="popover"]', function() {
$('.popover').not(this).popover('hide');
});
$('body').on('keypress', 'input.number-input,.number-input .select2-search__field', function(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
});
$('body').on('keypress', 'input.number-input-negative,.number-input-negative .select2-search__field', function(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
if (e.which == 45) {
if (this.value.length) {
return false;
}
} else {
return false;
}
}
});
$('body').on('keypress', 'input.number-input-exponential,.number-input-exponential .select2-search__field', function(e) {
if ((e.which != 8 && e.which != 0) && (e.which < 48 || e.which > 57) && (e.which != 69 && e.which != 101 && e.which != 43 && e.which != 45 && e.which != 46 && e.which != 190)) {
return false;
}
});
$("body").on('click', '.dropdown-menu.dropdown-changetitle li a', function() {
$(this).parents('li').find(".btn:first-child").html($(this).text() + ' <span class="caret"></span>');
});
$("body").on('click', '.btn', function() {
$(this).blur();
});
$.fn.select2.amd.define("ServiceTypeFilterDropdownAdapter", [
"select2/utils",
"select2/dropdown",
"select2/dropdown/attachBody",
"select2/dropdown/attachContainer",
"select2/dropdown/search",
"select2/dropdown/minimumResultsForSearch",
"select2/dropdown/closeOnSelect",
],
function(Utils, Dropdown, AttachBody, AttachContainer, Search, MinimumResultsForSearch, CloseOnSelect) {
// Decorate Dropdown with Search functionalities
var dropdownWithSearch = Utils.Decorate(Utils.Decorate(Dropdown, CloseOnSelect), Search);
dropdownWithSearch.prototype.render = function() {
// Copy and modify default search render method
var $rendered = Dropdown.prototype.render.call(this);
// Add ability for a placeholder in the search box
var placeholder = this.options.get("placeholderForSearch") || "";
var $search = $(
'<span class="select2-search select2-search--dropdown"><div class="row">' +
'<div class="col-md-10"><input class="select2-search__field" placeholder="' + placeholder + '" type="search"' +
' tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off"' +
' spellcheck="false" role="textbox" /></div>' +
'<div class="col-md-2"><button type="button" style="margin-left: -20px" class="btn btn-action btn-sm filter " title="Entity Attribute Filter"><i class="fa fa-filter"></i></button></div>' +
'</div></span>'
);
if (!this.options.options.getFilterBox) {
throw "In order to render the filter options adapter needed getFilterBox function"
}
var $Filter = $('<ul class="type-filter-ul"></ul>');
this.$Filter = $Filter;
this.$Filter.append(this.options.options.getFilterBox());
this.$Filter.hide();
this.$searchContainer = $search;
if ($Filter.find('input[type="checkbox"]:checked').length) {
$search.find('button.filter').addClass('active');
} else {
$search.find('button.filter').removeClass('active');
}
this.$search = $search.find('input');
$rendered.prepend($search);
$rendered.append($Filter);
return $rendered;
};
var oldDropdownWithSearchBindRef = dropdownWithSearch.prototype.bind;
dropdownWithSearch.prototype.bind = function(container, $container) {
var self = this;
oldDropdownWithSearchBindRef.call(this, container, $container);
var self = this;
this.$Filter.on('click', 'li', function() {
var itemCallback = self.options.options.onFilterItemSelect;
itemCallback && itemCallback(this);
})
this.$searchContainer.find('button.filter').click(function() {
container.$dropdown.find('.select2-search').hide(150);
container.$dropdown.find('.select2-results').hide(150);
self.$Filter.html(self.options.options.getFilterBox());
self.$Filter.show();
});
this.$Filter.on('click', 'button.filterDone', function() {
container.$dropdown.find('.select2-search').show(150);
container.$dropdown.find('.select2-results').show(150);
self.$Filter.hide();
var filterSubmitCallback = self.options.options.onFilterSubmit;
filterSubmitCallback && filterSubmitCallback({
filterVal: _.map(self.$Filter.find('input[type="checkbox"]:checked'), function(item) {
return $(item).data('value')
})
});
});
container.$element.on('hideFilter', function() {
container.$dropdown.find('.select2-search').show();
container.$dropdown.find('.select2-results').show();
self.$Filter.hide();
});
}
// Decorate the dropdown+search with necessary containers
var adapter = Utils.Decorate(dropdownWithSearch, AttachContainer);
adapter = Utils.Decorate(adapter, AttachBody);
return adapter;
});
// For placeholder support
if (!('placeholder' in HTMLInputElement.prototype)) {
var originalRender = Backbone.Marionette.LayoutView.prototype.render;
Backbone.Marionette.LayoutView.prototype.render = function() {
originalRender.apply(this, arguments);
this.$('input, textarea').placeholder();
}
}
String.prototype.trunc = String.prototype.trunc ||
function(n) {
......
......@@ -763,14 +763,5 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
this.attr(attributeName, firstString);
}
}
$('body').on('click', 'pre.code-block .expand-collapse-button', function(e) {
var $el = $(this).parents('.code-block');
if ($el.hasClass('shrink')) {
$el.removeClass('shrink');
} else {
$el.addClass('shrink');
}
});
return Utils;
});
\ No newline at end of file
......@@ -70,8 +70,8 @@ define(['require',
success: function(data) {
var data = _.first(data.toJSON()),
no_records = '<tr class="empty text-center"><td colspan="2"><span>No records found!</span></td></tr>',
activeEntityTable = _.isEmpty(data.entity.entityActive) ? no_records : CommonViewFunction.propertyTable({ scope: that, valueObject: data.entity.entityActive }),
deleteEntityTable = _.isEmpty(data.entity.entityDeleted) ? no_records : CommonViewFunction.propertyTable({ scope: that, valueObject: data.entity.entityDeleted });
activeEntityTable = _.isEmpty(data.entity.entityActive) ? no_records : CommonViewFunction.propertyTable({ scope: that, valueObject: data.entity.entityActive, numberFormat: _.numberFormatWithComa }),
deleteEntityTable = _.isEmpty(data.entity.entityDeleted) ? no_records : CommonViewFunction.propertyTable({ scope: that, valueObject: data.entity.entityDeleted, numberFormat: _.numberFormatWithComa });
var totalActive = 0,
totalDeleted = 0;
if (data.entity && data.general.entityCount) {
......@@ -84,8 +84,8 @@ define(['require',
}
that.ui.entityActive.html(activeEntityTable);
that.ui.entityDelete.html(deleteEntityTable);
that.ui.entityActiveHeader.html("&nbsp;(" + (totalActive - totalDeleted) + ")");
that.ui.entityDeletedHeader.html("&nbsp;(" + totalDeleted + ")");
that.ui.entityActiveHeader.html("&nbsp;(" + _.numberFormatWithComa((totalActive - totalDeleted)) + ")");
that.ui.entityDeletedHeader.html("&nbsp;(" + _.numberFormatWithComa(totalDeleted) + ")");
}
});
}
......
......@@ -390,7 +390,7 @@ define(['require',
val.entityGuid === that.id ? tag['self'].push(val) : tag['propagated'].push(val);
});
_.each(tag.self, function(val) {
tagData += '<span class="btn btn-action btn-sm btn-icon btn-blue" title=' + val.typeName + ' data-id="tagClick"><span>' + val.typeName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="tag" title="Remove Tag"></i></span>';
tagData += '<span class="btn btn-action btn-sm btn-icon btn-blue" data-id="tagClick"><span title=' + val.typeName + ' >' + val.typeName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="tag" title="Remove Tag"></i></span>';
});
_.each(tag.propagated, function(val) {
var crossButton = '<i class="fa fa-close" data-id="deleteTag" data-entityguid="' + val.entityGuid + '" data-type="tag" title="Remove Tag"></i>';
......
......@@ -51,11 +51,20 @@ define(['require',
selectDepth: 'select[data-id="selectDepth"]',
fltrTogler: '[data-id="fltr-togler"]',
lineageFilterPanel: '.lineage-fltr-panel',
LineageFullscreenToggler: '[data-id="fullScreen-toggler"]',
lineageFullscreenToggler: '[data-id="fullScreen-toggler"]',
searchTogler: '[data-id="search-togler"]',
lineageSearchPanel: '.lineage-search-panel',
lineageTypeSearch: '[data-id="typeSearch"]',
lineageDetailClose: '[data-id="close"]',
searchNode: '[data-id="searchNode"]',
nodeEntityList: '[data-id="entityList"]'
},
templateHelpers: function() {
return {
width: "100%",
height: "100%"
};
},
/** ui events hash */
events: function() {
var events = {};
......@@ -63,7 +72,8 @@ define(['require',
events["click " + this.ui.checkDeletedEntity] = 'onCheckUnwantedEntity';
events['change ' + this.ui.selectDepth] = 'onSelectDepthChange';
events["click " + this.ui.fltrTogler] = 'onClickFiltrTogler';
events["click " + this.ui.LineageFullscreenToggler] = 'onClickLineageFullscreenToggler';
events["click " + this.ui.lineageFullscreenToggler] = 'onClickLineageFullscreenToggler';
events["click " + this.ui.searchTogler] = 'onClickSearchTogler';
events["click " + this.ui.lineageDetailClose] = function() {
this.toggleLineageInfomationSlider({ close: true });
};
......@@ -87,6 +97,9 @@ define(['require',
isDeletedEntityHideCheck: false,
depthCount: ''
};
this.searchNodeObj = {
selectedNode: ''
}
},
initializeGraph: function() {
......@@ -156,7 +169,20 @@ define(['require',
},
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")
}
},
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");
}
},
onSelectDepthChange: function(e, options) {
this.initializeGraph();
......@@ -344,6 +370,10 @@ define(['require',
if (this.asyncFetchCounter == 0) {
this.createGraph();
}
if (this.lineageData) {
this.renderLineageTypeSearch();
this.lineageTypeSearch()
}
},
checkForLineageOrImpactFlag: function(relations, guid) {
var that = this,
......@@ -372,31 +402,28 @@ define(['require',
this.$('.lineage-edge-details').removeClass('open');
}
},
setGraphZoomPositionCal: function(argument) {
var initialScale = 1.6,
svgEl = this.$('svg'),
scaleEl = this.$('svg').find('>g'),
translateValue = [(this.$('svg').width() - this.g.graph().width * initialScale) / 2, (this.$('svg').height() - this.g.graph().height * initialScale) / 2]
if (_.keys(this.g._nodes).length > 15) {
initialScale = 0;
this.$('svg').addClass('noScale');
}
if (svgEl.parents('.panel.panel-fullscreen').length) {
translateValue = [20, 20];
if (svgEl.hasClass('noScale')) {
if (!scaleEl.hasClass('scaleLinage')) {
scaleEl.addClass('scaleLinage');
initialScale = 1.6;
} else {
scaleEl.removeClass('scaleLinage');
initialScale = 0;
}
}
} else {
scaleEl.removeClass('scaleLinage');
}
this.zoom.translate(translateValue)
.scale(initialScale);
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(),
viewerHeight = this.$('svg').height(),
gBBox = d3.select('g').node().getBBox(),
zoomListener = d3.behavior.zoom().scaleExtent([0.01, 50]).on("zoom", zoom),
scale = 1.2,
xa = -((x * scale) - (viewerWidth / 2)),
ya = -((y * scale) - (viewerHeight / 2));
this.zoom.translate([xa, ya]);
d3.select('g').transition()
.duration(350)
.attr("transform", "translate(" + xa + "," + ya + ")scale(" + scale + ")");
zoomListener.scale(scale);
zoomListener.translate([xa, ya]);
this.zoom.scale(scale);
},
zoomed: function(that) {
this.$('svg').find('>g').attr("transform",
......@@ -404,6 +431,18 @@ define(['require',
"scale(" + this.zoom.scale() + ")"
);
},
interpolateZoom: function(translate, scale, that, zoom) {
return d3.transition().duration(350).tween("zoom", function() {
var iTranslate = d3.interpolate(zoom.translate(), translate),
iScale = d3.interpolate(zoom.scale(), scale);
return function(t) {
zoom
.scale(iScale(t))
.translate(iTranslate(t));
that.zoomed();
};
});
},
createGraph: function() {
var that = this,
width = this.$('svg').width(),
......@@ -442,7 +481,7 @@ define(['require',
var shapeSvg = parent.append('circle')
.attr('fill', 'url(#img_' + node.id + ')')
.attr('r', '24px')
.attr('data-stroke',node.id)
.attr('data-stroke', node.id)
.attr("class", "nodeImage " + (currentNode ? "currentNode" : (node.isProcess ? "process" : "node")));
parent.insert("defs")
......@@ -481,31 +520,16 @@ define(['require',
.attr("enable-background", "new 0 0 " + width + " " + height),
svgGroup = svg.append("g");
var zoom = this.zoom = d3.behavior.zoom()
.scaleExtent([0.5, 6])
.center([width / 2, height / 2])
.scaleExtent([0.01, 50])
.on("zoom", that.zoomed.bind(this));
function interpolateZoom(translate, scale) {
var self = this;
return d3.transition().duration(350).tween("zoom", function() {
var iTranslate = d3.interpolate(zoom.translate(), translate),
iScale = d3.interpolate(zoom.scale(), scale);
return function(t) {
zoom
.scale(iScale(t))
.translate(iTranslate(t));
that.zoomed();
};
});
}
function zoomClick() {
var clicked = d3.event.target,
direction = 1,
factor = 0.2,
factor = 0.5,
target_zoom = 1,
center = [that.g.graph().width / 2, that.g.graph().height / 2],
extent = zoom.scaleExtent(),
center = [width / 2, height / 2],
translate = zoom.translate(),
translate0 = [],
l = [],
......@@ -515,10 +539,6 @@ define(['require',
direction = (this.id === 'zoom_in') ? 1 : -1;
target_zoom = zoom.scale() * (1 + factor * direction);
if (target_zoom < extent[0] || target_zoom > extent[1]) {
return false;
}
translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
view.k = target_zoom;
l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];
......@@ -526,7 +546,7 @@ define(['require',
view.x += center[0] - l[0];
view.y += center[1] - l[1];
interpolateZoom([view.x, view.y], view.k);
that.interpolateZoom([view.x, view.y], view.k, that, zoom);
}
d3.selectAll(this.$('.lineageZoomButton')).on('click', zoomClick);
var tooltip = d3Tip()
......@@ -555,7 +575,7 @@ define(['require',
}
render(svgGroup, this.g);
svg.on("dblclick.zoom", null)
.on("wheel.zoom", null);
// .on("wheel.zoom", null);
//change text postion
svgGroup.selectAll("g.nodes g.label")
.attr("transform", "translate(2,-35)");
......@@ -605,8 +625,8 @@ define(['require',
}).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) {
svgGroup.selectAll('[data-stroke]').attr('stroke', 'none');
svgGroup.selectAll('[data-stroke]').attr('stroke', function(c) {
if (c == d) {
return "#316132";
} else {
......@@ -639,7 +659,7 @@ define(['require',
});
// Center the graph
this.setGraphZoomPositionCal();
this.centerNode(that.guid);
zoom.event(svg);
//svg.attr('height', this.g.graph().height * initialScale + 40);
if (platform.name === "IE") {
......@@ -660,6 +680,60 @@ define(['require',
});
}
},
renderLineageTypeSearch: function() {
var that = this;
var lineageData = $.extend(true, {}, this.lineageData);
var data = [];
var typeStr = '<option></option>';
if (!_.isEmpty(lineageData)) {
_.each(lineageData.guidEntityMap, function(obj, index) {
typeStr += '<option value="' + obj.guid + '">' + obj.attributes.name + '</option>';
});
}
that.ui.lineageTypeSearch.html(typeStr);
},
lineageTypeSearch: function() {
var that = this;
that.ui.lineageTypeSearch.select2({
closeOnSelect: true,
placeholder: 'Select Node'
}).on('change.select2', function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
d3.selectAll(".serach-rect").remove();
var selectedNode = $('[data-id="typeSearch"]').val();
that.searchNodeObj.selectedNode = $('[data-id="typeSearch"]').val();
that.centerNode(selectedNode);
that.svg.selectAll('.nodes g.label').attr('stroke', function(c, d) {
if (c == selectedNode) {
return "#316132";
} else {
return 'none';
}
});
// Using jquery for selector because d3 select is not working for few process entities.
d3.select($(".node#" + selectedNode)[0]).insert("rect", "circle")
.attr("class", "serach-rect")
.attr("x", -50)
.attr("y", -27.5)
.attr("width", 100)
.attr("height", 55);
d3.selectAll(".nodes circle").classed("wobble", function(d, i, nodes) {
if (d == selectedNode) {
return true;
} else {
return false;
}
});
});
if (that.searchNodeObj.selectedNode) {
that.ui.lineageTypeSearch.val(that.searchNodeObj.selectedNode);
that.ui.lineageTypeSearch.trigger("change.select2");
}
},
toggleLineageInfomationSlider: function(options) {
if (options.open && !this.$('.lineage-details').hasClass("open")) {
this.$('.lineage-details').addClass('open');
......
......@@ -465,11 +465,11 @@ define(['require',
var name = Utils.getName(model.toJSON(), 'name');
if (model.get('category') == 'ENTITY' && (serviceTypeToBefiltered && serviceTypeToBefiltered.length ? _.contains(serviceTypeToBefiltered, model.get('serviceType')) : true)) {
var entityCount = (that.entityCountObj.entity.entityActive[name] + (that.entityCountObj.entity.entityDeleted[name] ? that.entityCountObj.entity.entityDeleted[name] : 0));
typeStr += '<option value="' + (name) + '" data-name="' + (name) + '">' + (name) + ' ' + (entityCount ? "(" + entityCount + ")" : '') + '</option>';
typeStr += '<option value="' + (name) + '" data-name="' + (name) + '">' + (name) + ' ' + (entityCount ? "(" + _.numberFormatWithComa(entityCount) + ")" : '') + '</option>';
}
if (isTypeOnly == undefined && model.get('category') == 'CLASSIFICATION') {
var tagEntityCount = that.entityCountObj.tag.tagEntities[name];
tagStr += '<option value="' + (name) + '" data-name="' + (name) + '">' + (name) + ' ' + (tagEntityCount ? "(" + tagEntityCount + ")" : '') + '</option>';
tagStr += '<option value="' + (name) + '" data-name="' + (name) + '">' + (name) + ' ' + (tagEntityCount ? "(" + _.numberFormatWithComa(tagEntityCount) + ")" : '') + '</option>';
}
});
if (_.isUndefined(isTypeOnly)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment