@mwater/visualization 5.2.0 → 5.3.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 (254) hide show
  1. package/lib/ColorComponent.d.ts +10 -11
  2. package/lib/ColorComponent.js +78 -29
  3. package/lib/ColorSchemeFactory.d.ts +13 -2
  4. package/lib/ColorSchemeFactory.js +7 -5
  5. package/lib/CustomColorsContext.d.ts +6 -0
  6. package/lib/CustomColorsContext.js +6 -0
  7. package/lib/FiltersDesignerComponent.d.ts +1 -4
  8. package/lib/FiltersDesignerComponent.js +2 -3
  9. package/lib/LocaleContextInjector.d.ts +5 -11
  10. package/lib/LocaleContextInjector.js +4 -12
  11. package/lib/MWaterAddRelatedFormComponent.js +3 -3
  12. package/lib/MWaterAddRelatedIndicatorComponent.d.ts +1 -4
  13. package/lib/MWaterAddRelatedIndicatorComponent.js +6 -6
  14. package/lib/MWaterCompleteTableSelectComponent.d.ts +5 -16
  15. package/lib/MWaterCompleteTableSelectComponent.js +36 -36
  16. package/lib/MWaterContextComponent.d.ts +4 -6
  17. package/lib/MWaterContextComponent.js +4 -13
  18. package/lib/MWaterLoaderComponent.d.ts +5 -3
  19. package/lib/MWaterLoaderComponent.js +2 -1
  20. package/lib/MWaterTableSelectComponent.d.ts +1 -4
  21. package/lib/MWaterTableSelectComponent.js +10 -12
  22. package/lib/UIComponents.d.ts +2 -2
  23. package/lib/UIComponents.js +4 -12
  24. package/lib/axes/AxisBuilder.d.ts +7 -4
  25. package/lib/axes/AxisBuilder.js +3 -1
  26. package/lib/axes/AxisComponent.d.ts +2 -5
  27. package/lib/axes/AxisComponent.js +1 -2
  28. package/lib/axes/ColorPaletteCollectionComponent.d.ts +5 -12
  29. package/lib/axes/ColorPaletteCollectionComponent.js +67 -36
  30. package/lib/dashboards/DashboardComponent.d.ts +4 -12
  31. package/lib/dashboards/DashboardComponent.js +18 -38
  32. package/lib/dashboards/DashboardDesign.d.ts +3 -3
  33. package/lib/dashboards/DashboardUpgrader.js +36 -1
  34. package/lib/dashboards/DashboardViewComponent.d.ts +5 -34
  35. package/lib/dashboards/DashboardViewComponent.js +109 -132
  36. package/lib/dashboards/FontStyleEditor.d.ts +8 -0
  37. package/lib/dashboards/FontStyleEditor.js +130 -0
  38. package/lib/dashboards/LayoutOptionsComponent.d.ts +0 -1
  39. package/lib/dashboards/LayoutOptionsComponent.js +211 -42
  40. package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -2
  41. package/lib/dashboards/ServerDashboardDataSource.js +52 -33
  42. package/lib/dashboards/WidgetComponent.d.ts +3 -3
  43. package/lib/dashboards/WidgetComponent.js +3 -6
  44. package/lib/dashboards/WidgetDataSourcePrioritizer.d.ts +20 -0
  45. package/lib/dashboards/WidgetDataSourcePrioritizer.js +72 -0
  46. package/lib/dashboards/layoutOptions.d.ts +83 -0
  47. package/lib/dashboards/layoutOptions.js +436 -10
  48. package/lib/datagrids/DatagridDesign.d.ts +7 -6
  49. package/lib/datagrids/ServerDatagridDataSource.d.ts +7 -6
  50. package/lib/datagrids/ServerDatagridDataSource.js +87 -33
  51. package/lib/demo.js +3 -3
  52. package/lib/index.css +5 -0
  53. package/lib/index.d.ts +1 -1
  54. package/lib/index.js +0 -1
  55. package/lib/layouts/LayoutManager.d.ts +33 -29
  56. package/lib/layouts/LayoutManager.js +2 -8
  57. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +26 -57
  58. package/lib/layouts/blocks/BlocksDisplayComponent.js +122 -205
  59. package/lib/layouts/blocks/BlocksLayoutManager.d.ts +6 -22
  60. package/lib/layouts/blocks/BlocksLayoutManager.js +5 -14
  61. package/lib/layouts/blocks/HorizontalBlockComponent.d.ts +5 -4
  62. package/lib/layouts/blocks/HorizontalBlockComponent.js +5 -5
  63. package/lib/mWaterLoader.d.ts +2 -0
  64. package/lib/mWaterLoader.js +2 -1
  65. package/lib/maps/AddLayerComponent.d.ts +6 -8
  66. package/lib/maps/AddLayerComponent.js +6 -6
  67. package/lib/maps/BingLayer.js +10 -20
  68. package/lib/maps/BufferLayer.js +2 -1
  69. package/lib/maps/ChoroplethLayer.js +2 -1
  70. package/lib/maps/DirectMapDataSource.d.ts +5 -2
  71. package/lib/maps/DirectMapDataSource.js +2 -1
  72. package/lib/maps/EditPopupComponent.js +2 -1
  73. package/lib/maps/MapComponent.d.ts +1 -4
  74. package/lib/maps/MapComponent.js +3 -3
  75. package/lib/maps/MarkersLayer.js +30 -25
  76. package/lib/maps/RasterMapViewComponent.d.ts +1 -4
  77. package/lib/maps/RasterMapViewComponent.js +3 -3
  78. package/lib/maps/ServerMapDataSource.d.ts +2 -3
  79. package/lib/maps/ServerMapDataSource.js +5 -5
  80. package/lib/maps/VectorMapViewComponent.js +2 -1
  81. package/lib/maps/mapSymbols.js +2 -0
  82. package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
  83. package/lib/maps/vectorMaps.js +61 -55
  84. package/lib/quickfilter/QuickfiltersComponent.d.ts +1 -4
  85. package/lib/quickfilter/QuickfiltersComponent.js +3 -3
  86. package/lib/richtext/DropdownPaletteItem.d.ts +32 -0
  87. package/lib/richtext/DropdownPaletteItem.js +82 -0
  88. package/lib/richtext/FontColorPaletteItem.d.ts +1 -5
  89. package/lib/richtext/FontColorPaletteItem.js +32 -27
  90. package/lib/richtext/ItemsHtmlConverter.js +12 -3
  91. package/lib/richtext/RichTextComponent.d.ts +26 -52
  92. package/lib/richtext/RichTextComponent.js +166 -128
  93. package/lib/valueFormatter.js +6 -1
  94. package/lib/wellknown.d.ts +5 -0
  95. package/lib/wellknown.js +288 -0
  96. package/lib/widgets/DropdownWidgetComponent.d.ts +8 -25
  97. package/lib/widgets/DropdownWidgetComponent.js +48 -25
  98. package/lib/widgets/IFrameWidgetComponent.d.ts +1 -2
  99. package/lib/widgets/ImageWidgetComponent.d.ts +2 -3
  100. package/lib/widgets/MapWidget.d.ts +2 -0
  101. package/lib/widgets/MapWidget.js +2 -1
  102. package/lib/widgets/TOCWidget.js +2 -1
  103. package/lib/widgets/Widget.d.ts +2 -0
  104. package/lib/widgets/WidgetDataSource.d.ts +3 -1
  105. package/lib/widgets/charts/Chart.d.ts +0 -1
  106. package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
  107. package/lib/widgets/charts/ChartViewComponent.js +11 -3
  108. package/lib/widgets/charts/ChartWidget.d.ts +1 -62
  109. package/lib/widgets/charts/ChartWidget.js +4 -183
  110. package/lib/widgets/charts/ChartWidgetComponent.d.ts +51 -0
  111. package/lib/widgets/charts/ChartWidgetComponent.js +167 -0
  112. package/lib/widgets/charts/calendar/CalendarChartViewComponent.d.ts +1 -4
  113. package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +4 -4
  114. package/lib/widgets/charts/layered/LayeredChart.d.ts +5 -10
  115. package/lib/widgets/charts/layered/LayeredChart.js +6 -7
  116. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +4 -2
  117. package/lib/widgets/charts/layered/LayeredChartCompiler.js +46 -32
  118. package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +4 -0
  119. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +3 -0
  120. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +21 -3
  121. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +1 -2
  122. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -1
  123. package/lib/widgets/charts/layered/LayeredChartViewComponent.d.ts +1 -4
  124. package/lib/widgets/charts/layered/LayeredChartViewComponent.js +89 -38
  125. package/lib/widgets/charts/pivot/IntersectionDesignerComponent.d.ts +5 -112
  126. package/lib/widgets/charts/pivot/IntersectionDesignerComponent.js +122 -166
  127. package/lib/widgets/charts/pivot/PivotChart.d.ts +6 -0
  128. package/lib/widgets/charts/pivot/PivotChart.js +47 -17
  129. package/lib/widgets/charts/pivot/PivotChartDesign.d.ts +11 -0
  130. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +1 -1
  131. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +1 -1
  132. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +2 -2
  133. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +20 -36
  134. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +0 -1
  135. package/lib/widgets/charts/pivot/PivotChartQueryBuilder.d.ts +23 -2
  136. package/lib/widgets/charts/pivot/PivotChartQueryBuilder.js +215 -181
  137. package/lib/widgets/charts/pivot/PivotChartUtils.d.ts +2 -2
  138. package/lib/widgets/charts/pivot/PivotChartViewComponent.d.ts +9 -28
  139. package/lib/widgets/charts/pivot/PivotChartViewComponent.js +20 -60
  140. package/lib/widgets/charts/table/TableChart.js +8 -4
  141. package/lib/widgets/charts/table/TableChartDesignerComponent.js +3 -3
  142. package/lib/widgets/charts/table/TableChartViewComponent.js +11 -11
  143. package/lib/widgets/text/TextComponent.d.ts +5 -12
  144. package/lib/widgets/text/TextComponent.js +19 -39
  145. package/lib/widgets/text/TextWidget.d.ts +2 -1
  146. package/lib/widgets/text/TextWidget.js +5 -1
  147. package/lib/widgets/text/TextWidgetComponent.d.ts +15 -3
  148. package/lib/widgets/text/TextWidgetComponent.js +76 -19
  149. package/lib/widgets/text/TextWidgetDesign.d.ts +13 -1
  150. package/lib/widgets/text/TextWidgetDesign.js +6 -0
  151. package/package.json +4 -4
  152. package/src/ColorComponent.tsx +177 -0
  153. package/src/ColorSchemeFactory.ts +12 -6
  154. package/src/CustomColorsContext.tsx +9 -0
  155. package/src/FiltersDesignerComponent.ts +3 -4
  156. package/src/LocaleContextInjector.tsx +14 -13
  157. package/src/MWaterAddRelatedFormComponent.ts +3 -3
  158. package/src/MWaterAddRelatedIndicatorComponent.ts +6 -6
  159. package/src/MWaterCompleteTableSelectComponent.tsx +36 -36
  160. package/src/MWaterContextComponent.tsx +8 -17
  161. package/src/MWaterLoaderComponent.ts +6 -3
  162. package/src/MWaterTableSelectComponent.tsx +11 -12
  163. package/src/{UIComponents.ts → UIComponents.tsx} +7 -15
  164. package/src/axes/AxisBuilder.ts +7 -5
  165. package/src/axes/AxisComponent.ts +3 -4
  166. package/src/axes/{ColorPaletteCollectionComponent.ts → ColorPaletteCollectionComponent.tsx} +87 -61
  167. package/src/dashboards/DashboardComponent.tsx +71 -107
  168. package/src/dashboards/DashboardDesign.ts +3 -3
  169. package/src/dashboards/DashboardUpgrader.ts +41 -1
  170. package/src/dashboards/DashboardViewComponent.tsx +313 -0
  171. package/src/dashboards/FontStyleEditor.tsx +166 -0
  172. package/src/dashboards/LayoutOptionsComponent.tsx +380 -75
  173. package/src/dashboards/ServerDashboardDataSource.ts +52 -33
  174. package/src/dashboards/WidgetComponent.tsx +6 -12
  175. package/src/dashboards/WidgetDataSourcePrioritizer.ts +82 -0
  176. package/src/dashboards/layoutOptions.tsx +581 -0
  177. package/src/datagrids/DatagridDesign.ts +8 -3
  178. package/src/datagrids/ServerDatagridDataSource.ts +106 -43
  179. package/src/demo.ts +3 -3
  180. package/src/index.css +5 -0
  181. package/src/index.ts +1 -1
  182. package/src/layouts/LayoutManager.ts +44 -42
  183. package/src/layouts/blocks/BlocksDisplayComponent.tsx +498 -0
  184. package/src/layouts/blocks/BlocksLayoutManager.ts +6 -15
  185. package/src/layouts/blocks/HorizontalBlockComponent.ts +9 -8
  186. package/src/mWaterLoader.ts +4 -1
  187. package/src/maps/AddLayerComponent.ts +9 -9
  188. package/src/maps/BingLayer.ts +16 -26
  189. package/src/maps/BufferLayer.ts +2 -1
  190. package/src/maps/ChoroplethLayer.ts +2 -1
  191. package/src/maps/DirectMapDataSource.ts +12 -3
  192. package/src/maps/EditPopupComponent.ts +2 -1
  193. package/src/maps/MapComponent.ts +3 -3
  194. package/src/maps/MarkersLayer.ts +38 -41
  195. package/src/maps/RasterMapViewComponent.ts +3 -3
  196. package/src/maps/ServerMapDataSource.ts +7 -7
  197. package/src/maps/VectorMapViewComponent.tsx +2 -1
  198. package/src/maps/mapSymbols.ts +2 -0
  199. package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
  200. package/src/maps/vectorMaps.tsx +79 -74
  201. package/src/quickfilter/QuickfiltersComponent.ts +3 -3
  202. package/src/richtext/DropdownPaletteItem.tsx +144 -0
  203. package/src/richtext/FontColorPaletteItem.tsx +160 -0
  204. package/src/richtext/ItemsHtmlConverter.ts +15 -5
  205. package/src/richtext/RichTextComponent.tsx +274 -232
  206. package/src/valueFormatter.ts +5 -1
  207. package/src/wellknown.ts +286 -0
  208. package/src/widgets/DropdownWidgetComponent.tsx +75 -0
  209. package/src/widgets/MapWidget.ts +5 -2
  210. package/src/widgets/TOCWidget.ts +2 -1
  211. package/src/widgets/Widget.ts +3 -0
  212. package/src/widgets/WidgetDataSource.ts +3 -1
  213. package/src/widgets/charts/Chart.ts +1 -1
  214. package/src/widgets/charts/ChartViewComponent.ts +16 -3
  215. package/src/widgets/charts/ChartWidget.ts +3 -275
  216. package/src/widgets/charts/ChartWidgetComponent.tsx +281 -0
  217. package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +4 -4
  218. package/src/widgets/charts/layered/LayeredChart.ts +4 -6
  219. package/src/widgets/charts/layered/LayeredChartCompiler.ts +80 -63
  220. package/src/widgets/charts/layered/LayeredChartDesign.ts +7 -1
  221. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +43 -10
  222. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +6 -6
  223. package/src/widgets/charts/layered/LayeredChartViewComponent.ts +140 -88
  224. package/src/widgets/charts/pivot/IntersectionDesignerComponent.tsx +305 -221
  225. package/src/widgets/charts/pivot/PivotChart.ts +56 -18
  226. package/src/widgets/charts/pivot/PivotChartDesign.ts +12 -0
  227. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +4 -3
  228. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +39 -76
  229. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +0 -1
  230. package/src/widgets/charts/pivot/PivotChartQueryBuilder.ts +230 -189
  231. package/src/widgets/charts/pivot/PivotChartUtils.ts +4 -4
  232. package/src/widgets/charts/pivot/{PivotChartViewComponent.ts → PivotChartViewComponent.tsx} +86 -89
  233. package/src/widgets/charts/table/TableChart.ts +8 -4
  234. package/src/widgets/charts/table/TableChartDesignerComponent.ts +4 -4
  235. package/src/widgets/charts/table/TableChartViewComponent.ts +13 -14
  236. package/src/widgets/text/TextComponent.tsx +47 -49
  237. package/src/widgets/text/TextWidget.ts +8 -3
  238. package/src/widgets/text/TextWidgetComponent.tsx +249 -0
  239. package/src/widgets/text/TextWidgetDesign.ts +22 -1
  240. package/src/ColorComponent.ts +0 -117
  241. package/src/dashboards/DashboardViewComponent.ts +0 -303
  242. package/src/dashboards/layoutOptions.ts +0 -40
  243. package/src/layout-styles.css +0 -263
  244. package/src/layouts/blocks/BlocksDisplayComponent.ts +0 -461
  245. package/src/layouts/grid/GridLayoutComponent.ts +0 -67
  246. package/src/layouts/grid/GridLayoutManager.ts +0 -185
  247. package/src/layouts/grid/LegoLayoutEngine.ts +0 -142
  248. package/src/layouts/grid/PaletteItemComponent.ts +0 -28
  249. package/src/layouts/grid/README.md +0 -14
  250. package/src/layouts/grid/WidgetContainerComponent.ts +0 -420
  251. package/src/richtext/FontColorPaletteItem.ts +0 -172
  252. package/src/richtext/FontSizePaletteItem.ts +0 -110
  253. package/src/widgets/DropdownWidgetComponent.ts +0 -78
  254. package/src/widgets/text/TextWidgetComponent.ts +0 -120
