@ohos-ports/jsvectormap 1.7.0-beta.0
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/LICENSE +21 -0
- package/dist/jsvectormap.cjs +2355 -0
- package/dist/jsvectormap.css +147 -0
- package/dist/jsvectormap.esm.js +2293 -0
- package/dist/jsvectormap.js +2301 -0
- package/dist/jsvectormap.min.css +1 -0
- package/dist/jsvectormap.min.js +1 -0
- package/dist/maps/world-merc.js +1 -0
- package/dist/maps/world.js +1 -0
- package/package.json +49 -0
- package/src/js/components/base.js +18 -0
- package/src/js/components/concerns/interactable.js +68 -0
- package/src/js/components/line.js +50 -0
- package/src/js/components/marker.js +109 -0
- package/src/js/components/region.js +53 -0
- package/src/js/components/route.js +76 -0
- package/src/js/components/tooltip.js +88 -0
- package/src/js/core/applyTransform.js +43 -0
- package/src/js/core/coordsToPoint.js +22 -0
- package/src/js/core/createLines.js +44 -0
- package/src/js/core/createMarkers.js +55 -0
- package/src/js/core/createRegions.js +23 -0
- package/src/js/core/createRoutes.js +16 -0
- package/src/js/core/createSeries.js +13 -0
- package/src/js/core/getInsetForPoint.js +13 -0
- package/src/js/core/getMarkerPosition.js +12 -0
- package/src/js/core/index.js +41 -0
- package/src/js/core/repositionLabels.js +21 -0
- package/src/js/core/repositionLines.js +30 -0
- package/src/js/core/repositionMarkers.js +11 -0
- package/src/js/core/resize.js +15 -0
- package/src/js/core/setFocus.js +46 -0
- package/src/js/core/setScale.js +65 -0
- package/src/js/core/setupContainerEvents.js +50 -0
- package/src/js/core/setupContainerTouchEvents.js +85 -0
- package/src/js/core/setupElementEvents.js +112 -0
- package/src/js/core/setupZoomButtons.js +40 -0
- package/src/js/core/updateSize.js +7 -0
- package/src/js/dataVisualization.js +87 -0
- package/src/js/defaults/events.js +11 -0
- package/src/js/defaults/options.js +90 -0
- package/src/js/eventHandler.js +47 -0
- package/src/js/index.js +25 -0
- package/src/js/legend.js +69 -0
- package/src/js/map.js +367 -0
- package/src/js/projection.js +127 -0
- package/src/js/scales/ordinalScale.js +21 -0
- package/src/js/series.js +68 -0
- package/src/js/svg/baseElement.js +53 -0
- package/src/js/svg/canvasElement.js +99 -0
- package/src/js/svg/imageElement.js +49 -0
- package/src/js/svg/shapeElement.js +48 -0
- package/src/js/svg/textElement.js +13 -0
- package/src/js/util/deepMerge.js +129 -0
- package/src/js/util/index.js +81 -0
- package/src/scss/_variables.scss +37 -0
- package/src/scss/jsvectormap.scss +153 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* ------------------------------------------------------------------------
|
|
4
|
+
* Object
|
|
5
|
+
* ------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
const Proj = {
|
|
8
|
+
|
|
9
|
+
/* sgn(n){
|
|
10
|
+
if (n > 0) {
|
|
11
|
+
return 1;
|
|
12
|
+
} else if (n < 0) {
|
|
13
|
+
return -1;
|
|
14
|
+
} else {
|
|
15
|
+
return n;
|
|
16
|
+
}
|
|
17
|
+
}, */
|
|
18
|
+
|
|
19
|
+
mill(lat, lng, c) {
|
|
20
|
+
return {
|
|
21
|
+
x: this.radius * (lng - c) * this.radDeg,
|
|
22
|
+
y: - this.radius * Math.log(Math.tan((45 + 0.4 * lat) * this.radDeg)) / 0.8
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
/* mill_inv(x, y, c) {
|
|
27
|
+
return {
|
|
28
|
+
lat: (2.5 * Math.atan(Math.exp(0.8 * y / this.radius)) - 5 * Math.PI / 8) * this.degRad,
|
|
29
|
+
lng: (c * this.radDeg + x / this.radius) * this.degRad
|
|
30
|
+
};
|
|
31
|
+
}, */
|
|
32
|
+
|
|
33
|
+
merc(lat, lng, c) {
|
|
34
|
+
return {
|
|
35
|
+
x: this.radius * (lng - c) * this.radDeg,
|
|
36
|
+
y: - this.radius * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360))
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/* merc_inv(x, y, c) {
|
|
41
|
+
return {
|
|
42
|
+
lat: (2 * Math.atan(Math.exp(y / this.radius)) - Math.PI / 2) * this.degRad,
|
|
43
|
+
lng: (c * this.radDeg + x / this.radius) * this.degRad
|
|
44
|
+
};
|
|
45
|
+
}, */
|
|
46
|
+
|
|
47
|
+
aea(lat, lng, c) {
|
|
48
|
+
var fi0 = 0,
|
|
49
|
+
lambda0 = c * this.radDeg,
|
|
50
|
+
fi1 = 29.5 * this.radDeg,
|
|
51
|
+
fi2 = 45.5 * this.radDeg,
|
|
52
|
+
fi = lat * this.radDeg,
|
|
53
|
+
lambda = lng * this.radDeg,
|
|
54
|
+
n = (Math.sin(fi1)+Math.sin(fi2)) / 2,
|
|
55
|
+
C = Math.cos(fi1)*Math.cos(fi1)+2*n*Math.sin(fi1),
|
|
56
|
+
theta = n*(lambda-lambda0),
|
|
57
|
+
ro = Math.sqrt(C-2*n*Math.sin(fi))/n,
|
|
58
|
+
ro0 = Math.sqrt(C-2*n*Math.sin(fi0))/n;
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
x: ro * Math.sin(theta) * this.radius,
|
|
62
|
+
y: - (ro0 - ro * Math.cos(theta)) * this.radius
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/* aea_inv(xCoord, yCoord, c) {
|
|
67
|
+
var x = xCoord / this.radius,
|
|
68
|
+
y = yCoord / this.radius,
|
|
69
|
+
fi0 = 0,
|
|
70
|
+
lambda0 = c * this.radDeg,
|
|
71
|
+
fi1 = 29.5 * this.radDeg,
|
|
72
|
+
fi2 = 45.5 * this.radDeg,
|
|
73
|
+
n = (Math.sin(fi1)+Math.sin(fi2)) / 2,
|
|
74
|
+
C = Math.cos(fi1)*Math.cos(fi1)+2*n*Math.sin(fi1),
|
|
75
|
+
ro0 = Math.sqrt(C-2*n*Math.sin(fi0))/n,
|
|
76
|
+
ro = Math.sqrt(x*x+(ro0-y)*(ro0-y)),
|
|
77
|
+
theta = Math.atan( x / (ro0 - y) );
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
lat: (Math.asin((C - ro * ro * n * n) / (2 * n))) * this.degRad,
|
|
81
|
+
lng: (lambda0 + theta / n) * this.degRad
|
|
82
|
+
};
|
|
83
|
+
}, */
|
|
84
|
+
|
|
85
|
+
lcc(lat, lng, c) {
|
|
86
|
+
var fi0 = 0,
|
|
87
|
+
lambda0 = c * this.radDeg,
|
|
88
|
+
lambda = lng * this.radDeg,
|
|
89
|
+
fi1 = 33 * this.radDeg,
|
|
90
|
+
fi2 = 45 * this.radDeg,
|
|
91
|
+
fi = lat * this.radDeg,
|
|
92
|
+
n = Math.log(Math.cos(fi1) * (1 / Math.cos(fi2)) ) / Math.log(Math.tan(Math.PI / 4 + fi2 / 2) * (1 / Math.tan(Math.PI / 4 + fi1 / 2) )),
|
|
93
|
+
F = (Math.cos(fi1) * Math.pow(Math.tan(Math.PI / 4 + fi1 / 2 ), n )) / n,
|
|
94
|
+
ro = F * Math.pow(1 / Math.tan(Math.PI / 4 + fi / 2), n),
|
|
95
|
+
ro0 = F * Math.pow(1 / Math.tan(Math.PI / 4 + fi0 / 2), n);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
x: ro * Math.sin(n * (lambda - lambda0)) * this.radius,
|
|
99
|
+
y: - (ro0 - ro * Math.cos(n * (lambda - lambda0))) * this.radius
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/* lcc_inv(xCoord, yCoord, c) {
|
|
104
|
+
var x = xCoord / this.radius,
|
|
105
|
+
y = yCoord / this.radius,
|
|
106
|
+
fi0 = 0,
|
|
107
|
+
lambda0 = c * this.radDeg,
|
|
108
|
+
fi1 = 33 * this.radDeg,
|
|
109
|
+
fi2 = 45 * this.radDeg,
|
|
110
|
+
n = Math.log( Math.cos(fi1) * (1 / Math.cos(fi2)) ) / Math.log( Math.tan( Math.PI / 4 + fi2 / 2) * (1 / Math.tan( Math.PI / 4 + fi1 / 2) ) ),
|
|
111
|
+
F = ( Math.cos(fi1) * Math.pow( Math.tan( Math.PI / 4 + fi1 / 2 ), n ) ) / n,
|
|
112
|
+
ro0 = F * Math.pow( 1 / Math.tan( Math.PI / 4 + fi0 / 2 ), n ),
|
|
113
|
+
ro = this.sgn(n) * Math.sqrt(x*x+(ro0-y)*(ro0-y)),
|
|
114
|
+
theta = Math.atan( x / (ro0 - y) );
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
lat: (2 * Math.atan(Math.pow(F/ro, 1/n)) - Math.PI / 2) * this.degRad,
|
|
118
|
+
lng: (lambda0 + theta / n) * this.degRad
|
|
119
|
+
};
|
|
120
|
+
} */
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
Proj.degRad = 180 / Math.PI
|
|
124
|
+
Proj.radDeg = Math.PI / 180
|
|
125
|
+
Proj.radius = 6381372
|
|
126
|
+
|
|
127
|
+
export default Proj
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class OrdinalScale {
|
|
2
|
+
constructor(scale) {
|
|
3
|
+
this._scale = scale
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
getValue(value){
|
|
7
|
+
return this._scale[value]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
getTicks() {
|
|
11
|
+
const ticks = []
|
|
12
|
+
|
|
13
|
+
for (let key in this._scale) {
|
|
14
|
+
ticks.push({ label: key, value: this._scale[key] })
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return ticks
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default OrdinalScale
|
package/src/js/series.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { merge } from './util/index'
|
|
2
|
+
import Legend from './legend'
|
|
3
|
+
import OrdinalScale from './scales/ordinalScale'
|
|
4
|
+
|
|
5
|
+
class Series {
|
|
6
|
+
constructor(config = {}, elements, map) {
|
|
7
|
+
// Private
|
|
8
|
+
this._map = map
|
|
9
|
+
this._elements = elements // Could be markers or regions
|
|
10
|
+
this._values = config.values || {}
|
|
11
|
+
|
|
12
|
+
// Protected
|
|
13
|
+
this.config = config
|
|
14
|
+
this.config.attribute = config.attribute || 'fill'
|
|
15
|
+
|
|
16
|
+
// Set initial attributes
|
|
17
|
+
if (config.attributes) {
|
|
18
|
+
this.setAttributes(config.attributes)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof config.scale === 'object') {
|
|
22
|
+
this.scale = new OrdinalScale(config.scale)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (this.config.legend) {
|
|
26
|
+
this.legend = new Legend(
|
|
27
|
+
merge({ map: this._map, series: this }, this.config.legend)
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.setValues(this._values)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setValues(values) {
|
|
35
|
+
let attrs = {}
|
|
36
|
+
|
|
37
|
+
for (let key in values) {
|
|
38
|
+
if (values[key]) {
|
|
39
|
+
attrs[key] = this.scale.getValue(values[key])
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.setAttributes(attrs)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setAttributes(attrs) {
|
|
47
|
+
for (let code in attrs) {
|
|
48
|
+
if (this._elements[code]) {
|
|
49
|
+
this._elements[code].element.setStyle(this.config.attribute, attrs[code])
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
clear() {
|
|
55
|
+
let key, attrs = {}
|
|
56
|
+
|
|
57
|
+
for (key in this._values) {
|
|
58
|
+
if (this._elements[key]) {
|
|
59
|
+
attrs[key] = this._elements[key].element.shape.style.initial[this.config.attribute]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.setAttributes(attrs)
|
|
64
|
+
this._values = {}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default Series
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hyphenate,
|
|
3
|
+
removeElement
|
|
4
|
+
} from '../util/index'
|
|
5
|
+
|
|
6
|
+
class SVGElement {
|
|
7
|
+
constructor(name, config) {
|
|
8
|
+
this.node = this._createElement(name)
|
|
9
|
+
|
|
10
|
+
if (config) {
|
|
11
|
+
this.set(config)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Create new SVG element `svg`, `g`, `path`, `line`, `circle`, `image`, etc.
|
|
16
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris
|
|
17
|
+
_createElement(tagName) {
|
|
18
|
+
return document.createElementNS('http://www.w3.org/2000/svg', tagName)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
addClass(className) {
|
|
22
|
+
this.node.setAttribute('class', className)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getBBox() {
|
|
26
|
+
return this.node.getBBox()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Apply attributes on the current node element
|
|
30
|
+
set(property, value) {
|
|
31
|
+
if (typeof property === 'object') {
|
|
32
|
+
for (let attr in property) {
|
|
33
|
+
this.applyAttr(attr, property[attr])
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
this.applyAttr(property, value)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get(property) {
|
|
41
|
+
return this.style.initial[property]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
applyAttr(property, value) {
|
|
45
|
+
this.node.setAttribute(hyphenate(property), value)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
remove() {
|
|
49
|
+
removeElement(this.node)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default SVGElement
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import SVGElement from './baseElement'
|
|
2
|
+
import SVGShapeElement from './shapeElement'
|
|
3
|
+
import SVGTextElement from './textElement'
|
|
4
|
+
import SVGImageElement from './imageElement'
|
|
5
|
+
|
|
6
|
+
class SVGCanvasElement extends SVGElement {
|
|
7
|
+
constructor(container) {
|
|
8
|
+
super('svg') // Create svg element for holding the whole map
|
|
9
|
+
|
|
10
|
+
this._container = container
|
|
11
|
+
|
|
12
|
+
// Create the defs element
|
|
13
|
+
this._defsElement = new SVGElement('defs')
|
|
14
|
+
|
|
15
|
+
// Create group element which will hold the paths (regions)
|
|
16
|
+
this._rootElement = new SVGElement('g', { id: 'jvm-regions-group' })
|
|
17
|
+
|
|
18
|
+
// Append the defs element to the this.node (SVG tag)
|
|
19
|
+
this.node.appendChild(this._defsElement.node)
|
|
20
|
+
|
|
21
|
+
// Append the group to this.node (SVG tag)
|
|
22
|
+
this.node.appendChild(this._rootElement.node)
|
|
23
|
+
|
|
24
|
+
// Append this.node (SVG tag) to the container
|
|
25
|
+
this._container.appendChild(this.node)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setSize(width, height) {
|
|
29
|
+
this.node.setAttribute('width', width)
|
|
30
|
+
this.node.setAttribute('height', height)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
applyTransformParams(scale, transX, transY) {
|
|
34
|
+
this._rootElement.node.setAttribute('transform', `scale(${scale}) translate(${transX}, ${transY})`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Create `path` element
|
|
38
|
+
createPath(config, style, group) {
|
|
39
|
+
const path = new SVGShapeElement('path', config, style)
|
|
40
|
+
|
|
41
|
+
path.node.setAttribute('fill-rule', 'evenodd')
|
|
42
|
+
|
|
43
|
+
return this._add(path, group)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Create `circle` element
|
|
47
|
+
createCircle(config, style, group) {
|
|
48
|
+
const circle = new SVGShapeElement('circle', config, style)
|
|
49
|
+
|
|
50
|
+
return this._add(circle, group)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Create `line` element
|
|
54
|
+
createLine(config, style, group) {
|
|
55
|
+
const line = new SVGShapeElement('line', config, style)
|
|
56
|
+
|
|
57
|
+
return this._add(line, group)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Create `text` element
|
|
61
|
+
createText(config, style, group) {
|
|
62
|
+
const text = new SVGTextElement(config, style)
|
|
63
|
+
|
|
64
|
+
return this._add(text, group)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Create `image` element
|
|
68
|
+
createImage(config, style, group) {
|
|
69
|
+
const image = new SVGImageElement(config, style)
|
|
70
|
+
|
|
71
|
+
return this._add(image, group)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Create `g` element
|
|
75
|
+
createGroup(id) {
|
|
76
|
+
const group = new SVGElement('g')
|
|
77
|
+
|
|
78
|
+
this.node.appendChild(group.node)
|
|
79
|
+
|
|
80
|
+
if (id) {
|
|
81
|
+
group.node.id = id
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
group.canvas = this
|
|
85
|
+
|
|
86
|
+
return group
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add some element to a spcific group or the root element if the group isn't given
|
|
90
|
+
_add(element, group) {
|
|
91
|
+
group = group || this._rootElement
|
|
92
|
+
|
|
93
|
+
group.node.appendChild(element.node)
|
|
94
|
+
|
|
95
|
+
return element
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default SVGCanvasElement
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import SVGShapeElement from './shapeElement'
|
|
2
|
+
|
|
3
|
+
class SVGImageElement extends SVGShapeElement {
|
|
4
|
+
constructor(config, style) {
|
|
5
|
+
super('image', config, style)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
applyAttr(attr, value) {
|
|
9
|
+
let imageUrl
|
|
10
|
+
|
|
11
|
+
if (attr === 'image') {
|
|
12
|
+
// This get executed when we have url in series.markers[0].scale.someScale.url
|
|
13
|
+
if (typeof value === 'object') {
|
|
14
|
+
imageUrl = value.url
|
|
15
|
+
this.offset = value.offset || [0, 0]
|
|
16
|
+
} else {
|
|
17
|
+
imageUrl = value
|
|
18
|
+
this.offset = [0, 0]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.node.setAttributeNS('http://www.w3.org/1999/xlink', 'href', imageUrl)
|
|
22
|
+
|
|
23
|
+
// Set width and height then call this `applyAttr` again
|
|
24
|
+
this.width = 23
|
|
25
|
+
this.height = 23
|
|
26
|
+
this.applyAttr('width', this.width)
|
|
27
|
+
this.applyAttr('height', this.height)
|
|
28
|
+
this.applyAttr('x', this.cx - this.width / 2 + this.offset[0])
|
|
29
|
+
this.applyAttr('y', this.cy - this.height / 2 + this.offset[1])
|
|
30
|
+
} else if (attr == 'cx') {
|
|
31
|
+
this.cx = value
|
|
32
|
+
|
|
33
|
+
if (this.width) {
|
|
34
|
+
this.applyAttr('x', value - this.width / 2 + this.offset[0])
|
|
35
|
+
}
|
|
36
|
+
} else if (attr == 'cy') {
|
|
37
|
+
this.cy = value
|
|
38
|
+
|
|
39
|
+
if (this.height) {
|
|
40
|
+
this.applyAttr('y', value - this.height / 2 + this.offset[1])
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// This time Call SVGElement
|
|
44
|
+
super.applyAttr.apply(this, arguments)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default SVGImageElement
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { merge } from '../util/index'
|
|
2
|
+
import SVGElement from './baseElement'
|
|
3
|
+
|
|
4
|
+
class SVGShapeElement extends SVGElement {
|
|
5
|
+
constructor(name, config, style = {}) {
|
|
6
|
+
super(name, config)
|
|
7
|
+
|
|
8
|
+
this.isHovered = false
|
|
9
|
+
this.isSelected = false
|
|
10
|
+
this.style = style
|
|
11
|
+
this.style.current = {}
|
|
12
|
+
|
|
13
|
+
this.updateStyle()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setStyle(property, value) {
|
|
17
|
+
if (typeof property === 'object') {
|
|
18
|
+
merge(this.style.current, property)
|
|
19
|
+
} else {
|
|
20
|
+
merge(this.style.current, { [property]: value })
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.updateStyle()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
updateStyle() {
|
|
27
|
+
const attrs = {}
|
|
28
|
+
|
|
29
|
+
merge(attrs, this.style.initial)
|
|
30
|
+
merge(attrs, this.style.current)
|
|
31
|
+
|
|
32
|
+
if (this.isHovered) {
|
|
33
|
+
merge(attrs, this.style.hover)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (this.isSelected) {
|
|
37
|
+
merge(attrs, this.style.selected)
|
|
38
|
+
|
|
39
|
+
if (this.isHovered) {
|
|
40
|
+
merge(attrs, this.style.selectedHover)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.set(attrs)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default SVGShapeElement
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import SVGShapeElement from './shapeElement'
|
|
2
|
+
|
|
3
|
+
class SVGTextElement extends SVGShapeElement {
|
|
4
|
+
constructor(config, style) {
|
|
5
|
+
super('text', config, style)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
applyAttr(attr, value) {
|
|
9
|
+
attr === 'text' ? this.node.textContent = value : super.applyAttr(attr, value)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default SVGTextElement
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* By https://github.com/TehShrike/deepmerge
|
|
3
|
+
*/
|
|
4
|
+
'use strict'
|
|
5
|
+
|
|
6
|
+
var isMergeableObject = function isMergeableObject(value) {
|
|
7
|
+
return isNonNullObject(value)
|
|
8
|
+
&& !isSpecial(value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isNonNullObject(value) {
|
|
12
|
+
return !!value && typeof value === 'object'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isSpecial(value) {
|
|
16
|
+
var stringValue = Object.prototype.toString.call(value)
|
|
17
|
+
|
|
18
|
+
return stringValue === '[object RegExp]'
|
|
19
|
+
|| stringValue === '[object Date]'
|
|
20
|
+
|| isNode(value)
|
|
21
|
+
|| isReactElement(value)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
|
|
25
|
+
var canUseSymbol = typeof Symbol === 'function' && Symbol.for
|
|
26
|
+
var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7
|
|
27
|
+
|
|
28
|
+
function isReactElement(value) {
|
|
29
|
+
return value.$$typeof === REACT_ELEMENT_TYPE
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isNode(value) {
|
|
33
|
+
return value instanceof Node
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function emptyTarget(val) {
|
|
37
|
+
return Array.isArray(val) ? [] : {}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function cloneUnlessOtherwiseSpecified(value, options) {
|
|
41
|
+
return (options.clone !== false && options.isMergeableObject(value))
|
|
42
|
+
? deepmerge(emptyTarget(value), value, options)
|
|
43
|
+
: value
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function defaultArrayMerge(target, source, options) {
|
|
47
|
+
return target.concat(source).map(function(element) {
|
|
48
|
+
return cloneUnlessOtherwiseSpecified(element, options)
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getMergeFunction(key, options) {
|
|
53
|
+
if (!options.customMerge) {
|
|
54
|
+
return deepmerge
|
|
55
|
+
}
|
|
56
|
+
var customMerge = options.customMerge(key)
|
|
57
|
+
return typeof customMerge === 'function' ? customMerge : deepmerge
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getEnumerableOwnPropertySymbols(target) {
|
|
61
|
+
return Object.getOwnPropertySymbols
|
|
62
|
+
? Object.getOwnPropertySymbols(target).filter(function(symbol) {
|
|
63
|
+
return target.propertyIsEnumerable(symbol)
|
|
64
|
+
})
|
|
65
|
+
: []
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getKeys(target) {
|
|
69
|
+
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function propertyIsOnObject(object, property) {
|
|
73
|
+
try {
|
|
74
|
+
return property in object
|
|
75
|
+
} catch(_) {
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Protects from prototype poisoning and unexpected merging up the prototype chain.
|
|
81
|
+
function propertyIsUnsafe(target, key) {
|
|
82
|
+
return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
|
|
83
|
+
&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
|
|
84
|
+
&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function mergeObject(target, source, options) {
|
|
88
|
+
var destination = {}
|
|
89
|
+
if (options.isMergeableObject(target)) {
|
|
90
|
+
getKeys(target).forEach(function(key) {
|
|
91
|
+
destination[key] = cloneUnlessOtherwiseSpecified(target[key], options)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
getKeys(source).forEach(function(key) {
|
|
95
|
+
if (propertyIsUnsafe(target, key)) {
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
|
|
100
|
+
destination[key] = getMergeFunction(key, options)(target[key], source[key], options)
|
|
101
|
+
} else {
|
|
102
|
+
destination[key] = cloneUnlessOtherwiseSpecified(source[key], options)
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
return destination
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
var deepmerge = function (target, source, options) {
|
|
109
|
+
options = options || {}
|
|
110
|
+
options.arrayMerge = options.arrayMerge || defaultArrayMerge
|
|
111
|
+
options.isMergeableObject = options.isMergeableObject || isMergeableObject
|
|
112
|
+
// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
|
|
113
|
+
// implementations can use it. The caller may not replace it.
|
|
114
|
+
options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified
|
|
115
|
+
|
|
116
|
+
var sourceIsArray = Array.isArray(source)
|
|
117
|
+
var targetIsArray = Array.isArray(target)
|
|
118
|
+
var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray
|
|
119
|
+
|
|
120
|
+
if (!sourceAndTargetTypesMatch) {
|
|
121
|
+
return cloneUnlessOtherwiseSpecified(source, options)
|
|
122
|
+
} else if (sourceIsArray) {
|
|
123
|
+
return options.arrayMerge(target, source, options)
|
|
124
|
+
} else {
|
|
125
|
+
return mergeObject(target, source, options)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default deepmerge
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import DeepMerge from './deepMerge'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* --------------------------------------------------------------------------
|
|
5
|
+
* Public Util Api
|
|
6
|
+
* --------------------------------------------------------------------------
|
|
7
|
+
*/
|
|
8
|
+
const getElement = selector => {
|
|
9
|
+
if (typeof selector === 'object' && typeof selector.nodeType !== 'undefined') {
|
|
10
|
+
return selector
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (typeof selector === 'string') {
|
|
14
|
+
return document.querySelector(selector)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const createElement = (type, classes, content, html = false) => {
|
|
21
|
+
let el = document.createElement(type)
|
|
22
|
+
|
|
23
|
+
if (content) {
|
|
24
|
+
el[!html ? 'textContent' : 'innerHTML'] = content
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (classes) {
|
|
28
|
+
el.className = classes
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return el
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const findElement = (parentElement, selector) => {
|
|
35
|
+
return Element.prototype.querySelector.call(parentElement, selector)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const removeElement = target => {
|
|
39
|
+
target.parentNode.removeChild(target)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const isImageUrl = url => {
|
|
43
|
+
return /\.(jpg|gif|png)$/.test(url)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const hyphenate = string => {
|
|
47
|
+
return string.replace(/[\w]([A-Z])/g, m => `${m[0]}-${m[1]}`).toLowerCase()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const merge = (target, source, deep = false) => {
|
|
51
|
+
if (deep) {
|
|
52
|
+
return DeepMerge(target, source)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return Object.assign(target, source)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const keys = object => {
|
|
59
|
+
return Object.keys(object)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const getLineUid = (from, to) => {
|
|
63
|
+
return `${from.toLowerCase()}:to:${to.toLowerCase()}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const inherit = (target, source) => {
|
|
67
|
+
Object.assign(target.prototype, source)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
getElement,
|
|
72
|
+
createElement,
|
|
73
|
+
findElement,
|
|
74
|
+
removeElement,
|
|
75
|
+
isImageUrl,
|
|
76
|
+
hyphenate,
|
|
77
|
+
merge,
|
|
78
|
+
keys,
|
|
79
|
+
getLineUid,
|
|
80
|
+
inherit,
|
|
81
|
+
}
|