@mwater/visualization 5.5.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.
Files changed (275) hide show
  1. package/lib/ColorComponent.js +2 -2
  2. package/lib/MWaterContextComponent.d.ts +1 -1
  3. package/lib/MWaterGlobalFiltersComponent.d.ts +2 -2
  4. package/lib/MWaterGlobalFiltersComponent.js +11 -20
  5. package/lib/MWaterLoaderComponent.d.ts +4 -13
  6. package/lib/MWaterLoaderComponent.js +2 -11
  7. package/lib/TranslationsTabComponent.d.ts +34 -0
  8. package/lib/TranslationsTabComponent.js +256 -0
  9. package/lib/UndoStack.d.ts +2 -1
  10. package/lib/UndoStack.js +12 -6
  11. package/lib/dashboards/DashboardComponent.js +6 -5
  12. package/lib/dashboards/DashboardDesign.d.ts +1 -1
  13. package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
  14. package/lib/dashboards/ServerDashboardDataSource.js +0 -25
  15. package/lib/dashboards/SettingsModalComponent.js +9 -233
  16. package/lib/datagrids/DatagridComponent.js +27 -2
  17. package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -3
  18. package/lib/datagrids/DatagridDesignerComponent.js +108 -120
  19. package/lib/datagrids/DatagridViewComponent.js +33 -6
  20. package/lib/datagrids/OrderBysDesignerComponent.d.ts +7 -7
  21. package/lib/datagrids/OrderBysDesignerComponent.js +19 -28
  22. package/lib/index.css +45 -2
  23. package/lib/index.d.ts +5 -5
  24. package/lib/index.js +2 -3
  25. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +8 -1
  26. package/lib/layouts/blocks/BlocksDisplayComponent.js +46 -4
  27. package/lib/maps/BufferLayer.d.ts +0 -13
  28. package/lib/maps/BufferLayer.js +24 -237
  29. package/lib/maps/BufferLayerDesign.d.ts +1 -1
  30. package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
  31. package/lib/maps/BufferLayerDesignerComponent.js +2 -7
  32. package/lib/maps/ChoroplethLayer.d.ts +1 -16
  33. package/lib/maps/ChoroplethLayer.js +25 -358
  34. package/lib/maps/ChoroplethLayerDesign.d.ts +5 -2
  35. package/lib/maps/ChoroplethLayerDesigner.d.ts +10 -32
  36. package/lib/maps/ChoroplethLayerDesigner.js +58 -89
  37. package/lib/maps/ClusterLayer.d.ts +0 -9
  38. package/lib/maps/ClusterLayer.js +0 -250
  39. package/lib/maps/DirectMapDataSource.js +1 -48
  40. package/lib/maps/EditHoverOver.d.ts +4 -3
  41. package/lib/maps/EditHoverOver.js +3 -3
  42. package/lib/maps/GridLayer.d.ts +0 -15
  43. package/lib/maps/GridLayer.js +0 -212
  44. package/lib/maps/HoverContent.js +1 -1
  45. package/lib/maps/Layer.d.ts +1 -26
  46. package/lib/maps/Layer.js +0 -13
  47. package/lib/maps/LeafletMapComponent.js +10 -19
  48. package/lib/maps/MapComponent.d.ts +19 -35
  49. package/lib/maps/MapComponent.js +135 -77
  50. package/lib/maps/MapControlComponent.d.ts +4 -5
  51. package/lib/maps/MapControlComponent.js +5 -12
  52. package/lib/maps/MapDesign.d.ts +8 -0
  53. package/lib/maps/MapDesignerComponent.d.ts +2 -0
  54. package/lib/maps/MapDesignerComponent.js +7 -2
  55. package/lib/maps/MapLayerDataSource.d.ts +0 -4
  56. package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
  57. package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
  58. package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
  59. package/lib/maps/MapLayersDesignerComponent.js +2 -1
  60. package/lib/maps/MapTranslationsTab.d.ts +15 -0
  61. package/lib/maps/MapTranslationsTab.js +47 -0
  62. package/lib/maps/MapUtils.d.ts +11 -0
  63. package/lib/maps/MapUtils.js +57 -1
  64. package/lib/maps/MapViewComponent.d.ts +1 -1
  65. package/lib/maps/MapViewComponent.js +1 -8
  66. package/lib/maps/MarkersLayer.d.ts +1 -14
  67. package/lib/maps/MarkersLayer.js +89 -254
  68. package/lib/maps/MarkersLayerDesign.d.ts +5 -1
  69. package/lib/maps/MarkersLayerDesignerComponent.d.ts +32 -57
  70. package/lib/maps/MarkersLayerDesignerComponent.js +158 -134
  71. package/lib/maps/ServerMapDataSource.d.ts +0 -1
  72. package/lib/maps/ServerMapDataSource.js +0 -25
  73. package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
  74. package/lib/maps/SwitchableTileUrlLayer.js +0 -9
  75. package/lib/maps/TileUrlLayer.d.ts +0 -1
  76. package/lib/maps/TileUrlLayer.js +0 -5
  77. package/lib/maps/VectorMapViewComponent.js +13 -10
  78. package/lib/maps/symbols/font-awesome/asterisk.png +0 -0
  79. package/lib/maps/symbols/font-awesome/ban.png +0 -0
  80. package/lib/maps/symbols/font-awesome/beer.png +0 -0
  81. package/lib/maps/symbols/font-awesome/bell.png +0 -0
  82. package/lib/maps/symbols/font-awesome/bolt.png +0 -0
  83. package/lib/maps/symbols/font-awesome/building.png +0 -0
  84. package/lib/maps/symbols/font-awesome/bullseye.png +0 -0
  85. package/lib/maps/symbols/font-awesome/bus.png +0 -0
  86. package/lib/maps/symbols/font-awesome/caret-up.png +0 -0
  87. package/lib/maps/symbols/font-awesome/certificate.png +0 -0
  88. package/lib/maps/symbols/font-awesome/check-circle.png +0 -0
  89. package/lib/maps/symbols/font-awesome/check.png +0 -0
  90. package/lib/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  91. package/lib/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  92. package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
  93. package/lib/maps/symbols/font-awesome/cloud.png +0 -0
  94. package/lib/maps/symbols/font-awesome/comment.png +0 -0
  95. package/lib/maps/symbols/font-awesome/crosshairs.png +0 -0
  96. package/lib/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  97. package/lib/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  98. package/lib/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  99. package/lib/maps/symbols/font-awesome/female.png +0 -0
  100. package/lib/maps/symbols/font-awesome/file.png +0 -0
  101. package/lib/maps/symbols/font-awesome/flag.png +0 -0
  102. package/lib/maps/symbols/font-awesome/flask.png +0 -0
  103. package/lib/maps/symbols/font-awesome/h-square.png +0 -0
  104. package/lib/maps/symbols/font-awesome/home.png +0 -0
  105. package/lib/maps/symbols/font-awesome/info-circle.png +0 -0
  106. package/lib/maps/symbols/font-awesome/male.png +0 -0
  107. package/lib/maps/symbols/font-awesome/medkit.png +0 -0
  108. package/lib/maps/symbols/font-awesome/mobile.png +0 -0
  109. package/lib/maps/symbols/font-awesome/plus-circle.png +0 -0
  110. package/lib/maps/symbols/font-awesome/plus-square.png +0 -0
  111. package/lib/maps/symbols/font-awesome/plus.png +0 -0
  112. package/lib/maps/symbols/font-awesome/square.png +0 -0
  113. package/lib/maps/symbols/font-awesome/star.png +0 -0
  114. package/lib/maps/symbols/font-awesome/thumbs-down.png +0 -0
  115. package/lib/maps/symbols/font-awesome/thumbs-up.png +0 -0
  116. package/lib/maps/symbols/font-awesome/ticket.png +0 -0
  117. package/lib/maps/symbols/font-awesome/times-circle.png +0 -0
  118. package/lib/maps/symbols/font-awesome/times.png +0 -0
  119. package/lib/maps/symbols/font-awesome/tint.png +0 -0
  120. package/lib/maps/symbols/font-awesome/tree.png +0 -0
  121. package/lib/maps/symbols/font-awesome/university.png +0 -0
  122. package/lib/maps/symbols/font-awesome/usd.png +0 -0
  123. package/lib/maps/symbols/font-awesome/user.png +0 -0
  124. package/lib/maps/symbols/font-awesome/users.png +0 -0
  125. package/lib/maps/symbols/font-awesome/wheelchair.png +0 -0
  126. package/lib/maps/symbols/sdf-ize.sh +93 -0
  127. package/lib/maps/vectorMaps.d.ts +6 -6
  128. package/lib/maps/vectorMaps.js +33 -45
  129. package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +4 -2
  130. package/lib/mwater_table_selection/IndicatorsListComponent.js +103 -34
  131. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.d.ts +18 -0
  132. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.js +80 -0
  133. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +26 -0
  134. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +237 -51
  135. package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +2 -2
  136. package/lib/mwater_table_selection/MWaterTableSelectComponent.js +9 -4
  137. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.d.ts +19 -0
  138. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.js +111 -0
  139. package/lib/quickfilter/QuickfiltersComponent.d.ts +3 -102
  140. package/lib/quickfilter/QuickfiltersComponent.js +53 -110
  141. package/lib/quickfilter/TextLiteralComponent.d.ts +23 -47
  142. package/lib/quickfilter/TextLiteralComponent.js +85 -82
  143. package/lib/widgets/MapWidget.js +6 -3
  144. package/lib/widgets/text/ExprItemEditorComponent.d.ts +3 -8
  145. package/lib/widgets/text/ExprItemEditorComponent.js +36 -33
  146. package/lib/widgets/text/ExprUpdateModalComponent.d.ts +1 -0
  147. package/package.json +3 -4
  148. package/src/ColorComponent.tsx +2 -2
  149. package/src/MWaterContextComponent.tsx +1 -1
  150. package/src/{MWaterGlobalFiltersComponent.ts → MWaterGlobalFiltersComponent.tsx} +32 -33
  151. package/src/{MWaterLoaderComponent.ts → MWaterLoaderComponent.tsx} +17 -18
  152. package/src/TranslationsTabComponent.tsx +429 -0
  153. package/src/UndoStack.ts +14 -6
  154. package/src/dashboards/DashboardComponent.tsx +6 -5
  155. package/src/dashboards/DashboardDesign.ts +1 -1
  156. package/src/dashboards/ServerDashboardDataSource.ts +0 -31
  157. package/src/dashboards/SettingsModalComponent.tsx +27 -383
  158. package/src/datagrids/DatagridComponent.tsx +36 -2
  159. package/src/datagrids/DatagridDesignerComponent.tsx +241 -229
  160. package/src/datagrids/DatagridViewComponent.tsx +44 -7
  161. package/src/datagrids/OrderBysDesignerComponent.tsx +61 -70
  162. package/src/index.css +45 -2
  163. package/src/index.ts +5 -11
  164. package/src/layouts/blocks/BlocksDisplayComponent.tsx +60 -5
  165. package/src/maps/BufferLayer.ts +30 -263
  166. package/src/maps/BufferLayerDesign.ts +1 -1
  167. package/src/maps/BufferLayerDesignerComponent.tsx +2 -7
  168. package/src/maps/ChoroplethLayer.ts +30 -394
  169. package/src/maps/ChoroplethLayerDesign.ts +5 -2
  170. package/src/maps/ChoroplethLayerDesigner.tsx +169 -165
  171. package/src/maps/ClusterLayer.ts +0 -274
  172. package/src/maps/DirectMapDataSource.ts +2 -61
  173. package/src/maps/EditHoverOver.tsx +9 -5
  174. package/src/maps/GridLayer.ts +0 -224
  175. package/src/maps/HoverContent.tsx +1 -1
  176. package/src/maps/Layer.ts +1 -35
  177. package/src/maps/LeafletMapComponent.tsx +10 -19
  178. package/src/maps/MapComponent.tsx +448 -0
  179. package/src/maps/MapControlComponent.tsx +41 -0
  180. package/src/maps/MapDesign.ts +6 -0
  181. package/src/maps/MapDesignerComponent.tsx +18 -1
  182. package/src/maps/MapLayerDataSource.ts +0 -5
  183. package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
  184. package/src/maps/MapLayersDesignerComponent.ts +4 -1
  185. package/src/maps/MapTranslationsTab.tsx +53 -0
  186. package/src/maps/MapUtils.ts +61 -1
  187. package/src/maps/MapViewComponent.tsx +2 -8
  188. package/src/maps/MarkersLayer.ts +101 -275
  189. package/src/maps/MarkersLayerDesign.ts +7 -1
  190. package/src/maps/MarkersLayerDesignerComponent.tsx +436 -0
  191. package/src/maps/ServerMapDataSource.ts +0 -31
  192. package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
  193. package/src/maps/TileUrlLayer.tsx +0 -6
  194. package/src/maps/VectorMapViewComponent.tsx +15 -15
  195. package/src/maps/symbols/font-awesome/asterisk.png +0 -0
  196. package/src/maps/symbols/font-awesome/ban.png +0 -0
  197. package/src/maps/symbols/font-awesome/beer.png +0 -0
  198. package/src/maps/symbols/font-awesome/bell.png +0 -0
  199. package/src/maps/symbols/font-awesome/bolt.png +0 -0
  200. package/src/maps/symbols/font-awesome/building.png +0 -0
  201. package/src/maps/symbols/font-awesome/bullseye.png +0 -0
  202. package/src/maps/symbols/font-awesome/bus.png +0 -0
  203. package/src/maps/symbols/font-awesome/caret-up.png +0 -0
  204. package/src/maps/symbols/font-awesome/certificate.png +0 -0
  205. package/src/maps/symbols/font-awesome/check-circle.png +0 -0
  206. package/src/maps/symbols/font-awesome/check.png +0 -0
  207. package/src/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  208. package/src/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  209. package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
  210. package/src/maps/symbols/font-awesome/cloud.png +0 -0
  211. package/src/maps/symbols/font-awesome/comment.png +0 -0
  212. package/src/maps/symbols/font-awesome/crosshairs.png +0 -0
  213. package/src/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  214. package/src/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  215. package/src/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  216. package/src/maps/symbols/font-awesome/female.png +0 -0
  217. package/src/maps/symbols/font-awesome/file.png +0 -0
  218. package/src/maps/symbols/font-awesome/flag.png +0 -0
  219. package/src/maps/symbols/font-awesome/flask.png +0 -0
  220. package/src/maps/symbols/font-awesome/h-square.png +0 -0
  221. package/src/maps/symbols/font-awesome/home.png +0 -0
  222. package/src/maps/symbols/font-awesome/info-circle.png +0 -0
  223. package/src/maps/symbols/font-awesome/male.png +0 -0
  224. package/src/maps/symbols/font-awesome/medkit.png +0 -0
  225. package/src/maps/symbols/font-awesome/mobile.png +0 -0
  226. package/src/maps/symbols/font-awesome/plus-circle.png +0 -0
  227. package/src/maps/symbols/font-awesome/plus-square.png +0 -0
  228. package/src/maps/symbols/font-awesome/plus.png +0 -0
  229. package/src/maps/symbols/font-awesome/square.png +0 -0
  230. package/src/maps/symbols/font-awesome/star.png +0 -0
  231. package/src/maps/symbols/font-awesome/thumbs-down.png +0 -0
  232. package/src/maps/symbols/font-awesome/thumbs-up.png +0 -0
  233. package/src/maps/symbols/font-awesome/ticket.png +0 -0
  234. package/src/maps/symbols/font-awesome/times-circle.png +0 -0
  235. package/src/maps/symbols/font-awesome/times.png +0 -0
  236. package/src/maps/symbols/font-awesome/tint.png +0 -0
  237. package/src/maps/symbols/font-awesome/tree.png +0 -0
  238. package/src/maps/symbols/font-awesome/university.png +0 -0
  239. package/src/maps/symbols/font-awesome/usd.png +0 -0
  240. package/src/maps/symbols/font-awesome/user.png +0 -0
  241. package/src/maps/symbols/font-awesome/users.png +0 -0
  242. package/src/maps/symbols/font-awesome/wheelchair.png +0 -0
  243. package/src/maps/symbols/sdf-ize.sh +93 -0
  244. package/src/maps/vectorMaps.tsx +32 -53
  245. package/src/mwater_table_selection/IndicatorsListComponent.tsx +165 -37
  246. package/src/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.tsx +111 -0
  247. package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +373 -37
  248. package/src/mwater_table_selection/MWaterTableSelectComponent.tsx +12 -8
  249. package/src/mwater_table_selection/MWaterWorkflowsSelectComponent.tsx +159 -0
  250. package/src/quickfilter/{QuickfiltersComponent.ts → QuickfiltersComponent.tsx} +165 -158
  251. package/src/quickfilter/TextLiteralComponent.tsx +197 -0
  252. package/src/widgets/MapWidget.tsx +11 -1
  253. package/src/widgets/text/ExprItemEditorComponent.tsx +83 -77
  254. package/src/widgets/text/ExprUpdateModalComponent.tsx +1 -0
  255. package/test/UndoStackTests.ts +52 -1
  256. package/.storybook/config.js +0 -7
  257. package/.storybook/head.html +0 -3
  258. package/.storybook/webpack.config.js +0 -15
  259. package/src/maps/BingLayer.ts +0 -146
  260. package/src/maps/MapComponent.ts +0 -312
  261. package/src/maps/MapControlComponent.ts +0 -46
  262. package/src/maps/MarkersLayerDesignerComponent.ts +0 -374
  263. package/src/maps/RasterMapViewComponent.ts +0 -345
  264. package/src/quickfilter/TextLiteralComponent.ts +0 -165
  265. package/stories/UpdateableComponent.js +0 -29
  266. package/stories/consoles.js +0 -202
  267. package/stories/dashboards.js +0 -217
  268. package/stories/datagridDesign.js +0 -114
  269. package/stories/datagrids.js +0 -69
  270. package/stories/dates.js +0 -80
  271. package/stories/exprcomponent.js +0 -43
  272. package/stories/index.js +0 -18
  273. package/stories/leaflet.js +0 -59
  274. package/stories/maps.js +0 -24
  275. package/stories/pivotChart.js +0 -235
