@datarailsshared/dr_renderer 1.2.8 → 1.2.9
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/.circleci/config.yml +53 -8
- package/README.md +5 -6
- package/babel.config.js +3 -0
- package/jest.config.js +27 -0
- package/package.json +25 -3
- package/src/charts/dr_gauge_chart.js +566 -0
- package/src/dataformatter.d.ts +13 -0
- package/src/dataformatter.js +60 -7
- package/src/dr-renderer-helpers.js +58 -0
- package/src/dr_chart_tooltip.js +277 -0
- package/src/dr_pivottable.js +606 -145
- package/src/graph-table-renderer.js +147 -0
- package/src/highcharts_renderer.js +5779 -2021
- package/src/index.js +8 -2
- package/src/novix_renderer.js +125 -48
- package/src/pivot.css +142 -17
- package/src/pivottable.js +84 -7
- package/src/published_items_renderer.js +365 -0
- package/src/seriesPointStyles-helper.js +43 -0
- package/tests/dr-renderer-helpers.test.js +150 -0
- package/tests/dr_chart_tooltip.test.js +739 -0
- package/tests/dr_gauge_chart.test.js +1931 -0
- package/tests/highcharts_renderer.test.js +9389 -0
- package/tests/mock/add-in-dynamic-ranges.json +127 -0
- package/tests/mock/add-in-functions.json +410 -0
- package/tests/mock/add-in-tables.json +347 -0
- package/tests/mock/tables.json +2258 -0
- package/tests/mock/widgets.json +403 -0
- package/tests/seriesPointStyles-helper.test.js +114 -0
- package/tsconfig.json +15 -0
- package/types/graph-table-renderer.d.ts +79 -0
- package/types/index.d.ts +1 -0
package/src/dataformatter.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
1
3
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
2
4
|
|
|
3
5
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -350,7 +352,7 @@ var DataFormatterImpl = function () {
|
|
|
350
352
|
|
|
351
353
|
n = this.roundDecimals(n, decimals).toString().split('.');
|
|
352
354
|
var integerPart = n[0];
|
|
353
|
-
var decimalPart = n[1] || 0;
|
|
355
|
+
var decimalPart = _.padEnd(String(n[1] || 0), decimals, '0');
|
|
354
356
|
|
|
355
357
|
return this.applyNumberPattern(integerPart, patternIntegerPart) + this.locale.decimalSeparator + this.applyNumberPattern(decimalPart, patternDecimalPart, n[1] && n[1][0] == '0' ? '' : 'right');
|
|
356
358
|
}
|
|
@@ -497,6 +499,13 @@ var DataFormatterImpl = function () {
|
|
|
497
499
|
var minutes = n.getMinutes();
|
|
498
500
|
var seconds = n.getSeconds();
|
|
499
501
|
|
|
502
|
+
var padStartTime = function(time) {
|
|
503
|
+
if (time < 10) {
|
|
504
|
+
return '0' + time;
|
|
505
|
+
}
|
|
506
|
+
return time;
|
|
507
|
+
}
|
|
508
|
+
|
|
500
509
|
// Build res
|
|
501
510
|
var res = pattern.replace(/((?:am\/pm)|(?:a\/p))|(?:(h[^ydsap]*?)mm)|(?:mm([^ydh]*?s))|(?:(h[^ydsap]*?)m)|(?:m([^ydh]*?s))/gi, function (a, ampm, fmin, fmin2, mmin, mmin2) {
|
|
502
511
|
|
|
@@ -506,11 +515,11 @@ var DataFormatterImpl = function () {
|
|
|
506
515
|
}
|
|
507
516
|
|
|
508
517
|
if (fmin) {
|
|
509
|
-
return fmin + _this3.applyNumberPattern(minutes, '00');
|
|
518
|
+
return fmin + _this3.applyNumberPattern(padStartTime(minutes), '00');
|
|
510
519
|
}
|
|
511
520
|
|
|
512
521
|
if (fmin2) {
|
|
513
|
-
return _this3.applyNumberPattern(minutes, '00') + fmin2;
|
|
522
|
+
return _this3.applyNumberPattern(padStartTime(minutes), '00') + fmin2;
|
|
514
523
|
}
|
|
515
524
|
|
|
516
525
|
if (mmin) {
|
|
@@ -527,7 +536,7 @@ var DataFormatterImpl = function () {
|
|
|
527
536
|
return res.replace(/(ss)|(s)|(hh)|(h)|(dddd)|(ddd)|(dd)|(d)|(mmmmm)|(mmmm)|(mmm)|(mm)|(m)|(yyyy)|(yy)|(\[\])/gi, function (a, ss, s, hh, h, dddd, ddd, dd, d, mmmmm, mmmm, mmm, mm, m, yyyy, yy, ampm) {
|
|
528
537
|
|
|
529
538
|
if (ss) {
|
|
530
|
-
return _this3.applyNumberPattern(seconds, '00');
|
|
539
|
+
return _this3.applyNumberPattern(padStartTime(seconds), '00');
|
|
531
540
|
}
|
|
532
541
|
|
|
533
542
|
if (s) {
|
|
@@ -535,7 +544,7 @@ var DataFormatterImpl = function () {
|
|
|
535
544
|
}
|
|
536
545
|
|
|
537
546
|
if (hh) {
|
|
538
|
-
return _this3.applyNumberPattern(foundAMPM ? hours % 12 : hours, '00');
|
|
547
|
+
return _this3.applyNumberPattern(padStartTime(foundAMPM ? hours % 12 : hours), '00');
|
|
539
548
|
}
|
|
540
549
|
|
|
541
550
|
if (h) {
|
|
@@ -858,7 +867,7 @@ var DataFormatterImpl = function () {
|
|
|
858
867
|
// Standard condition for negative number
|
|
859
868
|
case sectionIndex === 1:
|
|
860
869
|
condition = 'type == "Number" && parseFloat(n) < 0';
|
|
861
|
-
shouldAbsNumber =
|
|
870
|
+
shouldAbsNumber = !!section.match(/\(.*\)/);
|
|
862
871
|
break;
|
|
863
872
|
|
|
864
873
|
}
|
|
@@ -1003,6 +1012,10 @@ var DataFormatterImpl = function () {
|
|
|
1003
1012
|
|
|
1004
1013
|
// Call function
|
|
1005
1014
|
result = this.memoized[pattern].call(this, n, type);
|
|
1015
|
+
|
|
1016
|
+
if (result.value === result.pattern && !(String(n) === '0' && result.value.includes('0'))) {
|
|
1017
|
+
result.value = n;
|
|
1018
|
+
}
|
|
1006
1019
|
}
|
|
1007
1020
|
catch (e) {
|
|
1008
1021
|
|
|
@@ -1015,9 +1028,49 @@ var DataFormatterImpl = function () {
|
|
|
1015
1028
|
|
|
1016
1029
|
return result;
|
|
1017
1030
|
}
|
|
1031
|
+
}, {
|
|
1032
|
+
key: 'formatValue',
|
|
1033
|
+
value: function formatValue(data_type, number_format, value, override_values_format) {
|
|
1034
|
+
if (!number_format) {
|
|
1035
|
+
number_format = 'General';
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
if (Number.isNaN(value)) {
|
|
1039
|
+
return { value: "#Error" };
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
if (data_type === 'n' && value != null) {
|
|
1043
|
+
if (override_values_format) {
|
|
1044
|
+
number_format = override_values_format;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (number_format.indexOf('[kilo]') >= 0) {
|
|
1048
|
+
value = value / 1000;
|
|
1049
|
+
number_format = number_format.replace('[kilo]', '');
|
|
1050
|
+
} else if (number_format.indexOf('[mega]') >= 0) {
|
|
1051
|
+
value = value / 1000000;
|
|
1052
|
+
number_format = number_format.replace('[mega]', '');
|
|
1053
|
+
} else if (number_format.indexOf('[kilomega]') >= 0) {
|
|
1054
|
+
number_format = number_format.replace('[kilomega]', '');
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
return this.format(value, 'Number', number_format);
|
|
1058
|
+
} else if (data_type === 'd') {
|
|
1059
|
+
number_format = number_format.split(';')[0];
|
|
1060
|
+
let d;
|
|
1061
|
+
if (value instanceof Date || typeof value === 'string') {
|
|
1062
|
+
d = new Date(value);
|
|
1063
|
+
} else {
|
|
1064
|
+
d = new Date(value * 1000);
|
|
1065
|
+
}
|
|
1066
|
+
return this.format(d.toString(), 'DateTime', number_format);
|
|
1067
|
+
} else {
|
|
1068
|
+
return value;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1018
1071
|
}]);
|
|
1019
1072
|
|
|
1020
1073
|
return DataFormatterImpl;
|
|
1021
1074
|
}();
|
|
1022
1075
|
|
|
1023
|
-
module.exports = new DataFormatterImpl();
|
|
1076
|
+
module.exports = new DataFormatterImpl();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
function backendSortingKeysAreNotEmpty(keys) {
|
|
2
|
+
return !!keys && (!!keys.row_keys && !!keys.row_keys.length || !!keys.col_keys && !!keys.col_keys.length);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function capitalize(string) {
|
|
6
|
+
if (typeof string !== 'string') return '';
|
|
7
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function clamp(min, v, max) {
|
|
11
|
+
return Math.min(max, Math.max(v, min));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isNumber(n) {
|
|
15
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function mergeDeep(target, ...sources) {
|
|
19
|
+
const isObject = (obj) => obj && typeof obj === 'object' && !Array.isArray(obj);
|
|
20
|
+
|
|
21
|
+
if (!isObject(target)) return target;
|
|
22
|
+
|
|
23
|
+
sources.forEach((source) => {
|
|
24
|
+
if (!isObject(source)) return;
|
|
25
|
+
|
|
26
|
+
Object.keys(source).forEach((key) => {
|
|
27
|
+
const targetValue = target[key];
|
|
28
|
+
const sourceValue = source[key];
|
|
29
|
+
|
|
30
|
+
if (isObject(targetValue) && isObject(sourceValue)) {
|
|
31
|
+
target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue);
|
|
32
|
+
} else {
|
|
33
|
+
target[key] = sourceValue;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return target;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function removeSVGTextCorrection(svgEl, corr = 'yCorr') {
|
|
42
|
+
Object.defineProperty(svgEl, corr, {
|
|
43
|
+
set: function() {},
|
|
44
|
+
get: function() {
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return svgEl;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
backendSortingKeysAreNotEmpty,
|
|
53
|
+
capitalize,
|
|
54
|
+
clamp,
|
|
55
|
+
isNumber,
|
|
56
|
+
mergeDeep,
|
|
57
|
+
removeSVGTextCorrection,
|
|
58
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
const helpers = require("./dr-renderer-helpers");
|
|
2
|
+
|
|
3
|
+
const DR_TOOLTIP_OPTIONS_DEFAULT = {
|
|
4
|
+
anchorOffset: 10,
|
|
5
|
+
arrowRadius: 3,
|
|
6
|
+
arrowSize: 10,
|
|
7
|
+
background: "#fff",
|
|
8
|
+
border: 1,
|
|
9
|
+
borderColor: "#DFE0E3",
|
|
10
|
+
borderRadius: 8,
|
|
11
|
+
boxShadow: "0px 4px 8px 1px rgba(0, 0, 0, 0.25)",
|
|
12
|
+
direction: "top",
|
|
13
|
+
followPointer: false,
|
|
14
|
+
outerOffset: 8,
|
|
15
|
+
paddings: [6, 12],
|
|
16
|
+
showArrow: true,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function DrChartTooltip(chart, options) {
|
|
20
|
+
this.getOptions = function() {
|
|
21
|
+
return this.options;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.add = function(content, anchor, options = {}) {
|
|
25
|
+
const localOptions = Object.assign({}, this.options, options );
|
|
26
|
+
let tooltip;
|
|
27
|
+
|
|
28
|
+
if (!content || !anchor) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
anchor.addEventListener("mouseover", (event) => {
|
|
33
|
+
if (tooltip) {
|
|
34
|
+
tooltip.destroy();
|
|
35
|
+
}
|
|
36
|
+
tooltip = this.create(content, localOptions.followPointer ? event : anchor, localOptions);
|
|
37
|
+
tooltip.show();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
anchor.addEventListener("mouseleave", (event) => {
|
|
41
|
+
if (!tooltip) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
tooltip = tooltip.destroy();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (localOptions.followPointer) {
|
|
49
|
+
anchor.addEventListener("mousemove", (event) => {
|
|
50
|
+
if (!tooltip) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.setTooltipPosition(tooltip, event, localOptions);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.create = function(content, anchor, options) {
|
|
60
|
+
const tooltip = this.chart.renderer
|
|
61
|
+
.text(`${content}${options.showArrow ? `<span class="dr-renderer-tooltip_arrow" style="position: absolute"></span>` : ""}`, 0, 0, true)
|
|
62
|
+
.attr({
|
|
63
|
+
class: "dr-renderer-tooltip",
|
|
64
|
+
})
|
|
65
|
+
.css({
|
|
66
|
+
background: options.background,
|
|
67
|
+
border: `${options.border}px solid ${options.borderColor}`,
|
|
68
|
+
borderRadius: options.borderRadius + "px",
|
|
69
|
+
boxShadow: options.boxShadow,
|
|
70
|
+
color: options.color,
|
|
71
|
+
display: "flex",
|
|
72
|
+
alignItems: "center",
|
|
73
|
+
gap: "4px",
|
|
74
|
+
fontFamily: options.fontFamily,
|
|
75
|
+
fontSize: options.fontSize + "px",
|
|
76
|
+
padding: options.paddings.map((p) => `${p}px`).join(" "),
|
|
77
|
+
})
|
|
78
|
+
.add()
|
|
79
|
+
.hide();
|
|
80
|
+
|
|
81
|
+
helpers.removeSVGTextCorrection(tooltip);
|
|
82
|
+
|
|
83
|
+
this.setTooltipPosition(tooltip, anchor, options);
|
|
84
|
+
|
|
85
|
+
return tooltip;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.setTooltipPosition = function(tooltip, anchor, options) {
|
|
89
|
+
const position = this.getPosition(tooltip, anchor, options);
|
|
90
|
+
|
|
91
|
+
tooltip.attr({
|
|
92
|
+
x: position.x,
|
|
93
|
+
y: position.y,
|
|
94
|
+
class: `dr-renderer-tooltip ${position.direction}`,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (options.showArrow) {
|
|
98
|
+
this.setArrowPosition(tooltip, position, anchor, options);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.setArrowPosition = function(tooltip, position, anchor, options) {
|
|
103
|
+
const arrowEl = tooltip.element.querySelector(".dr-renderer-tooltip_arrow");
|
|
104
|
+
const anchorBox = this.getAnchorBox(anchor);
|
|
105
|
+
const tooltipBox = tooltip.getBBox();
|
|
106
|
+
arrowEl.removeAttribute("style");
|
|
107
|
+
const styles = {
|
|
108
|
+
position: "absolute",
|
|
109
|
+
display: "block",
|
|
110
|
+
width: `${options.arrowSize}px`,
|
|
111
|
+
height: `${options.arrowSize}px`,
|
|
112
|
+
transform: "rotate(-45deg)",
|
|
113
|
+
"border-style": "solid",
|
|
114
|
+
"border-width": `${options.border}px`,
|
|
115
|
+
background: options.background,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
switch (position.direction) {
|
|
119
|
+
case "top":
|
|
120
|
+
Object.assign(styles, {
|
|
121
|
+
"border-color": `transparent transparent ${options.borderColor} ${options.borderColor}`,
|
|
122
|
+
"border-bottom-left-radius": `${options.arrowRadius}px`,
|
|
123
|
+
bottom: `-${options.arrowSize / 2}px`,
|
|
124
|
+
left: `${helpers.clamp(
|
|
125
|
+
options.borderRadius,
|
|
126
|
+
Math.max(anchorBox.x - position.x, 0) +
|
|
127
|
+
Math.min(anchorBox.width, tooltipBox.width) / 2 -
|
|
128
|
+
options.arrowSize / 2,
|
|
129
|
+
tooltipBox.width - options.arrowSize - options.borderRadius
|
|
130
|
+
)}px`,
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
case "bottom":
|
|
134
|
+
Object.assign(styles, {
|
|
135
|
+
"border-color": `${options.borderColor} ${options.borderColor} transparent transparent`,
|
|
136
|
+
"border-top-right-radius": `${options.arrowRadius}px`,
|
|
137
|
+
top: `-${options.arrowSize / 2}px`,
|
|
138
|
+
left: `${helpers.clamp(
|
|
139
|
+
options.borderRadius,
|
|
140
|
+
Math.max(anchorBox.x - position.x, 0) +
|
|
141
|
+
Math.min(anchorBox.width, tooltipBox.width) / 2 -
|
|
142
|
+
options.arrowSize / 2,
|
|
143
|
+
tooltipBox.width - options.arrowSize - options.borderRadius
|
|
144
|
+
)}px`,
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
147
|
+
case "left":
|
|
148
|
+
Object.assign(styles, {
|
|
149
|
+
"border-color": `transparent ${options.borderColor} ${options.borderColor} transparent`,
|
|
150
|
+
"border-bottom-right-radius": `${options.arrowRadius}px`,
|
|
151
|
+
right: `-${options.arrowSize / 2}px`,
|
|
152
|
+
top: `${helpers.clamp(
|
|
153
|
+
options.borderRadius,
|
|
154
|
+
Math.max(anchorBox.y - position.y, 0) +
|
|
155
|
+
Math.min(anchorBox.height, tooltipBox.height) / 2 -
|
|
156
|
+
options.arrowSize / 2,
|
|
157
|
+
tooltipBox.height - options.arrowSize - options.borderRadius
|
|
158
|
+
)}px`,
|
|
159
|
+
});
|
|
160
|
+
break;
|
|
161
|
+
case "right":
|
|
162
|
+
Object.assign(styles, {
|
|
163
|
+
"border-color": `${options.borderColor} transparent transparent ${options.borderColor}`,
|
|
164
|
+
"border-top-left-radius": `${options.arrowRadius}px`,
|
|
165
|
+
left: `-${options.arrowSize / 2}px`,
|
|
166
|
+
top: `${helpers.clamp(
|
|
167
|
+
options.borderRadius,
|
|
168
|
+
Math.max(anchorBox.y - position.y, 0) +
|
|
169
|
+
Math.min(anchorBox.height, tooltipBox.height) / 2 -
|
|
170
|
+
options.arrowSize / 2,
|
|
171
|
+
tooltipBox.height - options.arrowSize - options.borderRadius
|
|
172
|
+
)}px`,
|
|
173
|
+
});
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
arrowEl.setAttribute(
|
|
178
|
+
"style",
|
|
179
|
+
Object.keys(styles)
|
|
180
|
+
.map((key) => `${key}:${styles[key]}`)
|
|
181
|
+
.join(";")
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.getCoords = function(direction, tooltip, anchor, options) {
|
|
186
|
+
const tooltipBox = tooltip.getBBox();
|
|
187
|
+
const anchorBox = this.getAnchorBox(anchor);
|
|
188
|
+
switch (direction) {
|
|
189
|
+
case "top":
|
|
190
|
+
return {
|
|
191
|
+
x: helpers.clamp(
|
|
192
|
+
options.outerOffset,
|
|
193
|
+
anchorBox.x + anchorBox.width / 2 - tooltipBox.width / 2,
|
|
194
|
+
this.chart.chartWidth - tooltipBox.width - options.outerOffset
|
|
195
|
+
),
|
|
196
|
+
y: anchorBox.y - tooltipBox.height - options.anchorOffset,
|
|
197
|
+
};
|
|
198
|
+
case "bottom":
|
|
199
|
+
return {
|
|
200
|
+
x: helpers.clamp(
|
|
201
|
+
options.outerOffset,
|
|
202
|
+
anchorBox.x + anchorBox.width / 2 - tooltipBox.width / 2,
|
|
203
|
+
this.chart.chartWidth - tooltipBox.width - options.outerOffset
|
|
204
|
+
),
|
|
205
|
+
y: anchorBox.y + anchorBox.height + options.anchorOffset,
|
|
206
|
+
};
|
|
207
|
+
case "left":
|
|
208
|
+
return {
|
|
209
|
+
x: anchorBox.x - tooltipBox.width - options.anchorOffset,
|
|
210
|
+
y: helpers.clamp(
|
|
211
|
+
options.outerOffset,
|
|
212
|
+
anchorBox.y + anchorBox.height / 2 - tooltipBox.height / 2,
|
|
213
|
+
this.chart.chartHeight - tooltipBox.height - options.outerOffset
|
|
214
|
+
),
|
|
215
|
+
};
|
|
216
|
+
case "right":
|
|
217
|
+
return {
|
|
218
|
+
x: anchorBox.x + anchorBox.width + options.anchorOffset,
|
|
219
|
+
y: helpers.clamp(
|
|
220
|
+
options.outerOffset,
|
|
221
|
+
anchorBox.y + anchorBox.height / 2 - tooltipBox.height / 2,
|
|
222
|
+
this.chart.chartHeight - tooltipBox.height - options.outerOffset
|
|
223
|
+
),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.getAnchorBox = function(el) {
|
|
229
|
+
if (el.getBBox) {
|
|
230
|
+
return el.getBBox();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const containerRect = this.chart.container.getBoundingClientRect();
|
|
234
|
+
|
|
235
|
+
if (el.getBoundingClientRect) {
|
|
236
|
+
const elRect = el.getBoundingClientRect();
|
|
237
|
+
return {
|
|
238
|
+
x: elRect.x - containerRect.x,
|
|
239
|
+
y: elRect.y - containerRect.y,
|
|
240
|
+
width: elRect.width,
|
|
241
|
+
height: elRect.height,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
x: el.x - containerRect.x,
|
|
246
|
+
y: el.y - containerRect.y,
|
|
247
|
+
width: 0,
|
|
248
|
+
height: 0,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
this.getPosition = function(tooltip, anchor, options) {
|
|
253
|
+
const bbox = tooltip.getBBox();
|
|
254
|
+
|
|
255
|
+
for (let direction of [options.direction, ...["top", "right", "bottom", "left"].filter((d) => d !== options.direction)]) {
|
|
256
|
+
const coords = this.getCoords(direction, tooltip, anchor, options);
|
|
257
|
+
|
|
258
|
+
if (
|
|
259
|
+
coords.x >= 0 &&
|
|
260
|
+
coords.x <= this.chart.chartWidth - bbox.width &&
|
|
261
|
+
coords.y >= 0 &&
|
|
262
|
+
coords.y <= this.chart.chartHeight - bbox.height
|
|
263
|
+
) {
|
|
264
|
+
return {
|
|
265
|
+
x: coords.x,
|
|
266
|
+
y: coords.y,
|
|
267
|
+
direction: direction,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this.chart = chart;
|
|
274
|
+
this.options = Object.assign({}, DR_TOOLTIP_OPTIONS_DEFAULT, options);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
module.exports = { DrChartTooltip, DR_TOOLTIP_OPTIONS_DEFAULT };
|