gridviz 2.1.9 → 2.1.10

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.
Files changed (57) hide show
  1. package/README.md +125 -125
  2. package/dist/gridviz.js +8036 -8024
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +77 -77
  5. package/src/App.js +705 -705
  6. package/src/BackgroundLayer.js +182 -182
  7. package/src/BackgroundLayerWMS.js +131 -131
  8. package/src/Dataset.js +76 -76
  9. package/src/DatasetComponent.js +113 -101
  10. package/src/GeoCanvas.js +420 -420
  11. package/src/LabelLayer.js +190 -190
  12. package/src/Layer.js +103 -103
  13. package/src/Legend.js +86 -86
  14. package/src/LineLayer.js +150 -150
  15. package/src/Style.js +129 -129
  16. package/src/Tooltip.js +180 -180
  17. package/src/dataset/COGeo.js +24 -24
  18. package/src/dataset/CSVGrid.js +104 -104
  19. package/src/dataset/GeoTIFF.js +127 -127
  20. package/src/dataset/GridTile.js +41 -41
  21. package/src/dataset/LGrid.js +54 -54
  22. package/src/dataset/TiledGrid.js +264 -264
  23. package/src/index.js +71 -71
  24. package/src/legend/ColorCategoryLegend.js +124 -124
  25. package/src/legend/ColorDiscreteLegend.js +103 -103
  26. package/src/legend/ColorLegend.js +124 -124
  27. package/src/legend/SegmentOrientationLegend.js +87 -87
  28. package/src/legend/SegmentWidthLegend.js +97 -97
  29. package/src/legend/SizeLegend.js +141 -141
  30. package/src/style/CompositionStyle.js +300 -300
  31. package/src/style/ContourStyle.js +54 -54
  32. package/src/style/DotDensityStyle.js +156 -156
  33. package/src/style/IsoFenceStyle.js +262 -262
  34. package/src/style/JoyPlotStyle.js +135 -135
  35. package/src/style/LegoStyle.js +112 -112
  36. package/src/style/MosaicStyle.js +107 -107
  37. package/src/style/NinjaStarStyle.js +125 -125
  38. package/src/style/PillarStyle.js +230 -230
  39. package/src/style/SegmentStyle.js +142 -142
  40. package/src/style/ShapeColorSizeStyle.js +126 -126
  41. package/src/style/SideCatStyle.js +172 -172
  42. package/src/style/SideStyle.js +216 -216
  43. package/src/style/SquareColorCatWGLStyle.js +120 -120
  44. package/src/style/SquareColorWGLStyle.js +146 -146
  45. package/src/style/StrokeStyle.js +131 -131
  46. package/src/style/TanakaStyle.js +160 -160
  47. package/src/style/TextStyle.js +132 -132
  48. package/src/style/TimeSeriesStyle.js +250 -250
  49. package/src/utils/Utils.js +35 -35
  50. package/src/utils/WebGLRectangleColoring.js +106 -106
  51. package/src/utils/WebGLSquareColoring.js +118 -118
  52. package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
  53. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
  54. package/src/utils/WebGLSquareColoringKS.js +153 -153
  55. package/src/utils/stretching.js +131 -131
  56. package/src/utils/webGLUtils.js +71 -71
  57. package/src/utils/zoomUtils.js +142 -142
