Skip to content

Commit 820c4c5

Browse files
authored
Merge pull request #195 from UW-Macrostrat/eodp-correlation
eODP correlation diagram fixes
2 parents 72b3719 + 84d8b0e commit 820c4c5

File tree

14 files changed

+453
-85
lines changed

14 files changed

+453
-85
lines changed

packages/api-types/src/columns.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Polygon, MultiPolygon } from "geojson";
1+
import { Polygon, MultiPolygon, Point } from "geojson";
22

33
export type ColumnSpec = {
44
col_id: number | string;
@@ -18,7 +18,7 @@ export type ColumnProperties = {
1818

1919
export interface ColumnGeoJSONRecord {
2020
type: "Feature";
21-
geometry: Polygon | MultiPolygon;
21+
geometry: Polygon | MultiPolygon | Point;
2222
properties: ColumnProperties;
2323
}
2424

packages/column-views/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format
44
is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this
55
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.4.1] - 2025-12-18
8+
9+
- Improve unit selection
10+
- Improve unit popover
11+
- Better unit navigation for correlation diagram
12+
- Show column name in unit popover
13+
714
## [2.4.0] - 2025-12-15
815

916
- Remove `UnitSelectionProvider` in favor of `jotai` state management

packages/column-views/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@macrostrat/column-views",
3-
"version": "2.4.0",
3+
"version": "2.4.1",
44
"description": "Data views for Macrostrat stratigraphic columns",
55
"type": "module",
66
"source": "src/index.ts",
@@ -42,6 +42,7 @@
4242
"@macrostrat/svg-map-components": "workspace:^",
4343
"@macrostrat/timescale": "workspace:^",
4444
"@macrostrat/ui-components": "workspace:^",
45+
"@turf/boolean-point-in-polygon": "^7.3.1",
4546
"@turf/buffer": "^7.2.0",
4647
"@turf/centroid": "^7.2.0",
4748
"@turf/distance": "^7.2.0",

packages/column-views/src/correlation-chart/main.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import {
55
useUnitSelectionDispatch,
66
useColumnRef,
77
} from "../data-provider";
8-
import { UnitSelectionPopover } from "../unit-details";
8+
import { UnitDetailsFeature, UnitSelectionPopover } from "../unit-details";
99
import hyper from "@macrostrat/hyper";
1010
import styles from "./main.module.sass";
11-
import { useMemo, useRef } from "react";
11+
import { useMemo } from "react";
1212
import { useInDarkMode } from "@macrostrat/ui-components";
1313
import { CompositeTimescaleCore } from "../section";
1414
import classNames from "classnames";
@@ -55,6 +55,13 @@ function MainChartArea({ children }) {
5555
return h("div.main-chart", { ref: columnRef }, children);
5656
}
5757

58+
const unitPopoverFeatures = new Set([
59+
UnitDetailsFeature.AdjacentUnits,
60+
UnitDetailsFeature.OutcropType,
61+
UnitDetailsFeature.DepthRange,
62+
UnitDetailsFeature.ColumnName,
63+
]);
64+
5865
export function CorrelationChart({
5966
data,
6067
columnSpacing = 0,
@@ -137,9 +144,11 @@ export function CorrelationChart({
137144
});
138145
}),
139146
),
140-
h.if(showUnitPopover)(UnitSelectionPopover),
147+
h.if(showUnitPopover)(UnitSelectionPopover, {
148+
features: unitPopoverFeatures,
149+
}),
141150
// Navigation only works within a column for now...
142-
h(UnitKeyboardNavigation, { units }),
151+
h(UnitKeyboardNavigation, { columnData: data }),
143152
]),
144153
]),
145154
),

packages/column-views/src/correlation-chart/stories/correlation-chart.stories.ts

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import {
66
ColumnCorrelationMap,
77
ColumnCorrelationProvider,
88
fetchUnits,
9+
MacrostratDataProvider,
910
MergeSectionsMode,
1011
useCorrelationMapStore,
12+
useMacrostratBaseURL,
13+
useMacrostratFetch,
1114
} from "../..";
1215
import { hyperStyled } from "@macrostrat/hyper";
1316