@@ -16,8 +16,14 @@ export interface MarkersLayerDesign {
16
16
 
17
17
  /** Color axis (to split into series based on a color) */
18
18
  color?: Axis
19
+
20
+ /** Label expression to display on/near markers (points only) */
21
+ label?: Axis
19
22
  }
20
23
 
24
+ /** Position of label relative to marker. Default "bottom" */
25
+ labelPosition?: "top" | "bottom" | "left" | "right"
26
+
21
27
  /** Optional logical expression to filter by */
22
28
  filter?: Expr
23
29
 
@@ -43,7 +49,7 @@ export interface MarkersLayerDesign {
43
49
  popup: { items: LayoutBlock }
44
50
 
45
51
  /** Contains items to display when hovering over the layer */
46
- hoverOver: { items: HoverOverItem[] }
52
+ hoverOver?: { items: HoverOverItem[] }
47
53
 
48
54
  /** Customizable filtering for popup */
49
55
  popupFilterJoins: PopupFilterJoins
@@ -0,0 +1,436 @@
1
+ import _ from "lodash"
2
+ import React from "react"
3
+ import { FilterExprComponent } from "@mwater/expressions-ui"
4
+ import { DataSource, Expr, ExprUtils, OpExpr, Schema } from "@mwater/expressions"
5
+ import { ExprCompiler } from "@mwater/expressions"
6
+ import AxisComponent from "../axes/AxisComponent"
7
+ import ColorComponent from "../ColorComponent"
8
+ import { TableSelectComponent } from "@mwater/expressions-ui"
9
+ import EditPopupComponent from "./EditPopupComponent"
10
+ import ZoomLevelsComponent from "./ZoomLevelsComponent"
11
+ import MarkerSymbolSelectComponent from "./MarkerSymbolSelectComponent"
12
+ import * as PopupFilterJoinsUtils from "./PopupFilterJoinsUtils"
13
+ import * as ui from "@mwater/react-library/lib/bootstrap"
14
+ import { EditHoverOver } from "./EditHoverOver"
15
+ import { MarkersLayerDesign } from "./MarkersLayerDesign"
16
+ import { default as Rcslider } from "rc-slider"
17
+ import { produce } from "immer"
18
+ import { Axis } from "../axes/Axis"
19
+ import { JsonQLFilter } from "../JsonQLFilter"
20
+
21
+ export interface MarkersLayerDesignerComponentProps {
22
+ /** Schema to use */
23
+ schema: Schema
24
+ dataSource: DataSource
25
+ /** Design of the marker layer */
26
+ design: MarkersLayerDesign
27
+ /** Called with new design */
28
+ onDesignChange: (design: MarkersLayerDesign) => void
29
+ filters?: JsonQLFilter[]
30
+ }
31
+
32
+ /** Designer for a markers layer */
33
+ export default class MarkersLayerDesignerComponent extends React.Component<MarkersLayerDesignerComponentProps> {
34
+ handleTableChange = (table: string) => {
35
+ this.props.onDesignChange(produce(this.props.design, draft => {
36
+ draft.table = table
37
+ }))
38
+ }
39
+ handleGeometryAxisChange = (axis: Axis) => {
40
+ this.props.onDesignChange(produce(this.props.design, draft => {
41
+ draft.axes.geometry = axis
42
+ }))
43
+ }
44
+ handleColorAxisChange = (axis: Axis | null) => {
45
+ this.props.onDesignChange(produce(this.props.design, draft => {
46
+ draft.axes.color = axis ?? undefined
47
+ }))
48
+ }
49
+ handleFilterChange = (expr: Expr) => {
50
+ this.props.onDesignChange(produce(this.props.design, draft => {
51
+ draft.filter = expr
52
+ }))
53
+ }
54
+ handleColorChange = (color: string) => {
55
+ this.props.onDesignChange(produce(this.props.design, draft => {
56
+ draft.color = color
57
+ }))
58
+ }
59
+ handlePolygonBorderColorChange = (polygonBorderColor: string) => {
60
+ this.props.onDesignChange(produce(this.props.design, draft => {
61
+ draft.polygonBorderColor = polygonBorderColor
62
+ }))
63
+ }
64
+ handlePolygonFillOpacityChange = (polygonFillOpacity: number) => {
65
+ this.props.onDesignChange(produce(this.props.design, draft => {
66
+ draft.polygonFillOpacity = polygonFillOpacity / 100
67
+ }))
68
+ }
69
+ handleSymbolChange = (symbol: string) => {
70
+ this.props.onDesignChange(produce(this.props.design, draft => {
71
+ draft.symbol = symbol
72
+ }))
73
+ }
74
+ handleMarkerSizeChange = (markerSize: number) => {
75
+ this.props.onDesignChange(produce(this.props.design, draft => {
76
+ draft.markerSize = markerSize
77
+ }))
78
+ }
79
+ handleLineWidthChange = (lineWidth: number) => {
80
+ this.props.onDesignChange(produce(this.props.design, draft => {
81
+ draft.lineWidth = lineWidth
82
+ }))
83
+ }
84
+ handleLabelAxisChange = (axis: Axis | null) => {
85
+ this.props.onDesignChange(produce(this.props.design, draft => {
86
+ draft.axes.label = axis ?? undefined
87
+ }))
88
+ }
89
+ handleLabelPositionChange = (labelPosition: "top" | "bottom" | "left" | "right") => {
90
+ this.props.onDesignChange(produce(this.props.design, draft => {
91
+ draft.labelPosition = labelPosition
92
+ }))
93
+ }
94
+
95
+ renderTable() {
96
+ return (
97
+ <div className="mb-3">
98
+ <label className="text-muted"><i className="fa fa-database" /> {T`Data Source`}</label>
99
+ <div style={{ marginLeft: 10 }}>
100
+ <TableSelectComponent
101
+ schema={this.props.schema}
102
+ value={this.props.design.table}
103
+ onChange={this.handleTableChange}
104
+ filter={this.props.design.filter}
105
+ onFilterChange={this.handleFilterChange}
106
+ />
107
+ </div>
108
+ </div>
109
+ )
110
+ }
111
+
112
+ renderGeometryAxis() {
113
+ if (!this.props.design.table) {
114
+ return
115
+ }
116
+
117
+ const title = <span><span className="fas fa-map-marker-alt" /> {T`Location`}</span>
118
+
119
+ const filters = _.clone(this.props.filters) || []
120
+
121
+ if (this.props.design.filter != null) {
122
+ const exprCompiler = new ExprCompiler(this.props.schema)
123
+ const jsonql = exprCompiler.compileExpr({ expr: this.props.design.filter, tableAlias: "{alias}" })
124
+ if (jsonql) {
125
+ filters.push({ table: (this.props.design.filter as OpExpr).table!, jsonql })
126
+ }
127
+ }
128
+
129
+ return (
130
+ <div className="mb-3">
131
+ <label className="text-muted">{title}</label>
132
+ <div style={{ marginLeft: 10 }}>
133
+ <AxisComponent
134
+ schema={this.props.schema}
135
+ dataSource={this.props.dataSource}
136
+ table={this.props.design.table}
137
+ types={["geometry"]}
138
+ aggrNeed="none"
139
+ value={this.props.design.axes.geometry}
140
+ onChange={this.handleGeometryAxisChange}
141
+ filters={filters}
142
+ />
143
+ </div>
144
+ </div>
145
+ )
146
+ }
147
+
148
+ renderColor() {
149
+ if (!this.props.design.axes.geometry) {
150
+ return
151
+ }
152
+
153
+ const filters = _.clone(this.props.filters) || []
154
+
155
+ if (this.props.design.filter != null) {
156
+ const exprCompiler = new ExprCompiler(this.props.schema)
157
+ const jsonql = exprCompiler.compileExpr({ expr: this.props.design.filter, tableAlias: "{alias}" })
158
+ if (jsonql) {
159
+ filters.push({ table: (this.props.design.filter as OpExpr).table!, jsonql })
160
+ }
161
+ }
162
+
163
+ return (
164
+ <div>
165
+ {!this.props.design.axes.color ? (
166
+ <div className="mb-3">
167
+ <label className="text-muted"><span className="fas fa-tint" />{T`Color`}</label>
168
+ <div>
169
+ <ColorComponent
170
+ color={this.props.design.color}
171
+ onChange={this.handleColorChange}
172
+ />
173
+ </div>
174
+ </div>
175
+ ) : undefined}
176
+
177
+ <div className="mb-3">
178
+ <label className="text-muted"><span className="fas fa-tint" />{T`Color By Data`}</label>
179
+ <AxisComponent
180
+ schema={this.props.schema}
181
+ dataSource={this.props.dataSource}
182
+ table={this.props.design.table}
183
+ types={["text", "enum", "boolean", "date"]}
184
+ aggrNeed="none"
185
+ value={this.props.design.axes.color}
186
+ defaultColor={this.props.design.color}
187
+ showColorMap={true}
188
+ onChange={this.handleColorAxisChange}
189
+ allowExcludedValues={true}
190
+ filters={filters}
191
+ />
192
+ </div>
193
+ </div>
194
+ )
195
+ }
196
+
197
+ renderSymbol() {
198
+ if (!this.props.design.axes.geometry) {
199
+ return
200
+ }
201
+
202
+ return <MarkerSymbolSelectComponent symbol={this.props.design.symbol} onChange={this.handleSymbolChange} />
203
+ }
204
+
205
+ renderMarkerSize() {
206
+ if (!this.props.design.axes.geometry) {
207
+ return
208
+ }
209
+
210
+ return (
211
+ <div className="mb-3">
212
+ <label className="text-muted">{T`Marker Size`}</label>
213
+ <ui.Select
214
+ value={this.props.design.markerSize || 10}
215
+ options={[
216
+ { value: 5, label: T`Extra small` },
217
+ { value: 8, label: T`Small` },
218
+ { value: 10, label: T`Normal` },
219
+ { value: 13, label: T`Large` },
220
+ { value: 16, label: T`Extra large` }
221
+ ]}
222
+ onChange={this.handleMarkerSizeChange}
223
+ />
224
+ </div>
225
+ )
226
+ }
227
+
228
+ renderLineWidth() {
229
+ if (!this.props.design.axes.geometry) {
230
+ return
231
+ }
232
+
233
+ return (
234
+ <div className="mb-3">
235
+ <label className="text-muted">{T`Line Width (for shapes)`}</label>
236
+ <ui.Select
237
+ value={this.props.design.lineWidth != null ? this.props.design.lineWidth : 3}
238
+ options={[
239
+ { value: 0, label: T`None` },
240
+ { value: 1, label: T`1 pixel` },
241
+ { value: 2, label: T`2 pixels` },
242
+ { value: 3, label: T`3 pixels` },
243
+ { value: 4, label: T`4 pixels` },
244
+ { value: 5, label: T`5 pixels` },
245
+ { value: 6, label: T`6 pixels` }
246
+ ]}
247
+ onChange={this.handleLineWidthChange}
248
+ />
249
+ </div>
250
+ )
251
+ }
252
+
253
+ renderPolygonBorderColor() {
254
+ if (!this.props.design.axes.geometry) {
255
+ return
256
+ }
257
+
258
+ return (
259
+ <div className="mb-3">
260
+ <label className="text-muted">{T`Polygon border color (blank for same as fill color)`}</label>
261
+ <div>
262
+ <ColorComponent
263
+ color={this.props.design.polygonBorderColor}
264
+ onChange={this.handlePolygonBorderColorChange}
265
+ />
266
+ </div>
267
+ </div>
268
+ )
269
+ }
270
+
271
+ renderPolygonFillOpacity() {
272
+ if (!this.props.design.axes.geometry) {
273
+ return
274
+ }
275
+
276
+ const opacity = this.props.design.polygonFillOpacity != null ? this.props.design.polygonFillOpacity : 0.25
277
+
278
+ return (
279
+ <div className="mb-3">
280
+ <label className="text-muted"><span>{T`Polygon Fill Opacity: ${Math.round(opacity * 100)}%`}</span></label>
281
+ <div style={{ padding: "10px" }}>
282
+ <Rcslider
283
+ min={0}
284
+ max={100}
285
+ step={1}
286
+ tipTransitionName="rc-slider-tooltip-zoom-down"
287
+ value={opacity * 100}
288
+ onChange={this.handlePolygonFillOpacityChange}
289
+ />
290
+ </div>
291
+ </div>
292
+ )
293
+ }
294
+
295
+ renderFilter() {
296
+ // If no data, hide
297
+ if (!this.props.design.axes.geometry) {
298
+ return null
299
+ }
300
+
301
+ return (
302
+ <div className="mb-3">
303
+ <label className="text-muted"><span className="fas fa-filter" />{T`Filters`}</label>
304
+ <div style={{ marginLeft: 8 }}>
305
+ <FilterExprComponent
306
+ schema={this.props.schema}
307
+ dataSource={this.props.dataSource}
308
+ onChange={this.handleFilterChange}
309
+ table={this.props.design.table}
310
+ value={this.props.design.filter}
311
+ />
312
+ </div>
313
+ </div>
314
+ )
315
+ }
316
+
317
+ renderLabelAxis() {
318
+ if (!this.props.design.axes.geometry) {
319
+ return
320
+ }
321
+
322
+ const filters = _.clone(this.props.filters) || []
323
+
324
+ if (this.props.design.filter != null) {
325
+ const exprCompiler = new ExprCompiler(this.props.schema)
326
+ const jsonql = exprCompiler.compileExpr({ expr: this.props.design.filter, tableAlias: "{alias}" })
327
+ if (jsonql) {
328
+ filters.push({ table: (this.props.design.filter as OpExpr).table!, jsonql })
329
+ }
330
+ }
331
+
332
+ return (
333
+ <div className="mb-3">
334
+ <label className="text-muted"><span className="fas fa-tag" /> {T`Label (points only)`}</label>
335
+ <AxisComponent
336
+ schema={this.props.schema}
337
+ dataSource={this.props.dataSource}
338
+ table={this.props.design.table}
339
+ types={["text", "number"]}
340
+ aggrNeed="none"
341
+ value={this.props.design.axes.label}
342
+ onChange={this.handleLabelAxisChange}
343
+ filters={filters}
344
+ />
345
+ </div>
346
+ )
347
+ }
348
+
349
+ renderLabelPosition() {
350
+ // Only show if label axis is set
351
+ if (!this.props.design.axes.label) {
352
+ return
353
+ }
354
+
355
+ return (
356
+ <div className="mb-3">
357
+ <label className="text-muted">{T`Label Position`}</label>
358
+ <ui.Select
359
+ value={this.props.design.labelPosition || "bottom"}
360
+ options={[
361
+ { value: "top", label: T`Top` },
362
+ { value: "bottom", label: T`Bottom` },
363
+ { value: "left", label: T`Left` },
364
+ { value: "right", label: T`Right` }
365
+ ]}
366
+ onChange={this.handleLabelPositionChange}
367
+ />
368
+ </div>
369
+ )
370
+ }
371
+
372
+ renderPopup() {
373
+ if (!this.props.design.table) {
374
+ return null
375
+ }
376
+
377
+ return (
378
+ <EditPopupComponent
379
+ design={this.props.design}
380
+ onDesignChange={this.props.onDesignChange}
381
+ schema={this.props.schema}
382
+ dataSource={this.props.dataSource}
383
+ table={this.props.design.table}
384
+ idTable={this.props.design.table}
385
+ defaultPopupFilterJoins={PopupFilterJoinsUtils.createDefaultPopupFilterJoins(this.props.design.table)}
386
+ />
387
+ )
388
+ }
389
+
390
+ renderHoverOver() {
391
+ if (!this.props.design.table) {
392
+ return null
393
+ }
394
+
395
+ return (
396
+ <EditHoverOver
397
+ design={this.props.design}
398
+ onDesignChange={this.props.onDesignChange}
399
+ schema={this.props.schema}
400
+ dataSource={this.props.dataSource}
401
+ table={this.props.design.table}
402
+ idTable={this.props.design.table}
403
+ defaultPopupFilterJoins={PopupFilterJoinsUtils.createDefaultPopupFilterJoins(this.props.design.table)}
404
+ aggrStatuses={["individual", "literal"]}
405
+ />
406
+ )
407
+ }
408
+
409
+ render() {
410
+ return (
411
+ <div>
412
+ {this.renderTable()}
413
+ {this.renderGeometryAxis()}
414
+ {this.renderColor()}
415
+ {this.renderSymbol()}
416
+ {this.renderMarkerSize()}
417
+ {this.renderLabelAxis()}
418
+ {this.renderLabelPosition()}
419
+ <ui.CollapsibleSection
420
+ label={T`Shape Options`}
421
+ labelMuted={true}
422
+ >
423
+ {this.renderLineWidth()}
424
+ {this.renderPolygonBorderColor()}
425
+ {this.renderPolygonFillOpacity()}
426
+ </ui.CollapsibleSection>
427
+ {this.renderFilter()}
428
+ {this.renderPopup()}
429
+ {this.renderHoverOver()}
430
+ {this.props.design.table ? (
431
+ <ZoomLevelsComponent design={this.props.design} onDesignChange={this.props.onDesignChange} />
432
+ ) : undefined}
433
+ </div>
434
+ )
435
+ }
436
+ }
@@ -126,25 +126,6 @@ class ServerLayerDataSource implements MapLayerDataSource {
126
126
  return this.createUrl(filters, "png")
127
127
  }
128
128
 
129
- // Get the url for the interactivity tiles with the specified filters applied
130
- // Called with (design, filters) where design is the design of the layer and filters are filters to apply. Returns URL
131
- getUtfGridUrl(design: any, filters: JsonQLFilter[]) {
132
- // Handle special cases
133
- if (this.options.layerView.type === "MWaterServer") {
134
- return this.createLegacyUrl(design, "grid.json", filters)
135
- }
136
-
137
- // Create layer
138
- const layer = LayerFactory.createLayer(this.options.layerView.type)
139
-
140
- // If layer has tiles url directly available
141
- if (layer.getLayerDefinitionType() === "TileUrl") {
142
- return layer.getUtfGridUrl(this.options.layerView.design, filters)
143
- }
144
-
145
- return this.createUrl(filters, "grid.json")
146
- }
147
-
148
129
  /** Get the url for vector tile source with an expiry time. Only for layers of type "VectorTile"
149
130
  * @param createdAfter ISO 8601 timestamp requiring that tile source on server is created after specified datetime
150
131
  */
@@ -214,12 +195,6 @@ class ServerLayerDataSource implements MapLayerDataSource {
214
195
 
215
196
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?` + querystring.stringify(query)
216
197
 
217
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
218
- // Used to speed queries
219
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
220
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/")
221
- }
222
-
223
198
  return url
224
199
  }
225
200
 
@@ -228,12 +203,6 @@ class ServerLayerDataSource implements MapLayerDataSource {
228
203
  let where
229
204
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?type=${design.type}&radius=1000`
230
205
 
231
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
232
- // Used to speed queries
233
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
234
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/")
235
- }
236
-
237
206
  if (this.options.client) {
238
207
  url += `&client=${this.options.client}`
239
208
  }
@@ -68,17 +68,6 @@ export default class SwitchableTileUrlLayer extends Layer<SwitchableTileUrlLayer
68
68
  return option.tileUrl || null
69
69
  }
