@carto/kepler.gl 0.0.1-alpha.map-libre

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 (913) hide show
  1. package/CHANGELOG.md +939 -0
  2. package/LICENSE +19 -0
  3. package/README.md +63 -0
  4. package/actions.js +21 -0
  5. package/cloud-providers.js +21 -0
  6. package/components.js +21 -0
  7. package/constants.js +21 -0
  8. package/dist/actions/action-wrapper.js +218 -0
  9. package/dist/actions/actions.js +198 -0
  10. package/dist/actions/identity-actions.js +105 -0
  11. package/dist/actions/index.js +161 -0
  12. package/dist/actions/map-state-actions.js +112 -0
  13. package/dist/actions/map-style-actions.js +167 -0
  14. package/dist/actions/provider-actions.js +129 -0
  15. package/dist/actions/ui-state-actions.js +316 -0
  16. package/dist/actions/vis-state-actions.js +1045 -0
  17. package/dist/cloud-providers/index.js +22 -0
  18. package/dist/cloud-providers/provider.js +386 -0
  19. package/dist/components/bottom-widget.js +215 -0
  20. package/dist/components/common/action-panel.js +134 -0
  21. package/dist/components/common/animation-control/animation-control.js +126 -0
  22. package/dist/components/common/animation-control/animation-controller.js +273 -0
  23. package/dist/components/common/animation-control/animation-speed-slider.js +101 -0
  24. package/dist/components/common/animation-control/floating-time-display.js +157 -0
  25. package/dist/components/common/animation-control/playback-controls.js +278 -0
  26. package/dist/components/common/animation-control/speed-control.js +68 -0
  27. package/dist/components/common/checkbox.js +155 -0
  28. package/dist/components/common/color-legend.js +249 -0
  29. package/dist/components/common/data-table/button.js +46 -0
  30. package/dist/components/common/data-table/canvas.js +32 -0
  31. package/dist/components/common/data-table/cell-size.js +174 -0
  32. package/dist/components/common/data-table/grid.js +84 -0
  33. package/dist/components/common/data-table/index.js +514 -0
  34. package/dist/components/common/data-table/option-dropdown.js +103 -0
  35. package/dist/components/common/dataset-label.js +36 -0
  36. package/dist/components/common/error-boundary.js +83 -0
  37. package/dist/components/common/field-selector.js +282 -0
  38. package/dist/components/common/field-token.js +42 -0
  39. package/dist/components/common/file-uploader/file-drop.js +227 -0
  40. package/dist/components/common/file-uploader/file-upload-progress.js +102 -0
  41. package/dist/components/common/file-uploader/file-upload.js +304 -0
  42. package/dist/components/common/file-uploader/upload-button.js +111 -0
  43. package/dist/components/common/histogram-plot.js +102 -0
  44. package/dist/components/common/icons/add.js +64 -0
  45. package/dist/components/common/icons/anchor_window.js +62 -0
  46. package/dist/components/common/icons/arrow-down-alt.js +64 -0
  47. package/dist/components/common/icons/arrow-down-solid .js +64 -0
  48. package/dist/components/common/icons/arrow-down.js +64 -0
  49. package/dist/components/common/icons/arrow-left.js +67 -0
  50. package/dist/components/common/icons/arrow-right.js +64 -0
  51. package/dist/components/common/icons/arrow-up-alt.js +65 -0
  52. package/dist/components/common/icons/arrow-up-solid.js +64 -0
  53. package/dist/components/common/icons/arrow-up.js +64 -0
  54. package/dist/components/common/icons/base.js +110 -0
  55. package/dist/components/common/icons/bug.js +66 -0
  56. package/dist/components/common/icons/cancel.js +64 -0
  57. package/dist/components/common/icons/checkmark.js +71 -0
  58. package/dist/components/common/icons/chevron-right.js +69 -0
  59. package/dist/components/common/icons/clipboard.js +65 -0
  60. package/dist/components/common/icons/clock.js +66 -0
  61. package/dist/components/common/icons/close.js +69 -0
  62. package/dist/components/common/icons/code-alt.js +68 -0
  63. package/dist/components/common/icons/copy.js +70 -0
  64. package/dist/components/common/icons/crosshairs.js +68 -0
  65. package/dist/components/common/icons/cube-3d.js +68 -0
  66. package/dist/components/common/icons/cursor-click.js +68 -0
  67. package/dist/components/common/icons/data-table.js +65 -0
  68. package/dist/components/common/icons/db.js +65 -0
  69. package/dist/components/common/icons/delete.js +65 -0
  70. package/dist/components/common/icons/docs.js +80 -0
  71. package/dist/components/common/icons/drag-n-drop.js +66 -0
  72. package/dist/components/common/icons/draw-polygon.js +87 -0
  73. package/dist/components/common/icons/email.js +68 -0
  74. package/dist/components/common/icons/expand.js +66 -0
  75. package/dist/components/common/icons/eye-seen.js +66 -0
  76. package/dist/components/common/icons/eye-unseen.js +66 -0
  77. package/dist/components/common/icons/file-type.js +45 -0
  78. package/dist/components/common/icons/file.js +64 -0
  79. package/dist/components/common/icons/files.js +66 -0
  80. package/dist/components/common/icons/filter-funnel.js +64 -0
  81. package/dist/components/common/icons/free-window.js +62 -0
  82. package/dist/components/common/icons/gear.js +66 -0
  83. package/dist/components/common/icons/hash.js +64 -0
  84. package/dist/components/common/icons/histogram.js +64 -0
  85. package/dist/components/common/icons/index.js +612 -0
  86. package/dist/components/common/icons/info.js +78 -0
  87. package/dist/components/common/icons/layers.js +64 -0
  88. package/dist/components/common/icons/left-arrow.js +68 -0
  89. package/dist/components/common/icons/legend.js +64 -0
  90. package/dist/components/common/icons/line-chart.js +63 -0
  91. package/dist/components/common/icons/login.js +66 -0
  92. package/dist/components/common/icons/logout.js +65 -0
  93. package/dist/components/common/icons/map-icon.js +73 -0
  94. package/dist/components/common/icons/map.js +73 -0
  95. package/dist/components/common/icons/messages.js +64 -0
  96. package/dist/components/common/icons/minus.js +64 -0
  97. package/dist/components/common/icons/pause.js +64 -0
  98. package/dist/components/common/icons/picture.js +66 -0
  99. package/dist/components/common/icons/pin.js +64 -0
  100. package/dist/components/common/icons/play.js +64 -0
  101. package/dist/components/common/icons/polygon.js +89 -0
  102. package/dist/components/common/icons/rectangle.js +90 -0
  103. package/dist/components/common/icons/reduce.js +67 -0
  104. package/dist/components/common/icons/reset.js +64 -0
  105. package/dist/components/common/icons/rocket.js +64 -0
  106. package/dist/components/common/icons/save.js +66 -0
  107. package/dist/components/common/icons/save2.js +70 -0
  108. package/dist/components/common/icons/search.js +66 -0
  109. package/dist/components/common/icons/settings.js +66 -0
  110. package/dist/components/common/icons/share.js +64 -0
  111. package/dist/components/common/icons/split.js +92 -0
  112. package/dist/components/common/icons/square-select.js +66 -0
  113. package/dist/components/common/icons/swap-horizontal.js +68 -0
  114. package/dist/components/common/icons/table.js +63 -0
  115. package/dist/components/common/icons/trash.js +66 -0
  116. package/dist/components/common/icons/upload.js +65 -0
  117. package/dist/components/common/icons/vert-dots.js +102 -0
  118. package/dist/components/common/icons/vert-three-dots.js +77 -0
  119. package/dist/components/common/icons/warning.js +79 -0
  120. package/dist/components/common/image-preview.js +73 -0
  121. package/dist/components/common/info-helper.js +84 -0
  122. package/dist/components/common/item-selector/accessor.js +56 -0
  123. package/dist/components/common/item-selector/chickleted-input.js +118 -0
  124. package/dist/components/common/item-selector/dropdown-list.js +316 -0
  125. package/dist/components/common/item-selector/item-selector-submenu.js +99 -0
  126. package/dist/components/common/item-selector/item-selector.js +363 -0
  127. package/dist/components/common/item-selector/typeahead.js +496 -0
  128. package/dist/components/common/line-chart.js +125 -0
  129. package/dist/components/common/loading-spinner.js +58 -0
  130. package/dist/components/common/logo.js +92 -0
  131. package/dist/components/common/map-layer-selector.js +50 -0
  132. package/dist/components/common/modal.js +204 -0
  133. package/dist/components/common/portaled.js +317 -0
  134. package/dist/components/common/progress-bar.js +56 -0
  135. package/dist/components/common/range-brush.js +319 -0
  136. package/dist/components/common/range-plot.js +148 -0
  137. package/dist/components/common/range-slider.js +346 -0
  138. package/dist/components/common/slider/mouse-event.js +136 -0
  139. package/dist/components/common/slider/slider-bar-handle.js +122 -0
  140. package/dist/components/common/slider/slider-handle.js +167 -0
  141. package/dist/components/common/slider/slider.js +268 -0
  142. package/dist/components/common/styled-components.js +395 -0
  143. package/dist/components/common/switch.js +47 -0
  144. package/dist/components/common/time-range-slider-time-title.js +74 -0
  145. package/dist/components/common/time-range-slider.js +131 -0
  146. package/dist/components/common/time-slider-marker.js +141 -0
  147. package/dist/components/common/toolbar-item.js +67 -0
  148. package/dist/components/common/toolbar.js +33 -0
  149. package/dist/components/common/vertical-toolbar.js +22 -0
  150. package/dist/components/container.js +217 -0
  151. package/dist/components/context.js +42 -0
  152. package/dist/components/editor/constants.js +47 -0
  153. package/dist/components/editor/editor.js +274 -0
  154. package/dist/components/editor/feature-action-panel.js +154 -0
  155. package/dist/components/editor/feature-styles.js +72 -0
  156. package/dist/components/editor/handle-style.js +80 -0
  157. package/dist/components/filters/components.js +20 -0
  158. package/dist/components/filters/filter-panels/filter-panel-with-field-select.js +110 -0
  159. package/dist/components/filters/filter-panels/multi-select-filter-panel.js +80 -0
  160. package/dist/components/filters/filter-panels/new-filter-panel.js +101 -0
  161. package/dist/components/filters/filter-panels/polygon-filter-panel.js +102 -0
  162. package/dist/components/filters/filter-panels/range-filter-panel.js +80 -0
  163. package/dist/components/filters/filter-panels/single-select-filter-panel.js +80 -0
  164. package/dist/components/filters/filter-panels/time-range-filter-panel.js +92 -0
  165. package/dist/components/filters/index.js +48 -0
  166. package/dist/components/filters/multi-select-filter.js +54 -0
  167. package/dist/components/filters/polygon-filter.js +96 -0
  168. package/dist/components/filters/range-filter.js +53 -0
  169. package/dist/components/filters/single-select-filter.js +63 -0
  170. package/dist/components/filters/time-range-filter.js +86 -0
  171. package/dist/components/filters/time-widget.js +173 -0
  172. package/dist/components/geocoder/geocoder.js +315 -0
  173. package/dist/components/geocoder-panel.js +224 -0
  174. package/dist/components/index.js +1485 -0
  175. package/dist/components/injector.js +178 -0
  176. package/dist/components/kepler-gl.js +563 -0
  177. package/dist/components/map/coordinate-info.js +68 -0
  178. package/dist/components/map/layer-hover-info.js +176 -0
  179. package/dist/components/map/layer-selector-panel.js +116 -0
  180. package/dist/components/map/locale-panel.js +113 -0
  181. package/dist/components/map/map-control-panel.js +79 -0
  182. package/dist/components/map/map-control-toolbar.js +25 -0
  183. package/dist/components/map/map-control-tooltip.js +55 -0
  184. package/dist/components/map/map-control.js +80 -0
  185. package/dist/components/map/map-draw-panel.js +142 -0
  186. package/dist/components/map/map-legend-panel.js +124 -0
  187. package/dist/components/map/map-legend.js +244 -0
  188. package/dist/components/map/map-popover.js +204 -0
  189. package/dist/components/map/split-map-button.js +98 -0
  190. package/dist/components/map/toggle-3d-button.js +86 -0
  191. package/dist/components/map-container.js +562 -0
  192. package/dist/components/maps-layout.js +58 -0
  193. package/dist/components/modal-container.js +536 -0
  194. package/dist/components/modals/add-map-style-modal.js +288 -0
  195. package/dist/components/modals/cloud-tile.js +124 -0
  196. package/dist/components/modals/data-table-modal.js +249 -0
  197. package/dist/components/modals/delete-data-modal.js +54 -0
  198. package/dist/components/modals/error-display.js +51 -0
  199. package/dist/components/modals/export-data-modal.js +227 -0
  200. package/dist/components/modals/export-image-modal.js +136 -0
  201. package/dist/components/modals/export-map-modal/components.js +51 -0
  202. package/dist/components/modals/export-map-modal/export-html-map.js +141 -0
  203. package/dist/components/modals/export-map-modal/export-json-map.js +87 -0
  204. package/dist/components/modals/export-map-modal/export-map-modal.js +133 -0
  205. package/dist/components/modals/image-modal-container.js +90 -0
  206. package/dist/components/modals/load-data-modal.js +97 -0
  207. package/dist/components/modals/load-storage-map.js +288 -0
  208. package/dist/components/modals/loading-dialog.js +48 -0
  209. package/dist/components/modals/modal-dialog.js +37 -0
  210. package/dist/components/modals/modal-tabs.js +99 -0
  211. package/dist/components/modals/overwrite-map-modal.js +80 -0
  212. package/dist/components/modals/provider-modal-container.js +84 -0
  213. package/dist/components/modals/save-map-modal.js +207 -0
  214. package/dist/components/modals/share-map-modal.js +202 -0
  215. package/dist/components/modals/status-panel.js +83 -0
  216. package/dist/components/modals/storage-map-viewer.js +135 -0
  217. package/dist/components/notification-panel/notification-item.js +164 -0
  218. package/dist/components/notification-panel.js +87 -0
  219. package/dist/components/performance.js +134 -0
  220. package/dist/components/plot-container.js +275 -0
  221. package/dist/components/side-panel/cloud-storage-dropdown.js +63 -0
  222. package/dist/components/side-panel/common/dataset-info.js +43 -0
  223. package/dist/components/side-panel/common/dataset-tag.js +42 -0
  224. package/dist/components/side-panel/common/dataset-title.js +170 -0
  225. package/dist/components/side-panel/common/source-data-catalog.js +60 -0
  226. package/dist/components/side-panel/common/source-data-selector.js +120 -0
  227. package/dist/components/side-panel/custom-panel.js +60 -0
  228. package/dist/components/side-panel/filter-manager.js +132 -0
  229. package/dist/components/side-panel/filter-panel/filter-panel-header.js +70 -0
  230. package/dist/components/side-panel/filter-panel/filter-panel.js +145 -0
  231. package/dist/components/side-panel/interaction-manager.js +58 -0
  232. package/dist/components/side-panel/interaction-panel/brush-config.js +54 -0
  233. package/dist/components/side-panel/interaction-panel/interaction-panel.js +168 -0
  234. package/dist/components/side-panel/interaction-panel/tooltip-config/tooltip-chicklet.js +250 -0
  235. package/dist/components/side-panel/interaction-panel/tooltip-config.js +163 -0
  236. package/dist/components/side-panel/layer-manager.js +321 -0
  237. package/dist/components/side-panel/layer-panel/color-dimension-scale-selector.js +45 -0
  238. package/dist/components/side-panel/layer-panel/color-palette.js +83 -0
  239. package/dist/components/side-panel/layer-panel/color-range-selector.js +370 -0
  240. package/dist/components/side-panel/layer-panel/color-selector.js +226 -0
  241. package/dist/components/side-panel/layer-panel/column-selector.js +65 -0
  242. package/dist/components/side-panel/layer-panel/custom-markers-config-group.js +40 -0
  243. package/dist/components/side-panel/layer-panel/custom-palette.js +318 -0
  244. package/dist/components/side-panel/layer-panel/custom-picker.js +128 -0
  245. package/dist/components/side-panel/layer-panel/dimension-scale-selector.js +61 -0
  246. package/dist/components/side-panel/layer-panel/layer-aggregation-resolution.js +26 -0
  247. package/dist/components/side-panel/layer-panel/layer-column-config.js +93 -0
  248. package/dist/components/side-panel/layer-panel/layer-config-group.js +245 -0
  249. package/dist/components/side-panel/layer-panel/layer-configurator.js +977 -0
  250. package/dist/components/side-panel/layer-panel/layer-panel-header.js +222 -0
  251. package/dist/components/side-panel/layer-panel/layer-panel.js +201 -0
  252. package/dist/components/side-panel/layer-panel/layer-type-dropdown-list.js +89 -0
  253. package/dist/components/side-panel/layer-panel/layer-type-list-item.js +71 -0
  254. package/dist/components/side-panel/layer-panel/layer-type-selector.js +96 -0
  255. package/dist/components/side-panel/layer-panel/layer-visibility-by-zoom.js +111 -0
  256. package/dist/components/side-panel/layer-panel/single-color-palette.js +109 -0
  257. package/dist/components/side-panel/layer-panel/text-label-panel.js +175 -0
  258. package/dist/components/side-panel/layer-panel/vis-config-by-field-selector.js +174 -0
  259. package/dist/components/side-panel/layer-panel/vis-config-slider.js +90 -0
  260. package/dist/components/side-panel/layer-panel/vis-config-switch.js +84 -0
  261. package/dist/components/side-panel/map-manager.js +155 -0
  262. package/dist/components/side-panel/map-style-panel/map-layer-selector.js +106 -0
  263. package/dist/components/side-panel/map-style-panel/map-style-selector.js +78 -0
  264. package/dist/components/side-panel/panel-dropdown.js +86 -0
  265. package/dist/components/side-panel/panel-header-action.js +121 -0
  266. package/dist/components/side-panel/panel-header.js +351 -0
  267. package/dist/components/side-panel/panel-tab.js +68 -0
  268. package/dist/components/side-panel/panel-title.js +28 -0
  269. package/dist/components/side-panel/panel-toggle.js +69 -0
  270. package/dist/components/side-panel/side-bar.js +164 -0
  271. package/dist/components/side-panel.js +242 -0
  272. package/dist/connect/keplergl-connect.js +68 -0
  273. package/dist/connect/with-local-selector.js +110 -0
  274. package/dist/constants/action-types.js +180 -0
  275. package/dist/constants/color-palette.js +547 -0
  276. package/dist/constants/color-ranges.js +70 -0
  277. package/dist/constants/custom-color-ranges.js +415 -0
  278. package/dist/constants/default-settings.js +902 -0
  279. package/dist/constants/index.js +370 -0
  280. package/dist/constants/keyevent.js +47 -0
  281. package/dist/constants/tooltip.js +205 -0
  282. package/dist/constants/user-feedbacks.js +33 -0
  283. package/dist/constants/user-guides.js +44 -0
  284. package/dist/deckgl-layers/3d-building-layer/3d-building-layer.js +88 -0
  285. package/dist/deckgl-layers/3d-building-layer/3d-building-utils.js +214 -0
  286. package/dist/deckgl-layers/cluster-layer/cluster-layer.js +334 -0
  287. package/dist/deckgl-layers/column-layer/enhanced-column-layer.js +78 -0
  288. package/dist/deckgl-layers/grid-layer/enhanced-cpu-grid-layer.js +96 -0
  289. package/dist/deckgl-layers/hexagon-layer/enhanced-hexagon-layer.js +96 -0
  290. package/dist/deckgl-layers/layer-utils/cluster-utils.js +119 -0
  291. package/dist/deckgl-layers/layer-utils/cpu-aggregator.js +643 -0
  292. package/dist/deckgl-layers/layer-utils/shader-utils.js +50 -0
  293. package/dist/deckgl-layers/line-layer/line-layer.js +111 -0
  294. package/dist/deckgl-layers/svg-icon-layer/scatterplot-icon-layer.js +78 -0
  295. package/dist/deckgl-layers/svg-icon-layer/svg-icon-layer.js +120 -0
  296. package/dist/index.js +155 -0
  297. package/dist/layers/aggregation-layer.js +416 -0
  298. package/dist/layers/arc-layer/arc-layer-icon.js +77 -0
  299. package/dist/layers/arc-layer/arc-layer.js +275 -0
  300. package/dist/layers/base-layer.js +1688 -0
  301. package/dist/layers/cluster-layer/cluster-layer-icon.js +80 -0
  302. package/dist/layers/cluster-layer/cluster-layer.js +151 -0
  303. package/dist/layers/default-layer-icon.js +87 -0
  304. package/dist/layers/geojson-layer/geojson-layer-icon.js +91 -0
  305. package/dist/layers/geojson-layer/geojson-layer.js +446 -0
  306. package/dist/layers/geojson-layer/geojson-utils.js +183 -0
  307. package/dist/layers/grid-layer/grid-layer-icon.js +136 -0
  308. package/dist/layers/grid-layer/grid-layer.js +115 -0
  309. package/dist/layers/grid-layer/grid-utils.js +62 -0
  310. package/dist/layers/h3-hexagon-layer/h3-hexagon-layer-icon.js +71 -0
  311. package/dist/layers/h3-hexagon-layer/h3-hexagon-layer.js +346 -0
  312. package/dist/layers/h3-hexagon-layer/h3-utils.js +97 -0
  313. package/dist/layers/heatmap-layer/heatmap-layer-icon.js +88 -0
  314. package/dist/layers/heatmap-layer/heatmap-layer.js +269 -0
  315. package/dist/layers/hexagon-layer/hexagon-layer-icon.js +100 -0
  316. package/dist/layers/hexagon-layer/hexagon-layer.js +120 -0
  317. package/dist/layers/hexagon-layer/hexagon-utils.js +74 -0
  318. package/dist/layers/icon-layer/icon-info-modal.js +117 -0
  319. package/dist/layers/icon-layer/icon-layer-icon.js +73 -0
  320. package/dist/layers/icon-layer/icon-layer.js +392 -0
  321. package/dist/layers/index.js +97 -0
  322. package/dist/layers/layer-factory.js +499 -0
  323. package/dist/layers/layer-text-label.js +72 -0
  324. package/dist/layers/layer-update.js +85 -0
  325. package/dist/layers/line-layer/line-layer-icon.js +79 -0
  326. package/dist/layers/line-layer/line-layer.js +209 -0
  327. package/dist/layers/mapbox-utils.js +204 -0
  328. package/dist/layers/mapboxgl-layer.js +210 -0
  329. package/dist/layers/point-layer/point-layer-icon.js +94 -0
  330. package/dist/layers/point-layer/point-layer.js +475 -0
  331. package/dist/layers/s2-geometry-layer/s2-geometry-layer.js +334 -0
  332. package/dist/layers/s2-geometry-layer/s2-layer-icon.js +70 -0
  333. package/dist/layers/s2-geometry-layer/s2-utils.js +51 -0
  334. package/dist/layers/scenegraph-layer/scenegraph-info-modal.js +48 -0
  335. package/dist/layers/scenegraph-layer/scenegraph-layer-icon.js +151 -0
  336. package/dist/layers/scenegraph-layer/scenegraph-layer.js +250 -0
  337. package/dist/layers/trip-layer/trip-info-modal.js +54 -0
  338. package/dist/layers/trip-layer/trip-layer-icon.js +89 -0
  339. package/dist/layers/trip-layer/trip-layer.js +403 -0
  340. package/dist/layers/trip-layer/trip-utils.js +204 -0
  341. package/dist/layers/types.js +47 -0
  342. package/dist/localization/en.js +480 -0
  343. package/dist/localization/formatted-message.js +45 -0
  344. package/dist/localization/index.js +60 -0
  345. package/dist/localization/locales.js +64 -0
  346. package/dist/middleware/index.js +47 -0
  347. package/dist/processors/data-processor.js +784 -0
  348. package/dist/processors/file-handler.js +432 -0
  349. package/dist/processors/index.js +106 -0
  350. package/dist/reducers/combined-updaters.js +195 -0
  351. package/dist/reducers/composer-helpers.js +110 -0
  352. package/dist/reducers/composers.js +27 -0
  353. package/dist/reducers/core.js +156 -0
  354. package/dist/reducers/index.js +139 -0
  355. package/dist/reducers/map-state-updaters.js +239 -0
  356. package/dist/reducers/map-state.js +47 -0
  357. package/dist/reducers/map-style-updaters.js +531 -0
  358. package/dist/reducers/map-style.js +46 -0
  359. package/dist/reducers/provider-state-updaters.js +541 -0
  360. package/dist/reducers/provider-state.js +46 -0
  361. package/dist/reducers/root.js +218 -0
  362. package/dist/reducers/ui-state-updaters.js +855 -0
  363. package/dist/reducers/ui-state.js +47 -0
  364. package/dist/reducers/vis-state-merger.js +615 -0
  365. package/dist/reducers/vis-state-selectors.js +52 -0
  366. package/dist/reducers/vis-state-updaters.js +2433 -0
  367. package/dist/reducers/vis-state.js +46 -0
  368. package/dist/schemas/dataset-schema.js +189 -0
  369. package/dist/schemas/index.js +132 -0
  370. package/dist/schemas/map-state-schema.js +49 -0
  371. package/dist/schemas/map-style-schema.js +122 -0
  372. package/dist/schemas/schema-manager.js +262 -0
  373. package/dist/schemas/schema-utils.js +62 -0
  374. package/dist/schemas/schema.js +114 -0
  375. package/dist/schemas/versions.js +38 -0
  376. package/dist/schemas/vis-state-schema.js +1071 -0
  377. package/dist/styles/base.js +1570 -0
  378. package/dist/styles/index.js +32 -0
  379. package/dist/styles/media-breakpoints.js +39 -0
  380. package/dist/tasks/tasks.js +122 -0
  381. package/dist/templates/export-map-html.js +45 -0
  382. package/dist/utils/aggregate-utils.js +75 -0
  383. package/dist/utils/color-utils.js +135 -0
  384. package/dist/utils/data-scale-utils.js +84 -0
  385. package/dist/utils/data-utils.js +491 -0
  386. package/dist/utils/dataset-utils.js +254 -0
  387. package/dist/utils/dom-to-image.js +557 -0
  388. package/dist/utils/dom-utils.js +425 -0
  389. package/dist/utils/export-utils.js +297 -0
  390. package/dist/utils/filter-utils.js +1286 -0
  391. package/dist/utils/gl-utils.js +35 -0
  392. package/dist/utils/gpu-filter-utils.js +261 -0
  393. package/dist/utils/index.js +226 -0
  394. package/dist/utils/interaction-utils.js +201 -0
  395. package/dist/utils/layer-utils.js +205 -0
  396. package/dist/utils/locale-utils.js +54 -0
  397. package/dist/utils/map-info-utils.js +32 -0
  398. package/dist/utils/map-style-utils/mapbox-gl-style-editor.js +212 -0
  399. package/dist/utils/map-style-utils/mapbox-utils.js +35 -0
  400. package/dist/utils/mapbox-utils.js +39 -0
  401. package/dist/utils/notifications-utils.js +89 -0
  402. package/dist/utils/observe-dimensions.js +147 -0
  403. package/dist/utils/projection-utils.js +83 -0
  404. package/dist/utils/searcher-utils.js +45 -0
  405. package/dist/utils/split-map-utils.js +108 -0
  406. package/dist/utils/table-utils/data-container-utils.js +69 -0
  407. package/dist/utils/table-utils/data-row.js +82 -0
  408. package/dist/utils/table-utils/index.js +20 -0
  409. package/dist/utils/table-utils/indexed-data-container.js +241 -0
  410. package/dist/utils/table-utils/kepler-table.js +544 -0
  411. package/dist/utils/table-utils/row-data-container.js +242 -0
  412. package/dist/utils/utils.js +234 -0
  413. package/layers.js +21 -0
  414. package/localization.js +21 -0
  415. package/middleware.js +21 -0
  416. package/package.json +281 -0
  417. package/processors.js +21 -0
  418. package/reducers.js +21 -0
  419. package/schemas.js +21 -0
  420. package/src/actions/action-wrapper.js +183 -0
  421. package/src/actions/actions.d.ts +104 -0
  422. package/src/actions/actions.js +178 -0
  423. package/src/actions/identity-actions.d.ts +53 -0
  424. package/src/actions/identity-actions.js +83 -0
  425. package/src/actions/index.d.ts +23 -0
  426. package/src/actions/index.js +42 -0
  427. package/src/actions/map-state-actions.d.ts +46 -0
  428. package/src/actions/map-state-actions.js +90 -0
  429. package/src/actions/map-style-actions.d.ts +116 -0
  430. package/src/actions/map-style-actions.js +135 -0
  431. package/src/actions/provider-actions.d.ts +203 -0
  432. package/src/actions/provider-actions.js +94 -0
  433. package/src/actions/ui-state-actions.d.ts +200 -0
  434. package/src/actions/ui-state-actions.js +272 -0
  435. package/src/actions/vis-state-actions.d.ts +502 -0
  436. package/src/actions/vis-state-actions.js +919 -0
  437. package/src/cloud-providers/index.d.ts +53 -0
  438. package/src/cloud-providers/index.js +21 -0
  439. package/src/cloud-providers/provider.js +233 -0
  440. package/src/components/bottom-widget.d.ts +33 -0
  441. package/src/components/bottom-widget.js +235 -0
  442. package/src/components/common/action-panel.d.ts +24 -0
  443. package/src/components/common/action-panel.js +177 -0
  444. package/src/components/common/animation-control/animation-control.js +155 -0
  445. package/src/components/common/animation-control/animation-controller.js +224 -0
  446. package/src/components/common/animation-control/animation-speed-slider.js +79 -0
  447. package/src/components/common/animation-control/floating-time-display.js +192 -0
  448. package/src/components/common/animation-control/playback-controls.js +278 -0
  449. package/src/components/common/animation-control/speed-control.js +71 -0
  450. package/src/components/common/checkbox.js +128 -0
  451. package/src/components/common/color-legend.js +198 -0
  452. package/src/components/common/data-table/button.js +47 -0
  453. package/src/components/common/data-table/canvas.js +43 -0
  454. package/src/components/common/data-table/cell-size.js +180 -0
  455. package/src/components/common/data-table/grid.js +55 -0
  456. package/src/components/common/data-table/index.js +620 -0
  457. package/src/components/common/data-table/option-dropdown.js +110 -0
  458. package/src/components/common/dataset-label.js +40 -0
  459. package/src/components/common/error-boundary.js +43 -0
  460. package/src/components/common/field-selector.js +233 -0
  461. package/src/components/common/field-token.js +56 -0
  462. package/src/components/common/file-uploader/file-drop.d.ts +19 -0
  463. package/src/components/common/file-uploader/file-drop.js +196 -0
  464. package/src/components/common/file-uploader/file-upload-progress.d.ts +11 -0
  465. package/src/components/common/file-uploader/file-upload-progress.js +110 -0
  466. package/src/components/common/file-uploader/file-upload.d.ts +22 -0
  467. package/src/components/common/file-uploader/file-upload.js +301 -0
  468. package/src/components/common/file-uploader/upload-button.d.ts.wip +11 -0
  469. package/src/components/common/file-uploader/upload-button.js +83 -0
  470. package/src/components/common/histogram-plot.js +102 -0
  471. package/src/components/common/icons/add.js +43 -0
  472. package/src/components/common/icons/anchor_window.js +53 -0
  473. package/src/components/common/icons/arrow-down-alt.js +43 -0
  474. package/src/components/common/icons/arrow-down-solid .js +43 -0
  475. package/src/components/common/icons/arrow-down.js +46 -0
  476. package/src/components/common/icons/arrow-left.js +48 -0
  477. package/src/components/common/icons/arrow-right.js +46 -0
  478. package/src/components/common/icons/arrow-up-alt.js +46 -0
  479. package/src/components/common/icons/arrow-up-solid.js +43 -0
  480. package/src/components/common/icons/arrow-up.js +46 -0
  481. package/src/components/common/icons/base.js +90 -0
  482. package/src/components/common/icons/bug.js +46 -0
  483. package/src/components/common/icons/cancel.js +43 -0
  484. package/src/components/common/icons/checkmark.js +45 -0
  485. package/src/components/common/icons/chevron-right.js +47 -0
  486. package/src/components/common/icons/clipboard.js +46 -0
  487. package/src/components/common/icons/clock.js +44 -0
  488. package/src/components/common/icons/close.js +49 -0
  489. package/src/components/common/icons/code-alt.js +43 -0
  490. package/src/components/common/icons/copy.js +44 -0
  491. package/src/components/common/icons/crosshairs.js +43 -0
  492. package/src/components/common/icons/cube-3d.js +45 -0
  493. package/src/components/common/icons/cursor-click.js +49 -0
  494. package/src/components/common/icons/data-table.js +45 -0
  495. package/src/components/common/icons/db.js +45 -0
  496. package/src/components/common/icons/delete.js +44 -0
  497. package/src/components/common/icons/docs.js +46 -0
  498. package/src/components/common/icons/drag-n-drop.js +44 -0
  499. package/src/components/common/icons/draw-polygon.js +60 -0
  500. package/src/components/common/icons/email.js +45 -0
  501. package/src/components/common/icons/expand.js +45 -0
  502. package/src/components/common/icons/eye-seen.js +44 -0
  503. package/src/components/common/icons/eye-unseen.js +44 -0
  504. package/src/components/common/icons/file-type.js +57 -0
  505. package/src/components/common/icons/file.js +43 -0
  506. package/src/components/common/icons/files.js +42 -0
  507. package/src/components/common/icons/filter-funnel.js +43 -0
  508. package/src/components/common/icons/free-window.js +53 -0
  509. package/src/components/common/icons/gear.js +45 -0
  510. package/src/components/common/icons/hash.js +43 -0
  511. package/src/components/common/icons/histogram.js +47 -0
  512. package/src/components/common/icons/index.js +96 -0
  513. package/src/components/common/icons/info.js +54 -0
  514. package/src/components/common/icons/layers.js +43 -0
  515. package/src/components/common/icons/left-arrow.js +43 -0
  516. package/src/components/common/icons/legend.js +43 -0
  517. package/src/components/common/icons/line-chart.js +45 -0
  518. package/src/components/common/icons/login.js +46 -0
  519. package/src/components/common/icons/logout.js +43 -0
  520. package/src/components/common/icons/map-icon.js +69 -0
  521. package/src/components/common/icons/map.js +69 -0
  522. package/src/components/common/icons/messages.js +43 -0
  523. package/src/components/common/icons/minus.js +45 -0
  524. package/src/components/common/icons/pause.js +43 -0
  525. package/src/components/common/icons/picture.js +43 -0
  526. package/src/components/common/icons/pin.js +43 -0
  527. package/src/components/common/icons/play.js +43 -0
  528. package/src/components/common/icons/polygon.js +74 -0
  529. package/src/components/common/icons/rectangle.js +75 -0
  530. package/src/components/common/icons/reduce.js +48 -0
  531. package/src/components/common/icons/reset.js +43 -0
  532. package/src/components/common/icons/rocket.js +43 -0
  533. package/src/components/common/icons/save.js +44 -0
  534. package/src/components/common/icons/save2.js +47 -0
  535. package/src/components/common/icons/search.js +44 -0
  536. package/src/components/common/icons/settings.js +45 -0
  537. package/src/components/common/icons/share.js +43 -0
  538. package/src/components/common/icons/split.js +63 -0
  539. package/src/components/common/icons/square-select.js +44 -0
  540. package/src/components/common/icons/swap-horizontal.js +43 -0
  541. package/src/components/common/icons/table.js +46 -0
  542. package/src/components/common/icons/trash.js +51 -0
  543. package/src/components/common/icons/upload.js +44 -0
  544. package/src/components/common/icons/vert-dots.js +50 -0
  545. package/src/components/common/icons/vert-three-dots.js +45 -0
  546. package/src/components/common/icons/warning.js +46 -0
  547. package/src/components/common/image-preview.js +111 -0
  548. package/src/components/common/info-helper.js +84 -0
  549. package/src/components/common/item-selector/accessor.js +45 -0
  550. package/src/components/common/item-selector/chickleted-input.js +143 -0
  551. package/src/components/common/item-selector/dropdown-list.js +250 -0
  552. package/src/components/common/item-selector/item-selector-submenu.js +68 -0
  553. package/src/components/common/item-selector/item-selector.d.ts +34 -0
  554. package/src/components/common/item-selector/item-selector.js +360 -0
  555. package/src/components/common/item-selector/typeahead.js +507 -0
  556. package/src/components/common/line-chart.js +134 -0
  557. package/src/components/common/loading-spinner.js +64 -0
  558. package/src/components/common/logo.js +92 -0
  559. package/src/components/common/map-layer-selector.d.ts +10 -0
  560. package/src/components/common/map-layer-selector.js +54 -0
  561. package/src/components/common/modal.js +233 -0
  562. package/src/components/common/portaled.js +264 -0
  563. package/src/components/common/progress-bar.d.ts +13 -0
  564. package/src/components/common/progress-bar.js +49 -0
  565. package/src/components/common/range-brush.js +256 -0
  566. package/src/components/common/range-plot.js +139 -0
  567. package/src/components/common/range-slider.js +299 -0
  568. package/src/components/common/slider/mouse-event.js +97 -0
  569. package/src/components/common/slider/slider-bar-handle.js +97 -0
  570. package/src/components/common/slider/slider-handle.js +181 -0
  571. package/src/components/common/slider/slider.js +213 -0
  572. package/src/components/common/styled-components.js +657 -0
  573. package/src/components/common/switch.js +50 -0
  574. package/src/components/common/time-range-slider-time-title.js +76 -0
  575. package/src/components/common/time-range-slider.js +163 -0
  576. package/src/components/common/time-slider-marker.js +168 -0
  577. package/src/components/common/toolbar-item.d.ts +14 -0
  578. package/src/components/common/toolbar-item.js +83 -0
  579. package/src/components/common/toolbar.js +45 -0
  580. package/src/components/common/vertical-toolbar.js +35 -0
  581. package/src/components/container.js +173 -0
  582. package/src/components/context.d.ts +10 -0
  583. package/src/components/context.js +32 -0
  584. package/src/components/editor/constants.js +39 -0
  585. package/src/components/editor/editor.js +218 -0
  586. package/src/components/editor/feature-action-panel.js +143 -0
  587. package/src/components/editor/feature-styles.js +75 -0
  588. package/src/components/editor/handle-style.js +89 -0
  589. package/src/components/filters/components.js +28 -0
  590. package/src/components/filters/filter-panels/filter-panel-types.d.ts +28 -0
  591. package/src/components/filters/filter-panels/filter-panel-with-field-select.js +124 -0
  592. package/src/components/filters/filter-panels/multi-select-filter-panel.js +75 -0
  593. package/src/components/filters/filter-panels/new-filter-panel.js +99 -0
  594. package/src/components/filters/filter-panels/polygon-filter-panel.js +96 -0
  595. package/src/components/filters/filter-panels/range-filter-panel.js +75 -0
  596. package/src/components/filters/filter-panels/single-select-filter-panel.js +75 -0
  597. package/src/components/filters/filter-panels/time-range-filter-panel.js +95 -0
  598. package/src/components/filters/index.js +25 -0
  599. package/src/components/filters/multi-select-filter.js +36 -0
  600. package/src/components/filters/polygon-filter.d.ts +13 -0
  601. package/src/components/filters/polygon-filter.js +73 -0
  602. package/src/components/filters/range-filter.js +43 -0
  603. package/src/components/filters/single-select-filter.js +49 -0
  604. package/src/components/filters/time-range-filter.js +68 -0
  605. package/src/components/filters/time-widget.js +228 -0
  606. package/src/components/geocoder/geocoder.d.ts +33 -0
  607. package/src/components/geocoder/geocoder.js +272 -0
  608. package/src/components/geocoder-panel.js +191 -0
  609. package/src/components/index.js +247 -0
  610. package/src/components/injector.js +161 -0
  611. package/src/components/kepler-gl.d.ts +60 -0
  612. package/src/components/kepler-gl.js +525 -0
  613. package/src/components/map/coordinate-info.js +53 -0
  614. package/src/components/map/layer-hover-info.d.ts +12 -0
  615. package/src/components/map/layer-hover-info.js +185 -0
  616. package/src/components/map/layer-selector-panel.d.ts +16 -0
  617. package/src/components/map/layer-selector-panel.js +106 -0
  618. package/src/components/map/locale-panel.d.ts +12 -0
  619. package/src/components/map/locale-panel.js +91 -0
  620. package/src/components/map/map-control-panel.d.ts +11 -0
  621. package/src/components/map/map-control-panel.js +98 -0
  622. package/src/components/map/map-control-toolbar.js +33 -0
  623. package/src/components/map/map-control-tooltip.d.ts +8 -0
  624. package/src/components/map/map-control-tooltip.js +40 -0
  625. package/src/components/map/map-control.d.ts +37 -0
  626. package/src/components/map/map-control.js +100 -0
  627. package/src/components/map/map-draw-panel.d.ts +16 -0
  628. package/src/components/map/map-draw-panel.js +125 -0
  629. package/src/components/map/map-legend-panel.d.ts +20 -0
  630. package/src/components/map/map-legend-panel.js +100 -0
  631. package/src/components/map/map-legend.d.ts +58 -0
  632. package/src/components/map/map-legend.js +228 -0
  633. package/src/components/map/map-popover.d.ts +28 -0
  634. package/src/components/map/map-popover.js +250 -0
  635. package/src/components/map/split-map-button.d.ts +19 -0
  636. package/src/components/map/split-map-button.js +82 -0
  637. package/src/components/map/toggle-3d-button.d.ts +16 -0
  638. package/src/components/map/toggle-3d-button.js +75 -0
  639. package/src/components/map-container.d.ts +18 -0
  640. package/src/components/map-container.js +502 -0
  641. package/src/components/maps-layout.d.ts +5 -0
  642. package/src/components/maps-layout.js +40 -0
  643. package/src/components/modal-container.d.ts +38 -0
  644. package/src/components/modal-container.js +545 -0
  645. package/src/components/modals/add-map-style-modal.js +301 -0
  646. package/src/components/modals/cloud-tile.js +147 -0
  647. package/src/components/modals/data-table-modal.js +217 -0
  648. package/src/components/modals/delete-data-modal.js +48 -0
  649. package/src/components/modals/error-display.js +39 -0
  650. package/src/components/modals/export-data-modal.js +193 -0
  651. package/src/components/modals/export-image-modal.d.ts +21 -0
  652. package/src/components/modals/export-image-modal.js +144 -0
  653. package/src/components/modals/export-map-modal/components.js +42 -0
  654. package/src/components/modals/export-map-modal/export-html-map.d.ts +21 -0
  655. package/src/components/modals/export-map-modal/export-html-map.js +145 -0
  656. package/src/components/modals/export-map-modal/export-json-map.js +100 -0
  657. package/src/components/modals/export-map-modal/export-map-modal.js +114 -0
  658. package/src/components/modals/image-modal-container.d.ts +13 -0
  659. package/src/components/modals/image-modal-container.js +76 -0
  660. package/src/components/modals/load-data-modal.d.ts +30 -0
  661. package/src/components/modals/load-data-modal.js +94 -0
  662. package/src/components/modals/load-storage-map.js +381 -0
  663. package/src/components/modals/loading-dialog.js +69 -0
  664. package/src/components/modals/modal-dialog.js +25 -0
  665. package/src/components/modals/modal-tabs.js +126 -0
  666. package/src/components/modals/overwrite-map-modal.d.ts +18 -0
  667. package/src/components/modals/overwrite-map-modal.js +97 -0
  668. package/src/components/modals/provider-modal-container.d.ts +12 -0
  669. package/src/components/modals/provider-modal-container.js +60 -0
  670. package/src/components/modals/save-map-modal.d.ts +32 -0
  671. package/src/components/modals/save-map-modal.js +244 -0
  672. package/src/components/modals/share-map-modal.js +208 -0
  673. package/src/components/modals/status-panel.js +95 -0
  674. package/src/components/modals/storage-map-viewer.js +177 -0
  675. package/src/components/notification-panel/notification-item.js +132 -0
  676. package/src/components/notification-panel.js +72 -0
  677. package/src/components/performance.js +103 -0
  678. package/src/components/plot-container.js +228 -0
  679. package/src/components/side-panel/cloud-storage-dropdown.js +52 -0
  680. package/src/components/side-panel/common/dataset-info.js +45 -0
  681. package/src/components/side-panel/common/dataset-tag.js +55 -0
  682. package/src/components/side-panel/common/dataset-title.js +146 -0
  683. package/src/components/side-panel/common/source-data-catalog.js +61 -0
  684. package/src/components/side-panel/common/source-data-selector.js +79 -0
  685. package/src/components/side-panel/custom-panel.js +50 -0
  686. package/src/components/side-panel/filter-manager.js +105 -0
  687. package/src/components/side-panel/filter-panel/filter-panel-header.js +83 -0
  688. package/src/components/side-panel/filter-panel/filter-panel.js +126 -0
  689. package/src/components/side-panel/interaction-manager.js +46 -0
  690. package/src/components/side-panel/interaction-panel/brush-config.js +51 -0
  691. package/src/components/side-panel/interaction-panel/interaction-panel.js +115 -0
  692. package/src/components/side-panel/interaction-panel/tooltip-config/tooltip-chicklet.js +199 -0
  693. package/src/components/side-panel/interaction-panel/tooltip-config.js +190 -0
  694. package/src/components/side-panel/layer-manager.js +290 -0
  695. package/src/components/side-panel/layer-panel/color-dimension-scale-selector.js +33 -0
  696. package/src/components/side-panel/layer-panel/color-palette.js +90 -0
  697. package/src/components/side-panel/layer-panel/color-range-selector.js +322 -0
  698. package/src/components/side-panel/layer-panel/color-selector.js +193 -0
  699. package/src/components/side-panel/layer-panel/column-selector.js +70 -0
  700. package/src/components/side-panel/layer-panel/custom-markers-config-group.js +30 -0
  701. package/src/components/side-panel/layer-panel/custom-palette.js +296 -0
  702. package/src/components/side-panel/layer-panel/custom-picker.js +88 -0
  703. package/src/components/side-panel/layer-panel/dimension-scale-selector.js +48 -0
  704. package/src/components/side-panel/layer-panel/layer-aggregation-resolution.js +13 -0
  705. package/src/components/side-panel/layer-panel/layer-column-config.js +113 -0
  706. package/src/components/side-panel/layer-panel/layer-config-group.js +237 -0
  707. package/src/components/side-panel/layer-panel/layer-configurator.js +1317 -0
  708. package/src/components/side-panel/layer-panel/layer-panel-header.js +236 -0
  709. package/src/components/side-panel/layer-panel/layer-panel.js +171 -0
  710. package/src/components/side-panel/layer-panel/layer-type-dropdown-list.js +105 -0
  711. package/src/components/side-panel/layer-panel/layer-type-list-item.js +83 -0
  712. package/src/components/side-panel/layer-panel/layer-type-selector.js +89 -0
  713. package/src/components/side-panel/layer-panel/layer-visibility-by-zoom.js +123 -0
  714. package/src/components/side-panel/layer-panel/single-color-palette.js +98 -0
  715. package/src/components/side-panel/layer-panel/text-label-panel.js +179 -0
  716. package/src/components/side-panel/layer-panel/vis-config-by-field-selector.js +163 -0
  717. package/src/components/side-panel/layer-panel/vis-config-slider.js +82 -0
  718. package/src/components/side-panel/layer-panel/vis-config-switch.js +87 -0
  719. package/src/components/side-panel/map-manager.js +114 -0
  720. package/src/components/side-panel/map-style-panel/map-layer-selector.js +128 -0
  721. package/src/components/side-panel/map-style-panel/map-style-selector.js +111 -0
  722. package/src/components/side-panel/panel-dropdown.js +53 -0
  723. package/src/components/side-panel/panel-header-action.js +106 -0
  724. package/src/components/side-panel/panel-header.js +321 -0
  725. package/src/components/side-panel/panel-tab.js +62 -0
  726. package/src/components/side-panel/panel-title.js +32 -0
  727. package/src/components/side-panel/panel-toggle.js +70 -0
  728. package/src/components/side-panel/side-bar.js +136 -0
  729. package/src/components/side-panel.d.ts +33 -0
  730. package/src/components/side-panel.js +253 -0
  731. package/src/connect/keplergl-connect.js +47 -0
  732. package/src/connect/with-local-selector.d.ts +11 -0
  733. package/src/connect/with-local-selector.js +67 -0
  734. package/src/constants/action-types.d.ts +135 -0
  735. package/src/constants/action-types.js +184 -0
  736. package/src/constants/color-palette.js +553 -0
  737. package/src/constants/color-ranges.js +63 -0
  738. package/src/constants/custom-color-ranges.js +551 -0
  739. package/src/constants/default-settings.js +991 -0
  740. package/src/constants/index.js +80 -0
  741. package/src/constants/keyevent.js +36 -0
  742. package/src/constants/tooltip.js +198 -0
  743. package/src/constants/user-feedbacks.js +32 -0
  744. package/src/constants/user-guides.js +32 -0
  745. package/src/deckgl-layers/3d-building-layer/3d-building-layer.js +56 -0
  746. package/src/deckgl-layers/3d-building-layer/3d-building-utils.js +192 -0
  747. package/src/deckgl-layers/cluster-layer/cluster-layer.js +255 -0
  748. package/src/deckgl-layers/column-layer/enhanced-column-layer.js +63 -0
  749. package/src/deckgl-layers/grid-layer/enhanced-cpu-grid-layer.js +70 -0
  750. package/src/deckgl-layers/hexagon-layer/enhanced-hexagon-layer.js +70 -0
  751. package/src/deckgl-layers/layer-utils/cluster-utils.js +76 -0
  752. package/src/deckgl-layers/layer-utils/cpu-aggregator.js +583 -0
  753. package/src/deckgl-layers/layer-utils/shader-utils.js +41 -0
  754. package/src/deckgl-layers/line-layer/line-layer.js +122 -0
  755. package/src/deckgl-layers/svg-icon-layer/scatterplot-icon-layer.js +57 -0
  756. package/src/deckgl-layers/svg-icon-layer/svg-icon-layer.js +85 -0
  757. package/src/index.js +52 -0
  758. package/src/layers/aggregation-layer.js +356 -0
  759. package/src/layers/arc-layer/arc-layer-icon.js +67 -0
  760. package/src/layers/arc-layer/arc-layer.js +221 -0
  761. package/src/layers/base-layer.js +1439 -0
  762. package/src/layers/cluster-layer/cluster-layer-icon.js +71 -0
  763. package/src/layers/cluster-layer/cluster-layer.js +125 -0
  764. package/src/layers/default-layer-icon.js +50 -0
  765. package/src/layers/geojson-layer/geojson-layer-icon.js +68 -0
  766. package/src/layers/geojson-layer/geojson-layer.js +344 -0
  767. package/src/layers/geojson-layer/geojson-utils.js +179 -0
  768. package/src/layers/grid-layer/grid-layer-icon.js +53 -0
  769. package/src/layers/grid-layer/grid-layer.js +95 -0
  770. package/src/layers/grid-layer/grid-utils.js +71 -0
  771. package/src/layers/h3-hexagon-layer/h3-hexagon-layer-icon.js +48 -0
  772. package/src/layers/h3-hexagon-layer/h3-hexagon-layer.js +264 -0
  773. package/src/layers/h3-hexagon-layer/h3-utils.js +65 -0
  774. package/src/layers/heatmap-layer/heatmap-layer-icon.js +64 -0
  775. package/src/layers/heatmap-layer/heatmap-layer.js +226 -0
  776. package/src/layers/hexagon-layer/hexagon-layer-icon.js +74 -0
  777. package/src/layers/hexagon-layer/hexagon-layer.js +95 -0
  778. package/src/layers/hexagon-layer/hexagon-utils.js +63 -0
  779. package/src/layers/icon-layer/icon-info-modal.js +155 -0
  780. package/src/layers/icon-layer/icon-layer-icon.js +56 -0
  781. package/src/layers/icon-layer/icon-layer.js +324 -0
  782. package/src/layers/index.d.ts +126 -0
  783. package/src/layers/index.js +72 -0
  784. package/src/layers/layer-factory.d.ts +148 -0
  785. package/src/layers/layer-factory.js +480 -0
  786. package/src/layers/layer-text-label.js +62 -0
  787. package/src/layers/layer-update.js +71 -0
  788. package/src/layers/line-layer/line-layer-icon.js +69 -0
  789. package/src/layers/line-layer/line-layer.js +161 -0
  790. package/src/layers/mapbox-utils.js +195 -0
  791. package/src/layers/mapboxgl-layer.js +154 -0
  792. package/src/layers/point-layer/point-layer-icon.js +51 -0
  793. package/src/layers/point-layer/point-layer.js +414 -0
  794. package/src/layers/s2-geometry-layer/s2-geometry-layer.js +265 -0
  795. package/src/layers/s2-geometry-layer/s2-layer-icon.js +47 -0
  796. package/src/layers/s2-geometry-layer/s2-utils.js +36 -0
  797. package/src/layers/scenegraph-layer/scenegraph-info-modal.js +97 -0
  798. package/src/layers/scenegraph-layer/scenegraph-layer-icon.js +144 -0
  799. package/src/layers/scenegraph-layer/scenegraph-layer.js +182 -0
  800. package/src/layers/trip-layer/trip-info-modal.js +82 -0
  801. package/src/layers/trip-layer/trip-layer-icon.js +62 -0
  802. package/src/layers/trip-layer/trip-layer.js +295 -0
  803. package/src/layers/trip-layer/trip-utils.js +169 -0
  804. package/src/layers/types.js +37 -0
  805. package/src/localization/en.js +501 -0
  806. package/src/localization/formatted-message.js +33 -0
  807. package/src/localization/index.js +32 -0
  808. package/src/localization/locales.js +46 -0
  809. package/src/middleware/index.js +34 -0
  810. package/src/processors/data-processor.d.ts +57 -0
  811. package/src/processors/data-processor.js +684 -0
  812. package/src/processors/file-handler.d.ts +46 -0
  813. package/src/processors/file-handler.js +220 -0
  814. package/src/processors/index.js +44 -0
  815. package/src/reducers/combined-updaters.d.ts +26 -0
  816. package/src/reducers/combined-updaters.js +198 -0
  817. package/src/reducers/composer-helpers.d.ts +32 -0
  818. package/src/reducers/composer-helpers.js +70 -0
  819. package/src/reducers/composers.js +33 -0
  820. package/src/reducers/core.d.ts +25 -0
  821. package/src/reducers/core.js +97 -0
  822. package/src/reducers/index.d.ts +118 -0
  823. package/src/reducers/index.js +53 -0
  824. package/src/reducers/map-state-updaters.d.ts +64 -0
  825. package/src/reducers/map-state-updaters.js +224 -0
  826. package/src/reducers/map-state.js +47 -0
  827. package/src/reducers/map-style-updaters.d.ts +76 -0
  828. package/src/reducers/map-style-updaters.js +541 -0
  829. package/src/reducers/map-style.js +53 -0
  830. package/src/reducers/provider-state-updaters.d.ts +88 -0
  831. package/src/reducers/provider-state-updaters.js +428 -0
  832. package/src/reducers/provider-state.js +53 -0
  833. package/src/reducers/root.js +230 -0
  834. package/src/reducers/types.d.ts +10 -0
  835. package/src/reducers/ui-state-updaters.d.ts +198 -0
  836. package/src/reducers/ui-state-updaters.js +766 -0
  837. package/src/reducers/ui-state.js +73 -0
  838. package/src/reducers/vis-state-merger.d.ts +78 -0
  839. package/src/reducers/vis-state-merger.js +545 -0
  840. package/src/reducers/vis-state-selectors.js +35 -0
  841. package/src/reducers/vis-state-updaters.d.ts +534 -0
  842. package/src/reducers/vis-state-updaters.js +2137 -0
  843. package/src/reducers/vis-state.js +155 -0
  844. package/src/schemas/dataset-schema.js +141 -0
  845. package/src/schemas/index.d.ts +24 -0
  846. package/src/schemas/index.js +42 -0
  847. package/src/schemas/map-state-schema.js +52 -0
  848. package/src/schemas/map-style-schema.js +95 -0
  849. package/src/schemas/schema-manager.d.ts +229 -0
  850. package/src/schemas/schema-manager.js +228 -0
  851. package/src/schemas/schema-utils.js +54 -0
  852. package/src/schemas/schema.d.ts +47 -0
  853. package/src/schemas/schema.js +90 -0
  854. package/src/schemas/versions.d.ts +23 -0
  855. package/src/schemas/versions.js +28 -0
  856. package/src/schemas/vis-state-schema.js +731 -0
  857. package/src/styles/base.js +1620 -0
  858. package/src/styles/index.js +22 -0
  859. package/src/styles/media-breakpoints.js +47 -0
  860. package/src/tasks/tasks.js +92 -0
  861. package/src/templates/export-map-html.js +262 -0
  862. package/src/typedefs/README.md +3 -0
  863. package/src/typedefs/deck.gl__core.d.ts +64 -0
  864. package/src/typedefs/deck.gl__mesh-layers.d.ts +33 -0
  865. package/src/utils/aggregate-utils.js +71 -0
  866. package/src/utils/color-utils.js +106 -0
  867. package/src/utils/data-scale-utils.d.ts +26 -0
  868. package/src/utils/data-scale-utils.js +61 -0
  869. package/src/utils/data-utils.d.ts +45 -0
  870. package/src/utils/data-utils.js +428 -0
  871. package/src/utils/dataset-utils.d.ts +10 -0
  872. package/src/utils/dataset-utils.js +255 -0
  873. package/src/utils/dom-to-image.js +533 -0
  874. package/src/utils/dom-utils.js +354 -0
  875. package/src/utils/export-utils.js +247 -0
  876. package/src/utils/filter-utils.d.ts +192 -0
  877. package/src/utils/filter-utils.js +1114 -0
  878. package/src/utils/gl-utils.js +42 -0
  879. package/src/utils/gpu-filter-utils.d.ts +28 -0
  880. package/src/utils/gpu-filter-utils.js +253 -0
  881. package/src/utils/index.d.ts +5 -0
  882. package/src/utils/index.js +55 -0
  883. package/src/utils/interaction-utils.d.ts +36 -0
  884. package/src/utils/interaction-utils.js +185 -0
  885. package/src/utils/layer-utils.d.ts +78 -0
  886. package/src/utils/layer-utils.js +205 -0
  887. package/src/utils/locale-utils.js +59 -0
  888. package/src/utils/map-info-utils.js +29 -0
  889. package/src/utils/map-style-utils/mapbox-gl-style-editor.js +201 -0
  890. package/src/utils/map-style-utils/mapbox-utils.js +28 -0
  891. package/src/utils/mapbox-utils.js +27 -0
  892. package/src/utils/notifications-utils.js +83 -0
  893. package/src/utils/observe-dimensions.d.ts +18 -0
  894. package/src/utils/observe-dimensions.js +115 -0
  895. package/src/utils/projection-utils.js +72 -0
  896. package/src/utils/searcher-utils.js +37 -0
  897. package/src/utils/split-map-utils.js +104 -0
  898. package/src/utils/table-utils/UPGRADE-data-container.md +38 -0
  899. package/src/utils/table-utils/data-container-interface.d.ts +140 -0
  900. package/src/utils/table-utils/data-container-utils.d.ts +43 -0
  901. package/src/utils/table-utils/data-container-utils.js +61 -0
  902. package/src/utils/table-utils/data-row.d.ts +65 -0
  903. package/src/utils/table-utils/data-row.js +54 -0
  904. package/src/utils/table-utils/index.d.ts +1 -0
  905. package/src/utils/table-utils/index.js +21 -0
  906. package/src/utils/table-utils/indexed-data-container.d.ts +26 -0
  907. package/src/utils/table-utils/indexed-data-container.js +152 -0
  908. package/src/utils/table-utils/kepler-table.d.ts +114 -0
  909. package/src/utils/table-utils/kepler-table.js +486 -0
  910. package/src/utils/table-utils/row-data-container.d.ts +30 -0
  911. package/src/utils/table-utils/row-data-container.js +151 -0
  912. package/src/utils/utils.js +202 -0
  913. package/styles.js +21 -0