package/src/Style.js CHANGED
@@ -1,129 +1,129 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- /**
5
- * Statistics of a set of values
6
- * @typedef {{min:number,max:number}} Stat */
7
-
8
- /** @typedef {"square"|"circle"|"diamond"|"donut"|"none"} Shape */
9
-
10
- /**
11
- * A style, to show a grid dataset.
12
- *
13
- * @abstract
14
- *
15
- * @author Joseph Davies, Julien Gaffuri
16
- */
17
- export class Style {
18
- /**
19
- * @abstract
20
- * @param {{filter?:function(import('./Dataset').Cell):boolean,offset?:function(import('./Dataset').Cell,number,number):{dx:number,dy:number},visible?:boolean,alpha?:function(number):number,blendOperation?:function(number):GlobalCompositeOperation,minZoom?:number,maxZoom?:number}} opts
21
- * minZoom: The minimum zoom level when to show the layer. maxZoom: The maximum zoom level when to show the layer
22
- */
23
- constructor(opts) {
24
- opts = opts || {}
25
-
26
- /** A filter function to apply to the cell list, to filter out some cells not to be drawn (such as for example the cells with value=0).
27
- * @protected
28
- * @type {function(import('./Dataset').Cell):boolean} */
29
- this.filter = opts.filter || (() => true)
30
-
31
- /** An offset. This is to alter the position of all symbols in a given direction. In geographical unit.
32
- * @protected
33
- * @type {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
34
- this.offset = opts.offset || ((c, r, zf) => ({ dx: 0, dy: 0 }))
35
-
36
- /** An attribute to specify if a style should be drawn or not
37
- * @type {boolean} */
38
- this.visible = opts.visible === false ? false : true
39
-
40
- /** A function returning the alpha (transparency/opacity), between 0.0 (fully transparent) and 1.0 (fully opaque).
41
- * The function parameter is the zoom factor.
42
- * (see CanvasRenderingContext2D: globalAlpha property)
43
- * @type {function(number):number|undefined} */
44
- this.alpha = opts.alpha
45
-
46
- /** A function returning the blend operation. The function parameter is the zoom factor.
47
- * (see CanvasRenderingContext2D: globalCompositeOperation property)
48
- * @type {function(number):GlobalCompositeOperation} */
49
- this.blendOperation = opts.blendOperation || (zf => "source-over")
50
-
51
- /** The minimum zoom factor: Below this level, the layer is not shown.
52
- * @type {number}
53
- * */
54
- this.minZoom = opts.minZoom || 0
55
-
56
- /** The maximum zoom factor: Above this level, the layer is not shown.
57
- * @type {number}
58
- * */
59
- this.maxZoom = opts.maxZoom || Infinity
60
-
61
- //ensure acceptable values for the zoom limits.
62
- if (this.minZoom >= this.maxZoom)
63
- throw new Error('Unexpected zoom limits for layer. Zoom min should be smaller than zoom max.')
64
-
65
- /**
66
- * @public
67
- * @type {Array.<import("./Legend").Legend>} */
68
- this.legends = []
69
- }
70
-
71
- /**
72
- * Draw cells.
73
- *
74
- * @param {Array.<import('./Dataset').Cell>} cells The cells to draw.
75
- * @param {number} resolution Their resolution (in geographic unit)
76
- * @param {import("./GeoCanvas").GeoCanvas} cg The canvas where to draw them.
77
- * @abstract
78
- */
79
- draw(cells, resolution, cg) {
80
- throw new Error('Method draw not implemented.')
81
- }
82
-
83
- //getters and setters
84
-
85
- /** @returns {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
86
- getOffset() {
87
- return this.offset
88
- }
89
- /** @param {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} val @returns {this} */
90
- setOffset(val) {
91
- this.offset = val
92
- return this
93
- }
94
-
95
- /** Hide all legend elements of the style, if any
96
- * @param {object} opts
97
- * @returns {this} */
98
- updateLegends(opts) {
99
- for (const lg of this.legends) lg.update(opts)
100
- return this
101
- }
102
-
103
- /**
104
- * Compute some statistics on a value of some cells.
105
- * This is used to define how to draw specifically the cells within the view.
106
- * TODO: compute median ?
107
- *
108
- * @param {Array.<import('./Dataset').Cell>} cells
109
- * @param {function(import('./Dataset').Cell):number} valFun
110
- * @param {boolean} ignoreZeros
111
- * @returns {Stat | undefined}
112
- */
113
- static getStatistics(cells, valFun, ignoreZeros) {
114
- if (!cells || cells.length == 0) return undefined
115
- let min = Infinity
116
- let max = -Infinity
117
- //let sum = 0
118
- //let nb = 0
119
- for (const cell of cells) {
120
- const v = +valFun(cell)
121
- if (ignoreZeros && !v) continue
122
- if (v < min) min = v
123
- if (v > max) max = v
124
- //sum += v
125
- //nb++
126
- }
127
- return { min: min, max: max }
128
- }
129
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ /**
5
+ * Statistics of a set of values
6
+ * @typedef {{min:number,max:number}} Stat */
7
+
8
+ /** @typedef {"square"|"circle"|"diamond"|"donut"|"none"} Shape */
9
+
10
+ /**
11
+ * A style, to show a grid dataset.
12
+ *
13
+ * @abstract
14
+ *
15
+ * @author Joseph Davies, Julien Gaffuri
16
+ */
17
+ export class Style {
18
+ /**
19
+ * @abstract
20
+ * @param {{filter?:function(import('./Dataset').Cell):boolean,offset?:function(import('./Dataset').Cell,number,number):{dx:number,dy:number},visible?:boolean,alpha?:function(number):number,blendOperation?:function(number):GlobalCompositeOperation,minZoom?:number,maxZoom?:number}} opts
21
+ * minZoom: The minimum zoom level when to show the layer. maxZoom: The maximum zoom level when to show the layer
22
+ */
23
+ constructor(opts) {
24
+ opts = opts || {}
25
+
26
+ /** A filter function to apply to the cell list, to filter out some cells not to be drawn (such as for example the cells with value=0).
27
+ * @protected
28
+ * @type {function(import('./Dataset').Cell):boolean} */
29
+ this.filter = opts.filter || (() => true)
30
+
31
+ /** An offset. This is to alter the position of all symbols in a given direction. In geographical unit.
32
+ * @protected
33
+ * @type {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
34
+ this.offset = opts.offset || ((c, r, zf) => ({ dx: 0, dy: 0 }))
35
+
36
+ /** An attribute to specify if a style should be drawn or not
37
+ * @type {boolean} */
38
+ this.visible = opts.visible === false ? false : true
39
+
40
+ /** A function returning the alpha (transparency/opacity), between 0.0 (fully transparent) and 1.0 (fully opaque).
41
+ * The function parameter is the zoom factor.
42
+ * (see CanvasRenderingContext2D: globalAlpha property)
43
+ * @type {function(number):number|undefined} */
44
+ this.alpha = opts.alpha
45
+
46
+ /** A function returning the blend operation. The function parameter is the zoom factor.
47
+ * (see CanvasRenderingContext2D: globalCompositeOperation property)
48
+ * @type {function(number):GlobalCompositeOperation} */
49
+ this.blendOperation = opts.blendOperation || (zf => "source-over")
50
+
51
+ /** The minimum zoom factor: Below this level, the layer is not shown.
52
+ * @type {number}
53
+ * */
54
+ this.minZoom = opts.minZoom || 0
55
+
56
+ /** The maximum zoom factor: Above this level, the layer is not shown.
57
+ * @type {number}
58
+ * */
59
+ this.maxZoom = opts.maxZoom || Infinity
60
+
61
+ //ensure acceptable values for the zoom limits.
62
+ if (this.minZoom >= this.maxZoom)
63
+ throw new Error('Unexpected zoom limits for layer. Zoom min should be smaller than zoom max.')
64
+
65
+ /**
66
+ * @public
67
+ * @type {Array.<import("./Legend").Legend>} */
68
+ this.legends = []
69
+ }
70
+
71
+ /**
72
+ * Draw cells.
73
+ *
74
+ * @param {Array.<import('./Dataset').Cell>} cells The cells to draw.
75
+ * @param {number} resolution Their resolution (in geographic unit)
76
+ * @param {import("./GeoCanvas").GeoCanvas} cg The canvas where to draw them.
77
+ * @abstract
78
+ */
79
+ draw(cells, resolution, cg) {
80
+ throw new Error('Method draw not implemented.')
81
+ }
82
+
83
+ //getters and setters
84
+
85
+ /** @returns {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
86
+ getOffset() {
87
+ return this.offset
88
+ }
89
+ /** @param {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} val @returns {this} */
90
+ setOffset(val) {
91
+ this.offset = val
92
+ return this
93
+ }
94
+
95
+ /** Hide all legend elements of the style, if any
96
+ * @param {object} opts
97
+ * @returns {this} */
98
+ updateLegends(opts) {
99
+ for (const lg of this.legends) lg.update(opts)
100
+ return this
101
+ }
102
+
103
+ /**
104
+ * Compute some statistics on a value of some cells.
105
+ * This is used to define how to draw specifically the cells within the view.
106
+ * TODO: compute median ?
107
+ *
108
+ * @param {Array.<import('./Dataset').Cell>} cells
109
+ * @param {function(import('./Dataset').Cell):number} valFun
110
+ * @param {boolean} ignoreZeros
111
+ * @returns {Stat | undefined}
112
+ */
113
+ static getStatistics(cells, valFun, ignoreZeros) {
114
+ if (!cells || cells.length == 0) return undefined
115
+ let min = Infinity
116
+ let max = -Infinity
117
+ //let sum = 0
118
+ //let nb = 0
119
+ for (const cell of cells) {
120
+ const v = +valFun(cell)
121
+ if (ignoreZeros && !v) continue
122
+ if (v < min) min = v
123
+ if (v > max) max = v
124
+ //sum += v
125
+ //nb++
126
+ }
127
+ return { min: min, max: max }
128
+ }
129
+ }
package/src/Tooltip.js CHANGED
@@ -1,180 +1,180 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { select } from 'd3-selection'
5
- //import { transition } from "d3-transition";
6
-
7
- /**
8
- * A generic class to make a tooltip.
9
- * It is a div element, which can be moved under the mouse pointer and filled with some information in html.
10
- */
11
- export class Tooltip {
12
- /**
13
- * @param {object} opts
14
- */
15
- constructor(opts) {
16
- opts = opts || {}
17
-
18
- /** @type {string} */
19
- this.div = opts.div || 'tooltip_eurostat'
20
- /** @type {string} */
21
- this.maxWidth = opts.maxWidth || '20em'
22
- /** @type {string} */
23
- this.fontSize = opts.fontSize || '1.2em'
24
- /** @type {string} */
25
- this.background = opts.background || 'white'
26
- /** @type {string} */
27
- this.padding = opts.padding || '5px'
28
- /** @type {string} */
29
- this.border = opts.border || '0px'
30
- /** @type {string} */
31
- this['border-radius'] = opts['border-radius'] || '5px'
32
- /** @type {string} */
33
- this['box-shadow'] = opts['box-shadow'] || '5px 5px 5px grey'
34
- /** @type {string} */
35
- this['font-family'] = opts['font-family'] || 'Helvetica, Arial, sans-serif'
36
-
37
- /** @type {number} */
38
- this.transitionDuration = opts.transitionDuration || 100
39
- /** @type {number} */
40
- this.xOffset = opts.xOffset || 30
41
- /** @type {number} */
42
- this.yOffset = opts.yOffset || 20
43
- /** @type {number} */ // e.g. to prevent mouse cursor covering cell being highlighted
44
- this.yMouseOffset = opts.yMouseOffset || 0
45
- /** @type {number} */
46
- this.xMouseOffset = opts.xMouseOffset || 0
47
- /** @type {HTMLElement} */
48
- this.parentElement = opts.parentElement || document.body
49
-
50
- /**
51
- * @public
52
- * @type {import("d3-selection").Selection} */
53
- this.tooltip = select('#' + this.div)
54
- if (this.tooltip.empty())
55
- this.tooltip = select(
56
- '#' + this.parentElement.id && this.parentElement.id != ''
57
- ? '#' + this.parentElement.id
58
- : 'body'
59
- )
60
- .append('div')
61
- .attr('id', this.div)
62
-
63
- //initialise
64
- this.tooltip.style('max-width', this.maxWidth)
65
- this.tooltip.style('overflow', 'hidden')
66
- this.tooltip.style('font-size', this.fontSize)
67
- this.tooltip.style('background', this.background)
68
- this.tooltip.style('padding', this.padding)
69
- this.tooltip.style('border', this.border)
70
- this.tooltip.style('border-radius', this['border-radius'])
71
- this.tooltip.style('box-shadow', this['box-shadow'])
72
- this.tooltip.style('font-family', this['font-family'])
73
- this.tooltip.style('position', 'absolute')
74
- this.tooltip.style('pointer-events', 'none')
75
- this.tooltip.style('opacity', '0')
76
- this.tooltip.style('text-wrap', 'nowrap')
77
-
78
- // aria-labels (thanks to wahlatlas)
79
- this.tooltip.attr('role', 'tooltip').attr('aria-live', 'polite')
80
- }
81
-
82
- /** Show the tooltip */
83
- show() {
84
- // @ts-ignore
85
- this.tooltip.transition().duration(this.transitionDuration).style('opacity', 1)
86
- }
87
-
88
- /** Hide the tooltip */
89
- hide() {
90
- // @ts-ignore
91
- this.tooltip.transition().duration(this.transitionDuration).style('opacity', 0)
92
- }
93
-
94
- /**
95
- * Set the content of the tooltip.
96
- * @param {string} html
97
- */
98
- html(html) {
99
- this.tooltip.html(html)
100
- }
101
-
102
- /**
103
- * Set the position of the tooltip at the mouse event position.
104
- * @param {MouseEvent} event
105
- */
106
- setPosition(event) {
107
- let parentRect = this.parentElement.getBoundingClientRect()
108
-
109
- let x = event.pageX + this.xOffset
110
- let y = event.pageY - this.yOffset
111
-
112
- this.tooltip.style('left', x + 'px').style('top', y + 'px')
113
-
114
- this.ensureTooltipInsideContainer(event, parentRect)
115
- }
116
-
117
- /*
118
- my.mouseover = function (event, html) {
119
- if (html) my.html(html);
120
- my.setPosition(event);
121
- my.show()
122
- //this.ensureTooltipInsideContainer();
123
- };
124
-
125
- my.mousemove = function (event) {
126
- my.setPosition(event);
127
- //this.ensureTooltipInsideContainer();
128
- };
129
-
130
- my.mouseout = function () {
131
- my.hide();
132
- };*/
133
-
134
- style(k, v) {
135
- if (arguments.length == 1) return this.tooltip.style(k)
136
- this.tooltip.style(k, v)
137
- return this
138
- }
139
-
140
- attr(k, v) {
141
- if (arguments.length == 1) return this.tooltip.attr(k)
142
- this.tooltip.attr(k, v)
143
- return this
144
- }
145
-
146
- /**
147
- * @function ensureTooltipInsideContainer
148
- * @description Prevents the tooltip from overflowing out of the App container (ensures that the tooltip is inside the gridviz container)
149
- * @param {MouseEvent} event
150
- * @param {DOMRect} parentRect
151
- */
152
- ensureTooltipInsideContainer = function (event, parentRect) {
153
- let node = this.tooltip.node()
154
- let parentWidth = parentRect.width
155
- let parentHeight = parentRect.height
156
-
157
- //too far right
158
- if (node.offsetLeft > parentRect.left + parentWidth - node.clientWidth) {
159
- let left = event.x - node.clientWidth - this.xOffset
160
- node.style.left = left + 'px'
161
- // check if mouse covers tooltip
162
- if (node.offsetLeft + node.clientWidth > event.x) {
163
- //move tooltip left so it doesnt cover mouse
164
- let left2 = event.x - node.clientWidth - this.xOffset
165
- node.style.left = left2 + 'px'
166
- }
167
- // node.style.top = node.offsetTop + config.yOffset + "px";
168
- }
169
-
170
- //too far down
171
- if (node.offsetTop + node.clientHeight > parentRect.top + parentHeight) {
172
- node.style.top = node.offsetTop - node.clientHeight + 'px'
173
- }
174
-
175
- //too far up
176
- if (node.offsetTop < parentRect.top) {
177
- node.style.top = parentRect.top + this.yOffset + 'px'
178
- }
179
- }
180
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { select } from 'd3-selection'
5
+ //import { transition } from "d3-transition";
6
+
7
+ /**
8
+ * A generic class to make a tooltip.
9
+ * It is a div element, which can be moved under the mouse pointer and filled with some information in html.
10
+ */
11
+ export class Tooltip {
12
+ /**
13
+ * @param {object} opts
14
+ */
15
+ constructor(opts) {
16
+ opts = opts || {}
17
+
18
+ /** @type {string} */
19
+ this.div = opts.div || 'tooltip_eurostat'
20
+ /** @type {string} */
21
+ this.maxWidth = opts.maxWidth || '20em'
22
+ /** @type {string} */
23
+ this.fontSize = opts.fontSize || '1.2em'
24
+ /** @type {string} */
25
+ this.background = opts.background || 'white'
26
+ /** @type {string} */
27
+ this.padding = opts.padding || '5px'
28
+ /** @type {string} */
29
+ this.border = opts.border || '0px'
30
+ /** @type {string} */
31
+ this['border-radius'] = opts['border-radius'] || '5px'
32
+ /** @type {string} */
33
+ this['box-shadow'] = opts['box-shadow'] || '5px 5px 5px grey'
34
+ /** @type {string} */
35
+ this['font-family'] = opts['font-family'] || 'Helvetica, Arial, sans-serif'
36
+
37
+ /** @type {number} */
38
+ this.transitionDuration = opts.transitionDuration || 100
39
+ /** @type {number} */
40
+ this.xOffset = opts.xOffset || 30
41
+ /** @type {number} */
42
+ this.yOffset = opts.yOffset || 20
43
+ /** @type {number} */ // e.g. to prevent mouse cursor covering cell being highlighted
44
+ this.yMouseOffset = opts.yMouseOffset || 0
45
+ /** @type {number} */
46
+ this.xMouseOffset = opts.xMouseOffset || 0
47
+ /** @type {HTMLElement} */
48
+ this.parentElement = opts.parentElement || document.body
49
+
50
+ /**
51
+ * @public
52
+ * @type {import("d3-selection").Selection} */
53
+ this.tooltip = select('#' + this.div)
54
+ if (this.tooltip.empty())
55
+ this.tooltip = select(
56
+ '#' + this.parentElement.id && this.parentElement.id != ''
57
+ ? '#' + this.parentElement.id
58
+ : 'body'
59
+ )
60
+ .append('div')
61
+ .attr('id', this.div)
62
+
63
+ //initialise
64
+ this.tooltip.style('max-width', this.maxWidth)
65
+ this.tooltip.style('overflow', 'hidden')
66
+ this.tooltip.style('font-size', this.fontSize)
67
+ this.tooltip.style('background', this.background)
68
+ this.tooltip.style('padding', this.padding)
69
+ this.tooltip.style('border', this.border)
70
+ this.tooltip.style('border-radius', this['border-radius'])
71
+ this.tooltip.style('box-shadow', this['box-shadow'])
72
+ this.tooltip.style('font-family', this['font-family'])
73
+ this.tooltip.style('position', 'absolute')
74
+ this.tooltip.style('pointer-events', 'none')
75
+ this.tooltip.style('opacity', '0')
76
+ this.tooltip.style('text-wrap', 'nowrap')
77
+
78
+ // aria-labels (thanks to wahlatlas)
79
+ this.tooltip.attr('role', 'tooltip').attr('aria-live', 'polite')
80
+ }
81
+
82
+ /** Show the tooltip */
83
+ show() {
84
+ // @ts-ignore
85
+ this.tooltip.transition().duration(this.transitionDuration).style('opacity', 1)
86
+ }
87
+
88
+ /** Hide the tooltip */
89
+ hide() {
90
+ // @ts-ignore
91
+ this.tooltip.transition().duration(this.transitionDuration).style('opacity', 0)
92
+ }
93
+
94
+ /**
95
+ * Set the content of the tooltip.
96
+ * @param {string} html
97
+ */
98
+ html(html) {
99
+ this.tooltip.html(html)
100
+ }
101
+
102
+ /**
103
+ * Set the position of the tooltip at the mouse event position.
104
+ * @param {MouseEvent} event
105
+ */
106
+ setPosition(event) {
107
+ let parentRect = this.parentElement.getBoundingClientRect()
108
+
109
+ let x = event.pageX + this.xOffset
110
+ let y = event.pageY - this.yOffset
111
+
112
+ this.tooltip.style('left', x + 'px').style('top', y + 'px')
113
+
114
+ this.ensureTooltipInsideContainer(event, parentRect)
115
+ }
116
+
117
+ /*
118
+ my.mouseover = function (event, html) {
119
+ if (html) my.html(html);
120
+ my.setPosition(event);
121
+ my.show()
122
+ //this.ensureTooltipInsideContainer();
123
+ };
124
+
125
+ my.mousemove = function (event) {
126
+ my.setPosition(event);
127
+ //this.ensureTooltipInsideContainer();
128
+ };
129
+
130
+ my.mouseout = function () {
131
+ my.hide();
132
+ };*/
133
+
134
+ style(k, v) {
135
+ if (arguments.length == 1) return this.tooltip.style(k)
136
+ this.tooltip.style(k, v)
137
+ return this
138
+ }
139
+
140
+ attr(k, v) {
141
+ if (arguments.length == 1) return this.tooltip.attr(k)
142
+ this.tooltip.attr(k, v)
143
+ return this
144
+ }
145
+
146
+ /**
147
+ * @function ensureTooltipInsideContainer
148
+ * @description Prevents the tooltip from overflowing out of the App container (ensures that the tooltip is inside the gridviz container)
149
+ * @param {MouseEvent} event
150
+ * @param {DOMRect} parentRect
151
+ */
152
+ ensureTooltipInsideContainer = function (event, parentRect) {
153
+ let node = this.tooltip.node()
154
+ let parentWidth = parentRect.width
155
+ let parentHeight = parentRect.height
156
+
157
+ //too far right
158
+ if (node.offsetLeft > parentRect.left + parentWidth - node.clientWidth) {
159
+ let left = event.x - node.clientWidth - this.xOffset
160
+ node.style.left = left + 'px'
161
+ // check if mouse covers tooltip
162
+ if (node.offsetLeft + node.clientWidth > event.x) {
163
+ //move tooltip left so it doesnt cover mouse
164
+ let left2 = event.x - node.clientWidth - this.xOffset
165
+ node.style.left = left2 + 'px'
166
+ }
167
+ // node.style.top = node.offsetTop + config.yOffset + "px";
168
+ }
169
+
170
+ //too far down
171
+ if (node.offsetTop + node.clientHeight > parentRect.top + parentHeight) {
172
+ node.style.top = node.offsetTop - node.clientHeight + 'px'
173
+ }
174
+
175
+ //too far up
176
+ if (node.offsetTop < parentRect.top) {
177
+ node.style.top = parentRect.top + this.yOffset + 'px'
178
+ }
179
+ }
180
+ }
@@ -1,24 +1,24 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { DatasetComponent } from '../DatasetComponent.js'
5
-
6
- /**
7
- * @todo
8
- * A dataset composed of a COGeo file.
9
- * @see https://www.cogeo.org/
10
- *
11
- * @author Joseph Davies, Julien Gaffuri
12
- */
13
- export class COGeo extends DatasetComponent {
14
- /**
15
- *
16
- * @param {String} url
17
- * @param {{preprocess?:(function(import("../Dataset").Cell):boolean)}} opts
18
- */
19
- constructor(url, opts = {}) {
20
- super(url, 0, opts)
21
- }
22
-
23
- //TODO Use https://geotiffjs.github.io/
24
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { DatasetComponent } from '../DatasetComponent.js'
5
+
6
+ /**
7
+ * @todo
8
+ * A dataset composed of a COGeo file.
9
+ * @see https://www.cogeo.org/
10
+ *
11
+ * @author Joseph Davies, Julien Gaffuri
12
+ */
13
+ export class COGeo extends DatasetComponent {
14
+ /**
15
+ *
16
+ * @param {String} url
17
+ * @param {{preprocess?:(function(import("../Dataset").Cell):boolean)}} opts
18
+ */
19
+ constructor(url, opts = {}) {
20
+ super(url, 0, opts)
21
+ }
22
+
23
+ //TODO Use https://geotiffjs.github.io/
24
+ }