@macrostrat/column-views 3.3.4 → 3.4.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 +63 -0
- package/dist/age-axis.d.ts +3 -3
- package/dist/column.cjs +2 -1
- package/dist/column.cjs.map +1 -1
- package/dist/column.d.ts +3 -3
- package/dist/column.js +2 -1
- package/dist/column.js.map +1 -1
- package/dist/correlation-chart/main.d.ts +1 -1
- package/dist/correlation-chart/prepare-data.d.ts +1 -1
- package/dist/data-provider/unit-selection.cjs +7 -3
- package/dist/data-provider/unit-selection.cjs.map +1 -1
- package/dist/data-provider/unit-selection.d.ts +3 -2
- package/dist/data-provider/unit-selection.js +7 -3
- package/dist/data-provider/unit-selection.js.map +1 -1
- package/dist/facets/carbon-isotopes/data-area.d.ts +1 -1
- package/dist/facets/carbon-isotopes/data-provider.d.ts +1 -1
- package/dist/facets/measurements/base.d.ts +2 -2
- package/dist/index.cjs +13 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/maps/column-correlation/state.d.ts +1 -1
- package/dist/maps/column-navigation/mapbox/state.d.ts +1 -1
- package/dist/maps/column-navigation/svg/data-fetcher.d.ts +1 -1
- package/dist/maps/column-navigation/svg/layers.d.ts +3 -3
- package/dist/maps/inset-map/index.d.ts +1 -1
- package/dist/maps/layers/columns.d.ts +1 -1
- package/dist/maps/layers/units.d.ts +1 -1
- package/dist/prepare-units/composite-scale.d.ts +1 -1
- package/dist/prepare-units/dynamic-scales.d.ts +1 -1
- package/dist/prepare-units/helpers.cjs +83 -49
- package/dist/prepare-units/helpers.cjs.map +1 -1
- package/dist/prepare-units/helpers.d.ts +21 -4
- package/dist/prepare-units/helpers.js +84 -50
- package/dist/prepare-units/helpers.js.map +1 -1
- package/dist/prepare-units/index.cjs.map +1 -1
- package/dist/prepare-units/index.d.ts +1 -1
- package/dist/prepare-units/index.js.map +1 -1
- package/dist/prepare-units/types.d.ts +2 -2
- package/dist/prepare-units/utils.d.ts +2 -2
- package/dist/section.cjs +1 -2
- package/dist/section.cjs.map +1 -1
- package/dist/section.d.ts +1 -1
- package/dist/section.js +1 -2
- package/dist/section.js.map +1 -1
- package/dist/unit-details/age-range.cjs.map +1 -1
- package/dist/unit-details/age-range.d.ts +2 -1
- package/dist/unit-details/age-range.js.map +1 -1
- package/dist/unit-details/identifiers.cjs +56 -0
- package/dist/unit-details/identifiers.cjs.map +1 -0
- package/dist/unit-details/identifiers.d.ts +31 -0
- package/dist/unit-details/identifiers.js +54 -0
- package/dist/unit-details/identifiers.js.map +1 -0
- package/dist/unit-details/index.d.ts +2 -0
- package/dist/unit-details/panel.cjs +73 -147
- package/dist/unit-details/panel.cjs.map +1 -1
- package/dist/unit-details/panel.d.ts +67 -0
- package/dist/unit-details/panel.js +19 -92
- package/dist/unit-details/panel.js.map +1 -1
- package/dist/unit-details/popover.cjs +1 -2
- package/dist/unit-details/popover.cjs.map +1 -1
- package/dist/unit-details/popover.js +2 -3
- package/dist/unit-details/popover.js.map +1 -1
- package/dist/unit-details/strat-names.cjs +44 -0
- package/dist/unit-details/strat-names.cjs.map +1 -0
- package/dist/unit-details/strat-names.d.ts +14 -0
- package/dist/unit-details/strat-names.js +42 -0
- package/dist/unit-details/strat-names.js.map +1 -0
- package/dist/units/boxes.d.ts +2 -2
- package/dist/units/colors.d.ts +1 -1
- package/dist/units/composite.d.ts +4 -4
- package/dist/units/index.cjs +20 -6
- package/dist/units/index.cjs.map +1 -1
- package/dist/units/index.d.ts +12 -21
- package/dist/units/index.js +20 -6
- package/dist/units/index.js.map +1 -1
- package/dist/units/names.d.ts +3 -3
- package/dist/units/resolvers.d.ts +2 -2
- package/package.json +19 -19
- package/src/column.ts +1 -1
- package/src/data-provider/unit-selection.ts +8 -4
- package/src/prepare-units/helpers.ts +121 -72
- package/src/prepare-units/index.ts +1 -1
- package/src/section.ts +0 -1
- package/src/unit-details/age-range.ts +1 -0
- package/src/unit-details/identifiers.ts +67 -0
- package/src/unit-details/index.ts +2 -0
- package/src/unit-details/panel.ts +27 -131
- package/src/unit-details/popover.ts +2 -7
- package/src/unit-details/strat-names.ts +57 -0
- package/src/units/index.ts +31 -8
|
@@ -16,95 +16,143 @@ import type { ExtUnit, SectionInfo, StratigraphicPackage } from "./types";
|
|
|
16
16
|
|
|
17
17
|
const dt = 0.001;
|
|
18
18
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
): ExtUnit[] {
|
|
23
|
-
/** Preprocess units to add overlapping units and columns. */
|
|
24
|
-
let units = section.units;
|
|
19
|
+
export type UnitWithDefinedOverlap<T extends BaseUnit> = T & {
|
|
20
|
+
overlap: UnitOverlapInfo<T>;
|
|
21
|
+
};
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
type UnitOverlapInfo<T extends BaseUnit> = {
|
|
24
|
+
column: number;
|
|
25
|
+
nColumns: number;
|
|
26
|
+
unitGroup: UnitGroup<T>;
|
|
27
|
+
};
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
class UnitGroup<T extends BaseUnit> implements StratigraphicPackage {
|
|
30
|
+
units: T[];
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
while (columns.includes(col)) {
|
|
39
|
-
col++;
|
|
40
|
-
}
|
|
41
|
-
d.column ??= col;
|
|
42
|
-
}
|
|
32
|
+
constructor(units: T[]) {
|
|
33
|
+
this.units = units;
|
|
34
|
+
}
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
get t_age(): number {
|
|
37
|
+
return Math.min(...this.units.map((d) => d.t_age));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get b_age(): number {
|
|
41
|
+
return Math.max(...this.units.map((d) => d.b_age));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getUnits(): UnitWithDefinedOverlap<T>[] {
|
|
45
|
+
return assignColumnsToUnitsWithinOverlappingGroup(this);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function groupUnitsByMutualOverlap<T extends BaseUnit>(
|
|
50
|
+
units: T[],
|
|
51
|
+
tolerance: number = dt,
|
|
52
|
+
): UnitGroup<T>[] {
|
|
53
|
+
/** Group units within a section that have mutual overlap. */
|
|
54
|
+
const sections = groupUnitsIntoSectionsByOverlap(
|
|
55
|
+
units,
|
|
56
|
+
ColumnAxisType.AGE,
|
|
57
|
+
tolerance,
|
|
58
|
+
);
|
|
59
|
+
return sections.map((d) => {
|
|
60
|
+
return new UnitGroup(d.units);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const sortByAge = createUnitSorter(ColumnAxisType.AGE);
|
|
65
|
+
|
|
66
|
+
function assignColumnsToUnitsWithinOverlappingGroup<T extends BaseUnit>(
|
|
67
|
+
group: UnitGroup<T>,
|
|
68
|
+
): UnitWithDefinedOverlap<T>[] {
|
|
69
|
+
/** A relatively naïve function to assign columns to units within a mutually overlapping group.
|
|
70
|
+
* This gets the number of columns that would be needed to accommodate the units in the group.
|
|
71
|
+
* It then assigns columns to units in the group based on the number of columns needed, with
|
|
72
|
+
* lower units further to the left.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
const sortedUnits = [...group.units].sort((a, b) => b.b_age - a.b_age);
|
|
76
|
+
|
|
77
|
+
const columns: T[][] = [];
|
|
78
|
+
|
|
79
|
+
for (const unit of sortedUnits) {
|
|
80
|
+
// Find a column that is not already occupied by an overlapping unit
|
|
81
|
+
let didAddToExistingColumn = false;
|
|
82
|
+
for (const column of columns) {
|
|
83
|
+
const lastUnit = column[column.length - 1];
|
|
84
|
+
if (!unitsOverlap(unit, lastUnit, ColumnAxisType.AGE, dt)) {
|
|
85
|
+
column.push(unit);
|
|
86
|
+
didAddToExistingColumn = true;
|
|
87
|
+
break;
|
|
52
88
|
}
|
|
53
89
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
d.b_clip_pos = section.b_pos;
|
|
57
|
-
}
|
|
58
|
-
if (t_pos < section.t_pos) {
|
|
59
|
-
d.t_clip_pos = section.t_pos;
|
|
60
|
-
}
|
|
90
|
+
if (!didAddToExistingColumn) {
|
|
91
|
+
columns.push([unit]);
|
|
61
92
|
}
|
|
62
|
-
// if (axisType == ColumnAxisType.HEIGHT) {
|
|
63
|
-
// if (b_pos < section.b_pos) {
|
|
64
|
-
// d.b_clip_pos = section.b_pos;
|
|
65
|
-
// }
|
|
66
|
-
// if (t_pos > section.t_pos) {
|
|
67
|
-
// d.t_clip_pos = section.t_pos;
|
|
68
|
-
// }
|
|
69
|
-
// }
|
|
70
93
|
}
|
|
71
94
|
|
|
72
|
-
|
|
95
|
+
const units: UnitWithDefinedOverlap<T>[] = columns.flatMap(
|
|
96
|
+
(column, columnIndex) =>
|
|
97
|
+
column.map((unit) => {
|
|
98
|
+
return {
|
|
99
|
+
...unit,
|
|
100
|
+
overlap: {
|
|
101
|
+
column: columnIndex,
|
|
102
|
+
nColumns: columns.length,
|
|
103
|
+
unitGroup: group,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
return units.toSorted(sortByAge);
|
|
73
110
|
}
|
|
74
111
|
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
i: number,
|
|
78
|
-
divisions: UnitLong[],
|
|
112
|
+
export function preprocessUnits<T extends UnitLong = UnitLong>(
|
|
113
|
+
section: SectionInfo<T>,
|
|
79
114
|
axisType: ColumnAxisType = ColumnAxisType.AGE,
|
|
80
|
-
): ExtUnit {
|
|
81
|
-
|
|
115
|
+
): ExtUnit[] {
|
|
116
|
+
/** Preprocess units to add overlapping units and columns. */
|
|
117
|
+
let units = section.units;
|
|
118
|
+
|
|
82
119
|
let tolerance = 0.001; // 1 kyr tolerance for age columns
|
|
83
120
|
if (axisType != ColumnAxisType.AGE) {
|
|
84
121
|
tolerance = 0.01; // 1cm tolerance for height/depth columns
|
|
85
122
|
}
|
|
86
123
|
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const d_pos = getUnitHeightRange(d, axisType);
|
|
94
|
-
// Check if the unit is below the current unit
|
|
95
|
-
return d_pos[0] < u_pos[0] + dt;
|
|
96
|
-
});
|
|
97
|
-
let column = 0;
|
|
98
|
-
if (overlappingUnits.length == 1) {
|
|
99
|
-
column = 1;
|
|
124
|
+
const unitGroups = groupUnitsByMutualOverlap(units, tolerance);
|
|
125
|
+
|
|
126
|
+
const divisions: any[] = [];
|
|
127
|
+
// Serialize all groups' units to a single array
|
|
128
|
+
for (const group of unitGroups) {
|
|
129
|
+
divisions.push(...group.getUnits());
|
|
100
130
|
}
|
|
101
131
|
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
132
|
+
return divisions.map((d) =>
|
|
133
|
+
enhanceUnitWithClippingPosition(section, d, axisType),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function enhanceUnitWithClippingPosition(section, d, axisType) {
|
|
138
|
+
const [b_pos, t_pos] = getUnitHeightRange(d, axisType);
|
|
139
|
+
if (axisType == ColumnAxisType.AGE) {
|
|
140
|
+
if (b_pos > section.b_age) {
|
|
141
|
+
d.b_clip_pos = section.b_age;
|
|
142
|
+
}
|
|
143
|
+
if (t_pos < section.t_age) {
|
|
144
|
+
d.t_clip_pos = section.t_age;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (axisType == ColumnAxisType.DEPTH) {
|
|
148
|
+
if (b_pos > section.b_pos) {
|
|
149
|
+
d.b_clip_pos = section.b_pos;
|
|
150
|
+
}
|
|
151
|
+
if (t_pos < section.t_pos) {
|
|
152
|
+
d.t_clip_pos = section.t_pos;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return d;
|
|
108
156
|
}
|
|
109
157
|
|
|
110
158
|
export function groupUnitsIntoSectionsBySectionID<T extends UnitLong>(
|
|
@@ -141,9 +189,10 @@ interface WorkingSection {
|
|
|
141
189
|
heightRange?: [number, number];
|
|
142
190
|
}
|
|
143
191
|
|
|
144
|
-
export function groupUnitsIntoSectionsByOverlap<T extends
|
|
192
|
+
export function groupUnitsIntoSectionsByOverlap<T extends BaseUnit>(
|
|
145
193
|
units: T[],
|
|
146
194
|
axisType: ColumnAxisType = ColumnAxisType.AGE,
|
|
195
|
+
tolerance: number = dt,
|
|
147
196
|
): SectionInfo<T>[] {
|
|
148
197
|
/** Group units into sections by overlap.
|
|
149
198
|
* This creates "synthetic" sections that correspond to packages bound by scale gaps.
|
|
@@ -157,7 +206,7 @@ export function groupUnitsIntoSectionsByOverlap<T extends UnitLong>(
|
|
|
157
206
|
const heightRange = getUnitHeightRange(unit, axisType);
|
|
158
207
|
let section: WorkingSection | undefined = sectionList.find(
|
|
159
208
|
(s) =>
|
|
160
|
-
compareAgeRanges(heightRange, s.heightRange) !==
|
|
209
|
+
compareAgeRanges(heightRange, s.heightRange, tolerance) !==
|
|
161
210
|
AgeRangeRelationship.Disjoint,
|
|
162
211
|
);
|
|
163
212
|
if (section == null) {
|
package/src/section.ts
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { isClickable, ItemInteractionProps } from "@macrostrat/data-components";
|
|
2
|
+
import h from "./panel.module.sass";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import classNames from "classnames";
|
|
5
|
+
|
|
6
|
+
export function ClickableText({
|
|
7
|
+
className,
|
|
8
|
+
...rest
|
|
9
|
+
}: {
|
|
10
|
+
className?: string;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
} & ItemInteractionProps) {
|
|
13
|
+
/** An optionally clickable text element */
|
|
14
|
+
const clickable = isClickable(rest);
|
|
15
|
+
const tag = clickable ? "a" : "span";
|
|
16
|
+
return h(tag, { className: classNames(className, { clickable }), ...rest });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function Identifier({
|
|
20
|
+
id,
|
|
21
|
+
className,
|
|
22
|
+
...rest
|
|
23
|
+
}: {
|
|
24
|
+
id: number | string;
|
|
25
|
+
className?: string;
|
|
26
|
+
} & ItemInteractionProps) {
|
|
27
|
+
/** An item that displays a numeric identifier, optionally clickable */
|
|
28
|
+
return h(
|
|
29
|
+
ClickableText,
|
|
30
|
+
{
|
|
31
|
+
className: classNames("identifier", className),
|
|
32
|
+
...rest,
|
|
33
|
+
},
|
|
34
|
+
id,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type UnitInfo = {
|
|
39
|
+
unitID: number;
|
|
40
|
+
colID?: number;
|
|
41
|
+
name?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export function UnitIdentifier({
|
|
45
|
+
unitID,
|
|
46
|
+
colID,
|
|
47
|
+
name,
|
|
48
|
+
...interactionProps
|
|
49
|
+
}: UnitInfo & ItemInteractionProps) {
|
|
50
|
+
if (name != null) {
|
|
51
|
+
return h(
|
|
52
|
+
ClickableText,
|
|
53
|
+
{
|
|
54
|
+
className: "unit-name",
|
|
55
|
+
...interactionProps,
|
|
56
|
+
},
|
|
57
|
+
name,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return h(Identifier, {
|
|
62
|
+
className: "unit-id",
|
|
63
|
+
key: unitID,
|
|
64
|
+
id: unitID,
|
|
65
|
+
...interactionProps,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import hyper from "@macrostrat/hyper";
|
|
2
|
-
import styles from "./panel.module.sass";
|
|
3
1
|
import { JSONView } from "@macrostrat/ui-components";
|
|
4
2
|
import { Button, ButtonGroup } from "@blueprintjs/core";
|
|
5
3
|
import { ReactNode, useMemo, useState } from "react";
|
|
6
4
|
import {
|
|
7
5
|
DataField,
|
|
8
6
|
EnvironmentsList,
|
|
9
|
-
isClickable,
|
|
10
|
-
ItemInteractionProps,
|
|
11
7
|
ItemList,
|
|
12
8
|
LithologyList,
|
|
13
9
|
LithologyTagFeature,
|
|
@@ -16,7 +12,6 @@ import {
|
|
|
16
12
|
MacrostratItemIdentifier,
|
|
17
13
|
Parenthetical,
|
|
18
14
|
useInteractionManager,
|
|
19
|
-
useInteractionProps,
|
|
20
15
|
Value,
|
|
21
16
|
} from "@macrostrat/data-components";
|
|
22
17
|
import { useColumnUnitsMap } from "../data-provider";
|
|
@@ -24,10 +19,10 @@ import {
|
|
|
24
19
|
useMacrostratColumnInfo,
|
|
25
20
|
useMacrostratData,
|
|
26
21
|
useMacrostratDefs,
|
|
27
|
-
useStratNames,
|
|
28
22
|
} from "@macrostrat/data-provider";
|
|
29
23
|
import type {
|
|
30
24
|
Environment,
|
|
25
|
+
EnvironmentIdentifier,
|
|
31
26
|
Interval,
|
|
32
27
|
Lithology,
|
|
33
28
|
UnitLong,
|
|
@@ -37,8 +32,10 @@ import { defaultNameFunction } from "../units/names";
|
|
|
37
32
|
import classNames from "classnames";
|
|
38
33
|
import { AgeField, Duration, IntervalProportions } from "./age-range";
|
|
39
34
|
import { formatRange, formatSignificance } from "./utils.ts";
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
import h from "./panel.module.sass";
|
|
36
|
+
import { StratNameField } from "./strat-names.ts";
|
|
37
|
+
import { Identifier, UnitIdentifier, UnitInfo } from "./identifiers.ts";
|
|
38
|
+
import { LithologyIdentifier } from "@macrostrat/api-types/src/lithologies";
|
|
42
39
|
|
|
43
40
|
export interface UnitDetailsPanelProps {
|
|
44
41
|
unit: any;
|
|
@@ -51,6 +48,7 @@ export interface UnitDetailsPanelProps {
|
|
|
51
48
|
onSelectUnit?: (unitID: number) => void;
|
|
52
49
|
onClickItem?: MacrostratItemClickHandler;
|
|
53
50
|
interactionManager?: MacrostratInteractionManager;
|
|
51
|
+
showJSON?: boolean;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
export function UnitDetailsPanel({
|
|
@@ -68,11 +66,12 @@ export function UnitDetailsPanel({
|
|
|
68
66
|
hiddenActions = null,
|
|
69
67
|
onSelectUnit,
|
|
70
68
|
onClickItem,
|
|
69
|
+
showJSON,
|
|
71
70
|
}: UnitDetailsPanelProps) {
|
|
72
|
-
const [
|
|
71
|
+
const [_showJSON, setShowJSON] = useState(false);
|
|
73
72
|
|
|
74
|
-
let content = null;
|
|
75
|
-
if (showJSON) {
|
|
73
|
+
let content: ReactNode = null;
|
|
74
|
+
if (showJSON ?? _showJSON) {
|
|
76
75
|
content = h(JSONView, { data: unit, showRoot: false });
|
|
77
76
|
} else {
|
|
78
77
|
content = h(UnitDetailsContent, {
|
|
@@ -120,7 +119,13 @@ export function UnitDetailsPanel({
|
|
|
120
119
|
if ("unit_id" in item && !("col_id" in item)) {
|
|
121
120
|
// We are selecting a unit within the column
|
|
122
121
|
return (event: MouseEvent) => {
|
|
123
|
-
onSelectUnit
|
|
122
|
+
if (onSelectUnit != null) {
|
|
123
|
+
onSelectUnit(item.unit_id);
|
|
124
|
+
} else if (onClickItem != null) {
|
|
125
|
+
console.warn(
|
|
126
|
+
"Unit selection: onClickItem is defined but onSelectUnit is not; ignoring click",
|
|
127
|
+
);
|
|
128
|
+
}
|
|
124
129
|
// Don't allow event to propagate further (e.g., to open a link)
|
|
125
130
|
event.preventDefault();
|
|
126
131
|
};
|
|
@@ -173,7 +178,7 @@ export function LegendPanelHeader({
|
|
|
173
178
|
minimal: true,
|
|
174
179
|
small: true,
|
|
175
180
|
onClick() {
|
|
176
|
-
onClose();
|
|
181
|
+
onClose?.();
|
|
177
182
|
},
|
|
178
183
|
}),
|
|
179
184
|
]);
|
|
@@ -223,7 +228,7 @@ function UnitDetailsContent({
|
|
|
223
228
|
const environments = enhanceEnvironments(unit.environ, envMap);
|
|
224
229
|
const lithologies = enhanceLithologies(unit.lith ?? [], lithMap);
|
|
225
230
|
|
|
226
|
-
let outcropField = null;
|
|
231
|
+
let outcropField: ReactNode = null;
|
|
227
232
|
if (features.has(UnitDetailsFeature.OutcropType)) {
|
|
228
233
|
// Determine outcrop type
|
|
229
234
|
let outcrop = unit.outcrop;
|
|
@@ -236,7 +241,7 @@ function UnitDetailsContent({
|
|
|
236
241
|
});
|
|
237
242
|
}
|
|
238
243
|
|
|
239
|
-
let thicknessOrHeightRange = null;
|
|
244
|
+
let thicknessOrHeightRange: ReactNode = null;
|
|
240
245
|
const [thickness, thicknessUnit] = getThickness(unit);
|
|
241
246
|
// Proxy for actual heights in t_pos and b_pos
|
|
242
247
|
if (
|
|
@@ -281,7 +286,7 @@ function UnitDetailsContent({
|
|
|
281
286
|
thicknessOrHeightRange,
|
|
282
287
|
h.if(lithologies != null)(LithologyList, {
|
|
283
288
|
label: "Lithology",
|
|
284
|
-
lithologies,
|
|
289
|
+
lithologies: lithologies ?? [],
|
|
285
290
|
features: lithologyFeatures,
|
|
286
291
|
}),
|
|
287
292
|
h(AgeField, { unit }, [
|
|
@@ -363,53 +368,7 @@ export function ReferencesField({ refs, className = null, ...rest }) {
|
|
|
363
368
|
);
|
|
364
369
|
}
|
|
365
370
|
|
|
366
|
-
function
|
|
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
|
-
|
|
388
|
-
let inner: any = h(Identifier, { id: strat_name_id });
|
|
389
|
-
const name = data?.strat_name_long;
|
|
390
|
-
if (name != null) {
|
|
391
|
-
inner = h("span.strat-name", name);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
const clickable = isClickable(coreProps);
|
|
395
|
-
|
|
396
|
-
return h(
|
|
397
|
-
DataField,
|
|
398
|
-
{
|
|
399
|
-
label: "Stratigraphic name",
|
|
400
|
-
},
|
|
401
|
-
h(
|
|
402
|
-
clickable ? "a" : "span",
|
|
403
|
-
{
|
|
404
|
-
className: classNames({ clickable }, className),
|
|
405
|
-
...coreProps,
|
|
406
|
-
},
|
|
407
|
-
inner,
|
|
408
|
-
),
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
function getThickness(unit): [string, string] {
|
|
371
|
+
function getThickness(unit): [string, string | null] {
|
|
413
372
|
let minThickness = unit.min_thick ?? 0;
|
|
414
373
|
let maxThickness = unit.max_thick ?? unit.min_thick ?? 0;
|
|
415
374
|
let _unit = "m";
|
|
@@ -480,8 +439,8 @@ function Citation({ data, tag = "p" }) {
|
|
|
480
439
|
}
|
|
481
440
|
|
|
482
441
|
function enhanceEnvironments(
|
|
483
|
-
environments
|
|
484
|
-
envMap
|
|
442
|
+
environments?: EnvironmentIdentifier[] | null,
|
|
443
|
+
envMap?: Map<number, Environment> | null,
|
|
485
444
|
) {
|
|
486
445
|
return environments?.map((env) => {
|
|
487
446
|
return {
|
|
@@ -492,8 +451,8 @@ function enhanceEnvironments(
|
|
|
492
451
|
}
|
|
493
452
|
|
|
494
453
|
function enhanceLithologies(
|
|
495
|
-
lithologies
|
|
496
|
-
lithMap
|
|
454
|
+
lithologies?: LithologyIdentifier[] | null,
|
|
455
|
+
lithMap?: Map<number, any> | null,
|
|
497
456
|
) {
|
|
498
457
|
return lithologies?.map((lith) => {
|
|
499
458
|
return {
|
|
@@ -503,44 +462,6 @@ function enhanceLithologies(
|
|
|
503
462
|
});
|
|
504
463
|
}
|
|
505
464
|
|
|
506
|
-
export function ClickableText({
|
|
507
|
-
className,
|
|
508
|
-
...rest
|
|
509
|
-
}: {
|
|
510
|
-
className?: string;
|
|
511
|
-
children: ReactNode;
|
|
512
|
-
} & ItemInteractionProps) {
|
|
513
|
-
/** An optionally clickable text element */
|
|
514
|
-
const clickable = isClickable(rest);
|
|
515
|
-
const tag = clickable ? "a" : "span";
|
|
516
|
-
return h(tag, { className: classNames(className, { clickable }), ...rest });
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
export function Identifier({
|
|
520
|
-
id,
|
|
521
|
-
className,
|
|
522
|
-
...rest
|
|
523
|
-
}: {
|
|
524
|
-
id: number | string;
|
|
525
|
-
className?: string;
|
|
526
|
-
} & ItemInteractionProps) {
|
|
527
|
-
/** An item that displays a numeric identifier, optionally clickable */
|
|
528
|
-
return h(
|
|
529
|
-
ClickableText,
|
|
530
|
-
{
|
|
531
|
-
className: classNames("identifier", className),
|
|
532
|
-
...rest,
|
|
533
|
-
},
|
|
534
|
-
id,
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
type UnitInfo = {
|
|
539
|
-
unitID: number;
|
|
540
|
-
colID?: number;
|
|
541
|
-
name?: string;
|
|
542
|
-
};
|
|
543
|
-
|
|
544
465
|
function UnitIDList({ units, showNames = false }) {
|
|
545
466
|
const unitsMap = useColumnUnitsMap();
|
|
546
467
|
|
|
@@ -551,7 +472,7 @@ function UnitIDList({ units, showNames = false }) {
|
|
|
551
472
|
if (showNames) {
|
|
552
473
|
return u1.map((unitID) => {
|
|
553
474
|
const unitData = unitsMap?.get(unitID);
|
|
554
|
-
let name: string =
|
|
475
|
+
let name: string | null = null;
|
|
555
476
|
if (unitData != null) {
|
|
556
477
|
name = defaultNameFunction(unitData);
|
|
557
478
|
}
|
|
@@ -586,28 +507,3 @@ function UnitIDList({ units, showNames = false }) {
|
|
|
586
507
|
}),
|
|
587
508
|
);
|
|
588
509
|
}
|
|
589
|
-
|
|
590
|
-
function UnitIdentifier({
|
|
591
|
-
unitID,
|
|
592
|
-
colID,
|
|
593
|
-
name,
|
|
594
|
-
...interactionProps
|
|
595
|
-
}: UnitInfo & ItemInteractionProps) {
|
|
596
|
-
if (name != null) {
|
|
597
|
-
return h(
|
|
598
|
-
ClickableText,
|
|
599
|
-
{
|
|
600
|
-
className: "unit-name",
|
|
601
|
-
...interactionProps,
|
|
602
|
-
},
|
|
603
|
-
name,
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
return h(Identifier, {
|
|
608
|
-
className: "unit-id",
|
|
609
|
-
key: unitID,
|
|
610
|
-
id: unitID,
|
|
611
|
-
...interactionProps,
|
|
612
|
-
});
|
|
613
|
-
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import hyper from "@macrostrat/hyper";
|
|
2
2
|
import { Popover } from "@blueprintjs/core";
|
|
3
3
|
import styles from "./popover.module.sass";
|
|
4
|
-
import {
|
|
5
|
-
useAtomOverlayPosition,
|
|
6
|
-
useSelectedUnit,
|
|
7
|
-
useUnitSelectionDispatch,
|
|
8
|
-
} from "../data-provider";
|
|
4
|
+
import { useAtomOverlayPosition, useUnitSelection } from "../data-provider";
|
|
9
5
|
import {
|
|
10
6
|
UnitDetailsFeature,
|
|
11
7
|
UnitDetailsPanel,
|
|
@@ -66,8 +62,7 @@ function InteractionBarrier({ children }) {
|
|
|
66
62
|
export function UnitSelectionPopover(
|
|
67
63
|
props: Omit<UnitDetailsPanelProps, "onSelectUnit" | "unit">,
|
|
68
64
|
) {
|
|
69
|
-
const unit =
|
|
70
|
-
const selectUnit = useUnitSelectionDispatch();
|
|
65
|
+
const [unit, selectUnit] = useUnitSelection();
|
|
71
66
|
const position = useAtomOverlayPosition();
|
|
72
67
|
if (unit == null) {
|
|
73
68
|
return null;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataField,
|
|
3
|
+
isClickable,
|
|
4
|
+
ItemInteractionProps,
|
|
5
|
+
useInteractionProps,
|
|
6
|
+
} from "@macrostrat/data-components";
|
|
7
|
+
import h from "./panel.module.sass";
|
|
8
|
+
import classNames from "classnames";
|
|
9
|
+
import { useStratNames } from "@macrostrat/data-provider";
|
|
10
|
+
import { Identifier } from "./identifiers.ts";
|
|
11
|
+
|
|
12
|
+
function useStratNameData(strat_name_id: number) {
|
|
13
|
+
const stratNames = useStratNames([strat_name_id]);
|
|
14
|
+
return stratNames?.[0];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function StratNameField(
|
|
18
|
+
props: {
|
|
19
|
+
strat_name_id: number;
|
|
20
|
+
className?: string;
|
|
21
|
+
} & ItemInteractionProps,
|
|
22
|
+
) {
|
|
23
|
+
/** Handling for stratigraphic name field */
|
|
24
|
+
const { strat_name_id, className, ...rest } = props;
|
|
25
|
+
|
|
26
|
+
const data = useStratNameData(strat_name_id);
|
|
27
|
+
|
|
28
|
+
const baseInteractionProps = useInteractionProps({ strat_name_id });
|
|
29
|
+
|
|
30
|
+
const coreProps = {
|
|
31
|
+
...baseInteractionProps,
|
|
32
|
+
...rest,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let inner: any = h(Identifier, { id: strat_name_id });
|
|
36
|
+
const name = data?.strat_name_long;
|
|
37
|
+
if (name != null) {
|
|
38
|
+
inner = h("span.strat-name", name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const clickable = isClickable(coreProps);
|
|
42
|
+
|
|
43
|
+
return h(
|
|
44
|
+
DataField,
|
|
45
|
+
{
|
|
46
|
+
label: "Stratigraphic name",
|
|
47
|
+
},
|
|
48
|
+
h(
|
|
49
|
+
clickable ? "a" : "span",
|
|
50
|
+
{
|
|
51
|
+
className: classNames({ clickable }, className),
|
|
52
|
+
...coreProps,
|
|
53
|
+
},
|
|
54
|
+
inner,
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
}
|