@vitessce/vit-s 2.0.3-beta.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/dist/index.js +41348 -18
  2. package/dist-tsc/CallbackPublisher.d.ts +18 -0
  3. package/dist-tsc/CallbackPublisher.d.ts.map +1 -0
  4. package/{dist → dist-tsc}/CallbackPublisher.js +6 -12
  5. package/dist-tsc/LoadingIndicator.d.ts +2 -0
  6. package/dist-tsc/LoadingIndicator.d.ts.map +1 -0
  7. package/{dist → dist-tsc}/LoadingIndicator.js +1 -2
  8. package/dist-tsc/TitleInfo.d.ts +2 -0
  9. package/dist-tsc/TitleInfo.d.ts.map +1 -0
  10. package/{dist → dist-tsc}/TitleInfo.js +6 -83
  11. package/dist-tsc/VitS.d.ts +45 -0
  12. package/dist-tsc/VitS.d.ts.map +1 -0
  13. package/dist-tsc/VitS.js +119 -0
  14. package/dist-tsc/VitessceGrid.d.ts +23 -0
  15. package/dist-tsc/VitessceGrid.d.ts.map +1 -0
  16. package/{dist → dist-tsc}/VitessceGrid.js +14 -13
  17. package/dist-tsc/VitessceGrid.test.d.ts +2 -0
  18. package/dist-tsc/VitessceGrid.test.d.ts.map +1 -0
  19. package/{dist → dist-tsc}/VitessceGrid.test.js +8 -4
  20. package/dist-tsc/Warning.d.ts +2 -0
  21. package/dist-tsc/Warning.d.ts.map +1 -0
  22. package/{dist → dist-tsc}/Warning.js +2 -2
  23. package/dist-tsc/classNames.d.ts +8 -0
  24. package/dist-tsc/classNames.d.ts.map +1 -0
  25. package/dist-tsc/data/AbstractLoader.d.ts +22 -0
  26. package/dist-tsc/data/AbstractLoader.d.ts.map +1 -0
  27. package/dist-tsc/data/AbstractLoader.js +18 -0
  28. package/dist-tsc/data/AbstractTwoStepLoader.d.ts +6 -0
  29. package/dist-tsc/data/AbstractTwoStepLoader.d.ts.map +1 -0
  30. package/{dist → dist-tsc}/data/AbstractTwoStepLoader.js +1 -1
  31. package/dist-tsc/data/LoaderResult.d.ts +7 -0
  32. package/dist-tsc/data/LoaderResult.d.ts.map +1 -0
  33. package/dist-tsc/data/index.d.ts +4 -0
  34. package/dist-tsc/data/index.d.ts.map +1 -0
  35. package/dist-tsc/data/index.js +3 -0
  36. package/dist-tsc/data/loader-registry.d.ts +9 -0
  37. package/dist-tsc/data/loader-registry.d.ts.map +1 -0
  38. package/dist-tsc/data/loader-registry.js +27 -0
  39. package/dist-tsc/data-hook-utils.d.ts +69 -0
  40. package/dist-tsc/data-hook-utils.d.ts.map +1 -0
  41. package/{dist → dist-tsc}/data-hook-utils.js +4 -6
  42. package/dist-tsc/data-hooks.d.ts +77 -0
  43. package/dist-tsc/data-hooks.d.ts.map +1 -0
  44. package/{dist → dist-tsc}/data-hooks.js +4 -4
  45. package/dist-tsc/errors/AbstractLoaderError.d.ts +10 -0
  46. package/dist-tsc/errors/AbstractLoaderError.d.ts.map +1 -0
  47. package/dist-tsc/errors/DataSourceFetchError.d.ts +8 -0
  48. package/dist-tsc/errors/DataSourceFetchError.d.ts.map +1 -0
  49. package/{dist → dist-tsc}/errors/DataSourceFetchError.js +1 -1
  50. package/dist-tsc/errors/DatasetNotFoundError.d.ts +6 -0
  51. package/dist-tsc/errors/DatasetNotFoundError.d.ts.map +1 -0
  52. package/{dist → dist-tsc}/errors/DatasetNotFoundError.js +1 -1
  53. package/dist-tsc/errors/LoaderNotFoundError.d.ts +10 -0
  54. package/dist-tsc/errors/LoaderNotFoundError.d.ts.map +1 -0
  55. package/{dist → dist-tsc}/errors/LoaderNotFoundError.js +1 -1
  56. package/dist-tsc/errors/LoaderValidationError.d.ts +10 -0
  57. package/dist-tsc/errors/LoaderValidationError.d.ts.map +1 -0
  58. package/{dist → dist-tsc}/errors/LoaderValidationError.js +1 -1
  59. package/dist-tsc/errors/index.d.ts +6 -0
  60. package/dist-tsc/errors/index.d.ts.map +1 -0
  61. package/{dist → dist-tsc}/errors/index.js +5 -6
  62. package/dist-tsc/hooks.d.ts +80 -0
  63. package/dist-tsc/hooks.d.ts.map +1 -0
  64. package/{dist → dist-tsc}/hooks.js +60 -4
  65. package/dist-tsc/index.d.ts +11 -0
  66. package/dist-tsc/index.d.ts.map +1 -0
  67. package/dist-tsc/index.js +11 -0
  68. package/dist-tsc/plugins.test.fixtures.d.ts +61 -0
  69. package/dist-tsc/plugins.test.fixtures.d.ts.map +1 -0
  70. package/{dist → dist-tsc}/schemas/config-1.0.16.schema.json +21 -41
  71. package/dist-tsc/schemas/obsSets.schema.d.ts +179 -0
  72. package/dist-tsc/schemas/obsSets.schema.d.ts.map +1 -0
  73. package/dist-tsc/schemas/obsSetsTabular.schema.d.ts +57 -0
  74. package/dist-tsc/schemas/obsSetsTabular.schema.d.ts.map +1 -0
  75. package/dist-tsc/schemas/raster.schema.d.ts +239 -0
  76. package/dist-tsc/schemas/raster.schema.d.ts.map +1 -0
  77. package/dist-tsc/shared-mui/components.d.ts +2 -0
  78. package/dist-tsc/shared-mui/components.d.ts.map +1 -0
  79. package/{dist → dist-tsc}/shared-mui/components.js +2 -8
  80. package/dist-tsc/shared-mui/container.d.ts +2 -0
  81. package/dist-tsc/shared-mui/container.d.ts.map +1 -0
  82. package/{dist → dist-tsc}/shared-mui/container.js +1 -1
  83. package/dist-tsc/shared-mui/styles.d.ts +5 -0
  84. package/dist-tsc/shared-mui/styles.d.ts.map +1 -0
  85. package/{dist → dist-tsc}/shared-mui/styles.js +4 -2
  86. package/dist-tsc/shared-plot-options/CellColorEncodingOption.d.ts +2 -0
  87. package/dist-tsc/shared-plot-options/CellColorEncodingOption.d.ts.map +1 -0
  88. package/{dist → dist-tsc}/shared-plot-options/CellColorEncodingOption.js +3 -4
  89. package/dist-tsc/shared-plot-options/OptionSelect.d.ts +2 -0
  90. package/dist-tsc/shared-plot-options/OptionSelect.d.ts.map +1 -0
  91. package/{dist → dist-tsc}/shared-plot-options/OptionSelect.js +2 -2
  92. package/dist-tsc/shared-plot-options/OptionsContainer.d.ts +2 -0
  93. package/dist-tsc/shared-plot-options/OptionsContainer.d.ts.map +1 -0
  94. package/{dist → dist-tsc}/shared-plot-options/OptionsContainer.js +2 -5
  95. package/dist-tsc/shared-plot-options/index.d.ts +5 -0
  96. package/dist-tsc/shared-plot-options/index.d.ts.map +1 -0
  97. package/dist-tsc/shared-plot-options/index.js +4 -0
  98. package/dist-tsc/shared-plot-options/styles.d.ts +2 -0
  99. package/dist-tsc/shared-plot-options/styles.d.ts.map +1 -0
  100. package/{dist → dist-tsc}/shared-plot-options/styles.js +1 -1
  101. package/dist-tsc/state/hooks.d.ts +216 -0
  102. package/dist-tsc/state/hooks.d.ts.map +1 -0
  103. package/{dist → dist-tsc}/state/hooks.js +47 -21
  104. package/dist-tsc/title-styles.d.ts +2 -0
  105. package/dist-tsc/title-styles.d.ts.map +1 -0
  106. package/dist-tsc/title-styles.js +72 -0
  107. package/dist-tsc/view-config-utils.d.ts +30 -0
  108. package/dist-tsc/view-config-utils.d.ts.map +1 -0
  109. package/{dist → dist-tsc}/view-config-utils.js +32 -84
  110. package/dist-tsc/view-config-utils.test.d.ts +2 -0
  111. package/dist-tsc/view-config-utils.test.d.ts.map +1 -0
  112. package/dist-tsc/view-config-utils.test.fixtures.d.ts +1049 -0
  113. package/dist-tsc/view-config-utils.test.fixtures.d.ts.map +1 -0
  114. package/{dist → dist-tsc}/view-config-utils.test.fixtures.js +118 -0
  115. package/dist-tsc/view-config-utils.test.js +209 -0
  116. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts +8 -0
  117. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts.map +1 -0
  118. package/{dist → dist-tsc}/vitessce-grid-layout/VitessceGridLayout.js +47 -28
  119. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.d.ts +2 -0
  120. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.d.ts.map +1 -0
  121. package/{dist → dist-tsc}/vitessce-grid-layout/VitessceGridLayout.test.js +13 -5
  122. package/dist-tsc/vitessce-grid-layout/index.d.ts +2 -0
  123. package/dist-tsc/vitessce-grid-layout/index.d.ts.map +1 -0
  124. package/dist-tsc/vitessce-grid-layout/index.js +1 -0
  125. package/dist-tsc/vitessce-grid-layout/layout-utils.d.ts +15 -0
  126. package/dist-tsc/vitessce-grid-layout/layout-utils.d.ts.map +1 -0
  127. package/{dist → dist-tsc}/vitessce-grid-layout/layout-utils.js +2 -1
  128. package/dist-tsc/vitessce-grid-layout/layout-utils.test.d.ts +2 -0
  129. package/dist-tsc/vitessce-grid-layout/layout-utils.test.d.ts.map +1 -0
  130. package/{dist → dist-tsc}/vitessce-grid-layout/layout-utils.test.js +3 -1
  131. package/dist-tsc/vitessce-grid-utils.d.ts +13 -0
  132. package/dist-tsc/vitessce-grid-utils.d.ts.map +1 -0
  133. package/{dist → dist-tsc}/vitessce-grid-utils.js +15 -14
  134. package/package.json +24 -11
  135. package/src/CallbackPublisher.js +77 -0
  136. package/src/LoadingIndicator.js +33 -0
  137. package/src/TitleInfo.js +167 -0
  138. package/src/VitS.js +202 -0
  139. package/src/VitessceGrid.js +118 -0
  140. package/src/VitessceGrid.test.jsx +57 -0
  141. package/src/Warning.js +62 -0
  142. package/src/classNames.js +8 -0
  143. package/src/data/AbstractLoader.js +23 -0
  144. package/src/data/AbstractTwoStepLoader.js +8 -0
  145. package/src/data/LoaderResult.js +8 -0
  146. package/src/data/index.js +3 -0
  147. package/src/data/loader-registry.js +28 -0
  148. package/src/data-hook-utils.js +195 -0
  149. package/src/data-hooks.js +354 -0
  150. package/src/errors/AbstractLoaderError.js +14 -0
  151. package/src/errors/DataSourceFetchError.js +15 -0
  152. package/src/errors/DatasetNotFoundError.js +23 -0
  153. package/src/errors/LoaderNotFoundError.js +24 -0
  154. package/src/errors/LoaderValidationError.js +23 -0
  155. package/src/errors/index.js +5 -0
  156. package/src/hooks.js +317 -0
  157. package/src/index.js +76 -0
  158. package/src/plugins.test.fixtures.js +78 -0
  159. package/src/schemas/config-0.1.0.schema.json +85 -0
  160. package/src/schemas/config-1.0.0.schema.json +733 -0
  161. package/src/schemas/config-1.0.1.schema.json +909 -0
  162. package/src/schemas/config-1.0.10.schema.json +969 -0
  163. package/src/schemas/config-1.0.11.schema.json +990 -0
  164. package/src/schemas/config-1.0.12.schema.json +997 -0
  165. package/src/schemas/config-1.0.13.schema.json +1013 -0
  166. package/src/schemas/config-1.0.14.schema.json +1048 -0
  167. package/src/schemas/config-1.0.15.schema.json +1048 -0
  168. package/src/schemas/config-1.0.16.schema.json +1089 -0
  169. package/src/schemas/config-1.0.2.schema.json +911 -0
  170. package/src/schemas/config-1.0.3.schema.json +911 -0
  171. package/src/schemas/config-1.0.4.schema.json +949 -0
  172. package/src/schemas/config-1.0.5.schema.json +949 -0
  173. package/src/schemas/config-1.0.6.schema.json +950 -0
  174. package/src/schemas/config-1.0.7.schema.json +950 -0
  175. package/src/schemas/config-1.0.8.schema.json +966 -0
  176. package/src/schemas/config-1.0.9.schema.json +965 -0
  177. package/src/schemas/fixtures/cellSets.good.json +16 -0
  178. package/src/schemas/fixtures/config-1.0.1.bad.json +1 -0
  179. package/src/schemas/fixtures/config-1.0.1.bad.message.json +11 -0
  180. package/src/schemas/fixtures/config-1.0.1.good.json +37 -0
  181. package/src/schemas/fixtures/config-1.0.2.bad.json +1 -0
  182. package/src/schemas/fixtures/config-1.0.2.bad.message.json +11 -0
  183. package/src/schemas/fixtures/config-1.0.2.good.json +38 -0
  184. package/src/schemas/fixtures/config-1.0.3.bad.json +1 -0
  185. package/src/schemas/fixtures/config-1.0.3.bad.message.json +11 -0
  186. package/src/schemas/fixtures/config-1.0.3.good.json +38 -0
  187. package/src/schemas/fixtures/obsSets.bad.json +1 -0
  188. package/src/schemas/fixtures/obsSets.bad.message.json +11 -0
  189. package/src/schemas/fixtures/obsSets.good.json +16 -0
  190. package/src/schemas/fixtures/obsSetsTabular.bad.json +1 -0
  191. package/src/schemas/fixtures/obsSetsTabular.bad.message.json +11 -0
  192. package/src/schemas/fixtures/obsSetsTabular.good.json +26 -0
  193. package/src/schemas/fixtures/raster.bad.json +1 -0
  194. package/src/schemas/fixtures/raster.bad.message.json +11 -0
  195. package/src/schemas/fixtures/raster.good.json +39 -0
  196. package/src/schemas/obsSets.schema.js +195 -0
  197. package/src/schemas/obsSetsTabular.schema.js +39 -0
  198. package/src/schemas/raster.schema.js +121 -0
  199. package/src/schemas/schema-schema.sh +34 -0
  200. package/src/shared-mui/components.js +81 -0
  201. package/src/shared-mui/container.js +212 -0
  202. package/src/shared-mui/styles.js +113 -0
  203. package/src/shared-plot-options/CellColorEncodingOption.js +42 -0
  204. package/src/shared-plot-options/OptionSelect.js +19 -0
  205. package/src/shared-plot-options/OptionsContainer.js +23 -0
  206. package/src/shared-plot-options/index.js +4 -0
  207. package/src/shared-plot-options/styles.js +49 -0
  208. package/src/state/hooks.js +640 -0
  209. package/src/title-styles.js +73 -0
  210. package/src/view-config-utils.js +263 -0
  211. package/src/view-config-utils.test.fixtures.js +893 -0
  212. package/src/view-config-utils.test.jsx +222 -0
  213. package/src/vitessce-grid-layout/VitessceGridLayout.js +179 -0
  214. package/src/vitessce-grid-layout/VitessceGridLayout.test.jsx +64 -0
  215. package/src/vitessce-grid-layout/index.js +1 -0
  216. package/src/vitessce-grid-layout/layout-utils.js +76 -0
  217. package/src/vitessce-grid-layout/layout-utils.test.js +167 -0
  218. package/src/vitessce-grid-utils.js +172 -0
  219. package/dist/VitS.js +0 -117
  220. package/dist/Vitessce.integration.test.js +0 -36
  221. package/dist/Vitessce.js +0 -101
  222. package/dist/component-registry.js +0 -16
  223. package/dist/data/AbstractLoader.js +0 -35
  224. package/dist/data/index.js +0 -3
  225. package/dist/data/loader-registry.js +0 -15
  226. package/dist/errors/OptionsValidationError.js +0 -15
  227. package/dist/export-utils.js +0 -70
  228. package/dist/export-utils.test.js +0 -66
  229. package/dist/file-options-schemas-legacy.js +0 -136
  230. package/dist/file-options-schemas-legacy.test.js +0 -126
  231. package/dist/file-options-schemas.js +0 -322
  232. package/dist/file-options-schemas.test.js +0 -23
  233. package/dist/joint-file-types-legacy.js +0 -278
  234. package/dist/joint-file-types-legacy.test.js +0 -400
  235. package/dist/joint-file-types.js +0 -148
  236. package/dist/joint-file-types.test.js +0 -139
  237. package/dist/loader-registry.js +0 -98
  238. package/dist/plugins.js +0 -154
  239. package/dist/plugins.test.js +0 -30
  240. package/dist/schemas/PrettyJsonSchema.js +0 -34
  241. package/dist/schemas/config-1.0.15.schema.test.js +0 -22
  242. package/dist/schemas/config-1.0.16.schema.test.js +0 -22
  243. package/dist/schemas/obs-sets-tabular.schema.js +0 -37
  244. package/dist/schemas/obs-sets.schema.js +0 -194
  245. package/dist/schemas/schema.test-old.js +0 -50
  246. package/dist/schemas/schema.test.js +0 -46
  247. package/dist/schemas-extra.js +0 -3
  248. package/dist/schemas.js +0 -4
  249. package/dist/shared-plot-options/index.js +0 -4
  250. package/dist/view-config-upgraders.js +0 -525
  251. package/dist/view-config-utils.test.js +0 -66
  252. package/dist/view-config-versions.js +0 -47
  253. package/dist/vitessce-grid-layout/index.js +0 -1
  254. /package/{dist → dist-tsc}/classNames.js +0 -0
  255. /package/{dist → dist-tsc}/data/LoaderResult.js +0 -0
  256. /package/{dist → dist-tsc}/errors/AbstractLoaderError.js +0 -0
  257. /package/{dist → dist-tsc}/plugins.test.fixtures.js +0 -0
  258. /package/{dist → dist-tsc}/schemas/config-0.1.0.schema.json +0 -0
  259. /package/{dist → dist-tsc}/schemas/config-1.0.0.schema.json +0 -0
  260. /package/{dist → dist-tsc}/schemas/config-1.0.1.schema.json +0 -0
  261. /package/{dist → dist-tsc}/schemas/config-1.0.10.schema.json +0 -0
  262. /package/{dist → dist-tsc}/schemas/config-1.0.11.schema.json +0 -0
  263. /package/{dist → dist-tsc}/schemas/config-1.0.12.schema.json +0 -0
  264. /package/{dist → dist-tsc}/schemas/config-1.0.13.schema.json +0 -0
  265. /package/{dist → dist-tsc}/schemas/config-1.0.14.schema.json +0 -0
  266. /package/{dist → dist-tsc}/schemas/config-1.0.15.schema.json +0 -0
  267. /package/{dist → dist-tsc}/schemas/config-1.0.2.schema.json +0 -0
  268. /package/{dist → dist-tsc}/schemas/config-1.0.3.schema.json +0 -0
  269. /package/{dist → dist-tsc}/schemas/config-1.0.4.schema.json +0 -0
  270. /package/{dist → dist-tsc}/schemas/config-1.0.5.schema.json +0 -0
  271. /package/{dist → dist-tsc}/schemas/config-1.0.6.schema.json +0 -0
  272. /package/{dist → dist-tsc}/schemas/config-1.0.7.schema.json +0 -0
  273. /package/{dist → dist-tsc}/schemas/config-1.0.8.schema.json +0 -0
  274. /package/{dist → dist-tsc}/schemas/config-1.0.9.schema.json +0 -0
  275. /package/{dist → dist-tsc}/schemas/obsSets.schema.js +0 -0
  276. /package/{dist → dist-tsc}/schemas/obsSetsTabular.schema.js +0 -0
  277. /package/{dist → dist-tsc}/schemas/raster.schema.js +0 -0