@@ -4,7 +4,7 @@ import { ExprUtils } from "@mwater/expressions"
4
4
  import AxisBuilder from "../../../axes/AxisBuilder"
5
5
  import { injectTableAlias } from "@mwater/expressions"
6
6
  import * as PivotChartUtils from "./PivotChartUtils"
7
- import { PivotChartDesign } from "./PivotChartDesign"
7
+ import { PivotChartDesign, PivotChartSegment } from "./PivotChartDesign"
8
8
  import { JsonQLFilter } from "../../../JsonQLFilter"
9
9
  import { JsonQLExpr, JsonQLQuery, JsonQLSelectQuery } from "@mwater/jsonql"
10
10
  import { Axis } from "../../../axes/Axis"
@@ -40,7 +40,6 @@ export default class PivotChartQueryBuilder {
40
40
  // extraFilters: array of filters to apply. Each is { table: table id, jsonql: jsonql condition with {alias} for tableAlias. }
41
41
  // Queries are indexed by intersection id, as one query is made for each intersection
42
42
  createQueries(design: PivotChartDesign, extraFilters: JsonQLFilter[]) {
43
- let filter, intersectionId, relevantFilters, whereClauses
44
43
  const exprCompiler = new ExprCompiler(this.schema)
45
44
 
46
45
  const queries: { [intersectionId: string]: JsonQLQuery } = {}
@@ -48,226 +47,268 @@ export default class PivotChartQueryBuilder {
48
47
  // For each intersection
49
48
  for (let rowPath of PivotChartUtils.getSegmentPaths(design.rows)) {
50
49
  for (let columnPath of PivotChartUtils.getSegmentPaths(design.columns)) {
51
- // Get id of intersection
52
- var i
53
- intersectionId = PivotChartUtils.getIntersectionId(rowPath, columnPath)
54
-
55
- // Get intersection
56
- const intersection = design.intersections[intersectionId]
57
-
58
- // Create shell of query
59
- const query: JsonQLSelectQuery = {
60
- type: "query",
61
- selects: [],
62
- from: exprCompiler.compileTable(design.table, "main"),
63
- limit: 10000,
64
- groupBy: []
50
+ const query = this.createIntersectionQuery(design, rowPath, columnPath, extraFilters)
51
+ if (query) {
52
+ queries[PivotChartUtils.getIntersectionId(rowPath, columnPath)] = query
65
53
  }
54
+ }
55
+ }
66
56
 
67
- // Filters to add (not yet compiled)
68
- const filters = []
57
+ // For each segment
58
+ const segments = PivotChartUtils.getAllSegments(design.rows).concat(PivotChartUtils.getAllSegments(design.columns))
59
+ for (const segment of segments) {
60
+ if (segment.orderExpr) {
61
+ const query = this.createSegmentOrderQuery(design, segment, extraFilters)
62
+ if (query) {
63
+ queries[segment.id] = query
64
+ }
65
+ }
66
+ }
69
67
 
70
- const compileSegmentAxis = (axis: Axis | null | undefined): JsonQLExpr => {
71
- // Get axis type
72
- const axisType = this.axisBuilder.getAxisType(axis)
68
+ return queries
69
+ }
73
70
 
74
- // Enumset needs to be unwrapped
75
- if (axisType === "enumset") {
76
- // Use to_jsonb(x) to convert to jsonb then jsonb_array_elements_text to convert to unnested array
77
- return {
78
- type: "op",
79
- op: "jsonb_array_elements_text",
80
- exprs: [
81
- {
82
- type: "op",
83
- op: "to_jsonb",
84
- exprs: [this.axisBuilder.compileAxis({ axis, tableAlias: "main" })]
85
- }
86
- ]
87
- }
88
- } else {
89
- return this.axisBuilder.compileAxis({ axis, tableAlias: "main" })
90
- }
91
- }
71
+ /**
72
+ * Create a query for an intersection. Query has columns:
73
+ * value: value of the cell (aggregate)
74
+ * r0: row segment value (if present)
75
+ * r1: inner row segment value (if present)
76
+ * ...
77
+ * c0: column segment value (if present)
78
+ * c1: inner column segment value (if present)
79
+ * ...
80
+ * bc: background color of the cell (if present)
81
+ * bcc0: background color condition 0 of the cell (if present)
82
+ * bcc1: background color condition 1 of the cell (if present)
83
+ * ...
84
+ * @param design - Design of the chart
85
+ * @param rowPath - Row path
86
+ * @param columnPath - Column path
87
+ * @param extraFilters - Extra filters
88
+ * @returns Query for the intersection
89
+ */
90
+ createIntersectionQuery(design: PivotChartDesign, rowPath: PivotChartSegment[], columnPath: PivotChartSegment[], extraFilters: JsonQLFilter[]) {
91
+ const exprCompiler = new ExprCompiler(this.schema)
92
92
 
93
- // Add segments
94
- for (i = 0; i < rowPath.length; i++) {
95
- const rowSegment = rowPath[i]
96
- query.selects.push({
97
- type: "select",
98
- expr: compileSegmentAxis(rowSegment.valueAxis),
99
- alias: `r${i}`
100
- })
101
- query.groupBy!.push(i + 1)
102
- if (rowSegment.filter) {
103
- filters.push(rowSegment.filter)
104
- }
105
- }
93
+ // Get id of intersection
94
+ const intersectionId = PivotChartUtils.getIntersectionId(rowPath, columnPath)
106
95
 
107
- for (i = 0; i < columnPath.length; i++) {
108
- const columnSegment = columnPath[i]
109
- query.selects.push({
110
- type: "select",
111
- expr: compileSegmentAxis(columnSegment.valueAxis),
112
- alias: `c${i}`
113
- })
114
- query.groupBy!.push(i + 1 + rowPath.length)
115
- if (columnSegment.filter) {
116
- filters.push(columnSegment.filter)
117
- }
118
- }
96
+ // Get intersection
97
+ const intersection = design.intersections[intersectionId]
119
98
 
120
- // Add value
121
- query.selects.push({
122
- type: "select",
123
- expr: this.axisBuilder.compileAxis({ axis: intersection?.valueAxis, tableAlias: "main" }),
124
- alias: "value"
125
- })
126
- if (intersection?.filter) {
127
- filters.push(intersection.filter)
128
- }
99
+ // Get intersection table
100
+ const intersectionTable = intersection.tableOverride || design.table
129
101
 
130
- // Add background color
131
- if (intersection?.backgroundColorAxis) {
132
- query.selects.push({
133
- type: "select",
134
- expr: this.axisBuilder.compileAxis({ axis: intersection?.backgroundColorAxis, tableAlias: "main" }),
135
- alias: "bc"
136
- })
137
- }
102
+ // Create shell of query
103
+ const query: JsonQLSelectQuery = {
104
+ type: "query",
105
+ selects: [],
106
+ from: exprCompiler.compileTable(intersectionTable, "main"),
107
+ limit: 10000,
108
+ groupBy: []
109
+ }
138
110
 
139
- // Add background color conditions
140
- const iterable = intersection.backgroundColorConditions || []
141
- for (i = 0; i < iterable.length; i++) {
142
- const backgroundColorCondition = iterable[i]
143
- query.selects.push({
144
- type: "select",
145
- expr: exprCompiler.compileExpr({ expr: backgroundColorCondition.condition ?? null, tableAlias: "main" }),
146
- alias: `bcc${i}`
147
- })
148
- }
111
+ // Filters to add (not yet compiled)
112
+ const filters = []
149
113
 
150
- // If all selects are null, don't create query
151
- if (_.all(query.selects, (select) => select.expr == null)) {
152
- continue
153
- }
114
+ const compileSegmentAxis = (segment: PivotChartSegment): JsonQLExpr => {
115
+ // Get axis type
116
+ const axisType = this.axisBuilder.getAxisType(segment.valueAxis!)
154
117
 
155
- // Add where
156
- whereClauses = []
157
- if (design.filter) {
158
- whereClauses.push(exprCompiler.compileExpr({ expr: design.filter, tableAlias: "main" }))
118
+ // Get axis (which can be overridden)
119
+ const axis = intersection.tableOverride ? (intersection.segmentValueAxisOverrides || {})[segment.id] : segment.valueAxis
120
+
121
+ // Enumset needs to be unwrapped
122
+ if (axisType === "enumset") {
123
+ // Use to_jsonb(x) to convert to jsonb then jsonb_array_elements_text to convert to unnested array
124
+ return {
125
+ type: "op",
126
+ op: "jsonb_array_elements_text",
127
+ exprs: [
128
+ {
129
+ type: "op",
130
+ op: "to_jsonb",
131
+ exprs: [this.axisBuilder.compileAxis({ axis, tableAlias: "main" })]
132
+ }
133
+ ]
159
134
  }
135
+ } else {
136
+ return this.axisBuilder.compileAxis({ axis, tableAlias: "main" })
137
+ }
138
+ }
139
+
140
+ // Add segments
141
+ for (let i = 0; i < rowPath.length; i++) {
142
+ const rowSegment = rowPath[i]
143
+ query.selects.push({
144
+ type: "select",
145
+ expr: compileSegmentAxis(rowSegment),
146
+ alias: `r${i}`
147
+ })
148
+ query.groupBy!.push(i + 1)
149
+ if (rowSegment.filter) {
150
+ filters.push(rowSegment.filter)
151
+ }
152
+ }
160
153
 
161
- // Add other filters
162
- whereClauses = whereClauses.concat(
163
- _.map(filters, (filter) => exprCompiler.compileExpr({ expr: filter, tableAlias: "main" }))
164
- )
154
+ for (let i = 0; i < columnPath.length; i++) {
155
+ const columnSegment = columnPath[i]
156
+ query.selects.push({
157
+ type: "select",
158
+ expr: compileSegmentAxis(columnSegment),
159
+ alias: `c${i}`
160
+ })
161
+ query.groupBy!.push(i + 1 + rowPath.length)
162
+ if (columnSegment.filter) {
163
+ filters.push(columnSegment.filter)
164
+ }
165
+ }
165
166
 
166
- // Add filters
167
- if (extraFilters && extraFilters.length > 0) {
168
- // Get relevant filters
169
- relevantFilters = _.where(extraFilters, { table: design.table })
167
+ // Add value
168
+ query.selects.push({
169
+ type: "select",
170
+ expr: this.axisBuilder.compileAxis({ axis: intersection?.valueAxis, tableAlias: "main" }),
171
+ alias: "value"
172
+ })
173
+ if (intersection?.filter) {
174
+ filters.push(intersection.filter)
175
+ }
170
176
 
171
- // Add filters
172
- for (filter of relevantFilters) {
173
- whereClauses.push(injectTableAlias(filter.jsonql, "main"))
174
- }
175
- }
177
+ // Add background color
178
+ if (intersection?.backgroundColorAxis) {
179
+ query.selects.push({
180
+ type: "select",
181
+ expr: this.axisBuilder.compileAxis({ axis: intersection?.backgroundColorAxis, tableAlias: "main" }),
182
+ alias: "bc"
183
+ })
184
+ }
185
+
186
+ // Add background color conditions
187
+ const iterable = intersection.backgroundColorConditions || []
188
+ for (let i = 0; i < iterable.length; i++) {
189
+ const backgroundColorCondition = iterable[i]
190
+ query.selects.push({
191
+ type: "select",
192
+ expr: exprCompiler.compileExpr({ expr: backgroundColorCondition.condition ?? null, tableAlias: "main" }),
193
+ alias: `bcc${i}`
194
+ })
195
+ }
176
196
 
177
- whereClauses = _.compact(whereClauses)
197
+ // If all selects are null, don't create query
198
+ if (_.all(query.selects, (select) => select.expr == null)) {
199
+ return null
200
+ }
178
201
 
179
- if (whereClauses.length === 1) {
180
- query.where = whereClauses[0]
181
- } else if (whereClauses.length > 1) {
182
- query.where = { type: "op", op: "and", exprs: whereClauses }
183
- }
202
+ // Add where
203
+ let whereClauses = []
204
+ if (design.filter) {
205
+ whereClauses.push(exprCompiler.compileExpr({ expr: design.filter, tableAlias: "main" }))
206
+ }
207
+
208
+ // Add other filters
209
+ whereClauses = whereClauses.concat(
210
+ _.map(filters, (filter) => exprCompiler.compileExpr({ expr: filter, tableAlias: "main" }))
211
+ )
184
212
 
185
- queries[intersectionId] = query
213
+ // Add filters
214
+ if (extraFilters && extraFilters.length > 0) {
215
+ // Get relevant filters
216
+ const relevantFilters = _.where(extraFilters, { table: intersection.tableOverride ?? design.table })
217
+
218
+ // Add filters
219
+ for (const filter of relevantFilters) {
220
+ whereClauses.push(injectTableAlias(filter.jsonql, "main"))
186
221
  }
187
222
  }
188
223
 
189
- // For each segment
190
- const segments = PivotChartUtils.getAllSegments(design.rows).concat(PivotChartUtils.getAllSegments(design.columns))
191
- for (let segment of segments) {
192
- if (segment.orderExpr) {
193
- // Create where which includes the segments filter (if present) and the "or" of all intersections that are present
194
- whereClauses = []
224
+ whereClauses = _.compact(whereClauses)
195
225
 
196
- if (segment.filter) {
197
- whereClauses.push(exprCompiler.compileExpr({ expr: segment.filter, tableAlias: "main" }))
198
- }
226
+ if (whereClauses.length === 1) {
227
+ query.where = whereClauses[0]
228
+ } else if (whereClauses.length > 1) {
229
+ query.where = { type: "op", op: "and", exprs: whereClauses }
230
+ }
199
231
 
200
- // Get all intersection filters
201
- const intersectionFilters: Expr[] = []
202
- for (intersectionId of _.keys(design.intersections)) {
203
- if (intersectionId.includes(segment.id)) {
204
- ;({ filter } = design.intersections[intersectionId])
205
- if (filter) {
206
- intersectionFilters.push(filter)
207
- } else {
208
- // If intersection has no filter, still needs to "or" with true
209
- intersectionFilters.push({ type: "literal", valueType: "boolean", value: true })
210
- }
211
- }
212
- }
232
+ return query
233
+ }
213
234
 
214
- if (intersectionFilters.length > 0) {
215
- whereClauses.push({
216
- type: "op",
217
- op: "or",
218
- exprs: _.map(intersectionFilters, (filter) =>
219
- exprCompiler.compileExpr({ expr: filter, tableAlias: "main" })
220
- )
221
- })
222
- }
235
+ createSegmentOrderQuery(design: PivotChartDesign, segment: PivotChartSegment, extraFilters: JsonQLFilter[]) {
236
+ const exprCompiler = new ExprCompiler(this.schema)
223
237
 
224
- if (design.filter) {
225
- whereClauses.push(exprCompiler.compileExpr({ expr: design.filter, tableAlias: "main" }))
226
- }
238
+ // Create where which includes the segments filter (if present) and the "or" of all intersections that are present
239
+ let whereClauses = []
227
240
 
228
- // Add extra filters
229
- if (extraFilters && extraFilters.length > 0) {
230
- // Get relevant filters
231
- relevantFilters = _.where(extraFilters, { table: design.table })
241
+ if (segment.filter) {
242
+ whereClauses.push(exprCompiler.compileExpr({ expr: segment.filter, tableAlias: "main" }))
243
+ }
232
244
 
233
- // Add filters
234
- for (filter of relevantFilters) {
235
- whereClauses.push(injectTableAlias(filter.jsonql, "main"))
236
- }
245
+ // Get all intersection filters
246
+ const intersectionFilters: Expr[] = []
247
+ for (const intersectionId of _.keys(design.intersections)) {
248
+ if (intersectionId.includes(segment.id)) {
249
+ const { filter } = design.intersections[intersectionId]
250
+ if (filter) {
251
+ intersectionFilters.push(filter)
252
+ } else {
253
+ // If intersection has no filter, still needs to "or" with true
254
+ intersectionFilters.push({ type: "literal", valueType: "boolean", value: true })
237
255
  }
256
+ }
257
+ }
238
258
 
239
- whereClauses = _.compact(whereClauses)
259
+ if (intersectionFilters.length > 0) {
260
+ whereClauses.push({
261
+ type: "op",
262
+ op: "or",
263
+ exprs: _.map(intersectionFilters, (filter) =>
264
+ exprCompiler.compileExpr({ expr: filter, tableAlias: "main" })
265
+ )
266
+ })
267
+ }
240
268
 
241
- let where = null
242
- if (whereClauses.length === 1) {
243
- where = whereClauses[0]
244
- } else if (whereClauses.length > 1) {
245
- where = { type: "op", op: "and", exprs: whereClauses }
246
- }
269
+ if (design.filter) {
270
+ whereClauses.push(exprCompiler.compileExpr({ expr: design.filter, tableAlias: "main" }))
271
+ }
247
272
 
248
- // Create query to get ordering
249
- queries[segment.id] = {
250
- type: "query",
251
- selects: [
252
- {
253
- type: "select",
254
- expr: this.axisBuilder.compileAxis({ axis: segment.valueAxis!, tableAlias: "main" }),
255
- alias: "value"
256
- }
257
- ],
258
- from: exprCompiler.compileTable(design.table, "main"),
259
- where,
260
- groupBy: [1],
261
- orderBy: [
262
- {
263
- expr: exprCompiler.compileExpr({ expr: segment.orderExpr, tableAlias: "main" }),
264
- direction: segment.orderDir || "asc"
265
- }
266
- ]
267
- }
273
+ // Add extra filters
274
+ if (extraFilters && extraFilters.length > 0) {
275
+ // Get relevant filters
276
+ const relevantFilters = _.where(extraFilters, { table: design.table })
277
+
278
+ // Add filters
279
+ for (const filter of relevantFilters) {
280
+ whereClauses.push(injectTableAlias(filter.jsonql, "main"))
268
281
  }
269
282
  }
270
283
 
271
- return queries
284
+ whereClauses = _.compact(whereClauses)
285
+
286
+ let where = null
287
+ if (whereClauses.length === 1) {
288
+ where = whereClauses[0]
289
+ } else if (whereClauses.length > 1) {
290
+ where = { type: "op", op: "and", exprs: whereClauses }
291
+ }
292
+
293
+ // Create query to get ordering
294
+ return {
295
+ type: "query",
296
+ selects: [
297
+ {
298
+ type: "select",
299
+ expr: this.axisBuilder.compileAxis({ axis: segment.valueAxis!, tableAlias: "main" }),
300
+ alias: "value"
301
+ }
302
+ ],
303
+ from: exprCompiler.compileTable(design.table, "main"),
304
+ where,
305
+ groupBy: [1],
306
+ orderBy: [
307
+ {
308
+ expr: exprCompiler.compileExpr({ expr: segment.orderExpr!, tableAlias: "main" }),
309
+ direction: segment.orderDir || "asc"
310
+ }
311
+ ]
312
+ } as JsonQLSelectQuery
272
313
  }
273
314
  }
@@ -36,7 +36,7 @@ export function getAllSegments(segments: PivotChartSegment[]): PivotChartSegment
36
36
  }
37
37
 
38
38
  // Gets the id of the intersection of the two paths
39
- export function getIntersectionId(rowPath: any, columnPath: any) {
39
+ export function getIntersectionId(rowPath: PivotChartSegment[], columnPath: PivotChartSegment[]) {
40
40
  return `${_.pluck(rowPath, "id").join(",")}:${_.pluck(columnPath, "id").join(",")}`
41
41
  }
42
42
 
@@ -45,7 +45,7 @@ export function findSegment(segments: PivotChartSegment[], id: any): PivotChartS
45
45
  }
46
46
 
47
47
  // Determine if can summarize segment (if segment before has a value axis and has no children)
48
- export function canSummarizeSegment(segments: any, id: any) {
48
+ export function canSummarizeSegment(segments: PivotChartSegment[], id: string) {
49
49
  const prevSegment = findPreviousSegment(segments, id)
50
50
  if (prevSegment && prevSegment.valueAxis && !prevSegment.children?.[0]) {
51
51
  return true
@@ -117,7 +117,7 @@ export function summarizeSegment(design: PivotChartDesign, id: any, label: any)
117
117
  summaryIntersection = _.cloneDeep(prevIntersection)
118
118
 
119
119
  // Find new row path (since has no children, will be only one)
120
- const summaryRowPath = _.find(getSegmentPaths(design.rows), (path) => path.includes(rowSegment))
120
+ const summaryRowPath = _.find(getSegmentPaths(design.rows), (path) => path.includes(rowSegment))!
121
121
  design.intersections[getIntersectionId(summaryRowPath, columnPath)] = summaryIntersection
122
122
  }
123
123
  }
@@ -142,7 +142,7 @@ export function summarizeSegment(design: PivotChartDesign, id: any, label: any)
142
142
  // Find new column path (since has no children, will be only one)
143
143
  const summaryColumnPath = _.find(getSegmentPaths(design.columns), (path) =>
144
144
  path.includes(columnSegment)
145
- )
145
+ )!
146
146
  design.intersections[getIntersectionId(rowPath, summaryColumnPath)] = summaryIntersection
147
147
  }
148
148
  }