@mwater/visualization 5.4.4 → 5.5.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 (136) hide show
  1. package/.storybook/head.html +0 -1
  2. package/lib/MWaterContextComponent.js +1 -1
  3. package/lib/MWaterLoaderComponent.d.ts +2 -2
  4. package/lib/dashboards/DashboardComponent.js +2 -1
  5. package/lib/dashboards/LayoutOptionsComponent.js +18 -11
  6. package/lib/dashboards/ServerDashboardDataSource.d.ts +10 -1
  7. package/lib/dashboards/ServerDashboardDataSource.js +29 -0
  8. package/lib/dashboards/layoutOptions.d.ts +5 -1
  9. package/lib/datagrids/DatagridComponent.js +1 -1
  10. package/lib/datagrids/ExprCellComponent.d.ts +1 -0
  11. package/lib/datagrids/ExprCellComponent.js +22 -20
  12. package/lib/maps/BufferLayer.d.ts +18 -0
  13. package/lib/maps/BufferLayer.js +24 -14
  14. package/lib/maps/ChoroplethLayer.d.ts +18 -0
  15. package/lib/maps/ChoroplethLayer.js +34 -25
  16. package/lib/maps/ChoroplethLayerDesign.d.ts +3 -2
  17. package/lib/maps/ChoroplethLayerDesigner.d.ts +11 -1
  18. package/lib/maps/DirectMapDataSource.js +17 -0
  19. package/lib/maps/EditHoverOver.d.ts +1 -1
  20. package/lib/maps/EditHoverOver.js +62 -33
  21. package/lib/maps/HoverContent.d.ts +10 -5
  22. package/lib/maps/HoverContent.js +6 -35
  23. package/lib/maps/Layer.d.ts +37 -0
  24. package/lib/maps/Layer.js +30 -4
  25. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  26. package/lib/maps/MWaterServerLayer.js +6 -6
  27. package/lib/maps/MapLayerDataSource.d.ts +9 -0
  28. package/lib/maps/MapUtils.d.ts +19 -1
  29. package/lib/maps/MapUtils.js +71 -1
  30. package/lib/maps/MarkersLayer.d.ts +18 -0
  31. package/lib/maps/MarkersLayer.js +24 -24
  32. package/lib/maps/MarkersLayerDesignerComponent.d.ts +14 -1
  33. package/lib/maps/RasterMapViewComponent.js +1 -1
  34. package/lib/maps/ServerMapDataSource.d.ts +9 -0
  35. package/lib/maps/ServerMapDataSource.js +29 -0
  36. package/lib/maps/VectorMapViewComponent.js +6 -6
  37. package/lib/maps/maps.d.ts +4 -2
  38. package/lib/mwater_table_selection/FormsListComponent.d.ts +33 -0
  39. package/lib/mwater_table_selection/FormsListComponent.js +141 -0
  40. package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +47 -0
  41. package/lib/mwater_table_selection/IndicatorsListComponent.js +182 -0
  42. package/lib/mwater_table_selection/IssuesListComponent.d.ts +29 -0
  43. package/lib/mwater_table_selection/IssuesListComponent.js +123 -0
  44. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.d.ts +20 -0
  45. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.js +157 -0
  46. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.d.ts +17 -0
  47. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.js +79 -0
  48. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +37 -0
  49. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +275 -0
  50. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.d.ts +17 -0
  51. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.js +94 -0
  52. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.d.ts +17 -0
  53. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.js +80 -0
  54. package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +32 -0
  55. package/lib/mwater_table_selection/MWaterTableSelectComponent.js +158 -0
  56. package/lib/quickfilter/Quickfilter.d.ts +2 -0
  57. package/lib/quickfilter/QuickfiltersDesignComponent.js +18 -10
  58. package/lib/widgets/charts/Chart.d.ts +11 -0
  59. package/lib/widgets/charts/Chart.js +15 -0
  60. package/lib/widgets/charts/ChartWidgetComponent.d.ts +1 -0
  61. package/lib/widgets/charts/ChartWidgetComponent.js +27 -1
  62. package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +1 -1
  63. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +1 -1
  64. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +5 -12
  65. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +43 -57
  66. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +113 -110
  67. package/lib/widgets/charts/layered/LayeredChartUtils.d.ts +2 -1
  68. package/lib/widgets/charts/layered/LayeredChartUtils.js +0 -2
  69. package/lib/widgets/charts/pivot/PivotChart.d.ts +2 -0
  70. package/lib/widgets/charts/pivot/PivotChart.js +156 -0
  71. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +5 -20
  72. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +31 -61
  73. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +4 -0
  74. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +4 -2
  75. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.d.ts +5 -44
  76. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +38 -63
  77. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +7 -68
  78. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +58 -106
  79. package/lib/widgets/charts/table/TableChart.d.ts +2 -0
  80. package/lib/widgets/charts/table/TableChart.js +172 -1
  81. package/lib/widgets/charts/table/TableChartDesignerComponent.d.ts +7 -17
  82. package/lib/widgets/charts/table/TableChartDesignerComponent.js +79 -95
  83. package/lib/widgets/charts/table/TableChartViewComponent.d.ts +1 -7
  84. package/lib/widgets/charts/table/TableChartViewComponent.js +19 -27
  85. package/package.json +3 -8
  86. package/src/MWaterContextComponent.tsx +1 -1
  87. package/src/MWaterLoaderComponent.ts +1 -1
  88. package/src/dashboards/DashboardComponent.tsx +2 -1
  89. package/src/dashboards/LayoutOptionsComponent.tsx +22 -10
  90. package/src/dashboards/ServerDashboardDataSource.ts +36 -1
  91. package/src/dashboards/layoutOptions.tsx +5 -1
  92. package/src/datagrids/DatagridComponent.tsx +1 -1
  93. package/src/datagrids/ExprCellComponent.tsx +23 -20
  94. package/src/maps/BufferLayer.ts +35 -20
  95. package/src/maps/ChoroplethLayer.ts +51 -33
  96. package/src/maps/ChoroplethLayerDesign.ts +3 -2
  97. package/src/maps/ChoroplethLayerDesigner.tsx +2 -2
  98. package/src/maps/DirectMapDataSource.ts +21 -1
  99. package/src/maps/EditHoverOver.tsx +91 -51
  100. package/src/maps/HoverContent.tsx +16 -47
  101. package/src/maps/Layer.ts +42 -4
  102. package/src/maps/MWaterServerLayer.ts +6 -6
  103. package/src/maps/MapLayerDataSource.ts +8 -0
  104. package/src/maps/MapUtils.ts +70 -3
  105. package/src/maps/MarkersLayer.ts +34 -24
  106. package/src/maps/RasterMapViewComponent.ts +1 -1
  107. package/src/maps/ServerMapDataSource.ts +35 -0
  108. package/src/maps/VectorMapViewComponent.tsx +6 -6
  109. package/src/maps/maps.ts +4 -2
  110. package/src/mwater_table_selection/FormsListComponent.tsx +188 -0
  111. package/src/mwater_table_selection/IndicatorsListComponent.tsx +283 -0
  112. package/src/mwater_table_selection/IssuesListComponent.tsx +167 -0
  113. package/src/mwater_table_selection/MWaterAccountingSystemListComponent.tsx +225 -0
  114. package/src/{MWaterAssetSystemsListComponent.tsx → mwater_table_selection/MWaterAssetSystemsListComponent.tsx} +2 -2
  115. package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +377 -0
  116. package/src/{MWaterCustomTablesetListComponent.tsx → mwater_table_selection/MWaterCustomTablesetListComponent.tsx} +1 -1
  117. package/src/{MWaterMetricsTableListComponent.tsx → mwater_table_selection/MWaterMetricsTableListComponent.tsx} +1 -1
  118. package/src/{MWaterTableSelectComponent.tsx → mwater_table_selection/MWaterTableSelectComponent.tsx} +83 -86
  119. package/src/quickfilter/Quickfilter.ts +3 -0
  120. package/src/quickfilter/QuickfiltersDesignComponent.tsx +19 -14
  121. package/src/widgets/charts/Chart.ts +17 -0
  122. package/src/widgets/charts/ChartWidgetComponent.tsx +36 -1
  123. package/src/widgets/charts/layered/LayeredChartDesign.ts +1 -1
  124. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +23 -24
  125. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +260 -211
  126. package/src/widgets/charts/layered/LayeredChartUtils.ts +7 -7
  127. package/src/widgets/charts/pivot/PivotChart.ts +191 -0
  128. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +124 -129
  129. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +4 -2
  130. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +120 -149
  131. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +178 -198
  132. package/src/widgets/charts/table/TableChart.ts +177 -1
  133. package/src/widgets/charts/table/TableChartDesignerComponent.tsx +422 -0
  134. package/src/widgets/charts/table/{TableChartViewComponent.ts → TableChartViewComponent.tsx} +65 -60
  135. package/src/MWaterCompleteTableSelectComponent.tsx +0 -975
  136. package/src/widgets/charts/table/TableChartDesignerComponent.ts +0 -441