package/src/hooks.js ADDED
@@ -0,0 +1,317 @@
1
+ import {
2
+ useRef, useState, useEffect, useCallback, useMemo,
3
+ } from 'react';
4
+ import { debounce, every } from 'lodash-es';
5
+ import { extent } from 'd3-array';
6
+ import { capitalize, fromEntries } from '@vitessce/utils';
7
+ import { useGridResize, useEmitGridResize } from './state/hooks.js';
8
+ import { VITESSCE_CONTAINER } from './classNames.js';
9
+
10
+ function getWindowDimensions() {
11
+ const { innerWidth: width, innerHeight: height } = window;
12
+ return {
13
+ width,
14
+ height,
15
+ };
16
+ }
17
+
18
+ export function useVitessceContainer(ref) {
19
+ return useCallback(() => {
20
+ if (ref.current) {
21
+ return ref.current.closest(`.${VITESSCE_CONTAINER}`);
22
+ }
23
+ return null;
24
+ }, [ref]);
25
+ }
26
+
27
+ /**
28
+ * Custom hook, gets the full window dimensions.
29
+ * @returns {array} `[width, height]` where width and height
30
+ * are numbers.
31
+ */
32
+ export function useWindowDimensions() {
33
+ const [windowDimensions, setWindowDimensions] = useState(
34
+ getWindowDimensions(),
35
+ );
36
+
37
+ useEffect(() => {
38
+ function handleResize() {
39
+ setWindowDimensions(getWindowDimensions());
40
+ }
41
+ const onResizeDebounced = debounce(handleResize, 100, { trailing: true });
42
+
43
+ window.addEventListener('resize', onResizeDebounced);
44
+ return () => window.removeEventListener('resize', onResizeDebounced);
45
+ }, []);
46
+
47
+ return windowDimensions;
48
+ }
49
+
50
+ /**
51
+ * Custom hook, subscribes to GRID_RESIZE and window resize events.
52
+ * @returns {array} `[width, height, containerRef]` where width and height
53
+ * are numbers and containerRef is a React ref.
54
+ */
55
+ export function useGridItemSize() {
56
+ const containerRef = useRef();
57
+
58
+ const [height, setHeight] = useState();
59
+ const [width, setWidth] = useState();
60
+
61
+ const resizeCount = useGridResize();
62
+ const incrementResizeCount = useEmitGridResize();
63
+
64
+ // On window resize events, increment the grid resize count.
65
+ useEffect(() => {
66
+ function onWindowResize() {
67
+ incrementResizeCount();
68
+ }
69
+ const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
70
+ window.addEventListener('resize', onResizeDebounced);
71
+ onWindowResize();
72
+ return () => {
73
+ window.removeEventListener('resize', onResizeDebounced);
74
+ };
75
+ }, [incrementResizeCount]);
76
+
77
+ // On new grid resize counts, re-compute the component
78
+ // width/height.
79
+ useEffect(() => {
80
+ if (!containerRef.current) return;
81
+ const container = containerRef.current;
82
+ const containerRect = container.getBoundingClientRect();
83
+ setHeight(containerRect.height);
84
+ setWidth(containerRect.width);
85
+ }, [resizeCount]);
86
+
87
+ return [width, height, containerRef];
88
+ }
89
+
90
+ /**
91
+ * Custom hook, subscribes to GRID_RESIZE and window resize events.
92
+ * @returns {array} `[width, height, deckRef]` where width and height
93
+ * are numbers and deckRef is a React ref to be used with
94
+ * a <DeckGL/> element (or a forwardRef to one).
95
+ */
96
+ export function useDeckCanvasSize() {
97
+ const deckRef = useRef();
98
+
99
+ const [height, setHeight] = useState();
100
+ const [width, setWidth] = useState();
101
+
102
+ const resizeCount = useGridResize();
103
+ const incrementResizeCount = useEmitGridResize();
104
+
105
+ // On window resize events, increment the grid resize count.
106
+ useEffect(() => {
107
+ function onWindowResize() {
108
+ incrementResizeCount();
109
+ }
110
+ const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
111
+ window.addEventListener('resize', onResizeDebounced);
112
+ onWindowResize();
113
+ return () => {
114
+ window.removeEventListener('resize', onResizeDebounced);
115
+ };
116
+ }, [incrementResizeCount]);
117
+
118
+ // On new grid resize counts, re-compute the DeckGL canvas
119
+ // width/height.
120
+ useEffect(() => {
121
+ if (!deckRef.current) return;
122
+ const { canvas } = deckRef.current.deck;
123
+ const canvasRect = canvas.getBoundingClientRect();
124
+ setHeight(canvasRect.height);
125
+ setWidth(canvasRect.width);
126
+ }, [resizeCount]);
127
+
128
+ return [width, height, deckRef];
129
+ }
130
+
131
+ /**
132
+ * This hook handles a boolean isReady value,
133
+ * which only returns true once every item in the
134
+ * input list has been marked as "ready".
135
+ * @param {string[]} statusValues The items to wait on.
136
+ * @returns {boolean} Whether the status values are all success.
137
+ */
138
+ export function useReady(statusValues) {
139
+ return useMemo(() => every(
140
+ statusValues, val => val === 'success',
141
+ // eslint-disable-next-line react-hooks/exhaustive-deps
142
+ ), statusValues);
143
+ }
144
+
145
+ /**
146
+ * This hook helps manage a list of URLs.
147
+ * @param {object} loaders The loaders dependency.
148
+ * @param {string} dataset The dataset UID dependency.
149
+ * @returns {array} An array
150
+ * [urls, addUrl]
151
+ * where urls is the array of URL objects,
152
+ * and addUrl is a function for adding a URL to the array.
153
+ */
154
+ export function useUrls(loaders, dataset) {
155
+ const [urls, setUrls] = useState([]);
156
+
157
+ const addUrl = useCallback((url, name) => {
158
+ if (url) {
159
+ setUrls(prev => ([...prev, { url, name }]));
160
+ }
161
+ }, [setUrls]);
162
+
163
+ useEffect(() => {
164
+ setUrls([]);
165
+ }, [loaders, dataset]);
166
+
167
+ return [urls, addUrl];
168
+ }
169
+
170
+ /**
171
+ * Custom hook, subscribes to the width and height of the closest .vitessce-container
172
+ * element and updates upon window resize events.
173
+ * @param {Ref} ref A React ref object within the `.vitessce-container`.
174
+ * @returns {array} `[width, height]` where width and height
175
+ * are numbers.
176
+ */
177
+ export function useClosestVitessceContainerSize(ref) {
178
+ const [height, setHeight] = useState();
179
+ const [width, setWidth] = useState();
180
+
181
+ useEffect(() => {
182
+ function onWindowResize() {
183
+ if (ref.current) {
184
+ const {
185
+ clientHeight: componentHeight, clientWidth: componentWidth,
186
+ } = ref.current.closest(`.${VITESSCE_CONTAINER}`);
187
+ setWidth(componentWidth);
188
+ setHeight(componentHeight);
189
+ }
190
+ }
191
+ const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
192
+ window.addEventListener('resize', onResizeDebounced);
193
+ onWindowResize();
194
+ return () => {
195
+ window.removeEventListener('resize', onResizeDebounced);
196
+ };
197
+ }, [ref]);
198
+
199
+ return [width, height];
200
+ }
201
+
202
+ /**
203
+ * Normalize an obsFeatureMatrix to a Uint8Array.
204
+ * @param {object} params
205
+ * @param {object} params.obsFeatureMatrix The obsFeatureMatrix
206
+ * returned by the useObsFeatureMatrix hook.
207
+ * @returns {array} A tuple [obsFeatureMatrix, dataExtent]
208
+ * where obsFeatureMatrix
209
+ * is a Uint8Array with the same shape as
210
+ * params.obsFeatureMatrix.data, and dataExtent is the
211
+ * [min, max] of the original data.
212
+ */
213
+ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
214
+ return useMemo(() => {
215
+ if (obsFeatureMatrix && obsFeatureMatrix.data) {
216
+ const dataExtent = extent(obsFeatureMatrix.data);
217
+ const [min, max] = dataExtent;
218
+ const ratio = 255 / (max - min);
219
+ const data = new Uint8Array(
220
+ obsFeatureMatrix.data.map(i => Math.floor((i - min) * ratio)),
221
+ );
222
+ return [{ data }, dataExtent];
223
+ }
224
+ return [null, null];
225
+ }, [obsFeatureMatrix]);
226
+ }
227
+
228
+ /**
229
+ * Normalize a feature selection (data for selected
230
+ * columns of an obsFeatureMatrix) to a Uint8Array.
231
+ * @param {array|null} expressionData The expressionData
232
+ * returned by the useFeatureSelection hook,
233
+ * where each element corresponds to an
234
+ * array of values for a selected feature.
235
+ * @returns {array} A tuple [normData, extents] where
236
+ * normData is an array of Uint8Arrays (or null), and extents is
237
+ * an array of [min, max] values for each feature (or null).
238
+ */
239
+ export function useUint8FeatureSelection(expressionData) {
240
+ return useMemo(() => {
241
+ if (expressionData && expressionData[0]) {
242
+ const extents = expressionData.map(arr => extent(arr));
243
+ const normData = expressionData.map((arr, i) => {
244
+ const [min, max] = extents[i];
245
+ const ratio = 255 / (max - min);
246
+ return new Uint8Array(
247
+ arr.map(j => Math.floor((j - min) * ratio)),
248
+ );
249
+ });
250
+ return [normData, extents];
251
+ }
252
+ return [null, null];
253
+ }, [expressionData]);
254
+ }
255
+
256
+ export function useExpressionValueGetter(
257
+ { instanceObsIndex, matrixObsIndex, expressionData },
258
+ ) {
259
+ // Get a mapping from cell ID to row index in the gene expression matrix.
260
+ // Since the two obsIndices (instanceObsIndex = the obsIndex from obsEmbedding)
261
+ // may be ordered differently (matrixObsIndex = the obsIndex from obsFeatureMatrix),
262
+ // we need a way to look up an obsFeatureMatrix obsIndex index
263
+ // given an obsEmbedding obsIndex index.
264
+ const toMatrixIndexMap = useMemo(() => {
265
+ if (instanceObsIndex && matrixObsIndex) {
266
+ const matrixIndexMap = new Map(matrixObsIndex.map((key, i) => ([key, i])));
267
+ return instanceObsIndex.map(key => matrixIndexMap.get(key));
268
+ }
269
+ return null;
270
+ }, [instanceObsIndex, matrixObsIndex]);
271
+
272
+ // Set up a getter function for gene expression values, to be used
273
+ // by the DeckGL layer to obtain values for instanced attributes.
274
+ const getExpressionValue = useCallback((entry, { index: instanceIndex }) => {
275
+ if (toMatrixIndexMap && expressionData && expressionData[0]) {
276
+ const rowIndex = toMatrixIndexMap[instanceIndex];
277
+ const val = expressionData[0][rowIndex];
278
+ return val;
279
+ }
280
+ return 0;
281
+ }, [toMatrixIndexMap, expressionData]);
282
+ return getExpressionValue;
283
+ }
284
+
285
+ export function useGetObsMembership(obsSetsMembership) {
286
+ return useCallback((obsId) => {
287
+ if (obsId) {
288
+ return obsSetsMembership?.get(obsId) || [];
289
+ }
290
+ return [];
291
+ }, [obsSetsMembership]);
292
+ }
293
+
294
+ export function useGetObsInfo(obsType, obsLabelsTypes, obsLabelsData, obsSetsMembership) {
295
+ return useCallback((obsId) => {
296
+ if (obsId) {
297
+ const obsMembership = obsSetsMembership?.get(obsId) || [];
298
+ return {
299
+ [`${capitalize(obsType)} ID`]: obsId,
300
+ ...fromEntries(obsMembership.flatMap(path => path.slice(1).map((pathEl, elLevel) => ([
301
+ `${path[0]}${path.length > 2 ? ` L${elLevel + 1}` : ''}`,
302
+ pathEl,
303
+ ])))),
304
+ ...fromEntries(Object.entries(obsLabelsTypes).map(([scopeKey, obsLabelsType]) => ([
305
+ obsLabelsType,
306
+ obsLabelsData?.[scopeKey]?.obsLabels?.[
307
+ // TODO: Maybe all loaders that return obsIndex should also return an obsIndexMap
308
+ // with keys: obsId, values: obsIdx
309
+ // which would avoid the indexOf calls.
310
+ obsLabelsData?.[scopeKey]?.obsIndex?.indexOf(obsId)
311
+ ],
312
+ ])).filter(([obsLabelsType]) => Boolean(obsLabelsType))),
313
+ };
314
+ }
315
+ return null;
316
+ }, [obsType, obsLabelsTypes, obsLabelsData, obsSetsMembership]);
317
+ }
package/src/index.js ADDED
@@ -0,0 +1,76 @@
1
+ export { VitS } from './VitS.js';
2
+ export { TitleInfo } from './TitleInfo.js';
3
+ export { PopperMenu } from './shared-mui/components.js';
4
+ // For plugin view types:
5
+ export {
6
+ useReady,
7
+ useUrls,
8
+ useVitessceContainer,
9
+ useDeckCanvasSize,
10
+ useUint8ObsFeatureMatrix,
11
+ useUint8FeatureSelection,
12
+ useExpressionValueGetter,
13
+ useGetObsMembership,
14
+ useGetObsInfo,
15
+ useClosestVitessceContainerSize,
16
+ useWindowDimensions,
17
+ useGridItemSize,
18
+ } from './hooks.js';
19
+ export {
20
+ useCoordination,
21
+ useComplexCoordination,
22
+ useMultiCoordinationValues,
23
+ useMultiDatasetCoordination,
24
+ useDatasetUids,
25
+ useLoaders,
26
+ useMatchingLoader,
27
+ useViewConfigStore,
28
+ useViewConfigStoreApi,
29
+ useComponentHover,
30
+ useSetComponentHover,
31
+ useComponentViewInfo,
32
+ useSetComponentViewInfo,
33
+ useWarning,
34
+ useSetWarning,
35
+ useAuxiliaryCoordination,
36
+ useComponentLayout,
37
+ } from './state/hooks.js';
38
+ export {
39
+ useDescription,
40
+ useImageData,
41
+ useObsSetsData,
42
+ useObsEmbeddingData,
43
+ useFeatureSelection,
44
+ useObsFeatureMatrixIndices,
45
+ useMultiObsLabels,
46
+
47
+ useObsLocationsData,
48
+ useObsSegmentationsData,
49
+ useNeighborhoodsData,
50
+ useObsLabelsData,
51
+
52
+ useObsFeatureMatrixData,
53
+ useFeatureLabelsData,
54
+ useGenomicProfilesData,
55
+ } from './data-hooks.js';
56
+ export {
57
+ useHasLoader,
58
+ } from './data-hook-utils.js';
59
+ export {
60
+ AbstractLoader,
61
+ AbstractTwoStepLoader,
62
+ LoaderResult,
63
+ } from './data/index.js';
64
+ export {
65
+ AbstractLoaderError,
66
+ DatasetNotFoundError,
67
+ LoaderNotFoundError,
68
+ LoaderValidationError,
69
+ DataSourceFetchError,
70
+ } from './errors/index.js';
71
+ export {
72
+ CellColorEncodingOption,
73
+ OptionsContainer,
74
+ OptionSelect,
75
+ usePlotOptionsStyles,
76
+ } from './shared-plot-options/index.js';
@@ -0,0 +1,78 @@
1
+ export const convenienceFileDefsCollapsed = {
2
+ version: '1.0.15',
3
+ name: 'My config name',
4
+ description: 'My config description',
5
+ initStrategy: 'auto',
6
+ datasets: [
7
+ {
8
+ files: [
9
+ {
10
+ fileType: 'anndata.convenience.zarr',
11
+ url: 'http://localhost:8000/my_anndata.zarr',
12
+ options: {
13
+ cells: {
14
+ xy: 'obsm/centroids',
15
+ },
16
+ cellSets: [
17
+ {
18
+ groupName: 'Leiden',
19
+ setName: 'obs/leiden',
20
+ },
21
+ ],
22
+ },
23
+ },
24
+ ],
25
+ name: 'A',
26
+ uid: 'A',
27
+ },
28
+ ],
29
+ layout: [],
30
+ };
31
+
32
+ export function pluginExpandAnnDataConvenience(fileDef) {
33
+ return [
34
+ {
35
+ fileType: 'anndata-cells.zarr',
36
+ url: fileDef.url,
37
+ options: fileDef.options.cells,
38
+ },
39
+ {
40
+ fileType: 'anndata-cell-sets.zarr',
41
+ url: fileDef.url,
42
+ options: fileDef.options.cellSets,
43
+ },
44
+ ];
45
+ }
46
+
47
+ export const convenienceFileDefsExpanded = {
48
+ version: '1.0.15',
49
+ name: 'My config name',
50
+ description: 'My config description',
51
+ initStrategy: 'auto',
52
+ datasets: [
53
+ {
54
+ files: [
55
+ {
56
+ fileType: 'anndata-cells.zarr',
57
+ url: 'http://localhost:8000/my_anndata.zarr',
58
+ options: {
59
+ xy: 'obsm/centroids',
60
+ },
61
+ },
62
+ {
63
+ fileType: 'anndata-cell-sets.zarr',
64
+ url: 'http://localhost:8000/my_anndata.zarr',
65
+ options: [
66
+ {
67
+ groupName: 'Leiden',
68
+ setName: 'obs/leiden',
69
+ },
70
+ ],
71
+ },
72
+ ],
73
+ name: 'A',
74
+ uid: 'A',
75
+ },
76
+ ],
77
+ layout: [],
78
+ };
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/vitessce/vitessce/#dataset",
4
+ "title": "Vitessce data set",
5
+ "type": "object",
6
+ "definitions": {
7
+ "components": {
8
+ "type": "array",
9
+ "items": {
10
+ "type": "object",
11
+ "additionalProperties": false,
12
+ "required": ["component", "x", "y"],
13
+ "properties": {
14
+ "component": { "type": "string" },
15
+ "props": { "type": "object" },
16
+ "x": { "type": "integer" },
17
+ "y": { "type": "integer" },
18
+ "w": { "type": "integer" },
19
+ "h": { "type": "integer" }
20
+ }
21
+ }
22
+ },
23
+ "requestInit": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": [],
27
+ "properties": {
28
+ "method": {
29
+ "type": "string"
30
+ },
31
+ "headers": {
32
+ "type": "object"
33
+ },
34
+ "body": {
35
+ "type": "string"
36
+ },
37
+ "mode": {
38
+ "type": "string"
39
+ },
40
+ "credentials": {
41
+ "type": "string"
42
+ },
43
+ "cache": {
44
+ "type": "string"
45
+ },
46
+ "redirect": {
47
+ "type": "string"
48
+ },
49
+ "referrer": {
50
+ "type": "string"
51
+ },
52
+ "integrity": {
53
+ "type": "string"
54
+ }
55
+ }
56
+ }
57
+ },
58
+ "additionalProperties": false,
59
+ "required": ["version", "name", "layers"],
60
+ "properties": {
61
+ "name": { "type": "string" },
62
+ "public": { "type": "boolean" },
63
+ "description": { "type": "string" },
64
+ "layers": {
65
+ "type": "array",
66
+ "items": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["name", "type", "fileType", "url"],
70
+ "properties": {
71
+ "name": { "type": "string" },
72
+ "type": { "type": "string" },
73
+ "fileType": { "type": "string" },
74
+ "url": { "type": "string" },
75
+ "requestInit": { "$ref": "#/definitions/requestInit" }
76
+ }
77
+ }
78
+ },
79
+ "staticLayout": { "$ref": "#/definitions/components" },
80
+ "version": {
81
+ "type": "string", "enum": ["0.1.0"]
82
+ }
83
+ }
84
+ }
85
+