@macrostrat/column-views 3.9.0 → 3.11.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 (138) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/column-views.css +10 -0
  3. package/dist/correlation-chart/main.cjs +11 -3
  4. package/dist/correlation-chart/main.cjs.map +1 -1
  5. package/dist/correlation-chart/main.d.ts +1 -1
  6. package/dist/correlation-chart/main.js +11 -3
  7. package/dist/correlation-chart/main.js.map +1 -1
  8. package/dist/index.cjs +18 -42
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.js +4 -34
  12. package/dist/index.js.map +1 -1
  13. package/dist/unit-details/age-window-tag.cjs +68 -0
  14. package/dist/unit-details/age-window-tag.cjs.map +1 -0
  15. package/dist/unit-details/age-window-tag.d.ts +26 -0
  16. package/dist/unit-details/age-window-tag.js +66 -0
  17. package/dist/unit-details/age-window-tag.js.map +1 -0
  18. package/dist/unit-details/age-window-tag.module.sass.cjs +12 -0
  19. package/dist/unit-details/age-window-tag.module.sass.cjs.map +1 -0
  20. package/dist/unit-details/age-window-tag.module.sass.js +11 -0
  21. package/dist/unit-details/age-window-tag.module.sass.js.map +1 -0
  22. package/dist/unit-details/index.d.ts +1 -0
  23. package/dist/units/boxes.cjs +3 -3
  24. package/dist/units/boxes.cjs.map +1 -1
  25. package/dist/units/boxes.js +3 -3
  26. package/dist/units/boxes.js.map +1 -1
  27. package/dist/units/index.cjs +7 -11
  28. package/dist/units/index.cjs.map +1 -1
  29. package/dist/units/index.d.ts +0 -1
  30. package/dist/units/index.js +4 -9
  31. package/dist/units/index.js.map +1 -1
  32. package/package.json +6 -27
  33. package/src/correlation-chart/main.ts +14 -2
  34. package/src/index.ts +3 -1
  35. package/src/unit-details/age-window-tag.module.sass +10 -0
  36. package/src/unit-details/age-window-tag.ts +102 -0
  37. package/src/unit-details/index.ts +1 -0
  38. package/src/units/boxes.ts +7 -4
  39. package/src/units/index.ts +9 -26
  40. package/dist/maps/column-correlation/core.cjs +0 -288
  41. package/dist/maps/column-correlation/core.cjs.map +0 -1
  42. package/dist/maps/column-correlation/core.d.ts +0 -9
  43. package/dist/maps/column-correlation/core.js +0 -286
  44. package/dist/maps/column-correlation/core.js.map +0 -1
  45. package/dist/maps/column-correlation/index.d.ts +0 -2
  46. package/dist/maps/column-correlation/state.cjs +0 -193
  47. package/dist/maps/column-correlation/state.cjs.map +0 -1
  48. package/dist/maps/column-correlation/state.d.ts +0 -62
  49. package/dist/maps/column-correlation/state.js +0 -190
  50. package/dist/maps/column-correlation/state.js.map +0 -1
  51. package/dist/maps/column-navigation/index.d.ts +0 -2
  52. package/dist/maps/column-navigation/mapbox/index.cjs +0 -215
  53. package/dist/maps/column-navigation/mapbox/index.cjs.map +0 -1
  54. package/dist/maps/column-navigation/mapbox/index.d.ts +0 -38
  55. package/dist/maps/column-navigation/mapbox/index.js +0 -213
  56. package/dist/maps/column-navigation/mapbox/index.js.map +0 -1
  57. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs +0 -105
  58. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs.map +0 -1
  59. package/dist/maps/column-navigation/mapbox/keyboard-navigation.d.ts +0 -8
  60. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js +0 -105
  61. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js.map +0 -1
  62. package/dist/maps/column-navigation/mapbox/state.cjs +0 -73
  63. package/dist/maps/column-navigation/mapbox/state.cjs.map +0 -1
  64. package/dist/maps/column-navigation/mapbox/state.d.ts +0 -23
  65. package/dist/maps/column-navigation/mapbox/state.js +0 -71
  66. package/dist/maps/column-navigation/mapbox/state.js.map +0 -1
  67. package/dist/maps/column-navigation/svg/animated.d.ts +0 -1
  68. package/dist/maps/column-navigation/svg/data-fetcher.cjs +0 -25
  69. package/dist/maps/column-navigation/svg/data-fetcher.cjs.map +0 -1
  70. package/dist/maps/column-navigation/svg/data-fetcher.d.ts +0 -6
  71. package/dist/maps/column-navigation/svg/data-fetcher.js +0 -25
  72. package/dist/maps/column-navigation/svg/data-fetcher.js.map +0 -1
  73. package/dist/maps/column-navigation/svg/index.cjs +0 -94
  74. package/dist/maps/column-navigation/svg/index.cjs.map +0 -1
  75. package/dist/maps/column-navigation/svg/index.d.ts +0 -9
  76. package/dist/maps/column-navigation/svg/index.js +0 -93
  77. package/dist/maps/column-navigation/svg/index.js.map +0 -1
  78. package/dist/maps/column-navigation/svg/layers.cjs +0 -177
  79. package/dist/maps/column-navigation/svg/layers.cjs.map +0 -1
  80. package/dist/maps/column-navigation/svg/layers.d.ts +0 -54
  81. package/dist/maps/column-navigation/svg/layers.js +0 -174
  82. package/dist/maps/column-navigation/svg/layers.js.map +0 -1
  83. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs +0 -50
  84. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs.map +0 -1
  85. package/dist/maps/column-navigation/utils/keyboard-navigation.d.ts +0 -10
  86. package/dist/maps/column-navigation/utils/keyboard-navigation.js +0 -50
  87. package/dist/maps/column-navigation/utils/keyboard-navigation.js.map +0 -1
  88. package/dist/maps/index.d.ts +0 -4
  89. package/dist/maps/inset-map/index.cjs +0 -71
  90. package/dist/maps/inset-map/index.cjs.map +0 -1
  91. package/dist/maps/inset-map/index.d.ts +0 -16
  92. package/dist/maps/inset-map/index.js +0 -69
  93. package/dist/maps/inset-map/index.js.map +0 -1
  94. package/dist/maps/layers/columns.cjs +0 -165
  95. package/dist/maps/layers/columns.cjs.map +0 -1
  96. package/dist/maps/layers/columns.d.ts +0 -28
  97. package/dist/maps/layers/columns.js +0 -165
  98. package/dist/maps/layers/columns.js.map +0 -1
  99. package/dist/maps/layers/index.d.ts +0 -2
  100. package/dist/maps/layers/units.cjs +0 -207
  101. package/dist/maps/layers/units.cjs.map +0 -1
  102. package/dist/maps/layers/units.d.ts +0 -14
  103. package/dist/maps/layers/units.js +0 -204
  104. package/dist/maps/layers/units.js.map +0 -1
  105. package/dist/units/colors.cjs +0 -115
  106. package/dist/units/colors.cjs.map +0 -1
  107. package/dist/units/colors.d.ts +0 -20
  108. package/dist/units/colors.js +0 -113
  109. package/dist/units/colors.js.map +0 -1
  110. package/dist/units/resolvers.cjs +0 -125
  111. package/dist/units/resolvers.cjs.map +0 -1
  112. package/dist/units/resolvers.d.ts +0 -8
  113. package/dist/units/resolvers.js +0 -125
  114. package/dist/units/resolvers.js.map +0 -1
  115. package/src/maps/column-correlation/column-correlation-map.stories.ts +0 -108
  116. package/src/maps/column-correlation/core.ts +0 -342
  117. package/src/maps/column-correlation/index.ts +0 -2
  118. package/src/maps/column-correlation/state.ts +0 -315
  119. package/src/maps/column-navigation/index.ts +0 -2
  120. package/src/maps/column-navigation/mapbox/column-navigation-map.stories.ts +0 -278
  121. package/src/maps/column-navigation/mapbox/index.ts +0 -276
  122. package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +0 -133
  123. package/src/maps/column-navigation/mapbox/state.ts +0 -119
  124. package/src/maps/column-navigation/svg/animated.ts +0 -78
  125. package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +0 -46
  126. package/src/maps/column-navigation/svg/data-fetcher.ts +0 -34
  127. package/src/maps/column-navigation/svg/index.ts +0 -96
  128. package/src/maps/column-navigation/svg/layers.ts +0 -233
  129. package/src/maps/column-navigation/utils/keyboard-navigation.ts +0 -58
  130. package/src/maps/index.ts +0 -4
  131. package/src/maps/inset-map/index.ts +0 -87
  132. package/src/maps/inset-map/inset-map.stories.ts +0 -20
  133. package/src/maps/layers/columns.ts +0 -216
  134. package/src/maps/layers/index.ts +0 -2
  135. package/src/maps/layers/units.ts +0 -286
  136. package/src/maps/unit-map.stories.ts +0 -79
  137. package/src/units/colors.ts +0 -183
  138. package/src/units/resolvers.ts +0 -141