@@ -28,7 +28,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const lodash_1 = __importDefault(require("lodash"));
30
30
  const react_1 = __importDefault(require("react"));
31
- const R = react_1.default.createElement;
32
31
  const uuid_1 = __importDefault(require("uuid"));
33
32
  const expressions_1 = require("@mwater/expressions");
34
33
  const AxisBuilder_1 = __importDefault(require("../../../axes/AxisBuilder"));
@@ -79,22 +78,18 @@ class TableChartDesignerComponent extends react_1.default.Component {
79
78
  this.updateDesign({ columns });
80
79
  };
81
80
  renderTable() {
82
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("i", { className: "fa fa-database" }), " ", T `Data Source`), ": ", R(expressions_ui_3.TableSelectComponent, {
83
- schema: this.props.schema,
84
- value: this.props.design.table,
85
- onChange: this.handleTableChange,
86
- filter: this.props.design.filter,
87
- onFilterChange: this.handleFilterChange
88
- }));
81
+ return (react_1.default.createElement("div", { className: "mb-3" },
82
+ react_1.default.createElement("label", { className: "text-muted" },
83
+ react_1.default.createElement("i", { className: "fa fa-database" }),
84
+ " ",
85
+ T `Data Source`),
86
+ ": ",
87
+ react_1.default.createElement(expressions_ui_3.TableSelectComponent, { schema: this.props.schema, value: this.props.design.table, onChange: this.handleTableChange, filter: this.props.design.filter, onFilterChange: this.handleFilterChange })));
89
88
  }
