@macrostrat/column-views 1.0.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/esm/{data-area.daff8da0.js → column-views.062d164a.js} +1 -1
  3. package/dist/esm/{data-area.daff8da0.js.map → column-views.062d164a.js.map} +1 -1
  4. package/dist/esm/{data-provider.1506eb64.js → column-views.07521ce6.js} +1 -1
  5. package/dist/esm/column-views.07521ce6.js.map +1 -0
  6. package/dist/esm/column-views.134b2e2a.js +9 -0
  7. package/dist/esm/column-views.134b2e2a.js.map +1 -0
  8. package/dist/esm/{selection-popover.module.0a701258.css → column-views.16cc7a58.css} +11 -8
  9. package/dist/esm/column-views.16cc7a58.css.map +1 -0
  10. package/dist/esm/column-views.1c589cc4.js +141 -0
  11. package/dist/esm/column-views.1c589cc4.js.map +1 -0
  12. package/dist/esm/column-views.1ece326b.js +420 -0
  13. package/dist/esm/column-views.1ece326b.js.map +1 -0
  14. package/dist/esm/column-views.1edc7300.js +40 -0
  15. package/dist/esm/column-views.1edc7300.js.map +1 -0
  16. package/dist/esm/column-views.240ef158.css +159 -0
  17. package/dist/esm/column-views.240ef158.css.map +1 -0
  18. package/dist/esm/column-views.25471fe0.css +111 -0
  19. package/dist/esm/column-views.25471fe0.css.map +1 -0
  20. package/dist/esm/column-views.28ee5f43.js +288 -0
  21. package/dist/esm/column-views.28ee5f43.js.map +1 -0
  22. package/dist/esm/column-views.30646469.js +118 -0
  23. package/dist/esm/column-views.30646469.js.map +1 -0
  24. package/dist/esm/column-views.338a7a83.css +134 -0
  25. package/dist/esm/column-views.338a7a83.css.map +1 -0
  26. package/dist/esm/column-views.33dbc778.js +95 -0
  27. package/dist/esm/column-views.33dbc778.js.map +1 -0
  28. package/dist/esm/column-views.343b5aa2.js +98 -0
  29. package/dist/esm/column-views.343b5aa2.js.map +1 -0
  30. package/dist/esm/column-views.34636ec7.js +104 -0
  31. package/dist/esm/column-views.34636ec7.js.map +1 -0
  32. package/dist/esm/column-views.3465c8ad.js +16 -0
  33. package/dist/esm/column-views.3465c8ad.js.map +1 -0
  34. package/dist/esm/column-views.39657bbf.js +55 -0
  35. package/dist/esm/column-views.39657bbf.js.map +1 -0
  36. package/dist/esm/column-views.3b972a9b.css +4 -0
  37. package/dist/esm/{composite.module.69a38fd1.css.map → column-views.3b972a9b.css.map} +1 -1
  38. package/dist/esm/column-views.3bec70d6.js +167 -0
  39. package/dist/esm/column-views.3bec70d6.js.map +1 -0
  40. package/dist/esm/column-views.3de4dc43.js +66 -0
  41. package/dist/esm/column-views.3de4dc43.js.map +1 -0
  42. package/dist/esm/{column.db058031.js → column-views.3f4db8cb.js} +8 -8
  43. package/dist/esm/column-views.3f4db8cb.js.map +1 -0
  44. package/dist/esm/column-views.40c1f361.js +206 -0
  45. package/dist/esm/column-views.40c1f361.js.map +1 -0
  46. package/dist/esm/{composite.module.0638e7ee.js → column-views.40cd59b5.js} +1 -1
  47. package/dist/esm/{composite.module.0638e7ee.js.map → column-views.40cd59b5.js.map} +1 -1
  48. package/dist/esm/column-views.4637f4ce.js +46 -0
  49. package/dist/esm/column-views.4637f4ce.js.map +1 -0
  50. package/dist/esm/column-views.4c4c5bac.js +163 -0
  51. package/dist/esm/column-views.4c4c5bac.js.map +1 -0
  52. package/dist/esm/column-views.4d374a35.js +19 -0
  53. package/dist/esm/column-views.4d374a35.js.map +1 -0
  54. package/dist/esm/column-views.57c4ddf3.js +125 -0
  55. package/dist/esm/column-views.57c4ddf3.js.map +1 -0
  56. package/dist/esm/column-views.58b82432.js +58 -0
  57. package/dist/esm/column-views.58b82432.js.map +1 -0
  58. package/dist/esm/column-views.5b2635fd.js +13 -0
  59. package/dist/esm/column-views.5b2635fd.js.map +1 -0
  60. package/dist/esm/column-views.5c02fee2.js +258 -0
  61. package/dist/esm/column-views.5c02fee2.js.map +1 -0
  62. package/dist/esm/column-views.5cc09c1d.js +152 -0
  63. package/dist/esm/column-views.5cc09c1d.js.map +1 -0
  64. package/dist/esm/{names.f6a4e9a4.js → column-views.650bd9f5.js} +5 -5
  65. package/dist/esm/column-views.650bd9f5.js.map +1 -0
  66. package/dist/esm/column-views.68409161.js +89 -0
  67. package/dist/esm/column-views.68409161.js.map +1 -0
  68. package/dist/esm/column-views.6a954628.js +70 -0
  69. package/dist/esm/column-views.6a954628.js.map +1 -0
  70. package/dist/esm/column-views.6c670c13.css +26 -0
  71. package/dist/esm/column-views.6c670c13.css.map +1 -0
  72. package/dist/esm/column-views.6d6b73b4.js +55 -0
  73. package/dist/esm/column-views.6d6b73b4.js.map +1 -0
  74. package/dist/esm/column-views.86c4b36f.js +222 -0
  75. package/dist/esm/column-views.86c4b36f.js.map +1 -0
  76. package/dist/esm/column-views.88de2cee.js +9 -0
  77. package/dist/esm/column-views.88de2cee.js.map +1 -0
  78. package/dist/esm/{resolvers.b5c82b78.js → column-views.8dd877af.js} +16 -3
  79. package/dist/esm/column-views.8dd877af.js.map +1 -0
  80. package/dist/esm/column-views.8e51206e.js +143 -0
  81. package/dist/esm/column-views.8e51206e.js.map +1 -0
  82. package/dist/esm/{column.module.7f47d25a.js → column-views.94b5cca1.js} +1 -1
  83. package/dist/esm/{column.module.7f47d25a.js.map → column-views.94b5cca1.js.map} +1 -1
  84. package/dist/esm/column-views.9804efda.js +75 -0
  85. package/dist/esm/column-views.9804efda.js.map +1 -0
  86. package/dist/esm/column-views.9bdd477a.js +57 -0
  87. package/dist/esm/column-views.9bdd477a.js.map +1 -0
  88. package/dist/esm/column-views.9ced149e.js +98 -0
  89. package/dist/esm/column-views.9ced149e.js.map +1 -0
  90. package/dist/esm/{column.module.cbb072df.css → column-views.a7be0a4a.css} +1 -1
  91. package/dist/esm/{column.module.cbb072df.css.map → column-views.a7be0a4a.css.map} +1 -1
  92. package/dist/esm/column-views.a98214b2.js +9 -0
  93. package/dist/esm/column-views.a98214b2.js.map +1 -0
  94. package/dist/esm/column-views.aa9fcdba.js +221 -0
  95. package/dist/esm/column-views.aa9fcdba.js.map +1 -0
  96. package/dist/esm/{isotopes-column.7cb5cc45.js → column-views.ac9fb5e1.js} +3 -3
  97. package/dist/esm/{isotopes-column.7cb5cc45.js.map → column-views.ac9fb5e1.js.map} +1 -1
  98. package/dist/esm/column-views.b2e5f1d9.js +11 -0
  99. package/dist/esm/column-views.b2e5f1d9.js.map +1 -0
  100. package/dist/esm/column-views.b775c0a3.js +112 -0
  101. package/dist/esm/column-views.b775c0a3.js.map +1 -0
  102. package/dist/esm/column-views.beb54e95.js +39 -0
  103. package/dist/esm/column-views.beb54e95.js.map +1 -0
  104. package/dist/esm/{core.4db8e452.js → column-views.c58aad3f.js} +15 -16
  105. package/dist/esm/column-views.c58aad3f.js.map +1 -0
  106. package/dist/esm/{carbon-isotopes.3b502a9e.js → column-views.d1ad48eb.js} +4 -4
  107. package/dist/esm/{carbon-isotopes.3b502a9e.js.map → column-views.d1ad48eb.js.map} +1 -1
  108. package/dist/esm/column-views.dc42f5d0.js +48 -0
  109. package/dist/esm/column-views.dc42f5d0.js.map +1 -0
  110. package/dist/esm/column-views.dff52504.js +22 -0
  111. package/dist/esm/column-views.dff52504.js.map +1 -0
  112. package/dist/esm/column-views.e2b9c23c.css +33 -0
  113. package/dist/esm/column-views.e2b9c23c.css.map +1 -0
  114. package/dist/esm/column-views.e40b8bfb.css +14 -0
  115. package/dist/esm/column-views.e40b8bfb.css.map +1 -0
  116. package/dist/esm/column-views.e77b9d6b.js +170 -0
  117. package/dist/esm/column-views.e77b9d6b.js.map +1 -0
  118. package/dist/esm/column-views.ea237aa8.js +52 -0
  119. package/dist/esm/column-views.ea237aa8.js.map +1 -0
  120. package/dist/esm/column-views.edf77621.js +22 -0
  121. package/dist/esm/column-views.edf77621.js.map +1 -0
  122. package/dist/esm/column-views.f1efcc2c.js +9 -0
  123. package/dist/esm/column-views.f1efcc2c.js.map +1 -0
  124. package/dist/esm/column-views.f2e5a72f.js +66 -0
  125. package/dist/esm/column-views.f2e5a72f.js.map +1 -0
  126. package/dist/esm/column-views.f71ec4b4.js +127 -0
  127. package/dist/esm/column-views.f71ec4b4.js.map +1 -0
  128. package/dist/esm/column-views.f9dab157.js +3 -0
  129. package/dist/esm/column-views.f9dab157.js.map +1 -0
  130. package/dist/esm/column-views.fa6f3292.js +215 -0
  131. package/dist/esm/column-views.fa6f3292.js.map +1 -0
  132. package/dist/esm/column-views.fc2b4611.js +9 -0
  133. package/dist/esm/column-views.fc2b4611.js.map +1 -0
  134. package/dist/esm/index.d.ts +797 -130
  135. package/dist/esm/index.d.ts.map +1 -1
  136. package/dist/esm/index.js +13 -9
  137. package/dist/esm/index.js.map +1 -1
  138. package/dist/node/index.js +1 -1
  139. package/dist/node/index.js.map +1 -1
  140. package/package.json +29 -13
  141. package/src/age-axis.module.sass +27 -0
  142. package/src/age-axis.ts +82 -19
  143. package/src/age-model-overlay.module.sass +11 -0
  144. package/src/age-model-overlay.ts +73 -0
  145. package/src/carbon-isotopes/column.ts +4 -2
  146. package/src/carbon-isotopes/core.ts +9 -6
  147. package/src/carbon-isotopes/data-provider.ts +3 -3
  148. package/src/column.module.sass +58 -49
  149. package/src/column.ts +149 -135
  150. package/src/correlation-chart/hash-string.ts +57 -0
  151. package/src/correlation-chart/index.ts +2 -0
  152. package/src/correlation-chart/main.module.sass +122 -0
  153. package/src/correlation-chart/main.ts +305 -0
  154. package/src/correlation-chart/prepare-data.ts +217 -0
  155. package/src/correlation-chart/stories/correlation-chart.stories.ts +192 -0
  156. package/src/correlation-chart/stories/stories.module.sass +18 -0
  157. package/src/correlation-chart/unconformity-line.module.sass +8 -0
  158. package/src/correlation-chart/unconformity-line.ts +25 -0
  159. package/src/data-provider/base.ts +388 -0
  160. package/src/data-provider/column-nav.ts +53 -0
  161. package/src/data-provider/fetch.ts +231 -0
  162. package/src/data-provider/index.ts +4 -0
  163. package/src/data-provider/store.ts +72 -0
  164. package/src/index.ts +5 -3
  165. package/src/maps/_shared/index.ts +2 -0
  166. package/src/maps/_shared/inset-map.stories.ts +20 -0
  167. package/src/maps/_shared/inset-map.ts +87 -0
  168. package/src/maps/_shared/styles.ts +57 -0
  169. package/src/maps/column-correlation/column-correlation-map.stories.ts +96 -0
  170. package/src/maps/column-correlation/core.ts +225 -0
  171. package/src/maps/column-correlation/index.ts +2 -0
  172. package/src/maps/column-correlation/state.ts +192 -0
  173. package/src/maps/column-navigation/index.ts +2 -0
  174. package/src/maps/column-navigation/mapbox/column-navigation-map.stories.ts +102 -0
  175. package/src/maps/column-navigation/mapbox/index.ts +219 -0
  176. package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +119 -0
  177. package/src/maps/column-navigation/mapbox/state.ts +109 -0
  178. package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +46 -0
  179. package/src/{map → maps/column-navigation/svg}/index.ts +18 -6
  180. package/src/{map → maps/column-navigation/svg}/layers.ts +28 -109
  181. package/src/maps/column-navigation/utils/keyboard-navigation.ts +58 -0
  182. package/src/maps/index.ts +3 -0
  183. package/src/prepare-units/composite-scale.ts +353 -0
  184. package/src/prepare-units/helpers.ts +226 -0
  185. package/src/prepare-units/index.ts +177 -0
  186. package/src/prepare-units/utils.ts +98 -0
  187. package/src/section.ts +264 -84
  188. package/src/unit-details/index.ts +2 -215
  189. package/src/unit-details/{index.module.sass → panel.module.sass} +39 -8
  190. package/src/unit-details/panel.ts +523 -0
  191. package/src/{selection-popover.module.sass → unit-details/popover.module.sass} +4 -2
  192. package/src/unit-details/popover.ts +82 -0
  193. package/src/units/boxes.module.sass +16 -0
  194. package/src/units/boxes.ts +243 -90
  195. package/src/units/colors.ts +64 -0
  196. package/src/units/composite.ts +157 -152
  197. package/src/units/index.ts +76 -9
  198. package/src/units/names.ts +8 -4
  199. package/src/units/resolvers.ts +12 -1
  200. package/src/units/selection.ts +115 -101
  201. package/src/units/types.ts +5 -16
  202. package/dist/esm/age-axis.64c509ee.js +0 -41
  203. package/dist/esm/age-axis.64c509ee.js.map +0 -1
  204. package/dist/esm/boxes.13968b76.js +0 -164
  205. package/dist/esm/boxes.13968b76.js.map +0 -1
  206. package/dist/esm/boxes.module.28873d08.css +0 -4
  207. package/dist/esm/boxes.module.28873d08.css.map +0 -1
  208. package/dist/esm/boxes.module.605bdcd6.js +0 -13
  209. package/dist/esm/boxes.module.605bdcd6.js.map +0 -1
  210. package/dist/esm/column.8dd26e1a.js +0 -149
  211. package/dist/esm/column.8dd26e1a.js.map +0 -1
  212. package/dist/esm/column.db058031.js.map +0 -1
  213. package/dist/esm/column.module.039d872c.css +0 -151
  214. package/dist/esm/column.module.039d872c.css.map +0 -1
  215. package/dist/esm/column.module.e632868a.js +0 -19
  216. package/dist/esm/column.module.e632868a.js.map +0 -1
  217. package/dist/esm/composite.608a4ca2.js +0 -153
  218. package/dist/esm/composite.608a4ca2.js.map +0 -1
  219. package/dist/esm/composite.module.69a38fd1.css +0 -4
  220. package/dist/esm/core.4db8e452.js.map +0 -1
  221. package/dist/esm/data-provider.1506eb64.js.map +0 -1
  222. package/dist/esm/helpers.8a03cfc7.js +0 -94
  223. package/dist/esm/helpers.8a03cfc7.js.map +0 -1
  224. package/dist/esm/index.module.0844afd8.css +0 -65
  225. package/dist/esm/index.module.0844afd8.css.map +0 -1
  226. package/dist/esm/index.module.24fe3a2e.js +0 -37
  227. package/dist/esm/index.module.24fe3a2e.js.map +0 -1
  228. package/dist/esm/layers.ad5fd25d.js +0 -231
  229. package/dist/esm/layers.ad5fd25d.js.map +0 -1
  230. package/dist/esm/map.7aa26f17.js +0 -82
  231. package/dist/esm/map.7aa26f17.js.map +0 -1
  232. package/dist/esm/names.f6a4e9a4.js.map +0 -1
  233. package/dist/esm/providers.cd1e652f.js +0 -25
  234. package/dist/esm/providers.cd1e652f.js.map +0 -1
  235. package/dist/esm/resolvers.b5c82b78.js.map +0 -1
  236. package/dist/esm/section.cc1b1100.js +0 -118
  237. package/dist/esm/section.cc1b1100.js.map +0 -1
  238. package/dist/esm/selection-popover.17d1bd55.js +0 -60
  239. package/dist/esm/selection-popover.17d1bd55.js.map +0 -1
  240. package/dist/esm/selection-popover.module.0a701258.css.map +0 -1
  241. package/dist/esm/selection-popover.module.e22f5183.js +0 -22
  242. package/dist/esm/selection-popover.module.e22f5183.js.map +0 -1
  243. package/dist/esm/selection.bbf26d0e.js +0 -117
  244. package/dist/esm/selection.bbf26d0e.js.map +0 -1
  245. package/dist/esm/store.25eaa168.js +0 -18
  246. package/dist/esm/store.25eaa168.js.map +0 -1
  247. package/dist/esm/types.f016e032.js +0 -18
  248. package/dist/esm/types.f016e032.js.map +0 -1
  249. package/dist/esm/unit-details.56ff8b70.js +0 -209
  250. package/dist/esm/unit-details.56ff8b70.js.map +0 -1
  251. package/dist/esm/units.361088d4.js +0 -42
  252. package/dist/esm/units.361088d4.js.map +0 -1
  253. package/src/helpers.ts +0 -133
  254. package/src/providers.ts +0 -34
  255. package/src/selection-popover.ts +0 -71
  256. package/src/store.ts +0 -12
  257. package/src/units/units.scss +0 -16
  258. /package/src/{map → maps/column-navigation/svg}/animated.ts +0 -0
