@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,7 +1,6 @@
1
1
  import PropTypes from "prop-types"
2
2
  import _ from "lodash"
3
3
  import React from "react"
4
- const R = React.createElement
5
4
 
6
5
  import * as ui from "@mwater/react-library/lib/bootstrap"
7
6
  import AxisComponent from "../../../axes/AxisComponent"
@@ -86,45 +85,42 @@ export default class SegmentDesignerComponent extends React.Component<
86
85
  }
87
86
 
88
87
  renderMode() {
89
- return R(
90
- ui.FormGroup,
91
- {
92
- labelMuted: true,
93
- label: T`Type`
94
- },
95
- <ui.Radio key="single" value={this.state.mode} radioValue={"single"} onChange={this.handleMode}>
96
- {T`Single ${this.props.segmentType}`}
97
- <span className="text-muted">
98
- {` - `}
99
- {T`used for summary ${this.props.segmentType}s and empty ${this.props.segmentType}s`}
100
- </span>
101
- </ui.Radio>,
88
+ return (
89
+ <ui.FormGroup labelMuted={true} label={T`Type`}>
90
+ <ui.Radio key="single" value={this.state.mode} radioValue={"single"} onChange={this.handleMode}>
91
+ {T`Single ${this.props.segmentType}`}
92
+ <span className="text-muted">
93
+ {` - `}
94
+ {T`used for summary ${this.props.segmentType}s and empty ${this.props.segmentType}s`}
95
+ </span>
96
+ </ui.Radio>
102
97
 
103
- <ui.Radio key="multiple" value={this.state.mode} radioValue={"multiple"} onChange={this.handleMode}>
104
- {T`Multiple ${this.props.segmentType}s`}
105
- {" - "}
106
- <span className="text-muted">{T`disaggregate data by a field`}</span>
107
- </ui.Radio>
98
+ <ui.Radio key="multiple" value={this.state.mode} radioValue={"multiple"} onChange={this.handleMode}>
99
+ {T`Multiple ${this.props.segmentType}s`}
100
+ {" - "}
101
+ <span className="text-muted">{T`disaggregate data by a field`}</span>
102
+ </ui.Radio>
103
+ </ui.FormGroup>
108
104
  )
109
105
  }
110
106
 
111
107
  renderLabel() {
112
- return R(
113
- ui.FormGroup,
114
- {
115
- labelMuted: true,
116
- label: T`Label`,
117
- help: this.state.mode === "multiple" ? T`Optional label for the ${this.props.segmentType}s` : undefined
118
- },
119
- R("input", {
120
- ref: (elem: HTMLInputElement | null) => {
121
- this.labelElem = elem
122
- },
123
- type: "text",
124
- className: "form-control",
125
- value: this.props.segment.label || "",
126
- onChange: this.handleLabelChange
127
- })
108
+ return (
109
+ <ui.FormGroup
110
+ labelMuted={true}
111
+ label={T`Label`}
112
+ help={this.state.mode === "multiple" ? T`Optional label for the ${this.props.segmentType}s` : undefined}
113
+ >
114
+ <input
115
+ ref={(elem: HTMLInputElement | null) => {
116
+ this.labelElem = elem
117
+ }}
118
+ type="text"
119
+ className="form-control"
120
+ value={this.props.segment.label || ""}
121
+ onChange={this.handleLabelChange}
122
+ />
123
+ </ui.FormGroup>
128
124
  )
129
125
  }
130
126
 
@@ -137,20 +133,18 @@ export default class SegmentDesignerComponent extends React.Component<
137
133
 
138
134
  return <ui.FormGroup labelMuted label={T`Field`} help={T`Field to disaggregate data by`}>
139
135
  <div style={{ marginLeft: 8 }}>
140
- {
141
- R(AxisComponent, {
142
- schema: this.props.schema,
143
- dataSource: this.props.dataSource,
144
- table: this.props.table,
145
- types: ["enum", "enumset", "text", "boolean", "date"],
146
- aggrNeed: "none",
147
- value: this.props.segment.valueAxis,
148
- onChange: this.handleValueAxisChange,
149
- allowExcludedValues: true,
150
- filters: this.props.filters,
151
- collapseCategories: true
152
- })
153
- }
136
+ <AxisComponent
137
+ schema={this.props.schema}
138
+ dataSource={this.props.dataSource}
139
+ table={this.props.table}
140
+ types={["enum", "enumset", "text", "boolean", "date"]}
141
+ aggrNeed="none"
142
+ value={this.props.segment.valueAxis}
143
+ onChange={this.handleValueAxisChange}
144
+ allowExcludedValues={true}
145
+ filters={this.props.filters}
146
+ collapseCategories={true}
147
+ />
154
148
  { allowValueAxisOnlyValuesPresent ?
155
149
  <ui.Checkbox
156
150
  value={this.props.segment.valueAxisOnlyValuesPresent}
@@ -168,158 +162,144 @@ export default class SegmentDesignerComponent extends React.Component<
168
162
  }
169
163
 
170
164
  renderFilter() {
171
- return R(
172
- ui.FormGroup,
173
- {
174
- labelMuted: true,
175
- label: [R(ui.Icon, { id: "glyphicon-filter" }), " ", T`Filters`],
176
- hint: T`Filters all data associated with this ${this.props.segmentType}`
177
- },
178
- R(FilterExprComponent, {
179
- schema: this.props.schema,
180
- dataSource: this.props.dataSource,
181
- onChange: this.handleFilterChange,
182
- table: this.props.table,
183
- value: this.props.segment.filter
184
- })
165
+ return (
166
+ <ui.FormGroup
167
+ labelMuted={true}
168
+ label={<><ui.Icon id="glyphicon-filter" /> {T`Filters`}</>}
169
+ hint={T`Filters all data associated with this ${this.props.segmentType}`}
170
+ >
171
+ <FilterExprComponent
172
+ schema={this.props.schema}
173
+ dataSource={this.props.dataSource}
174
+ onChange={this.handleFilterChange}
175
+ table={this.props.table}
176
+ value={this.props.segment.filter}
177
+ />
178
+ </ui.FormGroup>
185
179
  )
186
180
  }
187
181
 
188
182
  renderStyling() {
189
- return R(
190
- ui.FormGroup,
191
- {
192
- labelMuted: true,
193
- label: T`Styling`
194
- },
195
- <div>
196
- <ui.Checkbox
197
- key="bold"
198
- inline
199
- value={this.props.segment.bold === true}
200
- onChange={(value) => this.update({ bold: value })}
201
- >
202
- {T`Bold`}
203
- </ui.Checkbox>
204
- <ui.Checkbox
205
- key="italic"
206
- inline
207
- value={this.props.segment.italic === true}
208
- onChange={(value) => this.update({ italic: value })}
209
- >
210
- {T`Italic`}
211
- </ui.Checkbox>
212
- { this.props.segment.valueAxis && this.props.segment.label ?
213
- <ui.Checkbox
214
- key="valueLabelBold"
215
- inline
216
- value={this.props.segment.valueLabelBold === true}
217
- onChange={(value) => this.update({ valueLabelBold: value })}
218
- >
219
- {T`Header Bold`}
220
- </ui.Checkbox>
221
- : undefined}
222
- {this.props.segment.valueAxis && this.props.segment.label
223
- ? R(
224
- "div",
225
- { style: { paddingTop: 5 } },
226
- T`Shade filler cells: `,
227
- R(ColorComponent, {
228
- color: this.props.segment.fillerColor,
229
- onChange: (color: any) => this.update({ fillerColor: color })
230
- })
231
- )
183
+ return (
184
+ <ui.FormGroup labelMuted={true} label={T`Styling`}>
185
+ <div>
186
+ <ui.Checkbox
187
+ key="bold"
188
+ inline
189
+ value={this.props.segment.bold === true}
190
+ onChange={(value) => this.update({ bold: value })}
191
+ >
192
+ {T`Bold`}
193
+ </ui.Checkbox>
194
+ <ui.Checkbox
195
+ key="italic"
196
+ inline
197
+ value={this.props.segment.italic === true}
198
+ onChange={(value) => this.update({ italic: value })}
199
+ >
200
+ {T`Italic`}
201
+ </ui.Checkbox>
202
+ { this.props.segment.valueAxis && this.props.segment.label ?
203
+ <ui.Checkbox
204
+ key="valueLabelBold"
205
+ inline
206
+ value={this.props.segment.valueLabelBold === true}
207
+ onChange={(value) => this.update({ valueLabelBold: value })}
208
+ >
209
+ {T`Header Bold`}
210
+ </ui.Checkbox>
232
211
  : undefined}
233
- </div>
212
+ {this.props.segment.valueAxis && this.props.segment.label ? (
213
+ <div style={{ paddingTop: 5 }}>
214
+ {T`Shade filler cells: `}
215
+ <ColorComponent
216
+ color={this.props.segment.fillerColor}
217
+ onChange={(color: any) => this.update({ fillerColor: color })}
218
+ />
219
+ </div>
220
+ ) : undefined}
221
+ </div>
222
+ </ui.FormGroup>
234
223
  )
235
224
  }
236
225
 
237
226
  renderBorders() {
238
- return R(
239
- ui.FormGroup,
240
- {
241
- labelMuted: true,
242
- label: T`Borders`
243
- },
244
- R("div", { key: "before" }, this.props.segmentType === "row" ? T`Top: ` : T`Left: `),
245
- R(BorderComponent, {
246
- value: this.props.segment.borderBefore,
247
- defaultValue: 2,
248
- onChange: (value: any) => this.update({ borderBefore: value })
249
- }),
250
- R("div", { key: "within" }, T`Within: `),
251
- R(BorderComponent, {
252
- value: this.props.segment.borderWithin,
253
- defaultValue: 1,
254
- onChange: (value: any) => this.update({ borderWithin: value })
255
- }),
256
- R("div", { key: "after" }, this.props.segmentType === "row" ? T`Bottom: ` : T`Right: `),
257
- R(BorderComponent, {
258
- value: this.props.segment.borderAfter,
259
- defaultValue: 2,
260
- onChange: (value: any) => this.update({ borderAfter: value })
261
- })
227
+ return (
228
+ <ui.FormGroup labelMuted={true} label={T`Borders`}>
229
+ <div key="before">{this.props.segmentType === "row" ? T`Top: ` : T`Left: `}</div>
230
+ <BorderComponent
231
+ value={this.props.segment.borderBefore}
232
+ defaultValue={2}
233
+ onChange={(value: any) => this.update({ borderBefore: value })}
234
+ />
235
+ <div key="within">{T`Within: `}</div>
236
+ <BorderComponent
237
+ value={this.props.segment.borderWithin}
238
+ defaultValue={1}
239
+ onChange={(value: any) => this.update({ borderWithin: value })}
240
+ />
241
+ <div key="after">{this.props.segmentType === "row" ? T`Bottom: ` : T`Right: `}</div>
242
+ <BorderComponent
243
+ value={this.props.segment.borderAfter}
244
+ defaultValue={2}
245
+ onChange={(value: any) => this.update({ borderAfter: value })}
246
+ />
247
+ </ui.FormGroup>
262
248
  )
263
249
  }
264
250
 
265
251
  renderOrderExpr() {
266
- return R(
267
- ui.FormGroup,
268
- {
269
- labelMuted: true,
270
- label: [R(ui.Icon, { id: "fa-sort-amount-asc" }), " ", T`Sort`],
271
- hint: T`Sorts the display of this ${this.props.segmentType}`
272
- },
273
- R(ExprComponent, {
274
- schema: this.props.schema,
275
- dataSource: this.props.dataSource,
276
- onChange: this.handleOrderExprChange,
277
- table: this.props.table,
278
- types: ["enum", "text", "boolean", "date", "datetime", "number"],
279
- aggrStatuses: ["aggregate"],
280
- value: this.props.segment.orderExpr ?? null
281
- }),
252
+ return (
253
+ <ui.FormGroup
254
+ labelMuted={true}
255
+ label={<><ui.Icon id="fa-sort-amount-asc" /> {T`Sort`}</>}
256
+ hint={T`Sorts the display of this ${this.props.segmentType}`}
257
+ >
258
+ <ExprComponent
259
+ schema={this.props.schema}
260
+ dataSource={this.props.dataSource}
261
+ onChange={this.handleOrderExprChange}
262
+ table={this.props.table}
263
+ types={["enum", "text", "boolean", "date", "datetime", "number"]}
264
+ aggrStatuses={["aggregate"]}
265
+ value={this.props.segment.orderExpr ?? null}
266
+ />
282
267
 
283
- this.props.segment.orderExpr
284
- ? R(
285
- "div",
286
- null,
287
- R(
288
- ui.Radio,
289
- {
290
- value: this.props.segment.orderDir || "asc",
291
- radioValue: "asc",
292
- onChange: this.handleOrderDirChange,
293
- inline: true
294
- },
295
- T`Ascending`
296
- ),
297
- R(
298
- ui.Radio,
299
- {
300
- value: this.props.segment.orderDir || "asc",
301
- radioValue: "desc",
302
- onChange: this.handleOrderDirChange,
303
- inline: true
304
- },
305
- T`Descending`
306
- )
307
- )
308
- : undefined
268
+ {this.props.segment.orderExpr ? (
269
+ <div>
270
+ <ui.Radio
271
+ value={this.props.segment.orderDir || "asc"}
272
+ radioValue="asc"
273
+ onChange={this.handleOrderDirChange}
274
+ inline={true}
275
+ >
276
+ {T`Ascending`}
277
+ </ui.Radio>
278
+ <ui.Radio
279
+ value={this.props.segment.orderDir || "asc"}
280
+ radioValue="desc"
281
+ onChange={this.handleOrderDirChange}
282
+ inline={true}
283
+ >
284
+ {T`Descending`}
285
+ </ui.Radio>
286
+ </div>
287
+ ) : undefined}
288
+ </ui.FormGroup>
309
289
  )
310
290
  }
311
291
 
312
292
  render() {
313
- return R(
314
- "div",
315
- null,
316
- this.renderMode(),
317
- this.state.mode ? this.renderLabel() : undefined,
318
- this.state.mode === "multiple" ? this.renderValueAxis() : undefined,
319
- this.state.mode ? this.renderFilter() : undefined,
320
- this.state.mode === "multiple" ? this.renderOrderExpr() : undefined,
321
- this.state.mode ? this.renderStyling() : undefined,
322
- this.state.mode ? this.renderBorders() : undefined
293
+ return (
294
+ <div>
295
+ {this.renderMode()}
296
+ {this.state.mode ? this.renderLabel() : undefined}
297
+ {this.state.mode === "multiple" ? this.renderValueAxis() : undefined}
298
+ {this.state.mode ? this.renderFilter() : undefined}
299
+ {this.state.mode === "multiple" ? this.renderOrderExpr() : undefined}
300
+ {this.state.mode ? this.renderStyling() : undefined}
301
+ {this.state.mode ? this.renderBorders() : undefined}
302
+ </div>
323
303
  )
324
304
  }
325
305
  }
@@ -335,21 +315,21 @@ class BorderComponent extends React.Component<BorderComponentProps> {
335
315
  render() {
336
316
  const value = this.props.value != null ? this.props.value : this.props.defaultValue
337
317
 
338
- return R(
339
- "span",
340
- null,
341
- <Radio inline value={value} radioValue={0} onChange={() => this.props.onChange(0)}>
342
- {T`None`}
343
- </Radio>,
344
- <Radio inline value={value} radioValue={1} onChange={() => this.props.onChange(1)}>
345
- {T`Light`}
346
- </Radio>,
347
- <Radio inline value={value} radioValue={2} onChange={() => this.props.onChange(2)}>
348
- {T`Medium`}
349
- </Radio>,
350
- <Radio inline value={value} radioValue={3} onChange={() => this.props.onChange(3)}>
351
- {T`Heavy`}
352
- </Radio>
318
+ return (
319
+ <span>
320
+ <Radio inline value={value} radioValue={0} onChange={() => this.props.onChange(0)}>
321
+ {T`None`}
322
+ </Radio>
323
+ <Radio inline value={value} radioValue={1} onChange={() => this.props.onChange(1)}>
324
+ {T`Light`}
325
+ </Radio>
326
+ <Radio inline value={value} radioValue={2} onChange={() => this.props.onChange(2)}>
327
+ {T`Medium`}
328
+ </Radio>
329
+ <Radio inline value={value} radioValue={3} onChange={() => this.props.onChange(3)}>
330
+ {T`Heavy`}
331
+ </Radio>
332
+ </span>
353
333
  )
354
334
  }
355
335
  }
@@ -1,6 +1,5 @@
1
1
  import _ from "lodash"
2
2
  import React from "react"
3
- const R = React.createElement
4
3
  import uuid from "uuid"
5
4
  import { default as produce } from "immer"
6
5
  import { original } from "immer"
@@ -15,6 +14,8 @@ import { JsonQLSelectQuery } from "@mwater/jsonql"
15
14
  import { Axis } from "../../../axes/Axis"
16
15
  import { JsonQLFilter } from "../../../JsonQLFilter"
17
16
  import { Image } from "@mwater/forms/lib/RotationAwareImageComponent"
17
+ import * as XLSX from "xlsx-js-style"
18
+ import Color from "color"
18
19
 
19
20
  export interface TableChartDesign {
20
21
  version?: number
@@ -448,4 +449,179 @@ export default class TableChart extends Chart {
448
449
  }
449
450
  })
450
451
  }
452
+
453
+ // Override to indicate this chart supports XLSX export
454
+ supportsXlsxExport(): boolean {
455
+ return true
456
+ }
457
+
458
+ // Creates a SheetJS workbook for the chart data
459
+ createXlsxWorkbook(design: TableChartDesign, schema: Schema, dataSource: DataSource, data: any, locale: string): any {
460
+ const exprUtils = new ExprUtils(schema)
461
+ const axisBuilder = new AxisBuilder({ schema })
462
+ const workbook = XLSX.utils.book_new()
463
+
464
+ // Create array for headers
465
+ const headers = design.columns.map(column => column.headerText || exprUtils.summarizeExpr(column.textAxis?.expr || null, locale))
466
+
467
+ // Create arrays for data
468
+ const rows = data.main.map((record: any) => {
469
+ return design.columns.map((column: any, columnIndex: number) => {
470
+ const value = record[`c${columnIndex}`]
471
+ if (value == null) {
472
+ return ""
473
+ }
474
+
475
+ const exprType = exprUtils.getExprType(column.textAxis?.expr)
476
+
477
+ // Handle images as URLs
478
+ if (exprType === "image" && value) {
479
+ return dataSource.getImageUrl(value.id)
480
+ }
481
+
482
+ if (exprType === "imagelist" && value) {
483
+ return value.map((img: Image) => dataSource.getImageUrl(img.id)).join(", ")
484
+ }
485
+
486
+ // Handle dates properly for Excel
487
+ if (exprType === "date" && value) {
488
+ // Convert date string to JavaScript Date object
489
+ const date = new Date(value)
490
+ // Return a date that Excel can properly handle
491
+ return date
492
+ }
493
+
494
+ // Handle datetime properly for Excel
495
+ if (exprType === "datetime" && value) {
496
+ // Convert datetime string to JavaScript Date object
497
+ const date = new Date(value)
498
+ // Return a date that Excel can properly handle
499
+ return date
500
+ }
501
+
502
+ return exprUtils.stringifyExprLiteral(column.textAxis?.expr, value, locale)
503
+ })
504
+ })
505
+
506
+ // Add summary row if exists
507
+ if (data.summary) {
508
+ const summaryRow = design.columns.map((column: any, columnIndex: number) => {
509
+ if (data.summary[`c${columnIndex}`] != null) {
510
+ return data.summary[`c${columnIndex}`]
511
+ }
512
+ return ""
513
+ })
514
+ rows.push(summaryRow)
515
+ }
516
+
517
+ // Create worksheet from data
518
+ const worksheet = XLSX.utils.aoa_to_sheet([headers, ...rows])
519
+
520
+ // Set column widths based on content
521
+ const colWidths = headers.map((header, colIndex) => {
522
+ // Start with header width
523
+ let maxWidth = header.length
524
+
525
+ // Check data rows
526
+ rows.forEach((row: any[]) => {
527
+ const cellValue = row[colIndex]
528
+ if (cellValue) {
529
+ maxWidth = Math.max(maxWidth, String(cellValue).length)
530
+ }
531
+ })
532
+
533
+ // Add some padding and cap at 50 characters
534
+ return Math.min(maxWidth + 2, 50)
535
+ })
536
+
537
+ worksheet['!cols'] = colWidths.map(width => ({ wch: width }))
538
+
539
+ // Apply cell styles and background colors
540
+ const range = XLSX.utils.decode_range(worksheet['!ref']!)
541
+
542
+ for (let rowIndex = 0; rowIndex <= range.e.r; rowIndex++) {
543
+ for (let colIndex = 0; colIndex <= range.e.c; colIndex++) {
544
+ const cellAddress = XLSX.utils.encode_cell({ r: rowIndex, c: colIndex })
545
+ const cell = worksheet[cellAddress]
546
+
547
+ // Skip empty cells
548
+ if (!cell) continue
549
+
550
+ // Initialize style object if needed
551
+ if (!cell.s) cell.s = {}
552
+
553
+ // Apply header styles
554
+ if (rowIndex === 0) {
555
+ cell.s = {
556
+ ...cell.s,
557
+ font: { bold: true },
558
+ alignment: { horizontal: "center" },
559
+ border: {
560
+ bottom: { style: "thin" }
561
+ }
562
+ }
563
+ }
564
+
565
+ // Apply background colors for data cells
566
+ if (rowIndex > 0 && rowIndex <= data.main.length && colIndex < design.columns.length) {
567
+ const record = data.main[rowIndex - 1]
568
+ const column = design.columns[colIndex]
569
+
570
+ // Check if this column has a background color axis and the bc property exists
571
+ if (column?.backgroundColorAxis && record[`bc${colIndex}`] !== undefined) {
572
+ // Use the Color library to handle the color value safely
573
+ try {
574
+ // Call getValueColor to get the actual color
575
+ const axisBuilder = new AxisBuilder({ schema })
576
+ const bgColor = axisBuilder.getValueColor(column.backgroundColorAxis, record[`bc${colIndex}`])
577
+
578
+ if (bgColor) {
579
+ const color = Color(bgColor)
580
+ const hex = color.hex().substring(1) // Remove #
581
+
582
+ // Apply the background color
583
+ cell.s.fill = {
584
+ patternType: "solid",
585
+ fgColor: { rgb: hex },
586
+ bgColor: { rgb: hex }
587
+ }
588
+
589
+ // Adjust text color based on background lightness
590
+ const lightness = color.luminosity()
591
+ cell.s.font = {
592
+ ...cell.s.font,
593
+ color: { rgb: lightness < 0.3 ? "CCCCCC" : "000000" }
594
+ }
595
+ }
596
+ } catch (e) {
597
+ // Silently ignore color errors
598
+ console.error("Error applying background color", e)
599
+ }
600
+ }
601
+ }
602
+
603
+ // Apply summary row styling
604
+ if (data.summary && rowIndex === rows.length) {
605
+ cell.s = {
606
+ ...cell.s,
607
+ font: { bold: true },
608
+ border: {
609
+ top: { style: "thin" }
610
+ }
611
+ }
612
+ }
613
+ }
614
+ }
615
+
616
+ console.log(worksheet)
617
+
618
+ // Add the worksheet to the workbook
619
+ XLSX.utils.book_append_sheet(workbook, worksheet, "Data")
620
+
621
+ // Convert workbook to blob
622
+ const workbookBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })
623
+ const blob = new Blob([workbookBuffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })
624
+
625
+ return blob
626
+ }
451
627
  }