gridviz 3.0.22 → 3.0.24

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 (66) hide show
  1. package/README.md +128 -128
  2. package/dist/gridviz.js +8618 -8579
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +74 -74
  5. package/src/button/Button.js +67 -67
  6. package/src/button/FullscreenButton.js +121 -121
  7. package/src/button/ZoomButtons.js +103 -101
  8. package/src/core/Dataset.js +154 -154
  9. package/src/core/Drawable.js +78 -78
  10. package/src/core/GeoCanvas.js +437 -430
  11. package/src/core/Layer.js +23 -23
  12. package/src/core/Legend.js +108 -108
  13. package/src/core/Map.js +542 -516
  14. package/src/core/MultiResolutionDataset.js +93 -93
  15. package/src/core/Style.js +98 -98
  16. package/src/core/Tooltip.js +182 -182
  17. package/src/dataset/COGeo.js +25 -25
  18. package/src/dataset/CSVGrid.js +112 -112
  19. package/src/dataset/GeoTIFF.js +122 -122
  20. package/src/dataset/JSGrid.js +55 -55
  21. package/src/dataset/TiledGrid.js +302 -302
  22. package/src/dataset/worker.js +18 -18
  23. package/src/index.js +77 -77
  24. package/src/layer/BackgroundLayer.js +173 -173
  25. package/src/layer/BackgroundLayerImage.js +81 -81
  26. package/src/layer/BackgroundLayerWMS.js +104 -104
  27. package/src/layer/GeoJSONLayer.js +214 -214
  28. package/src/layer/GridLayer.js +148 -148
  29. package/src/layer/LabelLayer.js +194 -194
  30. package/src/legend/ColorCategoryLegend.js +109 -109
  31. package/src/legend/ColorDiscreteLegend.js +100 -100
  32. package/src/legend/ColorLegend.js +115 -115
  33. package/src/legend/OrientationLegend.js +89 -89
  34. package/src/legend/SizeLegend.js +224 -224
  35. package/src/legend/TernaryLegend.js +302 -302
  36. package/src/style/CompositionStyle.js +291 -291
  37. package/src/style/ContourStyle.js +21 -21
  38. package/src/style/DotDensityStyle.js +133 -133
  39. package/src/style/ImageStyle.js +100 -100
  40. package/src/style/IsoFenceStyle.js +217 -217
  41. package/src/style/JoyPlotStyle.js +127 -127
  42. package/src/style/LegoStyle.js +110 -110
  43. package/src/style/MosaicStyle.js +99 -99
  44. package/src/style/NinjaStarStyle.js +102 -102
  45. package/src/style/PillarStyle.js +207 -207
  46. package/src/style/SegmentStyle.js +105 -105
  47. package/src/style/ShapeColorSizeStyle.js +147 -147
  48. package/src/style/SideCategoryStyle.js +112 -112
  49. package/src/style/SideStyle.js +212 -212
  50. package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
  51. package/src/style/SquareColorWebGLStyle.js +126 -126
  52. package/src/style/StrokeStyle.js +135 -135
  53. package/src/style/TanakaStyle.js +69 -69
  54. package/src/style/TextStyle.js +110 -110
  55. package/src/style/TimeSeriesStyle.js +222 -222
  56. package/src/utils/WebGLRectangleColoring.js +106 -106
  57. package/src/utils/WebGLSquareColoring.js +118 -118
  58. package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
  59. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
  60. package/src/utils/WebGLSquareColoringKS.js +153 -153
  61. package/src/utils/scale.js +218 -218
  62. package/src/utils/stretching.js +120 -120
  63. package/src/utils/ternary.js +208 -208
  64. package/src/utils/utils.js +58 -58
  65. package/src/utils/webGLUtils.js +72 -72
  66. package/src/utils/zoomUtils.js +142 -142
