@datarailsshared/dr_renderer 1.1.41 → 1.2.2

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.
@@ -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 };