@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
@@ -0,0 +1,122 @@
1
+ $map-size: 40em
2
+ $map-size-inset: 12em
3
+
4
+ .page-header
5
+ display: flex
6
+ flex-direction: row
7
+ justify-content: space-between
8
+ margin-bottom: 1em
9
+
10
+ .diagram-container
11
+ flex: 1
12
+ position: relative
13
+ min-height: 0
14
+ display: flex
15
+
16
+ &.map-inset
17
+ .column-selection-map
18
+ position: absolute
19
+ top: 1em
20
+ right: 1em
21
+ height: $map-size-inset
22
+ width: $map-size-inset
23
+ z-index: 1000
24
+
25
+ &.map-expanded
26
+ flex-direction: row
27
+ gap: 1em
28
+
29
+ .assistant
30
+ width: 40em
31
+ position: relative
32
+
33
+ .column-selection-map, .unit-details-panel, .main-area
34
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3)
35
+ border-radius: 6px
36
+
37
+ .column-selection-map
38
+ overflow: hidden
39
+
40
+ .correlation-map
41
+ height: 100%
42
+ position: relative
43
+
44
+ flex: 1
45
+ min-height: $map-size-inset
46
+ max-height: $map-size
47
+ width: $map-size
48
+ position: relative
49
+ top: 0
50
+ right: 0
51
+
52
+ .unit-details-panel
53
+ overflow: scroll
54
+ background: var(--panel-secondary-background-color)
55
+ flex: 2
56
+ padding: 1em
57
+ max-width: 100%
58
+
59
+ .main-area
60
+ position: relative
61
+ flex: 1
62
+ min-height: 0
63
+ min-width: 0
64
+ overflow: scroll
65
+ background-color: var(--panel-secondary-background-color)
66
+
67
+
68
+ .correlation-diagram
69
+ padding: 1em
70
+ padding-left: 0
71
+ background-color: var(--panel-secondary-background-color)
72
+ //box-shadow: 0 0 0.3em 0 var(--card-shadow-color)
73
+ --column-background-color: var(--background-color)
74
+ --column-stroke-color: var(--text-color)
75
+
76
+
77
+ .package
78
+ position: relative
79
+
80
+ .package-overlay
81
+ position: absolute
82
+ top: 9px
83
+ left: 0
84
+ border: 2px solid red
85
+
86
+ .laterally-extensive-unit .strat-col-span
87
+ position: absolute
88
+ border: 2px solid red
89
+
90
+ .column-container
91
+ display: flex
92
+ flex-direction: row
93
+
94
+ .map-expanded-button
95
+ position: absolute
96
+ top: 0.5em
97
+ right: 0.5em
98
+ z-index: 100
99
+
100
+ .main-panel
101
+ position: relative
102
+ height: 100%
103
+ display: flex
104
+ flex-direction: column
105
+
106
+ .main-chart
107
+ position: relative
108
+
109
+ .correlation-chart-inner
110
+ display: flex
111
+ flex-direction: row
112
+ position: relative
113
+
114
+ .age-axis-container
115
+ display: flex
116
+ flex-direction: row
117
+ position: sticky
118
+ left: 0
119
+ z-index: 100
120
+ padding-left: 1em
121
+ padding-right: 2px
122
+ background-color: var(--panel-secondary-background-color)
@@ -0,0 +1,305 @@
1
+ /** Correlation chart */
2
+ import {
3
+ UnitSelectionProvider,
4
+ UnitKeyboardNavigation,
5
+ useUnitSelectionStore,
6
+ } from "../units";
7
+ import { UnitSelectionPopover } from "../unit-details";
8
+ import hyper from "@macrostrat/hyper";
9
+ import styles from "./main.module.sass";
10
+ import { useMemo, useRef } from "react";
11
+ import { useInDarkMode } from "@macrostrat/ui-components";
12
+ import { CompositeTimescaleCore } from "../section";
13
+ import classNames from "classnames";
14
+ import {
15
+ findLaterallyExtensiveUnits,
16
+ splitStratIntoBoxes,
17
+ UnitGroupBox,
18
+ CorrelationChartSettings,
19
+ buildCorrelationChartData,
20
+ } from "./prepare-data";
21
+ import {
22
+ CompositeAgeAxisCore,
23
+ CompositeStratigraphicScaleInfo,
24
+ } from "../age-axis";
25
+ import {
26
+ ColumnAxisType,
27
+ ColumnProvider,
28
+ SVG,
29
+ } from "@macrostrat/column-components";
30
+ import { ColoredUnitComponent } from "../units";
31
+ import { UnitBoxes } from "../units/boxes";
32
+ import { ExtUnit } from "../prepare-units/helpers";
33
+ import { ColumnContainer } from "../column";
34
+ import { ColumnData } from "../data-provider";
35
+ import { BaseUnit } from "@macrostrat/api-types";
36
+
37
+ const h = hyper.styled(styles);
38
+
39
+ export interface CorrelationChartProps extends CorrelationChartSettings {
40
+ data: ColumnData[];
41
+ columnWidth?: number;
42
+ columnSpacing?: number;
43
+ targetUnitHeight?: number;
44
+ unconformityLabels?: boolean;
45
+ selectedUnit?: number | null;
46
+ showUnitPopover?: boolean;
47
+ onUnitSelected?: (unitID: number | null, unit: BaseUnit | null) => void;
48
+ }
49
+
50
+ export function CorrelationChart({
51
+ data,
52
+ columnSpacing = 0,
53
+ columnWidth = 130,
54
+ unconformityLabels = true,
55
+ showUnitPopover = true,
56
+ selectedUnit,
57
+ onUnitSelected,
58
+ ...scaleProps
59
+ }: CorrelationChartProps) {
60
+ const defaultScaleProps = {
61
+ targetUnitHeight: 10,
62
+ unconformityHeight: 60,
63
+ minSectionHeight: 60,
64
+ collapseSmallUnconformities: true,
65
+ };
66
+
67
+ const chartData = useMemo(() => {
68
+ if (!data) return null;
69
+ return buildCorrelationChartData(data, {
70
+ ...defaultScaleProps,
71
+ ...scaleProps,
72
+ });
73
+ }, [data, ...Object.values(scaleProps)]);
74
+
75
+ const columnRef = useRef(null);
76
+
77
+ // A flattened units array is used to support keyboard navigation
78
+ const units = useMemo(() => {
79
+ return data?.map((d0) => d0.units).flat() ?? [];
80
+ }, [data]);
81
+
82
+ const inDarkMode = useInDarkMode();
83
+
84
+ const className = classNames({
85
+ "dark-mode": inDarkMode,
86
+ });
87
+
88
+ if (chartData == null) {
89
+ return null;
90
+ }
91
+
92
+ const { packages, scaleInfo, nColumns } = chartData;
93
+
94
+ const mainWidth = (columnWidth + columnSpacing) * nColumns;
95
+
96
+ return h(
97
+ ColumnContainer,
98
+ { className: "correlation-diagram" },
99
+ h(
100
+ UnitSelectionProvider,
101
+ { columnRef, selectedUnit, onUnitSelected, units },
102
+ h(ChartArea, [
103
+ h(TimescaleColumn, {
104
+ key: "timescale",
105
+ scaleInfo,
106
+ unconformityLabels,
107
+ }),
108
+ h("div.main-chart", { ref: columnRef }, [
109
+ h(
110
+ SVG,
111
+ {
112
+ className,
113
+ innerWidth: mainWidth,
114
+ height: scaleInfo.totalHeight,
115
+ paddingH: 4,
116
+ },
117
+ packages.map((pkg, i) => {
118
+ const { offset, domain, pixelScale, key } = scaleInfo.packages[i];
119
+ return h(Package, {
120
+ columnData: pkg.columnData,
121
+ key,
122
+ columnWidth,
123
+ columnSpacing,
124
+ offset,
125
+ domain,
126
+ pixelScale,
127
+ });
128
+ })
129
+ ),
130
+ h.if(showUnitPopover)(UnitSelectionPopover),
131
+ // Navigation only works within a column for now...
132
+ h(UnitKeyboardNavigation, { units }),
133
+ ]),
134
+ ])
135
+ )
136
+ );
137
+ }
138
+
139
+ function Package({
140
+ columnData,
141
+ columnSpacing,
142
+ columnWidth,
143
+ offset,
144
+ domain,
145
+ pixelScale,
146
+ }) {
147
+ return h("g.package", { transform: `translate(0 ${offset})` }, [
148
+ // Disable the SVG overlay for now
149
+ //h(PackageSVGOverlay, { data, columnSpacing }),
150
+ h("g.column-units", [
151
+ columnData.map((data, i) => {
152
+ return h(Column, {
153
+ units: data.units,
154
+ width: columnWidth,
155
+ key: i,
156
+ domain,
157
+ pixelScale,
158
+ offsetLeft: i * (columnWidth + columnSpacing),
159
+ });
160
+ }),
161
+ ]),
162
+ ]);
163
+ }
164
+
165
+ interface ColumnProps {
166
+ units: ExtUnit[];
167
+ unitComponent?: React.FunctionComponent<any>;
168
+ unitComponentProps?: any;
169
+ showLabels?: boolean;
170
+ width?: number;
171
+ columnWidth?: number;
172
+ columnSpacing?: number;
173
+ targetUnitHeight?: number;
174
+ offsetLeft?: number;
175
+ domain: [number, number];
176
+ pixelScale: number;
177
+ }
178
+
179
+ function Column(props: ColumnProps) {
180
+ const { units, width = 150, offsetLeft, domain, pixelScale } = props;
181
+
182
+ const columnWidth = width;
183
+
184
+ if (units.length == 0) {
185
+ return null;
186
+ }
187
+
188
+ return h(
189
+ "g.section",
190
+ {
191
+ transform: `translate(${offsetLeft} 0)`,
192
+ },
193
+ h(
194
+ ColumnProvider,
195
+ {
196
+ // Need to tighten up types here...
197
+ divisions: units as any[],
198
+ range: domain,
199
+ pixelsPerMeter: pixelScale, // Actually pixels per myr
200
+ axisType: ColumnAxisType.AGE,
201
+ },
202
+ h(UnitBoxes, {
203
+ unitComponent: ColoredUnitComponent,
204
+ unitComponentProps: {
205
+ nColumns: 2,
206
+ width: columnWidth,
207
+ },
208
+ })
209
+ )
210
+ );
211
+ }
212
+
213
+ function PackageSVGOverlay({ data, columnWidth = 100, columnSpacing = 0 }) {
214
+ const { b_age, t_age, bestPixelScale, columnData } = data;
215
+
216
+ const width = (columnWidth + columnSpacing) * columnData.length;
217
+ const height = Math.ceil((b_age - t_age) * bestPixelScale) + 2;
218
+
219
+ const extensiveUnits = findLaterallyExtensiveUnits(data);
220
+
221
+ const scale = (val: number) => {
222
+ return (val - t_age) * bestPixelScale;
223
+ };
224
+
225
+ return h(
226
+ "div.package-overlay",
227
+ { style: { width, height } },
228
+ extensiveUnits.map((d) => {
229
+ return h(LaterallyExtensiveUnit, {
230
+ data: d,
231
+ scale,
232
+ pixelScale: bestPixelScale,
233
+ columnSpacing,
234
+ });
235
+ })
236
+ );
237
+ }
238
+
239
+ function LaterallyExtensiveUnit({ data, scale, pixelScale, columnSpacing }) {
240
+ const { b_age, t_age, strat_name_long, units } = data;
241
+ // Build boxes by column groups
242
+ const boxes: UnitGroupBox[] = splitStratIntoBoxes(data);
243
+
244
+ return h(
245
+ "div.laterally-extensive-unit",
246
+ boxes.map((d, i) => {
247
+ return h(StratColSpan, {
248
+ scale,
249
+ data: d,
250
+ pixelScale,
251
+ key: i,
252
+ columnSpacing,
253
+ });
254
+ })
255
+ );
256
+ }
257
+
258
+ function StratColSpan({
259
+ data,
260
+ scale,
261
+ columnWidth = 100,
262
+ columnSpacing = 0,
263
+ pixelScale = 1,
264
+ }) {
265
+ const { startCol, endCol, strat_name_long, t_age, b_age } = data;
266
+ const top = scale(t_age);
267
+ const left = startCol * (columnWidth + columnSpacing);
268
+ const width = (endCol - startCol + 1) * (columnWidth + columnSpacing);
269
+ const height = (b_age - t_age) * pixelScale;
270
+ return h(
271
+ "div.strat-col-span",
272
+ { style: { top, height, width, left } },
273
+ strat_name_long
274
+ );
275
+ }
276
+
277
+ function ChartArea({ children }) {
278
+ const setSelectedUnit = useUnitSelectionStore(
279
+ (state) => state.setSelectedUnit
280
+ );
281
+
282
+ return h(
283
+ "div.correlation-chart-inner",
284
+ {
285
+ onClick() {
286
+ setSelectedUnit(null);
287
+ },
288
+ },
289
+ children
290
+ );
291
+ }
292
+
293
+ interface TimescaleColumnProps {
294
+ scaleInfo: CompositeStratigraphicScaleInfo;
295
+ showLabels?: boolean;
296
+ unconformityLabels?: boolean;
297
+ }
298
+
299
+ function TimescaleColumn(props: TimescaleColumnProps) {
300
+ const { scaleInfo, unconformityLabels = true } = props;
301
+ return h("div.column-container.age-axis-container", [
302
+ h(CompositeAgeAxisCore, { ...scaleInfo }),
303
+ h(CompositeTimescaleCore, { ...scaleInfo, unconformityLabels }),
304
+ ]);
305
+ }
@@ -0,0 +1,217 @@
1
+ import { CompositeStratigraphicScaleInfo } from "../age-axis";
2
+ import { PackageLayoutData } from "../prepare-units/composite-scale";
3
+ import { ColumnAxisType } from "@macrostrat/column-components";
4
+ import { type ColumnGeoJSONRecord, UnitLong } from "@macrostrat/api-types";
5
+ import {
6
+ MergeSectionsMode,
7
+ PrepareColumnOptions,
8
+ prepareColumnUnits,
9
+ preprocessUnits,
10
+ } from "../prepare-units";
11
+ import { mergeAgeRanges } from "@macrostrat/stratigraphy-utils";
12
+
13
+ export interface ColumnIdentifier {
14
+ col_id: number;
15
+ col_name: string;
16
+ project_id: number;
17
+ }
18
+
19
+ interface ColumnData {
20
+ columnID: number;
21
+ units: UnitLong[];
22
+ }
23
+
24
+ export interface CorrelationChartSettings
25
+ extends Omit<PrepareColumnOptions, "axisType"> {
26
+ targetUnitHeight?: number;
27
+ }
28
+
29
+ export interface CorrelationChartData {
30
+ packages: MultiColumnPackageData[];
31
+ scaleInfo: CompositeStratigraphicScaleInfo;
32
+ nColumns: number;
33
+ }
34
+
35
+ export interface ColumnIdentifier {
36
+ col_id: number;
37
+ col_name: string;
38
+ project_id: number;
39
+ }
40
+
41
+ export function buildCorrelationChartData(
42
+ columns: ColumnData[],
43
+ settings: CorrelationChartSettings
44
+ ): CorrelationChartData {
45
+ console.log(settings);
46
+ const {
47
+ mergeSections = MergeSectionsMode.OVERLAPPING,
48
+ targetUnitHeight,
49
+ ...rest
50
+ } = settings;
51
+
52
+ const opts: PrepareColumnOptions = {
53
+ axisType: ColumnAxisType.AGE,
54
+ targetUnitHeight,
55
+ ...rest,
56
+ };
57
+
58
+ if (columns.length == 0) {
59
+ return null;
60
+ }
61
+
62
+ // Flatten the units array to pretend that all units are in the same column
63
+ const _units = columns.map((d) => d.units).flat();
64
+
65
+ const columnIDs = columns.map((d) => d.columnID);
66
+
67
+ const preparedUnits = prepareColumnUnits(_units, opts);
68
+
69
+ const { sections, totalHeight } = preparedUnits;
70
+
71
+ const scaleInfo: CompositeStratigraphicScaleInfo = {
72
+ axisType: ColumnAxisType.AGE,
73
+ totalHeight,
74
+ packages: sections.map((d) => d.scaleInfo),
75
+ };
76
+
77
+ const packages = sections.map((d) => {
78
+ return separateColumns(d, columnIDs);
79
+ });
80
+
81
+ return { scaleInfo, packages, nColumns: columnIDs.length };
82
+ }
83
+
84
+ interface UnitGroup {
85
+ b_age: number;
86
+ t_age: number;
87
+ strat_name_id: number;
88
+ strat_name_long: string;
89
+ units: (UnitLong | null)[];
90
+ }
91
+
92
+ export interface UnitGroupBox extends UnitGroup {
93
+ units: UnitLong[];
94
+ startCol: number;
95
+ endCol: number;
96
+ }
97
+
98
+ interface ColumnExt {
99
+ columnID: number;
100
+ units: UnitLong[];
101
+ }
102
+
103
+ interface MultiColumnPackageData {
104
+ columnData: ColumnExt[];
105
+ bestPixelScale: number;
106
+ b_age: number;
107
+ t_age: number;
108
+ }
109
+
110
+ export function findLaterallyExtensiveUnits(
111
+ pkg: MultiColumnPackageData
112
+ ): UnitGroup[] {
113
+ const { columnData, b_age, t_age } = pkg;
114
+ // Group units by strat_name_id
115
+ const unitIndex = new Map<number, Map<number, UnitLong>>();
116
+ for (const column of columnData) {
117
+ const { units } = column;
118
+ for (const unit of units) {
119
+ if (unit.strat_name_id == null) continue;
120
+ if (!unitIndex.has(unit.strat_name_id)) {
121
+ unitIndex.set(unit.strat_name_id, new Map());
122
+ }
123
+ unitIndex.get(unit.strat_name_id).set(column.columnID, unit);
124
+ }
125
+ }
126
+
127
+ // Prepare grouped units for rendering
128
+ const unitGroups: UnitGroup[] = [];
129
+ for (const [strat_name_id, unitIndex0] of unitIndex) {
130
+ const units = columnData.map((d) => unitIndex0.get(d.columnID) ?? null);
131
+ const filteredUnits = units.filter((d) => d != null);
132
+ const [t_age, b_age] = mergeAgeRanges(
133
+ filteredUnits.map((d) => [d.t_age, d.b_age])
134
+ );
135
+ if (filteredUnits.length <= 1) continue;
136
+
137
+ unitGroups.push({
138
+ b_age,
139
+ t_age,
140
+ strat_name_id,
141
+ strat_name_long: filteredUnits[0].strat_name_long,
142
+ units,
143
+ });
144
+ }
145
+
146
+ return unitGroups;
147
+ }
148
+
149
+ export function splitStratIntoBoxes(pkg: UnitGroup): UnitGroupBox[] {
150
+ const { strat_name_long, strat_name_id, units } = pkg;
151
+ const boxes: UnitGroupBox[] = [];
152
+ let currentBox: UnitGroupBox = null;
153
+ for (let i = 0; i < units.length; i++) {
154
+ const unit = units[i];
155
+ if (unit == null) {
156
+ if (currentBox != null) {
157
+ boxes.push(currentBox);
158
+ currentBox = null;
159
+ }
160
+ continue;
161
+ }
162
+ if (currentBox == null) {
163
+ currentBox = {
164
+ startCol: i,
165
+ endCol: i,
166
+ strat_name_id,
167
+ strat_name_long,
168
+ t_age: unit.t_age,
169
+ b_age: unit.b_age,
170
+ units: [],
171
+ };
172
+ } else {
173
+ currentBox.endCol = i;
174
+ }
175
+ currentBox.units.push(unit);
176
+ }
177
+ return boxes;
178
+ }
179
+
180
+ function separateColumns(
181
+ pkg: PackageLayoutData,
182
+ columnIDs: number[]
183
+ ): MultiColumnPackageData {
184
+ /** Separate columns by col_id */
185
+ const { units, t_age, b_age } = pkg;
186
+
187
+ return {
188
+ columnData: columnIDs.map((d) => {
189
+ const u1 = units.filter((unit) => unit.col_id == d);
190
+ u1.sort((a, b) => a.t_age - b.t_age);
191
+ return {
192
+ columnID: d,
193
+ // Ensure that the units correctly show overlap
194
+ units: preprocessUnits(
195
+ {
196
+ ...pkg,
197
+ units: u1,
198
+ },
199
+ ColumnAxisType.AGE
200
+ ),
201
+ };
202
+ }),
203
+ bestPixelScale: pkg.scaleInfo.pixelScale,
204
+ t_age,
205
+ b_age,
206
+ };
207
+ }
208
+
209
+ export function columnGeoJSONRecordToColumnIdentifier(
210
+ col: ColumnGeoJSONRecord
211
+ ): ColumnIdentifier {
212
+ return {
213
+ col_id: col.properties.col_id,
214
+ col_name: col.properties.col_name,
215
+ project_id: col.properties.project_id,
216
+ };
217
+ }