@mwater/visualization 5.6.0 → 5.6.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/lib/ColorComponent.js +2 -2
- package/lib/TranslationsTabComponent.d.ts +34 -0
- package/lib/TranslationsTabComponent.js +256 -0
- package/lib/dashboards/DashboardComponent.js +1 -1
- package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
- package/lib/dashboards/ServerDashboardDataSource.js +0 -15
- package/lib/dashboards/SettingsModalComponent.js +9 -233
- package/lib/datagrids/DatagridComponent.js +5 -0
- package/lib/datagrids/DatagridViewComponent.js +30 -4
- package/lib/maps/BufferLayer.d.ts +0 -13
- package/lib/maps/BufferLayer.js +12 -237
- package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.js +0 -5
- package/lib/maps/ChoroplethLayer.d.ts +1 -16
- package/lib/maps/ChoroplethLayer.js +13 -358
- package/lib/maps/ClusterLayer.d.ts +0 -9
- package/lib/maps/ClusterLayer.js +0 -250
- package/lib/maps/DirectMapDataSource.js +1 -38
- package/lib/maps/GridLayer.d.ts +0 -15
- package/lib/maps/GridLayer.js +0 -212
- package/lib/maps/Layer.d.ts +1 -26
- package/lib/maps/Layer.js +0 -13
- package/lib/maps/MapComponent.d.ts +19 -35
- package/lib/maps/MapComponent.js +135 -76
- package/lib/maps/MapControlComponent.d.ts +4 -5
- package/lib/maps/MapControlComponent.js +5 -12
- package/lib/maps/MapDesign.d.ts +8 -0
- package/lib/maps/MapDesignerComponent.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.js +7 -2
- package/lib/maps/MapLayerDataSource.d.ts +0 -4
- package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
- package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
- package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
- package/lib/maps/MapLayersDesignerComponent.js +2 -1
- package/lib/maps/MapTranslationsTab.d.ts +15 -0
- package/lib/maps/MapTranslationsTab.js +47 -0
- package/lib/maps/MapUtils.d.ts +11 -0
- package/lib/maps/MapUtils.js +47 -0
- package/lib/maps/MapViewComponent.d.ts +1 -1
- package/lib/maps/MapViewComponent.js +1 -8
- package/lib/maps/MarkersLayer.d.ts +1 -14
- package/lib/maps/MarkersLayer.js +71 -252
- package/lib/maps/MarkersLayerDesign.d.ts +4 -0
- package/lib/maps/MarkersLayerDesignerComponent.d.ts +20 -16
- package/lib/maps/MarkersLayerDesignerComponent.js +77 -23
- package/lib/maps/ServerMapDataSource.d.ts +0 -1
- package/lib/maps/ServerMapDataSource.js +0 -15
- package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
- package/lib/maps/SwitchableTileUrlLayer.js +0 -9
- package/lib/maps/TileUrlLayer.d.ts +0 -1
- package/lib/maps/TileUrlLayer.js +0 -5
- package/lib/maps/VectorMapViewComponent.js +12 -1
- package/lib/maps/vectorMaps.d.ts +5 -6
- package/lib/maps/vectorMaps.js +13 -9
- package/lib/widgets/MapWidget.js +2 -1
- package/package.json +2 -2
- package/src/ColorComponent.tsx +2 -2
- package/src/TranslationsTabComponent.tsx +429 -0
- package/src/dashboards/DashboardComponent.tsx +1 -1
- package/src/dashboards/ServerDashboardDataSource.ts +0 -19
- package/src/dashboards/SettingsModalComponent.tsx +27 -383
- package/src/datagrids/DatagridComponent.tsx +6 -0
- package/src/datagrids/DatagridViewComponent.tsx +41 -5
- package/src/maps/BufferLayer.ts +16 -262
- package/src/maps/BufferLayerDesignerComponent.tsx +0 -6
- package/src/maps/ChoroplethLayer.ts +16 -393
- package/src/maps/ClusterLayer.ts +0 -274
- package/src/maps/DirectMapDataSource.ts +2 -49
- package/src/maps/GridLayer.ts +0 -224
- package/src/maps/Layer.ts +1 -35
- package/src/maps/MapComponent.tsx +448 -0
- package/src/maps/MapControlComponent.tsx +41 -0
- package/src/maps/MapDesign.ts +6 -0
- package/src/maps/MapDesignerComponent.tsx +18 -1
- package/src/maps/MapLayerDataSource.ts +0 -5
- package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
- package/src/maps/MapLayersDesignerComponent.ts +4 -1
- package/src/maps/MapTranslationsTab.tsx +53 -0
- package/src/maps/MapUtils.ts +48 -0
- package/src/maps/MapViewComponent.tsx +2 -8
- package/src/maps/MarkersLayer.ts +79 -270
- package/src/maps/MarkersLayerDesign.ts +6 -0
- package/src/maps/MarkersLayerDesignerComponent.tsx +114 -38
- package/src/maps/ServerMapDataSource.ts +0 -19
- package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
- package/src/maps/TileUrlLayer.tsx +0 -6
- package/src/maps/VectorMapViewComponent.tsx +13 -2
- package/src/maps/vectorMaps.tsx +12 -9
- package/src/widgets/MapWidget.tsx +2 -0
- package/src/maps/MapComponent.ts +0 -311
- package/src/maps/MapControlComponent.ts +0 -46
- package/src/maps/RasterMapViewComponent.ts +0 -345
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import PropTypes from "prop-types"
|
|
2
|
-
import React from "react"
|
|
3
|
-
const R = React.createElement
|
|
4
|
-
|
|
5
|
-
import MapLayersDesignerComponent from "./MapLayersDesignerComponent"
|
|
6
|
-
import BaseLayerDesignerComponent from "./BaseLayerDesignerComponent"
|
|
7
|
-
import { DataSource, Schema } from "@mwater/expressions"
|
|
8
|
-
|
|
9
|
-
export interface MapControlComponentProps {
|
|
10
|
-
/** Schema to use */
|
|
11
|
-
schema: Schema
|
|
12
|
-
dataSource: DataSource
|
|
13
|
-
/** See Map Design.md */
|
|
14
|
-
design: any
|
|
15
|
-
onDesignChange: any
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Allows controlling readonly map
|
|
19
|
-
export default class MapControlComponent extends React.Component<MapControlComponentProps> {
|
|
20
|
-
render() {
|
|
21
|
-
return R(
|
|
22
|
-
"div",
|
|
23
|
-
{ style: { padding: 5 } },
|
|
24
|
-
R(MapLayersDesignerComponent, {
|
|
25
|
-
schema: this.props.schema,
|
|
26
|
-
dataSource: this.props.dataSource,
|
|
27
|
-
design: this.props.design,
|
|
28
|
-
onDesignChange: this.props.onDesignChange,
|
|
29
|
-
allowEditingLayers: false
|
|
30
|
-
}),
|
|
31
|
-
|
|
32
|
-
R("br"),
|
|
33
|
-
|
|
34
|
-
R(
|
|
35
|
-
"div",
|
|
36
|
-
{ className: "mb-3" },
|
|
37
|
-
R("label", { className: "text-muted" }, T`Map Style`),
|
|
38
|
-
|
|
39
|
-
R(BaseLayerDesignerComponent, {
|
|
40
|
-
design: this.props.design,
|
|
41
|
-
onDesignChange: this.props.onDesignChange
|
|
42
|
-
})
|
|
43
|
-
)
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import _ from "lodash"
|
|
2
|
-
import React, { ReactNode } from "react"
|
|
3
|
-
const R = React.createElement
|
|
4
|
-
import LeafletMapComponent, { TileLayer } from "./LeafletMapComponent"
|
|
5
|
-
import { ExprUtils, Schema, DataSource } from "@mwater/expressions"
|
|
6
|
-
import LayerFactory from "./LayerFactory"
|
|
7
|
-
import ModalPopupComponent from "@mwater/react-library/lib/ModalPopupComponent"
|
|
8
|
-
import * as MapUtils from "./MapUtils"
|
|
9
|
-
import { LayerSwitcherComponent } from "./LayerSwitcherComponent"
|
|
10
|
-
import { default as LegendComponent } from "./LegendComponent"
|
|
11
|
-
import { JsonQLFilter } from "../JsonQLFilter"
|
|
12
|
-
import { MapDesign } from "./MapDesign"
|
|
13
|
-
import { LocaleContext } from "@mwater/expressions-ui"
|
|
14
|
-
import { MapViewComponentProps } from "./MapViewComponent"
|
|
15
|
-
|
|
16
|
-
export interface RasterMapViewComponentProps extends MapViewComponentProps {
|
|
17
|
-
/** Called with underlying leaflet map component */
|
|
18
|
-
leafletMapRef?: (map: LeafletMapComponent | null) => void
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Component that displays just the map, using raster tile technology */
|
|
22
|
-
export default class RasterMapViewComponent extends React.Component<
|
|
23
|
-
RasterMapViewComponentProps,
|
|
24
|
-
{
|
|
25
|
-
popupContents: ReactNode
|
|
26
|
-
legendHidden: boolean
|
|
27
|
-
}
|
|
28
|
-
> {
|
|
29
|
-
static contextType = LocaleContext
|
|
30
|
-
|
|
31
|
-
leafletMap?: LeafletMapComponent | null
|
|
32
|
-
|
|
33
|
-
constructor(props: any) {
|
|
34
|
-
super(props)
|
|
35
|
-
|
|
36
|
-
const initialLegendDisplay = props.design.initialLegendDisplay || "open"
|
|
37
|
-
|
|
38
|
-
this.state = {
|
|
39
|
-
popupContents: null, // Element in the popup
|
|
40
|
-
legendHidden: initialLegendDisplay === "closed" || (props.width < 500 && initialLegendDisplay === "closedIfSmall")
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
componentDidMount() {
|
|
45
|
-
// Autozoom
|
|
46
|
-
if (this.props.design.autoBounds) {
|
|
47
|
-
return this.performAutoZoom()
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
componentDidUpdate(prevProps: any) {
|
|
52
|
-
if (this.props.design.autoBounds) {
|
|
53
|
-
// Autozoom if filters or autozoom changed
|
|
54
|
-
if (
|
|
55
|
-
!_.isEqual(this.props.design.filters, prevProps.design.filters) ||
|
|
56
|
-
!_.isEqual(this.props.design.globalFilters, prevProps.design.globalFilters) ||
|
|
57
|
-
!_.isEqual(this.props.extraFilters, prevProps.extraFilters) ||
|
|
58
|
-
!prevProps.design.autoBounds
|
|
59
|
-
) {
|
|
60
|
-
return this.performAutoZoom()
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
// Update bounds
|
|
64
|
-
if (!_.isEqual(this.props.design.bounds, prevProps.design.bounds)) {
|
|
65
|
-
return this.leafletMap?.setBounds(this.props.design.bounds)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
performAutoZoom() {
|
|
71
|
-
return this.props.mapDataSource.getBounds(
|
|
72
|
-
this.props.design,
|
|
73
|
-
this.getCompiledFilters(),
|
|
74
|
-
(error: any, bounds: any) => {
|
|
75
|
-
if (bounds) {
|
|
76
|
-
this.leafletMap?.setBounds(bounds, 0.2)
|
|
77
|
-
|
|
78
|
-
// Also record if editable as part of bounds
|
|
79
|
-
if (this.props.onDesignChange != null) {
|
|
80
|
-
return this.props.onDesignChange(_.extend({}, this.props.design, { bounds }))
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
handleBoundsChange = (bounds: any) => {
|
|
88
|
-
// Ignore if readonly
|
|
89
|
-
if (this.props.onDesignChange == null) {
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (this.props.zoomLocked) {
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Ignore if autoBounds
|
|
98
|
-
if (this.props.design.autoBounds) {
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const design = _.extend({}, this.props.design, { bounds }) as MapDesign
|
|
103
|
-
return this.props.onDesignChange(design)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
handleGridClick = (layerViewId: any, ev: any) => {
|
|
107
|
-
const layerView = _.findWhere(this.props.design.layerViews, { id: layerViewId })!
|
|
108
|
-
|
|
109
|
-
// Create layer
|
|
110
|
-
const layer = LayerFactory.createLayer(layerView.type)
|
|
111
|
-
|
|
112
|
-
// Clean design (prevent ever displaying invalid/legacy designs)
|
|
113
|
-
const design = layer.cleanDesign(layerView.design, this.props.schema)
|
|
114
|
-
|
|
115
|
-
// Handle click of layer
|
|
116
|
-
// TODO not translated
|
|
117
|
-
const results = layer.onGridClick(ev, {
|
|
118
|
-
design,
|
|
119
|
-
schema: this.props.schema,
|
|
120
|
-
dataSource: this.props.dataSource,
|
|
121
|
-
layerDataSource: this.props.mapDataSource.getLayerDataSource(layerViewId),
|
|
122
|
-
scopeData: this.props.scope?.data?.layerViewId === layerViewId ? this.props.scope!.data.data : undefined,
|
|
123
|
-
filters: this.getCompiledFilters(),
|
|
124
|
-
locale: this.context,
|
|
125
|
-
translate: (input: string) => input
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
if (!results) {
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Handle popup first
|
|
133
|
-
if (results.popup) {
|
|
134
|
-
this.setState({ popupContents: results.popup })
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Handle onRowClick case
|
|
138
|
-
if (results.row && this.props.onRowClick) {
|
|
139
|
-
this.props.onRowClick(results.row.tableId, results.row.primaryKey)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Handle scoping
|
|
143
|
-
if (this.props.onScopeChange && _.has(results, "scope")) {
|
|
144
|
-
let scope
|
|
145
|
-
if (results.scope) {
|
|
146
|
-
// Encode layer view id into scope
|
|
147
|
-
scope = {
|
|
148
|
-
name: results.scope.name,
|
|
149
|
-
filter: results.scope.filter,
|
|
150
|
-
data: { layerViewId, data: results.scope.data }
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
153
|
-
scope = null
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return this.props.onScopeChange(scope)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Get filters from extraFilters combined with map filters
|
|
161
|
-
getCompiledFilters() {
|
|
162
|
-
return (this.props.extraFilters || []).concat(
|
|
163
|
-
MapUtils.getCompiledFilters(
|
|
164
|
-
this.props.design,
|
|
165
|
-
this.props.schema,
|
|
166
|
-
MapUtils.getFilterableTables(this.props.design, this.props.schema)
|
|
167
|
-
)
|
|
168
|
-
)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
renderLegend() {
|
|
172
|
-
if (this.state.legendHidden) {
|
|
173
|
-
return R(HiddenLegend, { onShow: () => this.setState({ legendHidden: false }) })
|
|
174
|
-
} else {
|
|
175
|
-
return R(LegendComponent, {
|
|
176
|
-
schema: this.props.schema,
|
|
177
|
-
layerViews: this.props.design.layerViews,
|
|
178
|
-
filters: this.getCompiledFilters(),
|
|
179
|
-
dataSource: this.props.dataSource,
|
|
180
|
-
locale: this.context,
|
|
181
|
-
translate: this.props.translate ?? ((input: string) => input),
|
|
182
|
-
onHide: () => this.setState({ legendHidden: true }),
|
|
183
|
-
zoom: null
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
renderPopup() {
|
|
189
|
-
if (!this.state.popupContents) {
|
|
190
|
-
return null
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return R(
|
|
194
|
-
ModalPopupComponent,
|
|
195
|
-
{
|
|
196
|
-
onClose: () => this.setState({ popupContents: null }),
|
|
197
|
-
showCloseX: true,
|
|
198
|
-
size: "x-large"
|
|
199
|
-
},
|
|
200
|
-
// Render in fixed height div so that dashboard doesn't collapse to nothing
|
|
201
|
-
R("div", { style: { height: "80vh" } }, this.state.popupContents),
|
|
202
|
-
R(
|
|
203
|
-
"div",
|
|
204
|
-
{ style: { textAlign: "right", marginTop: 10 } },
|
|
205
|
-
R("button", { className: "btn btn-secondary", onClick: () => this.setState({ popupContents: null }) }, T`Close`)
|
|
206
|
-
)
|
|
207
|
-
)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
render() {
|
|
211
|
-
let design, scopedCompiledFilters
|
|
212
|
-
const compiledFilters = this.getCompiledFilters()
|
|
213
|
-
|
|
214
|
-
// Determine scoped filters
|
|
215
|
-
if (this.props.scope) {
|
|
216
|
-
scopedCompiledFilters = compiledFilters.concat([this.props.scope.filter])
|
|
217
|
-
} else {
|
|
218
|
-
scopedCompiledFilters = compiledFilters
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Convert to leaflet layers, if layers are valid
|
|
222
|
-
const leafletLayers = []
|
|
223
|
-
for (let index = 0; index < this.props.design.layerViews.length; index++) {
|
|
224
|
-
// Create layer
|
|
225
|
-
const layerView = this.props.design.layerViews[index]
|
|
226
|
-
const layer = LayerFactory.createLayer(layerView.type)
|
|
227
|
-
|
|
228
|
-
// Clean design (prevent ever displaying invalid/legacy designs)
|
|
229
|
-
design = layer.cleanDesign(layerView.design, this.props.schema)
|
|
230
|
-
|
|
231
|
-
// Ignore if invalid
|
|
232
|
-
if (layer.validateDesign(design, this.props.schema)) {
|
|
233
|
-
continue
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Get layer data source
|
|
237
|
-
const layerDataSource = this.props.mapDataSource.getLayerDataSource(layerView.id)
|
|
238
|
-
|
|
239
|
-
// If layer is scoping, fade opacity and add extra filtered version
|
|
240
|
-
const isScoping = this.props.scope && this.props.scope.data.layerViewId === layerView.id
|
|
241
|
-
|
|
242
|
-
// Create leafletLayer
|
|
243
|
-
let leafletLayer: TileLayer = {
|
|
244
|
-
tileUrl: layerDataSource.getTileUrl(design, isScoping ? compiledFilters : scopedCompiledFilters)!,
|
|
245
|
-
utfGridUrl: this.props.disableInteraction
|
|
246
|
-
? undefined
|
|
247
|
-
: layerDataSource.getUtfGridUrl(design, isScoping ? compiledFilters : scopedCompiledFilters) ?? undefined,
|
|
248
|
-
visible: layerView.visible,
|
|
249
|
-
opacity: isScoping ? layerView.opacity * 0.3 : layerView.opacity,
|
|
250
|
-
minZoom: layer.getMinZoom(design) ?? undefined,
|
|
251
|
-
maxZoom: layer.getMaxZoom(design) ?? undefined,
|
|
252
|
-
onGridClick: this.handleGridClick.bind(null, layerView.id)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
leafletLayers.push(leafletLayer)
|
|
256
|
-
|
|
257
|
-
// Add scoped layer if scoping
|
|
258
|
-
if (isScoping) {
|
|
259
|
-
leafletLayer = {
|
|
260
|
-
tileUrl: layerDataSource.getTileUrl(design, scopedCompiledFilters)!,
|
|
261
|
-
utfGridUrl: this.props.disableInteraction
|
|
262
|
-
? undefined
|
|
263
|
-
: layerDataSource.getUtfGridUrl(design, scopedCompiledFilters) ?? undefined,
|
|
264
|
-
visible: layerView.visible,
|
|
265
|
-
opacity: layerView.opacity,
|
|
266
|
-
minZoom: layer.getMinZoom(design) ?? undefined,
|
|
267
|
-
maxZoom: layer.getMaxZoom(design) ?? undefined,
|
|
268
|
-
onGridClick: this.handleGridClick.bind(null, layerView.id)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
leafletLayers.push(leafletLayer)
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return R(
|
|
276
|
-
"div",
|
|
277
|
-
{ style: { width: this.props.width, height: this.props.height, position: "relative" } },
|
|
278
|
-
this.renderPopup(),
|
|
279
|
-
R(
|
|
280
|
-
"div",
|
|
281
|
-
{ style: { position: "absolute", maxWidth: 250, top: 10, right: 10, zIndex: 999, userSelect: "none" } },
|
|
282
|
-
R(
|
|
283
|
-
"div",
|
|
284
|
-
{ style: { display: "flex", gap: 6, position: "relative", flexDirection: "column", alignItems: "right" } },
|
|
285
|
-
this.props.onDesignChange && this.props.design.showLayerSwitcher
|
|
286
|
-
? R(LayerSwitcherComponent, {
|
|
287
|
-
design: this.props.design,
|
|
288
|
-
onDesignChange: this.props.onDesignChange,
|
|
289
|
-
translate: this.props.translate ?? (() => "")
|
|
290
|
-
})
|
|
291
|
-
: undefined
|
|
292
|
-
)
|
|
293
|
-
),
|
|
294
|
-
|
|
295
|
-
R(LeafletMapComponent, {
|
|
296
|
-
ref: (c: LeafletMapComponent | null) => {
|
|
297
|
-
this.leafletMap = c
|
|
298
|
-
if (this.props.leafletMapRef) {
|
|
299
|
-
this.props.leafletMapRef(c)
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
initialBounds: this.props.design.bounds,
|
|
303
|
-
baseLayerId: this.props.design.baseLayer,
|
|
304
|
-
baseLayerOpacity: this.props.design.baseLayerOpacity ?? undefined,
|
|
305
|
-
layers: leafletLayers,
|
|
306
|
-
width: this.props.width,
|
|
307
|
-
height: this.props.height,
|
|
308
|
-
legend: this.renderLegend(),
|
|
309
|
-
dragging: this.props.dragging,
|
|
310
|
-
touchZoom: this.props.touchZoom,
|
|
311
|
-
scrollWheelZoom: this.props.scrollWheelZoom,
|
|
312
|
-
onBoundsChange: this.handleBoundsChange,
|
|
313
|
-
extraAttribution: this.props.design.attribution,
|
|
314
|
-
loadingSpinner: true,
|
|
315
|
-
maxZoom: this.props.design.maxZoom ?? undefined,
|
|
316
|
-
showZoomControlOnHover: true
|
|
317
|
-
})
|
|
318
|
-
)
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Legend display tab at bottom right
|
|
323
|
-
class HiddenLegend extends React.Component<{ onShow: () => void }> {
|
|
324
|
-
render() {
|
|
325
|
-
const style = {
|
|
326
|
-
zIndex: 1000,
|
|
327
|
-
backgroundColor: "white",
|
|
328
|
-
position: "absolute",
|
|
329
|
-
bottom: 34,
|
|
330
|
-
right: 0,
|
|
331
|
-
fontSize: 14,
|
|
332
|
-
color: "#337ab7",
|
|
333
|
-
cursor: "pointer",
|
|
334
|
-
paddingTop: 4,
|
|
335
|
-
paddingBottom: 3,
|
|
336
|
-
paddingLeft: 3,
|
|
337
|
-
paddingRight: 3,
|
|
338
|
-
borderRadius: "4px 0px 0px 4px",
|
|
339
|
-
border: "solid 1px #AAA",
|
|
340
|
-
borderRight: "none"
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
return R("div", { style, onClick: this.props.onShow }, R("i", { className: "fa fa-angle-double-left" }))
|
|
344
|
-
}
|
|
345
|
-
}
|