@mwater/visualization 5.4.5 → 5.6.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.
Files changed (310) hide show
  1. package/lib/MWaterContextComponent.d.ts +1 -1
  2. package/lib/MWaterContextComponent.js +1 -1
  3. package/lib/MWaterGlobalFiltersComponent.d.ts +2 -2
  4. package/lib/MWaterGlobalFiltersComponent.js +11 -20
  5. package/lib/MWaterLoaderComponent.d.ts +5 -14
  6. package/lib/MWaterLoaderComponent.js +2 -11
  7. package/lib/UndoStack.d.ts +2 -1
  8. package/lib/UndoStack.js +12 -6
  9. package/lib/dashboards/DashboardComponent.js +7 -5
  10. package/lib/dashboards/DashboardDesign.d.ts +1 -1
  11. package/lib/dashboards/LayoutOptionsComponent.js +18 -11
  12. package/lib/dashboards/ServerDashboardDataSource.d.ts +10 -1
  13. package/lib/dashboards/ServerDashboardDataSource.js +29 -10
  14. package/lib/dashboards/SettingsModalComponent.js +1 -1
  15. package/lib/dashboards/layoutOptions.d.ts +5 -1
  16. package/lib/datagrids/DatagridComponent.js +23 -3
  17. package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -3
  18. package/lib/datagrids/DatagridDesignerComponent.js +108 -120
  19. package/lib/datagrids/DatagridViewComponent.js +3 -2
  20. package/lib/datagrids/ExprCellComponent.d.ts +1 -0
  21. package/lib/datagrids/ExprCellComponent.js +22 -20
  22. package/lib/datagrids/OrderBysDesignerComponent.d.ts +7 -7
  23. package/lib/datagrids/OrderBysDesignerComponent.js +19 -28
  24. package/lib/index.css +45 -2
  25. package/lib/index.d.ts +5 -5
  26. package/lib/index.js +2 -3
  27. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +8 -1
  28. package/lib/layouts/blocks/BlocksDisplayComponent.js +46 -4
  29. package/lib/maps/BufferLayer.d.ts +18 -0
  30. package/lib/maps/BufferLayer.js +36 -14
  31. package/lib/maps/BufferLayerDesign.d.ts +1 -1
  32. package/lib/maps/BufferLayerDesignerComponent.js +2 -2
  33. package/lib/maps/ChoroplethLayer.d.ts +18 -0
  34. package/lib/maps/ChoroplethLayer.js +46 -25
  35. package/lib/maps/ChoroplethLayerDesign.d.ts +7 -3
  36. package/lib/maps/ChoroplethLayerDesigner.d.ts +10 -22
  37. package/lib/maps/ChoroplethLayerDesigner.js +58 -89
  38. package/lib/maps/DirectMapDataSource.js +17 -10
  39. package/lib/maps/EditHoverOver.d.ts +4 -3
  40. package/lib/maps/EditHoverOver.js +64 -35
  41. package/lib/maps/HoverContent.d.ts +10 -5
  42. package/lib/maps/HoverContent.js +7 -36
  43. package/lib/maps/Layer.d.ts +37 -0
  44. package/lib/maps/Layer.js +30 -4
  45. package/lib/maps/LeafletMapComponent.js +10 -19
  46. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  47. package/lib/maps/MWaterServerLayer.js +6 -6
  48. package/lib/maps/MapComponent.js +0 -1
  49. package/lib/maps/MapLayerDataSource.d.ts +9 -0
  50. package/lib/maps/MapUtils.d.ts +19 -1
  51. package/lib/maps/MapUtils.js +80 -1
  52. package/lib/maps/MarkersLayer.d.ts +18 -0
  53. package/lib/maps/MarkersLayer.js +42 -26
  54. package/lib/maps/MarkersLayerDesign.d.ts +1 -1
  55. package/lib/maps/MarkersLayerDesignerComponent.d.ts +12 -28
  56. package/lib/maps/MarkersLayerDesignerComponent.js +81 -111
  57. package/lib/maps/RasterMapViewComponent.js +1 -1
  58. package/lib/maps/ServerMapDataSource.d.ts +9 -0
  59. package/lib/maps/ServerMapDataSource.js +29 -10
  60. package/lib/maps/VectorMapViewComponent.js +7 -15
  61. package/lib/maps/maps.d.ts +4 -2
  62. package/lib/maps/symbols/font-awesome/asterisk.png +0 -0
  63. package/lib/maps/symbols/font-awesome/ban.png +0 -0
  64. package/lib/maps/symbols/font-awesome/beer.png +0 -0
  65. package/lib/maps/symbols/font-awesome/bell.png +0 -0
  66. package/lib/maps/symbols/font-awesome/bolt.png +0 -0
  67. package/lib/maps/symbols/font-awesome/building.png +0 -0
  68. package/lib/maps/symbols/font-awesome/bullseye.png +0 -0
  69. package/lib/maps/symbols/font-awesome/bus.png +0 -0
  70. package/lib/maps/symbols/font-awesome/caret-up.png +0 -0
  71. package/lib/maps/symbols/font-awesome/certificate.png +0 -0
  72. package/lib/maps/symbols/font-awesome/check-circle.png +0 -0
  73. package/lib/maps/symbols/font-awesome/check.png +0 -0
  74. package/lib/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  75. package/lib/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  76. package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
  77. package/lib/maps/symbols/font-awesome/cloud.png +0 -0
  78. package/lib/maps/symbols/font-awesome/comment.png +0 -0
  79. package/lib/maps/symbols/font-awesome/crosshairs.png +0 -0
  80. package/lib/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  81. package/lib/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  82. package/lib/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  83. package/lib/maps/symbols/font-awesome/female.png +0 -0
  84. package/lib/maps/symbols/font-awesome/file.png +0 -0
  85. package/lib/maps/symbols/font-awesome/flag.png +0 -0
  86. package/lib/maps/symbols/font-awesome/flask.png +0 -0
  87. package/lib/maps/symbols/font-awesome/h-square.png +0 -0
  88. package/lib/maps/symbols/font-awesome/home.png +0 -0
  89. package/lib/maps/symbols/font-awesome/info-circle.png +0 -0
  90. package/lib/maps/symbols/font-awesome/male.png +0 -0
  91. package/lib/maps/symbols/font-awesome/medkit.png +0 -0
  92. package/lib/maps/symbols/font-awesome/mobile.png +0 -0
  93. package/lib/maps/symbols/font-awesome/plus-circle.png +0 -0
  94. package/lib/maps/symbols/font-awesome/plus-square.png +0 -0
  95. package/lib/maps/symbols/font-awesome/plus.png +0 -0
  96. package/lib/maps/symbols/font-awesome/square.png +0 -0
  97. package/lib/maps/symbols/font-awesome/star.png +0 -0
  98. package/lib/maps/symbols/font-awesome/thumbs-down.png +0 -0
  99. package/lib/maps/symbols/font-awesome/thumbs-up.png +0 -0
  100. package/lib/maps/symbols/font-awesome/ticket.png +0 -0
  101. package/lib/maps/symbols/font-awesome/times-circle.png +0 -0
  102. package/lib/maps/symbols/font-awesome/times.png +0 -0
  103. package/lib/maps/symbols/font-awesome/tint.png +0 -0
  104. package/lib/maps/symbols/font-awesome/tree.png +0 -0
  105. package/lib/maps/symbols/font-awesome/university.png +0 -0
  106. package/lib/maps/symbols/font-awesome/usd.png +0 -0
  107. package/lib/maps/symbols/font-awesome/user.png +0 -0
  108. package/lib/maps/symbols/font-awesome/users.png +0 -0
  109. package/lib/maps/symbols/font-awesome/wheelchair.png +0 -0
  110. package/lib/maps/symbols/sdf-ize.sh +93 -0
  111. package/lib/maps/vectorMaps.d.ts +1 -0
  112. package/lib/maps/vectorMaps.js +20 -36
  113. package/lib/mwater_table_selection/FormsListComponent.d.ts +33 -0
  114. package/lib/mwater_table_selection/FormsListComponent.js +141 -0
  115. package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +49 -0
  116. package/lib/mwater_table_selection/IndicatorsListComponent.js +251 -0
  117. package/lib/mwater_table_selection/IssuesListComponent.d.ts +29 -0
  118. package/lib/mwater_table_selection/IssuesListComponent.js +123 -0
  119. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.d.ts +20 -0
  120. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.js +157 -0
  121. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.d.ts +17 -0
  122. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.js +79 -0
  123. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.d.ts +18 -0
  124. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.js +80 -0
  125. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +63 -0
  126. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +461 -0
  127. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.d.ts +17 -0
  128. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.js +94 -0
  129. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.d.ts +17 -0
  130. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.js +80 -0
  131. package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +32 -0
  132. package/lib/mwater_table_selection/MWaterTableSelectComponent.js +163 -0
  133. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.d.ts +19 -0
  134. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.js +111 -0
  135. package/lib/quickfilter/QuickfiltersComponent.d.ts +3 -102
  136. package/lib/quickfilter/QuickfiltersComponent.js +53 -110
  137. package/lib/quickfilter/TextLiteralComponent.d.ts +23 -47
  138. package/lib/quickfilter/TextLiteralComponent.js +85 -82
  139. package/lib/widgets/MapWidget.js +4 -2
  140. package/lib/widgets/charts/Chart.d.ts +11 -0
  141. package/lib/widgets/charts/Chart.js +15 -0
  142. package/lib/widgets/charts/ChartWidgetComponent.d.ts +1 -0
  143. package/lib/widgets/charts/ChartWidgetComponent.js +27 -1
  144. package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +1 -1
  145. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +1 -1
  146. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +5 -12
  147. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +43 -57
  148. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +113 -110
  149. package/lib/widgets/charts/layered/LayeredChartUtils.d.ts +2 -1
  150. package/lib/widgets/charts/layered/LayeredChartUtils.js +0 -2
  151. package/lib/widgets/charts/pivot/PivotChart.d.ts +2 -0
  152. package/lib/widgets/charts/pivot/PivotChart.js +156 -0
  153. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +5 -20
  154. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +31 -61
  155. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +4 -0
  156. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +4 -2
  157. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.d.ts +5 -44
  158. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +38 -63
  159. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +7 -68
  160. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +58 -106
  161. package/lib/widgets/charts/table/TableChart.d.ts +2 -0
  162. package/lib/widgets/charts/table/TableChart.js +172 -1
  163. package/lib/widgets/charts/table/TableChartDesignerComponent.d.ts +7 -17
  164. package/lib/widgets/charts/table/TableChartDesignerComponent.js +79 -95
  165. package/lib/widgets/charts/table/TableChartViewComponent.d.ts +1 -7
  166. package/lib/widgets/charts/table/TableChartViewComponent.js +19 -27
  167. package/lib/widgets/text/ExprItemEditorComponent.d.ts +3 -8
  168. package/lib/widgets/text/ExprItemEditorComponent.js +36 -33
  169. package/lib/widgets/text/ExprUpdateModalComponent.d.ts +1 -0
  170. package/package.json +4 -10
  171. package/src/MWaterContextComponent.tsx +2 -2
  172. package/src/{MWaterGlobalFiltersComponent.ts → MWaterGlobalFiltersComponent.tsx} +32 -33
  173. package/src/{MWaterLoaderComponent.ts → MWaterLoaderComponent.tsx} +18 -19
  174. package/src/UndoStack.ts +14 -6
  175. package/src/dashboards/DashboardComponent.tsx +7 -5
  176. package/src/dashboards/DashboardDesign.ts +1 -1
  177. package/src/dashboards/LayoutOptionsComponent.tsx +22 -10
  178. package/src/dashboards/ServerDashboardDataSource.ts +36 -13
  179. package/src/dashboards/SettingsModalComponent.tsx +1 -1
  180. package/src/dashboards/layoutOptions.tsx +5 -1
  181. package/src/datagrids/DatagridComponent.tsx +31 -3
  182. package/src/datagrids/DatagridDesignerComponent.tsx +241 -229
  183. package/src/datagrids/DatagridViewComponent.tsx +3 -2
  184. package/src/datagrids/ExprCellComponent.tsx +23 -20
  185. package/src/datagrids/OrderBysDesignerComponent.tsx +61 -70
  186. package/src/index.css +45 -2
  187. package/src/index.ts +5 -11
  188. package/src/layouts/blocks/BlocksDisplayComponent.tsx +60 -5
  189. package/src/maps/BufferLayer.ts +48 -20
  190. package/src/maps/BufferLayerDesign.ts +1 -1
  191. package/src/maps/BufferLayerDesignerComponent.tsx +2 -1
  192. package/src/maps/ChoroplethLayer.ts +70 -39
  193. package/src/maps/ChoroplethLayerDesign.ts +6 -2
  194. package/src/maps/ChoroplethLayerDesigner.tsx +171 -167
  195. package/src/maps/DirectMapDataSource.ts +21 -13
  196. package/src/maps/EditHoverOver.tsx +98 -54
  197. package/src/maps/HoverContent.tsx +17 -48
  198. package/src/maps/Layer.ts +42 -4
  199. package/src/maps/LeafletMapComponent.tsx +10 -19
  200. package/src/maps/MWaterServerLayer.ts +6 -6
  201. package/src/maps/MapComponent.ts +0 -1
  202. package/src/maps/MapLayerDataSource.ts +8 -0
  203. package/src/maps/MapUtils.ts +82 -3
  204. package/src/maps/MarkersLayer.ts +54 -27
  205. package/src/maps/MarkersLayerDesign.ts +1 -1
  206. package/src/maps/MarkersLayerDesignerComponent.tsx +360 -0
  207. package/src/maps/RasterMapViewComponent.ts +1 -1
  208. package/src/maps/ServerMapDataSource.ts +35 -12
  209. package/src/maps/VectorMapViewComponent.tsx +8 -19
  210. package/src/maps/maps.ts +4 -2
  211. package/src/maps/symbols/font-awesome/asterisk.png +0 -0
  212. package/src/maps/symbols/font-awesome/ban.png +0 -0
  213. package/src/maps/symbols/font-awesome/beer.png +0 -0
  214. package/src/maps/symbols/font-awesome/bell.png +0 -0
  215. package/src/maps/symbols/font-awesome/bolt.png +0 -0
  216. package/src/maps/symbols/font-awesome/building.png +0 -0
  217. package/src/maps/symbols/font-awesome/bullseye.png +0 -0
  218. package/src/maps/symbols/font-awesome/bus.png +0 -0
  219. package/src/maps/symbols/font-awesome/caret-up.png +0 -0
  220. package/src/maps/symbols/font-awesome/certificate.png +0 -0
  221. package/src/maps/symbols/font-awesome/check-circle.png +0 -0
  222. package/src/maps/symbols/font-awesome/check.png +0 -0
  223. package/src/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  224. package/src/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  225. package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
  226. package/src/maps/symbols/font-awesome/cloud.png +0 -0
  227. package/src/maps/symbols/font-awesome/comment.png +0 -0
  228. package/src/maps/symbols/font-awesome/crosshairs.png +0 -0
  229. package/src/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  230. package/src/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  231. package/src/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  232. package/src/maps/symbols/font-awesome/female.png +0 -0
  233. package/src/maps/symbols/font-awesome/file.png +0 -0
  234. package/src/maps/symbols/font-awesome/flag.png +0 -0
  235. package/src/maps/symbols/font-awesome/flask.png +0 -0
  236. package/src/maps/symbols/font-awesome/h-square.png +0 -0
  237. package/src/maps/symbols/font-awesome/home.png +0 -0
  238. package/src/maps/symbols/font-awesome/info-circle.png +0 -0
  239. package/src/maps/symbols/font-awesome/male.png +0 -0
  240. package/src/maps/symbols/font-awesome/medkit.png +0 -0
  241. package/src/maps/symbols/font-awesome/mobile.png +0 -0
  242. package/src/maps/symbols/font-awesome/plus-circle.png +0 -0
  243. package/src/maps/symbols/font-awesome/plus-square.png +0 -0
  244. package/src/maps/symbols/font-awesome/plus.png +0 -0
  245. package/src/maps/symbols/font-awesome/square.png +0 -0
  246. package/src/maps/symbols/font-awesome/star.png +0 -0
  247. package/src/maps/symbols/font-awesome/thumbs-down.png +0 -0
  248. package/src/maps/symbols/font-awesome/thumbs-up.png +0 -0
  249. package/src/maps/symbols/font-awesome/ticket.png +0 -0
  250. package/src/maps/symbols/font-awesome/times-circle.png +0 -0
  251. package/src/maps/symbols/font-awesome/times.png +0 -0
  252. package/src/maps/symbols/font-awesome/tint.png +0 -0
  253. package/src/maps/symbols/font-awesome/tree.png +0 -0
  254. package/src/maps/symbols/font-awesome/university.png +0 -0
  255. package/src/maps/symbols/font-awesome/usd.png +0 -0
  256. package/src/maps/symbols/font-awesome/user.png +0 -0
  257. package/src/maps/symbols/font-awesome/users.png +0 -0
  258. package/src/maps/symbols/font-awesome/wheelchair.png +0 -0
  259. package/src/maps/symbols/sdf-ize.sh +93 -0
  260. package/src/maps/vectorMaps.tsx +20 -44
  261. package/src/mwater_table_selection/FormsListComponent.tsx +188 -0
  262. package/src/mwater_table_selection/IndicatorsListComponent.tsx +411 -0
  263. package/src/mwater_table_selection/IssuesListComponent.tsx +167 -0
  264. package/src/mwater_table_selection/MWaterAccountingSystemListComponent.tsx +225 -0
  265. package/src/{MWaterAssetSystemsListComponent.tsx → mwater_table_selection/MWaterAssetSystemsListComponent.tsx} +2 -2
  266. package/src/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.tsx +111 -0
  267. package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +713 -0
  268. package/src/{MWaterCustomTablesetListComponent.tsx → mwater_table_selection/MWaterCustomTablesetListComponent.tsx} +1 -1
  269. package/src/{MWaterMetricsTableListComponent.tsx → mwater_table_selection/MWaterMetricsTableListComponent.tsx} +1 -1
  270. package/src/{MWaterTableSelectComponent.tsx → mwater_table_selection/MWaterTableSelectComponent.tsx} +91 -90
  271. package/src/mwater_table_selection/MWaterWorkflowsSelectComponent.tsx +159 -0
  272. package/src/quickfilter/{QuickfiltersComponent.ts → QuickfiltersComponent.tsx} +165 -158
  273. package/src/quickfilter/TextLiteralComponent.tsx +197 -0
  274. package/src/widgets/MapWidget.tsx +9 -1
  275. package/src/widgets/charts/Chart.ts +17 -0
  276. package/src/widgets/charts/ChartWidgetComponent.tsx +36 -1
  277. package/src/widgets/charts/layered/LayeredChartDesign.ts +1 -1
  278. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +23 -24
  279. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +260 -211
  280. package/src/widgets/charts/layered/LayeredChartUtils.ts +7 -7
  281. package/src/widgets/charts/pivot/PivotChart.ts +191 -0
  282. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +124 -129
  283. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +4 -2
  284. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +120 -149
  285. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +178 -198
  286. package/src/widgets/charts/table/TableChart.ts +177 -1
  287. package/src/widgets/charts/table/TableChartDesignerComponent.tsx +422 -0
  288. package/src/widgets/charts/table/{TableChartViewComponent.ts → TableChartViewComponent.tsx} +65 -60
  289. package/src/widgets/text/ExprItemEditorComponent.tsx +83 -77
  290. package/src/widgets/text/ExprUpdateModalComponent.tsx +1 -0
  291. package/test/UndoStackTests.ts +52 -1
  292. package/.storybook/config.js +0 -7
  293. package/.storybook/head.html +0 -4
  294. package/.storybook/webpack.config.js +0 -15
  295. package/src/MWaterCompleteTableSelectComponent.tsx +0 -975
  296. package/src/maps/BingLayer.ts +0 -146
  297. package/src/maps/MarkersLayerDesignerComponent.ts +0 -374
  298. package/src/quickfilter/TextLiteralComponent.ts +0 -165
  299. package/src/widgets/charts/table/TableChartDesignerComponent.ts +0 -441
  300. package/stories/UpdateableComponent.js +0 -29
  301. package/stories/consoles.js +0 -202
  302. package/stories/dashboards.js +0 -217
  303. package/stories/datagridDesign.js +0 -114
  304. package/stories/datagrids.js +0 -69
  305. package/stories/dates.js +0 -80
  306. package/stories/exprcomponent.js +0 -43
  307. package/stories/index.js +0 -18
  308. package/stories/leaflet.js +0 -59
  309. package/stories/maps.js +0 -24
  310. package/stories/pivotChart.js +0 -235