@@ -1,104 +1,104 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Layer } from '../core/Layer.js'
5
-
6
- /**
7
- *
8
- * A map WMS background layer.
9
- *
10
- * @module layer
11
- * @author Julien Gaffuri
12
- */
13
- export class BackgroundLayerWMS extends Layer {
14
- /**
15
- * @param {object} opts
16
- */
17
- constructor(opts) {
18
- super(opts)
19
- opts = opts || {}
20
-
21
- /**
22
- * @type {string} */
23
- this.url = opts.url
24
-
25
- /** @type {HTMLImageElement|undefined} */
26
- this.img = undefined
27
-
28
- /** @type {number|undefined} */
29
- this.xMin = undefined
30
- /** @type {number|undefined} */
31
- this.xMax = undefined
32
- /** @type {number|undefined} */
33
- this.yMin = undefined
34
- /** @type {number|undefined} */
35
- this.yMax = undefined
36
- }
37
-
38
- /** Check if the view has moved and a new image needs to be retrieved.
39
- * @private */
40
- hasMoved(extGeo) {
41
- if (extGeo.xMin != this.xMin) return true
42
- else if (extGeo.xMax != this.xMax) return true
43
- else if (extGeo.yMin != this.yMin) return true
44
- else if (extGeo.yMax != this.yMax) return true
45
- else return false
46
- }
47
-
48
- /**
49
- * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
50
- * @returns {void}
51
- */
52
- draw(geoCanvas) {
53
- //update map extent
54
- geoCanvas.updateExtentGeo(0)
55
-
56
- if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
57
- //the map did not move and the image was already downloaded: draw the image
58
- geoCanvas.initCanvasTransform()
59
- geoCanvas.offscreenCtx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
60
- } else {
61
- //the map moved: retrieve new image
62
-
63
- //
64
- this.xMin = geoCanvas.extGeo.xMin
65
- this.xMax = geoCanvas.extGeo.xMax
66
- this.yMin = geoCanvas.extGeo.yMin
67
- this.yMax = geoCanvas.extGeo.yMax
68
-
69
- //build WMS URL
70
- const url = []
71
- url.push(this.url)
72
- url.push('&width=')
73
- url.push(geoCanvas.w)
74
- url.push('&height=')
75
- url.push(geoCanvas.h)
76
- //bbox: xmin ymin xmax ymax
77
- url.push('&bbox=')
78
- url.push(geoCanvas.extGeo.xMin)
79
- url.push(',')
80
- url.push(geoCanvas.extGeo.yMin)
81
- url.push(',')
82
- url.push(geoCanvas.extGeo.xMax)
83
- url.push(',')
84
- url.push(geoCanvas.extGeo.yMax)
85
-
86
- const urlS = url.join('')
87
- //console.log(urlS)
88
-
89
- if (!this.img) {
90
- this.img = new Image()
91
- this.img.onload = () => {
92
- geoCanvas.redraw()
93
- }
94
- this.img.onerror = () => {
95
- //case when no image
96
- console.warn('Could not retrieve WMS background image from', urlS)
97
- }
98
- }
99
-
100
- //set URL to launch the download
101
- this.img.src = urlS
102
- }
103
- }
104
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Layer } from '../core/Layer.js'
5
+
6
+ /**
7
+ *
8
+ * A map WMS background layer.
9
+ *
10
+ * @module layer
11
+ * @author Julien Gaffuri
12
+ */
13
+ export class BackgroundLayerWMS extends Layer {
14
+ /**
15
+ * @param {object} opts
16
+ */
17
+ constructor(opts) {
18
+ super(opts)
19
+ opts = opts || {}
20
+
21
+ /**
22
+ * @type {string} */
23
+ this.url = opts.url
24
+
25
+ /** @type {HTMLImageElement|undefined} */
26
+ this.img = undefined
27
+
28
+ /** @type {number|undefined} */
29
+ this.xMin = undefined
30
+ /** @type {number|undefined} */
31
+ this.xMax = undefined
32
+ /** @type {number|undefined} */
33
+ this.yMin = undefined
34
+ /** @type {number|undefined} */
35
+ this.yMax = undefined
36
+ }
37
+
38
+ /** Check if the view has moved and a new image needs to be retrieved.
39
+ * @private */
40
+ hasMoved(extGeo) {
41
+ if (extGeo.xMin != this.xMin) return true
42
+ else if (extGeo.xMax != this.xMax) return true
43
+ else if (extGeo.yMin != this.yMin) return true
44
+ else if (extGeo.yMax != this.yMax) return true
45
+ else return false
46
+ }
47
+
48
+ /**
49
+ * @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
50
+ * @returns {void}
51
+ */
52
+ draw(geoCanvas) {
53
+ //update map extent
54
+ geoCanvas.updateExtentGeo(0)
55
+
56
+ if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
57
+ //the map did not move and the image was already downloaded: draw the image
58
+ geoCanvas.initCanvasTransform()
59
+ geoCanvas.offscreenCtx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
60
+ } else {
61
+ //the map moved: retrieve new image
62
+
63
+ //
64
+ this.xMin = geoCanvas.extGeo.xMin
65
+ this.xMax = geoCanvas.extGeo.xMax
66
+ this.yMin = geoCanvas.extGeo.yMin
67
+ this.yMax = geoCanvas.extGeo.yMax
68
+
69
+ //build WMS URL
70
+ const url = []
71
+ url.push(this.url)
72
+ url.push('&width=')
73
+ url.push(geoCanvas.w)
74
+ url.push('&height=')
75
+ url.push(geoCanvas.h)
76
+ //bbox: xmin ymin xmax ymax
77
+ url.push('&bbox=')
78
+ url.push(geoCanvas.extGeo.xMin)
79
+ url.push(',')
80
+ url.push(geoCanvas.extGeo.yMin)
81
+ url.push(',')
82
+ url.push(geoCanvas.extGeo.xMax)
83
+ url.push(',')
84
+ url.push(geoCanvas.extGeo.yMax)
85
+
86
+ const urlS = url.join('')
87
+ //console.log(urlS)
88
+
89
+ if (!this.img) {
90
+ this.img = new Image()
91
+ this.img.onload = () => {
92
+ geoCanvas.redraw()
93
+ }
94
+ this.img.onerror = () => {
95
+ //case when no image
96
+ console.warn('Could not retrieve WMS background image from', urlS)
97
+ }
98
+ }
99
+
100
+ //set URL to launch the download
101
+ this.img.src = urlS
102
+ }
103
+ }
104
+ }
@@ -1,214 +1,214 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Layer } from '../core/Layer.js'
5
- import { json } from 'd3-fetch'
6
-
7
- /**
8
- * @module layer
9
- * @author Joseph Davies, Julien Gaffuri
10
- */
11
- export class GeoJSONLayer extends Layer {
12
- /**
13
- * @param {object} opts
14
- */
15
- constructor(opts) {
16
- super(opts)
17
- opts = opts || {}
18
-
19
- /**
20
- * @private
21
- * @type {string} */
22
- this.url = opts.url
23
-
24
- /**
25
- * A preprocess to run on each feature after loading.
26
- * It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
27
- * Return false if the label should not be kept.
28
- * @private
29
- * @type {function(object):boolean} */
30
- this.preprocess = opts.preprocess
31
-
32
- //for points
33
- /**
34
- * @private
35
- * @type {function(object,number):string} */
36
- this.shape = opts.shape || ((f, z) => 'circle')
37
- /**
38
- * In pixel
39
- * @private
40
- * @type {function(object,number):number} */
41
- this.size = opts.size || ((f, z) => 10)
42
- /**
43
- * @private
44
- * @type {function(object,number):string} */
45
- this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
46
- /**
47
- * @private
48
- * @type {function(object,number):string} */
49
- this.fillStyle = opts.fillStyle || ((f, z) => 'black')
50
- /**
51
- * In pixel
52
- * @private
53
- * @type {function(object,number):number} */
54
- this.lineWidth = opts.lineWidth || ((f, z) => 2)
55
-
56
- //for lines
57
-
58
- /**
59
- * @private
60
- * @type {function(object,number):string} */
61
- this.color = opts.color || ((f, z) => 'gray')
62
- /**
63
- * In pixel
64
- * @private
65
- * @type {function(object,number):number} */
66
- this.width = opts.width || ((f, z) => 2)
67
- /**
68
- * @private
69
- * @type {function(object,number):Array.<number>|undefined} */
70
- this.lineDash = opts.lineDash || ((f, z) => undefined)
71
-
72
- /**
73
- * @private
74
- * @type {Array.<object> | undefined} */
75
- this.fs = undefined
76
-
77
- /**
78
- * @private
79
- * @type {string} */
80
- this.loadingStatus = 'notLoaded'
81
- }
82
-
83
- /**
84
- * Draw the layer.
85
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
86
- * @returns {void}
87
- */
88
- draw(geoCanvas) {
89
- //load data, if not done yet.
90
- if (!this.fs) {
91
- this.load(geoCanvas.redraw)
92
- return
93
- }
94
-
95
- //
96
- const z = geoCanvas.view.z
97
- const ctx = geoCanvas.offscreenCtx
98
-
99
- for (const f of this.fs) {
100
- const gt = f.geometry.type
101
-
102
- if (gt == 'Point') {
103
- const c = f.geometry.coordinates
104
-
105
- //get style parameters for the point feature
106
- const shape = this.shape(f, z)
107
- if (!shape || shape == 'none') continue
108
- const size = this.size(f, z) * z
109
- if (!size) continue
110
- const strokeStyle = this.strokeStyle(f, z)
111
- const fillStyle = this.fillStyle(f, z)
112
- const lineWidth = this.lineWidth(f, z) * z
113
-
114
- //set canvas drawing parameters
115
- if (strokeStyle) ctx.strokeStyle = strokeStyle
116
- if (fillStyle) ctx.fillStyle = fillStyle
117
- if (lineWidth) ctx.lineWidth = lineWidth
118
-
119
- if (shape == 'circle') {
120
- //draw circle - fill and stroke
121
- ctx.beginPath()
122
- ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
123
- if (fillStyle) ctx.fill()
124
- if (strokeStyle && lineWidth) ctx.stroke()
125
- } else if (shape == 'square') {
126
- //draw square - fill and stroke
127
- ctx.beginPath()
128
- ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
129
- if (fillStyle) ctx.fill()
130
- if (strokeStyle && lineWidth) ctx.stroke()
131
- } else {
132
- console.error('Unexpected shape for point geojson: ' + shape)
133
- }
134
- } else if (gt == 'LineString') {
135
- const cs = f.geometry.coordinates
136
- if (cs.length < 2) continue
137
-
138
- //set color
139
- const col = this.color(f, z)
140
- if (!col || col == 'none') continue
141
- ctx.strokeStyle = col
142
-
143
- //set linewidth
144
- const wP = this.width(f, z)
145
- if (!wP || wP < 0) continue
146
- ctx.lineWidth = wP * z
147
-
148
- //set line dash
149
- const ldP = this.lineDash(f, z)
150
- if (ldP) ctx.setLineDash(ldP)
151
-
152
- //draw line
153
- ctx.beginPath()
154
- ctx.moveTo(cs[0][0], cs[0][1])
155
- for (let i = 1; i < cs.length; i++) ctx.lineTo(cs[i][0], cs[i][1])
156
- ctx.stroke()
157
- } else {
158
- console.log('Unsupported geometry type in GeoJSONLayer: ' + gt)
159
- }
160
- }
161
-
162
- //...
163
- ctx.setLineDash([])
164
- }
165
-
166
- /**
167
- * Load data for labels, from URL this.url
168
- * @param {function():void} callback
169
- * @private
170
- */
171
- async load(callback) {
172
- if (!this.url) {
173
- console.log('Failed loading boundaries: No URL specified. ' + this.url)
174
- this.loadingStatus = 'failed'
175
- this.labels = []
176
- return
177
- }
178
-
179
- //check if data already loaded
180
- if (this.loadingStatus != 'notLoaded') return
181
-
182
- //load data
183
- this.loadingStatus = 'loading'
184
-
185
- try {
186
- const data_ = await json(this.url)
187
-
188
- /** @type { Array.<object> } */
189
- const data = data_.features
190
-
191
- //preprocess/filter
192
- if (this.preprocess) {
193
- this.fs = []
194
- for (const c of data) {
195
- const b = this.preprocess(c)
196
- if (b == false) continue
197
- this.fs.push(c)
198
- }
199
- } else {
200
- //store labels
201
- this.fs = data
202
- }
203
-
204
- this.loadingStatus = 'loaded'
205
-
206
- //redraw
207
- if (callback) callback()
208
- } catch (error) {
209
- console.log('Failed loading boundaries from ' + this.url)
210
- this.fs = []
211
- this.loadingStatus = 'failed'
212
- }
213
- }
214
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Layer } from '../core/Layer.js'
5
+ import { json } from 'd3-fetch'
6
+
7
+ /**
8
+ * @module layer
9
+ * @author Joseph Davies, Julien Gaffuri
10
+ */
11
+ export class GeoJSONLayer extends Layer {
12
+ /**
13
+ * @param {object} opts
14
+ */
15
+ constructor(opts) {
16
+ super(opts)
17
+ opts = opts || {}
18
+
19
+ /**
20
+ * @private
21
+ * @type {string} */
22
+ this.url = opts.url
23
+
24
+ /**
25
+ * A preprocess to run on each feature after loading.
26
+ * It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
27
+ * Return false if the label should not be kept.
28
+ * @private
29
+ * @type {function(object):boolean} */
30
+ this.preprocess = opts.preprocess
31
+
32
+ //for points
33
+ /**
34
+ * @private
35
+ * @type {function(object,number):string} */
36
+ this.shape = opts.shape || ((f, z) => 'circle')
37
+ /**
38
+ * In pixel
39
+ * @private
40
+ * @type {function(object,number):number} */
41
+ this.size = opts.size || ((f, z) => 10)
42
+ /**
43
+ * @private
44
+ * @type {function(object,number):string} */
45
+ this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
46
+ /**
47
+ * @private
48
+ * @type {function(object,number):string} */
49
+ this.fillStyle = opts.fillStyle || ((f, z) => 'black')
50
+ /**
51
+ * In pixel
52
+ * @private
53
+ * @type {function(object,number):number} */
54
+ this.lineWidth = opts.lineWidth || ((f, z) => 2)
55
+
56
+ //for lines
57
+
58
+ /**
59
+ * @private
60
+ * @type {function(object,number):string} */
61
+ this.color = opts.color || ((f, z) => 'gray')
62
+ /**
63
+ * In pixel
64
+ * @private
65
+ * @type {function(object,number):number} */
66
+ this.width = opts.width || ((f, z) => 2)
67
+ /**
68
+ * @private
69
+ * @type {function(object,number):Array.<number>|undefined} */
70
+ this.lineDash = opts.lineDash || ((f, z) => undefined)
71
+
72
+ /**
73
+ * @private
74
+ * @type {Array.<object> | undefined} */
75
+ this.fs = undefined
76
+
77
+ /**
78
+ * @private
79
+ * @type {string} */
80
+ this.loadingStatus = 'notLoaded'
81
+ }
82
+
83
+ /**
84
+ * Draw the layer.
85
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
86
+ * @returns {void}
87
+ */
88
+ draw(geoCanvas) {
89
+ //load data, if not done yet.
90
+ if (!this.fs) {
91
+ this.load(geoCanvas.redraw)
92
+ return
93
+ }
94
+
95
+ //
96
+ const z = geoCanvas.view.z
97
+ const ctx = geoCanvas.offscreenCtx
98
+
99
+ for (const f of this.fs) {
100
+ const gt = f.geometry.type
101
+
102
+ if (gt == 'Point') {
103
+ const c = f.geometry.coordinates
104
+
105
+ //get style parameters for the point feature
106
+ const shape = this.shape(f, z)
107
+ if (!shape || shape == 'none') continue
108
+ const size = this.size(f, z) * z
109
+ if (!size) continue
110
+ const strokeStyle = this.strokeStyle(f, z)
111
+ const fillStyle = this.fillStyle(f, z)
112
+ const lineWidth = this.lineWidth(f, z) * z
113
+
114
+ //set canvas drawing parameters
115
+ if (strokeStyle) ctx.strokeStyle = strokeStyle
116
+ if (fillStyle) ctx.fillStyle = fillStyle
117
+ if (lineWidth) ctx.lineWidth = lineWidth
118
+
119
+ if (shape == 'circle') {
120
+ //draw circle - fill and stroke
121
+ ctx.beginPath()
122
+ ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
123
+ if (fillStyle) ctx.fill()
124
+ if (strokeStyle && lineWidth) ctx.stroke()
125
+ } else if (shape == 'square') {
126
+ //draw square - fill and stroke
127
+ ctx.beginPath()
128
+ ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
129
+ if (fillStyle) ctx.fill()
130
+ if (strokeStyle && lineWidth) ctx.stroke()
131
+ } else {
132
+ console.error('Unexpected shape for point geojson: ' + shape)
133
+ }
134
+ } else if (gt == 'LineString') {
135
+ const cs = f.geometry.coordinates
136
+ if (cs.length < 2) continue
137
+
138
+ //set color
139
+ const col = this.color(f, z)
140
+ if (!col || col == 'none') continue
141
+ ctx.strokeStyle = col
142
+
143
+ //set linewidth
144
+ const wP = this.width(f, z)
145
+ if (!wP || wP < 0) continue
146
+ ctx.lineWidth = wP * z
147
+
148
+ //set line dash
149
+ const ldP = this.lineDash(f, z)
150
+ if (ldP) ctx.setLineDash(ldP)
151
+
152
+ //draw line
153
+ ctx.beginPath()
154
+ ctx.moveTo(cs[0][0], cs[0][1])
155
+ for (let i = 1; i < cs.length; i++) ctx.lineTo(cs[i][0], cs[i][1])
156
+ ctx.stroke()
157
+ } else {
158
+ console.log('Unsupported geometry type in GeoJSONLayer: ' + gt)
159
+ }
160
+ }
161
+
162
+ //...
163
+ ctx.setLineDash([])
164
+ }
165
+
166
+ /**
167
+ * Load data for labels, from URL this.url
168
+ * @param {function():void} callback
169
+ * @private
170
+ */
171
+ async load(callback) {
172
+ if (!this.url) {
173
+ console.log('Failed loading boundaries: No URL specified. ' + this.url)
174
+ this.loadingStatus = 'failed'
175
+ this.labels = []
176
+ return
177
+ }
178
+
179
+ //check if data already loaded
180
+ if (this.loadingStatus != 'notLoaded') return
181
+
182
+ //load data
183
+ this.loadingStatus = 'loading'
184
+
185
+ try {
186
+ const data_ = await json(this.url)
187
+
188
+ /** @type { Array.<object> } */
189
+ const data = data_.features
190
+
191
+ //preprocess/filter
192
+ if (this.preprocess) {
193
+ this.fs = []
194
+ for (const c of data) {
195
+ const b = this.preprocess(c)
196
+ if (b == false) continue
197
+ this.fs.push(c)
198
+ }
199
+ } else {
200
+ //store labels
201
+ this.fs = data
202
+ }
203
+
204
+ this.loadingStatus = 'loaded'
205
+
206
+ //redraw
207
+ if (callback) callback()
208
+ } catch (error) {
209
+ console.log('Failed loading boundaries from ' + this.url)
210
+ this.fs = []
211
+ this.loadingStatus = 'failed'
212
+ }
213
+ }
214
+ }