@@ -9,31 +9,25 @@ import {
9
9
  } from "@macrostrat/column-components";
10
10
  import { SizeAwareLabel, Clickable } from "@macrostrat/ui-components";
11
11
  import hyper from "@macrostrat/hyper";
12
- import {
13
- ReactNode,
14
- useCallback,
15
- useContext,
16
- useEffect,
17
- useMemo,
18
- useRef,
19
- } from "react";
12
+ import { forwardRef, ReactNode, useContext, useMemo } from "react";
20
13
  import { resolveID, scalePattern } from "./resolvers";
21
- import { useSelectedUnit, useUnitSelectionDispatch } from "./selection";
22
- import { IUnit, transformAxisType } from "./types";
14
+ import { useUnitSelectionTarget } from "./selection";
15
+ import { IUnit } from "./types";
23
16
  import styles from "./boxes.module.sass";
17
+ import classNames from "classnames";
18
+ import { getUnitHeightRange } from "../prepare-units/utils";
19
+ import { useLithologies } from "../data-provider";
20
+ import { getMixedUnitColor } from "./colors";
21
+ import { path } from "d3-path";
22
+ import type { RectBounds } from "./types";
24
23
 
25
24
  const h = hyper.styled(styles);
26
25
 
27
- export interface RectBounds {
28
- x: number;
29
- y: number;
30
- width: number;
31
- height: number;
32
- }
33
-
34
26
  interface UnitRectOptions {
35
27
  widthFraction?: number;
36
28
  axisType?: ColumnAxisType;
29
+ // Padding to create overflow for zig-zags or other ornamented edges
30
+ padding?: number;
37
31
  }
