@hpcc-js/html 2.44.3 → 2.44.4

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.
@@ -1,385 +1,385 @@
1
- import { HTMLWidget } from "@hpcc-js/common";
2
- import { scopedLogger, ScopedLogging } from "@hpcc-js/util";
3
- import { select as d3Select } from "d3-selection";
4
-
5
- type Direction = "n" | "s" | "e" | "w" | "ne" | "nw" | "se" | "sw";
6
- type Position = { x: number, y: number };
7
- type DirectionalBBox = { [key in Direction]: Position; };
8
-
9
- type Rectangle = { top: number, left: number, width: number, height: number };
10
- export class HTMLTooltip extends HTMLWidget {
11
-
12
- public _triggerElement;
13
- public _contentNode;
14
- protected _prevContentNode;
15
-
16
- protected _tooltipElement;
17
- protected _arrowElement;
18
- protected _tooltipHTMLCallback = (data?) => "<b>_tooltipHTMLCallback is undefined</b>";
19
- protected _logger: ScopedLogging = scopedLogger("html/HTMLTooltip");
20
- constructor() {
21
- super();
22
- this.visible(false);
23
- }
24
-
25
- tooltipHTML(_: (data?) => string): this {
26
- this._tooltipHTMLCallback = _;
27
- return this;
28
- }
29
-
30
- tooltipContent(_): this {
31
- if (!arguments.length) return this._contentNode;
32
- this._contentNode = _;
33
- return this;
34
- }
35
-
36
- triggerElement(_): this {
37
- this._triggerElement = _;
38
- return this;
39
- }
40
-
41
- enter(domNode, element) {
42
- super.enter(domNode, element);
43
- const body = d3Select("body");
44
- this._tooltipElement = body.append("div")
45
- .attr("class", "tooltip-div")
46
- .style("z-index", "2147483638")
47
- .style("position", "fixed")
48
- ;
49
- this._arrowElement = body.append("div")
50
- .attr("class", "arrow-div")
51
- .style("z-index", "2147483638")
52
- .style("position", "fixed")
53
- ;
54
- }
55
-
56
- update(domNode, element) {
57
- super.update(domNode, element);
58
-
59
- if(this._contentNode !== this._prevContentNode){
60
- const node = this._tooltipElement.node();
61
- [...node.querySelectorAll("*")]
62
- .map(n=>n.__data__)
63
- .filter(n=>n)
64
- .forEach(w=>{
65
- if(typeof w.target === "function"){
66
- w.target(null);
67
- }
68
- if(typeof w.exit === "function"){
69
- w.exit();
70
- }
71
- });
72
- node.innerHTML = "";
73
- node.appendChild(this._contentNode);
74
- this._prevContentNode = this._contentNode;
75
- }
76
-
77
- if (this._contentNode) {
78
- this.onShowContent(this._contentNode);
79
- } else {
80
- this._tooltipElement
81
- .html(() => {
82
- return this._tooltipHTMLCallback(this.data());
83
- });
84
- }
85
- if(this.fitContent()){
86
- this._tooltipElement
87
- .style("width", "auto")
88
- .style("height", "auto")
89
- .style("padding", "0px")
90
- .style("box-sizing", "content-box")
91
- ;
92
- const rect = this._tooltipElement.node().getBoundingClientRect();
93
- this.tooltipWidth_default(rect.width);
94
- this.tooltipHeight_default(rect.height);
95
- }
96
- this._closing = false;
97
- this._tooltipElement
98
- .style("background-color", this.tooltipColor())
99
- .style("color", this.fontColor())
100
- .style("width", this.tooltipWidth() + "px")
101
- .style("height", this.tooltipHeight() + "px")
102
- .style("opacity", 1)
103
- .style("padding", this.padding() + "px")
104
- .style("pointer-events", this.enablePointerEvents() ? "all" : "none")
105
- .style("box-sizing", "content-box")
106
- ;
107
- this._arrowElement
108
- .style("opacity", 1)
109
- .style("pointer-events", "none")
110
- ;
111
- this.updateTooltipPosition();
112
- }
113
-
114
- onShowContent(node) {
115
-
116
- }
117
-
118
- protected updateTooltipPosition(): Position {
119
- const bbox = this.calcReferenceBBox();
120
- const direction = this.calcTooltipDirection(bbox);
121
- const box = bbox[direction];
122
- this._tooltipElement
123
- .style("top", box.y + "px")
124
- .style("left", box.x + "px")
125
- ;
126
- this.setArrowPosition(box, direction);
127
- return box;
128
- }
129
-
130
- protected calcTooltipDirection(bbox: DirectionalBBox): Direction {
131
- const directions: Direction[] = Object.keys(bbox) as Direction[];
132
-
133
- const defaultDirection = this.direction();
134
- directions.sort((a, b) => a === defaultDirection ? -1 : 1);
135
- const windowRect = {
136
- top: 0,
137
- left: 0,
138
- width: window.innerWidth,
139
- height: window.innerHeight
140
- };
141
- for (let i = 0; i < directions.length; i++) {
142
- const tooltipRect = {
143
- top: bbox[directions[i]].y,
144
- left: bbox[directions[i]].x,
145
- width: this.tooltipWidth(),
146
- height: this.tooltipHeight()
147
- };
148
- if (this.rectFits(tooltipRect, windowRect)) {
149
- return directions[i];
150
- }
151
- }
152
- this._logger.warning(`Tooltip doesn't fit in the window for any of the directions. Defaulting to '${defaultDirection}'`);
153
- this._logger.debug(windowRect);
154
- this._logger.debug({
155
- top: bbox[defaultDirection].y,
156
- left: bbox[defaultDirection].x,
157
- width: this.tooltipWidth(),
158
- height: this.tooltipHeight()
159
- });
160
- return defaultDirection;
161
- }
162
-
163
- protected rectFits(innerRect: Rectangle, outerRect: Rectangle): boolean {
164
- return (
165
- innerRect.top >= outerRect.top &&
166
- innerRect.left >= outerRect.left &&
167
- innerRect.width + innerRect.left <= outerRect.width + outerRect.left &&
168
- innerRect.height + innerRect.top <= outerRect.height + outerRect.top
169
- );
170
- }
171
-
172
- protected setArrowPosition(point: Position, direction: Direction) {
173
- let top;
174
- let left;
175
- let visibleBorderStyle = "border-top-color";
176
- this._arrowElement
177
- .style("border", `${this.arrowHeight()}px solid ${this.tooltipColor()}`)
178
- .style("border-top-color", "transparent")
179
- .style("border-right-color", "transparent")
180
- .style("border-bottom-color", "transparent")
181
- .style("border-left-color", "transparent")
182
- ;
183
- switch (direction) {
184
- case "n":
185
- top = point.y + this.tooltipHeight() + (this.padding() * 2);
186
- left = point.x + (this.tooltipWidth() / 2) - (this.arrowWidth() / 2) + this.padding();
187
- visibleBorderStyle = "border-top-color";
188
- this._arrowElement
189
- .style("border-top-width", `${this.arrowHeight()}px`)
190
- .style("border-bottom-width", "0px")
191
- .style("border-left-width", `${this.arrowWidth() / 2}px`)
192
- .style("border-right-width", `${this.arrowWidth() / 2}px`)
193
- ;
194
- break;
195
- case "s":
196
- top = point.y - this.arrowHeight();
197
- left = point.x + this.padding() + (this.tooltipWidth() / 2) - (this.arrowWidth() / 2);
198
- visibleBorderStyle = "border-bottom-color";
199
- this._arrowElement
200
- .style("border-top-width", "0px")
201
- .style("border-bottom-width", `${this.arrowHeight()}px`)
202
- .style("border-left-width", `${this.arrowWidth() / 2}px`)
203
- .style("border-right-width", `${this.arrowWidth() / 2}px`)
204
- ;
205
- break;
206
- case "e":
207
- top = point.y + (this.tooltipHeight() / 2) + this.padding() - (this.arrowWidth() / 2);
208
- left = point.x - this.arrowHeight();
209
- visibleBorderStyle = "border-right-color";
210
- this._arrowElement
211
- .style("border-top-width", `${this.arrowWidth() / 2}px`)
212
- .style("border-bottom-width", `${this.arrowWidth() / 2}px`)
213
- .style("border-left-width", "0px")
214
- .style("border-right-width", `${this.arrowHeight()}px`)
215
- ;
216
- break;
217
- case "w":
218
- top = point.y + (this.tooltipHeight() / 2) - (this.arrowWidth() / 2) + this.padding();
219
- left = point.x + this.tooltipWidth() + (this.padding() * 2);
220
- visibleBorderStyle = "border-left-color";
221
- this._arrowElement
222
- .style("border-top-width", `${this.arrowWidth() / 2}px`)
223
- .style("border-bottom-width", `${this.arrowWidth() / 2}px`)
224
- .style("border-left-width", `${this.arrowHeight()}px`)
225
- .style("border-right-width", "0px")
226
- ;
227
- break;
228
- }
229
- if (typeof top !== "undefined" && typeof left !== "undefined") {
230
- this._arrowElement
231
- .style("top", top + "px")
232
- .style("left", left + "px")
233
- .style(visibleBorderStyle, this.tooltipColor())
234
- .style("opacity", 1)
235
- ;
236
- } else {
237
- this._arrowElement
238
- .style("opacity", 0)
239
- ;
240
- }
241
- return point;
242
- }
243
-
244
- protected getReferenceNode() {
245
- if (!this._triggerElement) {
246
- return this.element().node().parentNode.parentNode;
247
- }
248
- return this._triggerElement.node();
249
- }
250
- public _cursorLoc;
251
- protected calcReferenceBBox() {
252
- const node = this.getReferenceNode();
253
- let { top, left, width, height } = node.getBoundingClientRect();
254
- const wholeW = this.tooltipWidth();
255
- const wholeH = this.tooltipHeight();
256
- const halfW = wholeW / 2;
257
- const halfH = wholeH / 2;
258
- const arrowH = this.arrowHeight();
259
- const p = this.padding();
260
- const p2 = p * 2;
261
-
262
- if(this.followCursor() && this._cursorLoc) {
263
-
264
- left = this._cursorLoc[0];
265
- top = this._cursorLoc[1];
266
- width = 1;
267
- height = 1;
268
- }
269
- const bbox = {
270
- n: {
271
- x: left + (width / 2) - halfW - p,
272
- y: top - wholeH - arrowH - p2
273
- },
274
- e: {
275
- x: left + width + arrowH,
276
- y: top + (height / 2) - halfH - p
277
- },
278
- s: {
279
- x: left + (width / 2) - halfW - p,
280
- y: top + height + arrowH
281
- },
282
- w: {
283
- x: left - wholeW - arrowH - p2,
284
- y: top + (height / 2) - halfH - p
285
- },
286
- nw: {
287
- x: left - wholeW - p2,
288
- y: top - wholeH - p2
289
- },
290
- ne: {
291
- x: left + width,
292
- y: top - wholeH - p2
293
- },
294
- se: {
295
- x: left + width,
296
- y: top + height
297
- },
298
- sw: {
299
- x: left - wholeW - p2,
300
- y: top + height
301
- }
302
- };
303
- return bbox;
304
- }
305
-
306
- private _closing = false;
307
- mouseout() {
308
- this._closing = true;
309
- this._tooltipElement.on("mouseover", () => {
310
- this._closing = false;
311
- });
312
- this._tooltipElement.on("mouseout", () => {
313
- this.mouseout();
314
- });
315
- setTimeout(()=>{
316
- if(this._closing){
317
- this.visible(false);
318
- }
319
- }, this.closeDelay());
320
- }
321
-
322
- visible(): boolean;
323
- visible(_: boolean): this;
324
- visible(_?: boolean): boolean | this {
325
- if (!arguments.length) return super.visible();
326
- if (this._arrowElement) {
327
- this._arrowElement.style("visibility", _ ? "visible" : "hidden");
328
- this._tooltipElement.style("visibility", _ ? "visible" : "hidden");
329
- }
330
- super.visible(_);
331
- return this;
332
- }
333
-
334
- exit(domNode, element) {
335
- if (this._arrowElement) {
336
- this._arrowElement.remove();
337
- this._tooltipElement.remove();
338
- }
339
- super.exit(domNode, element);
340
- }
341
- }
342
- HTMLTooltip.prototype._class += " html_HTMLTooltip";
343
-
344
- export interface HTMLTooltip {
345
- padding(): number;
346
- padding(_: number): this;
347
- direction(): Direction;
348
- direction(_: Direction): this;
349
- arrowHeight(): number;
350
- arrowHeight(_: number): this;
351
- arrowWidth(): number;
352
- arrowWidth(_: number): this;
353
- fontColor(): string;
354
- fontColor(_: string): this;
355
- tooltipColor(): string;
356
- tooltipColor(_: string): this;
357
- tooltipWidth(): number;
358
- tooltipWidth(_: number): this;
359
- tooltipWidth_default(_: number);
360
- tooltipHeight(): number;
361
- tooltipHeight(_: number): this;
362
- tooltipHeight_default(_: number);
363
- followCursor(): boolean;
364
- followCursor(_: boolean): this;
365
- enablePointerEvents(): boolean;
366
- enablePointerEvents(_: boolean): this;
367
- closeDelay(): number;
368
- closeDelay(_: number): this;
369
- fitContent(): boolean;
370
- fitContent(_: boolean): this;
371
-
372
- }
373
-
374
- HTMLTooltip.prototype.publish("fitContent", false, "boolean", "If true, tooltip will grow to fit its html content");
375
- HTMLTooltip.prototype.publish("followCursor", false, "boolean", "If true, tooltip will display relative to cursor location");
376
- HTMLTooltip.prototype.publish("closeDelay", 400, "number", "Number of milliseconds to wait before closing tooltip (cancelled on tooltip mouseover event)");
377
- HTMLTooltip.prototype.publish("direction", "n", "set", "Direction in which to display the tooltip", ["n", "s", "e", "w", "ne", "nw", "se", "sw"]);
378
- HTMLTooltip.prototype.publish("padding", 8, "number", "Padding (pixels)");
379
- HTMLTooltip.prototype.publish("arrowWidth", 16, "number", "Width (or height depending on direction) of the tooltip arrow (pixels)");
380
- HTMLTooltip.prototype.publish("arrowHeight", 8, "number", "Height (or width depending on direction) of the tooltip arrow (pixels)");
381
- HTMLTooltip.prototype.publish("fontColor", "#FFF", "html-color", "The default font color for text in the tooltip");
382
- HTMLTooltip.prototype.publish("tooltipColor", "#000000EE", "html-color", "Background color of the tooltip");
383
- HTMLTooltip.prototype.publish("tooltipWidth", 200, "number", "Width of the tooltip (not including arrow) (pixels)");
384
- HTMLTooltip.prototype.publish("tooltipHeight", 200, "number", "Height of the tooltip (not including arrow) (pixels)");
385
- HTMLTooltip.prototype.publish("enablePointerEvents", false, "boolean", "If true, the 'pointer-events: all' style will be used");
1
+ import { HTMLWidget } from "@hpcc-js/common";
2
+ import { scopedLogger, ScopedLogging } from "@hpcc-js/util";
3
+ import { select as d3Select } from "d3-selection";
4
+
5
+ type Direction = "n" | "s" | "e" | "w" | "ne" | "nw" | "se" | "sw";
6
+ type Position = { x: number, y: number };
7
+ type DirectionalBBox = { [key in Direction]: Position; };
8
+
9
+ type Rectangle = { top: number, left: number, width: number, height: number };
10
+ export class HTMLTooltip extends HTMLWidget {
11
+
12
+ public _triggerElement;
13
+ public _contentNode;
14
+ protected _prevContentNode;
15
+
16
+ protected _tooltipElement;
17
+ protected _arrowElement;
18
+ protected _tooltipHTMLCallback = (data?) => "<b>_tooltipHTMLCallback is undefined</b>";
19
+ protected _logger: ScopedLogging = scopedLogger("html/HTMLTooltip");
20
+ constructor() {
21
+ super();
22
+ this.visible(false);
23
+ }
24
+
25
+ tooltipHTML(_: (data?) => string): this {
26
+ this._tooltipHTMLCallback = _;
27
+ return this;
28
+ }
29
+
30
+ tooltipContent(_): this {
31
+ if (!arguments.length) return this._contentNode;
32
+ this._contentNode = _;
33
+ return this;
34
+ }
35
+
36
+ triggerElement(_): this {
37
+ this._triggerElement = _;
38
+ return this;
39
+ }
40
+
41
+ enter(domNode, element) {
42
+ super.enter(domNode, element);
43
+ const body = d3Select("body");
44
+ this._tooltipElement = body.append("div")
45
+ .attr("class", "tooltip-div")
46
+ .style("z-index", "2147483638")
47
+ .style("position", "fixed")
48
+ ;
49
+ this._arrowElement = body.append("div")
50
+ .attr("class", "arrow-div")
51
+ .style("z-index", "2147483638")
52
+ .style("position", "fixed")
53
+ ;
54
+ }
55
+
56
+ update(domNode, element) {
57
+ super.update(domNode, element);
58
+
59
+ if(this._contentNode !== this._prevContentNode){
60
+ const node = this._tooltipElement.node();
61
+ [...node.querySelectorAll("*")]
62
+ .map(n=>n.__data__)
63
+ .filter(n=>n)
64
+ .forEach(w=>{
65
+ if(typeof w.target === "function"){
66
+ w.target(null);
67
+ }
68
+ if(typeof w.exit === "function"){
69
+ w.exit();
70
+ }
71
+ });
72
+ node.innerHTML = "";
73
+ node.appendChild(this._contentNode);
74
+ this._prevContentNode = this._contentNode;
75
+ }
76
+
77
+ if (this._contentNode) {
78
+ this.onShowContent(this._contentNode);
79
+ } else {
80
+ this._tooltipElement
81
+ .html(() => {
82
+ return this._tooltipHTMLCallback(this.data());
83
+ });
84
+ }
85
+ if(this.fitContent()){
86
+ this._tooltipElement
87
+ .style("width", "auto")
88
+ .style("height", "auto")
89
+ .style("padding", "0px")
90
+ .style("box-sizing", "content-box")
91
+ ;
92
+ const rect = this._tooltipElement.node().getBoundingClientRect();
93
+ this.tooltipWidth_default(rect.width);
94
+ this.tooltipHeight_default(rect.height);
95
+ }
96
+ this._closing = false;
97
+ this._tooltipElement
98
+ .style("background-color", this.tooltipColor())
99
+ .style("color", this.fontColor())
100
+ .style("width", this.tooltipWidth() + "px")
101
+ .style("height", this.tooltipHeight() + "px")
102
+ .style("opacity", 1)
103
+ .style("padding", this.padding() + "px")
104
+ .style("pointer-events", this.enablePointerEvents() ? "all" : "none")
105
+ .style("box-sizing", "content-box")
106
+ ;
107
+ this._arrowElement
108
+ .style("opacity", 1)
109
+ .style("pointer-events", "none")
110
+ ;
111
+ this.updateTooltipPosition();
112
+ }
113
+
114
+ onShowContent(node) {
115
+
116
+ }
117
+
118
+ protected updateTooltipPosition(): Position {
119
+ const bbox = this.calcReferenceBBox();
120
+ const direction = this.calcTooltipDirection(bbox);
121
+ const box = bbox[direction];
122
+ this._tooltipElement
123
+ .style("top", box.y + "px")
124
+ .style("left", box.x + "px")
125
+ ;
126
+ this.setArrowPosition(box, direction);
127
+ return box;
128
+ }
129
+
130
+ protected calcTooltipDirection(bbox: DirectionalBBox): Direction {
131
+ const directions: Direction[] = Object.keys(bbox) as Direction[];
132
+
133
+ const defaultDirection = this.direction();
134
+ directions.sort((a, b) => a === defaultDirection ? -1 : 1);
135
+ const windowRect = {
136
+ top: 0,
137
+ left: 0,
138
+ width: window.innerWidth,
139
+ height: window.innerHeight
140
+ };
141
+ for (let i = 0; i < directions.length; i++) {
142
+ const tooltipRect = {
143
+ top: bbox[directions[i]].y,
144
+ left: bbox[directions[i]].x,
145
+ width: this.tooltipWidth(),
146
+ height: this.tooltipHeight()
147
+ };
148
+ if (this.rectFits(tooltipRect, windowRect)) {
149
+ return directions[i];
150
+ }
151
+ }
152
+ this._logger.warning(`Tooltip doesn't fit in the window for any of the directions. Defaulting to '${defaultDirection}'`);
153
+ this._logger.debug(windowRect);
154
+ this._logger.debug({
155
+ top: bbox[defaultDirection].y,
156
+ left: bbox[defaultDirection].x,
157
+ width: this.tooltipWidth(),
158
+ height: this.tooltipHeight()
159
+ });
160
+ return defaultDirection;
161
+ }
162
+
163
+ protected rectFits(innerRect: Rectangle, outerRect: Rectangle): boolean {
164
+ return (
165
+ innerRect.top >= outerRect.top &&
166
+ innerRect.left >= outerRect.left &&
167
+ innerRect.width + innerRect.left <= outerRect.width + outerRect.left &&
168
+ innerRect.height + innerRect.top <= outerRect.height + outerRect.top
169
+ );
170
+ }
171
+
172
+ protected setArrowPosition(point: Position, direction: Direction) {
173
+ let top;
174
+ let left;
175
+ let visibleBorderStyle = "border-top-color";
176
+ this._arrowElement
177
+ .style("border", `${this.arrowHeight()}px solid ${this.tooltipColor()}`)
178
+ .style("border-top-color", "transparent")
179
+ .style("border-right-color", "transparent")
180
+ .style("border-bottom-color", "transparent")
181
+ .style("border-left-color", "transparent")
182
+ ;
183
+ switch (direction) {
184
+ case "n":
185
+ top = point.y + this.tooltipHeight() + (this.padding() * 2);
186
+ left = point.x + (this.tooltipWidth() / 2) - (this.arrowWidth() / 2) + this.padding();
187
+ visibleBorderStyle = "border-top-color";
188
+ this._arrowElement
189
+ .style("border-top-width", `${this.arrowHeight()}px`)
190
+ .style("border-bottom-width", "0px")
191
+ .style("border-left-width", `${this.arrowWidth() / 2}px`)
192
+ .style("border-right-width", `${this.arrowWidth() / 2}px`)
193
+ ;
194
+ break;
195
+ case "s":
196
+ top = point.y - this.arrowHeight();
197
+ left = point.x + this.padding() + (this.tooltipWidth() / 2) - (this.arrowWidth() / 2);
198
+ visibleBorderStyle = "border-bottom-color";
199
+ this._arrowElement
200
+ .style("border-top-width", "0px")
201
+ .style("border-bottom-width", `${this.arrowHeight()}px`)
202
+ .style("border-left-width", `${this.arrowWidth() / 2}px`)
203
+ .style("border-right-width", `${this.arrowWidth() / 2}px`)
204
+ ;
205
+ break;
206
+ case "e":
207
+ top = point.y + (this.tooltipHeight() / 2) + this.padding() - (this.arrowWidth() / 2);
208
+ left = point.x - this.arrowHeight();
209
+ visibleBorderStyle = "border-right-color";
210
+ this._arrowElement
211
+ .style("border-top-width", `${this.arrowWidth() / 2}px`)
212
+ .style("border-bottom-width", `${this.arrowWidth() / 2}px`)
213
+ .style("border-left-width", "0px")
214
+ .style("border-right-width", `${this.arrowHeight()}px`)
215
+ ;
216
+ break;
217
+ case "w":
218
+ top = point.y + (this.tooltipHeight() / 2) - (this.arrowWidth() / 2) + this.padding();
219
+ left = point.x + this.tooltipWidth() + (this.padding() * 2);
220
+ visibleBorderStyle = "border-left-color";
221
+ this._arrowElement
222
+ .style("border-top-width", `${this.arrowWidth() / 2}px`)
223
+ .style("border-bottom-width", `${this.arrowWidth() / 2}px`)
224
+ .style("border-left-width", `${this.arrowHeight()}px`)
225
+ .style("border-right-width", "0px")
226
+ ;
227
+ break;
228
+ }
229
+ if (typeof top !== "undefined" && typeof left !== "undefined") {
230
+ this._arrowElement
231
+ .style("top", top + "px")
232
+ .style("left", left + "px")
233
+ .style(visibleBorderStyle, this.tooltipColor())
234
+ .style("opacity", 1)
235
+ ;
236
+ } else {
237
+ this._arrowElement
238
+ .style("opacity", 0)
239
+ ;
240
+ }
241
+ return point;
242
+ }
243
+
244
+ protected getReferenceNode() {
245
+ if (!this._triggerElement) {
246
+ return this.element().node().parentNode.parentNode;
247
+ }
248
+ return this._triggerElement.node();
249
+ }
250
+ public _cursorLoc;
251
+ protected calcReferenceBBox() {
252
+ const node = this.getReferenceNode();
253
+ let { top, left, width, height } = node.getBoundingClientRect();
254
+ const wholeW = this.tooltipWidth();
255
+ const wholeH = this.tooltipHeight();
256
+ const halfW = wholeW / 2;
257
+ const halfH = wholeH / 2;
258
+ const arrowH = this.arrowHeight();
259
+ const p = this.padding();
260
+ const p2 = p * 2;
261
+
262
+ if(this.followCursor() && this._cursorLoc) {
263
+
264
+ left = this._cursorLoc[0];
265
+ top = this._cursorLoc[1];
266
+ width = 1;
267
+ height = 1;
268
+ }
269
+ const bbox = {
270
+ n: {
271
+ x: left + (width / 2) - halfW - p,
272
+ y: top - wholeH - arrowH - p2
273
+ },
274
+ e: {
275
+ x: left + width + arrowH,
276
+ y: top + (height / 2) - halfH - p
277
+ },
278
+ s: {
279
+ x: left + (width / 2) - halfW - p,
280
+ y: top + height + arrowH
281
+ },
282
+ w: {
283
+ x: left - wholeW - arrowH - p2,
284
+ y: top + (height / 2) - halfH - p
285
+ },
286
+ nw: {
287
+ x: left - wholeW - p2,
288
+ y: top - wholeH - p2
289
+ },
290
+ ne: {
291
+ x: left + width,
292
+ y: top - wholeH - p2
293
+ },
294
+ se: {
295
+ x: left + width,
296
+ y: top + height
297
+ },
298
+ sw: {
299
+ x: left - wholeW - p2,
300
+ y: top + height
301
+ }
302
+ };
303
+ return bbox;
304
+ }
305
+
306
+ private _closing = false;
307
+ mouseout() {
308
+ this._closing = true;
309
+ this._tooltipElement.on("mouseover", () => {
310
+ this._closing = false;
311
+ });
312
+ this._tooltipElement.on("mouseout", () => {
313
+ this.mouseout();
314
+ });
315
+ setTimeout(()=>{
316
+ if(this._closing){
317
+ this.visible(false);
318
+ }
319
+ }, this.closeDelay());
320
+ }
321
+
322
+ visible(): boolean;
323
+ visible(_: boolean): this;
324
+ visible(_?: boolean): boolean | this {
325
+ if (!arguments.length) return super.visible();
326
+ if (this._arrowElement) {
327
+ this._arrowElement.style("visibility", _ ? "visible" : "hidden");
328
+ this._tooltipElement.style("visibility", _ ? "visible" : "hidden");
329
+ }
330
+ super.visible(_);
331
+ return this;
332
+ }
333
+
334
+ exit(domNode, element) {
335
+ if (this._arrowElement) {
336
+ this._arrowElement.remove();
337
+ this._tooltipElement.remove();
338
+ }
339
+ super.exit(domNode, element);
340
+ }
341
+ }
342
+ HTMLTooltip.prototype._class += " html_HTMLTooltip";
343
+
344
+ export interface HTMLTooltip {
345
+ padding(): number;
346
+ padding(_: number): this;
347
+ direction(): Direction;
348
+ direction(_: Direction): this;
349
+ arrowHeight(): number;
350
+ arrowHeight(_: number): this;
351
+ arrowWidth(): number;
352
+ arrowWidth(_: number): this;
353
+ fontColor(): string;
354
+ fontColor(_: string): this;
355
+ tooltipColor(): string;
356
+ tooltipColor(_: string): this;
357
+ tooltipWidth(): number;
358
+ tooltipWidth(_: number): this;
359
+ tooltipWidth_default(_: number);
360
+ tooltipHeight(): number;
361
+ tooltipHeight(_: number): this;
362
+ tooltipHeight_default(_: number);
363
+ followCursor(): boolean;
364
+ followCursor(_: boolean): this;
365
+ enablePointerEvents(): boolean;
366
+ enablePointerEvents(_: boolean): this;
367
+ closeDelay(): number;
368
+ closeDelay(_: number): this;
369
+ fitContent(): boolean;
370
+ fitContent(_: boolean): this;
371
+
372
+ }
373
+
374
+ HTMLTooltip.prototype.publish("fitContent", false, "boolean", "If true, tooltip will grow to fit its html content");
375
+ HTMLTooltip.prototype.publish("followCursor", false, "boolean", "If true, tooltip will display relative to cursor location");
376
+ HTMLTooltip.prototype.publish("closeDelay", 400, "number", "Number of milliseconds to wait before closing tooltip (cancelled on tooltip mouseover event)");
377
+ HTMLTooltip.prototype.publish("direction", "n", "set", "Direction in which to display the tooltip", ["n", "s", "e", "w", "ne", "nw", "se", "sw"]);
378
+ HTMLTooltip.prototype.publish("padding", 8, "number", "Padding (pixels)");
379
+ HTMLTooltip.prototype.publish("arrowWidth", 16, "number", "Width (or height depending on direction) of the tooltip arrow (pixels)");
380
+ HTMLTooltip.prototype.publish("arrowHeight", 8, "number", "Height (or width depending on direction) of the tooltip arrow (pixels)");
381
+ HTMLTooltip.prototype.publish("fontColor", "#FFF", "html-color", "The default font color for text in the tooltip");
382
+ HTMLTooltip.prototype.publish("tooltipColor", "#000000EE", "html-color", "Background color of the tooltip");
383
+ HTMLTooltip.prototype.publish("tooltipWidth", 200, "number", "Width of the tooltip (not including arrow) (pixels)");
384
+ HTMLTooltip.prototype.publish("tooltipHeight", 200, "number", "Height of the tooltip (not including arrow) (pixels)");
385
+ HTMLTooltip.prototype.publish("enablePointerEvents", false, "boolean", "If true, the 'pointer-events: all' style will be used");