gridviz 3.1.0 → 3.1.1
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/README.md +18 -15
- package/dist/gridviz.js +3829 -2623
- package/dist/gridviz.min.js +1 -1
- package/package.json +5 -3
- package/src/button/Button.js +77 -68
- package/src/button/FullscreenButton.js +123 -123
- package/src/button/ZoomButtons.js +109 -104
- package/src/core/GeoCanvas.js +15 -0
- package/src/core/Legend.js +267 -245
- package/src/core/Map.js +819 -670
- package/src/core/Tooltip.js +191 -185
- package/src/index.js +82 -79
- package/src/layer/GridLayer.js +4 -3
- package/src/layer/LabelLayer.js +7 -4
- package/src/legend/ColorCategoryLegend.js +127 -125
- package/src/legend/ColorDiscreteLegend.js +116 -114
- package/src/legend/ColorLegend.js +33 -11
- package/src/legend/OrientationLegend.js +94 -92
- package/src/legend/SizeLegend.js +8 -1
- package/src/legend/TernaryLegend.js +317 -314
- package/src/legend/VennLegend.js +202 -0
- package/src/style/CircleColorSizeWebGLStyle.js +249 -0
- package/src/style/CompositionStyle.js +1 -1
- package/src/style/DotDensityStyle.js +8 -4
- package/src/style/ImageStyle.js +1 -1
- package/src/style/Interpolator.js +283 -259
- package/src/style/IsoFenceStyle.js +1 -1
- package/src/style/LegoStyle.js +6 -5
- package/src/style/MosaicStyle.js +1 -1
- package/src/style/NinjaStarStyle.js +1 -1
- package/src/style/PillarStyle.js +1 -1
- package/src/style/RandomWalkInterpolator.js +213 -0
- package/src/style/ShadingRayStyle.js +16 -2
- package/src/style/ShadingStyle.js +80 -72
- package/src/style/ShapeColorSizeStyle.js +18 -2
- package/src/style/SideCategoryStyle.js +1 -1
- package/src/style/SideStyle.js +1 -1
- package/src/style/SideTanakaStyle.js +1 -1
- package/src/style/SquareColorCategoryWebGLStyle.js +71 -20
- package/src/style/SquareColorWebGLStyle.js +7 -4
- package/src/style/StrokeStyle.js +1 -1
- package/src/style/TextStyle.js +1 -1
- package/src/style/TimeSeriesStyle.js +14 -7
- package/src/utils/WebGLSquareColoringAdvanced.js +47 -9
- package/src/utils/scale.js +20 -0
- package/src/utils/webGLUtils.js +52 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gridviz",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Visualization tool for gridded statistics",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"statistics",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"doc": "jsdoc -c docs/jsdoc/jsdoc.conf.json",
|
|
43
43
|
"build-prod": "webpack --config webpack.config.prod.cjs",
|
|
44
44
|
"test": "node --test \"test/*.test.js\"",
|
|
45
|
+
"test:browser": "node test/browser/run.mjs",
|
|
45
46
|
"format": "prettier --write ."
|
|
46
47
|
},
|
|
47
48
|
"files": [
|
|
@@ -55,13 +56,14 @@
|
|
|
55
56
|
"d3-random": "^3.0.1",
|
|
56
57
|
"d3-scale": "^4.0.2",
|
|
57
58
|
"d3-selection": "^3.0.0",
|
|
58
|
-
"d3-zoom": "^3.0.0"
|
|
59
|
-
"jsdoc": "^4.0.4"
|
|
59
|
+
"d3-zoom": "^3.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@babel/preset-env": "^7.25.4",
|
|
63
63
|
"babel-loader": "^8.1.0",
|
|
64
|
+
"jsdoc": "^4.0.4",
|
|
64
65
|
"jshint": "^2.12.0",
|
|
66
|
+
"playwright-core": "^1.64.1",
|
|
65
67
|
"prettier": "^2.8.8",
|
|
66
68
|
"webpack": "^5.96.1",
|
|
67
69
|
"webpack-cli": "^5.1.4",
|
package/src/button/Button.js
CHANGED
|
@@ -1,68 +1,77 @@
|
|
|
1
|
-
import { select } from 'd3-selection'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Parent class for button elements used to interact with the gridviz viewer.
|
|
5
|
-
*
|
|
6
|
-
* @module button
|
|
7
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
-
*/
|
|
9
|
-
export class Button {
|
|
10
|
-
/**
|
|
11
|
-
* @param {Object} opts
|
|
12
|
-
* opts.parentNode
|
|
13
|
-
* opts.id
|
|
14
|
-
* opts.title
|
|
15
|
-
* opts.class
|
|
16
|
-
* opts.onClickFunction
|
|
17
|
-
* opts.x
|
|
18
|
-
* opts.y
|
|
19
|
-
*/
|
|
20
|
-
constructor(opts = {}) {
|
|
21
|
-
this.map = opts.map
|
|
22
|
-
this.parentNode = opts.parentNode || opts.map.container
|
|
23
|
-
|
|
24
|
-
// the div element
|
|
25
|
-
if (opts.id) this.div = select('#' + opts.id)
|
|
26
|
-
|
|
27
|
-
if (!this.div || this.div.empty()) {
|
|
28
|
-
this.div = select(document.createElement('div'))
|
|
29
|
-
if (opts.id) this.div.attr('id', opts.id)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (opts.title) this.div.attr('title', opts.title)
|
|
33
|
-
this.div.classed('gridviz-button', true)
|
|
34
|
-
if (opts.class) for (const c of String(opts.class).split(/\s+/)) if (c) this.div.classed(c, true)
|
|
35
|
-
|
|
36
|
-
// add events
|
|
37
|
-
if (opts.onClickFunction) this.div.on('click', opts.onClickFunction)
|
|
38
|
-
|
|
39
|
-
//set styles
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.style('
|
|
45
|
-
this.style('
|
|
46
|
-
this.style('
|
|
47
|
-
this.style('
|
|
48
|
-
this.style('
|
|
49
|
-
this.style('
|
|
50
|
-
this.style('
|
|
51
|
-
this.style('
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
import { select } from 'd3-selection'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parent class for button elements used to interact with the gridviz viewer.
|
|
5
|
+
*
|
|
6
|
+
* @module button
|
|
7
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
+
*/
|
|
9
|
+
export class Button {
|
|
10
|
+
/**
|
|
11
|
+
* @param {Object} opts
|
|
12
|
+
* opts.parentNode
|
|
13
|
+
* opts.id
|
|
14
|
+
* opts.title
|
|
15
|
+
* opts.class
|
|
16
|
+
* opts.onClickFunction
|
|
17
|
+
* opts.x
|
|
18
|
+
* opts.y
|
|
19
|
+
*/
|
|
20
|
+
constructor(opts = {}) {
|
|
21
|
+
this.map = opts.map
|
|
22
|
+
this.parentNode = opts.parentNode || opts.map.container
|
|
23
|
+
|
|
24
|
+
// the div element
|
|
25
|
+
if (opts.id) this.div = select('#' + opts.id)
|
|
26
|
+
|
|
27
|
+
if (!this.div || this.div.empty()) {
|
|
28
|
+
this.div = select(document.createElement('div'))
|
|
29
|
+
if (opts.id) this.div.attr('id', opts.id)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (opts.title) this.div.attr('title', opts.title)
|
|
33
|
+
this.div.classed('gridviz-button', true)
|
|
34
|
+
if (opts.class) for (const c of String(opts.class).split(/\s+/)) if (c) this.div.classed(c, true)
|
|
35
|
+
|
|
36
|
+
// add events
|
|
37
|
+
if (opts.onClickFunction) this.div.on('click', opts.onClickFunction)
|
|
38
|
+
|
|
39
|
+
//set styles: the look of the map controls of the statistical atlas (white, with a thin border and rounded corners).
|
|
40
|
+
//Each one is a CSS variable with the usual value as fallback, so that a page can change it without !important:
|
|
41
|
+
//--gridviz-button-color, --gridviz-button-background, --gridviz-button-hover-background, --gridviz-button-border-color,
|
|
42
|
+
//--gridviz-button-radius and --gridviz-button-size (the width and height, border included)
|
|
43
|
+
this.style('box-sizing', 'border-box')
|
|
44
|
+
this.style('box-shadow', 'none')
|
|
45
|
+
this.style('background-color', Button.BACKGROUND)
|
|
46
|
+
this.style('border', '1px solid var(--gridviz-button-border-color, #0e47cb)')
|
|
47
|
+
this.style('border-radius', 'var(--gridviz-button-radius, 10px)')
|
|
48
|
+
this.style('color', 'var(--gridviz-button-color, #0e47cb)')
|
|
49
|
+
this.style('overflow', 'hidden')
|
|
50
|
+
this.style('position', 'absolute')
|
|
51
|
+
this.style('cursor', 'pointer')
|
|
52
|
+
this.style('display', 'flex')
|
|
53
|
+
this.style('justify-content', 'center')
|
|
54
|
+
this.style('align-items', 'center')
|
|
55
|
+
this.style('width', 'var(--gridviz-button-size, 38px)')
|
|
56
|
+
this.style('height', 'var(--gridviz-button-size, 38px)')
|
|
57
|
+
|
|
58
|
+
// append to parent
|
|
59
|
+
this.parentNode.appendChild(this.div.node())
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The background of a button. */
|
|
63
|
+
static BACKGROUND = 'var(--gridviz-button-background, #ffffff)'
|
|
64
|
+
/** The background of a button when the mouse is over it. */
|
|
65
|
+
static HOVER_BACKGROUND = 'var(--gridviz-button-hover-background, #f4f4f4)'
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Apply a style to the button div.
|
|
69
|
+
* @param {string} k
|
|
70
|
+
* @param {string} v
|
|
71
|
+
* @returns {this}
|
|
72
|
+
*/
|
|
73
|
+
style(k, v) {
|
|
74
|
+
this.div.style(k, v)
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import { Button } from './Button.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Button for toggling fullscreen mode
|
|
5
|
-
*
|
|
6
|
-
* @module button
|
|
7
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
-
*/
|
|
9
|
-
export class FullscreenButton extends Button {
|
|
10
|
-
/**
|
|
11
|
-
* @param {Object} opts
|
|
12
|
-
* opts.parentNode - the node that the button is appended to
|
|
13
|
-
* opts.canvas - the gridviz canvas
|
|
14
|
-
* opts.id
|
|
15
|
-
* opts.title - HTML title attribute
|
|
16
|
-
* opts.class - css class
|
|
17
|
-
* opts.onClickFunction
|
|
18
|
-
* opts.x - x position of the button
|
|
19
|
-
* opts.y - y position of the button
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
// default state
|
|
23
|
-
isFullscreen = false
|
|
24
|
-
|
|
25
|
-
constructor(opts) {
|
|
26
|
-
super(opts)
|
|
27
|
-
this.div.classed('gridviz-fullscreen-button', true)
|
|
28
|
-
|
|
29
|
-
// append fullscreen icon to button container
|
|
30
|
-
this.div.node().innerHTML = `
|
|
31
|
-
<svg
|
|
32
|
-
class="gridviz-fullscreen-icon"
|
|
33
|
-
style="height:
|
|
34
|
-
focusable="false"
|
|
35
|
-
aria-hidden="true"
|
|
36
|
-
>
|
|
37
|
-
<svg fill="
|
|
38
|
-
<title/>
|
|
39
|
-
<g>
|
|
40
|
-
<path d="M30,0H6A5.9966,5.9966,0,0,0,0,6V30a6,6,0,0,0,12,0V12H30A6,6,0,0,0,30,0Z"/>
|
|
41
|
-
<path d="M90,0H66a6,6,0,0,0,0,12H84V30a6,6,0,0,0,12,0V6A5.9966,5.9966,0,0,0,90,0Z"/>
|
|
42
|
-
<path d="M30,84H12V66A6,6,0,0,0,0,66V90a5.9966,5.9966,0,0,0,6,6H30a6,6,0,0,0,0-12Z"/>
|
|
43
|
-
<path d="M90,60a5.9966,5.9966,0,0,0-6,6V84H66a6,6,0,0,0,0,12H90a5.9966,5.9966,0,0,0,6-6V66A5.9966,5.9966,0,0,0,90,60Z"/>
|
|
44
|
-
</g>
|
|
45
|
-
</svg>
|
|
46
|
-
</svg>
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
//save initial map dimensions
|
|
50
|
-
this.defaultHeight = this.map.h
|
|
51
|
-
this.defaultWidth = this.map.w
|
|
52
|
-
|
|
53
|
-
// event handler
|
|
54
|
-
this.div.on('click', (e) => {
|
|
55
|
-
this.onClickFunction(e)
|
|
56
|
-
})
|
|
57
|
-
this.div.on('mouseover', (e) => {
|
|
58
|
-
this.style('background-color',
|
|
59
|
-
})
|
|
60
|
-
this.div.on('mouseout', (e) => {
|
|
61
|
-
this.style('background-color',
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
//set position
|
|
65
|
-
if (opts.x) {
|
|
66
|
-
this.style('left', opts.x + 'px')
|
|
67
|
-
} else {
|
|
68
|
-
this.style('right', '10px')
|
|
69
|
-
}
|
|
70
|
-
if (opts.y) {
|
|
71
|
-
this.style('top', opts.y + 'px')
|
|
72
|
-
} else {
|
|
73
|
-
this.style('top', '90px')
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
onClickFunction(e) {
|
|
78
|
-
if (this.isFullscreen) {
|
|
79
|
-
this.closeFullscreen(this.map.container)
|
|
80
|
-
//resize canvas to default
|
|
81
|
-
this.map.h = this.defaultHeight
|
|
82
|
-
this.map.w = this.defaultWidth
|
|
83
|
-
this.map.geoCanvas.h = this.defaultHeight
|
|
84
|
-
this.map.geoCanvas.w = this.defaultWidth
|
|
85
|
-
this.map.geoCanvas.canvas.setAttribute('width', '' + this.defaultWidth)
|
|
86
|
-
this.map.geoCanvas.canvas.setAttribute('height', '' + this.defaultHeight)
|
|
87
|
-
this.map.redraw()
|
|
88
|
-
this.isFullscreen = false
|
|
89
|
-
} else {
|
|
90
|
-
this.openFullscreen(this.map.container)
|
|
91
|
-
//resize canvas to fullscreen
|
|
92
|
-
this.map.h = window.screen.height
|
|
93
|
-
this.map.w = window.screen.width
|
|
94
|
-
this.isFullscreen = true
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/* Open fullscreen */
|
|
99
|
-
openFullscreen(elem) {
|
|
100
|
-
if (elem.requestFullscreen) {
|
|
101
|
-
elem.requestFullscreen()
|
|
102
|
-
} else if (elem.webkitRequestFullscreen) {
|
|
103
|
-
/* Safari */
|
|
104
|
-
elem.webkitRequestFullscreen()
|
|
105
|
-
} else if (elem.msRequestFullscreen) {
|
|
106
|
-
/* IE11 */
|
|
107
|
-
elem.msRequestFullscreen()
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* Close fullscreen */
|
|
112
|
-
closeFullscreen() {
|
|
113
|
-
if (document.exitFullscreen) {
|
|
114
|
-
document.exitFullscreen()
|
|
115
|
-
} else if (document.webkitExitFullscreen) {
|
|
116
|
-
/* Safari */
|
|
117
|
-
document.webkitExitFullscreen()
|
|
118
|
-
} else if (document.msExitFullscreen) {
|
|
119
|
-
/* IE11 */
|
|
120
|
-
document.msExitFullscreen()
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
1
|
+
import { Button } from './Button.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Button for toggling fullscreen mode
|
|
5
|
+
*
|
|
6
|
+
* @module button
|
|
7
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
+
*/
|
|
9
|
+
export class FullscreenButton extends Button {
|
|
10
|
+
/**
|
|
11
|
+
* @param {Object} opts
|
|
12
|
+
* opts.parentNode - the node that the button is appended to
|
|
13
|
+
* opts.canvas - the gridviz canvas
|
|
14
|
+
* opts.id
|
|
15
|
+
* opts.title - HTML title attribute
|
|
16
|
+
* opts.class - css class
|
|
17
|
+
* opts.onClickFunction
|
|
18
|
+
* opts.x - x position of the button
|
|
19
|
+
* opts.y - y position of the button
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// default state
|
|
23
|
+
isFullscreen = false
|
|
24
|
+
|
|
25
|
+
constructor(opts) {
|
|
26
|
+
super(opts)
|
|
27
|
+
this.div.classed('gridviz-fullscreen-button', true)
|
|
28
|
+
|
|
29
|
+
// append fullscreen icon to button container
|
|
30
|
+
this.div.node().innerHTML = `
|
|
31
|
+
<svg
|
|
32
|
+
class="gridviz-fullscreen-icon"
|
|
33
|
+
style="height: 20px; width: 20px; fill: currentColor; margin:0;"
|
|
34
|
+
focusable="false"
|
|
35
|
+
aria-hidden="true"
|
|
36
|
+
>
|
|
37
|
+
<svg fill="currentColor" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg">
|
|
38
|
+
<title/>
|
|
39
|
+
<g>
|
|
40
|
+
<path d="M30,0H6A5.9966,5.9966,0,0,0,0,6V30a6,6,0,0,0,12,0V12H30A6,6,0,0,0,30,0Z"/>
|
|
41
|
+
<path d="M90,0H66a6,6,0,0,0,0,12H84V30a6,6,0,0,0,12,0V6A5.9966,5.9966,0,0,0,90,0Z"/>
|
|
42
|
+
<path d="M30,84H12V66A6,6,0,0,0,0,66V90a5.9966,5.9966,0,0,0,6,6H30a6,6,0,0,0,0-12Z"/>
|
|
43
|
+
<path d="M90,60a5.9966,5.9966,0,0,0-6,6V84H66a6,6,0,0,0,0,12H90a5.9966,5.9966,0,0,0,6-6V66A5.9966,5.9966,0,0,0,90,60Z"/>
|
|
44
|
+
</g>
|
|
45
|
+
</svg>
|
|
46
|
+
</svg>
|
|
47
|
+
`
|
|
48
|
+
|
|
49
|
+
//save initial map dimensions
|
|
50
|
+
this.defaultHeight = this.map.h
|
|
51
|
+
this.defaultWidth = this.map.w
|
|
52
|
+
|
|
53
|
+
// event handler
|
|
54
|
+
this.div.on('click', (e) => {
|
|
55
|
+
this.onClickFunction(e)
|
|
56
|
+
})
|
|
57
|
+
this.div.on('mouseover', (e) => {
|
|
58
|
+
this.style('background-color', Button.HOVER_BACKGROUND)
|
|
59
|
+
})
|
|
60
|
+
this.div.on('mouseout', (e) => {
|
|
61
|
+
this.style('background-color', Button.BACKGROUND)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
//set position
|
|
65
|
+
if (opts.x) {
|
|
66
|
+
this.style('left', opts.x + 'px')
|
|
67
|
+
} else {
|
|
68
|
+
this.style('right', '10px')
|
|
69
|
+
}
|
|
70
|
+
if (opts.y) {
|
|
71
|
+
this.style('top', opts.y + 'px')
|
|
72
|
+
} else {
|
|
73
|
+
this.style('top', '90px')
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
onClickFunction(e) {
|
|
78
|
+
if (this.isFullscreen) {
|
|
79
|
+
this.closeFullscreen(this.map.container)
|
|
80
|
+
//resize canvas to default
|
|
81
|
+
this.map.h = this.defaultHeight
|
|
82
|
+
this.map.w = this.defaultWidth
|
|
83
|
+
this.map.geoCanvas.h = this.defaultHeight
|
|
84
|
+
this.map.geoCanvas.w = this.defaultWidth
|
|
85
|
+
this.map.geoCanvas.canvas.setAttribute('width', '' + this.defaultWidth)
|
|
86
|
+
this.map.geoCanvas.canvas.setAttribute('height', '' + this.defaultHeight)
|
|
87
|
+
this.map.redraw()
|
|
88
|
+
this.isFullscreen = false
|
|
89
|
+
} else {
|
|
90
|
+
this.openFullscreen(this.map.container)
|
|
91
|
+
//resize canvas to fullscreen
|
|
92
|
+
this.map.h = window.screen.height
|
|
93
|
+
this.map.w = window.screen.width
|
|
94
|
+
this.isFullscreen = true
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Open fullscreen */
|
|
99
|
+
openFullscreen(elem) {
|
|
100
|
+
if (elem.requestFullscreen) {
|
|
101
|
+
elem.requestFullscreen()
|
|
102
|
+
} else if (elem.webkitRequestFullscreen) {
|
|
103
|
+
/* Safari */
|
|
104
|
+
elem.webkitRequestFullscreen()
|
|
105
|
+
} else if (elem.msRequestFullscreen) {
|
|
106
|
+
/* IE11 */
|
|
107
|
+
elem.msRequestFullscreen()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Close fullscreen */
|
|
112
|
+
closeFullscreen() {
|
|
113
|
+
if (document.exitFullscreen) {
|
|
114
|
+
document.exitFullscreen()
|
|
115
|
+
} else if (document.webkitExitFullscreen) {
|
|
116
|
+
/* Safari */
|
|
117
|
+
document.webkitExitFullscreen()
|
|
118
|
+
} else if (document.msExitFullscreen) {
|
|
119
|
+
/* IE11 */
|
|
120
|
+
document.msExitFullscreen()
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,104 +1,109 @@
|
|
|
1
|
-
import { Button } from './Button.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Button for toggling fullscreen mode
|
|
5
|
-
*
|
|
6
|
-
* @module button
|
|
7
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
-
*/
|
|
9
|
-
export class ZoomButtons extends Button {
|
|
10
|
-
/**
|
|
11
|
-
* @param {Object} opts
|
|
12
|
-
*/
|
|
13
|
-
constructor(opts) {
|
|
14
|
-
super(opts)
|
|
15
|
-
|
|
16
|
-
this.onZoom = opts.onZoom // custom user event handler
|
|
17
|
-
this.delta = opts.delta || 0.2
|
|
18
|
-
this.div.classed('gridviz-zoom-buttons', true)
|
|
19
|
-
|
|
20
|
-
// Create zoom in button
|
|
21
|
-
this.zoomInBtn = document.createElement('a')
|
|
22
|
-
this.zoomInBtn.id = 'zoom-in'
|
|
23
|
-
this.zoomInBtn.className = 'gridviz-zoom-button gridviz-zoom-button--in'
|
|
24
|
-
this.zoomInBtn.title = 'Zoom in'
|
|
25
|
-
this.zoomInBtn.textContent = '+'
|
|
26
|
-
this.zoomInBtn.addEventListener('click', (e) => {
|
|
27
|
-
this.zoomIn(e)
|
|
28
|
-
})
|
|
29
|
-
this.zoomInBtn.addEventListener('mouseover', () => {
|
|
30
|
-
this.zoomInBtn.style.backgroundColor =
|
|
31
|
-
})
|
|
32
|
-
this.zoomInBtn.addEventListener('mouseout', () => {
|
|
33
|
-
this.zoomInBtn.style.backgroundColor =
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// Create zoom out button
|
|
37
|
-
this.zoomOutBtn = document.createElement('a')
|
|
38
|
-
this.zoomOutBtn.id = 'zoom-out'
|
|
39
|
-
this.zoomOutBtn.className = 'gridviz-zoom-button gridviz-zoom-button--out'
|
|
40
|
-
this.zoomOutBtn.title = 'Zoom out'
|
|
41
|
-
this.zoomOutBtn.textContent =
|
|
42
|
-
this.zoomOutBtn.addEventListener('click', (e) => {
|
|
43
|
-
this.zoomOut(e)
|
|
44
|
-
})
|
|
45
|
-
this.zoomOutBtn.addEventListener('mouseover', () => {
|
|
46
|
-
this.zoomOutBtn.style.backgroundColor =
|
|
47
|
-
})
|
|
48
|
-
this.zoomOutBtn.addEventListener('mouseout', () => {
|
|
49
|
-
this.zoomOutBtn.style.backgroundColor =
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
// Set common styles for buttons
|
|
53
|
-
const buttons = [this.zoomInBtn, this.zoomOutBtn]
|
|
54
|
-
buttons.forEach((btn, index) => {
|
|
55
|
-
btn.style.alignItems = 'center'
|
|
56
|
-
btn.style.justifyContent = 'center'
|
|
57
|
-
btn.style.display = 'flex'
|
|
58
|
-
btn.style.border = 'none'
|
|
59
|
-
btn.style.color = '
|
|
60
|
-
btn.style.
|
|
61
|
-
btn.style.
|
|
62
|
-
btn.style.
|
|
63
|
-
btn.style.
|
|
64
|
-
btn.style.
|
|
65
|
-
|
|
66
|
-
btn.style.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (opts.
|
|
81
|
-
this.style('
|
|
82
|
-
} else {
|
|
83
|
-
this.style('
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.map.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
1
|
+
import { Button } from './Button.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Button for toggling fullscreen mode
|
|
5
|
+
*
|
|
6
|
+
* @module button
|
|
7
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
8
|
+
*/
|
|
9
|
+
export class ZoomButtons extends Button {
|
|
10
|
+
/**
|
|
11
|
+
* @param {Object} opts
|
|
12
|
+
*/
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts)
|
|
15
|
+
|
|
16
|
+
this.onZoom = opts.onZoom // custom user event handler
|
|
17
|
+
this.delta = opts.delta || 0.2
|
|
18
|
+
this.div.classed('gridviz-zoom-buttons', true)
|
|
19
|
+
|
|
20
|
+
// Create zoom in button
|
|
21
|
+
this.zoomInBtn = document.createElement('a')
|
|
22
|
+
this.zoomInBtn.id = 'zoom-in'
|
|
23
|
+
this.zoomInBtn.className = 'gridviz-zoom-button gridviz-zoom-button--in'
|
|
24
|
+
this.zoomInBtn.title = 'Zoom in'
|
|
25
|
+
this.zoomInBtn.textContent = '+'
|
|
26
|
+
this.zoomInBtn.addEventListener('click', (e) => {
|
|
27
|
+
this.zoomIn(e)
|
|
28
|
+
})
|
|
29
|
+
this.zoomInBtn.addEventListener('mouseover', () => {
|
|
30
|
+
this.zoomInBtn.style.backgroundColor = Button.HOVER_BACKGROUND
|
|
31
|
+
})
|
|
32
|
+
this.zoomInBtn.addEventListener('mouseout', () => {
|
|
33
|
+
this.zoomInBtn.style.backgroundColor = Button.BACKGROUND
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// Create zoom out button
|
|
37
|
+
this.zoomOutBtn = document.createElement('a')
|
|
38
|
+
this.zoomOutBtn.id = 'zoom-out'
|
|
39
|
+
this.zoomOutBtn.className = 'gridviz-zoom-button gridviz-zoom-button--out'
|
|
40
|
+
this.zoomOutBtn.title = 'Zoom out'
|
|
41
|
+
this.zoomOutBtn.textContent = String.fromCharCode(0x2212) // a minus sign, as wide as the plus (not a literal character, which breaks in pages without a charset)
|
|
42
|
+
this.zoomOutBtn.addEventListener('click', (e) => {
|
|
43
|
+
this.zoomOut(e)
|
|
44
|
+
})
|
|
45
|
+
this.zoomOutBtn.addEventListener('mouseover', () => {
|
|
46
|
+
this.zoomOutBtn.style.backgroundColor = Button.HOVER_BACKGROUND
|
|
47
|
+
})
|
|
48
|
+
this.zoomOutBtn.addEventListener('mouseout', () => {
|
|
49
|
+
this.zoomOutBtn.style.backgroundColor = Button.BACKGROUND
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Set common styles for buttons
|
|
53
|
+
const buttons = [this.zoomInBtn, this.zoomOutBtn]
|
|
54
|
+
buttons.forEach((btn, index) => {
|
|
55
|
+
btn.style.alignItems = 'center'
|
|
56
|
+
btn.style.justifyContent = 'center'
|
|
57
|
+
btn.style.display = 'flex'
|
|
58
|
+
btn.style.border = 'none'
|
|
59
|
+
btn.style.color = 'var(--gridviz-button-color, #0e47cb)'
|
|
60
|
+
btn.style.fontFamily = "'Helvetica Neue', Arial, Helvetica, sans-serif"
|
|
61
|
+
btn.style.textAlign = 'center'
|
|
62
|
+
btn.style.textDecoration = 'none'
|
|
63
|
+
btn.style.padding = '0'
|
|
64
|
+
btn.style.boxSizing = 'border-box'
|
|
65
|
+
// the size of the button, less its border
|
|
66
|
+
btn.style.width = 'calc(var(--gridviz-button-size, 38px) - 2px)'
|
|
67
|
+
btn.style.height = 'calc(var(--gridviz-button-size, 38px) - 2px)'
|
|
68
|
+
btn.style.fontSize = '22px'
|
|
69
|
+
btn.style.fontWeight = 'bold'
|
|
70
|
+
btn.style.userSelect = 'none'
|
|
71
|
+
btn.style.backgroundColor = Button.BACKGROUND
|
|
72
|
+
if (index === 0) btn.style.borderBottom = '1px solid #ccc' // Zoom in button only
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Unset parent class height and display for dual buttons
|
|
76
|
+
this.style('height', 'unset')
|
|
77
|
+
this.style('display', 'unset')
|
|
78
|
+
|
|
79
|
+
// Set position
|
|
80
|
+
if (opts.x) {
|
|
81
|
+
this.style('left', opts.x + 'px')
|
|
82
|
+
} else {
|
|
83
|
+
this.style('right', '10px')
|
|
84
|
+
}
|
|
85
|
+
if (opts.y) {
|
|
86
|
+
this.style('top', opts.y + 'px')
|
|
87
|
+
} else {
|
|
88
|
+
this.style('top', '10px')
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Append buttons to the container
|
|
92
|
+
this.div.node().appendChild(this.zoomInBtn)
|
|
93
|
+
this.div.node().appendChild(this.zoomOutBtn)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Zoom in */
|
|
97
|
+
zoomIn(e) {
|
|
98
|
+
this.map.setZoom(this.map.getZoom() * (1 - this.delta)).redraw()
|
|
99
|
+
if (this.onZoom) this.onZoom(e)
|
|
100
|
+
if (this.map.geoCanvas.onZoomFun) this.map.geoCanvas.onZoomFun(e)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Zoom out */
|
|
104
|
+
zoomOut(e) {
|
|
105
|
+
this.map.setZoom(this.map.getZoom() * (1 + this.delta)).redraw()
|
|
106
|
+
if (this.onZoom) this.onZoom(e)
|
|
107
|
+
if (this.map.geoCanvas.onZoomFun) this.map.geoCanvas.onZoomFun(e)
|
|
108
|
+
}
|
|
109
|
+
}
|