@@ -0,0 +1,2137 @@
1
+ // Copyright (c) 2022 Uber Technologies, Inc.
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ import {console as Console} from 'global/window';
22
+ import {disableStackCapturing, withTask} from 'react-palm/tasks';
23
+ import cloneDeep from 'lodash.clonedeep';
24
+ import uniq from 'lodash.uniq';
25
+ import get from 'lodash.get';
26
+ import xor from 'lodash.xor';
27
+ import copy from 'copy-to-clipboard';
28
+ import {parseFieldValue} from 'utils/data-utils';
29
+ // Tasks
30
+ import {LOAD_FILE_TASK, UNWRAP_TASK, PROCESS_FILE_DATA, DELAY_TASK} from 'tasks/tasks';
31
+ // Actions
32
+ import {
33
+ loadFilesErr,
34
+ loadFilesSuccess,
35
+ loadFileStepSuccess,
36
+ loadNextFile,
37
+ nextFileBatch
38
+ } from 'actions/vis-state-actions';
39
+ // Utils
40
+ import {findFieldsToShow, getDefaultInteraction} from 'utils/interaction-utils';
41
+ import {
42
+ applyFilterFieldName,
43
+ applyFiltersToDatasets,
44
+ featureToFilterValue,
45
+ FILTER_UPDATER_PROPS,
46
+ filterDatasetCPU,
47
+ generatePolygonFilter,
48
+ getDefaultFilter,
49
+ getDefaultFilterPlotType,
50
+ getFilterIdInFeature,
51
+ getFilterPlot,
52
+ getTimeWidgetTitleFormatter,
53
+ isInRange,
54
+ LIMITED_FILTER_EFFECT_PROPS,
55
+ updateFilterDataId
56
+ } from 'utils/filter-utils';
57
+ import {assignGpuChannel, setFilterGpuMode} from 'utils/gpu-filter-utils';
58
+ import {createNewDataEntry} from 'utils/dataset-utils';
59
+ import {sortDatasetByColumn} from 'utils/table-utils/kepler-table';
60
+ import {set, toArray, arrayInsert, generateHashId} from 'utils/utils';
61
+
62
+ import {calculateLayerData, findDefaultLayer} from 'utils/layer-utils';
63
+
64
+ import {
65
+ isValidMerger,
66
+ VIS_STATE_MERGERS,
67
+ validateLayerWithData,
68
+ createLayerFromConfig,
69
+ serializeLayer
70
+ } from './vis-state-merger';
71
+
72
+ import {
73
+ addNewLayersToSplitMap,
74
+ computeSplitMapLayers,
75
+ removeLayerFromSplitMaps
76
+ } from 'utils/split-map-utils';
77
+
78
+ import {Layer, LayerClasses, LAYER_ID_LENGTH} from 'layers';
79
+ import {DEFAULT_TEXT_LABEL, DEFAULT_SECONDARY_TEXT_LABEL} from 'layers/layer-factory';
80
+ import {EDITOR_MODES, SORT_ORDER, FILTER_TYPES} from 'constants/default-settings';
81
+ import {pick_, merge_, swap_} from './composer-helpers';
82
+ import {processFileContent} from 'actions/vis-state-actions';
83
+
84
+ import KeplerGLSchema from 'schemas';
85
+
86
+ // type imports
87
+ /** @typedef {import('./vis-state-updaters').Field} Field */
88
+ /** @typedef {import('./vis-state-updaters').Filter} Filter */
89
+ /** @typedef {import('./vis-state-updaters').KeplerTable} KeplerTable */
90
+ /** @typedef {import('./vis-state-updaters').VisState} VisState */
91
+ /** @typedef {import('./vis-state-updaters').Datasets} Datasets */
92
+ /** @typedef {import('./vis-state-updaters').AnimationConfig} AnimationConfig */
93
+ /** @typedef {import('./vis-state-updaters').Editor} Editor */
94
+
95
+ // react-palm
96
+ // disable capture exception for react-palm call to withTask
97
+ disableStackCapturing();
98
+
99
+ /**
100
+ * Updaters for `visState` reducer. Can be used in your root reducer to directly modify kepler.gl's state.
101
+ * Read more about [Using updaters](../advanced-usage/using-updaters.md)
102
+ *
103
+ * @public
104
+ * @example
105
+ *
106
+ * import keplerGlReducer, {visStateUpdaters} from 'kepler.gl/reducers';
107
+ * // Root Reducer
108
+ * const reducers = combineReducers({
109
+ * keplerGl: keplerGlReducer,
110
+ * app: appReducer
111
+ * });
112
+ *
113
+ * const composedReducer = (state, action) => {
114
+ * switch (action.type) {
115
+ * case 'CLICK_BUTTON':
116
+ * return {
117
+ * ...state,
118
+ * keplerGl: {
119
+ * ...state.keplerGl,
120
+ * foo: {
121
+ * ...state.keplerGl.foo,
122
+ * visState: visStateUpdaters.enlargeFilterUpdater(
123
+ * state.keplerGl.foo.visState,
124
+ * {idx: 0}
125
+ * )
126
+ * }
127
+ * }
128
+ * };
129
+ * }
130
+ * return reducers(state, action);
131
+ * };
132
+ *
133
+ * export default composedReducer;
134
+ */
135
+ /* eslint-disable no-unused-vars */
136
+ // @ts-ignore
137
+ const visStateUpdaters = null;
138
+ /* eslint-enable no-unused-vars */
139
+
140
+ /** @type {AnimationConfig} */
141
+ export const DEFAULT_ANIMATION_CONFIG = {
142
+ domain: null,
143
+ currentTime: null,
144
+ speed: 1,
145
+ isAnimating: false,
146
+ timeFormat: null,
147
+ timezone: null,
148
+ defaultTimeFormat: null
149
+ };
150
+
151
+ /** @type {Editor} */
152
+ export const DEFAULT_EDITOR = {
153
+ mode: EDITOR_MODES.DRAW_POLYGON,
154
+ features: [],
155
+ selectedFeature: null,
156
+ visible: true
157
+ };
158
+
159
+ /**
160
+ * Default initial `visState`
161
+ * @memberof visStateUpdaters
162
+ * @constant
163
+ * @type {VisState}
164
+ * @public
165
+ */
166
+ export const INITIAL_VIS_STATE = {
167
+ // map info
168
+ mapInfo: {
169
+ title: '',
170
+ description: ''
171
+ },
172
+ // layers
173
+ layers: [],
174
+ layerData: [],
175
+ layerToBeMerged: [],
176
+ layerOrder: [],
177
+
178
+ // filters
179
+ filters: [],
180
+ filterToBeMerged: [],
181
+
182
+ // a collection of multiple dataset
183
+ datasets: {},
184
+ editingDataset: undefined,
185
+
186
+ interactionConfig: getDefaultInteraction(),
187
+ interactionToBeMerged: undefined,
188
+
189
+ layerBlending: 'normal',
190
+ hoverInfo: undefined,
191
+ clicked: undefined,
192
+ mousePos: {},
193
+
194
+ // this is used when user split maps
195
+ splitMaps: [
196
+ // this will contain a list of objects to
197
+ // describe the state of layer availability and visibility for each map
198
+ // [
199
+ // {
200
+ // layers: {layer_id: true | false}
201
+ // }
202
+ // ]
203
+ ],
204
+ splitMapsToBeMerged: [],
205
+
206
+ // defaults layer classes
207
+ layerClasses: LayerClasses,
208
+
209
+ // default animation
210
+ // time in unix timestamp (milliseconds) (the number of seconds since the Unix Epoch)
211
+ animationConfig: DEFAULT_ANIMATION_CONFIG,
212
+
213
+ editor: DEFAULT_EDITOR,
214
+
215
+ fileLoading: false,
216
+ fileLoadingProgress: {},
217
+
218
+ loaders: [],
219
+ loadOptions: {},
220
+
221
+ // visStateMergers
222
+ mergers: VIS_STATE_MERGERS,
223
+
224
+ // kepler schemas
225
+ schema: KeplerGLSchema
226
+ };
227
+
228
+ /**
229
+ * Update state with updated layer and layerData
230
+ * @type {typeof import('./vis-state-updaters').updateStateWithLayerAndData}
231
+ *
232
+ */
233
+ export function updateStateWithLayerAndData(state, {layerData, layer, idx}) {
234
+ return {
235
+ ...state,
236
+ layers: state.layers.map((lyr, i) => (i === idx ? layer : lyr)),
237
+ layerData: layerData
238
+ ? state.layerData.map((d, i) => (i === idx ? layerData : d))
239
+ : state.layerData
240
+ };
241
+ }
242
+
243
+ export function updateStateOnLayerVisibilityChange(state, layer) {
244
+ let newState = state;
245
+ if (state.splitMaps.length) {
246
+ newState = {
247
+ ...state,
248
+ splitMaps: layer.config.isVisible
249
+ ? addNewLayersToSplitMap(state.splitMaps, layer)
250
+ : removeLayerFromSplitMaps(state.splitMaps, layer)
251
+ };
252
+ }
253
+
254
+ if (layer.config.animation.enabled) {
255
+ newState = updateAnimationDomain(state);
256
+ }
257
+
258
+ return newState;
259
+ }
260
+
261
+ /**
262
+ * Update layer base config: dataId, label, column, isVisible
263
+ * @memberof visStateUpdaters
264
+ * @type {typeof import('./vis-state-updaters').layerConfigChangeUpdater}
265
+ * @returns nextState
266
+ */
267
+ export function layerConfigChangeUpdater(state, action) {
268
+ const {oldLayer} = action;
269
+ const idx = state.layers.findIndex(l => l.id === oldLayer.id);
270
+ const props = Object.keys(action.newConfig);
271
+ if (typeof action.newConfig.dataId === 'string') {
272
+ const {dataId, ...restConfig} = action.newConfig;
273
+ const stateWithDataId = layerDataIdChangeUpdater(state, {
274
+ oldLayer,
275
+ newConfig: {dataId}
276
+ });
277
+ const nextLayer = stateWithDataId.layers.find(l => l.id === oldLayer.id);
278
+ return nextLayer && Object.keys(restConfig).length
279
+ ? layerConfigChangeUpdater(stateWithDataId, {oldLayer: nextLayer, newConfig: restConfig})
280
+ : stateWithDataId;
281
+ }
282
+
283
+ let newLayer = oldLayer.updateLayerConfig(action.newConfig);
284
+
285
+ let layerData;
286
+
287
+ // let newLayer;
288
+ if (newLayer.shouldCalculateLayerData(props)) {
289
+ const oldLayerData = state.layerData[idx];
290
+ const updateLayerDataResult = calculateLayerData(newLayer, state, oldLayerData);
291
+
292
+ layerData = updateLayerDataResult.layerData;
293
+ newLayer = updateLayerDataResult.layer;
294
+ }
295
+
296
+ let newState = state;
297
+ if ('isVisible' in action.newConfig) {
298
+ newState = updateStateOnLayerVisibilityChange(state, newLayer);
299
+ }
300
+
301
+ return updateStateWithLayerAndData(newState, {
302
+ layer: newLayer,
303
+ layerData,
304
+ idx
305
+ });
306
+ }
307
+
308
+ function addOrRemoveTextLabels(newFields, textLabel) {
309
+ let newTextLabel = textLabel.slice();
310
+
311
+ const currentFields = textLabel.map(tl => tl.field && tl.field.name).filter(d => d);
312
+
313
+ const addFields = newFields.filter(f => !currentFields.includes(f.name));
314
+ const deleteFields = currentFields.filter(f => !newFields.find(fd => fd.name === f));
315
+
316
+ // delete
317
+ newTextLabel = newTextLabel.filter(tl => tl.field && !deleteFields.includes(tl.field.name));
318
+
319
+ // add
320
+ newTextLabel = newTextLabel.filter(tl => tl.field);
321
+ const defaultLabel = newTextLabel.length ? DEFAULT_SECONDARY_TEXT_LABEL : DEFAULT_TEXT_LABEL;
322
+ newTextLabel = [...newTextLabel, ...addFields.map(af => ({...defaultLabel, field: af}))];
323
+
324
+ // limit to 2 labels (overwrite 2nd label with 3rd)
325
+ if (newTextLabel.length > 2) {
326
+ newTextLabel = [newTextLabel[0], newTextLabel[2]];
327
+ }
328
+
329
+ // default
330
+ newTextLabel = !newTextLabel.length ? [DEFAULT_TEXT_LABEL] : newTextLabel;
331
+
332
+ return newTextLabel;
333
+ }
334
+
335
+ function updateTextLabelPropAndValue(idx, prop, value, textLabel) {
336
+ if (!textLabel[idx].hasOwnProperty(prop)) {
337
+ return textLabel;
338
+ }
339
+
340
+ let newTextLabel = textLabel.slice();
341
+
342
+ if (prop && (value || textLabel.length === 1)) {
343
+ newTextLabel = textLabel.map((tl, i) => (i === idx ? {...tl, [prop]: value} : tl));
344
+ } else if (prop === 'field' && value === null && textLabel.length > 1) {
345
+ // remove label when field value is set to null
346
+ newTextLabel.splice(idx, 1);
347
+ }
348
+
349
+ return newTextLabel;
350
+ }
351
+
352
+ /**
353
+ * Update layer base config: dataId, label, column, isVisible
354
+ * @memberof visStateUpdaters
355
+ * @type {typeof import('./vis-state-updaters').layerTextLabelChangeUpdater}
356
+ * @returns nextState
357
+ */
358
+ export function layerTextLabelChangeUpdater(state, action) {
359
+ const {oldLayer, idx, prop, value} = action;
360
+ const {textLabel} = oldLayer.config;
361
+
362
+ let newTextLabel = textLabel.slice();
363
+ if (!textLabel[idx] && idx === textLabel.length) {
364
+ // if idx is set to length, add empty text label
365
+ newTextLabel = [...textLabel, idx === 0 ? DEFAULT_TEXT_LABEL : DEFAULT_SECONDARY_TEXT_LABEL];
366
+ }
367
+
368
+ if (idx === 'all' && prop === 'fields') {
369
+ newTextLabel = addOrRemoveTextLabels(value, textLabel);
370
+ } else {
371
+ newTextLabel = updateTextLabelPropAndValue(idx, prop, value, newTextLabel);
372
+ }
373
+ // update text label prop and value
374
+ return layerConfigChangeUpdater(state, {
375
+ oldLayer,
376
+ newConfig: {textLabel: newTextLabel}
377
+ });
378
+ }
379
+
380
+ function validateExistingLayerWithData(dataset, layerClasses, layer) {
381
+ const loadedLayer = serializeLayer(layer);
382
+ return validateLayerWithData(dataset, loadedLayer, layerClasses, {
383
+ allowEmptyColumn: true
384
+ });
385
+ }
386
+
387
+ /**
388
+ * Update layer config dataId
389
+ * @memberof visStateUpdaters
390
+ * @type {typeof import('./vis-state-updaters').layerDataIdChangeUpdater}
391
+ * @returns nextState
392
+ */
393
+ export function layerDataIdChangeUpdater(state, action) {
394
+ const {oldLayer, newConfig} = action;
395
+ const {dataId} = newConfig;
396
+
397
+ if (!oldLayer || !state.datasets[dataId]) {
398
+ return state;
399
+ }
400
+ const idx = state.layers.findIndex(l => l.id === oldLayer.id);
401
+
402
+ let newLayer = oldLayer.updateLayerConfig({dataId});
403
+ // this may happen when a layer is new (type: null and no columns) but it's not ready to be saved
404
+ if (newLayer.isValidToSave()) {
405
+ const validated = validateExistingLayerWithData(
406
+ state.datasets[dataId],
407
+ state.layerClasses,
408
+ newLayer
409
+ );
410
+ // if cant validate it with data create a new one
411
+ if (!validated) {
412
+ newLayer = new state.layerClasses[oldLayer.type]({dataId, id: oldLayer.id});
413
+ } else {
414
+ newLayer = validated;
415
+ }
416
+ }
417
+
418
+ newLayer = newLayer.updateLayerConfig({
419
+ isVisible: oldLayer.config.isVisible,
420
+ isConfigActive: true
421
+ });
422
+
423
+ newLayer.updateLayerDomain(state.datasets);
424
+ const {layerData, layer} = calculateLayerData(newLayer, state, undefined);
425
+
426
+ return updateStateWithLayerAndData(state, {layerData, layer, idx});
427
+ }
428
+
429
+ /**
430
+ * Update layer type. Previews layer config will be copied if applicable.
431
+ * @memberof visStateUpdaters
432
+ * @type {typeof import('./vis-state-updaters').layerTypeChangeUpdater}
433
+ * @public
434
+ */
435
+ export function layerTypeChangeUpdater(state, action) {
436
+ const {oldLayer, newType} = action;
437
+ if (!oldLayer) {
438
+ return state;
439
+ }
440
+ const oldId = oldLayer.id;
441
+ const idx = state.layers.findIndex(l => l.id === oldId);
442
+
443
+ if (!state.layerClasses[newType]) {
444
+ Console.error(`${newType} is not a valid layer type`);
445
+ return state;
446
+ }
447
+
448
+ // get a mint layer, with new id and type
449
+ // because deck.gl uses id to match between new and old layer.
450
+ // If type has changed but id is the same, it will break
451
+ const newLayer = new state.layerClasses[newType]();
452
+
453
+ newLayer.assignConfigToLayer(oldLayer.config, oldLayer.visConfigSettings);
454
+
455
+ newLayer.updateLayerDomain(state.datasets);
456
+ const {layerData, layer} = calculateLayerData(newLayer, state);
457
+ let newState = updateStateWithLayerAndData(state, {layerData, layer, idx});
458
+
459
+ if (layer.config.animation.enabled || oldLayer.config.animation.enabled) {
460
+ newState = updateAnimationDomain(newState);
461
+ }
462
+
463
+ // update splitMap layer id
464
+ if (state.splitMaps.length) {
465
+ newState = {
466
+ ...newState,
467
+ splitMaps: newState.splitMaps.map(settings => {
468
+ const {[oldId]: oldLayerMap, ...otherLayers} = settings.layers;
469
+ return oldId in settings.layers
470
+ ? {
471
+ ...settings,
472
+ layers: {
473
+ ...otherLayers,
474
+ [layer.id]: oldLayerMap
475
+ }
476
+ }
477
+ : settings;
478
+ })
479
+ };
480
+ }
481
+
482
+ return newState;
483
+ }
484
+
485
+ /**
486
+ * Update layer visual channel
487
+ * @memberof visStateUpdaters
488
+ * @type {typeof import('./vis-state-updaters').layerVisualChannelChangeUpdater}
489
+ * @returns {Object} nextState
490
+ * @public
491
+ */
492
+ export function layerVisualChannelChangeUpdater(state, action) {
493
+ const {oldLayer, newConfig, channel} = action;
494
+ if (!oldLayer.config.dataId) {
495
+ return state;
496
+ }
497
+ const dataset = state.datasets[oldLayer.config.dataId];
498
+
499
+ const idx = state.layers.findIndex(l => l.id === oldLayer.id);
500
+ const newLayer = oldLayer.updateLayerConfig(newConfig);
501
+
502
+ newLayer.updateLayerVisualChannel(dataset, channel);
503
+
504
+ const oldLayerData = state.layerData[idx];
505
+ const {layerData, layer} = calculateLayerData(newLayer, state, oldLayerData);
506
+
507
+ return updateStateWithLayerAndData(state, {layerData, layer, idx});
508
+ }
509
+
510
+ /**
511
+ * Update layer `visConfig`
512
+ * @memberof visStateUpdaters
513
+ * @type {typeof import('./vis-state-updaters').layerVisConfigChangeUpdater}
514
+ * @public
515
+ */
516
+ export function layerVisConfigChangeUpdater(state, action) {
517
+ const {oldLayer} = action;
518
+ const idx = state.layers.findIndex(l => l.id === oldLayer.id);
519
+ const props = Object.keys(action.newVisConfig);
520
+ const newVisConfig = {
521
+ ...oldLayer.config.visConfig,
522
+ ...action.newVisConfig
523
+ };
524
+
525
+ const newLayer = oldLayer.updateLayerConfig({visConfig: newVisConfig});
526
+
527
+ if (newLayer.shouldCalculateLayerData(props)) {
528
+ const oldLayerData = state.layerData[idx];
529
+ const {layerData, layer} = calculateLayerData(newLayer, state, oldLayerData);
530
+ return updateStateWithLayerAndData(state, {layerData, layer, idx});
531
+ }
532
+
533
+ return updateStateWithLayerAndData(state, {layer: newLayer, idx});
534
+ }
535
+
536
+ /**
537
+ * Update filter property
538
+ * @memberof visStateUpdaters
539
+ * @type {typeof import('./vis-state-updaters').setFilterAnimationTimeUpdater}
540
+ * @public
541
+ */
542
+ export function setFilterAnimationTimeUpdater(state, action) {
543
+ return setFilterUpdater(state, action);
544
+ }
545
+
546
+ /**
547
+ * Update filter animation window
548
+ * @memberof visStateUpdaters
549
+ * @type {typeof import('./vis-state-updaters').setFilterAnimationWindowUpdater}
550
+ * @public
551
+ */
552
+ export function setFilterAnimationWindowUpdater(state, {id, animationWindow}) {
553
+ return {
554
+ ...state,
555
+ filters: state.filters.map(f =>
556
+ f.id === id
557
+ ? {
558
+ ...f,
559
+ animationWindow
560
+ }
561
+ : f
562
+ )
563
+ };
564
+ }
565
+ /**
566
+ * Update filter property
567
+ * @memberof visStateUpdaters
568
+ * @type {typeof import('./vis-state-updaters').setFilterUpdater}
569
+ * @public
570
+ */
571
+ export function setFilterUpdater(state, action) {
572
+ const {idx, prop, value, valueIndex = 0} = action;
573
+ const oldFilter = state.filters[idx];
574
+
575
+ if (!oldFilter) {
576
+ Console.error(`filters.${idx} is undefined`);
577
+ return state;
578
+ }
579
+ let newFilter = set([prop], value, oldFilter);
580
+ let newState = state;
581
+
582
+ const {dataId} = newFilter;
583
+
584
+ // Ensuring backward compatibility
585
+ let datasetIds = toArray(dataId);
586
+
587
+ switch (prop) {
588
+ // TODO: Next PR for UI if we update dataId, we need to consider two cases:
589
+ // 1. dataId is empty: create a default filter
590
+ // 2. Add a new dataset id
591
+ case FILTER_UPDATER_PROPS.dataId:
592
+ // if trying to update filter dataId. create an empty new filter
593
+ newFilter = updateFilterDataId(dataId);
594
+ break;
595
+
596
+ case FILTER_UPDATER_PROPS.name:
597
+ // we are supporting the current functionality
598
+ // TODO: Next PR for UI filter name will only update filter name but it won't have side effects
599
+ // we are gonna use pair of datasets and fieldIdx to update the filter
600
+ const datasetId = newFilter.dataId[valueIndex];
601
+ const {filter: updatedFilter, dataset: newDataset} = applyFilterFieldName(
602
+ newFilter,
603
+ state.datasets[datasetId],
604
+ value,
605
+ valueIndex,
606
+ {mergeDomain: false}
607
+ );
608
+ if (!updatedFilter) {
609
+ return state;
610
+ }
611
+
612
+ newFilter = updatedFilter;
613
+
614
+ if (newFilter.gpu) {
615
+ newFilter = setFilterGpuMode(newFilter, state.filters);
616
+ newFilter = assignGpuChannel(newFilter, state.filters);
617
+ }
618
+
619
+ newState = set(['datasets', datasetId], newDataset, state);
620
+
621
+ // only filter the current dataset
622
+ break;
623
+ case FILTER_UPDATER_PROPS.layerId:
624
+ // We need to update only datasetId/s if we have added/removed layers
625
+ // - check for layerId changes (XOR works because of string values)
626
+ // if no differences between layerIds, don't do any filtering
627
+ // @ts-ignore
628
+ const layerIdDifference = xor(newFilter.layerId, oldFilter.layerId);
629
+
630
+ const layerDataIds = uniq(
631
+ layerIdDifference
632
+ .map(lid =>
633
+ get(
634
+ state.layers.find(l => l.id === lid),
635
+ ['config', 'dataId']
636
+ )
637
+ )
638
+ .filter(d => d)
639
+ );
640
+
641
+ // only filter datasetsIds
642
+ datasetIds = layerDataIds;
643
+
644
+ // Update newFilter dataIds
645
+ const newDataIds = uniq(
646
+ newFilter.layerId
647
+ .map(lid =>
648
+ get(
649
+ state.layers.find(l => l.id === lid),
650
+ ['config', 'dataId']
651
+ )
652
+ )
653
+ .filter(d => d)
654
+ );
655
+
656
+ newFilter = {
657
+ ...newFilter,
658
+ dataId: newDataIds
659
+ };
660
+
661
+ break;
662
+ default:
663
+ break;
664
+ }
665
+
666
+ const enlargedFilter = state.filters.find(f => f.enlarged);
667
+
668
+ if (enlargedFilter && enlargedFilter.id !== newFilter.id) {
669
+ // there should be only one enlarged filter
670
+ newFilter.enlarged = false;
671
+ }
672
+
673
+ // save new filters to newState
674
+ newState = set(['filters', idx], newFilter, newState);
675
+
676
+ // if we are currently setting a prop that only requires to filter the current
677
+ // dataset we will pass only the current dataset to applyFiltersToDatasets and
678
+ // updateAllLayerDomainData otherwise we pass the all list of datasets as defined in dataId
679
+ const datasetIdsToFilter = LIMITED_FILTER_EFFECT_PROPS[prop]
680
+ ? [datasetIds[valueIndex]]
681
+ : datasetIds;
682
+
683
+ // filter data
684
+ const filteredDatasets = applyFiltersToDatasets(
685
+ datasetIdsToFilter,
686
+ newState.datasets,
687
+ newState.filters,
688
+ newState.layers
689
+ );
690
+
691
+ newState = set(['datasets'], filteredDatasets, newState);
692
+ // dataId is an array
693
+ // pass only the dataset we need to update
694
+ newState = updateAllLayerDomainData(newState, datasetIdsToFilter, newFilter);
695
+
696
+ return newState;
697
+ }
698
+
699
+ /**
700
+ * Set the property of a filter plot
701
+ * @memberof visStateUpdaters
702
+ * @type {typeof import('./vis-state-updaters').setFilterPlotUpdater}
703
+ * @public
704
+ */
705
+ export const setFilterPlotUpdater = (state, {idx, newProp, valueIndex = 0}) => {
706
+ let newFilter = {...state.filters[idx], ...newProp};
707
+ const prop = Object.keys(newProp)[0];
708
+ if (prop === 'yAxis') {
709
+ const plotType = getDefaultFilterPlotType(newFilter);
710
+ // TODO: plot is not supported in multi dataset filter for now
711
+ if (plotType) {
712
+ newFilter = {
713
+ ...newFilter,
714
+ ...getFilterPlot({...newFilter, plotType}, state.datasets[newFilter.dataId[valueIndex]]),
715
+ plotType
716
+ };
717
+ }
718
+ }
719
+
720
+ return {
721
+ ...state,
722
+ filters: state.filters.map((f, i) => (i === idx ? newFilter : f))
723
+ };
724
+ };
725
+
726
+ /**
727
+ * Add a new filter
728
+ * @memberof visStateUpdaters
729
+ * @type {typeof import('./vis-state-updaters').addFilterUpdater}
730
+ * @public
731
+ */
732
+ export const addFilterUpdater = (state, action) =>
733
+ !action.dataId
734
+ ? state
735
+ : {
736
+ ...state,
737
+ filters: [...state.filters, getDefaultFilter(action.dataId)]
738
+ };
739
+
740
+ /**
741
+ * Set layer color palette ui state
742
+ * @memberof visStateUpdaters
743
+ * @type {typeof import('./vis-state-updaters').layerColorUIChangeUpdater}
744
+ */
745
+ export const layerColorUIChangeUpdater = (state, {oldLayer, prop, newConfig}) => {
746
+ const oldVixConfig = oldLayer.config.visConfig[prop];
747
+ const newLayer = oldLayer.updateLayerColorUI(prop, newConfig);
748
+ const newVisConfig = newLayer.config.visConfig[prop];
749
+ if (oldVixConfig !== newVisConfig) {
750
+ return layerVisConfigChangeUpdater(state, {
751
+ oldLayer,
752
+ newVisConfig: {
753
+ [prop]: newVisConfig
754
+ }
755
+ });
756
+ }
757
+ return {
758
+ ...state,
759
+ layers: state.layers.map(l => (l.id === oldLayer.id ? newLayer : l))
760
+ };
761
+ };
762
+
763
+ /**
764
+ * Start and end filter animation
765
+ * @memberof visStateUpdaters
766
+ * @type {typeof import('./vis-state-updaters').toggleFilterAnimationUpdater}
767
+ * @public
768
+ */
769
+ export const toggleFilterAnimationUpdater = (state, action) => ({
770
+ ...state,
771
+ filters: state.filters.map((f, i) => (i === action.idx ? {...f, isAnimating: !f.isAnimating} : f))
772
+ });
773
+
774
+ /**
775
+ * @memberof visStateUpdaters
776
+ * @type {typeof import('./vis-state-updaters').toggleLayerAnimationUpdater}
777
+ * @public
778
+ */
779
+ export const toggleLayerAnimationUpdater = state => ({
780
+ ...state,
781
+ animationConfig: {
782
+ ...state.animationConfig,
783
+ isAnimating: !state.animationConfig.isAnimating
784
+ }
785
+ });
786
+
787
+ /**
788
+ * Hide and show layer animation control
789
+ * @memberof visStateUpdaters
790
+ * @type {typeof import('./vis-state-updaters').toggleLayerAnimationControlUpdater}
791
+ * @public
792
+ */
793
+ export const toggleLayerAnimationControlUpdater = state => ({
794
+ ...state,
795
+ animationConfig: {
796
+ ...state.animationConfig,
797
+ hideControl: !state.animationConfig.hideControl
798
+ }
799
+ });
800
+
801
+ /**
802
+ * Change filter animation speed
803
+ * @memberof visStateUpdaters
804
+ * @type {typeof import('./vis-state-updaters').updateFilterAnimationSpeedUpdater}
805
+ * @public
806
+ */
807
+ export const updateFilterAnimationSpeedUpdater = (state, action) => ({
808
+ ...state,
809
+ filters: state.filters.map((f, i) => (i === action.idx ? {...f, speed: action.speed} : f))
810
+ });
811
+
812
+ /**
813
+ * Reset animation config current time to a specified value
814
+ * @memberof visStateUpdaters
815
+ * @type {typeof import('./vis-state-updaters').setLayerAnimationTimeUpdater}
816
+ * @public
817
+ *
818
+ */
819
+ export const setLayerAnimationTimeUpdater = (state, {value}) => ({
820
+ ...state,
821
+ animationConfig: {
822
+ ...state.animationConfig,
823
+ currentTime: value
824
+ }
825
+ });
826
+
827
+ /**
828
+ * Update animation speed with the vertical speed slider
829
+ * @memberof visStateUpdaters
830
+ * @type {typeof import('./vis-state-updaters').updateLayerAnimationSpeedUpdater}
831
+ * @public
832
+ *
833
+ */
834
+ export const updateLayerAnimationSpeedUpdater = (state, {speed}) => {
835
+ return {
836
+ ...state,
837
+ animationConfig: {
838
+ ...state.animationConfig,
839
+ speed
840
+ }
841
+ };
842
+ };
843
+
844
+ /**
845
+ * Show larger time filter at bottom for time playback (apply to time filter only)
846
+ * @memberof visStateUpdaters
847
+ * @type {typeof import('./vis-state-updaters').enlargeFilterUpdater}
848
+ * @public
849
+ */
850
+ export const enlargeFilterUpdater = (state, action) => {
851
+ return {
852
+ ...state,
853
+ filters: state.filters.map((f, i) =>
854
+ i === action.idx
855
+ ? {
856
+ ...f,
857
+ enlarged: !f.enlarged
858
+ }
859
+ : f
860
+ )
861
+ };
862
+ };
863
+
864
+ /**
865
+ * Toggles filter feature visibility
866
+ * @memberof visStateUpdaters
867
+ * @type {typeof import('./vis-state-updaters').toggleFilterFeatureUpdater}
868
+ */
869
+ export const toggleFilterFeatureUpdater = (state, action) => {
870
+ const filter = state.filters[action.idx];
871
+ const isVisible = get(filter, ['value', 'properties', 'isVisible']);
872
+ const newFilter = {
873
+ ...filter,
874
+ value: featureToFilterValue(filter.value, filter.id, {
875
+ isVisible: !isVisible
876
+ })
877
+ };
878
+
879
+ return {
880
+ ...state,
881
+ filters: Object.assign([...state.filters], {[action.idx]: newFilter})
882
+ };
883
+ };
884
+
885
+ /**
886
+ * Remove a filter
887
+ * @memberof visStateUpdaters
888
+ * @type {typeof import('./vis-state-updaters').removeFilterUpdater}
889
+ * @public
890
+ */
891
+ export const removeFilterUpdater = (state, action) => {
892
+ const {idx} = action;
893
+ const {dataId, id} = state.filters[idx];
894
+
895
+ const newFilters = [
896
+ ...state.filters.slice(0, idx),
897
+ ...state.filters.slice(idx + 1, state.filters.length)
898
+ ];
899
+
900
+ const filteredDatasets = applyFiltersToDatasets(dataId, state.datasets, newFilters, state.layers);
901
+ const newEditor =
902
+ getFilterIdInFeature(state.editor.selectedFeature) === id
903
+ ? {
904
+ ...state.editor,
905
+ selectedFeature: null
906
+ }
907
+ : state.editor;
908
+
909
+ let newState = set(['filters'], newFilters, state);
910
+ newState = set(['datasets'], filteredDatasets, newState);
911
+ newState = set(['editor'], newEditor, newState);
912
+
913
+ return updateAllLayerDomainData(newState, dataId, undefined);
914
+ };
915
+
916
+ /**
917
+ * Add a new layer
918
+ * @memberof visStateUpdaters
919
+ * @type {typeof import('./vis-state-updaters').addLayerUpdater}
920
+ * @public
921
+ */
922
+ export const addLayerUpdater = (state, action) => {
923
+ let newLayer;
924
+ let newLayerData;
925
+ if (action.config) {
926
+ newLayer = createLayerFromConfig(state, action.config);
927
+ if (!newLayer) {
928
+ Console.warn(
929
+ 'Failed to create layer from config, it usually means the config is not be in correct format',
930
+ action.config
931
+ );
932
+ return state;
933
+ }
934
+
935
+ const result = calculateLayerData(newLayer, state);
936
+ newLayer = result.layer;
937
+ newLayerData = result.layerData;
938
+ } else {
939
+ // create an empty layer with the first available dataset
940
+ const defaultDataset = Object.keys(state.datasets)[0];
941
+ newLayer = new Layer({
942
+ isVisible: true,
943
+ isConfigActive: true,
944
+ dataId: defaultDataset
945
+ });
946
+ newLayerData = {};
947
+ }
948
+ return {
949
+ ...state,
950
+ layers: [...state.layers, newLayer],
951
+ layerData: [...state.layerData, newLayerData],
952
+ layerOrder: [...state.layerOrder, state.layerOrder.length],
953
+ splitMaps: addNewLayersToSplitMap(state.splitMaps, newLayer)
954
+ };
955
+ };
956
+
957
+ /**
958
+ * remove layer
959
+ * @memberof visStateUpdaters
960
+ * @type {typeof import('./vis-state-updaters').removeLayerUpdater}
961
+ * @public
962
+ */
963
+ export const removeLayerUpdater = (state, {idx}) => {
964
+ const {layers, layerData, clicked, hoverInfo} = state;
965
+ const layerToRemove = state.layers[idx];
966
+ const newMaps = removeLayerFromSplitMaps(state.splitMaps, layerToRemove);
967
+
968
+ const newState = {
969
+ ...state,
970
+ layers: [...layers.slice(0, idx), ...layers.slice(idx + 1, layers.length)],
971
+ layerData: [...layerData.slice(0, idx), ...layerData.slice(idx + 1, layerData.length)],
972
+ layerOrder: state.layerOrder.filter(i => i !== idx).map(pid => (pid > idx ? pid - 1 : pid)),
973
+ clicked: layerToRemove.isLayerHovered(clicked) ? undefined : clicked,
974
+ hoverInfo: layerToRemove.isLayerHovered(hoverInfo) ? undefined : hoverInfo,
975
+ splitMaps: newMaps
976
+ // TODO: update filters, create helper to remove layer form filter (remove layerid and dataid) if mapped
977
+ };
978
+
979
+ return updateAnimationDomain(newState);
980
+ };
981
+
982
+ /**
983
+ * duplicate layer
984
+ * @memberof visStateUpdaters
985
+ * @type {typeof import('./vis-state-updaters').duplicateLayerUpdater}
986
+ * @public
987
+ */
988
+ export const duplicateLayerUpdater = (state, {idx}) => {
989
+ const {layers} = state;
990
+ const original = state.layers[idx];
991
+ const originalLayerOrderIdx = state.layerOrder.findIndex(i => i === idx);
992
+
993
+ if (!original) {
994
+ Console.warn(`layer.${idx} is undefined`);
995
+ return state;
996
+ }
997
+ let newLabel = `Copy of ${original.config.label}`;
998
+ let postfix = 0;
999
+ // eslint-disable-next-line no-loop-func
1000
+ while (layers.find(l => l.config.label === newLabel)) {
1001
+ newLabel = `Copy of ${original.config.label} ${++postfix}`;
1002
+ }
1003
+
1004
+ // collect layer config from original
1005
+ const loadedLayer = serializeLayer(original);
1006
+
1007
+ // assign new id and label to copied layer
1008
+ if (!loadedLayer.config) {
1009
+ return state;
1010
+ }
1011
+ loadedLayer.config.label = newLabel;
1012
+ loadedLayer.id = generateHashId(LAYER_ID_LENGTH);
1013
+
1014
+ // add layer to state
1015
+ let nextState = addLayerUpdater(state, {config: loadedLayer});
1016
+
1017
+ // new added layer are at the end, move it to be on top of original layer
1018
+ const newLayerOrderIdx = nextState.layerOrder.length - 1;
1019
+ const newLayerOrder = arrayInsert(
1020
+ nextState.layerOrder.slice(0, newLayerOrderIdx),
1021
+ originalLayerOrderIdx,
1022
+ newLayerOrderIdx
1023
+ );
1024
+
1025
+ nextState = {
1026
+ ...nextState,
1027
+ layerOrder: newLayerOrder
1028
+ };
1029
+
1030
+ return updateAnimationDomain(nextState);
1031
+ };
1032
+
1033
+ /**
1034
+ * Reorder layer
1035
+ * @memberof visStateUpdaters
1036
+ * @type {typeof import('./vis-state-updaters').reorderLayerUpdater}
1037
+ * @public
1038
+ */
1039
+ export const reorderLayerUpdater = (state, {order}) => ({
1040
+ ...state,
1041
+ layerOrder: order
1042
+ });
1043
+
1044
+ /**
1045
+ * Remove a dataset and all layers, filters, tooltip configs that based on it
1046
+ * @memberof visStateUpdaters
1047
+ * @type {typeof import('./vis-state-updaters').removeDatasetUpdater}
1048
+ * @public
1049
+ */
1050
+ export const removeDatasetUpdater = (state, action) => {
1051
+ // extract dataset key
1052
+ const {dataId: datasetKey} = action;
1053
+ const {datasets} = state;
1054
+
1055
+ // check if dataset is present
1056
+ if (!datasets[datasetKey]) {
1057
+ return state;
1058
+ }
1059
+
1060
+ /* eslint-disable no-unused-vars */
1061
+ const {
1062
+ layers,
1063
+ datasets: {[datasetKey]: dataset, ...newDatasets}
1064
+ } = state;
1065
+ /* eslint-enable no-unused-vars */
1066
+
1067
+ const indexes = layers.reduce((listOfIndexes, layer, index) => {
1068
+ if (layer.config.dataId === datasetKey) {
1069
+ // @ts-ignore
1070
+ listOfIndexes.push(index);
1071
+ }
1072
+ return listOfIndexes;
1073
+ }, []);
1074
+
1075
+ // remove layers and datasets
1076
+ const {newState} = indexes.reduce(
1077
+ ({newState: currentState, indexCounter}, idx) => {
1078
+ const currentIndex = idx - indexCounter;
1079
+ currentState = removeLayerUpdater(currentState, {idx: currentIndex});
1080
+ indexCounter++;
1081
+ return {newState: currentState, indexCounter};
1082
+ },
1083
+ {newState: {...state, datasets: newDatasets}, indexCounter: 0}
1084
+ );
1085
+
1086
+ // remove filters
1087
+ const filters = state.filters.filter(filter => !filter.dataId.includes(datasetKey));
1088
+
1089
+ // update interactionConfig
1090
+ let {interactionConfig} = state;
1091
+ const {tooltip} = interactionConfig;
1092
+ if (tooltip) {
1093
+ const {config} = tooltip;
1094
+ /* eslint-disable no-unused-vars */
1095
+ const {[datasetKey]: fields, ...fieldsToShow} = config.fieldsToShow;
1096
+ /* eslint-enable no-unused-vars */
1097
+ interactionConfig = {
1098
+ ...interactionConfig,
1099
+ tooltip: {...tooltip, config: {...config, fieldsToShow}}
1100
+ };
1101
+ }
1102
+
1103
+ return {...newState, filters, interactionConfig};
1104
+ };
1105
+
1106
+ /**
1107
+ * update layer blending mode
1108
+ * @memberof visStateUpdaters
1109
+ * @type {typeof import('./vis-state-updaters').updateLayerBlendingUpdater}
1110
+ * @public
1111
+ */
1112
+ export const updateLayerBlendingUpdater = (state, action) => ({
1113
+ ...state,
1114
+ layerBlending: action.mode
1115
+ });
1116
+
1117
+ /**
1118
+ * Display dataset table in a modal
1119
+ * @memberof visStateUpdaters
1120
+ * @type {typeof import('./vis-state-updaters').showDatasetTableUpdater}
1121
+ * @public
1122
+ */
1123
+ export const showDatasetTableUpdater = (state, action) => {
1124
+ return {
1125
+ ...state,
1126
+ editingDataset: action.dataId
1127
+ };
1128
+ };
1129
+
1130
+ /**
1131
+ * reset visState to initial State
1132
+ * @memberof visStateUpdaters
1133
+ * @type {typeof import('./vis-state-updaters').resetMapConfigUpdater}
1134
+ * @public
1135
+ */
1136
+ export const resetMapConfigUpdater = state => ({
1137
+ ...INITIAL_VIS_STATE,
1138
+ ...state.initialState,
1139
+ initialState: state.initialState
1140
+ });
1141
+
1142
+ /**
1143
+ * Propagate `visState` reducer with a new configuration. Current config will be override.
1144
+ * @memberof visStateUpdaters
1145
+ * @type {typeof import('./vis-state-updaters').receiveMapConfigUpdater}
1146
+ * @public
1147
+ */
1148
+ export const receiveMapConfigUpdater = (state, {payload: {config = {}, options = {}}}) => {
1149
+ if (!config.visState) {
1150
+ return state;
1151
+ }
1152
+
1153
+ const {keepExistingConfig} = options;
1154
+
1155
+ // reset config if keepExistingConfig is falsy
1156
+ let mergedState = !keepExistingConfig ? resetMapConfigUpdater(state) : state;
1157
+ for (const merger of state.mergers) {
1158
+ if (isValidMerger(merger) && config.visState[merger.prop]) {
1159
+ mergedState = merger.merge(mergedState, config.visState[merger.prop], true);
1160
+ }
1161
+ }
1162
+
1163
+ return mergedState;
1164
+ };
1165
+
1166
+ /**
1167
+ * Trigger layer hover event with hovered object
1168
+ * @memberof visStateUpdaters
1169
+ * @type {typeof import('./vis-state-updaters').layerHoverUpdater}
1170
+ * @public
1171
+ */
1172
+ export const layerHoverUpdater = (state, action) => ({
1173
+ ...state,
1174
+ hoverInfo: action.info
1175
+ });
1176
+
1177
+ /* eslint-enable max-statements */
1178
+
1179
+ /**
1180
+ * Update `interactionConfig`
1181
+ * @memberof visStateUpdaters
1182
+ * @type {typeof import('./vis-state-updaters').interactionConfigChangeUpdater}
1183
+ * @public
1184
+ */
1185
+ export function interactionConfigChangeUpdater(state, action) {
1186
+ const {config} = action;
1187
+
1188
+ const interactionConfig = {
1189
+ ...state.interactionConfig,
1190
+ ...{[config.id]: config}
1191
+ };
1192
+
1193
+ // Don't enable tooltip and brush at the same time
1194
+ // but coordinates can be shown at all time
1195
+ const contradict = ['brush', 'tooltip'];
1196
+
1197
+ if (
1198
+ contradict.includes(config.id) &&
1199
+ config.enabled &&
1200
+ !state.interactionConfig[config.id].enabled
1201
+ ) {
1202
+ // only enable one interaction at a time
1203
+ contradict.forEach(k => {
1204
+ if (k !== config.id) {
1205
+ interactionConfig[k] = {...interactionConfig[k], enabled: false};
1206
+ }
1207
+ });
1208
+ }
1209
+
1210
+ const newState = {
1211
+ ...state,
1212
+ interactionConfig
1213
+ };
1214
+
1215
+ if (config.id === 'geocoder' && !config.enabled) {
1216
+ return removeDatasetUpdater(newState, {dataId: 'geocoder_dataset'});
1217
+ }
1218
+
1219
+ return newState;
1220
+ }
1221
+
1222
+ /**
1223
+ * Trigger layer click event with clicked object
1224
+ * @memberof visStateUpdaters
1225
+ * @type {typeof import('./vis-state-updaters').layerClickUpdater}
1226
+ * @public
1227
+ */
1228
+ export const layerClickUpdater = (state, action) => ({
1229
+ ...state,
1230
+ mousePos: state.interactionConfig.coordinate.enabled
1231
+ ? {
1232
+ ...state.mousePos,
1233
+ pinned: state.mousePos.pinned ? null : cloneDeep(state.mousePos)
1234
+ }
1235
+ : state.mousePos,
1236
+ clicked: action.info && action.info.picked ? action.info : null
1237
+ });
1238
+
1239
+ /**
1240
+ * Trigger map click event, unselect clicked object
1241
+ * @memberof visStateUpdaters
1242
+ * @type {typeof import('./vis-state-updaters').mapClickUpdater}
1243
+ * @public
1244
+ */
1245
+ export const mapClickUpdater = state => {
1246
+ return {
1247
+ ...state,
1248
+ clicked: null
1249
+ };
1250
+ };
1251
+
1252
+ /**
1253
+ * Trigger map move event
1254
+ * @memberof visStateUpdaters
1255
+ * @type {typeof import('./vis-state-updaters').mouseMoveUpdater}
1256
+ * @public
1257
+ */
1258
+ export const mouseMoveUpdater = (state, {evt}) => {
1259
+ if (Object.values(state.interactionConfig).some(config => config.enabled)) {
1260
+ return {
1261
+ ...state,
1262
+ mousePos: {
1263
+ ...state.mousePos,
1264
+ mousePosition: [...evt.point],
1265
+ coordinate: [...evt.lngLat]
1266
+ }
1267
+ };
1268
+ }
1269
+
1270
+ return state;
1271
+ };
1272
+ /**
1273
+ * Toggle visibility of a layer for a split map
1274
+ * @memberof visStateUpdaters
1275
+ * @type {typeof import('./vis-state-updaters').toggleSplitMapUpdater}
1276
+ * @public
1277
+ */
1278
+ export const toggleSplitMapUpdater = (state, action) =>
1279
+ state.splitMaps && state.splitMaps.length === 0
1280
+ ? {
1281
+ ...state,
1282
+ // maybe we should use an array to store state for a single map as well
1283
+ // if current maps length is equal to 0 it means that we are about to split the view
1284
+ splitMaps: computeSplitMapLayers(state.layers)
1285
+ }
1286
+ : closeSpecificMapAtIndex(state, action);
1287
+
1288
+ /**
1289
+ * Toggle visibility of a layer in a split map
1290
+ * @memberof visStateUpdaters
1291
+ * @type {typeof import('./vis-state-updaters').toggleLayerForMapUpdater}
1292
+ * @public
1293
+ */
1294
+ export const toggleLayerForMapUpdater = (state, {mapIndex, layerId}) => {
1295
+ const {splitMaps} = state;
1296
+
1297
+ return {
1298
+ ...state,
1299
+ splitMaps: splitMaps.map((sm, i) =>
1300
+ i === mapIndex
1301
+ ? {
1302
+ ...splitMaps[i],
1303
+ layers: {
1304
+ ...splitMaps[i].layers,
1305
+ // if layerId not in layers, set it to visible
1306
+ [layerId]: !splitMaps[i].layers[layerId]
1307
+ }
1308
+ }
1309
+ : sm
1310
+ )
1311
+ };
1312
+ };
1313
+
1314
+ /**
1315
+ * Add new dataset to `visState`, with option to load a map config along with the datasets
1316
+ * @memberof visStateUpdaters
1317
+ * @type {typeof import('./vis-state-updaters').updateVisDataUpdater}
1318
+ * @public
1319
+ */
1320
+ /* eslint-disable max-statements */
1321
+ // eslint-disable-next-line complexity
1322
+ export const updateVisDataUpdater = (state, action) => {
1323
+ // datasets can be a single data entries or an array of multiple data entries
1324
+ const {config, options} = action;
1325
+ const datasets = toArray(action.datasets);
1326
+
1327
+ const newDataEntries = datasets.reduce(
1328
+ (accu, {info = {}, ...rest} = {}) => ({
1329
+ ...accu,
1330
+ ...(createNewDataEntry({info, ...rest}, state.datasets) || {})
1331
+ }),
1332
+ {}
1333
+ );
1334
+
1335
+ const dataEmpty = Object.keys(newDataEntries).length < 1;
1336
+
1337
+ // apply config if passed from action
1338
+ const previousState = config
1339
+ ? receiveMapConfigUpdater(state, {
1340
+ payload: {config, options}
1341
+ })
1342
+ : state;
1343
+
1344
+ let mergedState = {
1345
+ ...previousState,
1346
+ datasets: {
1347
+ ...previousState.datasets,
1348
+ ...newDataEntries
1349
+ }
1350
+ };
1351
+
1352
+ // merge state with config to be merged
1353
+ for (const merger of mergedState.mergers) {
1354
+ if (isValidMerger(merger) && merger.toMergeProp && mergedState[merger.toMergeProp]) {
1355
+ const toMerge = mergedState[merger.toMergeProp];
1356
+ mergedState[merger.toMergeProp] = INITIAL_VIS_STATE[merger.toMergeProp];
1357
+ mergedState = merger.merge(mergedState, toMerge);
1358
+ }
1359
+ }
1360
+
1361
+ let newLayers = !dataEmpty
1362
+ ? mergedState.layers.filter(l => l.config.dataId && l.config.dataId in newDataEntries)
1363
+ : [];
1364
+
1365
+ if (!newLayers.length && (options || {}).autoCreateLayers !== false) {
1366
+ // no layer merged, find defaults
1367
+ const result = addDefaultLayers(mergedState, newDataEntries);
1368
+ mergedState = result.state;
1369
+ newLayers = result.newLayers;
1370
+ }
1371
+
1372
+ if (mergedState.splitMaps.length) {
1373
+ // if map is split, add new layers to splitMaps
1374
+ newLayers = mergedState.layers.filter(
1375
+ l => l.config.dataId && l.config.dataId in newDataEntries
1376
+ );
1377
+ mergedState = {
1378
+ ...mergedState,
1379
+ splitMaps: addNewLayersToSplitMap(mergedState.splitMaps, newLayers)
1380
+ };
1381
+ }
1382
+
1383
+ // if no tooltips merged add default tooltips
1384
+ Object.keys(newDataEntries).forEach(dataId => {
1385
+ const tooltipFields = mergedState.interactionConfig.tooltip.config.fieldsToShow[dataId];
1386
+ if (!Array.isArray(tooltipFields) || !tooltipFields.length) {
1387
+ mergedState = addDefaultTooltips(mergedState, newDataEntries[dataId]);
1388
+ }
1389
+ });
1390
+
1391
+ let updatedState = updateAllLayerDomainData(
1392
+ mergedState,
1393
+ dataEmpty ? Object.keys(mergedState.datasets) : Object.keys(newDataEntries),
1394
+ undefined
1395
+ );
1396
+
1397
+ // register layer animation domain,
1398
+ // need to be called after layer data is calculated
1399
+ updatedState = updateAnimationDomain(updatedState);
1400
+
1401
+ return updatedState;
1402
+ };
1403
+ /* eslint-enable max-statements */
1404
+
1405
+ /**
1406
+ * Rename an existing dataset in `visState`
1407
+ * @memberof visStateUpdaters
1408
+ * @type {typeof import('./vis-state-updaters').renameDatasetUpdater}
1409
+ * @public
1410
+ */
1411
+ export function renameDatasetUpdater(state, action) {
1412
+ const {dataId, label} = action;
1413
+ const {datasets} = state;
1414
+ const existing = datasets[dataId];
1415
+ // @ts-ignore
1416
+ return existing
1417
+ ? {
1418
+ ...state,
1419
+ datasets: {
1420
+ ...datasets,
1421
+ [dataId]: {
1422
+ ...existing,
1423
+ label
1424
+ }
1425
+ }
1426
+ }
1427
+ : // No-op if the dataset doesn't exist
1428
+ state;
1429
+ }
1430
+
1431
+ /**
1432
+ * When a user clicks on the specific map closing icon
1433
+ * the application will close the selected map
1434
+ * and will merge the remaining one with the global state
1435
+ * TODO: i think in the future this action should be called merge map layers with global settings
1436
+ * @param {Object} state `visState`
1437
+ * @param {Object} action action
1438
+ * @returns {Object} nextState
1439
+ */
1440
+ export function closeSpecificMapAtIndex(state, action) {
1441
+ // retrieve layers meta data from the remaining map that we need to keep
1442
+ const indexToRetrieve = 1 - action.payload;
1443
+ const mapLayers = state.splitMaps[indexToRetrieve].layers;
1444
+ const {layers} = state;
1445
+
1446
+ // update layer visibility
1447
+ const newLayers = layers.map(layer =>
1448
+ !mapLayers[layer.id] && layer.config.isVisible
1449
+ ? layer.updateLayerConfig({
1450
+ // if layer.id is not in mapLayers, it should be inVisible
1451
+ isVisible: false
1452
+ })
1453
+ : layer
1454
+ );
1455
+
1456
+ // delete map
1457
+ return {
1458
+ ...state,
1459
+ layers: newLayers,
1460
+ splitMaps: []
1461
+ };
1462
+ }
1463
+
1464
+ /**
1465
+ * Trigger file loading dispatch `addDataToMap` if succeed, or `loadFilesErr` if failed
1466
+ * @memberof visStateUpdaters
1467
+ * @type {typeof import('./vis-state-updaters').loadFilesUpdater}
1468
+ * @public
1469
+ */
1470
+ export const loadFilesUpdater = (state, action) => {
1471
+ const {files, onFinish = loadFilesSuccess} = action;
1472
+ if (!files.length) {
1473
+ return state;
1474
+ }
1475
+
1476
+ const fileLoadingProgress = Array.from(files).reduce(
1477
+ (accu, f, i) => merge_(initialFileLoadingProgress(f, i))(accu),
1478
+ {}
1479
+ );
1480
+
1481
+ const fileLoading = {
1482
+ fileCache: [],
1483
+ filesToLoad: files,
1484
+ onFinish
1485
+ };
1486
+
1487
+ const nextState = merge_({fileLoadingProgress, fileLoading})(state);
1488
+
1489
+ return loadNextFileUpdater(nextState);
1490
+ };
1491
+
1492
+ /**
1493
+ * Sucessfully loaded one file, move on to the next one
1494
+ * @memberof visStateUpdaters
1495
+ * @type {typeof import('./vis-state-updaters').loadFileStepSuccessUpdater}
1496
+ * @public
1497
+ */
1498
+ export function loadFileStepSuccessUpdater(state, action) {
1499
+ if (!state.fileLoading) {
1500
+ return state;
1501
+ }
1502
+ const {fileName, fileCache} = action;
1503
+ const {filesToLoad, onFinish} = state.fileLoading;
1504
+ const stateWithProgress = updateFileLoadingProgressUpdater(state, {
1505
+ fileName,
1506
+ progress: {percent: 1, message: 'Done'}
1507
+ });
1508
+
1509
+ // save processed file to fileCache
1510
+ const stateWithCache = pick_('fileLoading')(merge_({fileCache}))(stateWithProgress);
1511
+
1512
+ return withTask(
1513
+ stateWithCache,
1514
+ DELAY_TASK(200).map(filesToLoad.length ? loadNextFile : () => onFinish(fileCache))
1515
+ );
1516
+ }
1517
+
1518
+ // withTask<T>(state: T, task: any): T
1519
+
1520
+ /**
1521
+ *
1522
+ * @memberof visStateUpdaters
1523
+ * @type {typeof import('./vis-state-updaters').loadNextFileUpdater}
1524
+ * @public
1525
+ */
1526
+ export function loadNextFileUpdater(state) {
1527
+ if (!state.fileLoading) {
1528
+ return state;
1529
+ }
1530
+ const {filesToLoad} = state.fileLoading;
1531
+ const [file, ...remainingFilesToLoad] = filesToLoad;
1532
+
1533
+ // save filesToLoad to state
1534
+ const nextState = pick_('fileLoading')(merge_({filesToLoad: remainingFilesToLoad}))(state);
1535
+
1536
+ const stateWithProgress = updateFileLoadingProgressUpdater(nextState, {
1537
+ fileName: file.name,
1538
+ progress: {percent: 0, message: 'loading...'}
1539
+ });
1540
+
1541
+ const {loaders, loadOptions} = state;
1542
+ return withTask(
1543
+ stateWithProgress,
1544
+ makeLoadFileTask(file, nextState.fileLoading.fileCache, loaders, loadOptions)
1545
+ );
1546
+ }
1547
+
1548
+ export function makeLoadFileTask(file, fileCache, loaders = [], loadOptions = {}) {
1549
+ return LOAD_FILE_TASK({file, fileCache, loaders, loadOptions}).bimap(
1550
+ // prettier ignore
1551
+ // success
1552
+ gen =>
1553
+ nextFileBatch({
1554
+ gen,
1555
+ fileName: file.name,
1556
+ onFinish: result =>
1557
+ processFileContent({
1558
+ content: result,
1559
+ fileCache
1560
+ })
1561
+ }),
1562
+
1563
+ // error
1564
+ err => loadFilesErr(file.name, err)
1565
+ );
1566
+ }
1567
+
1568
+ /**
1569
+ *
1570
+ * @memberof visStateUpdaters
1571
+ * @type {typeof import('./vis-state-updaters').processFileContentUpdater}
1572
+ * @public
1573
+ */
1574
+ export function processFileContentUpdater(state, action) {
1575
+ const {content, fileCache} = action.payload;
1576
+
1577
+ const stateWithProgress = updateFileLoadingProgressUpdater(state, {
1578
+ fileName: content.fileName,
1579
+ progress: {percent: 1, message: 'processing...'}
1580
+ });
1581
+
1582
+ return withTask(
1583
+ stateWithProgress,
1584
+ PROCESS_FILE_DATA({content, fileCache}).bimap(
1585
+ result => loadFileStepSuccess({fileName: content.fileName, fileCache: result}),
1586
+ err => loadFilesErr(content.fileName, err)
1587
+ )
1588
+ );
1589
+ }
1590
+
1591
+ export function parseProgress(prevProgress = {}, progress) {
1592
+ // This happens when receiving query metadata or other cases we don't
1593
+ // have an update for the user.
1594
+ if (!progress || !progress.percent) {
1595
+ return {};
1596
+ }
1597
+
1598
+ return {
1599
+ percent: progress.percent
1600
+ };
1601
+ }
1602
+
1603
+ /**
1604
+ * gets called with payload = AsyncGenerator<???>
1605
+ * @memberof visStateUpdaters
1606
+ * @type {typeof import('./vis-state-updaters').nextFileBatchUpdater}
1607
+ * @public
1608
+ */
1609
+ export const nextFileBatchUpdater = (
1610
+ state,
1611
+ {payload: {gen, fileName, progress, accumulated, onFinish}}
1612
+ ) => {
1613
+ const stateWithProgress = updateFileLoadingProgressUpdater(state, {
1614
+ fileName,
1615
+ progress: parseProgress(state.fileLoadingProgress[fileName], progress)
1616
+ });
1617
+ return withTask(
1618
+ stateWithProgress,
1619
+ UNWRAP_TASK(gen.next()).bimap(
1620
+ ({value, done}) => {
1621
+ return done
1622
+ ? onFinish(accumulated)
1623
+ : nextFileBatch({
1624
+ gen,
1625
+ fileName,
1626
+ progress: value.progress,
1627
+ accumulated: value,
1628
+ onFinish
1629
+ });
1630
+ },
1631
+ err => loadFilesErr(fileName, err)
1632
+ )
1633
+ );
1634
+ };
1635
+
1636
+ /**
1637
+ * Trigger loading file error
1638
+ * @memberof visStateUpdaters
1639
+ * @type {typeof import('./vis-state-updaters').loadFilesErrUpdater}
1640
+ * @public
1641
+ */
1642
+ export const loadFilesErrUpdater = (state, {error, fileName}) => {
1643
+ // update ui with error message
1644
+ Console.warn(error);
1645
+ if (!state.fileLoading) {
1646
+ return state;
1647
+ }
1648
+ const {filesToLoad, onFinish, fileCache} = state.fileLoading;
1649
+
1650
+ const nextState = updateFileLoadingProgressUpdater(state, {
1651
+ fileName,
1652
+ progress: {error}
1653
+ });
1654
+
1655
+ // kick off next file or finish
1656
+ return withTask(
1657
+ nextState,
1658
+ DELAY_TASK(200).map(filesToLoad.length ? loadNextFile : () => onFinish(fileCache))
1659
+ );
1660
+ };
1661
+
1662
+ /**
1663
+ * When select dataset for export, apply cpu filter to selected dataset
1664
+ * @memberof visStateUpdaters
1665
+ * @type {typeof import('./vis-state-updaters').applyCPUFilterUpdater}
1666
+ * @public
1667
+ */
1668
+ export const applyCPUFilterUpdater = (state, {dataId}) => {
1669
+ // apply cpuFilter
1670
+ const dataIds = toArray(dataId);
1671
+
1672
+ return dataIds.reduce((accu, id) => filterDatasetCPU(accu, id), state);
1673
+ };
1674
+
1675
+ /**
1676
+ * User input to update the info of the map
1677
+ * @memberof visStateUpdaters
1678
+ * @type {typeof import('./vis-state-updaters').setMapInfoUpdater}
1679
+ * @public
1680
+ */
1681
+ export const setMapInfoUpdater = (state, action) => ({
1682
+ ...state,
1683
+ mapInfo: {
1684
+ ...state.mapInfo,
1685
+ ...action.info
1686
+ }
1687
+ });
1688
+ /**
1689
+ * Helper function to update All layer domain and layer data of state
1690
+ * @type {typeof import('./vis-state-updaters').addDefaultLayers}
1691
+ */
1692
+ export function addDefaultLayers(state, datasets) {
1693
+ /** @type {Layer[]} */
1694
+ const empty = [];
1695
+ const defaultLayers = Object.values(datasets).reduce((accu, dataset) => {
1696
+ const foundLayers = findDefaultLayer(dataset, state.layerClasses);
1697
+ return foundLayers && foundLayers.length ? accu.concat(foundLayers) : accu;
1698
+ }, empty);
1699
+
1700
+ return {
1701
+ state: {
1702
+ ...state,
1703
+ layers: [...state.layers, ...defaultLayers],
1704
+ layerOrder: [
1705
+ // put new layers on top of old ones
1706
+ ...defaultLayers.map((_, i) => state.layers.length + i),
1707
+ ...state.layerOrder
1708
+ ]
1709
+ },
1710
+ newLayers: defaultLayers
1711
+ };
1712
+ }
1713
+
1714
+ /**
1715
+ * helper function to find default tooltips
1716
+ * @param {Object} state
1717
+ * @param {Object} dataset
1718
+ * @returns {Object} nextState
1719
+ */
1720
+ export function addDefaultTooltips(state, dataset) {
1721
+ const tooltipFields = dataset.metadata.isDynamicSpatialIndex
1722
+ ? {[dataset.id]: []}
1723
+ : findFieldsToShow(dataset);
1724
+ const merged = {
1725
+ ...state.interactionConfig.tooltip.config.fieldsToShow,
1726
+ ...tooltipFields
1727
+ };
1728
+
1729
+ return set(['interactionConfig', 'tooltip', 'config', 'fieldsToShow'], merged, state);
1730
+ }
1731
+
1732
+ export function initialFileLoadingProgress(file, index) {
1733
+ const fileName = file.name || `Untitled File ${index}`;
1734
+ return {
1735
+ [fileName]: {
1736
+ // percent of current file
1737
+ percent: 0,
1738
+ message: '',
1739
+ fileName,
1740
+ error: null
1741
+ }
1742
+ };
1743
+ }
1744
+
1745
+ export function updateFileLoadingProgressUpdater(state, {fileName, progress}) {
1746
+ return pick_('fileLoadingProgress')(pick_(fileName)(merge_(progress)))(state);
1747
+ }
1748
+ /**
1749
+ * Helper function to update layer domains for an array of datasets
1750
+ * @type {typeof import('./vis-state-updaters').updateAllLayerDomainData}
1751
+ */
1752
+ export function updateAllLayerDomainData(state, dataId, updatedFilter) {
1753
+ const dataIds = typeof dataId === 'string' ? [dataId] : dataId;
1754
+ const newLayers = [];
1755
+ const newLayerData = [];
1756
+
1757
+ state.layers.forEach((oldLayer, i) => {
1758
+ if (oldLayer.config.dataId && dataIds.includes(oldLayer.config.dataId)) {
1759
+ // No need to recalculate layer domain if filter has fixed domain
1760
+ const newLayer =
1761
+ updatedFilter && updatedFilter.fixedDomain
1762
+ ? oldLayer
1763
+ : oldLayer.updateLayerDomain(state.datasets, updatedFilter);
1764
+
1765
+ const {layerData, layer} = calculateLayerData(newLayer, state, state.layerData[i]);
1766
+
1767
+ newLayers.push(layer);
1768
+ newLayerData.push(layerData);
1769
+ } else {
1770
+ newLayers.push(oldLayer);
1771
+ newLayerData.push(state.layerData[i]);
1772
+ }
1773
+ });
1774
+
1775
+ const newState = {
1776
+ ...state,
1777
+ layers: newLayers,
1778
+ layerData: newLayerData
1779
+ };
1780
+
1781
+ return newState;
1782
+ }
1783
+
1784
+ export function updateAnimationDomain(state) {
1785
+ // merge all animatable layer domain and update global config
1786
+ const animatableLayers = state.layers.filter(
1787
+ l =>
1788
+ l.config.isVisible &&
1789
+ l.config.animation &&
1790
+ l.config.animation.enabled &&
1791
+ Array.isArray(l.animationDomain)
1792
+ );
1793
+
1794
+ if (!animatableLayers.length) {
1795
+ return {
1796
+ ...state,
1797
+ animationConfig: {
1798
+ ...state.animationConfig,
1799
+ domain: null,
1800
+ defaultTimeFormat: null
1801
+ }
1802
+ };
1803
+ }
1804
+
1805
+ const mergedDomain = animatableLayers.reduce(
1806
+ (accu, layer) => [
1807
+ Math.min(accu[0], layer.animationDomain[0]),
1808
+ Math.max(accu[1], layer.animationDomain[1])
1809
+ ],
1810
+ [Number(Infinity), -Infinity]
1811
+ );
1812
+ const defaultTimeFormat = getTimeWidgetTitleFormatter(mergedDomain);
1813
+
1814
+ return {
1815
+ ...state,
1816
+ animationConfig: {
1817
+ ...state.animationConfig,
1818
+ currentTime: isInRange(state.animationConfig.currentTime, mergedDomain)
1819
+ ? state.animationConfig.currentTime
1820
+ : mergedDomain[0],
1821
+ domain: mergedDomain,
1822
+ defaultTimeFormat
1823
+ }
1824
+ };
1825
+ }
1826
+
1827
+ /**
1828
+ * Update the status of the editor
1829
+ * @memberof visStateUpdaters
1830
+ * @type {typeof import('./vis-state-updaters').setEditorModeUpdater}
1831
+ */
1832
+ export const setEditorModeUpdater = (state, {mode}) => ({
1833
+ ...state,
1834
+ editor: {
1835
+ ...state.editor,
1836
+ mode,
1837
+ selectedFeature: null
1838
+ }
1839
+ });
1840
+
1841
+ // const featureToFilterValue = (feature) => ({...feature, id: feature.id});
1842
+ /**
1843
+ * Update editor features
1844
+ * @memberof visStateUpdaters
1845
+ * @type {typeof import('./vis-state-updaters').setFeaturesUpdater}
1846
+ */
1847
+ export function setFeaturesUpdater(state, {features = []}) {
1848
+ const lastFeature = features.length && features[features.length - 1];
1849
+
1850
+ const newState = {
1851
+ ...state,
1852
+ editor: {
1853
+ ...state.editor,
1854
+ // only save none filter features to editor
1855
+ features: features.filter(f => !getFilterIdInFeature(f)),
1856
+ mode: lastFeature && lastFeature.properties.isClosed ? EDITOR_MODES.EDIT : state.editor.mode
1857
+ }
1858
+ };
1859
+
1860
+ // Retrieve existing feature
1861
+ const {selectedFeature} = state.editor;
1862
+
1863
+ // If no feature is selected we can simply return since no operations
1864
+ if (!selectedFeature) {
1865
+ return newState;
1866
+ }
1867
+
1868
+ // TODO: check if the feature has changed
1869
+ const feature = features.find(f => f.id === selectedFeature.id);
1870
+
1871
+ // if feature is part of a filter
1872
+ const filterId = feature && getFilterIdInFeature(feature);
1873
+ if (filterId && feature) {
1874
+ const featureValue = featureToFilterValue(feature, filterId);
1875
+ const filterIdx = state.filters.findIndex(fil => fil.id === filterId);
1876
+ return setFilterUpdater(newState, {
1877
+ idx: filterIdx,
1878
+ prop: 'value',
1879
+ value: featureValue
1880
+ });
1881
+ }
1882
+
1883
+ return newState;
1884
+ }
1885
+
1886
+ /**
1887
+ * Set the current selected feature
1888
+ * @memberof uiStateUpdaters
1889
+ * @type {typeof import('./vis-state-updaters').setSelectedFeatureUpdater}
1890
+ */
1891
+ export const setSelectedFeatureUpdater = (state, {feature}) => ({
1892
+ ...state,
1893
+ editor: {
1894
+ ...state.editor,
1895
+ selectedFeature: feature
1896
+ }
1897
+ });
1898
+
1899
+ /**
1900
+ * Delete existing feature from filters
1901
+ * @memberof visStateUpdaters
1902
+ * @type {typeof import('./vis-state-updaters').deleteFeatureUpdater}
1903
+ */
1904
+ export function deleteFeatureUpdater(state, {feature}) {
1905
+ if (!feature) {
1906
+ return state;
1907
+ }
1908
+
1909
+ const newState = {
1910
+ ...state,
1911
+ editor: {
1912
+ ...state.editor,
1913
+ selectedFeature: null
1914
+ }
1915
+ };
1916
+
1917
+ if (getFilterIdInFeature(feature)) {
1918
+ const filterIdx = newState.filters.findIndex(f => f.id === getFilterIdInFeature(feature));
1919
+
1920
+ return filterIdx > -1 ? removeFilterUpdater(newState, {idx: filterIdx}) : newState;
1921
+ }
1922
+
1923
+ // modify editor object
1924
+ const newEditor = {
1925
+ ...state.editor,
1926
+ features: state.editor.features.filter(f => f.id !== feature.id),
1927
+ selectedFeature: null
1928
+ };
1929
+
1930
+ return {
1931
+ ...state,
1932
+ editor: newEditor
1933
+ };
1934
+ }
1935
+
1936
+ /**
1937
+ * Toggle feature as layer filter
1938
+ * @memberof visStateUpdaters
1939
+ * @type {typeof import('./vis-state-updaters').setPolygonFilterLayerUpdater}
1940
+ */
1941
+ export function setPolygonFilterLayerUpdater(state, payload) {
1942
+ const {layer, feature} = payload;
1943
+ const filterId = getFilterIdInFeature(feature);
1944
+
1945
+ // let newFilter = null;
1946
+ let filterIdx;
1947
+ let newLayerId = [layer.id];
1948
+ let newState = state;
1949
+ // If polygon filter already exists, we need to find out if the current layer is already included
1950
+ if (filterId) {
1951
+ filterIdx = state.filters.findIndex(f => f.id === filterId);
1952
+
1953
+ if (!state.filters[filterIdx]) {
1954
+ // what if filter doesn't exist?... not possible.
1955
+ // because features in the editor is passed in from filters and editors.
1956
+ // but we will move this feature back to editor just in case
1957
+ const noneFilterFeature = {
1958
+ ...feature,
1959
+ properties: {
1960
+ ...feature.properties,
1961
+ filterId: null
1962
+ }
1963
+ };
1964
+
1965
+ return {
1966
+ ...state,
1967
+ editor: {
1968
+ ...state.editor,
1969
+ features: [...state.editor.features, noneFilterFeature],
1970
+ selectedFeature: noneFilterFeature
1971
+ }
1972
+ };
1973
+ }
1974
+ const filter = state.filters[filterIdx];
1975
+ const {layerId = []} = filter;
1976
+ const isLayerIncluded = layerId.includes(layer.id);
1977
+
1978
+ newLayerId = isLayerIncluded
1979
+ ? // if layer is included, remove it
1980
+ layerId.filter(l => l !== layer.id)
1981
+ : [...layerId, layer.id];
1982
+ } else {
1983
+ // if we haven't create the polygon filter, create it
1984
+ const newFilter = generatePolygonFilter([], feature);
1985
+ filterIdx = state.filters.length;
1986
+
1987
+ // add feature, remove feature from eidtor
1988
+ newState = {
1989
+ ...state,
1990
+ filters: [...state.filters, newFilter],
1991
+ editor: {
1992
+ ...state.editor,
1993
+ features: state.editor.features.filter(f => f.id !== feature.id),
1994
+ selectedFeature: newFilter.value
1995
+ }
1996
+ };
1997
+ }
1998
+
1999
+ return setFilterUpdater(newState, {
2000
+ idx: filterIdx,
2001
+ prop: 'layerId',
2002
+ value: newLayerId
2003
+ });
2004
+ }
2005
+
2006
+ /**
2007
+ * @memberof visStateUpdaters
2008
+ * @type {typeof import('./vis-state-updaters').sortTableColumnUpdater}
2009
+ * @public
2010
+ */
2011
+ export function sortTableColumnUpdater(state, {dataId, column, mode}) {
2012
+ const dataset = state.datasets[dataId];
2013
+ if (!dataset) {
2014
+ return state;
2015
+ }
2016
+ let sortMode = mode;
2017
+ if (!sortMode) {
2018
+ const currentMode = get(dataset, ['sortColumn', column]);
2019
+ // @ts-ignore - should be fixable in a TS file
2020
+ sortMode = currentMode
2021
+ ? Object.keys(SORT_ORDER).find(m => m !== currentMode)
2022
+ : SORT_ORDER.ASCENDING;
2023
+ }
2024
+
2025
+ const sorted = sortDatasetByColumn(dataset, column, sortMode);
2026
+ return set(['datasets', dataId], sorted, state);
2027
+ }
2028
+
2029
+ /**
2030
+ * @memberof visStateUpdaters
2031
+ * @type {typeof import('./vis-state-updaters').pinTableColumnUpdater}
2032
+ * @public
2033
+ */
2034
+ export function pinTableColumnUpdater(state, {dataId, column}) {
2035
+ const dataset = state.datasets[dataId];
2036
+ if (!dataset) {
2037
+ return state;
2038
+ }
2039
+ const field = dataset.fields.find(f => f.name === column);
2040
+ if (!field) {
2041
+ return state;
2042
+ }
2043
+
2044
+ let pinnedColumns;
2045
+ if (Array.isArray(dataset.pinnedColumns) && dataset.pinnedColumns.includes(field.name)) {
2046
+ // unpin it
2047
+ pinnedColumns = dataset.pinnedColumns.filter(co => co !== field.name);
2048
+ } else {
2049
+ pinnedColumns = (dataset.pinnedColumns || []).concat(field.name);
2050
+ }
2051
+
2052
+ return set(['datasets', dataId, 'pinnedColumns'], pinnedColumns, state);
2053
+ }
2054
+
2055
+ /**
2056
+ * Copy column content as strings
2057
+ * @memberof visStateUpdaters
2058
+ * @type {typeof import('./vis-state-updaters').copyTableColumnUpdater}
2059
+ * @public
2060
+ */
2061
+ export function copyTableColumnUpdater(state, {dataId, column}) {
2062
+ const dataset = state.datasets[dataId];
2063
+ if (!dataset) {
2064
+ return state;
2065
+ }
2066
+ const fieldIdx = dataset.fields.findIndex(f => f.name === column);
2067
+ if (fieldIdx < 0) {
2068
+ return state;
2069
+ }
2070
+ const {type} = dataset.fields[fieldIdx];
2071
+ const text = dataset.dataContainer
2072
+ .map(row => parseFieldValue(row.valueAt(fieldIdx), type), true)
2073
+ .join('\n');
2074
+
2075
+ copy(text);
2076
+
2077
+ return state;
2078
+ }
2079
+
2080
+ /**
2081
+ * Update editor
2082
+ * @type {typeof import('./vis-state-updaters').toggleEditorVisibilityUpdater}
2083
+ */
2084
+ export function toggleEditorVisibilityUpdater(state) {
2085
+ return {
2086
+ ...state,
2087
+ editor: {
2088
+ ...state.editor,
2089
+ visible: !state.editor.visible
2090
+ }
2091
+ };
2092
+ }
2093
+
2094
+ export function setFilterAnimationTimeConfigUpdater(state, {idx, config}) {
2095
+ const oldFilter = state.filters[idx];
2096
+ if (!oldFilter) {
2097
+ Console.error(`filters.${idx} is undefined`);
2098
+ return state;
2099
+ }
2100
+ if (oldFilter.type !== FILTER_TYPES.timeRange) {
2101
+ Console.error(
2102
+ `setFilterAnimationTimeConfig can only be called to update a time filter. check filter.type === 'timeRange'`
2103
+ );
2104
+ return state;
2105
+ }
2106
+
2107
+ const updates = checkTimeConfigArgs(config);
2108
+
2109
+ return pick_('filters')(swap_(merge_(updates)(oldFilter)))(state);
2110
+ }
2111
+
2112
+ function checkTimeConfigArgs(config) {
2113
+ const allowed = ['timeFormat', 'timezone'];
2114
+ return Object.keys(config).reduce((accu, prop) => {
2115
+ if (!allowed.includes(prop)) {
2116
+ Console.error(
2117
+ `setLayerAnimationTimeConfig takes timeFormat and/or timezone as options, found ${prop}`
2118
+ );
2119
+ return accu;
2120
+ }
2121
+
2122
+ // here we are NOT checking if timezone or timeFormat input is valid
2123
+ accu[prop] = config[prop];
2124
+ return accu;
2125
+ }, {});
2126
+ }
2127
+ /**
2128
+ * Update editor
2129
+ * @type {typeof import('./vis-state-updaters').setLayerAnimationTimeConfigUpdater}
2130
+ */
2131
+ export function setLayerAnimationTimeConfigUpdater(state, {config}) {
2132
+ if (!config) {
2133
+ return state;
2134
+ }
2135
+ const updates = checkTimeConfigArgs(config);
2136
+ return pick_('animationConfig')(merge_(updates))(state);
2137
+ }