@@ -1,5 +1,5 @@
1
1
  import _ from "lodash"
2
- import { DataSource, Expr, injectTableAlias, Schema } from "@mwater/expressions"
2
+ import { DataSource, Expr, ExprCompiler, injectTableAlias, Schema } from "@mwater/expressions"
3
3
  import { JsonQLFilter } from "../JsonQLFilter"
4
4
  import BlocksLayoutManager from "../layouts/blocks/BlocksLayoutManager"
5
5
  import WidgetFactory from "../widgets/WidgetFactory"
@@ -16,6 +16,7 @@ import TileUrlLayer from "./TileUrlLayer"
16
16
  import * as QuickfilterUtils from "../quickfilter/QuickfilterUtils"
17
17
  import { useState, useEffect } from 'react'
18
18
  import { useStableCallback } from "@mwater/react-library/lib/useStableCallback"
19
+ import { JsonQLSelectQuery } from "@mwater/jsonql"
19
20
 
20
21
  export interface DirectMapDataSourceOptions {
21
22
  /** schema to use */
@@ -349,12 +350,6 @@ class DirectLayerDataSource implements MapLayerDataSource {
349
350
 
350
351
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?` + querystring.stringify(query)
351
352
 
352
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
353
- // Used to speed queries
354
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
355
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/")
356
- }
357
-
358
353
  return url
359
354
  }
360
355
 
@@ -363,12 +358,6 @@ class DirectLayerDataSource implements MapLayerDataSource {
363
358
  let where
364
359
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?type=${design.type}&radius=1000`
365
360
 
366
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
367
- // Used to speed queries
368
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
369
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/")
370
- }
371
-
372
361
  if (this.options.client) {
373
362
  url += `&client=${this.options.client}`
374
363
  }
@@ -392,4 +381,23 @@ class DirectLayerDataSource implements MapLayerDataSource {
392
381
 
393
382
  return url
394
383
  }
384
+
385
+ /** Gets hover over data for hover over items
386
+ * @param design The design of the layer
387
+ * @param data The data of the current item being hovered over. e.g. { id: 123 }
388
+ * @param filters The filters to apply to the hover over data, not including filtering down to the current item
389
+ * @returns A promise that resolves to the hover over data, indexed by the id of the hover over item
390
+ */
391
+ getHoverOverData(design: any, data: any, filters: JsonQLFilter[]): Promise<{ [key: string]: any }> {
392
+ // Create layer
393
+ const layer = LayerFactory.createLayer(this.options.layerView.type)
394
+
395
+ return layer.getHoverOverData({
396
+ design,
397
+ data,
398
+ filters,
399
+ schema: this.options.schema,
400
+ dataSource: this.options.dataSource,
401
+ })
402
+ }
395
403
  }