90
89
  renderTitle() {
91
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Title`), R("input", {
92
- type: "text",
93
- className: "form-control form-control-sm",
94
- value: this.props.design.titleText,
95
- onChange: this.handleTitleTextChange,
96
- placeholder: T `Untitled`
97
- }));
90
+ return (react_1.default.createElement("div", { className: "mb-3" },
91
+ react_1.default.createElement("label", { className: "text-muted" }, T `Title`),
92
+ react_1.default.createElement("input", { type: "text", className: "form-control form-control-sm", value: this.props.design.titleText, onChange: this.handleTitleTextChange, placeholder: T `Untitled` })));
98
93
  }
99
94
  renderColumn = (column, index, connectDragSource, connectDragPreview, connectDropTarget) => {
100
95
  const style = {
@@ -102,15 +97,8 @@ class TableChartDesignerComponent extends react_1.default.Component {
102
97
  paddingTop: 10,
103
98
  paddingBottom: 10
104
99
  };
105
- return connectDragPreview(connectDropTarget(R("div", { key: index, style }, react_1.default.createElement(TableChartColumnDesignerComponent, {
106
- design: this.props.design,
107
- schema: this.props.schema,
108
- dataSource: this.props.dataSource,
109
- index,
110
- onChange: this.handleColumnChange.bind(null, index),
111
- onRemove: this.handleRemoveColumn.bind(null, index),
112
- connectDragSource
113
- }))));
100
+ return connectDragPreview(connectDropTarget(react_1.default.createElement("div", { key: index, style: style },
101
+ react_1.default.createElement(TableChartColumnDesignerComponent, { design: this.props.design, schema: this.props.schema, dataSource: this.props.dataSource, index: index, onChange: this.handleColumnChange.bind(null, index), onRemove: this.handleRemoveColumn.bind(null, index), connectDragSource: connectDragSource }))));
114
102
  };
115
103
  handleReorder = (map) => {
116
104
  return this.updateDesign({ columns: map });
@@ -119,12 +107,12 @@ class TableChartDesignerComponent extends react_1.default.Component {
119
107
  if (!this.props.design.table) {
120
108
  return;
121
109
  }
122
- return R("div", null, R(ReorderableListComponent_1.default, {
123
- items: this.props.design.columns,
124
- onReorder: this.handleReorder,
125
- renderItem: this.renderColumn,
126
- getItemId: (item) => item.id
127
- }), R("button", { className: "btn btn-secondary btn-sm", type: "button", onClick: this.handleAddColumn }, R("span", { className: "fas fa-plus" }), " ", T `Add Column`));
110
+ return (react_1.default.createElement("div", null,
111
+ react_1.default.createElement(ReorderableListComponent_1.default, { items: this.props.design.columns, onReorder: this.handleReorder, renderItem: this.renderColumn, getItemId: (item) => item.id }),
112
+ react_1.default.createElement("button", { className: "btn btn-secondary btn-sm", type: "button", onClick: this.handleAddColumn },
113
+ react_1.default.createElement("span", { className: "fas fa-plus" }),
114
+ " ",
115
+ T `Add Column`)));
128
116
  }
129
117
  // return R 'div', className: "form-group",
130
118
  // _.map(@props.design.columns, (column, i) => @renderColumn(i))
@@ -134,41 +122,47 @@ class TableChartDesignerComponent extends react_1.default.Component {
134
122
  if (!this.props.design.table) {
135
123
  return null;
136
124
  }
137
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("span", { className: "fas fa-sort-amount-down" }), " ", T `Ordering`), R("div", { style: { marginLeft: 8 } }, react_1.default.createElement(OrderingsComponent_1.default, {
138
- schema: this.props.schema,
139
- dataSource: this.props.dataSource,
140
- orderings: this.props.design.orderings,
141
- onOrderingsChange: this.handleOrderingsChange,
142
- table: this.props.design.table
143
- })));
125
+ return (react_1.default.createElement("div", { className: "mb-3" },
126
+ react_1.default.createElement("label", { className: "text-muted" },
127
+ react_1.default.createElement("span", { className: "fas fa-sort-amount-down" }),
128
+ " ",
129
+ T `Ordering`),
130
+ react_1.default.createElement("div", { style: { marginLeft: 8 } },
131
+ react_1.default.createElement(OrderingsComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, orderings: this.props.design.orderings, onOrderingsChange: this.handleOrderingsChange, table: this.props.design.table }))));
144
132
  }
145
133
  renderFilter() {
146
134
  // If no table, hide
147
135
  if (!this.props.design.table) {
148
136
  return null;
149
137
  }
150
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("span", { className: "fas fa-filter" }), " ", T `Filters`), R("div", { style: { marginLeft: 8 } }, react_1.default.createElement(expressions_ui_2.FilterExprComponent, {
151
- schema: this.props.schema,
152
- dataSource: this.props.dataSource,
153
- onChange: this.handleFilterChange,
154
- table: this.props.design.table,
155
- value: this.props.design.filter
156
- })));
138
+ return (react_1.default.createElement("div", { className: "mb-3" },
139
+ react_1.default.createElement("label", { className: "text-muted" },
140
+ react_1.default.createElement("span", { className: "fas fa-filter" }),
141
+ " ",
142
+ T `Filters`),
143
+ react_1.default.createElement("div", { style: { marginLeft: 8 } },
144
+ react_1.default.createElement(expressions_ui_2.FilterExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, onChange: this.handleFilterChange, table: this.props.design.table, value: this.props.design.filter }))));
157
145
  }
158
146
  renderLimit() {
159
147
  // If no table, hide
160
148
  if (!this.props.design.table) {
161
149
  return null;
162
150
  }
163
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Maximum Number of Rows (up to 1000)`), R("div", { style: { marginLeft: 8 } }, R(ui.NumberInput, {
164
- value: this.props.design.limit,
165
- onChange: this.handleLimitChange,
166
- decimal: false,
167
- placeholder: "1000"
168
- })));
151
+ return (react_1.default.createElement("div", { className: "mb-3" },
152
+ react_1.default.createElement("label", { className: "text-muted" }, T `Maximum Number of Rows (up to 1000)`),
153
+ react_1.default.createElement("div", { style: { marginLeft: 8 } },
154
+ react_1.default.createElement(ui.NumberInput, { value: this.props.design.limit, onChange: this.handleLimitChange, decimal: false, placeholder: "1000" }))));
169
155
  }