38
32
 
39
33
  interface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {
@@ -44,6 +38,9 @@ interface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {
44
38
  widthFraction?: number;
45
39
  children?: ReactNode;
46
40
  className?: string;
41
+ fill?: string;
42
+ backgroundColor?: string;
43
+ patternColor?: string;
47
44
  }
48
45
 
49
46
  export interface LabeledUnitProps
@@ -54,109 +51,262 @@ export interface LabeledUnitProps
54
51
  label: string;
55
52
  onLabelUpdated?(label: string, shown: boolean);
56
53
  halfWidth?: boolean;
54
+ showLabel?: boolean;
55
+ backgroundColor?: string;
57
56
  }
58
57
 
59
58
  function useUnitRect(
60
59
  division: IUnit,
61
60
  options: UnitRectOptions = {}
62
61
  ): RectBounds {
63
- const { widthFraction = 1, axisType = ColumnAxisType.AGE } = options;
62
+ const {
63
+ widthFraction = 1,
64
+ axisType = ColumnAxisType.AGE,
65
+ padding = 0,
66
+ } = options;
64
67
  const { scale } = useContext(ColumnContext);
65
68
  const { width } = useContext(ColumnLayoutContext);
66
- const macrostratAxisKey = transformAxisType(axisType);
67
- const t_key = "t_" + macrostratAxisKey;
68
- const b_key = "b_" + macrostratAxisKey;
69
-
70
- const topHeight = division[t_key];
71
- const bottomHeight = division[b_key];
72
- if (topHeight == null && bottomHeight == null) {
73
- console.warn(
74
- `Missing keys ${t_key} and ${b_key} for ${division.unit_id} (${division.unit_name})`
75
- );
76
- }
69
+
70
+ const [bottomHeight, topHeight] = getUnitHeightRange(division, axisType);
77
71
 
78
72
  const y = scale(topHeight);
79
73
  const height = Math.abs(scale(bottomHeight) - y);
80
74
 
81
75
  return {
82
- x: width * (1 - widthFraction),
83
- y,
84
- height,
85
- width: widthFraction * width,
76
+ x: width * (1 - widthFraction) - padding,
77
+ y: y - padding,
78
+ height: height + padding * 2,
79
+ width: widthFraction * width + padding * 2,
86
80
  };
87
81
  }