@@ -35,38 +38,45 @@ function CorrelationStoryUI({
3538
...rest
3639
}: any) {
3740
return h(
38-
ColumnCorrelationProvider,
39-
{
40-
focusedLine,
41-
columns: null,
42-
onSelectColumns(cols, line) {
43-
setFocusedLine(line);
41+
MacrostratDataProvider,
42+
{ baseURL: "https://dev.macrostrat.org/api/v2" },
43+
h(
44+
ColumnCorrelationProvider,
45+
{
46+
focusedLine,
47+
columns: null,
48+
projectID,
49+
onSelectColumns(cols, line) {
50+
setFocusedLine(line);
51+
},
4452
},
45-
},
46-
h("div.correlation-ui", [
47-
h("div.correlation-container", h(CorrelationDiagramWrapper, rest)),
48-
h("div.right-column", [
49-
h(ColumnCorrelationMap, {
50-
accessToken: mapboxToken,
51-
className: "correlation-map",
52-
//showLogo: false,
53-
}),
53+
h("div.correlation-ui", [
54+
h("div.correlation-container", h(CorrelationDiagramWrapper, rest)),
55+
h("div.right-column", [
56+
h(ColumnCorrelationMap, {
57+
accessToken: mapboxToken,
58+
className: "correlation-map",
59+
//showLogo: false,
60+
}),
61+
]),
5462
]),
55-
]),
63+
),
5664
);
5765
}
5866

5967
function CorrelationDiagramWrapper(props: Omit<CorrelationChartProps, "data">) {
6068
/** This state management is a bit too complicated, but it does kinda sorta work */
6169

70+
const fetch = useMacrostratFetch();
71+
6272
// Sync focused columns with map
6373
const focusedColumns = useCorrelationMapStore(
6474
(state) => state.focusedColumns,
6575
);
6676

6777
const columnUnits = useAsyncMemo(async () => {
6878
const col_ids = focusedColumns.map((col) => col.properties.col_id);
69-
return await fetchUnits(col_ids);
79+
return await fetchUnits(col_ids, fetch);
7080
}, [focusedColumns]);
7181

7282
return h("div.correlation-diagram", [
@@ -161,6 +171,11 @@ export default {
161171
type: "number",
162172
},
163173
},
174+
projectID: {
175+
control: {
176+
type: "number",
177+
},
178+
},
164179
},
165180
} as Meta<typeof CorrelationStoryUI>;
166181

@@ -221,3 +236,9 @@ WithPowerScaleMerged.args = {
221236
scale: scalePow().exponent(0.3).domain([0, 2500]).range([0, 1000]),
222237
mergeSections: MergeSectionsMode.ALL,
223238
};
239+
240+
export const eODPCorrelationChart = Template.bind({});
241+
eODPCorrelationChart.args = {
242+
focusedLine: "-125,38 -120,32",
243+
projectID: 3,
244+
};

packages/column-views/src/data-provider/base.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ export function useMacrostratBaseURL(
288288
return ctx.getState().baseURL;
289289
}
290290

291+
export function useMacrostratFetch() {
292+
const ctx = useContext(MacrostratDataProviderContext);
293+
if (ctx == null) {
294+
throw new Error("Missing MacrostratDataProvider");
295+
}
296+
return ctx.getState().fetch;
297+
}
298+
291299
type DataTypeKey =
292300
| "lithologies"
293301
| "intervals"
@@ -345,6 +353,20 @@ export function useMacrostratColumns(
345353
}, [colData, inProcess]);
346354
}
347355

356+
export function useMacrostratColumnInfo(
357+
columnID: number,
358+
): ColumnGeoJSONRecord["properties"] | null {
359+
/** Get basic info for a column, without automatically fetching it (assumes the overall set of relevant columns has already been fetched) */
360+
const columnsMap = useMacrostratStore((s) => s.columnFootprints);
361+
return useMemo(() => {
362+
for (const colData of columnsMap.values()) {
363+
const col = colData.columns.find((d) => d.properties.col_id === columnID);
364+
if (col != null) return col.properties;
365+
}
366+
return null;
367+
}, [columnsMap, columnID]);
368+
}
369+
348370
export function useMacrostratData(dataType: DataTypeKey, ...args: any[]) {
349371
const selector = dataTypeMapping[dataType];
350372
const operator = useMacrostratStore(selector);

packages/column-views/src/data-provider/fetch.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
ColumnGeoJSONRecordWithID,
44
MacrostratRef,
55
StratName,
6-
StratUnit,
76
UnitLong,
87
} from "@macrostrat/api-types";
98
import {
@@ -14,16 +13,15 @@ import {
1413
import crossFetch from "cross-fetch";
1514
import { feature } from "topojson-client";
1615
import { geoArea } from "d3-geo";
17-
import _ from "underscore";
1816

19-
function defaultFetch(
20-
url: string,
21-
options: RequestInit | undefined = undefined,
22-
) {
23-
const baseURL = "https://macrostrat.org/api/v2";
24-
return crossFetch(baseURL + url, options);
17+
function createScopedFetch(baseURL: string) {
18+
return function (url: string, options: RequestInit | undefined = undefined) {
19+
return crossFetch(baseURL + url, options);
20+
};
2521
}
2622

23+
const defaultFetch = createScopedFetch("https://macrostrat.org/api/v2");
24+
2725
export type ColumnStatusCode = "in process" | "active" | "obsolete";
2826

2927
export interface ColumnFetchOptions {
@@ -232,8 +230,35 @@ export async function fetchUnits(
232230
columns: number[],
233231
fetch = defaultFetch,
234232
): Promise<ColumnData[]> {
235-
const promises = columns.map((col_id) => fetchColumnUnits(col_id, fetch));
236-
return await Promise.all(promises);
233+
const params = new URLSearchParams();
234+
params.append("response", "long");
235+
236+
if (columns.length == 0) {
237+
return [];
238+
}
239+
240+
const col_string = columns.map((column) => column.toString()).join(",");
241+
params.append("col_id", col_string);
242+
243+
const res = await fetch("/units" + "?" + params.toString());
244+
const data = await res.json();
245+
if (!data.success) {
246+
throw new Error("Failed to fetch column units");
247+
}
248+
const units = data.success.data;
249+
const unitsMap = new Map<number, UnitLong[]>();
250+
for (const unit of units) {
251+
const colID = unit.col_id;
252+
if (!unitsMap.has(colID)) {
253+
unitsMap.set(colID, []);
254+
}
255+
unitsMap.get(colID).push(unit);
256+
}
257+
const result: ColumnData[] = [];
258+
for (const colID of columns) {
259+
result.push({ columnID: colID, units: unitsMap.get(colID) || [] });
260+
}
261+
return result;
237262
}
238263

239264
export async function fetchColumnUnits(

0 commit comments

Comments
 (0)