@@ -1,11 +1,13 @@
1
1
  import { omit } from "lodash"
2
- import { DataSource, Expr, Schema } from "@mwater/expressions"
2
+ import { AggrStatus, DataSource, Expr, ExprUtils, Schema } from "@mwater/expressions"
3
3
  import { ExprComponent } from "@mwater/expressions-ui"
4
4
  import React, { useState } from "react"
5
- import ModalWindowComponent from "@mwater/react-library/lib/ModalWindowComponent"
5
+ import ActionCancelModalComponent from "@mwater/react-library/lib/ActionCancelModalComponent"
6
6
  import * as ui from "@mwater/react-library/lib/bootstrap"
7
7
  import uuid from "uuid"
8
8
  import { HoverOverItem } from "./maps"
9
+ import { canFormatType, getDefaultFormat } from "../valueFormatter"
10
+ import { getFormatOptions } from "../valueFormatter"
9
11
 
10
12
  export interface EditHoverOverProps {
11
13
  /** Schema to use */
@@ -20,88 +22,105 @@ export interface EditHoverOverProps {
20
22
  /** Table of the row that join is to. Usually same as table except for choropleth maps */
21
23
  idTable: string
22
24
  defaultPopupFilterJoins: any
25
+
26
+ /** Aggr statuses to allow in hover over expressions */
27
+ aggrStatuses: AggrStatus[]
23
28
  }
24
29
 
25
- const EditHoverOver: React.FC<EditHoverOverProps> = props => {
30
+ export function EditHoverOver(props: EditHoverOverProps) {
31
+ const { schema, dataSource, design, onDesignChange, table } = props
26
32
  const [editing, setEditing] = useState(false)
33
+ const [draftItems, setDraftItems] = useState<HoverOverItem[] | undefined>(undefined)
27
34
 
28
35
  const handleRemovePopup = () => {
29
- const design = omit(props.design, "hoverOver")
30
- props.onDesignChange(design)
36
+ const newDesign = omit(design, "hoverOver")
37
+ onDesignChange(newDesign)
31
38
  }
32
39
 
33
- const handleDesignChange = (items: HoverOverItem[]) => {
34
- const hoverOver = { ...(props.design.hoverOver ?? {}), items }
35
- const design = { ...props.design, hoverOver }
40
+ const handleItemChange = (item: HoverOverItem) => {
41
+ setDraftItems(draftItems?.map((i) => (item.id === i.id ? item : i)))
42
+ }
36
43
 
37
- return props.onDesignChange(design)
44
+ const handleItemDelete = (item: HoverOverItem) => {
45
+ setDraftItems(draftItems?.filter((i) => item.id !== i.id))
38
46
  }
39
47
 
40
- const handleItemChange = (item: HoverOverItem) => {
41
- const items = (props.design.hoverOver?.items ?? []).map((i: HoverOverItem) => (item.id === i.id ? item : i))
42
- const design = { ...props.design, hoverOver: { ...props.design.hoverOver, items } }
48
+ const handleAddItem = () => {
49
+ setDraftItems([...(draftItems ?? []), { id: uuid().replace(/-/g, ""), label: "" }])
50
+ }
43
51
 
44
- return props.onDesignChange(design)
52
+ const handleSave = () => {
53
+ const hoverOver = { ...(design.hoverOver ?? {}), items: draftItems ?? [] }
54
+ const newDesign = { ...design, hoverOver }
55
+ onDesignChange(newDesign)
56
+ setEditing(false)
57
+ setDraftItems(undefined)
45
58
  }
46
59
 
47
- const handleItemDelete = (item: HoverOverItem) => {
48
- const items = (props.design.hoverOver?.items ?? []).filter((i: HoverOverItem) => item.id !== i.id)
49
- const design = { ...props.design, hoverOver: { ...props.design.hoverOver, items } }
60
+ const handleCancel = () => {
61
+ setEditing(false)
62
+ setDraftItems(undefined)
63
+ }
50
64
 
51
- return props.onDesignChange(design)
65
+ const handleOpen = () => {
66
+ setDraftItems(design.hoverOver?.items ?? [])
67
+ setEditing(true)
52
68
  }
53
69
 
54
70
  return (
55
71
  <>
56
- <button className="btn btn-link" onClick={() => setEditing(true)}>
72
+ <button className="btn btn-link" onClick={handleOpen}>
57
73
  <span className="fa fa-pencil" /> {T`Customize Hoverover`}
58
74
  </button>
59
- {props.design.hoverOver && (
75
+ {design.hoverOver && (
60
76
  <button className="btn btn-link" onClick={handleRemovePopup}>
61
77
  <span className="fa fa-times" /> {T`Remove Hover over`}
62
78
  </button>
63
79
  )}
64
80
 
65
81
  {editing && (
66
- <ModalWindowComponent isOpen onRequestClose={() => setEditing(false)}>
67
- {(props.design.hoverOver?.items ?? []).length > 0 && (
82
+ <ActionCancelModalComponent
83
+ onAction={handleSave}
84
+ onCancel={handleCancel}
85
+ actionLabel={T`Save`}
86
+ title={T`Customize Hoverover`}
87
+ size="x-large"
88
+ >
89
+ {(draftItems ?? []).length > 0 && (
68
90
  <table className="table">
69
91
  <thead>
70
92
  <tr>
71
93
  <th>{T`Label`}</th>
72
94
  <th>{T`Value`}</th>
73
- <th></th>
95
+ <th style={{ width: "1%", whiteSpace: "nowrap" }}>{T`Format`}</th>
96
+ <th style={{ width: "1%", whiteSpace: "nowrap" }}></th>
74
97
  </tr>
75
98
  </thead>
76
99
  <tbody>
77
- {props.design.hoverOver?.items.map((item: HoverOverItem) => (
100
+ {draftItems?.map((item: HoverOverItem) => (
78
101
  <HoverOverItemEditor
79
- schema={props.schema}
80
- dataSource={props.dataSource}
81
- table={props.design.table}
102
+ key={item.id}
103
+ schema={schema}
104
+ dataSource={dataSource}
105
+ table={table}
82
106
  onItemChange={handleItemChange}
83
107
  onItemDelete={handleItemDelete}
84
108
  item={item}
109
+ aggrStatuses={props.aggrStatuses}
85
110
  />
86
111
  ))}
87
112
  </tbody>
88
113
  </table>
89
114
  )}
90
115
 
91
- {(props.design.hoverOver?.items ?? []).length < 3 && (
92
- <button
93
- className="btn btn-link"
94
- onClick={() =>
95
- handleDesignChange([
96
- ...(props.design.hoverOver?.items ?? []),
97
- { id: uuid().replace(/-/g, ""), label: "" }
98
- ])
99
- }>
100
- <span className="fa fa-plus" />
101
- {T`Add item`}
102
- </button>
103
- )}
104
- </ModalWindowComponent>
116
+ <button
117
+ className="btn btn-link"
118
+ onClick={handleAddItem}
119
+ >
120
+ <span className="fas fa-plus me-1" />
121
+ {T`Add Item`}
122
+ </button>
123
+ </ActionCancelModalComponent>
105
124
  )}
106
125
  </>
107
126
  )
@@ -114,21 +133,45 @@ interface HoverOverItemEditorProps {
114
133
  onItemChange: (item: HoverOverItem) => void
115
134
  onItemDelete: (item: HoverOverItem) => void
116
135
  table: string
136
+ /** Aggr statuses to allow in hover over expressions */
137
+ aggrStatuses: AggrStatus[]
117
138
  }
118
- const HoverOverItemEditor: React.FC<HoverOverItemEditorProps> = ({
119
- schema,
120
- dataSource,
121
- table,
122
- item,
123
- onItemChange,
124
- onItemDelete
125
- }) => {
139
+
140
+ function HoverOverItemEditor(props: HoverOverItemEditorProps) {
141
+ const { schema, dataSource, table, item, onItemChange, onItemDelete } = props
142
+
143
+ function renderFormat() {
144
+ const exprUtils = new ExprUtils(schema)
145
+ const exprType = exprUtils.getExprType(item.value ?? null)
146
+ if (!exprType) {
147
+ return null
148
+ }
149
+
150
+ if (!canFormatType(exprType)) {
151
+ return null
152
+ }
153
+
154
+ const formats = getFormatOptions(exprType)
155
+ if (!formats) {
156
+ return null
157
+ }
158
+
159
+ return (
160
+ <ui.Select
161
+ options={formats.map(f => ({ value: f.value, label: f.label }))}
162
+ value={item.format ?? getDefaultFormat(exprType)}
163
+ onChange={value => onItemChange({ ...item, format: value ?? undefined })}
164
+ style={{ width: "auto", display: "inline-block" }}
165
+ />
166
+ )
167
+ }
168
+
126
169
  return (
127
170
  <tr>
128
- <td>
171
+ <td className="align-middle">
129
172
  <ui.TextInput value={item.label} onChange={value => onItemChange({ ...item, label: value })} />
130
173
  </td>
131
- <td>
174
+ <td className="align-middle">
132
175
  <ExprComponent
133
176
  schema={schema}
134
177
  dataSource={dataSource}
@@ -136,10 +179,13 @@ const HoverOverItemEditor: React.FC<HoverOverItemEditorProps> = ({
136
179
  types={["text", "number", "enum", "boolean", "date", "datetime", "id"]}
137
180
  onChange={expr => onItemChange({ ...item, value: expr })}
138
181
  value={item.value ?? null}
139
- aggrStatuses={["individual", "literal", "aggregate"]}
182
+ aggrStatuses={props.aggrStatuses}
140
183
  />
141
184
  </td>
142
- <td>
185
+ <td className="align-middle" style={{ width: "1%", whiteSpace: "nowrap" }}>
186
+ {renderFormat()}
187
+ </td>
188
+ <td className="align-middle" style={{ width: "1%", whiteSpace: "nowrap" }}>
143
189
  <button className="btn btn-link" onClick={() => onItemDelete(item)}>
144
190
  <span className="fa fa-close" />
145
191
  </button>
@@ -147,5 +193,3 @@ const HoverOverItemEditor: React.FC<HoverOverItemEditorProps> = ({
147
193
  </tr>
148
194
  )
149
195
  }
150
-
151
- export default EditHoverOver
@@ -1,19 +1,22 @@
1
1
  import React, { useEffect, useState } from "react"
2
- import { DataSource, ExprCompiler, ExprUtils, Schema, injectTableAlias } from "@mwater/expressions"
3
- import { JsonQLSelectQuery } from "@mwater/jsonql"
2
+ import { ExprUtils, Schema } from "@mwater/expressions"
4
3
  import { JsonQLFilter } from ".."
5
- import { compact } from "lodash"
6
4
  import { HoverOverItem } from "./maps"
7
5
  import { canFormatType } from "../valueFormatter"
8
6
  import { formatValue } from "../valueFormatter"
7
+ import { MapLayerDataSource } from "./MapLayerDataSource"
9
8
 
10
9
  export interface HoverContentProps {
11
10
  /** Schema to use */
12
11
  schema: Schema
13
- dataSource: DataSource
14
- filters?: JsonQLFilter[]
15
- /** Table that hover over is for */
16
- table: string
12
+ /** Map data source */
13
+ mapLayerDataSource: MapLayerDataSource
14
+ /** Design of the layer */
15
+ design: any
16
+ /** Data of the current item being hovered over. e.g. { id: 123 } */
17
+ data: any
18
+ /** Additional filters to apply to the hover over data */
19
+ filters: JsonQLFilter[]
17
20
  /** Hover over items */
18
21
  items: HoverOverItem[]
19
22
  /** Locale to use */
@@ -33,48 +36,14 @@ const HoverContent = (props: HoverContentProps) => {
33
36
  const items = props.items
34
37
 
35
38
  if (items.length > 0) {
36
- const exprCompiler = new ExprCompiler(props.schema)
37
- const query: JsonQLSelectQuery = {
38
- type: "query",
39
- selects: [],
40
- from: exprCompiler.compileTable(props.table, "main"),
41
- limit: 1
42
- }
43
-
44
- items.forEach((item: HoverOverItem) => {
45
- if (item.value) {
46
- query.selects.push({
47
- type: "select",
48
- expr: exprCompiler.compileExpr({ expr: item.value, tableAlias: "main" }),
49
- alias: item.id
50
- })
39
+ props.mapLayerDataSource.getHoverOverData(props.design, props.data, props.filters).then((data) => {
40
+ if (mounted) {
41
+ setValues(data)
51
42
  }
52
- })
53
-
54
- if (props.filters) {
55
- let whereClauses = props.filters.map(f => injectTableAlias(f.jsonql, "main"))
56
-
57
- whereClauses = compact(whereClauses)
58
-
59
- // Wrap if multiple
60
- if (whereClauses.length > 1) {
61
- query.where = { type: "op", op: "and", exprs: whereClauses }
62
- } else {
63
- query.where = whereClauses[0]
43
+ }).catch((error) => {
44
+ if (mounted) {
45
+ setError(error.message)
64
46
  }
65
- }
66
-
67
- props.dataSource.performQuery(query, (error: any, data: any) => {
68
- if (!mounted) {
69
- return
70
- }
71
-
72
- if (error) {
73
- setError(props.translate("Error loading hover data"))
74
- return
75
- }
76
-
77
- setValues(data?.[0] ?? {})
78
47
  })
79
48
  }
80
49
 
@@ -88,7 +57,7 @@ const HoverContent = (props: HoverContentProps) => {
88
57
  }
89
58
 
90
59
  return (
91
- <div className="_mviz-map-hover-content">
60
+ <div className="mwater-visualization-map-hover-content">
92
61
  {props.items.map((item: HoverOverItem) => {
93
62
  let value = values[item.id]
94
63
 
package/src/maps/Layer.ts CHANGED
@@ -169,6 +169,25 @@ export default class Layer<LayerDesign> {
169
169
  return null
170
170
  }
171
171
 
172
+ /**
173
+ * Called when the interactivity grid is hovered over.
174
+ * arguments:
175
+ * ev: { data: interactivty data e.g. `{ id: 123 }` }
176
+ * options:
177
+ * design: design of layer
178
+ * schema: schema to use
179
+ * dataSource: data source to use
180
+ * layerDataSource: layer data source
181
+ * scopeData: current scope data if layer is scoping
182
+ * filters: compiled filters to apply to the popup
183
+ *
184
+ * Returns:
185
+ * null
186
+ * or
187
+ * {
188
+ * hoverOver: React element to put into a hover over
189
+ * }
190
+ */
172
191
  onGridHoverOver(ev: { data: any; event: any }, options: OnGridHoverOptions<LayerDesign>): OnGridHoverResults {
173
192
  return null
174
193
  }
@@ -316,10 +335,10 @@ export default class Layer<LayerDesign> {
316
335
  const [w, s, e, n] = bbox(results[0].bounds)
317
336
  // Pad bounds to prevent too small box (100m)
318
337
  bounds = {
319
- w: w - 0.001,
320
- s: s - 0.001,
321
- e: e + 0.001,
322
- n: n + 0.001
338
+ w: Math.max(w - 0.001, -180),
339
+ s: Math.max(s - 0.001, -90),
340
+ e: Math.min(e + 0.001, 180),
341
+ n: Math.min(n + 0.001, 90)
323
342
  }
324
343
  }
325
344
 
@@ -332,6 +351,25 @@ export default class Layer<LayerDesign> {
332
351
  getTranslatableStrings(design: LayerDesign, schema: Schema): string[] {
333
352
  return []
334
353
  }
354
+
355
+ /** Gets hover over data for hover over items. This should be implemented by layers that have hover over items.
356
+ * It will be called on the server side if using a server map data source, or on the client side if using a direct
357
+ * map data source.
358
+ */
359
+ getHoverOverData(options: {
360
+ /** Design of the layer */
361
+ design: LayerDesign,
362
+ /** Data of the current item being hovered over. e.g. { id: 123 } */
363
+ data: any,
364
+ /** Filters to apply to the hover over data, not including filtering down to the current item */
365
+ filters: JsonQLFilter[],
366
+ /** Schema to use */
367
+ schema: Schema,
368
+ /** Data source to use */
369
+ dataSource: DataSource,
370
+ }): Promise<{ [key: string]: any }> {
371
+ return Promise.resolve({})
372
+ }
335
373
  }
336
374
 
337
375
  export interface LegendOptions<LayerDesign> {
@@ -3,7 +3,6 @@ import React, { ReactElement, Component } from "react"
3
3
  import ReactDOM from "react-dom"
4
4
  import LeafletLoading from "./LeafletLoading"
5
5
  import L, { PathOptions, CircleMarkerOptions } from "leaflet"
6
- let BingLayer = require("./BingLayer")
7
6
  let UtfGridLayer = require("./UtfGridLayer")
8
7
 
9
8
  const R = React.createElement
@@ -387,36 +386,28 @@ export default class LeafletMapComponent extends Component<Props> {
387
386
 
388
387
  switch (this.props.baseLayerId) {
389
388
  case "bing_road":
390
- this.baseLayer = new BingLayer("Ao26dWY2IC8PjorsJKFaoR85EPXCnCohrJdisCWXIULAXFo0JAXquGauppTMQbyU", {
391
- type: "Road"
389
+ this.baseLayer = L.tileLayer('https://tiles.stadiamaps.com/tiles/osm_bright/{z}/{x}/{y}{r}.png?api_key=835a418e-91f9-4eb8-9856-0883c3656c9d', {
390
+ maxZoom: 20,
391
+ attribution: '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
392
392
  })
393
393
  break
394
- // @baseLayer = L.tileLayer('https://{s}.api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
395
- // attribution: '© <a href="https://www.mapbox.com/about/maps/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> <strong><a href="https://www.mapbox.com/map-feedback/" target="_blank">Improve this map</a></strong>',
396
- // tileSize: 512,
397
- // maxZoom: 21,
398
- // maxNativeZoom: 19,
399
- // subdomains: ["a", "b"],
400
- // zoomOffset: -1,
401
- // id: 'mapbox/streets-v11',
402
- // accessToken: 'pk.eyJ1IjoiZ3Jhc3NpY2siLCJhIjoiY2ozMzU1N3ZoMDA3ZDJxbzh0aTRtOTRoeSJ9.fFWBZ88vbdezyhfw-I-fag'
403
- // })
404
394
  case "bing_aerial":
405
- this.baseLayer = new BingLayer("Ao26dWY2IC8PjorsJKFaoR85EPXCnCohrJdisCWXIULAXFo0JAXquGauppTMQbyU", {
406
- type: "AerialWithLabels"
395
+ this.baseLayer = L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_satellite/{z}/{x}/{y}.jpg?api_key=835a418e-91f9-4eb8-9856-0883c3656c9d', {
396
+ maxZoom: 20,
397
+ attribution: '&copy; CNES, Distribution Airbus DS, &copy; Airbus DS, &copy; PlanetObserver (Contains Copernicus Data) | &copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
407
398
  })
408
399
  break
409
400
  case "cartodb_positron":
410
- this.baseLayer = L.tileLayer("https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png", {
401
+ this.baseLayer = L.tileLayer("https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png?api_key=835a418e-91f9-4eb8-9856-0883c3656c9d", {
411
402
  attribution:
412
- '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://cartodb.com/attributions">CartoDB</a>',
403
+ '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a>, &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
413
404
  maxZoom: 21
414
405
  })
415
406
  break
416
407
  case "cartodb_dark_matter":
417
- this.baseLayer = L.tileLayer("https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png", {
408
+ this.baseLayer = L.tileLayer("https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png?api_key=835a418e-91f9-4eb8-9856-0883c3656c9d", {
418
409
  attribution:
419
- '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://cartodb.com/attributions">CartoDB</a>',
410
+ '&copy; <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a>, &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
420
411
  maxZoom: 21
421
412
  })
422
413
  break
@@ -94,15 +94,15 @@ class LoadingLegend extends React.Component<LoadingLegendProps, LoadingLegendSta
94
94
  }
95
95
 
96
96
  componentDidMount() {
97
- return $.get(this.props.url).done((data: any) => {
98
- return this.setState({ html: data })
97
+ $.get(this.props.url).done((data: any) => {
98
+ this.setState({ html: data })
99
99
  })
100
100
  }
101
101
 
102
- componentWillReceiveProps(nextProps: any) {
103
- if (nextProps.url !== this.props.url) {
104
- return $.get(nextProps.url).done((data: any) => {
105
- return this.setState({ html: data })
102
+ componentDidUpdate(prevProps: any) {
103
+ if (prevProps.url !== this.props.url) {
104
+ $.get(this.props.url).done((data: any) => {
105
+ this.setState({ html: data })
106
106
  })
107
107
  }
108
108
  }
@@ -290,7 +290,6 @@ export default class MapComponent extends React.Component<MapComponentProps, Map
290
290
 
291
291
  render() {
292
292
  const designerVisible = !this.getDesign().hideDesignPanel
293
- console.log("designerVisible", designerVisible)
294
293
  return R(
295
294
  "div",
296
295
  {
@@ -24,4 +24,12 @@ export interface MapLayerDataSource {
24
24
 
25
25
  /** Gets widget data source for a popup widget */
26
26
  getPopupWidgetDataSource(design: any, widgetId: string): WidgetDataSource
27
+
28
+ /** Gets hover over data for hover over items
29
+ * @param design The design of the layer
30
+ * @param data The data of the current item being hovered over. e.g. { id: 123 }
31
+ * @param filters The filters to apply to the layer does not include filters that narrow down to a specific item
32
+ * @returns A promise that resolves to the hover over data, indexed by the id of the hover over item
33
+ */
34
+ getHoverOverData(design: any, data: any, filters: JsonQLFilter[]): Promise<{ [key: string]: any }>
27
35
  }
@@ -1,12 +1,13 @@
1
1
  // General utilities for a map
2
2
 
3
- import { JsonQLExpr } from "@mwater/jsonql"
4
- import _ from "lodash"
5
- import { Expr, ExprCleaner, ExprCompiler, ExprUtils, FieldExpr, Schema } from "@mwater/expressions"
3
+ import { JsonQLExpr, JsonQLSelectQuery } from "@mwater/jsonql"
4
+ import _, { compact } from "lodash"
5
+ import { DataSource, Expr, ExprCleaner, ExprCompiler, ExprUtils, FieldExpr, injectTableAlias, Schema } from "@mwater/expressions"
6
6
  import { JsonQLFilter } from "../JsonQLFilter"
7
7
  import LayerFactory from "./LayerFactory"
8
8
  import { MapDesign } from "./MapDesign"
9
9
  import { produce } from "immer"
10
+ import { HoverOverItem } from "./maps"
10
11
 
11
12
  export interface MapScope {
12
13
  name: string
@@ -170,3 +171,81 @@ export function getTranslatableStrings(design: MapDesign, schema: Schema): strin
170
171
  // Remove duplicates
171
172
  return _.uniq(strings)
172
173
  }
174
+
175
+ /**
176
+ * Convenience function to get hover over data for a map given an id and a list of hover over items
177
+ */
178
+ export async function getSimpleHoverOverData(options: {
179
+ /** Id of the item to get hover over data for. If null, will not filter by id */
180
+ id: any,
181
+ /** Table of the item to get hover over data for */
182
+ table: string,
183
+ /** Extra filters to apply to the hover over data, not including filtering down to the current item */
184
+ filters: JsonQLFilter[],
185
+ /** Schema to use */
186
+ schema: Schema,
187
+ /** Data source to use */
188
+ dataSource: DataSource,
189
+ /** Hover over items */
190
+ hoverOverItems: HoverOverItem[]
191
+ }) {
192
+ const { id, table, filters, schema, dataSource, hoverOverItems } = options
193
+
194
+ const exprUtils = new ExprUtils(schema)
195
+ const exprCompiler = new ExprCompiler(schema)
196
+ const query: JsonQLSelectQuery = {
197
+ type: "query",
198
+ selects: [],
199
+ from: exprCompiler.compileTable(table, "main"),
200
+ groupBy: [],
201
+ limit: 1
202
+ }
203
+
204
+ // Check if any items are aggregate
205
+ const isAggregate = hoverOverItems.some(item => exprUtils.getExprAggrStatus(item.value ?? null) === "aggregate")
206
+
207
+ for (let i = 0; i < hoverOverItems.length; i++) {
208
+ const item = hoverOverItems[i]
209
+
210
+ if (item.value) {
211
+ query.selects.push({
212
+ type: "select",
213
+ expr: exprCompiler.compileExpr({ expr: item.value, tableAlias: "main" }),
214
+ alias: item.id
215
+ })
216
+
217
+ // Group by if there are aggregate items and this is not aggregate
218
+ if (isAggregate && exprUtils.getExprAggrStatus(item.value) !== "aggregate") {
219
+ query.groupBy!.push(i + 1)
220
+ }
221
+ }
222
+ }
223
+
224
+ if (filters) {
225
+ let whereClauses = filters.filter(f => f.table === table).map(f => injectTableAlias(f.jsonql, "main"))
226
+
227
+ // Add id filter
228
+ if (id != null) {
229
+ whereClauses.push({
230
+ type: "op",
231
+ op: "=",
232
+ exprs: [
233
+ exprCompiler.compileExpr({ expr: { type: "id", table }, tableAlias: "main" }),
234
+ { type: "literal", value: id }
235
+ ]
236
+ })
237
+ }
238
+
239
+ whereClauses = compact(whereClauses)
240
+
241
+ // Wrap if multiple
242
+ if (whereClauses.length > 1) {
243
+ query.where = { type: "op", op: "and", exprs: whereClauses }
244
+ } else {
245
+ query.where = whereClauses[0]
246
+ }
247
+ }
248
+
249
+ const rows = await dataSource.performQuery(query)
250
+ return rows?.[0] ?? {}
251
+ }