88
82
 
83
+ export function MinimalUnit(props) {
84
+ const {
85
+ division: d,
86
+ children,
87
+ className,
88
+ widthFraction = 1,
89
+ axisType: _, // not sure why this is brought in...
90
+ nColumns: __,
91
+ ...baseBounds
92
+ } = props;
93
+
94
+ const { axisType } = useColumn();
95
+ const lithMap = useLithologies();
96
+ const bounds = {
97
+ ...useUnitRect(d, { widthFraction, axisType }),
98
+ ...baseBounds,
99
+ };
100
+
101
+ const backgroundColor = getMixedUnitColor(d, lithMap, null, false);
102
+
103
+ const [ref, selected, onClick] = useUnitSelectionTarget(d);
104
+
105
+ return h(
106
+ "g.unit",
107
+ {
108
+ className,
109
+ style: {
110
+ "--column-unit-background-color": backgroundColor,
111
+ "--column-stroke-color": backgroundColor,
112
+ },
113
+ },
114
+ [
115
+ h("rect.unit.background", {
116
+ ref,
117
+ ...bounds,
118
+ fill: backgroundColor,
119
+ fillOpacity: 0.8,
120
+ stroke: backgroundColor,
121
+ onClick,
122
+ }),
123
+ h.if(selected)("rect.selection-overlay", bounds),
124
+ ]
125
+ );
126
+ }
127
+
89
128
  function Unit(props: UnitProps) {
90
129
  const {
91
130
  division: d,
92
131
  children,
132
+ fill,
93
133
  defaultFill = "transparent",
94
134
  className,
95
135
  widthFraction = 1,
136
+ backgroundColor,
137
+ patternColor,
138
+ axisType: _, // not sure why this is brought in...
96
139
  ...baseBounds
97
140
  } = props;
98
141
 
99
142
  const { axisType } = useColumn();
143
+
144
+ const hasOverflowTop = d.t_clip_pos != null;
145
+ const hasOverflowBottom = d.b_clip_pos != null;
146
+
100
147
  const bounds = {
101
148
  ...useUnitRect(d, { widthFraction, axisType }),
102
149
  ...baseBounds,
150
+ overflowTop: hasOverflowTop,
151
+ overflowBottom: hasOverflowBottom,
103
152
  };
104
153
  const patternID = resolveID(d);
105
- const fill = useGeologicPattern(patternID, defaultFill);
106
- // Allow us to select this unit if in the proper context
154
+ let _fill = fill ?? useGeologicPattern(patternID, defaultFill);
107
155
 
108
- const ref = useRef<HTMLElement>();
156
+ const hasBackgroundColor = backgroundColor != null;
109
157
 
110
- const [selected, onClick] = useUnitSelectionManager(ref, d);
158
+ const _className = classNames(className, { colored: hasBackgroundColor });
111
159
 
112
- return h("g.unit", { className }, [
113
- h("rect.unit", {
114
- ref,
115
- ...bounds,
116
- fill,
117
- onClick,
118
- }),
119
- h.if(selected)("rect.selection-overlay", bounds),
120
- children,
121
- ]);
122
- }
123
-
124
- function useUnitSelectionManager(
125
- ref: React.RefObject<HTMLElement>,
126
- unit: IUnit
127
- ): [boolean, (evt: Event) => void] {
128
- const selectedUnit = useSelectedUnit();
129
- const selected = selectedUnit?.unit_id == unit.unit_id;
160
+ const [ref, selected, onClick] = useUnitSelectionTarget(d);
130
161
 
131
- const dispatch = useUnitSelectionDispatch();
162
+ //const key = `unit-${d.unit_id}`;
132
163
 
133
- const onClick = useCallback(
134
- (evt: Event) => {
135
- dispatch(unit, ref.current, evt);
136
- evt.stopPropagation();
164
+ return h(
165
+ "g.unit",
166
+ {
167
+ className: _className,
168
+ style: {
169
+ "--column-unit-background-color": backgroundColor,
170
+ },
137
171
  },
138
- [unit, ref, dispatch]
172
+ [
173
+ h(UnitRect, {
174
+ ...bounds,
175
+ fill: backgroundColor,
176
+ onClick,
177
+ className: "background",
178
+ }),
179
+ h(UnitRect, {
180
+ ref,
181
+ ...bounds,
182
+ fill: _fill,
183
+ //mask,
184
+ onClick,
185
+ className: "unit",
186
+ }),
187
+ h.if(selected)(UnitRect, { ...bounds, className: "selection-overlay" }),
188
+ //defs,
189
+ children,
190
+ ]
139
191
  );
192
+ }
193
+
194
+ interface UnitRectProps {
195
+ x: number;
196
+ y: number;
197
+ width: number;
198
+ height: number;
199
+ className: string;
200
+ // Used to determine if the rect should have a zig-zag edge on the top or bottom
201
+ overflowTop?: boolean;
202
+ overflowBottom?: boolean;
203
+ [key: string]: any;
204
+ }
140
205
 
141
- useEffect(() => {
142
- if (!selected) return;
143
- // In case we haven't set the position of the unit (if we don't have a target), set the selected unit
144
- dispatch(unit, ref.current, null);
206
+ const UnitRect = forwardRef((props: UnitRectProps, ref) => {
207
+ const {
208
+ x,
209
+ y,
210
+ width,
211
+ height,
212
+ overflowTop = false,
213
+ overflowBottom = false,
214
+ ...rest
215
+ } = props;
145
216
 
146
- // Scroll the unit into view
147
- ref.current?.scrollIntoView({
148
- behavior: "smooth",
149
- block: "center",
150
- inline: "nearest",
217
+ if (!overflowTop && !overflowBottom) {
218
+ return h("rect", {
219
+ x,
220
+ y,
221
+ width,
222
+ height,
223
+ ref,
224
+ ...rest,
225
+ });
226
+ } else {
227
+ const d = zigZagBoxPath(x, y, width, height, overflowTop, overflowBottom);
228
+ return h("path", {
229
+ d,
230
+ ref,
231
+ ...rest,
151
232
  });
152
- }, [selected]);
233
+ }
234
+ });
235
+
236
+ function zigZagBoxPath(x, y, width, height, top: boolean, bottom: boolean) {
237
+ const zigZagWidth = 10;
238
+ const zigZagHeight = 4;
239
+
240
+ const d = path();
241
+
242
+ const nZigZags = Math.floor(width / zigZagWidth - 0.5);
243
+ const _zigZagWidth = width / (nZigZags + 0.5);
244
+
245
+ d.moveTo(x, y);
246
+ let dy = zigZagHeight / 2;
247
+ // Each zig-zag consists of a short outward motion
248
+ let dx = _zigZagWidth / 4;
249
+
250
+ let cx = x;
251
+ let cy = y;
252
+
253
+ const doZigZag = (last = false) => {
254
+ cx += dx;
255
+ cy -= dy;
256
+ d.lineTo(cx, cy);
257
+ let scalar = last ? 1 : 2;
258
+ cx += dx * scalar;
259
+ cy += dy * scalar;
260
+ d.lineTo(cx, cy);
261
+ cx += dx;
262
+ cy -= dy;
263
+ };
264
+
265
+ if (top) {
266
+ // Move to the offset
267
+ //d.lineTo(cx, y);
268
+ // Draw the zig-zags
269
+ for (let i = 0; i < nZigZags; i++) {
270
+ doZigZag();
271
+ }
272
+ // Draw the last half zig-zag
273
+ doZigZag(true);
274
+ }
275
+ // Draw the right edge
276
+ d.lineTo(x + width, y);
277
+ d.lineTo(x + width, y + height);
278
+
279
+ if (bottom) {
280
+ dx = -dx;
281
+ dy = -dy;
282
+ cx = x + width;
283
+ cy = y + height;
153
284
 
154
- return [selected, onClick];
285
+ for (let i = 0; i < nZigZags; i++) {
286
+ doZigZag();
287
+ }
288
+ doZigZag(true);
289
+ }
290
+ // Draw the last line to the left edge
291
+ d.lineTo(x, y + height);
292
+ // Draw the left edge
293
+ d.closePath();
294
+
295
+ // Now render the path;
296
+ return d.toString();
155
297
  }
156
298
 
157
299
  function LabeledUnit(props: LabeledUnitProps) {
158
- const { division, label, onLabelUpdated, widthFraction, ...baseBounds } =
159
- props;
300
+ const {
301
+ division,
302
+ label,
303
+ onLabelUpdated,
304
+ widthFraction,
305
+ showLabel = true,
306
+ backgroundColor,
307
+ axisType: _, // not sure why this is brought in...
308
+ ...baseBounds
309
+ } = props;
160
310
 
161
311
  const { axisType } = useColumn();
162
312
  const bounds = {
@@ -164,21 +314,25 @@ function LabeledUnit(props: LabeledUnitProps) {
164
314
  ...baseBounds,
165
315
  };
166
316
  const { width, height } = bounds;
167
- return h(Unit, { className: "labeled-unit", division, ...bounds }, [
168
- h(
169
- ForeignObject,
170
- { ...bounds, className: "unit-label-container" },
171
- h(SizeAwareLabel, {
172
- className: "unit-overlay",
173
- labelClassName: "unit-label",
174
- style: { width, height },
175
- label,
176
- onVisibilityChanged(viz) {
177
- onLabelUpdated(label, viz);
178
- },
179
- })
180
- ),
181
- ]);
317
+ return h(
318
+ Unit,
319
+ { className: "labeled-unit", division, backgroundColor, ...bounds },
320
+ [
321
+ h.if(showLabel)(
322
+ ForeignObject,
323
+ { ...bounds, className: "unit-label-container" },
324
+ h(SizeAwareLabel, {
325
+ className: "unit-overlay",
326
+ labelClassName: "unit-label",
327
+ style: { width, height },
328
+ label,
329
+ onVisibilityChanged(viz) {
330
+ onLabelUpdated(label, viz);
331
+ },
332
+ })
333
+ ),
334
+ ]
335
+ );
182
336
  }
183
337
 
184
338
  function UnitBoxes<T>(props: {
@@ -205,7 +359,6 @@ function UnitBoxes<T>(props: {
205
359
  return h(unitComponent, {
206
360
  division,
207
361
  key: division.unit_id,
208
- axisType: ColumnAxisType.HEIGHT,
209
362
  ...unitComponentProps,
210
363
  });
211
364
  });
@@ -0,0 +1,64 @@
1
+ import chroma from "chroma-js";
2
+ import { UnitLong } from "@macrostrat/api-types";
3
+
4
+ export function getMixedUnitColor(
5
+ unit: UnitLong,
6
+ lithMap,
7
+ inDarkMode = false,
8
+ asBackground = true
9
+ ): string | null {
10
+ const liths = unit.lith;
11
+ if (liths == null) {
12
+ return "gray";
13
+ }
14
+ const lithData = liths
15
+ .map((d) => {
16
+ let prop = d.prop;
17
+ if (prop == null || isNaN(prop) || prop <= 0) {
18
+ prop = null;
19
+ }
20
+ return {
21
+ lith_id: d.lith_id,
22
+ prop,
23
+ color: lithMap?.get(d.lith_id)?.color,
24
+ };
25
+ })
26
+ .filter((d) => d.color != null);
27
+
28
+ const lithsWithProp = lithData.filter((d) => d.prop != null);
29
+ const lithsWithoutProp = lithData.filter((d) => d.prop == null);
30
+
31
+ const totalProp = lithsWithProp.reduce((sum, d) => sum + d.prop, 0);
32
+ if (totalProp < 1 && lithsWithoutProp.length > 0) {
33
+ const remainingProp = 1 - totalProp;
34
+ // Distribute remaining proportion equally among liths without prop
35
+ const equalProp = remainingProp / lithsWithoutProp.length;
36
+ lithsWithoutProp.forEach((d) => {
37
+ lithsWithProp.push({
38
+ ...d,
39
+ prop: equalProp,
40
+ });
41
+ });
42
+ }
43
+
44
+ if (lithsWithProp.length == 0) {
45
+ return null;
46
+ }
47
+
48
+ // Mix colors proportionally
49
+ const baseColor = chroma.average(
50
+ lithsWithProp.map((d) => d.color),
51
+ "lrgb",
52
+ lithsWithProp.map((d) => d.prop)
53
+ );
54
+
55
+ if (!asBackground) {
56
+ return baseColor.hex();
57
+ }
58
+
59
+ if (inDarkMode) {
60
+ return baseColor.set("hsl.l", 0.2).hex();
61
+ } else {
62
+ return baseColor.set("hsl.l", 0.9).hex();
63
+ }
64
+ }