@@ -1,278 +0,0 @@
1
- import h from "@macrostrat/hyper";
2
-
3
- const mapboxToken = import.meta.env.VITE_MAPBOX_API_TOKEN;
4
-
5
- import { Meta } from "@storybook/react-vite";
6
- import { ColumnNavigationMap } from ".";
7
- import { useState } from "react";
8
-
9
- function ColumnNavigationMapExt(props) {
10
- return h(ColumnNavigationMap, {
11
- style: { width: "800px", height: "600px" },
12
- padding: 100,
13
- accessToken: mapboxToken,
14
- ...props,
15
- });
16
- }
17
-
18
- // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
19
- export default {
20
- title: "Column views/Maps/Column navigation",
21
- component: ColumnNavigationMapExt,
22
- description: "Cross section creation map",
23
- } as Meta<typeof ColumnNavigationMap>;
24
-
25
- export const ColumnNavigation = {
26
- args: {
27
- showTriangulation: false,
28
- },
29
- };
30
-
31
- export const ColumnNavigationFilterableByIds = {
32
- args: {
33
- showTriangulation: false,
34
- columnIDs: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
35
- },
36
- };
37
-
38
- const colData = [
39
- {
40
- id: 1,
41
- type: "Feature",
42
- geometry: {
43
- type: "Polygon",
44
- coordinates: [
45
- [
46
- [-86.9992, 34.6946],
47
- [-86.9041, 35.4015],
48
- [-86.5971, 35.4513],
49
- [-86.1652, 35.0947],
50
- [-86.1746, 34.7447],
51
- [-86.5036, 34.4262],
52
- [-86.6318, 34.4244],
53
- [-86.9992, 34.6946],
54
- ],
55
- ],
56
- },
57
- properties: {
58
- col_id: 2,
59
- col_name: "Madison Co, Alabama",
60
- col_group: "Southern Appalachians",
61
- col_group_id: 17,
62
- group_col_id: "1.00",
63
- lat: "34.85300",
64
- lng: "-86.56200",
65
- col_area: "6345.4",
66
- project_id: 1,
67
- col_type: "column",
68
- refs: [1],
69
- max_thick: 2559,
70
- max_min_thick: 2411,
71
- min_min_thick: 529,
72
- b_age: 1550,
73
- t_age: 322.15,
74
- b_int_name: "Calymmian",
75
- t_int_name: "Morrowan",
76
- pbdb_collections: 3,
77
- lith: [
78
- {
79
- name: "mudstone",
80
- type: "siliciclastic",
81
- class: "sedimentary",
82
- prop: 0.0041,
83
- lith_id: 7,
84
- },
85
- {
86
- name: "shale",
87
- type: "siliciclastic",
88
- class: "sedimentary",
89
- prop: 0.2598,
90
- lith_id: 8,
91
- },
92
- {
93
- name: "siltstone",
94
- type: "siliciclastic",
95
- class: "sedimentary",
96
- prop: 0.0107,
97
- lith_id: 9,
98
- },
99
- {
100
- name: "sandstone",
101
- type: "siliciclastic",
102
- class: "sedimentary",
103
- prop: 0.0322,
104
- lith_id: 10,
105
- },
106
- {
107
- name: "limestone",
108
- type: "carbonate",
109
- class: "sedimentary",
110
- prop: 0.4093,
111
- lith_id: 30,
112
- },
113
- {
114
- name: "dolomite",
115
- type: "carbonate",
116
- class: "sedimentary",
117
- prop: 0.1132,
118
- lith_id: 31,
119
- },
120
- {
121
- name: "coal",
122
- type: "organic",
123
- class: "sedimentary",
124
- prop: 0.0057,
125
- lith_id: 38,
126
- },
127
- {
128
- name: "chert",
129
- type: "chemical",
130
- class: "sedimentary",
131
- prop: 0.0674,
132
- lith_id: 45,
133
- },
134
- {
135
- name: "granite",
136
- type: "plutonic",
137
- class: "igneous",
138
- prop: 0.0379,
139
- lith_id: 53,
140
- },
141
- {
142
- name: "rhyolite",
143
- type: "volcanic",
144
- class: "igneous",
145
- prop: 0.0076,
146
- lith_id: 64,
147
- },
148
- {
149
- name: "ash",
150
- type: "volcanic",
151
- class: "igneous",
152
- prop: 0.0107,
153
- lith_id: 75,
154
- },
155
- {
156
- name: "quartz arenite",
157
- type: "siliciclastic",
158
- class: "sedimentary",
159
- prop: 0.0207,
160
- lith_id: 169,
161
- },
162
- {
163
- name: "sublitharenite",
164
- type: "siliciclastic",
165
- class: "sedimentary",
166
- prop: 0.0207,
167
- lith_id: 199,
168
- },
169
- ],
170
- environ: [
171
- {
172
- name: "marine",
173
- type: "",
174
- class: "marine",
175
- prop: 0.0476,
176
- environ_id: 38,
177
- },
178
- {
179
- name: "fluvial-deltaic indet.",
180
- type: "fluvial",
181
- class: "non-marine",
182
- prop: 0.0476,
183
- environ_id: 57,
184
- },
185
- {
186
- name: "inferred marine",
187
- type: "",
188
- class: "marine",
189
- prop: 0.9048,
190
- environ_id: 93,
191
- },
192
- ],
193
- econ: [],
194
- t_units: 22,
195
- t_sections: 6,
196
- },
197
- },
198
- ];
199
-
200
- export const ColumnNavigationFilterableByGeojson = {
201
- args: {
202
- showTriangulation: false,
203
- columns: colData,
204
- },
205
- };
206
-
207
- export const nonStandardProjectInProcess = {
208
- args: {
209
- padding: 100,
210
- projectID: 10,
211
- inProcess: true,
212
- showTriangulation: false,
213
- mapPosition: {
214
- camera: {
215
- lng: -72,
216
- lat: 44,
217
- altitude: 600000,
218
- },
219
- },
220
- },
221
- };
222
-
223
- export const DeepSea = {
224
- args: {
225
- padding: 100,
226
- projectID: 4,
227
- inProcess: true,
228
- showTriangulation: false,
229
- center: [0, 0],
230
- zoom: 2,
231
- mapPosition: null,
232
- },
233
- };
234
-
235
- export const eODP = {
236
- args: {
237
- projectID: 3,
238
- inProcess: true,
239
- },
240
- };
241
-
242
- export const showTriangulation = {
243
- description: "Show the triangulation used for keyboard navigation",
244
- args: {
245
- showTriangulation: true,
246
- columnColor: "#1fff53",
247
- triangulationColor: "#9a33bb",
248
- },
249
- };
250
-
251
- export const onlyPhysicalBasemap = {
252
- args: {
253
- mapStyle: "mapbox://styles/mapbox/outdoors-v11",
254
- showLabels: true,
255
- showAdmin: false,
256
- showRoads: false,
257
- },
258
- };
259
-
260
- export function ControlledColumnNavigation() {
261
- const [selectedColumn, setSelectedColumn] = useState(157);
262
- const [hoveredColumn, setHoveredColumn] = useState(null);
263
-
264
- return h("div.controlled-navigation", [
265
- h(ColumnNavigationMapExt, {
266
- selectedColumn,
267
- hoveredColumn,
268
- onSelectColumn: setSelectedColumn,
269
- onHoverColumn: setHoveredColumn,
270
- }),
271
- h("div.column-info", [
272
- h("h3", "Selected column"),
273
- h("p", selectedColumn),
274
- h("h3", "Hovered column"),
275
- h("p", hoveredColumn),
276
- ]),
277
- ]);
278
- }
@@ -1,276 +0,0 @@
1
- import { useMapRef, useMapStyleOperator } from "@macrostrat/mapbox-react";
2
- import h from "@macrostrat/hyper";
3
- import { ReactNode, useCallback, useEffect, useMemo, useRef } from "react";
4
-
5
- import {
6
- ColumnNavigationProvider,
7
- NavigationProviderProps,
8
- useColumnNavigationStore,
9
- } from "./state";
10
- import { InsetMap, type InsetMapProps } from "../../inset-map";
11
- import { geoCentroid } from "d3-geo";
12
- import { BaseColumnsLayer, SelectedColumnOverlay } from "../../layers";
13
- import { ColumnKeyboardNavigation } from "./keyboard-navigation";
14
- import type { ColumnFeature } from "../../layers";
15
-
16
- export interface ColumnNavigationMapProps extends InsetMapProps {
17
- padding?: number;
18
- children?: ReactNode;
19
- accessToken?: string;
20
- selectedColumn?: number;
21
- hoveredColumn?: number;
22
- onSelectColumn?: (colID: number | null) => void;
23
- onHoverColumn?: (colID: number | null) => void;
24
- showTriangulation?: boolean;
25
- columnColor?: string;
26
- }
27
-
28
- export function ColumnNavigationMap(
29
- props: ColumnNavigationMapProps & NavigationProviderProps,
30
- ) {
31
- const {
32
- padding = 50,
33
- children,
34
- columnColor,
35
- showTriangulation,
36
- triangulationColor,
37
- keyboardNavigation = true,
38
- columns,
39
- columnIDs,
40
- onSelectColumn,
41
- onHoverColumn,
42
- selectedColumn,
43
- hoveredColumn,
44
- projectID,
45
- inProcess,
46
- ...rest
47
- } = props;
48
-
49
- return h(
50
- InsetMap,
51
- {
52
- ...rest,
53
- boxZoom: false,
54
- dragRotate: false,
55
- },
56
- [
57
- h(ColumnsNavigationLayer, {
58
- color: columnColor,
59
- columns,
60
- columnIDs,
61
- onSelectColumn,
62
- onHoverColumn,
63
- selectedColumn,
64
- hoveredColumn,
65
- projectID,
66
- inProcess,
67
- keyboardNavigation,
68
- showTriangulation,
69
- triangulationColor,
70
- }),
71
- children,
72
- ],
73
- );
74
- }
75
-
76
- interface ColumnLayerProps {
77
- enabled?: boolean;
78
- color?: string;
79
- }
80
-
81
- interface ColumnKeyboardNavigationProps {
82
- triangulationColor?: string;
83
- keyboardNavigation?: boolean;
84
- showTriangulation?: boolean;
85
- }
86
-
87
- export function ColumnsNavigationLayer(
88
- props: NavigationProviderProps &
89
- ColumnLayerProps &
90
- ColumnKeyboardNavigationProps,
91
- ) {
92
- const {
93
- enabled,
94
- color,
95
- keyboardNavigation,
96
- showTriangulation,
97
- triangulationColor,
98
- ...providerProps
99
- } = props;
100
-
101
- return h(ColumnNavigationProvider, providerProps, [
102
- h(_ColumnsNavigationLayer, { enabled, color }),
103
- h.if(keyboardNavigation)(ColumnKeyboardNavigation, {
104
- showTriangulation,
105
- triangulationColor,
106
- }),
107
- ]);
108
- }
109
-
110
- const columnLayers = ["columns-points", "columns-fill"];
111
-
112
- function _ColumnsNavigationLayer({ enabled = true, color }) {
113
- const columns = useColumnNavigationStore((state) => state.columns);
114
- const selectedColumnID = useColumnNavigationStore(
115
- (state) => state.selectedColumn,
116
- );
117
- const selectColumn = useColumnNavigationStore((state) => state.selectColumn);
118
- const setHoveredColumn = useColumnNavigationStore(
119
- (state) => state.setHoveredColumn,
120
- );
121
-
122
- const onHover = useCallback(
123
- (event) => setHoveredColumn(event.features?.[0]?.id),
124
- [setHoveredColumn],
125
- );
126
-
127
- /** Convert features into column IDs to pass to the selection manager */
128
- const onSelectColumn = useCallback(
129
- (column) => selectColumn(column.id),
130
- [selectColumn],
131
- );
132
-
133
- const selectedColumnFeature = useMemo(() => {
134
- if (columns == null || selectedColumnID == null) return null;
135
- return columns.find((d) => d.id == selectedColumnID);
136
- }, [selectedColumnID, columns]);
137
-
138
- return h([
139
- h(BaseColumnsLayer, { enabled, color, columns }),
140
- h(ColumnSelectionManager, {
141
- selectedColumn: selectedColumnFeature,
142
- onSelectColumn,
143
- }),
144
- h(ColumnHoverInteraction, { onHover }),
145
- ]);
146
- }
147
-
148
- export function ColumnSelectionManager({
149
- selectedColumn,
150
- onSelectColumn,
151
- centerOnSelect = true,
152
- }: {
153
- selectedColumn: ColumnFeature;
154
- onSelectColumn: (column: ColumnFeature) => void;
155
- centerOnSelect?: boolean;
156
- }) {
157
- const onClick = useCallback(
158
- (event) => {
159
- if (event.features.length == 0) return;
160
- const selectedColumn = event.features[0];
161
- onSelectColumn(selectedColumn);
162
- },
163
- [onSelectColumn],
164
- );
165
-
166
- return h([
167
- h.if(centerOnSelect)(SelectedColumnCenterer, {
168
- selectedColumn,
169
- }),
170
- h(SelectedColumnOverlay, { selectedColumn }),
171
- h(ClickInteraction, {
172
- onClick,
173
- layers: columnLayers,
174
- }),
175
- ]);
176
- }
177
-
178
- export function ColumnHoverInteraction({ onHover }) {
179
- return h(HoverInteraction, { onHover, layers: columnLayers });
180
- }
181
-
182
- function ClickInteraction({ onClick, layers }) {
183
- useMapStyleOperator(
184
- (map) => {
185
- // Setup hover styles on map
186
- map.on("click", layers, onClick);
187
- return () => {
188
- map.off("click", layers, onClick);
189
- };
190
- },
191
- [layers, onClick],
192
- );
193
- return null;
194
- }
195
-
196
- function HoverInteraction({ onHover, layers }) {
197
- const hoveredFeaturesRef = useRef([]);
198
- const updateFeatureState = useCallback((map, features) => {
199
- // Reset hover state for previously hovered features
200
- for (const f of hoveredFeaturesRef.current) {
201
- map.setFeatureState(
202
- { source: f.source, id: f.id, sourceLayer: f.sourceLayer },
203
- { hover: false },
204
- );
205
- }
206
- // Set hover state for new features
207
- for (const f of features) {
208
- map.setFeatureState(
209
- { source: f.source, id: f.id, sourceLayer: f.sourceLayer },
210
- { hover: true },
211
- );
212
- }
213
- hoveredFeaturesRef.current = features;
214
- }, []);
215
-
216
- useMapStyleOperator(
217
- (map) => {
218
- const mouseMove = (event) => {
219
- if (event.features.length == 0) return;
220
- onHover?.(event);
221
- updateFeatureState(map, event.features);
222
- map.getCanvas().style.cursor = "pointer";
223
- };
224
- const mouseLeave = (event) => {
225
- onHover?.(event);
226
- updateFeatureState(map, event.features ?? []);
227
- map.getCanvas().style.cursor = "";
228
- };
229
-
230
- // Setup hover styles on map
231
- map.on("mousemove", layers, mouseMove);
232
- map.on("mouseleave", layers, mouseLeave);
233
-
234
- return () => {
235
- map.off("mouseenter", layers, mouseMove);
236
- map.off("mouseleave", layers, mouseLeave);
237
- };
238
- },
239
- [layers, onHover],
240
- );
241
- return null;
242
- }
243
-
244
- function SelectedColumnCenterer({
245
- selectedColumn,
246
- easeDuration = 500,
247
- }: {
248
- selectedColumn: ColumnFeature;
249
- easeDuration?: number;
250
- }) {
251
- const columnCenter = useMemo(() => {
252
- const columnGeometry = selectedColumn?.geometry;
253
- if (columnGeometry == null) return null;
254
- return geoCentroid(columnGeometry);
255
- }, [selectedColumn]);
256
-
257
- const mapRef = useMapRef();
258
- const map = mapRef.current;
259
- const initialRenderRef = useRef(true);
260
- // Center the map on the selected column when it changes
261
- useEffect(() => {
262
- if (map == null) return;
263
- const isInitialRender = initialRenderRef.current;
264
- if (isInitialRender) initialRenderRef.current = false;
265
- // If this is the first render of the map, jump to the location. Otherwise, ease to it.
266
- if (columnCenter == null) return;
267
- if (isInitialRender) {
268
- map.setCenter(columnCenter);
269
- initialRenderRef.current = false;
270
- } else {
271
- map.easeTo({ center: columnCenter }, { duration: easeDuration });
272
- }
273
- }, [mapRef.current, columnCenter]);
274
-
275
- return null;
276
- }
@@ -1,133 +0,0 @@
1
- import { useCallback, useEffect, useMemo } from "react";
2
- import { buildGeoJSONSource, setGeoJSON } from "@macrostrat/mapbox-utils";
3
- import {
4
- useMapRef,
5
- useMapStyleOperator,
6
- useOverlayStyle,
7
- } from "@macrostrat/mapbox-react";
8
- import { useColumnNavigationStore } from "./state";
9
- import {
10
- buildTriangulation,
11
- buildKeyMapping,
12
- } from "../utils/keyboard-navigation";
13
- import { StyleSpecification } from "mapbox-gl";
14
-
15
- interface KeyboardNavProps {
16
- showTriangulation: boolean;
17
- triangulationColor?: string;
18
- }
19
-
20
- export function ColumnKeyboardNavigation(props: KeyboardNavProps) {
21
- /** Keyboard navigation of columns using a Delaunay triangulation */
22
- const { showTriangulation = false, triangulationColor } = props;
23
- const columns = useColumnNavigationStore((state) => state.columns);
24
- const col_id = useColumnNavigationStore((state) => state.selectedColumn);
25
- const selectColumn = useColumnNavigationStore((state) => state.selectColumn);
26
-
27
- const voronoi = useMemo(() => {
28
- if (!columns || columns.length == 0) return null;
29
- return buildTriangulation(columns);
30
- }, [columns]);
31
-
32
- const mapRef = useMapRef();
33
- const map = mapRef.current;
34
-
35
- // Set up overlay style for triangulation
36
- useOverlayStyle(() => {
37
- if (!showTriangulation) return null;
38
- return buildKeyboardNavigationStyle(
39
- triangulationColor,
40
- ) as Partial<StyleSpecification>;
41
- }, [triangulationColor, showTriangulation]);
42
-
43
- const keyMapping = useMemo(() => {
44
- if (columns == null || voronoi == null || map == null) return null;
45
-
46
- const projection = (d) => {
47
- const pt = map.project(d);
48
- return [pt.x, pt.y];
49
- };
50
-
51
- const currentIndex = columns.findIndex(
52
- (d) => d.properties.col_id == col_id,
53
- );
54
-
55
- const neighbors = voronoi.tri.delaunay.neighbors[currentIndex];
56
- return buildKeyMapping(
57
- neighbors,
58
- voronoi.centroids,
59
- currentIndex,
60
- projection,
61
- );
62
- }, [col_id, columns, voronoi, map]);
63
-
64
- const onKeyDown = useCallback(
65
- (event: KeyboardEvent) => {
66
- if (keyMapping == null) return;
67
- const nextColumnIx = keyMapping[event.which];
68
- if (nextColumnIx == null) return;
69
- event.preventDefault();
70
- event.stopPropagation();
71
- // @ts-ignore
72
- selectColumn(columns[nextColumnIx].id);
73
- return false;
74
- },
75
- [keyMapping, selectColumn],
76
- );
77
-
78
- useEffect(() => {
79
- if (map == null) return;
80
- const canvas = map.getCanvas();
81
- canvas.addEventListener("keydown", onKeyDown);
82
- return () => {
83
- canvas.removeEventListener("keydown", onKeyDown);
84
- };
85
- }, [map, onKeyDown]);
86
-
87
- useMapStyleOperator(
88
- (map) => {
89
- if (voronoi == null || !showTriangulation) return;
90
- const { features } = voronoi.tri.links();
91
-
92
- setGeoJSON(map, "column-links", {
93
- type: "FeatureCollection",
94
- features,
95
- });
96
- },
97
- [voronoi, showTriangulation],
98
- );
99
-
100
- //if (neighbors == null) return null;
101
- //const neighborFeatures = neighbors.map((d) => features[d]);
102
-
103
- return null;
104
- }
105
-
106
- export function buildKeyboardNavigationStyle(color: string = "purple") {
107
- return {
108
- sources: {
109
- "column-links": buildGeoJSONSource(),
110
- //neighbors: buildGeoJSONSource(),
111
- },
112
- layers: [
113
- {
114
- id: "column-links",
115
- type: "line",
116
- source: "column-links",
117
- paint: {
118
- "line-color": color,
119
- "line-width": 1.5,
120
- },
121
- },
122
- {
123
- id: "column-centers",
124
- type: "circle",
125
- source: "column-links",
126
- paint: {
127
- "circle-radius": 2,
128
- "circle-color": color,
129
- },
130
- },
131
- ],
132
- } as Partial<StyleSpecification>;
133
- }