170
156
  render() {
171
- return R("div", null, this.renderTable(), this.renderColumns(), this.props.design.table ? R("hr") : undefined, this.renderOrderings(), this.renderFilter(), this.renderLimit(), R("hr"), this.renderTitle());
157
+ return (react_1.default.createElement("div", null,
158
+ this.renderTable(),
159
+ this.renderColumns(),
160
+ this.props.design.table ? react_1.default.createElement("hr", null) : undefined,
161
+ this.renderOrderings(),
162
+ this.renderFilter(),
163
+ this.renderLimit(),
164
+ react_1.default.createElement("hr", null),
165
+ this.renderTitle()));
172
166
  }
173
167
  }
174
168
  exports.default = TableChartDesignerComponent;
@@ -197,21 +191,18 @@ class TableChartColumnDesignerComponent extends react_1.default.Component {
197
191
  };
198
192
  renderRemove() {
199
193
  if (this.props.design.columns.length > 1) {
200
- return R("button", { className: "btn btn-sm btn-link float-end", type: "button", onClick: this.props.onRemove }, R("span", { className: "fas fa-times" }));
194
+ return (react_1.default.createElement("button", { className: "btn btn-sm btn-link float-end", type: "button", onClick: this.props.onRemove },
195
+ react_1.default.createElement("span", { className: "fas fa-times" })));
201
196
  }
202
197
  return null;
203
198
  }
204
199
  renderExpr() {
205
200
  const column = this.props.design.columns[this.props.index];
206
201
  const title = T `Value`;
207
- return R("div", null, R("label", { className: "text-muted" }, title), ": ", react_1.default.createElement(expressions_ui_1.ExprComponent, {
208
- schema: this.props.schema,
209
- dataSource: this.props.dataSource,
210
- table: this.props.design.table,
211
- value: column.textAxis ? column.textAxis.expr : null,
212
- onChange: this.handleExprChange,
213
- aggrStatuses: ["literal", "individual", "aggregate"]
214
- }));
202
+ return (react_1.default.createElement("div", null,
203
+ react_1.default.createElement("label", { className: "text-muted" }, title),
204
+ ": ",
205
+ react_1.default.createElement(expressions_ui_1.ExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, table: this.props.design.table, value: column.textAxis ? column.textAxis.expr : null, onChange: this.handleExprChange, aggrStatuses: ["literal", "individual", "aggregate"] })));
215
206
  }
