UNPKG

13.6 kBJavaScriptView Raw
1import { a as __extends } from './tslib.es6-f952ba6f.js';
2import { U as Utils } from './Utils-38a0872e.js';
3import { select, selectAll, pointer } from 'd3';
4import { C as Component } from './Component-5173b5ea.js';
5
6var HierarchyNode = /** @class */ (function () {
7 function HierarchyNode(name, level) {
8 this.children = [];
9 this.isExpanded = false;
10 this.isSelected = false;
11 this.isLeaf = false;
12 this.childrenInFilter = false;
13 this.selfInFilter = false;
14 this.color = function () { return null; };
15 this.click = function (n) { };
16 this.isLeafParent = false; // used in the event of context menut to denote that we should use a context menu for children
17 this.name = name;
18 this.level = level;
19 this.markedName = name;
20 }
21 HierarchyNode.prototype.filter = function (filterText) {
22 var regExp = new RegExp(filterText, 'i');
23 var isInFilter = function (node) {
24 var childrenInFilter = node.children.reduce(function (p, c) {
25 p = isInFilter(c) || p;
26 return p;
27 }, false);
28 var selfInFilter = regExp.test(node.name);
29 node.markedName = selfInFilter ? Utils.mark(filterText, node.name) : node.name;
30 if (node.parent != null)
31 node.parent.childrenInFilter = (selfInFilter || childrenInFilter) && filterText.length > 0;
32 node.selfInFilter = selfInFilter && filterText.length > 0;
33 node.childrenInFilter = childrenInFilter && filterText.length > 0;
34 return childrenInFilter || selfInFilter;
35 };
36 isInFilter(this);
37 };
38 HierarchyNode.prototype.traverse = function (condition) {
39 var traversal = [];
40 if (condition(this))
41 traversal.push(this);
42 this.children.forEach(function (n) {
43 traversal = traversal.concat(n.traverse(condition));
44 });
45 return traversal;
46 };
47 HierarchyNode.prototype.colorify = function (el) {
48 if (this.isLeaf && this.isSelected && this.color(this))
49 el.style('background-color', this.color(this));
50 if (!this.isSelected && this.isLeaf)
51 el.style('background-color', null);
52 };
53 return HierarchyNode;
54}());
55
56var Hierarchy = /** @class */ (function (_super) {
57 __extends(Hierarchy, _super);
58 function Hierarchy(renderTarget) {
59 var _this = _super.call(this, renderTarget) || this;
60 _this.filterText = '';
61 _this.withContextMenu = false;
62 _this.expandCollapseList = function (node, el, isFromClick, event) {
63 if (isFromClick === void 0) { isFromClick = false; }
64 _this.closeContextMenu();
65 if (el.classed('tsi-expanded') && !(_this.withContextMenu && node.isLeafParent)) {
66 el.selectAll('ul').remove();
67 el.classed('tsi-expanded', false);
68 node.isExpanded = false;
69 }
70 else {
71 if (_this.withContextMenu && node.isLeafParent) {
72 if (_this.clickedNode != el.node()) {
73 _this.clickedNode = el.node();
74 _this.contextMenu = _this.hierarchyList.append('div');
75 node.children.filter(function (n) { return n.name[0] !== '~'; }).forEach(function (n) {
76 _this.contextMenu.append('div').text("" + n.name).on('click', function () { return n.click(n); });
77 });
78 _this.contextMenu.append('div').classed('tsi-break', true);
79 node.children.filter(function (n) { return n.name[0] === '~'; }).forEach(function (n) {
80 var noTildeName = n.name.slice(1);
81 _this.contextMenu.append('div').text("" + noTildeName).on('click', function () { return n.click(n); });
82 });
83 _this.contextMenu.classed('tsi-hierarchyContextMenu', true);
84 if (event) {
85 var mouseWrapper_1 = pointer(event, _this.hierarchyList.node());
86 var mouseElt_1 = pointer(event, el.node());
87 _this.contextMenu.attr('style', function () { return "top: " + (mouseWrapper_1[1] - mouseElt_1[1]) + "px"; });
88 }
89 el.classed('tsi-resultSelected', true);
90 _this.hierarchyList.selectAll('.tsi-noPad').on('scroll', function () { _this.closeContextMenu(); });
91 }
92 else {
93 _this.clickedNode = null;
94 }
95 }
96 else {
97 var list = el.append('ul');
98 node.children.forEach(function (n) {
99 if (isFromClick || n.selfInFilter || n.childrenInFilter || (node.isExpanded && _this.filterText.length == 0)) {
100 var self = _this;
101 var clickMethod = function () {
102 if (n.isLeaf) {
103 var parent = n.parent;
104 while (parent != this.root) {
105 parent.isExpanded = true;
106 parent = parent.parent;
107 }
108 n.isSelected = !n.isSelected;
109 n.click(n);
110 var selector = select(this);
111 n.colorify(selector);
112 selector.classed('tsi-selected', n.isSelected);
113 }
114 else {
115 self.expandCollapseList(n, select(this), true, event);
116 }
117 event.stopPropagation();
118 };
119 var li = list.append('li').classed('tsi-leaf', n.isLeaf)
120 .classed('tsi-leafParent', n.isLeafParent && _this.withContextMenu)
121 .classed('tsi-selected', n.isSelected).on('click', clickMethod);
122 li.append('span').classed('tsi-caret', true).attr('style', "left: " + (n.level - 1) * 18 + "px");
123 li.append('span').classed('tsi-markedName', true).html(n.markedName) // known unsafe usage of .html
124 .attr('style', "padding-left: " + (40 + (n.level - 1) * 18 - (n.isLeafParent && _this.withContextMenu ? 16 : 0)) + "px")
125 .attr('title', n.isLeafParent && _this.withContextMenu ? n.name : '');
126 n.colorify(li);
127 if ((n.isExpanded || n.childrenInFilter) && !n.isLeaf) {
128 _this.expandCollapseList(n, li, isFromClick, event);
129 }
130 }
131 });
132 node.isExpanded = (node.isExpanded || isFromClick) || (node == _this.root);
133 el.classed('tsi-expanded', true);
134 }
135 }
136 };
137 return _this;
138 }
139 Hierarchy.prototype.render = function (data, options) {
140 var _this = this;
141 var self = this;
142 var targetElement = select(this.renderTarget).classed('tsi-hierarchy', true);
143 targetElement.html('');
144 this.chartOptions.setOptions(options);
145 _super.prototype.themify.call(this, targetElement, this.chartOptions.theme);
146 this.withContextMenu = this.chartOptions.withContextMenu;
147 this.root = this.buildTree(data);
148 this.root.isExpanded = true;
149 select("html").on("click." + Utils.guid(), function (event) {
150 if (_this.clickedNode && event.target != _this.clickedNode && _this.contextMenu) {
151 _this.closeContextMenu();
152 _this.clickedNode = null;
153 }
154 });
155 var inputDebounceTimeout;
156 var filter = targetElement.append('div').classed('tsi-filterWrapper', true).append('input').attr('placeholder', 'Search...').on('input', function (event) {
157 var _this = this;
158 clearTimeout(inputDebounceTimeout);
159 inputDebounceTimeout = setTimeout(function () {
160 self.filterText = _this.value.trim();
161 if (self.filterText.length == 1)
162 return; // quick return for small sets
163 var splitFilterText = self.filterText.split('/');
164 self.root.filter(splitFilterText[0]);
165 if (splitFilterText.length > 1) {
166 for (var i = 1; i < splitFilterText.length; i++) {
167 if (splitFilterText[i].length) {
168 var nodesInFilter = self.root.traverse(function (n) { return n.selfInFilter; });
169 nodesInFilter.forEach(function (n) {
170 var markedName = n.markedName;
171 n.filter(splitFilterText[i], false);
172 n.markedName = markedName;
173 });
174 nodesInFilter.forEach(function (n) {
175 if (!n.childrenInFilter)
176 n.selfInFilter = false;
177 });
178 }
179 }
180 }
181 list.selectAll('ul').remove();
182 list.classed('tsi-expanded', false);
183 self.root.childrenInFilter = self.root.childrenInFilter || self.filterText.length == 0;
184 if (self.root.childrenInFilter == false)
185 list.append('ul').append('div').text(self.getString('No filter results'));
186 else
187 self.expandCollapseList(self.root, list, false, event);
188 list.select('ul').classed('tsi-noPad', true);
189 }, 250);
190 });
191 var navTabs = targetElement.append('div').classed('tsi-navTabWrapper', true);
192 var allTab = navTabs.append('div').classed('tsi-navTab tsi-selected', true).text(this.getString('All hierarchies'));
193 var selectedTab = navTabs.append('div').classed('tsi-navTab', true).text(this.getString('Selected'));
194 var list = targetElement.append('div').classed('tsi-hierarchyList', true);
195 this.hierarchyList = list;
196 allTab.on('click', function (event) {
197 if (!allTab.classed('tsi-selected')) {
198 allTab.classed('tsi-selected', true);
199 selectedTab.classed('tsi-selected', false);
200 list.html('').classed('tsi-expanded', false);
201 _this.expandCollapseList(_this.root, list, true, event);
202 list.select('ul').classed('tsi-noPad', true);
203 filter.attr('disabled', null);
204 }
205 });
206 selectedTab.on('click', function () {
207 if (!selectedTab.classed('tsi-selected')) {
208 allTab.classed('tsi-selected', false);
209 selectedTab.classed('tsi-selected', true);
210 list.html('');
211 var ul = list.append('ul').classed('tsi-noPad', true);
212 var leafs = _this.root.traverse(function (n) { return n.isSelected; });
213 leafs.forEach(function (n) {
214 var li = ul.append('li').classed('tsi-leaf', n.isLeaf).classed('tsi-selected', n.isSelected).on('click', function () {
215 n.isSelected = !n.isSelected;
216 select(this).classed('tsi-selected', n.isSelected);
217 n.click(n);
218 n.colorify(select(this));
219 });
220 li.append('span').text(n.name).classed('tsi-markedName', true);
221 n.colorify(li);
222 });
223 filter.attr('disabled', true);
224 }
225 });
226 this.expandCollapseList(this.root, list, false);
227 list.select('ul').classed('tsi-noPad', true);
228 };
229 Hierarchy.prototype.buildTree = function (data) {
230 var traverse = function (data, key, level, parent) {
231 if (parent === void 0) { parent = null; }
232 var node = new HierarchyNode(key, level);
233 node.parent = parent;
234 if (data.hasOwnProperty('$leaf')) {
235 node.isLeaf = true;
236 if (data.hasOwnProperty('click'))
237 node.click = data.click;
238 if (data.hasOwnProperty('color'))
239 node.color = data.color;
240 node.parent.isLeafParent = true;
241 }
242 else {
243 Object.keys(data).sort().forEach(function (k) {
244 node.children.push(traverse(data[k], k, level + 1, node));
245 });
246 }
247 return node;
248 };
249 return traverse(data, '', 0);
250 };
251 Hierarchy.prototype.closeContextMenu = function () {
252 if (this.contextMenu) {
253 this.contextMenu.remove();
254 }
255 selectAll('.tsi-resultSelected').classed('tsi-resultSelected', false);
256 };
257 return Hierarchy;
258}(Component));
259
260export { Hierarchy as H };