@hpcc-js/api 2.14.2 → 2.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Tooltip.ts CHANGED
@@ -1,386 +1,386 @@
1
- // Based on https://github.com/GordonSmith/d3-tip forked from https://github.com/Caged/d3-tip
2
-
3
- import { map } from "d3-collection";
4
- import { select, selection } from "d3-selection";
5
-
6
- export function tip() {
7
- let direction = d3TipDirection;
8
- let offset = d3TipOffset;
9
- let html = d3TipHTML;
10
- let rootElement = functor(document.body);
11
- let node = initNode();
12
- let svg = null;
13
- let point = null;
14
- let target = null;
15
-
16
- const tip: any = function (vis) {
17
- svg = getSVGNode(vis);
18
- if (!svg) return;
19
- point = svg.createSVGPoint();
20
- const re = rootElement();
21
- if (!re) return;
22
- if (!node) return;
23
- re.appendChild(node);
24
- };
25
-
26
- // Public - show the tooltip on the screen
27
- //
28
- // Returns a tip
29
- tip.show = function (d, idx, arr) {
30
- target = arr[idx];
31
- const args = Array.prototype.slice.call(arguments);
32
- const content = html.apply(this, args);
33
- if (content === null) {
34
- return tip;
35
- }
36
- const poffset = offset.apply(this, args);
37
- const nodel = getNodeEl();
38
- let i = directions.length;
39
- let coords;
40
- const root_bbox = rootElement().getBoundingClientRect();
41
- nodel.html(content)
42
- .style("opacity", 1).style("pointer-events", "all");
43
-
44
- while (i--) nodel.classed(directions[i], false);
45
- let placement_success = false;
46
- const placement_overflow = {};
47
- let least_overflow_direction = directions[0];
48
- for (let i = 0; i < directions.length; i++) {
49
- placement_success = _placement_attempt(directions[i]);
50
- if (placement_success) break;
51
- }
52
- if (!placement_success) {
53
- nodel.classed("notick", true);
54
- const top_offset = _vertical_adjustment(placement_overflow[least_overflow_direction]);
55
- const left_offset = _horizontal_adjustment(placement_overflow[least_overflow_direction]);
56
- _placement_attempt(least_overflow_direction, top_offset, left_offset);
57
- } else {
58
- nodel.classed("notick", false);
59
- }
60
- return tip;
61
-
62
- function _horizontal_adjustment(overflow_obj) {
63
- if (overflow_obj.left > overflow_obj.right) {
64
- return overflow_obj.left > 0 ? -overflow_obj.left : 0;
65
- } else {
66
- return overflow_obj.right > 0 ? overflow_obj.right : 0;
67
- }
68
- }
69
- function _vertical_adjustment(overflow_obj) {
70
- if (overflow_obj.top > overflow_obj.bottom) {
71
- return overflow_obj.top > 0 ? -overflow_obj.top : 0;
72
- } else {
73
- return overflow_obj.bottom;
74
- }
75
- }
76
-
77
- function _placement_attempt(_dir, _top_offset?, _left_offset?) {
78
- _top_offset = _top_offset ? _top_offset : 0;
79
- _left_offset = _left_offset ? _left_offset : 0;
80
- nodel.style("white-space", "nowrap");
81
- coords = directionCallbacks.get(_dir).apply(this);
82
- nodel.classed(_dir, true)
83
- .style("top", (coords.top + poffset[0] - _top_offset) + "px")
84
- .style("left", (coords.left + poffset[1] - _left_offset) + "px");
85
- const nodel_bbox = nodel.node().getBoundingClientRect();
86
- const ret = nodel_bbox.top > root_bbox.top
87
- && nodel_bbox.left > root_bbox.left
88
- && nodel_bbox.bottom < root_bbox.bottom
89
- && nodel_bbox.right < root_bbox.right
90
- ;
91
- placement_overflow[_dir] = {
92
- top: root_bbox.top - nodel_bbox.top,
93
- right: nodel_bbox.right - root_bbox.right,
94
- bottom: nodel_bbox.bottom - root_bbox.bottom,
95
- left: root_bbox.left - nodel_bbox.left
96
- };
97
- nodel.style("white-space", "normal");
98
- placement_overflow[_dir].total_overflow = Object.keys(placement_overflow[_dir])
99
- .filter(side => placement_overflow[_dir][side] > 0)
100
- .reduce((sum, side) => {
101
- const side_overflow = placement_overflow[_dir][side];
102
- return sum + side_overflow;
103
- }, 0);
104
- if (placement_overflow[least_overflow_direction].total_overflow > placement_overflow[_dir].total_overflow) {
105
- least_overflow_direction = _dir;
106
- }
107
- if (!ret) {
108
- nodel.classed(_dir, false);
109
- }
110
- return ret;
111
- }
112
- };
113
-
114
- // Public - hide the tooltip
115
- //
116
- // Returns a tip
117
- tip.hide = function () {
118
- const nodel = getNodeEl();
119
- nodel.style("opacity", 0).style("pointer-events", "none");
120
- return tip;
121
- };
122
-
123
- // Public: Proxy attr calls to the d3 tip container.
124
- // Sets or gets attribute value.
125
- //
126
- // n - name of the attribute
127
- // v - value of the attribute
128
- //
129
- // Returns tip or attribute value
130
- // eslint-disable-next-line no-unused-vars
131
- tip.attr = function (n, v) {
132
- if (arguments.length < 2 && typeof n === "string") {
133
- return getNodeEl().attr(n);
134
- }
135
-
136
- const args = Array.prototype.slice.call(arguments);
137
- selection.prototype.attr.apply(getNodeEl(), args);
138
- return tip;
139
- };
140
-
141
- // Public: Proxy style calls to the d3 tip container.
142
- // Sets or gets a style value.
143
- //
144
- // n - name of the property
145
- // v - value of the property
146
- //
147
- // Returns tip or style property value
148
- // eslint-disable-next-line no-unused-vars
149
- tip.style = function (n, v) {
150
- if (arguments.length < 2 && typeof n === "string") {
151
- return getNodeEl().style(n);
152
- }
153
-
154
- const args = Array.prototype.slice.call(arguments);
155
- selection.prototype.style.apply(getNodeEl(), args);
156
- return tip;
157
- };
158
-
159
- // Public: Set or get the direction of the tooltip
160
- //
161
- // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
162
- // sw(southwest), ne(northeast) or se(southeast)
163
- //
164
- // Returns tip or direction
165
- tip.direction = function (v) {
166
- if (!arguments.length) return direction;
167
- direction = v == null ? v : functor(v);
168
-
169
- return tip;
170
- };
171
-
172
- // Public: Sets or gets the offset of the tip
173
- //
174
- // v - Array of [x, y] offset
175
- //
176
- // Returns offset or
177
- tip.offset = function (v) {
178
- if (!arguments.length) return offset;
179
- offset = v == null ? v : functor(v);
180
-
181
- return tip;
182
- };
183
-
184
- // Public: sets or gets the html value of the tooltip
185
- //
186
- // v - String value of the tip
187
- //
188
- // Returns html value or tip
189
- tip.html = function (v) {
190
- if (!arguments.length) return html;
191
- html = v == null ? v : functor(v);
192
-
193
- return tip;
194
- };
195
-
196
- // Public: sets or gets the root element anchor of the tooltip
197
- //
198
- // v - root element of the tooltip
199
- //
200
- // Returns root node of tip
201
- tip.rootElement = function (v) {
202
- if (!arguments.length) return rootElement;
203
- rootElement = functor(v);
204
-
205
- return tip;
206
- };
207
-
208
- // Public: destroys the tooltip and removes it from the DOM
209
- //
210
- // Returns a tip
211
- tip.destroy = function () {
212
- if (node) {
213
- getNodeEl().remove();
214
- node = null;
215
- }
216
- return tip;
217
- };
218
-
219
- function d3TipDirection() { return "n"; }
220
- function d3TipOffset() { return [0, 0]; }
221
- function d3TipHTML() { return " "; }
222
-
223
- const directionCallbacks = map({
224
- n: directionNorth,
225
- s: directionSouth,
226
- e: directionEast,
227
- w: directionWest,
228
- nw: directionNorthWest,
229
- ne: directionNorthEast,
230
- sw: directionSouthWest,
231
- se: directionSouthEast
232
- });
233
- const directions = directionCallbacks.keys();
234
-
235
- function directionNorth() {
236
- const bbox = getScreenBBox(window);
237
- return {
238
- top: bbox.n.y - node.offsetHeight,
239
- left: bbox.n.x - node.offsetWidth / 2
240
- };
241
- }
242
-
243
- function directionSouth() {
244
- const bbox = getScreenBBox(window);
245
- return {
246
- top: bbox.s.y + 8,
247
- left: bbox.s.x - node.offsetWidth / 2
248
- };
249
- }
250
-
251
- function directionEast() {
252
- const bbox = getScreenBBox(window);
253
- return {
254
- top: bbox.e.y - node.offsetHeight / 2,
255
- left: bbox.e.x + 8
256
- };
257
- }
258
-
259
- function directionWest() {
260
- const bbox = getScreenBBox(window);
261
- return {
262
- top: bbox.w.y - node.offsetHeight / 2,
263
- left: bbox.w.x - node.offsetWidth - 8
264
- };
265
- }
266
-
267
- function directionNorthWest() {
268
- const bbox = getScreenBBox(window);
269
- return {
270
- top: bbox.nw.y - node.offsetHeight,
271
- left: bbox.nw.x - node.offsetWidth
272
- };
273
- }
274
-
275
- function directionNorthEast() {
276
- const bbox = getScreenBBox(window);
277
- return {
278
- top: bbox.ne.y - node.offsetHeight,
279
- left: bbox.ne.x
280
- };
281
- }
282
-
283
- function directionSouthWest() {
284
- const bbox = getScreenBBox(window);
285
- return {
286
- top: bbox.sw.y,
287
- left: bbox.sw.x - node.offsetWidth
288
- };
289
- }
290
-
291
- function directionSouthEast() {
292
- const bbox = getScreenBBox(window);
293
- return {
294
- top: bbox.se.y,
295
- left: bbox.se.x
296
- };
297
- }
298
-
299
- function initNode() {
300
- const div = select(document.createElement("div"));
301
- div
302
- .attr("class", "d3-tip")
303
- .style("position", "absolute")
304
- .style("top", "0px")
305
- .style("opacity", 0)
306
- .style("pointer-events", "none")
307
- .style("box-sizing", "border-box");
308
-
309
- return div.node();
310
- }
311
-
312
- function getSVGNode(element) {
313
- const svgNode = element.node();
314
- if (!svgNode) return null;
315
- if (svgNode.tagName.toLowerCase() === "svg") return svgNode;
316
- return svgNode.ownerSVGElement;
317
- }
318
-
319
- function getNodeEl() {
320
- if (node == null) {
321
- node = initNode();
322
- // re-add node to DOM
323
- rootElement().appendChild(node);
324
- }
325
- return select(node);
326
- }
327
-
328
- // Private - gets the screen coordinates of a shape
329
- //
330
- // Given a shape on the screen, will return an SVGPoint for the directions
331
- // n(north), s(south), e(east), w(west), ne(northeast), se(southeast),
332
- // nw(northwest), sw(southwest).
333
- //
334
- // +-+-+
335
- // | |
336
- // + +
337
- // | |
338
- // +-+-+
339
- //
340
- // Returns an Object {n, s, e, w, nw, sw, ne, se}
341
- function getScreenBBox(targetShape) {
342
- let targetel = target || targetShape;
343
-
344
- while (targetel.getCTM == null && targetel.parentNode != null) {
345
- targetel = targetel.parentNode;
346
- }
347
-
348
- const bbox: any = {};
349
- const matrix = targetel.getCTM();
350
- const tbbox = targetel.getBBox();
351
- const width = tbbox.width;
352
- const height = tbbox.height;
353
- const x = tbbox.x;
354
- const y = tbbox.y;
355
-
356
- point.x = x;
357
- point.y = y;
358
- bbox.nw = point.matrixTransform(matrix);
359
- point.x += width;
360
- bbox.ne = point.matrixTransform(matrix);
361
- point.y += height;
362
- bbox.se = point.matrixTransform(matrix);
363
- point.x -= width;
364
- bbox.sw = point.matrixTransform(matrix);
365
- point.y -= height / 2;
366
- bbox.w = point.matrixTransform(matrix);
367
- point.x += width;
368
- bbox.e = point.matrixTransform(matrix);
369
- point.x -= width / 2;
370
- point.y -= height / 2;
371
- bbox.n = point.matrixTransform(matrix);
372
- point.y += height;
373
- bbox.s = point.matrixTransform(matrix);
374
-
375
- return bbox;
376
- }
377
-
378
- // Private - replace D3JS 3.X d3.functor() function
379
- function functor(v) {
380
- return typeof v === "function" ? v : function () {
381
- return v;
382
- };
383
- }
384
-
385
- return tip;
386
- }
1
+ // Based on https://github.com/GordonSmith/d3-tip forked from https://github.com/Caged/d3-tip
2
+
3
+ import { map } from "d3-collection";
4
+ import { select, selection } from "d3-selection";
5
+
6
+ export function tip() {
7
+ let direction = d3TipDirection;
8
+ let offset = d3TipOffset;
9
+ let html = d3TipHTML;
10
+ let rootElement = functor(document.body);
11
+ let node = initNode();
12
+ let svg = null;
13
+ let point = null;
14
+ let target = null;
15
+
16
+ const tip: any = function (vis) {
17
+ svg = getSVGNode(vis);
18
+ if (!svg) return;
19
+ point = svg.createSVGPoint();
20
+ const re = rootElement();
21
+ if (!re) return;
22
+ if (!node) return;
23
+ re.appendChild(node);
24
+ };
25
+
26
+ // Public - show the tooltip on the screen
27
+ //
28
+ // Returns a tip
29
+ tip.show = function (d, idx, arr) {
30
+ target = arr[idx];
31
+ const args = Array.prototype.slice.call(arguments);
32
+ const content = html.apply(this, args);
33
+ if (content === null) {
34
+ return tip;
35
+ }
36
+ const poffset = offset.apply(this, args);
37
+ const nodel = getNodeEl();
38
+ let i = directions.length;
39
+ let coords;
40
+ const root_bbox = rootElement().getBoundingClientRect();
41
+ nodel.html(content)
42
+ .style("opacity", 1).style("pointer-events", "all");
43
+
44
+ while (i--) nodel.classed(directions[i], false);
45
+ let placement_success = false;
46
+ const placement_overflow = {};
47
+ let least_overflow_direction = directions[0];
48
+ for (let i = 0; i < directions.length; i++) {
49
+ placement_success = _placement_attempt(directions[i]);
50
+ if (placement_success) break;
51
+ }
52
+ if (!placement_success) {
53
+ nodel.classed("notick", true);
54
+ const top_offset = _vertical_adjustment(placement_overflow[least_overflow_direction]);
55
+ const left_offset = _horizontal_adjustment(placement_overflow[least_overflow_direction]);
56
+ _placement_attempt(least_overflow_direction, top_offset, left_offset);
57
+ } else {
58
+ nodel.classed("notick", false);
59
+ }
60
+ return tip;
61
+
62
+ function _horizontal_adjustment(overflow_obj) {
63
+ if (overflow_obj.left > overflow_obj.right) {
64
+ return overflow_obj.left > 0 ? -overflow_obj.left : 0;
65
+ } else {
66
+ return overflow_obj.right > 0 ? overflow_obj.right : 0;
67
+ }
68
+ }
69
+ function _vertical_adjustment(overflow_obj) {
70
+ if (overflow_obj.top > overflow_obj.bottom) {
71
+ return overflow_obj.top > 0 ? -overflow_obj.top : 0;
72
+ } else {
73
+ return overflow_obj.bottom;
74
+ }
75
+ }
76
+
77
+ function _placement_attempt(_dir, _top_offset?, _left_offset?) {
78
+ _top_offset = _top_offset ? _top_offset : 0;
79
+ _left_offset = _left_offset ? _left_offset : 0;
80
+ nodel.style("white-space", "nowrap");
81
+ coords = directionCallbacks.get(_dir).apply(this);
82
+ nodel.classed(_dir, true)
83
+ .style("top", (coords.top + poffset[0] - _top_offset) + "px")
84
+ .style("left", (coords.left + poffset[1] - _left_offset) + "px");
85
+ const nodel_bbox = nodel.node().getBoundingClientRect();
86
+ const ret = nodel_bbox.top > root_bbox.top
87
+ && nodel_bbox.left > root_bbox.left
88
+ && nodel_bbox.bottom < root_bbox.bottom
89
+ && nodel_bbox.right < root_bbox.right
90
+ ;
91
+ placement_overflow[_dir] = {
92
+ top: root_bbox.top - nodel_bbox.top,
93
+ right: nodel_bbox.right - root_bbox.right,
94
+ bottom: nodel_bbox.bottom - root_bbox.bottom,
95
+ left: root_bbox.left - nodel_bbox.left
96
+ };
97
+ nodel.style("white-space", "normal");
98
+ placement_overflow[_dir].total_overflow = Object.keys(placement_overflow[_dir])
99
+ .filter(side => placement_overflow[_dir][side] > 0)
100
+ .reduce((sum, side) => {
101
+ const side_overflow = placement_overflow[_dir][side];
102
+ return sum + side_overflow;
103
+ }, 0);
104
+ if (placement_overflow[least_overflow_direction].total_overflow > placement_overflow[_dir].total_overflow) {
105
+ least_overflow_direction = _dir;
106
+ }
107
+ if (!ret) {
108
+ nodel.classed(_dir, false);
109
+ }
110
+ return ret;
111
+ }
112
+ };
113
+
114
+ // Public - hide the tooltip
115
+ //
116
+ // Returns a tip
117
+ tip.hide = function () {
118
+ const nodel = getNodeEl();
119
+ nodel.style("opacity", 0).style("pointer-events", "none");
120
+ return tip;
121
+ };
122
+
123
+ // Public: Proxy attr calls to the d3 tip container.
124
+ // Sets or gets attribute value.
125
+ //
126
+ // n - name of the attribute
127
+ // v - value of the attribute
128
+ //
129
+ // Returns tip or attribute value
130
+ // eslint-disable-next-line no-unused-vars
131
+ tip.attr = function (n, v) {
132
+ if (arguments.length < 2 && typeof n === "string") {
133
+ return getNodeEl().attr(n);
134
+ }
135
+
136
+ const args = Array.prototype.slice.call(arguments);
137
+ selection.prototype.attr.apply(getNodeEl(), args);
138
+ return tip;
139
+ };
140
+
141
+ // Public: Proxy style calls to the d3 tip container.
142
+ // Sets or gets a style value.
143
+ //
144
+ // n - name of the property
145
+ // v - value of the property
146
+ //
147
+ // Returns tip or style property value
148
+ // eslint-disable-next-line no-unused-vars
149
+ tip.style = function (n, v) {
150
+ if (arguments.length < 2 && typeof n === "string") {
151
+ return getNodeEl().style(n);
152
+ }
153
+
154
+ const args = Array.prototype.slice.call(arguments);
155
+ selection.prototype.style.apply(getNodeEl(), args);
156
+ return tip;
157
+ };
158
+
159
+ // Public: Set or get the direction of the tooltip
160
+ //
161
+ // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
162
+ // sw(southwest), ne(northeast) or se(southeast)
163
+ //
164
+ // Returns tip or direction
165
+ tip.direction = function (v) {
166
+ if (!arguments.length) return direction;
167
+ direction = v == null ? v : functor(v);
168
+
169
+ return tip;
170
+ };
171
+
172
+ // Public: Sets or gets the offset of the tip
173
+ //
174
+ // v - Array of [x, y] offset
175
+ //
176
+ // Returns offset or
177
+ tip.offset = function (v) {
178
+ if (!arguments.length) return offset;
179
+ offset = v == null ? v : functor(v);
180
+
181
+ return tip;
182
+ };
183
+
184
+ // Public: sets or gets the html value of the tooltip
185
+ //
186
+ // v - String value of the tip
187
+ //
188
+ // Returns html value or tip
189
+ tip.html = function (v) {
190
+ if (!arguments.length) return html;
191
+ html = v == null ? v : functor(v);
192
+
193
+ return tip;
194
+ };
195
+
196
+ // Public: sets or gets the root element anchor of the tooltip
197
+ //
198
+ // v - root element of the tooltip
199
+ //
200
+ // Returns root node of tip
201
+ tip.rootElement = function (v) {
202
+ if (!arguments.length) return rootElement;
203
+ rootElement = functor(v);
204
+
205
+ return tip;
206
+ };
207
+
208
+ // Public: destroys the tooltip and removes it from the DOM
209
+ //
210
+ // Returns a tip
211
+ tip.destroy = function () {
212
+ if (node) {
213
+ getNodeEl().remove();
214
+ node = null;
215
+ }
216
+ return tip;
217
+ };
218
+
219
+ function d3TipDirection() { return "n"; }
220
+ function d3TipOffset() { return [0, 0]; }
221
+ function d3TipHTML() { return " "; }
222
+
223
+ const directionCallbacks = map({
224
+ n: directionNorth,
225
+ s: directionSouth,
226
+ e: directionEast,
227
+ w: directionWest,
228
+ nw: directionNorthWest,
229
+ ne: directionNorthEast,
230
+ sw: directionSouthWest,
231
+ se: directionSouthEast
232
+ });
233
+ const directions = directionCallbacks.keys();
234
+
235
+ function directionNorth() {
236
+ const bbox = getScreenBBox(window);
237
+ return {
238
+ top: bbox.n.y - node.offsetHeight,
239
+ left: bbox.n.x - node.offsetWidth / 2
240
+ };
241
+ }
242
+
243
+ function directionSouth() {
244
+ const bbox = getScreenBBox(window);
245
+ return {
246
+ top: bbox.s.y + 8,
247
+ left: bbox.s.x - node.offsetWidth / 2
248
+ };
249
+ }
250
+
251
+ function directionEast() {
252
+ const bbox = getScreenBBox(window);
253
+ return {
254
+ top: bbox.e.y - node.offsetHeight / 2,
255
+ left: bbox.e.x + 8
256
+ };
257
+ }
258
+
259
+ function directionWest() {
260
+ const bbox = getScreenBBox(window);
261
+ return {
262
+ top: bbox.w.y - node.offsetHeight / 2,
263
+ left: bbox.w.x - node.offsetWidth - 8
264
+ };
265
+ }
266
+
267
+ function directionNorthWest() {
268
+ const bbox = getScreenBBox(window);
269
+ return {
270
+ top: bbox.nw.y - node.offsetHeight,
271
+ left: bbox.nw.x - node.offsetWidth
272
+ };
273
+ }
274
+
275
+ function directionNorthEast() {
276
+ const bbox = getScreenBBox(window);
277
+ return {
278
+ top: bbox.ne.y - node.offsetHeight,
279
+ left: bbox.ne.x
280
+ };
281
+ }
282
+
283
+ function directionSouthWest() {
284
+ const bbox = getScreenBBox(window);
285
+ return {
286
+ top: bbox.sw.y,
287
+ left: bbox.sw.x - node.offsetWidth
288
+ };
289
+ }
290
+
291
+ function directionSouthEast() {
292
+ const bbox = getScreenBBox(window);
293
+ return {
294
+ top: bbox.se.y,
295
+ left: bbox.se.x
296
+ };
297
+ }
298
+
299
+ function initNode() {
300
+ const div = select(document.createElement("div"));
301
+ div
302
+ .attr("class", "d3-tip")
303
+ .style("position", "absolute")
304
+ .style("top", "0px")
305
+ .style("opacity", 0)
306
+ .style("pointer-events", "none")
307
+ .style("box-sizing", "border-box");
308
+
309
+ return div.node();
310
+ }
311
+
312
+ function getSVGNode(element) {
313
+ const svgNode = element.node();
314
+ if (!svgNode) return null;
315
+ if (svgNode.tagName.toLowerCase() === "svg") return svgNode;
316
+ return svgNode.ownerSVGElement;
317
+ }
318
+
319
+ function getNodeEl() {
320
+ if (node == null) {
321
+ node = initNode();
322
+ // re-add node to DOM
323
+ rootElement().appendChild(node);
324
+ }
325
+ return select(node);
326
+ }
327
+
328
+ // Private - gets the screen coordinates of a shape
329
+ //
330
+ // Given a shape on the screen, will return an SVGPoint for the directions
331
+ // n(north), s(south), e(east), w(west), ne(northeast), se(southeast),
332
+ // nw(northwest), sw(southwest).
333
+ //
334
+ // +-+-+
335
+ // | |
336
+ // + +
337
+ // | |
338
+ // +-+-+
339
+ //
340
+ // Returns an Object {n, s, e, w, nw, sw, ne, se}
341
+ function getScreenBBox(targetShape) {
342
+ let targetel = target || targetShape;
343
+
344
+ while (targetel.getCTM == null && targetel.parentNode != null) {
345
+ targetel = targetel.parentNode;
346
+ }
347
+
348
+ const bbox: any = {};
349
+ const matrix = targetel.getCTM();
350
+ const tbbox = targetel.getBBox();
351
+ const width = tbbox.width;
352
+ const height = tbbox.height;
353
+ const x = tbbox.x;
354
+ const y = tbbox.y;
355
+
356
+ point.x = x;
357
+ point.y = y;
358
+ bbox.nw = point.matrixTransform(matrix);
359
+ point.x += width;
360
+ bbox.ne = point.matrixTransform(matrix);
361
+ point.y += height;
362
+ bbox.se = point.matrixTransform(matrix);
363
+ point.x -= width;
364
+ bbox.sw = point.matrixTransform(matrix);
365
+ point.y -= height / 2;
366
+ bbox.w = point.matrixTransform(matrix);
367
+ point.x += width;
368
+ bbox.e = point.matrixTransform(matrix);
369
+ point.x -= width / 2;
370
+ point.y -= height / 2;
371
+ bbox.n = point.matrixTransform(matrix);
372
+ point.y += height;
373
+ bbox.s = point.matrixTransform(matrix);
374
+
375
+ return bbox;
376
+ }
377
+
378
+ // Private - replace D3JS 3.X d3.functor() function
379
+ function functor(v) {
380
+ return typeof v === "function" ? v : function () {
381
+ return v;
382
+ };
383
+ }
384
+
385
+ return tip;
386
+ }