216
207
  renderFormat() {
217
208
  const column = this.props.design.columns[this.props.index];
@@ -225,25 +216,19 @@ class TableChartColumnDesignerComponent extends react_1.default.Component {
225
216
  if (!formats) {
226
217
  return null;
227
218
  }
228
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Format`), ": ", R("select", {
229
- value: column.format != null ? column.format : (0, valueFormatter_2.getDefaultFormat)(exprType),
230
- className: "form-select",
231
- style: { width: "auto", display: "inline-block" },
232
- onChange: this.handleFormatChange
233
- }, lodash_1.default.map(formats, (format) => R("option", { key: format.value, value: format.value }, format.label))));
219
+ return (react_1.default.createElement("div", { className: "mb-3" },
220
+ react_1.default.createElement("label", { className: "text-muted" }, T `Format`),
221
+ ": ",
222
+ react_1.default.createElement("select", { value: column.format != null ? column.format : (0, valueFormatter_2.getDefaultFormat)(exprType), className: "form-select", style: { width: "auto", display: "inline-block" }, onChange: this.handleFormatChange }, lodash_1.default.map(formats, (format) => react_1.default.createElement("option", { key: format.value, value: format.value }, format.label)))));
234
223
  }
235
224
  renderHeader() {
236
225
  const column = this.props.design.columns[this.props.index];
237
226
  const axisBuilder = new AxisBuilder_1.default({ schema: this.props.schema });
238
227
  const placeholder = column.textAxis ? axisBuilder.summarizeAxis(column.textAxis ?? null, this.context) : "";
239
- return R("div", null, R("label", { className: "text-muted" }, T `Header`), ": ", R("input", {
240
- type: "text",
241
- className: "form-control form-control-sm",
242
- style: { display: "inline-block", width: "15em" },
243
- value: column.headerText,
244
- onChange: this.handleHeaderTextChange,
245
- placeholder
246
- }));
228
+ return (react_1.default.createElement("div", null,
229
+ react_1.default.createElement("label", { className: "text-muted" }, T `Header`),
230
+ ": ",
231
+ react_1.default.createElement("input", { type: "text", className: "form-control form-control-sm", style: { display: "inline-block", width: "15em" }, value: column.headerText, onChange: this.handleHeaderTextChange, placeholder: placeholder })));
247
232
  }
248
233
  renderSummarize() {
249
234
  const column = this.props.design.columns[this.props.index];
@@ -252,31 +237,21 @@ class TableChartColumnDesignerComponent extends react_1.default.Component {
252
237
  if (!exprType || exprType !== 'number') {
253
238
  return null;
254
239
  }
255
- return R('div', null, R(ui.Checkbox, { value: column.summarize, inline: true, onChange: (summarize) => this.updateColumn({ summarize, summaryType: column.summaryType ?? 'sum' }) }, T `Summarize`), column.summarize ?
256
- R('div', null, R("label", { className: "text-muted" }, T `Summary Type`), ": ", R(ui.Select, {
257
- inline: true,
258
- value: column.summaryType,
259
- onChange: (summaryType) => this.updateColumn({ summaryType }),
260
- options: [{ value: 'avg', label: T `Average` }, { value: 'sum', label: T `Sum` }, { value: 'min', label: T `Minimum` }, { value: 'max', label: T `Maximum` }]
261
- })) : undefined);
240
+ return (react_1.default.createElement("div", null,
241
+ react_1.default.createElement(ui.Checkbox, { value: column.summarize, inline: true, onChange: (summarize) => this.updateColumn({ summarize, summaryType: column.summaryType ?? 'sum' }) }, T `Summarize`),
242
+ column.summarize ?
243
+ react_1.default.createElement("div", null,
244
+ react_1.default.createElement("label", { className: "text-muted" }, T `Summary Type`),
245
+ ": ",
246
+ react_1.default.createElement(ui.Select, { inline: true, value: column.summaryType, onChange: (summaryType) => this.updateColumn({ summaryType }), options: [{ value: 'avg', label: T `Average` }, { value: 'sum', label: T `Sum` }, { value: 'min', label: T `Minimum` }, { value: 'max', label: T `Maximum` }] }))
247
+ : undefined));
262
248
  }
263
249
  renderBackgroundColorAxis() {
264
250
  const column = this.props.design.columns[this.props.index];
265
251
  if (!column.textAxis)
266
252
  return null;
267
- return R(ui.CollapsibleSection, {
268
- label: T `Background color by data`,
269
- labelMuted: true
270
- }, R(AxisComponent_1.default, {
271
- schema: this.props.schema,
272
- dataSource: this.props.dataSource,
273
- table: this.props.design.table,
274
- types: ["enum", "text", "boolean", "date"],
275
- value: column.backgroundColorAxis,
276
- onChange: (backgroundColorAxis) => this.updateColumn({ backgroundColorAxis }),
277
- showColorMap: true,
278
- aggrNeed: "optional"
279
- }));
253
+ return (react_1.default.createElement(ui.CollapsibleSection, { label: T `Background color by data`, labelMuted: true },
254
+ react_1.default.createElement(AxisComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, table: this.props.design.table, types: ["enum", "text", "boolean", "date"], value: column.backgroundColorAxis, onChange: (backgroundColorAxis) => this.updateColumn({ backgroundColorAxis }), showColorMap: true, aggrNeed: "optional" })));
280
255
  }
281
256
  render() {
282
257
  const iconStyle = {
@@ -286,6 +261,15 @@ class TableChartColumnDesignerComponent extends react_1.default.Component {
286
261
  fontSize: 12,
287
262
  height: 20
288
263
  };
289
- return R("div", null, this.props.connectDragSource(R("i", { className: "fa fa-bars", style: iconStyle })), this.renderRemove(), R("label", null, T `Column ${this.props.index + 1}`), R("div", { style: { marginLeft: 5 } }, this.renderExpr(), this.renderFormat(), this.renderHeader(), this.renderSummarize(), this.renderBackgroundColorAxis()));
264
+ return (react_1.default.createElement("div", null,
265
+ this.props.connectDragSource(react_1.default.createElement("i", { className: "fa fa-bars", style: iconStyle })),
266
+ this.renderRemove(),
267
+ react_1.default.createElement("label", null, T `Column ${this.props.index + 1}`),
268
+ react_1.default.createElement("div", { style: { marginLeft: 5 } },
269
+ this.renderExpr(),
270
+ this.renderFormat(),
271
+ this.renderHeader(),
272
+ this.renderSummarize(),
273
+ this.renderBackgroundColorAxis())));
290
274
  }
291
275
  }
@@ -19,11 +19,5 @@ export interface TableChartViewComponentProps {
19
19
  }
20
20
  export default class TableChartViewComponent extends React.Component<TableChartViewComponentProps> {
21
21
  shouldComponentUpdate(prevProps: TableChartViewComponentProps): boolean;
22
- render(): React.DetailedReactHTMLElement<{
23
- style: {
24
- width: number | undefined;
25
- height: number | undefined;
26
- };
27
- className: string;
28
- }, HTMLElement>;
22
+ render(): React.JSX.Element;
29
23
  }
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const lodash_1 = __importDefault(require("lodash"));
7
7
  const react_1 = __importDefault(require("react"));
8
- const R = react_1.default.createElement;
9
8
  const react_linkify_1 = __importDefault(require("react-linkify"));
10
9
  const AxisBuilder_1 = __importDefault(require("../../../axes/AxisBuilder"));
11
10
  const expressions_1 = require("@mwater/expressions");
@@ -21,14 +20,9 @@ class TableChartViewComponent extends react_1.default.Component {
21
20
  width: this.props.width,
22
21
  height: this.props.height
23
22
  };
24
- return R("div", { style, className: "overflow-auto-except-print" }, R("div", { style: { fontWeight: "bold", textAlign: "center" } }, this.props.design.titleText), R(TableContentsComponent, {
25
- columns: this.props.design.columns,
26
- table: this.props.design.table,
27
- data: this.props.data,
28
- schema: this.props.schema,
29
- dataSource: this.props.dataSource,
30
- onRowClick: this.props.onRowClick
31
- }));
23
+ return (react_1.default.createElement("div", { style: style, className: "overflow-auto-except-print" },
24
+ react_1.default.createElement("div", { style: { fontWeight: "bold", textAlign: "center" } }, this.props.design.titleText),
25
+ react_1.default.createElement(TableContentsComponent, { columns: this.props.design.columns, table: this.props.design.table, data: this.props.data, schema: this.props.schema, dataSource: this.props.dataSource, onRowClick: this.props.onRowClick })));
32
26
  }
33
27
  }
34
28
  exports.default = TableChartViewComponent;
@@ -90,19 +84,13 @@ class TableContentsComponent extends react_1.default.Component {
90
84
  const column = this.props.columns[index];
91
85
  //(this.state.sort?.direction === 'asc' ? "":"")
92
86
  const text = column.headerText ?? (column.textAxis ? axisBuilder.summarizeAxis(column.textAxis, this.context) : "");
93
- return R("th", {
94
- key: index,
95
- style: { cursor: "pointer" },
96
- onClick: () => this.handleSort(index)
97
- }, text, this.state.sort?.column === index
98
- ? R("span", {
99
- style: { marginLeft: 10 },
100
- className: `fa ${this.state.sort?.direction === "asc" ? "fa-sort-asc" : "fa-sort-desc"}`
101
- })
102
- : undefined);
87
+ return (react_1.default.createElement("th", { key: index, style: { cursor: "pointer" }, onClick: () => this.handleSort(index) },
88
+ text,
89
+ this.state.sort?.column === index ? (react_1.default.createElement("span", { style: { marginLeft: 10 }, className: `fa ${this.state.sort?.direction === "asc" ? "fa-sort-asc" : "fa-sort-desc"}` })) : undefined));
103
90
  }
104
91
  renderHeader() {
105
- return R("thead", { key: "head" }, R("tr", { key: "head" }, lodash_1.default.map(this.props.columns, (column, i) => this.renderHeaderCell(i))));
92
+ return (react_1.default.createElement("thead", { key: "head" },
93
+ react_1.default.createElement("tr", { key: "head" }, lodash_1.default.map(this.props.columns, (column, i) => this.renderHeaderCell(i)))));
106
94
  }
107
95
  renderFooterCell(index) {
108
96
  const exprUtils = new expressions_1.ExprUtils(this.props.schema);
@@ -120,11 +108,12 @@ class TableContentsComponent extends react_1.default.Component {
120
108
  if (!this.props.data.summary) {
121
109
  return null;
122
110
  }
123
- return R("tfoot", { key: "foot" }, R("tr", { key: "foot" }, lodash_1.default.map(this.props.columns, (column, i) => R("th", { key: i }, this.renderFooterCell(i)))));
111
+ return (react_1.default.createElement("tfoot", { key: "foot" },
112
+ react_1.default.createElement("tr", { key: "foot" }, lodash_1.default.map(this.props.columns, (column, i) => react_1.default.createElement("th", { key: i }, this.renderFooterCell(i))))));
124
113
  }
125
114
  renderImage(id) {
126
115
  const url = this.props.dataSource.getImageUrl(id);
127
- return R("a", { href: url, onClick: (e) => { e.stopPropagation(); }, key: id, target: "_blank", style: { paddingLeft: 5, paddingRight: 5 } }, T `Image`);
116
+ return (react_1.default.createElement("a", { href: url, onClick: (e) => { e.stopPropagation(); }, key: id, target: "_blank", style: { paddingLeft: 5, paddingRight: 5 } }, T `Image`));
128
117
  }
129
118
  renderCell(rowIndex, columnIndex) {
130
119
  const axisBuilder = new AxisBuilder_1.default({ schema: this.props.schema });
@@ -163,7 +152,7 @@ class TableContentsComponent extends react_1.default.Component {
163
152
  switch (exprType) {
164
153
  case "text":
165
154
  if (lodash_1.default.isString(value)) {
166
- node = R(react_linkify_1.default, { properties: { target: "_blank" } }, value);
155
+ node = react_1.default.createElement(react_linkify_1.default, { properties: { target: "_blank" } }, value);
167
156
  }
168
157
  break;
169
158
  case "number":
@@ -211,15 +200,18 @@ class TableContentsComponent extends react_1.default.Component {
211
200
  const lightness = 1 - (1 - c.luminosity()) * c.alpha();
212
201
  textColor = lightness < 0.3 ? "rgb(204,204,204)" : "inherit";
213
202
  }
214
- return R("td", { key: columnIndex, style: { backgroundColor, color: textColor } }, node);
203
+ return react_1.default.createElement("td", { key: columnIndex, style: { backgroundColor, color: textColor } }, node);
215
204
  }
216
205
  renderRow(index) {
217
- return R("tr", { key: index, onClick: this.handleRowClick.bind(null, index) }, lodash_1.default.map(this.props.columns, (column, i) => this.renderCell(index, i)));
206
+ return (react_1.default.createElement("tr", { key: index, onClick: this.handleRowClick.bind(null, index) }, lodash_1.default.map(this.props.columns, (column, i) => this.renderCell(index, i))));
218
207
  }
219
208
  renderBody() {
220
- return R("tbody", { key: "body" }, lodash_1.default.map(this.state.data, (row, i) => this.renderRow(i)));
209
+ return (react_1.default.createElement("tbody", { key: "body" }, lodash_1.default.map(this.state.data, (row, i) => this.renderRow(i))));
221
210
  }
222
211
  render() {
223
- return R("table", { className: "mwater-visualization-table", style: { marginBottom: 0 } }, this.renderHeader(), this.renderBody(), this.renderFooter());
212
+ return (react_1.default.createElement("table", { className: "mwater-visualization-table", style: { marginBottom: 0 } },
213
+ this.renderHeader(),
214
+ this.renderBody(),
215
+ this.renderFooter()));
224
216
  }
225
217
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mwater/visualization",
3
- "version": "5.4.4",
3
+ "version": "5.5.0",
4
4
  "description": "Visualization library",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -10,11 +10,6 @@
10
10
  "build": "rsync -av --exclude '*.ts' --exclude '*.tsx' src/ lib/ ; tsc -p tsconfig.build.json",
11
11
  "prepublish": "npm run build"
12
12
  },
13
- "husky": {
14
- "hooks": {
15
- "pre-commit": "npm test"
16
- }
17
- },
18
13
  "style": "lib/index.css",
19
14
  "author": "mWater",
20
15
  "license": "MIT",
@@ -75,7 +70,8 @@
75
70
  "shallowequal": "^0.2.2",
76
71
  "update-object": "^1.0.0",
77
72
  "utm": "^1.1.1",
78
- "uuid": "^3.4.0"
73
+ "uuid": "^3.4.0",
74
+ "xlsx-js-style": "^1.2.0"
79
75
  },
80
76
  "devDependencies": {
81
77
  "@kadira/storybook": "^2.21.0",
@@ -101,7 +97,6 @@
101
97
  "enzyme": "^3.11.0",
102
98
  "enzyme-adapter-react-16": "^1.15.5",
103
99
  "esbuild": "^0.8.34",
104
- "husky": "^1.0.0-rc.13",
105
100
  "ignore-styles": "^5.0.1",
106
101
  "jsdom": "^15.2.1",
107
102
  "react-addons-test-utils": "^0.14.0",
@@ -2,7 +2,7 @@ import _ from "lodash"
2
2
  import React, { createContext } from "react"
3
3
  const R = React.createElement
4
4
 
5
- import MWaterTableSelectComponent from "./MWaterTableSelectComponent"
5
+ import MWaterTableSelectComponent from "./mwater_table_selection/MWaterTableSelectComponent"
6
6
  import MWaterAddRelatedFormComponent from "./MWaterAddRelatedFormComponent"
7
7
  import MWaterAddRelatedIndicatorComponent from "./MWaterAddRelatedIndicatorComponent"
8
8
  import MWaterGlobalFiltersComponent from "./MWaterGlobalFiltersComponent"
@@ -24,7 +24,7 @@ export interface MWaterLoaderComponentProps {
24
24
  locales?: string[]
25
25
  /** Override default add layer component. See AddLayerComponent for details */
26
26
  addLayerElementFactory?: AddLayerElementFactory
27
- children: (error: any, config?: { schema: Schema; dataSource: DataSource }) => ReactElement<any>
27
+ children: (error: any, config?: { schema: Schema; dataSource: DataSource }) => ReactElement<any> | null
28
28
  /** Custom error formatter that returns React node or string, gets passed the error response from server */
29
29
  errorFormatter?: (data: any, defaultError: string) => string
30
30
  /** Origin of usage. e.g. "dashboards:43445364..." */
@@ -107,7 +107,8 @@ export default class DashboardComponent extends React.Component<DashboardCompone
107
107
  props.onDesignChange != null,
108
108
  layoutOptionsOpen: false,
109
109
  hideQuickfilters:
110
- layoutOptions.hideQuickfiltersWidth != null && layoutOptions.hideQuickfiltersWidth > document.body.clientWidth,
110
+ layoutOptions.hideQuickfiltersWidth === 0 ||
111
+ (layoutOptions.hideQuickfiltersWidth != null && layoutOptions.hideQuickfiltersWidth > document.body.clientWidth),
111
112
  refreshKey: 1,
112
113
  locale: initialLocale
113
114
  }
@@ -91,8 +91,9 @@ export function LayoutOptionsComponent(props: {
91
91
  <div style={{ backgroundColor: "#888" }}></div>
92
92
  <div style={{ height: "100%", display: "grid", gridTemplateRows: "auto 1fr" }}>
93
93
  <div key="quickfilters">
94
- {layoutOptions.hideQuickfiltersWidth == null ||
95
- sizeOptions[previewSize].value.width > layoutOptions.hideQuickfiltersWidth
94
+ {(layoutOptions.hideQuickfiltersWidth !== 0) &&
95
+ (layoutOptions.hideQuickfiltersWidth == null ||
96
+ sizeOptions[previewSize].value.width > layoutOptions.hideQuickfiltersWidth)
96
97
  ? props.quickfiltersView
97
98
  : null}
98
99
  </div>
@@ -376,6 +377,7 @@ function CustomizeLayout(props: { layoutOptions: BlocksLayoutOptions; onLayoutOp
376
377
  onLayoutOptionsChange({ ...layoutOptions, hideQuickfiltersWidth })
377
378
  }}
378
379
  sign="< "
380
+ includeAlways
379
381
  />
380
382
  </FormGroup>
381
383
  <FormGroup label={T`Minimum Width (before scrolling or scaling)`}>
@@ -515,20 +517,30 @@ function WidthSelector(props: {
515
517
  onChange: (value: number | null) => void
516
518
  /** E.g. >=, <= */
517
519
  sign: string
520
+ /** If true, include an "Always" option with value 0 */
521
+ includeAlways?: boolean
518
522
  }) {
523
+ // Create options array with conditional "Always" option
524
+ const options = [
525
+ { value: 400, label: `${props.sign}400px (${T`Phone`})` },
526
+ { value: 600, label: `${props.sign}600px (${T`Small tablet`})` },
527
+ { value: 800, label: `${props.sign}800px (${T`Tablet`})` },
528
+ { value: 1000, label: `${props.sign}1000px (${T`Laptop`})` },
529
+ { value: 1200, label: `${props.sign}1200px (${T`Desktop`})` },
530
+ { value: 1600, label: `${props.sign}1600px (${T`Wide Desktop`})` }
531
+ ]
532
+
533
+ // Add "Always" option if requested
534
+ if (props.includeAlways) {
535
+ options.push({ value: 0, label: T`Always` })
536
+ }
537
+
519
538
  return (
520
539
  <Select
521
540
  value={props.value}
522
541
  onChange={props.onChange}
523
542
  nullLabel={T`N/A`}
524
- options={[
525
- { value: 400, label: `${props.sign}400px (${T`Phone`})` },
526
- { value: 600, label: `${props.sign}600px (${T`Small tablet`})` },
527
- { value: 800, label: `${props.sign}800px (${T`Tablet`})` },
528
- { value: 1000, label: `${props.sign}1000px (${T`Laptop`})` },
529
- { value: 1200, label: `${props.sign}1200px (${T`Desktop`})` },
530
- { value: 1600, label: `${props.sign}1600px (${T`Wide Desktop`})` }
531
- ]}
543
+ options={options}
532
544
  />
533
545
  )
534
546
  }
@@ -28,7 +28,7 @@ interface ServerDashboardDataSourceOptions {
28
28
  dataSource: DataSource
29
29
 
30
30
  /** revision to use to allow caching */
31
- rev: string
31
+ rev?: number
32
32
  }
33
33
 
34
34
  interface ServerWidgetDataSourceOptions extends ServerDashboardDataSourceOptions {
@@ -454,6 +454,41 @@ class ServerWidgetLayerDataSource implements MapLayerDataSource {
454
454
 
455
455
  return url
456
456
  }
457
+
458
+ /** Gets hover over data for hover over items
459
+ * @param design The design of the layer
460
+ * @param data The data of the current item being hovered over. e.g. { id: 123 }
461
+ * @param filters The filters to apply to the layer does not include filters that narrow down to a specific item
462
+ * @returns A promise that resolves to the hover over data, indexed by the id of the hover over item
463
+ */
464
+ async getHoverOverData(design: any, data: any, filters: JsonQLFilter[]): Promise<{ [key: string]: any }> {
465
+ const query = {
466
+ client: this.options.client,
467
+ share: this.options.share,
468
+ filters: compressJson(filters || []),
469
+ data: compressJson(data),
470
+ rev: this.options.rev
471
+ }
472
+
473
+ const url =
474
+ `${this.options.apiUrl}dashboards/${this.options.dashboardId}/widgets/${this.options.widgetId}/layers/${this.options.layerView.id}/hoverdata?` +
475
+ querystring.stringify(query)
476
+
477
+ const response = await fetch(url, {
478
+ method: "GET",
479
+ headers: {
480
+ Accept: "application/json"
481
+ }
482
+ })
483
+
484
+ if (!response.ok) {
485
+ const errorText = await response.text()
486
+ console.error(errorText)
487
+ throw new Error(`Error fetching hover data: ${response.statusText}`)
488
+ }
489
+
490
+ return await response.json()
491
+ }
457
492
  }
458
493
 
459
494
  interface ServerWidgetLayerPopupDataSourceOptions extends ServerDashboardDataSourceOptions {
@@ -21,7 +21,11 @@ export interface BlocksLayoutOptions {
21
21
  /** Width above which pads */
22
22
  maximumWidth: number | null
23
23
 
24
- /** Width at which to hide quickfilters. Null for never */
24
+ /** Width at which to hide quickfilters.
25
+ * Null for never hide
26
+ * 0 for always hide
27
+ * Positive number for responsive hiding based on width
28
+ */
25
29
  hideQuickfiltersWidth: number | null
26
30
 
27
31
  /** The padding around the entire dashboard */
@@ -380,7 +380,7 @@ export default forwardRef<DatagridComponentRef, DatagridComponentProps>(function
380
380
  return (
381
381
  <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: 40, padding: 4 }}>
382
382
  <div style={{ float: "right" }}>
383
- {design.showNumRows && numRows ? <small className='text-muted text-sm'>{`${d3Format(',')(numRows)} rows`}</small> : undefined}
383
+ {design.showNumRows && numRows ? <small className='text-muted text-sm me-2'>{`${d3Format(',')(numRows)} rows`}</small> : undefined}
384
384
  {renderDeleteRows()}
385
385
  {renderFindReplace()}
386
386
  {renderCellEdit()}