@macrostrat/column-views 3.0.3 → 3.2.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 +14 -0
- package/dist/age-axis.js +2 -2
- package/dist/age-axis.js.map +1 -1
- package/dist/age-axis.module.sass.cjs +6 -1
- package/dist/age-axis.module.sass.cjs.map +1 -1
- package/dist/age-axis.module.sass.js +4 -1
- package/dist/age-axis.module.sass.js.map +1 -1
- package/dist/age-model-overlay.js +2 -2
- package/dist/age-model-overlay.js.map +1 -1
- package/dist/age-model-overlay.module.sass.cjs +6 -1
- package/dist/age-model-overlay.module.sass.cjs.map +1 -1
- package/dist/age-model-overlay.module.sass.js +4 -1
- package/dist/age-model-overlay.module.sass.js.map +1 -1
- package/dist/column.js +2 -2
- package/dist/column.js.map +1 -1
- package/dist/column.module.sass.cjs +6 -1
- package/dist/column.module.sass.cjs.map +1 -1
- package/dist/column.module.sass.js +4 -1
- package/dist/column.module.sass.js.map +1 -1
- package/dist/correlation-chart/main.js +2 -2
- package/dist/correlation-chart/main.js.map +1 -1
- package/dist/correlation-chart/main.module.sass.cjs +6 -1
- package/dist/correlation-chart/main.module.sass.cjs.map +1 -1
- package/dist/correlation-chart/main.module.sass.js +4 -1
- package/dist/correlation-chart/main.module.sass.js.map +1 -1
- package/dist/data-provider/column-nav.js +1 -1
- package/dist/data-provider/index.d.ts +0 -2
- package/dist/data-provider/store.cjs +49 -6
- package/dist/data-provider/store.cjs.map +1 -1
- package/dist/data-provider/store.js +47 -4
- package/dist/data-provider/store.js.map +1 -1
- package/dist/data-provider/unit-selection.cjs +9 -9
- package/dist/data-provider/unit-selection.cjs.map +1 -1
- package/dist/data-provider/unit-selection.d.ts +1 -1
- package/dist/data-provider/unit-selection.js +2 -2
- package/dist/data-provider/unit-selection.js.map +1 -1
- package/dist/facets/carbon-isotopes/isotopes-column.js +2 -2
- package/dist/facets/carbon-isotopes/isotopes-column.js.map +1 -1
- package/dist/facets/carbon-isotopes/isotopes-column.module.sass.cjs +6 -1
- package/dist/facets/carbon-isotopes/isotopes-column.module.sass.cjs.map +1 -1
- package/dist/facets/carbon-isotopes/isotopes-column.module.sass.js +4 -1
- package/dist/facets/carbon-isotopes/isotopes-column.module.sass.js.map +1 -1
- package/dist/facets/detrital-zircon/index.js +2 -2
- package/dist/facets/detrital-zircon/index.js.map +1 -1
- package/dist/facets/detrital-zircon/index.module.sass.cjs +6 -1
- package/dist/facets/detrital-zircon/index.module.sass.cjs.map +1 -1
- package/dist/facets/detrital-zircon/index.module.sass.js +4 -1
- package/dist/facets/detrital-zircon/index.module.sass.js.map +1 -1
- package/dist/facets/fossils/index.js +2 -2
- package/dist/facets/fossils/index.js.map +1 -1
- package/dist/facets/fossils/taxon-ranges.js +2 -2
- package/dist/facets/fossils/taxon-ranges.js.map +1 -1
- package/dist/facets/fossils/taxon-ranges.module.sass.cjs +6 -1
- package/dist/facets/fossils/taxon-ranges.module.sass.cjs.map +1 -1
- package/dist/facets/fossils/taxon-ranges.module.sass.js +4 -1
- package/dist/facets/fossils/taxon-ranges.module.sass.js.map +1 -1
- package/dist/facets/measurements/base.js +2 -2
- package/dist/facets/measurements/base.js.map +1 -1
- package/dist/facets/measurements/base.module.sass.cjs +6 -1
- package/dist/facets/measurements/base.module.sass.cjs.map +1 -1
- package/dist/facets/measurements/base.module.sass.js +4 -1
- package/dist/facets/measurements/base.module.sass.js.map +1 -1
- package/dist/index.cjs +15 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -24
- package/dist/index.js.map +1 -1
- package/dist/maps/_shared/styles.cjs +6 -1
- package/dist/maps/_shared/styles.cjs.map +1 -1
- package/dist/maps/_shared/styles.js +6 -1
- package/dist/maps/_shared/styles.js.map +1 -1
- package/dist/maps/column-correlation/state.cjs +2 -2
- package/dist/maps/column-correlation/state.cjs.map +1 -1
- package/dist/maps/column-correlation/state.d.ts +1 -0
- package/dist/maps/column-correlation/state.js +1 -1
- package/dist/maps/column-correlation/state.js.map +1 -1
- package/dist/maps/column-navigation/mapbox/keyboard-navigation.d.ts +1 -1
- package/dist/maps/column-navigation/mapbox/state.cjs +3 -3
- package/dist/maps/column-navigation/mapbox/state.cjs.map +1 -1
- package/dist/maps/column-navigation/mapbox/state.js +1 -1
- package/dist/maps/column-navigation/mapbox/state.js.map +1 -1
- package/dist/maps/column-navigation/svg/data-fetcher.cjs +25 -0
- package/dist/maps/column-navigation/svg/data-fetcher.cjs.map +1 -0
- package/dist/maps/column-navigation/svg/data-fetcher.d.ts +6 -0
- package/dist/maps/column-navigation/svg/data-fetcher.js +25 -0
- package/dist/maps/column-navigation/svg/data-fetcher.js.map +1 -0
- package/dist/maps/column-navigation/svg/layers.cjs +2 -3
- package/dist/maps/column-navigation/svg/layers.cjs.map +1 -1
- package/dist/maps/column-navigation/svg/layers.js +1 -2
- package/dist/maps/column-navigation/svg/layers.js.map +1 -1
- package/dist/maps/index.d.ts +1 -0
- package/dist/maps/units-overlay/index.cjs +254 -0
- package/dist/maps/units-overlay/index.cjs.map +1 -0
- package/dist/maps/units-overlay/index.d.ts +14 -0
- package/dist/maps/units-overlay/index.js +252 -0
- package/dist/maps/units-overlay/index.js.map +1 -0
- package/dist/section.cjs +3 -3
- package/dist/section.cjs.map +1 -1
- package/dist/section.js +4 -4
- package/dist/section.js.map +1 -1
- package/dist/unit-details/panel.cjs +76 -57
- package/dist/unit-details/panel.cjs.map +1 -1
- package/dist/unit-details/panel.js +74 -55
- package/dist/unit-details/panel.js.map +1 -1
- package/dist/unit-details/panel.module.sass.cjs +6 -1
- package/dist/unit-details/panel.module.sass.cjs.map +1 -1
- package/dist/unit-details/panel.module.sass.js +4 -1
- package/dist/unit-details/panel.module.sass.js.map +1 -1
- package/dist/unit-details/popover.js +2 -2
- package/dist/unit-details/popover.js.map +1 -1
- package/dist/unit-details/popover.module.sass.cjs +6 -1
- package/dist/unit-details/popover.module.sass.cjs.map +1 -1
- package/dist/unit-details/popover.module.sass.js +4 -1
- package/dist/unit-details/popover.module.sass.js.map +1 -1
- package/dist/units/boxes.cjs +1 -0
- package/dist/units/boxes.cjs.map +1 -1
- package/dist/units/boxes.js +3 -2
- package/dist/units/boxes.js.map +1 -1
- package/dist/units/boxes.module.sass.cjs +6 -1
- package/dist/units/boxes.module.sass.cjs.map +1 -1
- package/dist/units/boxes.module.sass.js +4 -1
- package/dist/units/boxes.module.sass.js.map +1 -1
- package/dist/units/colors.cjs +79 -18
- package/dist/units/colors.cjs.map +1 -1
- package/dist/units/colors.d.ts +17 -4
- package/dist/units/colors.js +79 -18
- package/dist/units/colors.js.map +1 -1
- package/dist/units/composite.js +2 -2
- package/dist/units/composite.js.map +1 -1
- package/dist/units/composite.module.sass.cjs +6 -1
- package/dist/units/composite.module.sass.cjs.map +1 -1
- package/dist/units/composite.module.sass.js +4 -1
- package/dist/units/composite.module.sass.js.map +1 -1
- package/dist/units/index.cjs +6 -4
- package/dist/units/index.cjs.map +1 -1
- package/dist/units/index.js +4 -1
- package/dist/units/index.js.map +1 -1
- package/dist/units/resolvers.cjs +11 -0
- package/dist/units/resolvers.cjs.map +1 -1
- package/dist/units/resolvers.d.ts +5 -0
- package/dist/units/resolvers.js +11 -0
- package/dist/units/resolvers.js.map +1 -1
- package/package.json +11 -9
- package/src/correlation-chart/stories/correlation-chart.stories.ts +29 -22
- package/src/data-provider/index.ts +0 -2
- package/src/data-provider/store.ts +52 -10
- package/src/data-provider/unit-selection.ts +4 -4
- package/src/maps/_shared/styles.ts +10 -3
- package/src/maps/column-correlation/state.ts +2 -1
- package/src/maps/column-navigation/mapbox/state.ts +1 -1
- package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +1 -1
- package/src/maps/column-navigation/svg/data-fetcher.ts +34 -0
- package/src/maps/column-navigation/svg/layers.ts +1 -1
- package/src/maps/index.ts +1 -0
- package/src/maps/unit-map.stories.ts +64 -0
- package/src/maps/units-overlay/index.ts +336 -0
- package/src/section.ts +1 -1
- package/src/unit-details/panel.ts +97 -60
- package/src/units/boxes.ts +2 -1
- package/src/units/colors.ts +137 -25
- package/src/units/index.ts +1 -1
- package/src/units/resolvers.ts +16 -0
- package/dist/data-provider/base.cjs +0 -352
- package/dist/data-provider/base.cjs.map +0 -1
- package/dist/data-provider/base.d.ts +0 -65
- package/dist/data-provider/base.js +0 -349
- package/dist/data-provider/base.js.map +0 -1
- package/dist/data-provider/core.cjs +0 -58
- package/dist/data-provider/core.cjs.map +0 -1
- package/dist/data-provider/core.d.ts +0 -31
- package/dist/data-provider/core.js +0 -56
- package/dist/data-provider/core.js.map +0 -1
- package/dist/data-provider/fetch.cjs +0 -212
- package/dist/data-provider/fetch.cjs.map +0 -1
- package/dist/data-provider/fetch.d.ts +0 -27
- package/dist/data-provider/fetch.js +0 -210
- package/dist/data-provider/fetch.js.map +0 -1
- package/dist/data-provider/store.d.ts +0 -34
- package/dist/unit-details/panel.d.ts +0 -87
- package/src/data-provider/base.ts +0 -475
- package/src/data-provider/core.ts +0 -89
- package/src/data-provider/fetch.ts +0 -278
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useLithologies,
|
|
3
|
+
useMacrostratColumns,
|
|
4
|
+
} from "@macrostrat/data-provider";
|
|
5
|
+
import { useAPIResult } from "@macrostrat/ui-components";
|
|
6
|
+
import { useMapStyleOperator } from "@macrostrat/mapbox-react";
|
|
7
|
+
import { FeatureCollection } from "geojson";
|
|
8
|
+
import { useMemo } from "react";
|
|
9
|
+
import { mergeStyles, setGeoJSON } from "@macrostrat/mapbox-utils";
|
|
10
|
+
import { UnitLithology, UnitLong } from "@macrostrat/api-types";
|
|
11
|
+
import { flattenLithologies, getMixedColorForData } from "../../units";
|
|
12
|
+
import { getBestFGDCPatternForLithologyList } from "../../units/resolvers";
|
|
13
|
+
import {
|
|
14
|
+
setupStyleImageManager,
|
|
15
|
+
loadStyleImage,
|
|
16
|
+
StyleFragment,
|
|
17
|
+
} from "@macrostrat/map-styles";
|
|
18
|
+
import { asChromaColor, getCSSVariable } from "@macrostrat/color-utils";
|
|
19
|
+
import { buildGeoJSONSource } from "@macrostrat/mapbox-utils";
|
|
20
|
+
import pMap from "p-map";
|
|
21
|
+
|
|
22
|
+
export interface UnitsOverlayProps {
|
|
23
|
+
time: number;
|
|
24
|
+
ageSpan?: number;
|
|
25
|
+
project?: number | number[];
|
|
26
|
+
patterns?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function MacrostratUnitsOverlay(props: UnitsOverlayProps) {
|
|
30
|
+
const { time, ageSpan = 0.05, patterns = false } = props;
|
|
31
|
+
const lithMap = useLithologies();
|
|
32
|
+
|
|
33
|
+
useMapStyleOperator(
|
|
34
|
+
(map) => {
|
|
35
|
+
if (!patterns) return;
|
|
36
|
+
setupStyleImageManager(map, { verbose: false });
|
|
37
|
+
},
|
|
38
|
+
[patterns],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const params = useMemo(() => {
|
|
42
|
+
let project: number[] | undefined;
|
|
43
|
+
if (Number.isFinite(props.project)) {
|
|
44
|
+
project = [props.project as number];
|
|
45
|
+
} else if (!Array.isArray(props.project)) {
|
|
46
|
+
project = undefined;
|
|
47
|
+
}
|
|
48
|
+
// Project can only be a single project for now
|
|
49
|
+
const projectCompat =
|
|
50
|
+
project != null && project.length > 0 ? project[0] : undefined;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
age_bottom: time + ageSpan / 2,
|
|
54
|
+
age_top: time - ageSpan / 2,
|
|
55
|
+
response: "long",
|
|
56
|
+
project: projectCompat,
|
|
57
|
+
};
|
|
58
|
+
}, [time, ageSpan, props.project]);
|
|
59
|
+
|
|
60
|
+
const units: UnitLong[] = useAPIResult("/units", params);
|
|
61
|
+
const columns = useMacrostratColumns(params.project, false);
|
|
62
|
+
|
|
63
|
+
// Set up basic columns layer
|
|
64
|
+
useMapStyleOperator(
|
|
65
|
+
(map) => {
|
|
66
|
+
if (columns == null) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const data: FeatureCollection = {
|
|
70
|
+
type: "FeatureCollection",
|
|
71
|
+
features: columns,
|
|
72
|
+
};
|
|
73
|
+
setGeoJSON(map, "columns", data);
|
|
74
|
+
},
|
|
75
|
+
[columns],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
useMapStyleOperator(
|
|
79
|
+
(map) => {
|
|
80
|
+
if (units == null || columns == null || lithMap == null) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const getColorForLithology = (data: UnitLithology): string | null => {
|
|
85
|
+
return lithMap?.get(data.lith_id)?.color ?? null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const unitsMap = postProcessUnits(units, getColorForLithology);
|
|
89
|
+
handleUnitsLayerUpdate(map, unitsMap, columns);
|
|
90
|
+
if (patterns) {
|
|
91
|
+
handlePatternOverlayUpdate(
|
|
92
|
+
map,
|
|
93
|
+
unitsMap,
|
|
94
|
+
columns,
|
|
95
|
+
getColorForLithology,
|
|
96
|
+
).then(() => {});
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
[units, lithMap, columns, patterns],
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function handleUnitsLayerUpdate(
|
|
106
|
+
map,
|
|
107
|
+
unitsMap: Map<number, UnitsDisplayInfo>,
|
|
108
|
+
columns: any[],
|
|
109
|
+
) {
|
|
110
|
+
// Update feature states
|
|
111
|
+
for (const column of columns) {
|
|
112
|
+
const col_id = column.properties.col_id;
|
|
113
|
+
const info = unitsMap.get(Number(col_id));
|
|
114
|
+
const color = info?.color;
|
|
115
|
+
map.setFeatureState(
|
|
116
|
+
{ source: "columns", id: col_id },
|
|
117
|
+
{
|
|
118
|
+
color,
|
|
119
|
+
shown: color != null,
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function handlePatternOverlayUpdate(
|
|
126
|
+
map,
|
|
127
|
+
unitsMap: Map<number, UnitsDisplayInfo>,
|
|
128
|
+
columns: any[],
|
|
129
|
+
getColor: LithologyColorGetter,
|
|
130
|
+
) {
|
|
131
|
+
// synthesize patterns not yet in cache
|
|
132
|
+
|
|
133
|
+
const colsWithPatterns = [];
|
|
134
|
+
const patternIDs = new Set<string>();
|
|
135
|
+
// Update feature states
|
|
136
|
+
for (const column of columns) {
|
|
137
|
+
const col_id = column.properties.col_id;
|
|
138
|
+
const info = unitsMap.get(Number(col_id));
|
|
139
|
+
if (info == null) continue;
|
|
140
|
+
const pattern = getPatternSpec(info?.liths, getColor);
|
|
141
|
+
if (pattern == null) continue;
|
|
142
|
+
|
|
143
|
+
colsWithPatterns.push({
|
|
144
|
+
type: "Feature",
|
|
145
|
+
geometry: column.geometry,
|
|
146
|
+
properties: {
|
|
147
|
+
col_id,
|
|
148
|
+
pattern,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
patternIDs.add(pattern);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const patternsToLoad = patternIDs.values().filter((d) => !map.hasImage(d));
|
|
155
|
+
|
|
156
|
+
const mapper = async (patternID) => {
|
|
157
|
+
try {
|
|
158
|
+
await loadStyleImage(map, patternID, { pixelRatio: 10 });
|
|
159
|
+
} catch (e) {}
|
|
160
|
+
};
|
|
161
|
+
// Load all pattern images
|
|
162
|
+
await pMap(patternsToLoad, mapper, { concurrency: 5 });
|
|
163
|
+
|
|
164
|
+
// Set data for pattern layer
|
|
165
|
+
// This is inefficient but the only way to set per-feature patterns in Mapbox
|
|
166
|
+
const patternData: FeatureCollection = {
|
|
167
|
+
type: "FeatureCollection",
|
|
168
|
+
features: colsWithPatterns,
|
|
169
|
+
};
|
|
170
|
+
setGeoJSON(map, "column-patterns", patternData);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const cachedColors = new Map<string, string>();
|
|
174
|
+
|
|
175
|
+
function getDarkenedColor(color: string): string {
|
|
176
|
+
/** Memoized function to get a darkened version of a color for pattern use */
|
|
177
|
+
if (cachedColors.has(color)) {
|
|
178
|
+
return cachedColors.get(color);
|
|
179
|
+
}
|
|
180
|
+
const c1 = asChromaColor(color).set("hsl.l", 0.4).set("hsl.s", 0.8).hex();
|
|
181
|
+
cachedColors.set(color, c1);
|
|
182
|
+
return c1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface UnitsDisplayInfo {
|
|
186
|
+
col_id: number;
|
|
187
|
+
units: UnitLong[];
|
|
188
|
+
color: string;
|
|
189
|
+
liths: UnitLithology[];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
type LithologyColorGetter = (val: UnitLithology) => string | null;
|
|
193
|
+
|
|
194
|
+
function postProcessUnits(
|
|
195
|
+
units: UnitLong[],
|
|
196
|
+
getColor: LithologyColorGetter,
|
|
197
|
+
): Map<number, UnitsDisplayInfo> {
|
|
198
|
+
// Group by col_id
|
|
199
|
+
const unitsByColumn: Map<number, UnitLong[]> = new Map();
|
|
200
|
+
for (const unit of units) {
|
|
201
|
+
const col_id = Number(unit.col_id);
|
|
202
|
+
if (!unitsByColumn.has(col_id)) {
|
|
203
|
+
unitsByColumn.set(col_id, [unit]);
|
|
204
|
+
} else {
|
|
205
|
+
unitsByColumn.set(col_id, [...unitsByColumn.get(col_id), unit]);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Summarize units for display
|
|
210
|
+
const res = new Map<number, UnitsDisplayInfo>();
|
|
211
|
+
for (const [col_id, unitList] of unitsByColumn.entries()) {
|
|
212
|
+
const liths = flattenLithologies(unitList.map((u) => u.lith));
|
|
213
|
+
res.set(col_id, {
|
|
214
|
+
col_id,
|
|
215
|
+
units: unitList,
|
|
216
|
+
liths,
|
|
217
|
+
color: getMixedColorForData(liths, getColor),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return res;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function getPatternSpec(
|
|
225
|
+
liths: UnitLithology[],
|
|
226
|
+
getColor: LithologyColorGetter,
|
|
227
|
+
): string | null {
|
|
228
|
+
const patternData = getBestFGDCPatternForLithologyList(liths);
|
|
229
|
+
if (patternData == null) return null;
|
|
230
|
+
let { patternID, lith } = patternData;
|
|
231
|
+
const color = getDarkenedColor(getColor(lith));
|
|
232
|
+
return `fgdc:${patternID}:${color}:transparent`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
type UnitsStyleOptions = {
|
|
236
|
+
color?: string;
|
|
237
|
+
patterns?: boolean;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export function buildUnitsStyle(opts: UnitsStyleOptions = {}): StyleFragment {
|
|
241
|
+
const { color = null, patterns = false } = opts;
|
|
242
|
+
|
|
243
|
+
let columnBaseColor: any =
|
|
244
|
+
color ?? getCSSVariable("--text-subtle-color", "black");
|
|
245
|
+
const columnSelectedColor = getCSSVariable("--selection-color", "purple");
|
|
246
|
+
|
|
247
|
+
// If color is in the feature state or geojson properties, use that as second choice
|
|
248
|
+
|
|
249
|
+
let columnColor: any = [
|
|
250
|
+
"coalesce",
|
|
251
|
+
["feature-state", "color"],
|
|
252
|
+
["get", "color"],
|
|
253
|
+
columnBaseColor,
|
|
254
|
+
];
|
|
255
|
+
|
|
256
|
+
const baseStyle: StyleFragment = {
|
|
257
|
+
sources: {
|
|
258
|
+
columns: buildGeoJSONSource(),
|
|
259
|
+
},
|
|
260
|
+
version: 8,
|
|
261
|
+
layers: [
|
|
262
|
+
{
|
|
263
|
+
id: "columns-fill",
|
|
264
|
+
type: "fill",
|
|
265
|
+
source: "columns",
|
|
266
|
+
paint: {
|
|
267
|
+
"fill-color": columnColor,
|
|
268
|
+
"fill-opacity": [
|
|
269
|
+
"case",
|
|
270
|
+
["boolean", ["feature-state", "shown"], false],
|
|
271
|
+
0.8,
|
|
272
|
+
["boolean", ["feature-state", "hover"], false],
|
|
273
|
+
0.3,
|
|
274
|
+
0.1,
|
|
275
|
+
],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: "columns-line",
|
|
280
|
+
type: "line",
|
|
281
|
+
source: "columns",
|
|
282
|
+
paint: {
|
|
283
|
+
"line-color": columnColor,
|
|
284
|
+
"line-width": 1,
|
|
285
|
+
"line-opacity": 0.5,
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: "columns-points",
|
|
290
|
+
type: "circle",
|
|
291
|
+
source: "columns",
|
|
292
|
+
paint: {
|
|
293
|
+
"circle-radius": 4,
|
|
294
|
+
"circle-color": [
|
|
295
|
+
"case",
|
|
296
|
+
["boolean", ["feature-state", "shown"], false],
|
|
297
|
+
columnColor,
|
|
298
|
+
columnBaseColor,
|
|
299
|
+
],
|
|
300
|
+
"circle-opacity": [
|
|
301
|
+
"case",
|
|
302
|
+
["boolean", ["feature-state", "shown"], false],
|
|
303
|
+
0.8,
|
|
304
|
+
["boolean", ["feature-state", "hover"], false],
|
|
305
|
+
0.3,
|
|
306
|
+
0.1,
|
|
307
|
+
],
|
|
308
|
+
},
|
|
309
|
+
filter: ["==", "$type", "Point"],
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
if (!patterns) {
|
|
315
|
+
return baseStyle;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const patternStyle: StyleFragment = {
|
|
319
|
+
sources: {
|
|
320
|
+
"column-patterns": buildGeoJSONSource(),
|
|
321
|
+
},
|
|
322
|
+
layers: [
|
|
323
|
+
{
|
|
324
|
+
id: "columns-fill-pattern",
|
|
325
|
+
type: "fill",
|
|
326
|
+
source: "column-patterns",
|
|
327
|
+
paint: {
|
|
328
|
+
"fill-pattern": ["get", "pattern"],
|
|
329
|
+
"fill-opacity": 1,
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
],
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
return mergeStyles(baseStyle, patternStyle);
|
|
336
|
+
}
|
package/src/section.ts
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
useMacrostratColumnData,
|
|
17
17
|
useMacrostratUnits,
|
|
18
18
|
MacrostratColumnProvider,
|
|
19
|
-
useMacrostratBaseURL,
|
|
20
19
|
} from "./data-provider";
|
|
20
|
+
import { useMacrostratBaseURL } from "@macrostrat/data-provider";
|
|
21
21
|
import { Duration } from "./unit-details";
|
|
22
22
|
import { Value } from "@macrostrat/data-components";
|
|
23
23
|
import type { ExtUnit, PackageScaleLayoutData } from "./prepare-units/types";
|
|
@@ -2,7 +2,7 @@ import hyper from "@macrostrat/hyper";
|
|
|
2
2
|
import styles from "./panel.module.sass";
|
|
3
3
|
import { JSONView } from "@macrostrat/ui-components";
|
|
4
4
|
import { Button, ButtonGroup } from "@blueprintjs/core";
|
|
5
|
-
import { ReactNode, useMemo, useState } from "react";
|
|
5
|
+
import { ReactNode, useCallback, useMemo, useState } from "react";
|
|
6
6
|
import {
|
|
7
7
|
DataField,
|
|
8
8
|
EnvironmentsList,
|
|
@@ -13,13 +13,21 @@ import {
|
|
|
13
13
|
LithologyTagFeature,
|
|
14
14
|
Parenthetical,
|
|
15
15
|
Value,
|
|
16
|
+
MacrostratInteractionManager,
|
|
17
|
+
useInteractionProps,
|
|
18
|
+
ItemInteractionProps,
|
|
19
|
+
useInteractionManager,
|
|
20
|
+
MacrostratItemIdentifier,
|
|
21
|
+
MacrostratInteractionProvider,
|
|
22
|
+
isClickable,
|
|
16
23
|
} from "@macrostrat/data-components";
|
|
24
|
+
import { useColumnUnitsMap } from "../data-provider";
|
|
17
25
|
import {
|
|
18
|
-
useColumnUnitsMap,
|
|
19
26
|
useMacrostratColumnInfo,
|
|
20
27
|
useMacrostratData,
|
|
21
28
|
useMacrostratDefs,
|
|
22
|
-
|
|
29
|
+
useStratNames,
|
|
30
|
+
} from "@macrostrat/data-provider";
|
|
23
31
|
import type {
|
|
24
32
|
Environment,
|
|
25
33
|
UnitLong,
|
|
@@ -42,6 +50,7 @@ export interface UnitDetailsPanelProps {
|
|
|
42
50
|
lithologyFeatures?: Set<LithologyTagFeature>;
|
|
43
51
|
onSelectUnit?: (unitID: number) => void;
|
|
44
52
|
onClickItem?: MacrostratItemClickHandler;
|
|
53
|
+
interactionManager?: MacrostratInteractionManager;
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
export function UnitDetailsPanel({
|
|
@@ -71,7 +80,6 @@ export function UnitDetailsPanel({
|
|
|
71
80
|
features,
|
|
72
81
|
lithologyFeatures,
|
|
73
82
|
onClickItem,
|
|
74
|
-
onSelectUnit,
|
|
75
83
|
});
|
|
76
84
|
}
|
|
77
85
|
|
|
@@ -94,7 +102,7 @@ export function UnitDetailsPanel({
|
|
|
94
102
|
]);
|
|
95
103
|
}
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
const main = h("div.unit-details-panel", { className }, [
|
|
98
106
|
h(LegendPanelHeader, {
|
|
99
107
|
onClose,
|
|
100
108
|
title,
|
|
@@ -104,6 +112,36 @@ export function UnitDetailsPanel({
|
|
|
104
112
|
}),
|
|
105
113
|
h("div.unit-details-content-holder", content),
|
|
106
114
|
]);
|
|
115
|
+
|
|
116
|
+
/** Handle unit selection clicks */
|
|
117
|
+
const clickHandlerForItem = useMemo(() => {
|
|
118
|
+
if (onSelectUnit == null && onClickItem == null) return null;
|
|
119
|
+
return (item: MacrostratItemIdentifier) => {
|
|
120
|
+
if ("unit_id" in item && !("col_id" in item)) {
|
|
121
|
+
// We are selecting a unit within the column
|
|
122
|
+
return (event: MouseEvent) => {
|
|
123
|
+
onSelectUnit(item.unit_id);
|
|
124
|
+
// Don't allow event to propagate further (e.g., to open a link)
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
};
|
|
130
|
+
}, [onSelectUnit, onClickItem]);
|
|
131
|
+
|
|
132
|
+
if (clickHandlerForItem != null) {
|
|
133
|
+
// We wrap this in a MacrostratInteractionManager to handle unit selection
|
|
134
|
+
return h(
|
|
135
|
+
MacrostratInteractionProvider,
|
|
136
|
+
{
|
|
137
|
+
clickHandlerForItem,
|
|
138
|
+
inherit: true,
|
|
139
|
+
},
|
|
140
|
+
main,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return main;
|
|
107
145
|
}
|
|
108
146
|
|
|
109
147
|
export function LegendPanelHeader({
|
|
@@ -162,7 +200,6 @@ export type MacrostratItemClickHandler = (
|
|
|
162
200
|
|
|
163
201
|
function UnitDetailsContent({
|
|
164
202
|
unit,
|
|
165
|
-
onSelectUnit,
|
|
166
203
|
lithologyFeatures = new Set([
|
|
167
204
|
LithologyTagFeature.Proportion,
|
|
168
205
|
LithologyTagFeature.Attributes,
|
|
@@ -175,7 +212,6 @@ function UnitDetailsContent({
|
|
|
175
212
|
getItemHref,
|
|
176
213
|
}: {
|
|
177
214
|
unit: UnitLong;
|
|
178
|
-
onSelectUnit?: (unitID: number) => void;
|
|
179
215
|
lithologyFeatures?: Set<LithologyTagFeature>;
|
|
180
216
|
features?: Set<UnitDetailsFeature>;
|
|
181
217
|
onClickItem?: MacrostratItemClickHandler;
|
|
@@ -243,12 +279,10 @@ function UnitDetailsContent({
|
|
|
243
279
|
col_id: unit.col_id,
|
|
244
280
|
}),
|
|
245
281
|
thicknessOrHeightRange,
|
|
246
|
-
h.if(lithologies)(LithologyList, {
|
|
282
|
+
h.if(lithologies != null)(LithologyList, {
|
|
247
283
|
label: "Lithology",
|
|
248
284
|
lithologies,
|
|
249
285
|
features: lithologyFeatures,
|
|
250
|
-
getItemHref,
|
|
251
|
-
onClickItem,
|
|
252
286
|
}),
|
|
253
287
|
h(AgeField, { unit }, [
|
|
254
288
|
h(Parenthetical, h(Duration, { value: unit.b_age - unit.t_age })),
|
|
@@ -257,10 +291,8 @@ function UnitDetailsContent({
|
|
|
257
291
|
onClickItem,
|
|
258
292
|
}),
|
|
259
293
|
]),
|
|
260
|
-
h.if(environments)(EnvironmentsList, {
|
|
294
|
+
h.if(environments != null)(EnvironmentsList, {
|
|
261
295
|
environments,
|
|
262
|
-
onClickItem,
|
|
263
|
-
getItemHref,
|
|
264
296
|
}),
|
|
265
297
|
h.if(unit.strat_name_id != null)(StratNameField, {
|
|
266
298
|
strat_name_id: unit.strat_name_id,
|
|
@@ -272,7 +304,6 @@ function UnitDetailsContent({
|
|
|
272
304
|
{ label: "Above" },
|
|
273
305
|
h(UnitIDList, {
|
|
274
306
|
units: unit.units_above,
|
|
275
|
-
onSelectUnit,
|
|
276
307
|
showNames: true,
|
|
277
308
|
}),
|
|
278
309
|
),
|
|
@@ -281,7 +312,6 @@ function UnitDetailsContent({
|
|
|
281
312
|
{ label: "Below" },
|
|
282
313
|
h(UnitIDList, {
|
|
283
314
|
units: unit.units_below,
|
|
284
|
-
onSelectUnit,
|
|
285
315
|
showNames: true,
|
|
286
316
|
}),
|
|
287
317
|
),
|
|
@@ -333,27 +363,35 @@ export function ReferencesField({ refs, className = null, ...rest }) {
|
|
|
333
363
|
);
|
|
334
364
|
}
|
|
335
365
|
|
|
336
|
-
function
|
|
337
|
-
strat_name_id
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
366
|
+
function useStratNameData(strat_name_id: number) {
|
|
367
|
+
const stratNames = useStratNames([strat_name_id]);
|
|
368
|
+
return stratNames?.[0];
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function StratNameField(
|
|
372
|
+
props: {
|
|
373
|
+
strat_name_id: number;
|
|
374
|
+
className?: string;
|
|
375
|
+
} & ItemInteractionProps,
|
|
376
|
+
) {
|
|
377
|
+
/** Handling for stratigraphic name field */
|
|
378
|
+
const { strat_name_id, className, ...rest } = props;
|
|
379
|
+
const data = useStratNameData(strat_name_id);
|
|
380
|
+
|
|
381
|
+
const baseInteractionProps = useInteractionProps({ strat_name_id });
|
|
382
|
+
|
|
383
|
+
const coreProps = {
|
|
384
|
+
...baseInteractionProps,
|
|
385
|
+
...rest,
|
|
386
|
+
};
|
|
387
|
+
|
|
346
388
|
let inner: any = h(Identifier, { id: strat_name_id });
|
|
347
|
-
const name =
|
|
389
|
+
const name = data?.strat_name_long;
|
|
348
390
|
if (name != null) {
|
|
349
391
|
inner = h("span.strat-name", name);
|
|
350
392
|
}
|
|
351
393
|
|
|
352
|
-
const clickable =
|
|
353
|
-
|
|
354
|
-
const className = classNames({
|
|
355
|
-
clickable,
|
|
356
|
-
});
|
|
394
|
+
const clickable = isClickable(coreProps);
|
|
357
395
|
|
|
358
396
|
return h(
|
|
359
397
|
DataField,
|
|
@@ -363,8 +401,8 @@ function StratNameField({
|
|
|
363
401
|
h(
|
|
364
402
|
clickable ? "a" : "span",
|
|
365
403
|
{
|
|
366
|
-
className,
|
|
367
|
-
|
|
404
|
+
className: classNames({ clickable }, className),
|
|
405
|
+
...coreProps,
|
|
368
406
|
},
|
|
369
407
|
inner,
|
|
370
408
|
),
|
|
@@ -566,36 +604,32 @@ function enhanceLithologies(
|
|
|
566
604
|
}
|
|
567
605
|
|
|
568
606
|
export function ClickableText({
|
|
569
|
-
onClick,
|
|
570
607
|
className,
|
|
571
|
-
|
|
608
|
+
...rest
|
|
572
609
|
}: {
|
|
573
|
-
onClick: () => void;
|
|
574
610
|
className?: string;
|
|
575
611
|
children: ReactNode;
|
|
576
|
-
}) {
|
|
612
|
+
} & ItemInteractionProps) {
|
|
577
613
|
/** An optionally clickable text element */
|
|
578
|
-
const
|
|
579
|
-
|
|
614
|
+
const clickable = isClickable(rest);
|
|
615
|
+
const tag = clickable ? "a" : "span";
|
|
616
|
+
return h(tag, { className: classNames(className, { clickable }), ...rest });
|
|
580
617
|
}
|
|
581
618
|
|
|
582
619
|
export function Identifier({
|
|
583
620
|
id,
|
|
584
|
-
onClick,
|
|
585
621
|
className,
|
|
622
|
+
...rest
|
|
586
623
|
}: {
|
|
587
624
|
id: number | string;
|
|
588
|
-
onClick?: (id: number | string) => void;
|
|
589
625
|
className?: string;
|
|
590
|
-
}) {
|
|
626
|
+
} & ItemInteractionProps) {
|
|
591
627
|
/** An item that displays a numeric identifier, optionally clickable */
|
|
592
|
-
const _onClick = onClick != null ? () => onClick(id) : null;
|
|
593
|
-
|
|
594
628
|
return h(
|
|
595
629
|
ClickableText,
|
|
596
630
|
{
|
|
597
|
-
onClick: _onClick,
|
|
598
631
|
className: classNames("identifier", className),
|
|
632
|
+
...rest,
|
|
599
633
|
},
|
|
600
634
|
id,
|
|
601
635
|
);
|
|
@@ -607,9 +641,11 @@ type UnitInfo = {
|
|
|
607
641
|
name?: string;
|
|
608
642
|
};
|
|
609
643
|
|
|
610
|
-
function UnitIDList({ units,
|
|
644
|
+
function UnitIDList({ units, showNames = false }) {
|
|
611
645
|
const unitsMap = useColumnUnitsMap();
|
|
612
646
|
|
|
647
|
+
const interactionManager = useInteractionManager();
|
|
648
|
+
|
|
613
649
|
const extUnits: UnitInfo[] = useMemo(() => {
|
|
614
650
|
const u1 = units.filter((d) => d != 0);
|
|
615
651
|
if (showNames) {
|
|
@@ -637,9 +673,17 @@ function UnitIDList({ units, onSelectUnit, showNames = false }) {
|
|
|
637
673
|
return h(
|
|
638
674
|
ItemList,
|
|
639
675
|
{ className: "units-list" },
|
|
640
|
-
extUnits.map((info) =>
|
|
641
|
-
|
|
642
|
-
|
|
676
|
+
extUnits.map((info) => {
|
|
677
|
+
return h(
|
|
678
|
+
"span.item",
|
|
679
|
+
h(UnitIdentifier, {
|
|
680
|
+
...info,
|
|
681
|
+
...interactionManager?.interactionPropsForItem({
|
|
682
|
+
unit_id: info.unitID,
|
|
683
|
+
}),
|
|
684
|
+
}),
|
|
685
|
+
);
|
|
686
|
+
}),
|
|
643
687
|
);
|
|
644
688
|
}
|
|
645
689
|
|
|
@@ -647,21 +691,14 @@ function UnitIdentifier({
|
|
|
647
691
|
unitID,
|
|
648
692
|
colID,
|
|
649
693
|
name,
|
|
650
|
-
|
|
651
|
-
}: UnitInfo &
|
|
652
|
-
const onClick = useMemo(() => {
|
|
653
|
-
if (onSelectUnit == null) return null;
|
|
654
|
-
return () => {
|
|
655
|
-
onSelectUnit(unitID);
|
|
656
|
-
};
|
|
657
|
-
}, [onSelectUnit]);
|
|
658
|
-
|
|
694
|
+
...interactionProps
|
|
695
|
+
}: UnitInfo & ItemInteractionProps) {
|
|
659
696
|
if (name != null) {
|
|
660
697
|
return h(
|
|
661
698
|
ClickableText,
|
|
662
699
|
{
|
|
663
700
|
className: "unit-name",
|
|
664
|
-
|
|
701
|
+
...interactionProps,
|
|
665
702
|
},
|
|
666
703
|
name,
|
|
667
704
|
);
|
|
@@ -669,9 +706,9 @@ function UnitIdentifier({
|
|
|
669
706
|
|
|
670
707
|
return h(Identifier, {
|
|
671
708
|
className: "unit-id",
|
|
672
|
-
onClick,
|
|
673
709
|
key: unitID,
|
|
674
710
|
id: unitID,
|
|
711
|
+
...interactionProps,
|
|
675
712
|
});
|
|
676
713
|
}
|
|
677
714
|
|
package/src/units/boxes.ts
CHANGED
|
@@ -12,7 +12,8 @@ import { SizeAwareLabel, Clickable } from "@macrostrat/ui-components";
|
|
|
12
12
|
import hyper from "@macrostrat/hyper";
|
|
13
13
|
import { forwardRef, ReactNode, useContext, useMemo } from "react";
|
|
14
14
|
import { resolveID, scalePattern } from "./resolvers";
|
|
15
|
-
import { useUnitSelectionTarget
|
|
15
|
+
import { useUnitSelectionTarget } from "../data-provider";
|
|
16
|
+
import { useLithologies } from "@macrostrat/data-provider";
|
|
16
17
|
import { IUnit } from "./types";
|
|
17
18
|
import styles from "./boxes.module.sass";
|
|
18
19
|
import classNames from "classnames";
|