@macrostrat/column-views 1.0.3 → 2.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.
- package/CHANGELOG.md +17 -0
- package/dist/esm/_shared.f7eec55a.js +9 -0
- package/dist/esm/_shared.f7eec55a.js.map +1 -0
- package/dist/esm/age-axis.4a8cf5e6.js +98 -0
- package/dist/esm/age-axis.4a8cf5e6.js.map +1 -0
- package/dist/esm/age-axis.module.03773a80.css +33 -0
- package/dist/esm/age-axis.module.03773a80.css.map +1 -0
- package/dist/esm/age-axis.module.3cc91335.js +22 -0
- package/dist/esm/age-axis.module.3cc91335.js.map +1 -0
- package/dist/esm/age-model-overlay.c7226855.js +57 -0
- package/dist/esm/age-model-overlay.c7226855.js.map +1 -0
- package/dist/esm/age-model-overlay.module.5d9e78fb.css +14 -0
- package/dist/esm/age-model-overlay.module.5d9e78fb.css.map +1 -0
- package/dist/esm/age-model-overlay.module.cd985dcb.js +16 -0
- package/dist/esm/age-model-overlay.module.cd985dcb.js.map +1 -0
- package/dist/esm/base.910b80b4.js +288 -0
- package/dist/esm/base.910b80b4.js.map +1 -0
- package/dist/esm/boxes.8292cff2.js +258 -0
- package/dist/esm/boxes.8292cff2.js.map +1 -0
- package/dist/esm/boxes.module.2b5fb18e.css +26 -0
- package/dist/esm/boxes.module.2b5fb18e.css.map +1 -0
- package/dist/esm/boxes.module.4ebc7796.js +19 -0
- package/dist/esm/boxes.module.4ebc7796.js.map +1 -0
- package/dist/esm/{carbon-isotopes.3b502a9e.js → carbon-isotopes.10db8285.js} +2 -2
- package/dist/esm/{carbon-isotopes.3b502a9e.js.map → carbon-isotopes.10db8285.js.map} +1 -1
- package/dist/esm/colors.395c6db5.js +40 -0
- package/dist/esm/colors.395c6db5.js.map +1 -0
- package/dist/esm/column-correlation.c8dcfe98.js +9 -0
- package/dist/esm/column-correlation.c8dcfe98.js.map +1 -0
- package/dist/esm/column-nav.5414677c.js +55 -0
- package/dist/esm/column-nav.5414677c.js.map +1 -0
- package/dist/esm/column-navigation.37cd3245.js +9 -0
- package/dist/esm/column-navigation.37cd3245.js.map +1 -0
- package/dist/esm/column.01d68dd8.js +127 -0
- package/dist/esm/column.01d68dd8.js.map +1 -0
- package/dist/esm/{column.db058031.js → column.a25f8ebd.js} +4 -4
- package/dist/esm/column.a25f8ebd.js.map +1 -0
- package/dist/esm/column.module.1b776e15.js +46 -0
- package/dist/esm/column.module.1b776e15.js.map +1 -0
- package/dist/esm/column.module.a67a6b4c.css +159 -0
- package/dist/esm/column.module.a67a6b4c.css.map +1 -0
- package/dist/esm/composite-scale.577bf64a.js +222 -0
- package/dist/esm/composite-scale.577bf64a.js.map +1 -0
- package/dist/esm/composite.039e4798.js +163 -0
- package/dist/esm/composite.039e4798.js.map +1 -0
- package/dist/esm/{core.4db8e452.js → core.843310d3.js} +11 -12
- package/dist/esm/core.843310d3.js.map +1 -0
- package/dist/esm/core.91ede078.js +206 -0
- package/dist/esm/core.91ede078.js.map +1 -0
- package/dist/esm/correlation-chart.abd8b346.js +9 -0
- package/dist/esm/correlation-chart.abd8b346.js.map +1 -0
- package/dist/esm/data-provider.1506eb64.js.map +1 -1
- package/dist/esm/data-provider.f10c6d0b.js +13 -0
- package/dist/esm/data-provider.f10c6d0b.js.map +1 -0
- package/dist/esm/fetch.99aec438.js +152 -0
- package/dist/esm/fetch.99aec438.js.map +1 -0
- package/dist/esm/hash-string.285b37fb.js +39 -0
- package/dist/esm/hash-string.285b37fb.js.map +1 -0
- package/dist/esm/helpers.2f0a0cb7.js +141 -0
- package/dist/esm/helpers.2f0a0cb7.js.map +1 -0
- package/dist/esm/index.d.ts +797 -130
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +13 -9
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/inset-map.3c18106d.js +66 -0
- package/dist/esm/inset-map.3c18106d.js.map +1 -0
- package/dist/esm/keyboard-navigation.6713401b.js +48 -0
- package/dist/esm/keyboard-navigation.6713401b.js.map +1 -0
- package/dist/esm/keyboard-navigation.a9fc80dd.js +112 -0
- package/dist/esm/keyboard-navigation.a9fc80dd.js.map +1 -0
- package/dist/esm/layers.033d3fb0.js +170 -0
- package/dist/esm/layers.033d3fb0.js.map +1 -0
- package/dist/esm/main.2e0375a5.js +221 -0
- package/dist/esm/main.2e0375a5.js.map +1 -0
- package/dist/esm/main.module.3dd9500b.css +134 -0
- package/dist/esm/main.module.3dd9500b.css.map +1 -0
- package/dist/esm/main.module.c09154b1.js +70 -0
- package/dist/esm/main.module.c09154b1.js.map +1 -0
- package/dist/esm/mapbox.cac42eed.js +167 -0
- package/dist/esm/mapbox.cac42eed.js.map +1 -0
- package/dist/esm/maps.bcdea9c1.js +11 -0
- package/dist/esm/maps.bcdea9c1.js.map +1 -0
- package/dist/esm/{names.f6a4e9a4.js → names.a8f2b452.js} +5 -5
- package/dist/esm/names.a8f2b452.js.map +1 -0
- package/dist/esm/panel.598f76a5.js +420 -0
- package/dist/esm/panel.598f76a5.js.map +1 -0
- package/dist/esm/panel.module.386166cc.js +58 -0
- package/dist/esm/panel.module.386166cc.js.map +1 -0
- package/dist/esm/panel.module.3d2ea3c6.css +111 -0
- package/dist/esm/panel.module.3d2ea3c6.css.map +1 -0
- package/dist/esm/popover.a810b7bc.js +66 -0
- package/dist/esm/popover.a810b7bc.js.map +1 -0
- package/dist/esm/popover.module.c4ba4189.js +22 -0
- package/dist/esm/popover.module.c4ba4189.js.map +1 -0
- package/dist/esm/{selection-popover.module.0a701258.css → popover.module.c4d6bfb0.css} +11 -8
- package/dist/esm/popover.module.c4d6bfb0.css.map +1 -0
- package/dist/esm/prepare-data.d4284b4a.js +125 -0
- package/dist/esm/prepare-data.d4284b4a.js.map +1 -0
- package/dist/esm/prepare-units.6c890a96.js +104 -0
- package/dist/esm/prepare-units.6c890a96.js.map +1 -0
- package/dist/esm/{resolvers.b5c82b78.js → resolvers.36013b49.js} +13 -2
- package/dist/esm/resolvers.36013b49.js.map +1 -0
- package/dist/esm/section.a34d379a.js +215 -0
- package/dist/esm/section.a34d379a.js.map +1 -0
- package/dist/esm/selection.f5b0297e.js +143 -0
- package/dist/esm/selection.f5b0297e.js.map +1 -0
- package/dist/esm/state.178ef364.js +75 -0
- package/dist/esm/state.178ef364.js.map +1 -0
- package/dist/esm/state.2952cbca.js +118 -0
- package/dist/esm/state.2952cbca.js.map +1 -0
- package/dist/esm/store.c4d7a8a4.js +52 -0
- package/dist/esm/store.c4d7a8a4.js.map +1 -0
- package/dist/esm/styles.7bc776d1.js +95 -0
- package/dist/esm/styles.7bc776d1.js.map +1 -0
- package/dist/esm/svg.4b9a96c1.js +89 -0
- package/dist/esm/svg.4b9a96c1.js.map +1 -0
- package/dist/esm/types.0f0b57c9.js +3 -0
- package/dist/esm/types.0f0b57c9.js.map +1 -0
- package/dist/esm/unit-details.071cefed.js +9 -0
- package/dist/esm/unit-details.071cefed.js.map +1 -0
- package/dist/esm/units.5a4fc058.js +98 -0
- package/dist/esm/units.5a4fc058.js.map +1 -0
- package/dist/esm/utils.d7a43a2a.js +55 -0
- package/dist/esm/utils.d7a43a2a.js.map +1 -0
- package/dist/node/index.js.map +1 -1
- package/package.json +24 -7
- package/src/age-axis.module.sass +27 -0
- package/src/age-axis.ts +82 -19
- package/src/age-model-overlay.module.sass +11 -0
- package/src/age-model-overlay.ts +73 -0
- package/src/carbon-isotopes/column.ts +4 -2
- package/src/carbon-isotopes/core.ts +9 -6
- package/src/carbon-isotopes/data-provider.ts +3 -3
- package/src/column.module.sass +58 -49
- package/src/column.ts +149 -135
- package/src/correlation-chart/hash-string.ts +57 -0
- package/src/correlation-chart/index.ts +2 -0
- package/src/correlation-chart/main.module.sass +122 -0
- package/src/correlation-chart/main.ts +305 -0
- package/src/correlation-chart/prepare-data.ts +217 -0
- package/src/correlation-chart/stories/correlation-chart.stories.ts +192 -0
- package/src/correlation-chart/stories/stories.module.sass +18 -0
- package/src/correlation-chart/unconformity-line.module.sass +8 -0
- package/src/correlation-chart/unconformity-line.ts +25 -0
- package/src/data-provider/base.ts +388 -0
- package/src/data-provider/column-nav.ts +53 -0
- package/src/data-provider/fetch.ts +231 -0
- package/src/data-provider/index.ts +4 -0
- package/src/data-provider/store.ts +72 -0
- package/src/index.ts +5 -3
- package/src/maps/_shared/index.ts +2 -0
- package/src/maps/_shared/inset-map.stories.ts +20 -0
- package/src/maps/_shared/inset-map.ts +87 -0
- package/src/maps/_shared/styles.ts +57 -0
- package/src/maps/column-correlation/column-correlation-map.stories.ts +96 -0
- package/src/maps/column-correlation/core.ts +225 -0
- package/src/maps/column-correlation/index.ts +2 -0
- package/src/maps/column-correlation/state.ts +192 -0
- package/src/maps/column-navigation/index.ts +2 -0
- package/src/maps/column-navigation/mapbox/column-navigation-map.stories.ts +102 -0
- package/src/maps/column-navigation/mapbox/index.ts +219 -0
- package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +119 -0
- package/src/maps/column-navigation/mapbox/state.ts +109 -0
- package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +46 -0
- package/src/{map → maps/column-navigation/svg}/index.ts +18 -6
- package/src/{map → maps/column-navigation/svg}/layers.ts +28 -109
- package/src/maps/column-navigation/utils/keyboard-navigation.ts +58 -0
- package/src/maps/index.ts +3 -0
- package/src/prepare-units/composite-scale.ts +353 -0
- package/src/prepare-units/helpers.ts +226 -0
- package/src/prepare-units/index.ts +177 -0
- package/src/prepare-units/utils.ts +98 -0
- package/src/section.ts +264 -84
- package/src/unit-details/index.ts +2 -215
- package/src/unit-details/{index.module.sass → panel.module.sass} +39 -8
- package/src/unit-details/panel.ts +523 -0
- package/src/{selection-popover.module.sass → unit-details/popover.module.sass} +4 -2
- package/src/unit-details/popover.ts +82 -0
- package/src/units/boxes.module.sass +16 -0
- package/src/units/boxes.ts +243 -90
- package/src/units/colors.ts +64 -0
- package/src/units/composite.ts +157 -152
- package/src/units/index.ts +76 -9
- package/src/units/names.ts +8 -4
- package/src/units/resolvers.ts +11 -0
- package/src/units/selection.ts +115 -101
- package/src/units/types.ts +5 -16
- package/dist/esm/age-axis.64c509ee.js +0 -41
- package/dist/esm/age-axis.64c509ee.js.map +0 -1
- package/dist/esm/boxes.13968b76.js +0 -164
- package/dist/esm/boxes.13968b76.js.map +0 -1
- package/dist/esm/boxes.module.28873d08.css +0 -4
- package/dist/esm/boxes.module.28873d08.css.map +0 -1
- package/dist/esm/boxes.module.605bdcd6.js +0 -13
- package/dist/esm/boxes.module.605bdcd6.js.map +0 -1
- package/dist/esm/column.8dd26e1a.js +0 -149
- package/dist/esm/column.8dd26e1a.js.map +0 -1
- package/dist/esm/column.db058031.js.map +0 -1
- package/dist/esm/column.module.039d872c.css +0 -151
- package/dist/esm/column.module.039d872c.css.map +0 -1
- package/dist/esm/column.module.e632868a.js +0 -19
- package/dist/esm/column.module.e632868a.js.map +0 -1
- package/dist/esm/composite.608a4ca2.js +0 -153
- package/dist/esm/composite.608a4ca2.js.map +0 -1
- package/dist/esm/core.4db8e452.js.map +0 -1
- package/dist/esm/helpers.8a03cfc7.js +0 -94
- package/dist/esm/helpers.8a03cfc7.js.map +0 -1
- package/dist/esm/index.module.0844afd8.css +0 -65
- package/dist/esm/index.module.0844afd8.css.map +0 -1
- package/dist/esm/index.module.24fe3a2e.js +0 -37
- package/dist/esm/index.module.24fe3a2e.js.map +0 -1
- package/dist/esm/layers.ad5fd25d.js +0 -231
- package/dist/esm/layers.ad5fd25d.js.map +0 -1
- package/dist/esm/map.7aa26f17.js +0 -82
- package/dist/esm/map.7aa26f17.js.map +0 -1
- package/dist/esm/names.f6a4e9a4.js.map +0 -1
- package/dist/esm/providers.cd1e652f.js +0 -25
- package/dist/esm/providers.cd1e652f.js.map +0 -1
- package/dist/esm/resolvers.b5c82b78.js.map +0 -1
- package/dist/esm/section.cc1b1100.js +0 -118
- package/dist/esm/section.cc1b1100.js.map +0 -1
- package/dist/esm/selection-popover.17d1bd55.js +0 -60
- package/dist/esm/selection-popover.17d1bd55.js.map +0 -1
- package/dist/esm/selection-popover.module.0a701258.css.map +0 -1
- package/dist/esm/selection-popover.module.e22f5183.js +0 -22
- package/dist/esm/selection-popover.module.e22f5183.js.map +0 -1
- package/dist/esm/selection.bbf26d0e.js +0 -117
- package/dist/esm/selection.bbf26d0e.js.map +0 -1
- package/dist/esm/store.25eaa168.js +0 -18
- package/dist/esm/store.25eaa168.js.map +0 -1
- package/dist/esm/types.f016e032.js +0 -18
- package/dist/esm/types.f016e032.js.map +0 -1
- package/dist/esm/unit-details.56ff8b70.js +0 -209
- package/dist/esm/unit-details.56ff8b70.js.map +0 -1
- package/dist/esm/units.361088d4.js +0 -42
- package/dist/esm/units.361088d4.js.map +0 -1
- package/src/helpers.ts +0 -133
- package/src/providers.ts +0 -34
- package/src/selection-popover.ts +0 -71
- package/src/store.ts +0 -12
- package/src/units/units.scss +0 -16
- /package/src/{map → maps/column-navigation/svg}/animated.ts +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.column-ui
|
|
2
|
+
height: 100%
|
|
3
|
+
width: 100%
|
|
4
|
+
overflow: scroll
|
|
5
|
+
|
|
6
|
+
.correlation-container
|
|
7
|
+
padding: 2em calc(350px + 2em) 2em 2em
|
|
8
|
+
width: fit-content
|
|
9
|
+
|
|
10
|
+
.right-column
|
|
11
|
+
width: 350px
|
|
12
|
+
position: fixed
|
|
13
|
+
top: 0
|
|
14
|
+
right: 0
|
|
15
|
+
padding: 1em
|
|
16
|
+
|
|
17
|
+
.column-selector-map, .correlation-map
|
|
18
|
+
height: 350px
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import hyper from "@macrostrat/hyper";
|
|
2
|
+
import styles from "./unconformity-line.module.sass";
|
|
3
|
+
|
|
4
|
+
const h = hyper.styled(styles);
|
|
5
|
+
|
|
6
|
+
export function UnconformityLine({ width }) {
|
|
7
|
+
return h("div.unconformity-line", [h(UnconformityLineSVG, { width })]);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function UnconformityLineSVG({ width }) {
|
|
11
|
+
// Path with a repeating squiggly stroke filling width
|
|
12
|
+
|
|
13
|
+
let d = "M0 5 Q2.5 2 5 5";
|
|
14
|
+
|
|
15
|
+
for (let i = 10; i < width; i += 5) {
|
|
16
|
+
d += ` T${i} 5`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return h("svg", { width, height: 10 }, [
|
|
20
|
+
h("path", {
|
|
21
|
+
d,
|
|
22
|
+
fill: "none",
|
|
23
|
+
}),
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/** Data provider for information that needs to be loaded in bulk for frontend views */
|
|
2
|
+
import baseFetch from "cross-fetch";
|
|
3
|
+
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import h from "@macrostrat/hyper";
|
|
5
|
+
import { create, useStore } from "zustand";
|
|
6
|
+
import {
|
|
7
|
+
ColumnGeoJSONRecord,
|
|
8
|
+
ColumnGeoJSONRecordWithID,
|
|
9
|
+
Environment,
|
|
10
|
+
MacrostratRef,
|
|
11
|
+
} from "@macrostrat/api-types";
|
|
12
|
+
import {
|
|
13
|
+
fetchAllColumns,
|
|
14
|
+
fetchEnvironments,
|
|
15
|
+
fetchIntervals,
|
|
16
|
+
fetchLithologies,
|
|
17
|
+
fetchRefs,
|
|
18
|
+
} from "./fetch";
|
|
19
|
+
import { APIProvider } from "@macrostrat/ui-components";
|
|
20
|
+
import { ColumnProvider } from "@macrostrat/column-components";
|
|
21
|
+
|
|
22
|
+
import { ReactNode } from "react";
|
|
23
|
+
import { useMacrostratColumnData } from "./store";
|
|
24
|
+
|
|
25
|
+
export interface MacrostratDataProviderProps {
|
|
26
|
+
baseURL: string;
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ColumnFootprintsStorage {
|
|
31
|
+
project_id: number;
|
|
32
|
+
// Whether the "in process" flag was used
|
|
33
|
+
inProcess: boolean;
|
|
34
|
+
// The column footprints
|
|
35
|
+
columns: ColumnGeoJSONRecordWithID[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface RefsSlice {
|
|
39
|
+
refs: Map<number, MacrostratRef>;
|
|
40
|
+
inFlightRequests: Set<string>; // Track requests to avoid duplicates
|
|
41
|
+
getRefs(ids: number[]): Promise<MacrostratRef[]>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface MacrostratStore extends RefsSlice {
|
|
45
|
+
baseURL: string;
|
|
46
|
+
fetch: any;
|
|
47
|
+
lithologies: Map<number, any> | null;
|
|
48
|
+
getLithologies(ids: number[] | null): Promise<any>;
|
|
49
|
+
intervals: Map<number, any> | null;
|
|
50
|
+
getIntervals(ids: number[] | null, timescaleID: number | null): Promise<any>;
|
|
51
|
+
environments: Map<number, Environment> | null;
|
|
52
|
+
getEnvironments(ids: number[] | null): Promise<Environment[]>;
|
|
53
|
+
columnFootprints: Map<number, ColumnFootprintsStorage>;
|
|
54
|
+
getColumns(
|
|
55
|
+
projectID: number | null,
|
|
56
|
+
inProcess: boolean
|
|
57
|
+
): Promise<ColumnGeoJSONRecord[]>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createMacrostratStore(
|
|
61
|
+
baseURL: string = "https://macrostrat.org/api/v2"
|
|
62
|
+
) {
|
|
63
|
+
return create<MacrostratStore>((set, get): MacrostratStore => {
|
|
64
|
+
return {
|
|
65
|
+
baseURL,
|
|
66
|
+
inFlightRequests: new Set(),
|
|
67
|
+
async fetch(url: string, options?: RequestInit) {
|
|
68
|
+
const url1 = baseURL + url;
|
|
69
|
+
// Avoid duplicate requests
|
|
70
|
+
const { inFlightRequests } = get();
|
|
71
|
+
if (inFlightRequests.has(url1)) {
|
|
72
|
+
return null; // Return null if already in flight
|
|
73
|
+
}
|
|
74
|
+
inFlightRequests.add(url1);
|
|
75
|
+
//set({ inFlightRequests });
|
|
76
|
+
const res = await baseFetch(url1, options);
|
|
77
|
+
inFlightRequests.delete(url1);
|
|
78
|
+
//set({in})
|
|
79
|
+
return res;
|
|
80
|
+
},
|
|
81
|
+
...createLithologiesSlice(set, get),
|
|
82
|
+
...createIntervalsSlice(set, get),
|
|
83
|
+
...createEnvironmentsSlice(set, get),
|
|
84
|
+
...createColumnsSlice(set, get),
|
|
85
|
+
...createRefsSlice(set, get),
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function createRefsSlice(set, get) {
|
|
91
|
+
return {
|
|
92
|
+
refs: new Map(),
|
|
93
|
+
async getRefs(ids: number[]): Promise<MacrostratRef[]> {
|
|
94
|
+
const { refs, fetch } = get();
|
|
95
|
+
const missing = ids.filter((id) => !refs.has(id));
|
|
96
|
+
if (missing.length == 0) {
|
|
97
|
+
return ids.map((id) => refs.get(id));
|
|
98
|
+
}
|
|
99
|
+
const data = await fetchRefs(missing, fetch);
|
|
100
|
+
if (data == null) return [];
|
|
101
|
+
for (const d of data) {
|
|
102
|
+
refs.set(d.ref_id, d);
|
|
103
|
+
}
|
|
104
|
+
set({ refs });
|
|
105
|
+
return ids.map((id) => refs.get(id));
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function createColumnsSlice(set, get) {
|
|
111
|
+
// Column footprints separated by project
|
|
112
|
+
return {
|
|
113
|
+
columnFootprints: new Map(),
|
|
114
|
+
async getColumns(projectID: number | null, inProcess: boolean) {
|
|
115
|
+
const { columnFootprints, baseURL, fetch } = get();
|
|
116
|
+
const key = projectID ?? -1;
|
|
117
|
+
let _inProcess = inProcess;
|
|
118
|
+
if (projectID == null) {
|
|
119
|
+
// If no project is specified, in process columns cannot be included
|
|
120
|
+
_inProcess = false;
|
|
121
|
+
}
|
|
122
|
+
let footprints = columnFootprints.get(key);
|
|
123
|
+
if (footprints == null || footprints.inProcess != _inProcess) {
|
|
124
|
+
// Fetch the columns
|
|
125
|
+
const statusCode = inProcess ? "in process" : null;
|
|
126
|
+
let columns = await fetchAllColumns({
|
|
127
|
+
projectID,
|
|
128
|
+
statusCode: null,
|
|
129
|
+
fetch,
|
|
130
|
+
});
|
|
131
|
+
if (columns == null) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (_inProcess) {
|
|
135
|
+
const inProcessColumns = await fetchAllColumns({
|
|
136
|
+
projectID,
|
|
137
|
+
statusCode: "in process",
|
|
138
|
+
fetch,
|
|
139
|
+
});
|
|
140
|
+
if (inProcessColumns == null) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Combine active and in-process columns
|
|
144
|
+
columns = columns.concat(inProcessColumns);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
footprints = {
|
|
148
|
+
project_id: projectID,
|
|
149
|
+
inProcess,
|
|
150
|
+
columns,
|
|
151
|
+
};
|
|
152
|
+
// We could break multi-project result sets into separate caches here...
|
|
153
|
+
// Copy the original map
|
|
154
|
+
const columnFootprints2 = new Map(columnFootprints);
|
|
155
|
+
columnFootprints2.set(key, footprints);
|
|
156
|
+
set({ columnFootprints: columnFootprints2 });
|
|
157
|
+
}
|
|
158
|
+
return footprints.columns;
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function createLithologiesSlice(set, get) {
|
|
164
|
+
return {
|
|
165
|
+
lithologies: null,
|
|
166
|
+
async getLithologies(ids: number[] | null) {
|
|
167
|
+
const { lithologies, fetch } = get();
|
|
168
|
+
let lithMap = lithologies;
|
|
169
|
+
if (lithMap == null) {
|
|
170
|
+
const data = await fetchLithologies(fetch);
|
|
171
|
+
if (data == null) return;
|
|
172
|
+
lithMap = new Map(data.map((d) => [d.lith_id, d]));
|
|
173
|
+
set({ lithologies: lithMap });
|
|
174
|
+
}
|
|
175
|
+
// Now get the lithologies
|
|
176
|
+
if (ids == null) return lithMap.values();
|
|
177
|
+
return ids.map((id) => lithMap.get(id));
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function createEnvironmentsSlice(set, get) {
|
|
183
|
+
return {
|
|
184
|
+
environments: null,
|
|
185
|
+
async getEnvironments(ids: number[] | null): Promise<Environment[]> {
|
|
186
|
+
const { environments, fetch } = get();
|
|
187
|
+
let envMap = environments;
|
|
188
|
+
if (envMap == null) {
|
|
189
|
+
const data = await fetchEnvironments(fetch);
|
|
190
|
+
if (data == null) return [];
|
|
191
|
+
envMap = new Map(data.map((d) => [d.environ_id, d]));
|
|
192
|
+
set({ environments: envMap });
|
|
193
|
+
}
|
|
194
|
+
// Now get the environments
|
|
195
|
+
if (ids == null) return envMap.values();
|
|
196
|
+
return ids.map((id) => envMap.get(id));
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function createIntervalsSlice(set, get) {
|
|
202
|
+
return {
|
|
203
|
+
intervals: null,
|
|
204
|
+
async getIntervals(ids: number[] | null, timescaleID: number | null) {
|
|
205
|
+
const { intervals, fetch } = get();
|
|
206
|
+
let _intervals = intervals;
|
|
207
|
+
if (intervals == null || !includesTimescale(intervals, timescaleID)) {
|
|
208
|
+
// Fetch the intervals
|
|
209
|
+
const data = await fetchIntervals(timescaleID, fetch);
|
|
210
|
+
if (data == null) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
const intervalMap = intervals ?? new Map();
|
|
214
|
+
for (const d of data) {
|
|
215
|
+
intervalMap.set(d.int_id, d);
|
|
216
|
+
}
|
|
217
|
+
_intervals = intervalMap;
|
|
218
|
+
set({ intervals: _intervals });
|
|
219
|
+
}
|
|
220
|
+
if (ids == null && timescaleID == null)
|
|
221
|
+
return Array.from(_intervals.values());
|
|
222
|
+
if (timescaleID != null) {
|
|
223
|
+
return Array.from(_intervals.values() as any[]).filter(
|
|
224
|
+
(d) => d.timescale_id == timescaleID
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
return ids.map((id) => intervals.get(id));
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function includesTimescale(intervals: Map<number, any>, timescaleID: number) {
|
|
233
|
+
if (intervals == null) return false;
|
|
234
|
+
if (timescaleID == null) return true;
|
|
235
|
+
return Array.from(intervals.values()).some(
|
|
236
|
+
(d) => d.timescale_id == timescaleID
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
type MacrostratSelector = (store: MacrostratStore) => any;
|
|
241
|
+
|
|
242
|
+
export function useMacrostratStore(selector: MacrostratSelector | "api") {
|
|
243
|
+
const ctx = useContext(MacrostratDataProviderContext);
|
|
244
|
+
if (ctx == null) {
|
|
245
|
+
throw new Error("Missing MacrostratDataProvider");
|
|
246
|
+
}
|
|
247
|
+
if (selector === "api") {
|
|
248
|
+
return ctx;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return useStore(ctx, selector);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const dataTypeMapping = {
|
|
255
|
+
lithologies: (store) => store.getLithologies,
|
|
256
|
+
intervals: (store) => store.getIntervals,
|
|
257
|
+
columns: (store) => store.getColumns,
|
|
258
|
+
environments: (store) => store.getEnvironments,
|
|
259
|
+
refs: (store) => store.getRefs,
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export function useMacrostratDefs(dataType: string): Map<number, any> | null {
|
|
263
|
+
if (dataType == "columns") {
|
|
264
|
+
throw new Error("Columns are not provided as a map");
|
|
265
|
+
}
|
|
266
|
+
const operator = useMacrostratStore(dataTypeMapping[dataType]);
|
|
267
|
+
useEffect(() => {
|
|
268
|
+
operator();
|
|
269
|
+
}, []);
|
|
270
|
+
return useMacrostratStore((state) => state[dataType]);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function useMacrostratColumns(
|
|
274
|
+
projectID: number | null,
|
|
275
|
+
inProcess: boolean
|
|
276
|
+
) {
|
|
277
|
+
const getColumns = useMacrostratStore((s) => s.getColumns);
|
|
278
|
+
const columnsMap = useMacrostratStore((s) => s.columnFootprints);
|
|
279
|
+
const key = projectID ?? -1;
|
|
280
|
+
const colData = columnsMap?.get(key);
|
|
281
|
+
useEffect(() => {
|
|
282
|
+
// Refetch if the columns are not available, or if we have requested inProcess columns where we didn't before
|
|
283
|
+
if (colData == null || (inProcess && !colData.inProcess)) {
|
|
284
|
+
getColumns(projectID, inProcess);
|
|
285
|
+
}
|
|
286
|
+
// If we've already fetched the columns there's nothing to do...
|
|
287
|
+
}, [colData, inProcess, getColumns]);
|
|
288
|
+
|
|
289
|
+
return useMemo(() => {
|
|
290
|
+
if (colData == null) return null;
|
|
291
|
+
let columns = colData.columns;
|
|
292
|
+
if (!inProcess && colData.inProcess) {
|
|
293
|
+
// Our available set of columns includes 'in process' columns, but we don't want them
|
|
294
|
+
columns.features = columns.features?.filter(
|
|
295
|
+
(d) => d.properties.status != "in process"
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
return columns;
|
|
299
|
+
}, [colData, inProcess]);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function useMacrostratData(dataType: string, ...args: any[]) {
|
|
303
|
+
const selector = dataTypeMapping[dataType];
|
|
304
|
+
const operator = useMacrostratStore(selector);
|
|
305
|
+
|
|
306
|
+
const [value, setValue] = useState(null);
|
|
307
|
+
|
|
308
|
+
useEffect(() => {
|
|
309
|
+
operator(...args).then(setValue);
|
|
310
|
+
}, [operator, ...args]);
|
|
311
|
+
|
|
312
|
+
return value;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** By default, we provide a store linked to the production API */
|
|
316
|
+
const MacrostratDataProviderContext = createContext(createMacrostratStore());
|
|
317
|
+
|
|
318
|
+
export function MacrostratDataProvider(props: MacrostratDataProviderProps) {
|
|
319
|
+
const { baseURL = "https://macrostrat.org/api/v2", children } = props;
|
|
320
|
+
|
|
321
|
+
const [store] = useState(() => createMacrostratStore(baseURL));
|
|
322
|
+
|
|
323
|
+
return h(
|
|
324
|
+
MacrostratAPIProvider,
|
|
325
|
+
{ baseURL },
|
|
326
|
+
h(MacrostratDataProviderContext.Provider, { value: store }, children)
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Legacy API provider so useAPIResult can work */
|
|
331
|
+
|
|
332
|
+
type APIProviderProps = {
|
|
333
|
+
children: ReactNode;
|
|
334
|
+
useDev?: boolean;
|
|
335
|
+
baseURL?: string;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
export function MacrostratAPIProvider({
|
|
339
|
+
children,
|
|
340
|
+
useDev = false,
|
|
341
|
+
baseURL,
|
|
342
|
+
}: APIProviderProps) {
|
|
343
|
+
baseURL ??= useDev
|
|
344
|
+
? "https://dev2.macrostrat.org/api/v2"
|
|
345
|
+
: "https://macrostrat.org/api/v2";
|
|
346
|
+
|
|
347
|
+
return h(
|
|
348
|
+
APIProvider,
|
|
349
|
+
{
|
|
350
|
+
baseURL,
|
|
351
|
+
unwrapResponse: (res) => res.success.data,
|
|
352
|
+
},
|
|
353
|
+
children
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export function MacrostratColumnProvider(props) {
|
|
358
|
+
/** A column provider specialized the Macrostrat API. Maps more
|
|
359
|
+
* generic concepts to Macrostrat-specific ones.
|
|
360
|
+
*/
|
|
361
|
+
|
|
362
|
+
const { axisType } = useMacrostratColumnData();
|
|
363
|
+
const { units, domain, pixelScale, children } = props;
|
|
364
|
+
return h(
|
|
365
|
+
ColumnProvider,
|
|
366
|
+
{ axisType, divisions: units, range: domain, pixelsPerMeter: pixelScale },
|
|
367
|
+
children
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** This is now a legacy provider */
|
|
372
|
+
export function LithologiesProvider({ children }) {
|
|
373
|
+
useEffect(() => {
|
|
374
|
+
console.warn(
|
|
375
|
+
"LithologiesProvider is deprecated. Replace with MacrostratDataProvider"
|
|
376
|
+
);
|
|
377
|
+
}, []);
|
|
378
|
+
return children;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export function useLithologies() {
|
|
382
|
+
const getLithologies = useMacrostratStore((s) => s.getLithologies);
|
|
383
|
+
const lithologies = useMacrostratStore((s) => s.lithologies);
|
|
384
|
+
useEffect(() => {
|
|
385
|
+
if (lithologies == null) getLithologies();
|
|
386
|
+
}, [lithologies, getLithologies]);
|
|
387
|
+
return lithologies;
|
|
388
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import h from "@macrostrat/hyper";
|
|
2
|
+
import { getQueryString, setQueryString } from "@macrostrat/ui-components";
|
|
3
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export interface ColumnArgs {
|
|
6
|
+
col_id?: number;
|
|
7
|
+
unit_id?: number;
|
|
8
|
+
project_id?: number;
|
|
9
|
+
status_code?: "in process";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type ColumnManagerData = [ColumnArgs, (c: ColumnArgs) => void];
|
|
13
|
+
|
|
14
|
+
const ColumnNavCtx = createContext<ColumnManagerData | null>(null);
|
|
15
|
+
|
|
16
|
+
export function useColumnNav(
|
|
17
|
+
defaultArgs: ColumnArgs = { col_id: 495, unit_id: null }
|
|
18
|
+
): ColumnManagerData {
|
|
19
|
+
const ctx = useContext(ColumnNavCtx);
|
|
20
|
+
if (ctx != null) return ctx;
|
|
21
|
+
|
|
22
|
+
const [columnArgs, setColumnArgs] = useState<ColumnArgs>(
|
|
23
|
+
extractColumnArgs(getQueryString(window.location.search)) ?? defaultArgs
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
useEffect(() => setQueryString(columnArgs), [columnArgs]);
|
|
27
|
+
|
|
28
|
+
const { col_id, project_id, status_code } = columnArgs;
|
|
29
|
+
|
|
30
|
+
const setCurrentColumn = (obj) => {
|
|
31
|
+
let args = obj;
|
|
32
|
+
if ("properties" in obj) {
|
|
33
|
+
args = { col_id: obj.properties.col_id, project_id, status_code };
|
|
34
|
+
}
|
|
35
|
+
// Set query string
|
|
36
|
+
setQueryString(args);
|
|
37
|
+
setColumnArgs(args);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return [columnArgs, setCurrentColumn];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function extractColumnArgs(search: any): ColumnArgs | null {
|
|
44
|
+
const { col_id, unit_id, project_id, status_code } = search ?? {};
|
|
45
|
+
if (col_id == null) return null;
|
|
46
|
+
return { col_id, unit_id, project_id, status_code };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function ColumnNavProvider({ children, ...defaultArgs }) {
|
|
50
|
+
/** Column navigation provider that manages the query string for selected columns */
|
|
51
|
+
const value = useColumnNav(defaultArgs as any);
|
|
52
|
+
return h(ColumnNavCtx.Provider, { value }, children);
|
|
53
|
+
}
|