70
70
 
71
- /** Gets the utf grid url for definition type "TileUrl" */
72
- getUtfGridUrl(design: SwitchableTileUrlLayerDesign, filters: JsonQLFilter[]): string | null {
73
- // Find active option
74
- const option = design.options.find((d) => d.id === design.activeOption)
75
- if (!option) {
76
- return null
77
- }
78
-
79
- return option.utfGridUrl || null
80
- }
81
-
82
71
  getLegend(options: LegendOptions<SwitchableTileUrlLayerDesign>): ReactNode {
83
72
  const { design, name } = options
84
73
  // Find active option
@@ -31,7 +31,6 @@ Design is:
31
31
  legendUrl:
32
32
  */
33
33
  export default class TileUrlLayer extends Layer<TileUrlLayerDesign> {
34
- // Gets the type of layer definition ("JsonQLCss"/"TileUrl")
35
34
  getLayerDefinitionType(): "TileUrl" {
36
35
  return "TileUrl"
37
36
  }
@@ -41,11 +40,6 @@ export default class TileUrlLayer extends Layer<TileUrlLayerDesign> {
41
40
  return design.tileUrl
42
41
  }
43
42
 
44
- // Gets the utf grid url for definition type "TileUrl"
45
- getUtfGridUrl(design: any, filters: any) {
46
- return null
47
- }
48
-
49
43
  // Get min and max zoom levels
50
44
  getMinZoom(design: any) {
51
45
  return design.minZoom
@@ -1,12 +1,10 @@
1
1
  import _, { find } from "lodash"
2
2
  import { LayerSpecification, MapLayerMouseEvent } from "maplibre-gl"
3
- import { DataSource, Schema } from "@mwater/expressions"
4
- import React, { CSSProperties, ReactNode, useEffect, useMemo, useState } from "react"
3
+ import React, { CSSProperties, ReactNode, useCallback, useEffect, useMemo, useState } from "react"
5
4
  import { useRef } from "react"
6
5
  import { JsonQLFilter } from "../JsonQLFilter"
7
6
  import { default as LayerFactory } from "./LayerFactory"
8
- import { MapBounds, MapDesign, MapLayerView } from "./MapDesign"
9
- import { MapDataSource } from "./MapDataSource"
7
+ import { MapBounds, MapLayerView } from "./MapDesign"
10
8
  import ModalPopupComponent from "@mwater/react-library/lib/ModalPopupComponent"
11
9
  import { useStableCallback } from "@mwater/react-library/lib/useStableCallback"
12
10
  import {
@@ -77,7 +75,18 @@ export function VectorMapViewComponent(props: VectorMapViewComponentProps) {
77
75
  const locale = props.locale || props.design.locale || "en"
78
76
 
79
77
  // Translate function to use
80
- const translate = props.translate || ((input: string) => input)
78
+ const translate = useCallback((input: string) => {
79
+ // Use passed in translate function if present
80
+ if (props.translate) {
81
+ return props.translate(input)
82
+ }
83
+ // If locale is the same as the design locale, don't translate
84
+ if (locale === props.design.locale) {
85
+ return input
86
+ }
87
+ // Otherwise, use translation from design
88
+ return props.design.translations?.[locale]?.[input] ?? input
89
+ }, [props.translate, props.design.translations, props.design.locale, locale])
81
90
 
82
91
  // Last feature that mouse entered
83
92
  const lastFeature = useRef<string>()
@@ -278,18 +287,9 @@ export function VectorMapViewComponent(props: VectorMapViewComponentProps) {
278
287
  } else {
279
288
  const tileUrl = props.mapDataSource.getLayerDataSource(layerView.id).getTileUrl(design, [])
280
289
  if (tileUrl) {
281
- // Replace "{s}" with "a", "b", "c"
282
- let tiles: string[] = []
283
-
284
- if (tileUrl.includes("{s}")) {
285
- tiles = [tileUrl.replace("{s}", "a"), tileUrl.replace("{s}", "b"), tileUrl.replace("{s}", "c")]
286
- } else {
287
- tiles = [tileUrl]
288
- }
289
-
290
290
  newSources[layerView.id] = {
291
291
  type: "raster",
292
- tiles,
292
+ tiles: [tileUrl],
293
293
  tileSize: 256
294
294
  }
295
295