@macrostrat/column-views 3.11.0 → 3.12.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 +169 -0
- package/dist/age-model/data.cjs +57 -0
- package/dist/age-model/data.cjs.map +1 -0
- package/dist/age-model/data.d.ts +29 -0
- package/dist/age-model/data.js +57 -0
- package/dist/age-model/data.js.map +1 -0
- package/dist/age-model/details.cjs +261 -0
- package/dist/age-model/details.cjs.map +1 -0
- package/dist/age-model/details.d.ts +39 -0
- package/dist/age-model/details.js +258 -0
- package/dist/age-model/details.js.map +1 -0
- package/dist/age-model/details.module.sass.cjs +42 -0
- package/dist/age-model/details.module.sass.cjs.map +1 -0
- package/dist/age-model/details.module.sass.js +40 -0
- package/dist/age-model/details.module.sass.js.map +1 -0
- package/dist/age-model/index.d.ts +5 -0
- package/dist/age-model/legacy.cjs +28 -0
- package/dist/age-model/legacy.cjs.map +1 -0
- package/dist/age-model/legacy.d.ts +6 -0
- package/dist/age-model/legacy.js +26 -0
- package/dist/age-model/legacy.js.map +1 -0
- package/dist/age-model/surfaces.cjs +355 -0
- package/dist/age-model/surfaces.cjs.map +1 -0
- package/dist/age-model/surfaces.d.ts +68 -0
- package/dist/age-model/surfaces.js +352 -0
- package/dist/age-model/surfaces.js.map +1 -0
- package/dist/age-model/surfaces.module.sass.cjs +45 -0
- package/dist/age-model/surfaces.module.sass.cjs.map +1 -0
- package/dist/age-model/surfaces.module.sass.js +43 -0
- package/dist/age-model/surfaces.module.sass.js.map +1 -0
- package/dist/age-model/types.cjs +229 -0
- package/dist/age-model/types.cjs.map +1 -0
- package/dist/age-model/types.d.ts +112 -0
- package/dist/age-model/types.js +229 -0
- package/dist/age-model/types.js.map +1 -0
- package/dist/column-views.css +389 -57
- package/dist/column.cjs +20 -13
- package/dist/column.cjs.map +1 -1
- package/dist/column.d.ts +21 -6
- package/dist/column.js +21 -14
- package/dist/column.js.map +1 -1
- package/dist/column.module.sass.cjs +19 -15
- package/dist/column.module.sass.cjs.map +1 -1
- package/dist/column.module.sass.js +19 -15
- package/dist/column.module.sass.js.map +1 -1
- package/dist/data-provider/store.cjs +34 -1
- package/dist/data-provider/store.cjs.map +1 -1
- package/dist/data-provider/store.d.ts +5 -0
- package/dist/data-provider/store.js +35 -2
- package/dist/data-provider/store.js.map +1 -1
- package/dist/index.cjs +54 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +54 -3
- package/dist/index.js.map +1 -1
- package/dist/notes.cjs +11 -2
- package/dist/notes.cjs.map +1 -1
- package/dist/notes.d.ts +11 -1
- package/dist/notes.js +11 -2
- package/dist/notes.js.map +1 -1
- package/dist/prepare-units/composite-scale.cjs +18 -16
- package/dist/prepare-units/composite-scale.cjs.map +1 -1
- package/dist/prepare-units/composite-scale.js +18 -16
- package/dist/prepare-units/composite-scale.js.map +1 -1
- package/dist/prepare-units/density.cjs +83 -0
- package/dist/prepare-units/density.cjs.map +1 -0
- package/dist/prepare-units/density.d.ts +92 -0
- package/dist/prepare-units/density.js +83 -0
- package/dist/prepare-units/density.js.map +1 -0
- package/dist/prepare-units/index.cjs +15 -7
- package/dist/prepare-units/index.cjs.map +1 -1
- package/dist/prepare-units/index.d.ts +1 -0
- package/dist/prepare-units/index.js +15 -7
- package/dist/prepare-units/index.js.map +1 -1
- package/dist/prepare-units/types.cjs.map +1 -1
- package/dist/prepare-units/types.d.ts +34 -13
- package/dist/prepare-units/types.js.map +1 -1
- package/dist/section.cjs +108 -24
- package/dist/section.cjs.map +1 -1
- package/dist/section.d.ts +66 -6
- package/dist/section.js +109 -25
- package/dist/section.js.map +1 -1
- package/dist/timescale-zoom.cjs +191 -0
- package/dist/timescale-zoom.cjs.map +1 -0
- package/dist/timescale-zoom.d.ts +74 -0
- package/dist/timescale-zoom.js +191 -0
- package/dist/timescale-zoom.js.map +1 -0
- package/dist/unit-details/age-range.cjs +1 -0
- package/dist/unit-details/age-range.cjs.map +1 -1
- package/dist/unit-details/age-range.d.ts +5 -1
- package/dist/unit-details/age-range.js +1 -0
- package/dist/unit-details/age-range.js.map +1 -1
- package/dist/units/composite.cjs +4 -1
- package/dist/units/composite.cjs.map +1 -1
- package/dist/units/composite.d.ts +2 -0
- package/dist/units/composite.js +4 -1
- package/dist/units/composite.js.map +1 -1
- package/package.json +7 -7
- package/src/age-model/data.ts +98 -0
- package/src/age-model/details.module.sass +108 -0
- package/src/age-model/details.ts +333 -0
- package/src/age-model/index.ts +5 -0
- package/src/age-model/legacy.ts +30 -0
- package/src/age-model/surfaces.module.sass +168 -0
- package/src/age-model/surfaces.ts +568 -0
- package/src/age-model/types.ts +392 -0
- package/src/column.module.sass +59 -8
- package/src/column.ts +49 -23
- package/src/data-provider/store.ts +50 -1
- package/src/index.ts +5 -1
- package/src/notes.ts +20 -2
- package/src/prepare-units/composite-scale.ts +34 -31
- package/src/prepare-units/density.ts +197 -0
- package/src/prepare-units/index.ts +25 -6
- package/src/prepare-units/types.ts +34 -13
- package/src/section.ts +219 -33
- package/src/timescale-zoom.ts +341 -0
- package/src/unit-details/age-range.ts +3 -3
- package/src/units/composite.ts +11 -0
- package/dist/age-model-overlay.cjs +0 -50
- package/dist/age-model-overlay.cjs.map +0 -1
- package/dist/age-model-overlay.d.ts +0 -24
- package/dist/age-model-overlay.js +0 -48
- package/dist/age-model-overlay.js.map +0 -1
- package/dist/age-model-overlay.module.sass.cjs +0 -12
- package/dist/age-model-overlay.module.sass.cjs.map +0 -1
- package/dist/age-model-overlay.module.sass.js +0 -11
- package/dist/age-model-overlay.module.sass.js.map +0 -1
- package/src/age-model-overlay.module.sass +0 -11
- package/src/age-model-overlay.ts +0 -96
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,174 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.12.0] - 2026-09-21 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.11.0...@macrostrat/column-views-v3.12.0)
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Reduce the options that set how tall a column draws to the few that say
|
|
8
|
+
[0614432f](https://github.com/UW-Macrostrat/web-components/commit/0614432fe94bfd2c222375b9add8f7ac100e33c3)
|
|
9
|
+
different things. They all resolve to one quantity — density, the pixels given
|
|
10
|
+
to one unit of the axis.
|
|
11
|
+
|
|
12
|
+
`targetUnitHeight` is the usual knob: room for a typical unit, now the
|
|
13
|
+
geometric mean of the visible units' extents rather than their arithmetic
|
|
14
|
+
mean, which a few long units skew far above anything on screen.
|
|
15
|
+
`minSectionHeight` and `minPixelScale` floor it for legibility. `pixelScale`
|
|
16
|
+
is the alternative: a density stated outright, which is then the density — the
|
|
17
|
+
floors no longer apply to it, since they would undo the scale you stated, and
|
|
18
|
+
`Column` no longer adjusts them behind the scenes. It is quoted in whatever
|
|
19
|
+
the axis measures, so `pixelsPerMyr` and `pixelsPerMeter` spell it per axis,
|
|
20
|
+
the way `t_age` and `t_pos` already do for the window: both can be held at
|
|
21
|
+
once and the axis picks, since useful values for the two differ by orders of
|
|
22
|
+
magnitude. `sectionOptions` decides any of these per section, given what the
|
|
23
|
+
section holds.
|
|
24
|
+
|
|
25
|
+
`heightMultiplier` is gone — asking for more room per unit is the same
|
|
26
|
+
control, and leaves the legibility floors where they belong — as is the
|
|
27
|
+
internal `visibleWindow`, which only restated `t_age`/`b_age`.
|
|
28
|
+
|
|
29
|
+
- Add a surfaces view for a column's age model. `ColumnSurfaces`, dropped into a
|
|
30
|
+
[ea700ff1](https://github.com/UW-Macrostrat/web-components/commit/ea700ff1e7725703d971e3cac440fad0f7540a65)
|
|
31
|
+
`Column` as a child, draws the column's calibration surfaces from the
|
|
32
|
+
`/age_model` route as lines across the units (`ColumnSurfaceLines`) and as a
|
|
33
|
+
collision-avoiding notes column of labels beside them (`ColumnSurfaceLabels`),
|
|
34
|
+
styled by `boundary_status` and `boundary_type`, with hover and selection.
|
|
35
|
+
Labels use the standard `IntervalTag` for the calibration interval (with the
|
|
36
|
+
position within it) over the modeled age, are drawn by default only for the
|
|
37
|
+
tie points where the age model was constrained (absolute, relative, spike,
|
|
38
|
+
imposed — `labelStatuses` widens this), and take the label column over from
|
|
39
|
+
the unit labels while mounted (`useClaimLabelColumn`, a new way for a column's
|
|
40
|
+
children to claim that space). `SurfaceDetailsPanel` inspects a selected
|
|
41
|
+
surface — model age, calibration interval and position within it, the units it
|
|
42
|
+
separates, provenance — and `SurfaceStatusLegend` explains the line styles.
|
|
43
|
+
|
|
44
|
+
The view is data-agnostic: `useColumnAgeModel` fetches boundaries through the
|
|
45
|
+
`MacrostratDataProvider` base URL (the old overlay hardcoded the dev server),
|
|
46
|
+
`surfacesFromBoundaries` maps them to `ColumnSurface` records, and
|
|
47
|
+
`surfacesFromUnits` derives surfaces from unit tops and bottoms as the
|
|
48
|
+
fallback for columns without `unit_boundaries` (or for an editor's own state).
|
|
49
|
+
`BoundaryAgeModelOverlay` and `ComputedSurfacesOverlay` remain as deprecated
|
|
50
|
+
wrappers. `ColumnNotes` gains `onClickNote` and `className` passthroughs.
|
|
51
|
+
|
|
52
|
+
`@macrostrat/api-types` gains `AgeModelBoundary` and the `BoundaryStatus` /
|
|
53
|
+
`BoundaryType` vocabularies, mirroring the database enums.
|
|
54
|
+
|
|
55
|
+
- Draw several timescales beside a column. A new `timescales` prop takes them in
|
|
56
|
+
[1b694ccf](https://github.com/UW-Macrostrat/web-components/commit/1b694ccfcc40321a6edc609b8c07106a87164a3b)
|
|
57
|
+
order, each a Macrostrat timescale ID or a timescale carrying its own
|
|
58
|
+
intervals, levels and label — the international timescale is one of these
|
|
59
|
+
rather than a special case. Clicks and per-interval styles report which
|
|
60
|
+
timescale they came from, so the same interval drawn in two of them can be
|
|
61
|
+
told apart, and `useTimescaleZoom` treats a click in another timescale as
|
|
62
|
+
moving the selection rather than zooming out. Timescales are fetched in one
|
|
63
|
+
place rather than once per section.
|
|
64
|
+
- Suppress unit labels below a pixel height, rather than labeling units too thin
|
|
65
|
+
[0614432f](https://github.com/UW-Macrostrat/web-components/commit/0614432fe94bfd2c222375b9add8f7ac100e33c3)
|
|
66
|
+
to see: `labelSuppressHeight` on `Column`, 2px by default. A gap between
|
|
67
|
+
sections is also labeled in the units of the axis, so a drill core reads
|
|
68
|
+
metres rather than Myr.
|
|
69
|
+
- One selection color across a column: `--column-selection-color` (the accent
|
|
70
|
+
[1b694ccf](https://github.com/UW-Macrostrat/web-components/commit/1b694ccfcc40321a6edc609b8c07106a87164a3b)
|
|
71
|
+
color, purple) drives both the unit selection overlay — now a box with an
|
|
72
|
+
outline and a light wash, rather than a heavy red fill — and the surface
|
|
73
|
+
selection.
|
|
74
|
+
|
|
75
|
+
Surface lines are drawn at a constant weight; status shows in the dash pattern
|
|
76
|
+
and color. A selected surface is outlined as a box, keeping its interval color
|
|
77
|
+
inside, and a selected label bolds its interval tag rather than sitting in a
|
|
78
|
+
card.
|
|
79
|
+
|
|
80
|
+
`useTimescaleZoom`: shift-clicking a timescale interval widens the window to
|
|
81
|
+
take it in, instead of moving the window to it. `selectedIntervals` reports
|
|
82
|
+
everything in the selection; all of them are styled as selected.
|
|
83
|
+
|
|
84
|
+
`CompositeTimescale` takes a `timescaleID` (which timescale the leveled column
|
|
85
|
+
draws) and `additionalTimescales` (further timescales drawn as extra level
|
|
86
|
+
columns beside it, against the same section scales), and is exported. `Column`
|
|
87
|
+
passes `additionalTimescales` through: narrow `timescaleLevels` by as many to
|
|
88
|
+
swap the finest international level for a regional one rather than widen the
|
|
89
|
+
timescale.
|
|
90
|
+
|
|
91
|
+
`heightMultiplier` on `Column` multiplies the heights the layout works out by
|
|
92
|
+
a fixed factor. The scaling approach is unchanged — density still comes from
|
|
93
|
+
`targetUnitHeight` and the section floors — so sections keep their proportions
|
|
94
|
+
and only the size changes; unconformity gaps and `windowPadding`, being chrome
|
|
95
|
+
rather than scale, stay put.
|
|
96
|
+
|
|
97
|
+
- Infer `relative` status for age-model surfaces that cannot have been
|
|
98
|
+
[c17e6379](https://github.com/UW-Macrostrat/web-components/commit/c17e637909bbff76f7bbf4366134b0ba5c5f59ef)
|
|
99
|
+
interpolated: those sitting on the base or top of their calibration interval,
|
|
100
|
+
and the edges of gap-bound packages (the youngest surface in a section with no
|
|
101
|
+
unit above, or the oldest with none below). `boundary_status` records many of
|
|
102
|
+
these as `modeled`, so filtering to the tie-point statuses was hiding real tie
|
|
103
|
+
points. `inferTiePointStatuses` promotes them client-side and marks the result
|
|
104
|
+
`statusInferred`, which `SurfaceStatusTag` shows. On by default;
|
|
105
|
+
`inferTiePoints: false` on `ColumnSurfaces`, `useColumnSurfaces` or
|
|
106
|
+
`surfacesFromBoundaries` takes the data as recorded.
|
|
107
|
+
|
|
108
|
+
Fix surface lines drifting out of alignment with the units column: the overlay
|
|
109
|
+
measured its position once and only re-measured on its own resize, so a
|
|
110
|
+
sibling changing width — the timescale, once its intervals load — left it
|
|
111
|
+
stale.
|
|
112
|
+
|
|
113
|
+
- Color age-model surfaces by the interval they are calibrated against: the
|
|
114
|
+
[acc9f478](https://github.com/UW-Macrostrat/web-components/commit/acc9f4782cbae65bfe017aa195e1b51456871822)
|
|
115
|
+
surface line and its label's leader line both take the interval's color, and
|
|
116
|
+
the lines are drawn a little heavier. The label's endpoint marker is gone —
|
|
117
|
+
the leader now runs into the surface line itself.
|
|
118
|
+
|
|
119
|
+
`SurfaceDetailsPanel` accepts a `null` surface and renders an empty state, so
|
|
120
|
+
a panel bound to a selection doesn't have to be guarded by its caller.
|
|
121
|
+
|
|
122
|
+
- Add `useTimescaleZoom`: click-to-zoom navigation over geologic time, extracted
|
|
123
|
+
[af6d14e1](https://github.com/UW-Macrostrat/web-components/commit/af6d14e1da59af8d09712ed5cb750b1b6bca7cc8)
|
|
124
|
+
from the Interval zoom story. Clicking a timescale interval animates the
|
|
125
|
+
rendered age window to it, clicking the interval you are in zooms back out a
|
|
126
|
+
level, and the timescale's level window slides with the selection so finer
|
|
127
|
+
intervals come into reach as you drill. `columnProps` spreads the window, the
|
|
128
|
+
levels, the click handler and the selected-interval styling onto a `Column`.
|
|
129
|
+
`unitsAgeExtent` derives the full extent from a set of units.
|
|
130
|
+
|
|
131
|
+
### Patch Changes
|
|
132
|
+
|
|
133
|
+
- Notes columns re-run their force layout once the notes' rendered heights have
|
|
134
|
+
[7252f222](https://github.com/UW-Macrostrat/web-components/commit/7252f22207f63d57ef91172cf898f6b27c38725a)
|
|
135
|
+
been measured. The first layout ran on a 10px guess per note and was never
|
|
136
|
+
revisited, so notes taller than that (interval tags, two-line labels)
|
|
137
|
+
overlapped their neighbors. `ColumnNotes` also passes `forceOptions` through
|
|
138
|
+
to the layout.
|
|
139
|
+
- Treat an unset age or depth bound as unbounded rather than as a real one. A
|
|
140
|
+
[0614432f](https://github.com/UW-Macrostrat/web-components/commit/0614432fe94bfd2c222375b9add8f7ac100e33c3)
|
|
141
|
+
`null` `t_age` is the ordinary way to say "no window" — it is what clearing a
|
|
142
|
+
window leaves behind — and columns laid out with a hybrid scale, which clip
|
|
143
|
+
before laying out, were dropping every unit when they saw one.
|
|
144
|
+
- Judge an unconformity against the finer of the two scales it falls between,
|
|
145
|
+
[aa4fda55](https://github.com/UW-Macrostrat/web-components/commit/aa4fda557137cdb652cb3ddce98d1b5dae8109ef)
|
|
146
|
+
rather than the coarser one. A gap has no density of its own, and taking the
|
|
147
|
+
smaller estimate let a sparse neighbor speak for one the other neighbor would
|
|
148
|
+
have drawn many times larger — a 16 Myr hiatus read as 26px against one
|
|
149
|
+
section and 166px against the other, and collapsed.
|
|
150
|
+
- Updated dependencies
|
|
151
|
+
[ea700ff1](https://github.com/UW-Macrostrat/web-components/commit/ea700ff1e7725703d971e3cac440fad0f7540a65)
|
|
152
|
+
- Updated dependencies
|
|
153
|
+
[1b694ccf](https://github.com/UW-Macrostrat/web-components/commit/1b694ccfcc40321a6edc609b8c07106a87164a3b)
|
|
154
|
+
- Updated dependencies
|
|
155
|
+
[1b694ccf](https://github.com/UW-Macrostrat/web-components/commit/1b694ccfcc40321a6edc609b8c07106a87164a3b)
|
|
156
|
+
- Updated dependencies
|
|
157
|
+
[acc9f478](https://github.com/UW-Macrostrat/web-components/commit/acc9f4782cbae65bfe017aa195e1b51456871822)
|
|
158
|
+
- Updated dependencies
|
|
159
|
+
[aa4fda55](https://github.com/UW-Macrostrat/web-components/commit/aa4fda557137cdb652cb3ddce98d1b5dae8109ef)
|
|
160
|
+
- Updated dependencies
|
|
161
|
+
[af6d14e1](https://github.com/UW-Macrostrat/web-components/commit/af6d14e1da59af8d09712ed5cb750b1b6bca7cc8)
|
|
162
|
+
- Updated dependencies
|
|
163
|
+
[7252f222](https://github.com/UW-Macrostrat/web-components/commit/7252f22207f63d57ef91172cf898f6b27c38725a)
|
|
164
|
+
- Updated dependencies
|
|
165
|
+
[1b694ccf](https://github.com/UW-Macrostrat/web-components/commit/1b694ccfcc40321a6edc609b8c07106a87164a3b)
|
|
166
|
+
- @macrostrat/api-types@1.4.0
|
|
167
|
+
- @macrostrat/data-provider@1.3.1
|
|
168
|
+
- @macrostrat/timescale@3.3.0
|
|
169
|
+
- @macrostrat/column-components@2.2.0
|
|
170
|
+
- @macrostrat/stratigraphy-utils@1.4.2
|
|
171
|
+
|
|
3
172
|
## [3.11.0] - 2026-09-04 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.10.0...@macrostrat/column-views-v3.11.0)
|
|
4
173
|
|
|
5
174
|
### Minor Changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const React = require("react");
|
|
4
|
+
const uiComponents = require("@macrostrat/ui-components");
|
|
5
|
+
const dataProvider = require("@macrostrat/data-provider");
|
|
6
|
+
const types = require("./types.cjs");
|
|
7
|
+
const store = require("../data-provider/store.cjs");
|
|
8
|
+
const AGE_MODEL_ROUTE = "/age_model";
|
|
9
|
+
function useColumnAgeModel(col_id) {
|
|
10
|
+
const baseURL = dataProvider.useMacrostratBaseURL();
|
|
11
|
+
const params = React.useMemo(() => ({ col_id }), [col_id]);
|
|
12
|
+
let route = null;
|
|
13
|
+
if (col_id != null) {
|
|
14
|
+
route = baseURL + AGE_MODEL_ROUTE;
|
|
15
|
+
}
|
|
16
|
+
return uiComponents.useAPIResult(route, params, unwrapAgeModel) ?? null;
|
|
17
|
+
}
|
|
18
|
+
function unwrapAgeModel(res) {
|
|
19
|
+
return res?.success?.data ?? [];
|
|
20
|
+
}
|
|
21
|
+
function useColumnSurfaces(options = {}) {
|
|
22
|
+
const {
|
|
23
|
+
surfaces: provided,
|
|
24
|
+
col_id,
|
|
25
|
+
fallbackToUnits = true,
|
|
26
|
+
inferTiePoints = true
|
|
27
|
+
} = options;
|
|
28
|
+
const units = store.useMacrostratUnits();
|
|
29
|
+
const { axisType } = store.useMacrostratColumnData();
|
|
30
|
+
let fetchID = null;
|
|
31
|
+
if (provided == null) {
|
|
32
|
+
fetchID = col_id ?? units?.[0]?.col_id ?? null;
|
|
33
|
+
}
|
|
34
|
+
const boundaries = useColumnAgeModel(fetchID);
|
|
35
|
+
const fromAgeModel = React.useMemo(
|
|
36
|
+
() => types.surfacesFromBoundaries(boundaries, { inferTiePoints }),
|
|
37
|
+
[boundaries, inferTiePoints]
|
|
38
|
+
);
|
|
39
|
+
const derived = React.useMemo(() => {
|
|
40
|
+
if (!fallbackToUnits) return [];
|
|
41
|
+
return types.surfacesFromUnits(units, { axisType });
|
|
42
|
+
}, [units, axisType, fallbackToUnits]);
|
|
43
|
+
if (provided != null) {
|
|
44
|
+
return { surfaces: provided, source: "provided" };
|
|
45
|
+
}
|
|
46
|
+
if (fetchID != null && boundaries == null) {
|
|
47
|
+
return { surfaces: [], source: "loading" };
|
|
48
|
+
}
|
|
49
|
+
if (fromAgeModel.length > 0) {
|
|
50
|
+
return { surfaces: fromAgeModel, source: "age-model" };
|
|
51
|
+
}
|
|
52
|
+
return { surfaces: derived, source: "derived" };
|
|
53
|
+
}
|
|
54
|
+
exports.AGE_MODEL_ROUTE = AGE_MODEL_ROUTE;
|
|
55
|
+
exports.useColumnAgeModel = useColumnAgeModel;
|
|
56
|
+
exports.useColumnSurfaces = useColumnSurfaces;
|
|
57
|
+
//# sourceMappingURL=data.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.cjs","sources":["../../src/age-model/data.ts"],"sourcesContent":["/** Data hooks for a column's age model. */\nimport { useMemo } from \"react\";\nimport { useAPIResult } from \"@macrostrat/ui-components\";\nimport { useMacrostratBaseURL } from \"@macrostrat/data-provider\";\nimport type { UnitLong } from \"@macrostrat/api-types\";\nimport { useMacrostratColumnData, useMacrostratUnits } from \"../data-provider\";\nimport {\n type AgeModelBoundary,\n type ColumnSurface,\n surfacesFromBoundaries,\n surfacesFromUnits,\n} from \"./types\";\n\nexport const AGE_MODEL_ROUTE = \"/age_model\";\n\n/** The age-model boundaries of a column, from `/age_model?col_id=` on the\n * API the enclosing `MacrostratDataProvider` points at (production when there\n * is none). `null` while loading or when `col_id` is not set. */\nexport function useColumnAgeModel(\n col_id: number | null | undefined,\n): AgeModelBoundary[] | null {\n const baseURL = useMacrostratBaseURL();\n const params = useMemo(() => ({ col_id }), [col_id]);\n let route: string | null = null;\n if (col_id != null) {\n route = baseURL + AGE_MODEL_ROUTE;\n }\n return useAPIResult(route, params, unwrapAgeModel) ?? null;\n}\n\nfunction unwrapAgeModel(res: any): AgeModelBoundary[] {\n return res?.success?.data ?? [];\n}\n\n/** Where a column's surfaces came from */\nexport type SurfacesSource = \"provided\" | \"age-model\" | \"derived\" | \"loading\";\n\nexport interface UseColumnSurfacesOptions {\n /** Surfaces to show. When given, nothing is fetched. */\n surfaces?: ColumnSurface[] | null;\n /** The column whose age model to fetch. Defaults to the column being\n * rendered (read from its units). */\n col_id?: number | null;\n /** When the age model has no boundaries, derive surfaces from the units\n * instead (default `true`). */\n fallbackToUnits?: boolean;\n /** Promote `modeled` surfaces that must in fact constrain the age model to\n * `relative` (default `true`) — see `inferTiePointStatuses`. */\n inferTiePoints?: boolean;\n}\n\nexport interface ColumnSurfacesData {\n surfaces: ColumnSurface[];\n source: SurfacesSource;\n}\n\n/** Resolve the surfaces to show for the enclosing `Column`: the ones passed\n * in, else the column's age model, else (optionally) surfaces derived from\n * its units. Must be used inside a `Column`. */\nexport function useColumnSurfaces(\n options: UseColumnSurfacesOptions = {},\n): ColumnSurfacesData {\n const {\n surfaces: provided,\n col_id,\n fallbackToUnits = true,\n inferTiePoints = true,\n } = options;\n const units = useMacrostratUnits() as UnitLong[] | undefined;\n const { axisType } = useMacrostratColumnData();\n\n let fetchID: number | null = null;\n if (provided == null) {\n fetchID = col_id ?? units?.[0]?.col_id ?? null;\n }\n const boundaries = useColumnAgeModel(fetchID);\n\n const fromAgeModel = useMemo(\n () => surfacesFromBoundaries(boundaries, { inferTiePoints }),\n [boundaries, inferTiePoints],\n );\n\n const derived = useMemo(() => {\n if (!fallbackToUnits) return [];\n return surfacesFromUnits(units, { axisType });\n }, [units, axisType, fallbackToUnits]);\n\n if (provided != null) {\n return { surfaces: provided, source: \"provided\" };\n }\n if (fetchID != null && boundaries == null) {\n return { surfaces: [], source: \"loading\" };\n }\n if (fromAgeModel.length > 0) {\n return { surfaces: fromAgeModel, source: \"age-model\" };\n }\n return { surfaces: derived, source: \"derived\" };\n}\n"],"names":["useMacrostratBaseURL","useMemo","useAPIResult","useMacrostratUnits","useMacrostratColumnData","surfacesFromBoundaries","surfacesFromUnits"],"mappings":";;;;;;;AAaO,MAAM,kBAAkB;AAKxB,SAAS,kBACd,QAC2B;AAC3B,QAAM,UAAUA,aAAAA,qBAAA;AAChB,QAAM,SAASC,MAAAA,QAAQ,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;AACnD,MAAI,QAAuB;AAC3B,MAAI,UAAU,MAAM;AAClB,YAAQ,UAAU;AAAA,EACpB;AACA,SAAOC,aAAAA,aAAa,OAAO,QAAQ,cAAc,KAAK;AACxD;AAEA,SAAS,eAAe,KAA8B;AACpD,SAAO,KAAK,SAAS,QAAQ,CAAA;AAC/B;AA2BO,SAAS,kBACd,UAAoC,IAChB;AACpB,QAAM;AAAA,IACJ,UAAU;AAAA,IACV;AAAA,IACA,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EAAA,IACf;AACJ,QAAM,QAAQC,MAAAA,mBAAA;AACd,QAAM,EAAE,SAAA,IAAaC,8BAAA;AAErB,MAAI,UAAyB;AAC7B,MAAI,YAAY,MAAM;AACpB,cAAU,UAAU,QAAQ,CAAC,GAAG,UAAU;AAAA,EAC5C;AACA,QAAM,aAAa,kBAAkB,OAAO;AAE5C,QAAM,eAAeH,MAAAA;AAAAA,IACnB,MAAMI,6BAAuB,YAAY,EAAE,gBAAgB;AAAA,IAC3D,CAAC,YAAY,cAAc;AAAA,EAAA;AAG7B,QAAM,UAAUJ,MAAAA,QAAQ,MAAM;AAC5B,QAAI,CAAC,gBAAiB,QAAO,CAAA;AAC7B,WAAOK,wBAAkB,OAAO,EAAE,UAAU;AAAA,EAC9C,GAAG,CAAC,OAAO,UAAU,eAAe,CAAC;AAErC,MAAI,YAAY,MAAM;AACpB,WAAO,EAAE,UAAU,UAAU,QAAQ,WAAA;AAAA,EACvC;AACA,MAAI,WAAW,QAAQ,cAAc,MAAM;AACzC,WAAO,EAAE,UAAU,IAAI,QAAQ,UAAA;AAAA,EACjC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,EAAE,UAAU,cAAc,QAAQ,YAAA;AAAA,EAC3C;AACA,SAAO,EAAE,UAAU,SAAS,QAAQ,UAAA;AACtC;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AgeModelBoundary, ColumnSurface } from './types';
|
|
2
|
+
export declare const AGE_MODEL_ROUTE = "/age_model";
|
|
3
|
+
/** The age-model boundaries of a column, from `/age_model?col_id=` on the
|
|
4
|
+
* API the enclosing `MacrostratDataProvider` points at (production when there
|
|
5
|
+
* is none). `null` while loading or when `col_id` is not set. */
|
|
6
|
+
export declare function useColumnAgeModel(col_id: number | null | undefined): AgeModelBoundary[] | null;
|
|
7
|
+
/** Where a column's surfaces came from */
|
|
8
|
+
export type SurfacesSource = "provided" | "age-model" | "derived" | "loading";
|
|
9
|
+
export interface UseColumnSurfacesOptions {
|
|
10
|
+
/** Surfaces to show. When given, nothing is fetched. */
|
|
11
|
+
surfaces?: ColumnSurface[] | null;
|
|
12
|
+
/** The column whose age model to fetch. Defaults to the column being
|
|
13
|
+
* rendered (read from its units). */
|
|
14
|
+
col_id?: number | null;
|
|
15
|
+
/** When the age model has no boundaries, derive surfaces from the units
|
|
16
|
+
* instead (default `true`). */
|
|
17
|
+
fallbackToUnits?: boolean;
|
|
18
|
+
/** Promote `modeled` surfaces that must in fact constrain the age model to
|
|
19
|
+
* `relative` (default `true`) — see `inferTiePointStatuses`. */
|
|
20
|
+
inferTiePoints?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ColumnSurfacesData {
|
|
23
|
+
surfaces: ColumnSurface[];
|
|
24
|
+
source: SurfacesSource;
|
|
25
|
+
}
|
|
26
|
+
/** Resolve the surfaces to show for the enclosing `Column`: the ones passed
|
|
27
|
+
* in, else the column's age model, else (optionally) surfaces derived from
|
|
28
|
+
* its units. Must be used inside a `Column`. */
|
|
29
|
+
export declare function useColumnSurfaces(options?: UseColumnSurfacesOptions): ColumnSurfacesData;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useAPIResult } from "@macrostrat/ui-components";
|
|
3
|
+
import { useMacrostratBaseURL } from "@macrostrat/data-provider";
|
|
4
|
+
import { surfacesFromBoundaries, surfacesFromUnits } from "./types.js";
|
|
5
|
+
import { useMacrostratUnits, useMacrostratColumnData } from "../data-provider/store.js";
|
|
6
|
+
const AGE_MODEL_ROUTE = "/age_model";
|
|
7
|
+
function useColumnAgeModel(col_id) {
|
|
8
|
+
const baseURL = useMacrostratBaseURL();
|
|
9
|
+
const params = useMemo(() => ({ col_id }), [col_id]);
|
|
10
|
+
let route = null;
|
|
11
|
+
if (col_id != null) {
|
|
12
|
+
route = baseURL + AGE_MODEL_ROUTE;
|
|
13
|
+
}
|
|
14
|
+
return useAPIResult(route, params, unwrapAgeModel) ?? null;
|
|
15
|
+
}
|
|
16
|
+
function unwrapAgeModel(res) {
|
|
17
|
+
return res?.success?.data ?? [];
|
|
18
|
+
}
|
|
19
|
+
function useColumnSurfaces(options = {}) {
|
|
20
|
+
const {
|
|
21
|
+
surfaces: provided,
|
|
22
|
+
col_id,
|
|
23
|
+
fallbackToUnits = true,
|
|
24
|
+
inferTiePoints = true
|
|
25
|
+
} = options;
|
|
26
|
+
const units = useMacrostratUnits();
|
|
27
|
+
const { axisType } = useMacrostratColumnData();
|
|
28
|
+
let fetchID = null;
|
|
29
|
+
if (provided == null) {
|
|
30
|
+
fetchID = col_id ?? units?.[0]?.col_id ?? null;
|
|
31
|
+
}
|
|
32
|
+
const boundaries = useColumnAgeModel(fetchID);
|
|
33
|
+
const fromAgeModel = useMemo(
|
|
34
|
+
() => surfacesFromBoundaries(boundaries, { inferTiePoints }),
|
|
35
|
+
[boundaries, inferTiePoints]
|
|
36
|
+
);
|
|
37
|
+
const derived = useMemo(() => {
|
|
38
|
+
if (!fallbackToUnits) return [];
|
|
39
|
+
return surfacesFromUnits(units, { axisType });
|
|
40
|
+
}, [units, axisType, fallbackToUnits]);
|
|
41
|
+
if (provided != null) {
|
|
42
|
+
return { surfaces: provided, source: "provided" };
|
|
43
|
+
}
|
|
44
|
+
if (fetchID != null && boundaries == null) {
|
|
45
|
+
return { surfaces: [], source: "loading" };
|
|
46
|
+
}
|
|
47
|
+
if (fromAgeModel.length > 0) {
|
|
48
|
+
return { surfaces: fromAgeModel, source: "age-model" };
|
|
49
|
+
}
|
|
50
|
+
return { surfaces: derived, source: "derived" };
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
AGE_MODEL_ROUTE,
|
|
54
|
+
useColumnAgeModel,
|
|
55
|
+
useColumnSurfaces
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sources":["../../src/age-model/data.ts"],"sourcesContent":["/** Data hooks for a column's age model. */\nimport { useMemo } from \"react\";\nimport { useAPIResult } from \"@macrostrat/ui-components\";\nimport { useMacrostratBaseURL } from \"@macrostrat/data-provider\";\nimport type { UnitLong } from \"@macrostrat/api-types\";\nimport { useMacrostratColumnData, useMacrostratUnits } from \"../data-provider\";\nimport {\n type AgeModelBoundary,\n type ColumnSurface,\n surfacesFromBoundaries,\n surfacesFromUnits,\n} from \"./types\";\n\nexport const AGE_MODEL_ROUTE = \"/age_model\";\n\n/** The age-model boundaries of a column, from `/age_model?col_id=` on the\n * API the enclosing `MacrostratDataProvider` points at (production when there\n * is none). `null` while loading or when `col_id` is not set. */\nexport function useColumnAgeModel(\n col_id: number | null | undefined,\n): AgeModelBoundary[] | null {\n const baseURL = useMacrostratBaseURL();\n const params = useMemo(() => ({ col_id }), [col_id]);\n let route: string | null = null;\n if (col_id != null) {\n route = baseURL + AGE_MODEL_ROUTE;\n }\n return useAPIResult(route, params, unwrapAgeModel) ?? null;\n}\n\nfunction unwrapAgeModel(res: any): AgeModelBoundary[] {\n return res?.success?.data ?? [];\n}\n\n/** Where a column's surfaces came from */\nexport type SurfacesSource = \"provided\" | \"age-model\" | \"derived\" | \"loading\";\n\nexport interface UseColumnSurfacesOptions {\n /** Surfaces to show. When given, nothing is fetched. */\n surfaces?: ColumnSurface[] | null;\n /** The column whose age model to fetch. Defaults to the column being\n * rendered (read from its units). */\n col_id?: number | null;\n /** When the age model has no boundaries, derive surfaces from the units\n * instead (default `true`). */\n fallbackToUnits?: boolean;\n /** Promote `modeled` surfaces that must in fact constrain the age model to\n * `relative` (default `true`) — see `inferTiePointStatuses`. */\n inferTiePoints?: boolean;\n}\n\nexport interface ColumnSurfacesData {\n surfaces: ColumnSurface[];\n source: SurfacesSource;\n}\n\n/** Resolve the surfaces to show for the enclosing `Column`: the ones passed\n * in, else the column's age model, else (optionally) surfaces derived from\n * its units. Must be used inside a `Column`. */\nexport function useColumnSurfaces(\n options: UseColumnSurfacesOptions = {},\n): ColumnSurfacesData {\n const {\n surfaces: provided,\n col_id,\n fallbackToUnits = true,\n inferTiePoints = true,\n } = options;\n const units = useMacrostratUnits() as UnitLong[] | undefined;\n const { axisType } = useMacrostratColumnData();\n\n let fetchID: number | null = null;\n if (provided == null) {\n fetchID = col_id ?? units?.[0]?.col_id ?? null;\n }\n const boundaries = useColumnAgeModel(fetchID);\n\n const fromAgeModel = useMemo(\n () => surfacesFromBoundaries(boundaries, { inferTiePoints }),\n [boundaries, inferTiePoints],\n );\n\n const derived = useMemo(() => {\n if (!fallbackToUnits) return [];\n return surfacesFromUnits(units, { axisType });\n }, [units, axisType, fallbackToUnits]);\n\n if (provided != null) {\n return { surfaces: provided, source: \"provided\" };\n }\n if (fetchID != null && boundaries == null) {\n return { surfaces: [], source: \"loading\" };\n }\n if (fromAgeModel.length > 0) {\n return { surfaces: fromAgeModel, source: \"age-model\" };\n }\n return { surfaces: derived, source: \"derived\" };\n}\n"],"names":[],"mappings":";;;;;AAaO,MAAM,kBAAkB;AAKxB,SAAS,kBACd,QAC2B;AAC3B,QAAM,UAAU,qBAAA;AAChB,QAAM,SAAS,QAAQ,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;AACnD,MAAI,QAAuB;AAC3B,MAAI,UAAU,MAAM;AAClB,YAAQ,UAAU;AAAA,EACpB;AACA,SAAO,aAAa,OAAO,QAAQ,cAAc,KAAK;AACxD;AAEA,SAAS,eAAe,KAA8B;AACpD,SAAO,KAAK,SAAS,QAAQ,CAAA;AAC/B;AA2BO,SAAS,kBACd,UAAoC,IAChB;AACpB,QAAM;AAAA,IACJ,UAAU;AAAA,IACV;AAAA,IACA,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EAAA,IACf;AACJ,QAAM,QAAQ,mBAAA;AACd,QAAM,EAAE,SAAA,IAAa,wBAAA;AAErB,MAAI,UAAyB;AAC7B,MAAI,YAAY,MAAM;AACpB,cAAU,UAAU,QAAQ,CAAC,GAAG,UAAU;AAAA,EAC5C;AACA,QAAM,aAAa,kBAAkB,OAAO;AAE5C,QAAM,eAAe;AAAA,IACnB,MAAM,uBAAuB,YAAY,EAAE,gBAAgB;AAAA,IAC3D,CAAC,YAAY,cAAc;AAAA,EAAA;AAG7B,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,CAAC,gBAAiB,QAAO,CAAA;AAC7B,WAAO,kBAAkB,OAAO,EAAE,UAAU;AAAA,EAC9C,GAAG,CAAC,OAAO,UAAU,eAAe,CAAC;AAErC,MAAI,YAAY,MAAM;AACpB,WAAO,EAAE,UAAU,UAAU,QAAQ,WAAA;AAAA,EACvC;AACA,MAAI,WAAW,QAAQ,cAAc,MAAM;AACzC,WAAO,EAAE,UAAU,IAAI,QAAQ,UAAA;AAAA,EACjC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,EAAE,UAAU,cAAc,QAAQ,YAAA;AAAA,EAC3C;AACA,SAAO,EAAE,UAAU,SAAS,QAAQ,UAAA;AACtC;"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const h$1 = require("@macrostrat/hyper");
|
|
4
|
+
const classNames = require("classnames");
|
|
5
|
+
const React = require("react");
|
|
6
|
+
const core = require("@blueprintjs/core");
|
|
7
|
+
const dataComponents = require("@macrostrat/data-components");
|
|
8
|
+
const dataProvider = require("@macrostrat/data-provider");
|
|
9
|
+
const ageRange = require("../unit-details/age-range.cjs");
|
|
10
|
+
const panel = require("../unit-details/panel.cjs");
|
|
11
|
+
const surfaces = require("./surfaces.cjs");
|
|
12
|
+
const surfaces_module = require("./surfaces.module.sass.cjs");
|
|
13
|
+
const details_module = require("./details.module.sass.cjs");
|
|
14
|
+
const types = require("./types.cjs");
|
|
15
|
+
const store = require("../data-provider/store.cjs");
|
|
16
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
17
|
+
const h__default = /* @__PURE__ */ _interopDefault(h$1);
|
|
18
|
+
const classNames__default = /* @__PURE__ */ _interopDefault(classNames);
|
|
19
|
+
const h = h__default.default.styled({ ...surfaces_module.default, ...details_module.default });
|
|
20
|
+
function SurfaceDetailsPanel(props) {
|
|
21
|
+
const {
|
|
22
|
+
surface,
|
|
23
|
+
onClose,
|
|
24
|
+
onSelectUnit,
|
|
25
|
+
actions,
|
|
26
|
+
positionLabel = "Position",
|
|
27
|
+
className
|
|
28
|
+
} = props;
|
|
29
|
+
if (surface == null) {
|
|
30
|
+
return h(
|
|
31
|
+
"div.surface-details-panel.no-surface",
|
|
32
|
+
{ className },
|
|
33
|
+
h("p.placeholder", "No surface selected.")
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
let closeButton = null;
|
|
37
|
+
if (onClose != null) {
|
|
38
|
+
closeButton = h(core.Button, {
|
|
39
|
+
icon: "cross",
|
|
40
|
+
variant: "minimal",
|
|
41
|
+
size: "small",
|
|
42
|
+
onClick: onClose,
|
|
43
|
+
"aria-label": "Close"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
let positionField = null;
|
|
47
|
+
if (surface.position != null) {
|
|
48
|
+
positionField = h(dataComponents.DataField, {
|
|
49
|
+
label: positionLabel,
|
|
50
|
+
value: surface.position.toLocaleString("en-US", {
|
|
51
|
+
maximumFractionDigits: 2
|
|
52
|
+
}),
|
|
53
|
+
unit: "m"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
let sectionField = null;
|
|
57
|
+
if (surface.section_id != null) {
|
|
58
|
+
sectionField = h(
|
|
59
|
+
dataComponents.DataField,
|
|
60
|
+
{ label: "Section" },
|
|
61
|
+
h(dataComponents.Identifier, { id: surface.section_id })
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
let refsField = null;
|
|
65
|
+
if (surface.ref_id != null) {
|
|
66
|
+
refsField = h(panel.ReferencesField, { refs: [surface.ref_id] });
|
|
67
|
+
}
|
|
68
|
+
return h(
|
|
69
|
+
"div.surface-details-panel",
|
|
70
|
+
{ className: classNames__default.default(className, surfaces.surfaceClasses(surface)) },
|
|
71
|
+
[
|
|
72
|
+
h("div.surface-details-header", [
|
|
73
|
+
h("h3.surface-details-title", [
|
|
74
|
+
"Surface ",
|
|
75
|
+
h(SurfaceIdentifier, { id: surface.id })
|
|
76
|
+
]),
|
|
77
|
+
h("div.surface-details-tags", [
|
|
78
|
+
h(SurfaceStatusTag, {
|
|
79
|
+
status: surface.status,
|
|
80
|
+
inferred: surface.statusInferred
|
|
81
|
+
}),
|
|
82
|
+
h(SurfaceTypeTag, { type: surface.type })
|
|
83
|
+
]),
|
|
84
|
+
h("div.spacer"),
|
|
85
|
+
actions,
|
|
86
|
+
closeButton
|
|
87
|
+
]),
|
|
88
|
+
h("div.surface-details-content", [
|
|
89
|
+
h(dataComponents.DataField, { label: "Model age" }, h(ageRange.AgeLabel, { age: surface.age })),
|
|
90
|
+
h(SurfaceCalibrationField, { surface }),
|
|
91
|
+
positionField,
|
|
92
|
+
h(SurfaceUnitsField, {
|
|
93
|
+
label: "Unit above",
|
|
94
|
+
unitIDs: surface.unitsAbove,
|
|
95
|
+
onSelectUnit
|
|
96
|
+
}),
|
|
97
|
+
h(SurfaceUnitsField, {
|
|
98
|
+
label: "Unit below",
|
|
99
|
+
unitIDs: surface.unitsBelow,
|
|
100
|
+
onSelectUnit
|
|
101
|
+
}),
|
|
102
|
+
sectionField,
|
|
103
|
+
refsField
|
|
104
|
+
])
|
|
105
|
+
]
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function SurfaceIdentifier({ id }) {
|
|
109
|
+
if (typeof id === "number") {
|
|
110
|
+
return h(dataComponents.Identifier, { id });
|
|
111
|
+
}
|
|
112
|
+
return h("code.surface-id", String(id));
|
|
113
|
+
}
|
|
114
|
+
function SurfaceCalibrationField({ surface }) {
|
|
115
|
+
const { calibration, proportion } = surface;
|
|
116
|
+
const ids = React.useMemo(() => {
|
|
117
|
+
if (calibration == null) return [];
|
|
118
|
+
return [calibration.id];
|
|
119
|
+
}, [calibration?.id]);
|
|
120
|
+
const intervalMap = dataProvider.useMacrostratDefs("intervals", ids, null);
|
|
121
|
+
if (calibration == null) {
|
|
122
|
+
return h(dataComponents.DataField, {
|
|
123
|
+
label: "Calibration",
|
|
124
|
+
value: "None",
|
|
125
|
+
className: "no-calibration"
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const def = intervalMap?.get(calibration.id);
|
|
129
|
+
const interval = {
|
|
130
|
+
id: calibration.id,
|
|
131
|
+
name: calibration.name,
|
|
132
|
+
b_age: calibration.b_age,
|
|
133
|
+
t_age: calibration.t_age,
|
|
134
|
+
color: def?.color,
|
|
135
|
+
rank: def?.rank
|
|
136
|
+
};
|
|
137
|
+
return h(dataComponents.DataField, { label: "Calibration" }, [
|
|
138
|
+
h(
|
|
139
|
+
"div.calibration-interval",
|
|
140
|
+
h(dataComponents.IntervalTag, {
|
|
141
|
+
interval,
|
|
142
|
+
prefix: h(ageRange.Proportion, { value: proportion })
|
|
143
|
+
})
|
|
144
|
+
)
|
|
145
|
+
]);
|
|
146
|
+
}
|
|
147
|
+
function SurfaceUnitsField({
|
|
148
|
+
label,
|
|
149
|
+
unitIDs,
|
|
150
|
+
onSelectUnit
|
|
151
|
+
}) {
|
|
152
|
+
const unitsMap = store.useColumnUnitsMap();
|
|
153
|
+
if (unitIDs.length === 0) {
|
|
154
|
+
return h(dataComponents.DataField, { label, value: "None", className: "no-units" });
|
|
155
|
+
}
|
|
156
|
+
return h(
|
|
157
|
+
dataComponents.DataField,
|
|
158
|
+
{ label, className: "surface-units-field" },
|
|
159
|
+
h(
|
|
160
|
+
"ul.surface-units-list",
|
|
161
|
+
unitIDs.map((unitID) => {
|
|
162
|
+
const unit = unitsMap?.get(unitID);
|
|
163
|
+
let onClick = void 0;
|
|
164
|
+
if (onSelectUnit != null) {
|
|
165
|
+
onClick = () => onSelectUnit(unitID);
|
|
166
|
+
}
|
|
167
|
+
return h(
|
|
168
|
+
"li",
|
|
169
|
+
{ key: unitID },
|
|
170
|
+
h(dataComponents.UnitIdentifier, {
|
|
171
|
+
unitID,
|
|
172
|
+
colID: unit?.col_id,
|
|
173
|
+
name: unit?.unit_name,
|
|
174
|
+
onClick
|
|
175
|
+
})
|
|
176
|
+
);
|
|
177
|
+
})
|
|
178
|
+
)
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
function SurfaceStatusTag({
|
|
182
|
+
status,
|
|
183
|
+
inferred = false,
|
|
184
|
+
className
|
|
185
|
+
}) {
|
|
186
|
+
let label = types.surfaceStatusLabels[status] ?? status;
|
|
187
|
+
let title = types.surfaceStatusDescriptions[status];
|
|
188
|
+
if (inferred) {
|
|
189
|
+
label = [label, h("span.inferred-marker", "*")];
|
|
190
|
+
title = INFERRED_STATUS_DESCRIPTION;
|
|
191
|
+
}
|
|
192
|
+
return h(
|
|
193
|
+
core.Tag,
|
|
194
|
+
{
|
|
195
|
+
variant: "minimal",
|
|
196
|
+
className: classNames__default.default(
|
|
197
|
+
"surface-tag",
|
|
198
|
+
className,
|
|
199
|
+
surfaces.surfaceClasses({ status }),
|
|
200
|
+
{ inferred }
|
|
201
|
+
),
|
|
202
|
+
title
|
|
203
|
+
},
|
|
204
|
+
label
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
const INFERRED_STATUS_DESCRIPTION = "Recorded as modeled, but this surface cannot have been interpolated — it sits on the base or top of its interval, or is the edge of a gap-bound package — so it constrains the age model rather than falling out of it";
|
|
208
|
+
function SurfaceTypeTag({
|
|
209
|
+
type,
|
|
210
|
+
className
|
|
211
|
+
}) {
|
|
212
|
+
if (type == null || type === "") return null;
|
|
213
|
+
return h(
|
|
214
|
+
core.Tag,
|
|
215
|
+
{
|
|
216
|
+
variant: "minimal",
|
|
217
|
+
className: classNames__default.default("surface-tag", "surface-type-tag", className)
|
|
218
|
+
},
|
|
219
|
+
type
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
function SurfaceStatusLegend(props) {
|
|
223
|
+
const {
|
|
224
|
+
statuses = types.surfaceStatuses,
|
|
225
|
+
showDescriptions = false,
|
|
226
|
+
className
|
|
227
|
+
} = props;
|
|
228
|
+
return h(
|
|
229
|
+
"ul.surface-status-legend",
|
|
230
|
+
{
|
|
231
|
+
className: classNames__default.default(className, {
|
|
232
|
+
"with-descriptions": showDescriptions
|
|
233
|
+
})
|
|
234
|
+
},
|
|
235
|
+
statuses.map((status) => {
|
|
236
|
+
let description = null;
|
|
237
|
+
if (showDescriptions) {
|
|
238
|
+
description = h(
|
|
239
|
+
"div.legend-description",
|
|
240
|
+
types.surfaceStatusDescriptions[status]
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
return h(
|
|
244
|
+
"li.legend-item",
|
|
245
|
+
{ key: status, className: surfaces.surfaceClasses({ status }) },
|
|
246
|
+
[
|
|
247
|
+
h("div.surface-label-marker"),
|
|
248
|
+
h("div.legend-text", [
|
|
249
|
+
h("div.legend-label", types.surfaceStatusLabels[status]),
|
|
250
|
+
description
|
|
251
|
+
])
|
|
252
|
+
]
|
|
253
|
+
);
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
exports.SurfaceDetailsPanel = SurfaceDetailsPanel;
|
|
258
|
+
exports.SurfaceStatusLegend = SurfaceStatusLegend;
|
|
259
|
+
exports.SurfaceStatusTag = SurfaceStatusTag;
|
|
260
|
+
exports.SurfaceTypeTag = SurfaceTypeTag;
|
|
261
|
+
//# sourceMappingURL=details.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"details.cjs","sources":["../../src/age-model/details.ts"],"sourcesContent":["/** The inspector for a selected surface, and the small tags and legend that\n * explain surface statuses and types. */\nimport hyper from \"@macrostrat/hyper\";\nimport classNames from \"classnames\";\nimport { type ReactNode, useMemo } from \"react\";\nimport { Button, Tag } from \"@blueprintjs/core\";\nimport {\n DataField,\n Identifier,\n type IntervalShort,\n IntervalTag,\n UnitIdentifier,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useMacrostratDefs } from \"@macrostrat/data-provider\";\nimport type { UnitLong } from \"@macrostrat/api-types\";\nimport { useColumnUnitsMap } from \"../data-provider\";\nimport { AgeLabel, Proportion } from \"../unit-details/age-range\";\nimport { formatRange } from \"../unit-details/utils\";\nimport { ReferencesField } from \"../unit-details/panel\";\nimport { surfaceClasses } from \"./surfaces\";\nimport surfaceStyles from \"./surfaces.module.sass\";\nimport styles from \"./details.module.sass\";\nimport {\n type BoundaryType,\n type ColumnSurface,\n type SurfaceStatus,\n formatProportion,\n surfaceStatuses,\n surfaceStatusDescriptions,\n surfaceStatusLabels,\n} from \"./types\";\n\nconst h = hyper.styled({ ...surfaceStyles, ...styles });\n\nexport interface SurfaceDetailsPanelProps {\n /** The surface to inspect; `null` renders the panel's empty state */\n surface: ColumnSurface | null;\n onClose?: () => void;\n /** Called when a unit above or below the surface is clicked */\n onSelectUnit?: (unitID: number) => void;\n /** Extra controls for the header */\n actions?: ReactNode;\n /** Label for the measured-position field (\"Height\" or \"Depth\") */\n positionLabel?: string;\n className?: string;\n}\n\n/** Details of one surface: its age, calibration, the units it separates, and\n * provenance. A companion to `UnitDetailsPanel`. */\nexport function SurfaceDetailsPanel(props: SurfaceDetailsPanelProps) {\n const {\n surface,\n onClose,\n onSelectUnit,\n actions,\n positionLabel = \"Position\",\n className,\n } = props;\n\n // A selection that hasn't been made yet is an ordinary state for a panel\n // bound to one, not a caller error\n if (surface == null) {\n return h(\n \"div.surface-details-panel.no-surface\",\n { className },\n h(\"p.placeholder\", \"No surface selected.\"),\n );\n }\n\n let closeButton: ReactNode = null;\n if (onClose != null) {\n closeButton = h(Button, {\n icon: \"cross\",\n variant: \"minimal\",\n size: \"small\",\n onClick: onClose,\n \"aria-label\": \"Close\",\n });\n }\n\n let positionField: ReactNode = null;\n if (surface.position != null) {\n positionField = h(DataField, {\n label: positionLabel,\n value: surface.position.toLocaleString(\"en-US\", {\n maximumFractionDigits: 2,\n }),\n unit: \"m\",\n });\n }\n\n let sectionField: ReactNode = null;\n if (surface.section_id != null) {\n sectionField = h(\n DataField,\n { label: \"Section\" },\n h(Identifier, { id: surface.section_id }),\n );\n }\n\n let refsField: ReactNode = null;\n if (surface.ref_id != null) {\n refsField = h(ReferencesField, { refs: [surface.ref_id] });\n }\n\n return h(\n \"div.surface-details-panel\",\n { className: classNames(className, surfaceClasses(surface)) },\n [\n h(\"div.surface-details-header\", [\n h(\"h3.surface-details-title\", [\n \"Surface \",\n h(SurfaceIdentifier, { id: surface.id }),\n ]),\n h(\"div.surface-details-tags\", [\n h(SurfaceStatusTag, {\n status: surface.status,\n inferred: surface.statusInferred,\n }),\n h(SurfaceTypeTag, { type: surface.type }),\n ]),\n h(\"div.spacer\"),\n actions,\n closeButton,\n ]),\n h(\"div.surface-details-content\", [\n h(DataField, { label: \"Model age\" }, h(AgeLabel, { age: surface.age })),\n h(SurfaceCalibrationField, { surface }),\n positionField,\n h(SurfaceUnitsField, {\n label: \"Unit above\",\n unitIDs: surface.unitsAbove,\n onSelectUnit,\n }),\n h(SurfaceUnitsField, {\n label: \"Unit below\",\n unitIDs: surface.unitsBelow,\n onSelectUnit,\n }),\n sectionField,\n refsField,\n ]),\n ],\n );\n}\n\nfunction SurfaceIdentifier({ id }: { id: ColumnSurface[\"id\"] }) {\n if (typeof id === \"number\") {\n return h(Identifier, { id });\n }\n return h(\"code.surface-id\", String(id));\n}\n\n/** The calibration interval as a colored tag, with the surface's position in\n * it: \"Calymmian (1600–1400 Ma), 85% above base\". */\nfunction SurfaceCalibrationField({ surface }: { surface: ColumnSurface }) {\n const { calibration, proportion } = surface;\n const ids = useMemo(() => {\n if (calibration == null) return [];\n return [calibration.id];\n }, [calibration?.id]);\n // Interval colors come from the definitions table; the age model itself\n // doesn't carry them\n const intervalMap = useMacrostratDefs(\"intervals\", ids, null);\n\n if (calibration == null) {\n return h(DataField, {\n label: \"Calibration\",\n value: \"None\",\n className: \"no-calibration\",\n });\n }\n\n const def = intervalMap?.get(calibration.id);\n const interval: IntervalShort = {\n id: calibration.id,\n name: calibration.name,\n b_age: calibration.b_age,\n t_age: calibration.t_age,\n color: def?.color,\n rank: def?.rank,\n };\n\n return h(DataField, { label: \"Calibration\" }, [\n h(\n \"div.calibration-interval\",\n h(IntervalTag, {\n interval,\n prefix: h(Proportion, { value: proportion }),\n }),\n ),\n ]);\n}\n\nfunction SurfaceUnitsField({\n label,\n unitIDs,\n onSelectUnit,\n}: {\n label: string;\n unitIDs: number[];\n onSelectUnit?: (unitID: number) => void;\n}) {\n const unitsMap = useColumnUnitsMap();\n if (unitIDs.length === 0) {\n return h(DataField, { label, value: \"None\", className: \"no-units\" });\n }\n return h(\n DataField,\n { label, className: \"surface-units-field\" },\n h(\n \"ul.surface-units-list\",\n unitIDs.map((unitID) => {\n const unit = unitsMap?.get(unitID) as UnitLong | undefined;\n let onClick: (() => void) | undefined = undefined;\n if (onSelectUnit != null) {\n onClick = () => onSelectUnit(unitID);\n }\n return h(\n \"li\",\n { key: unitID },\n h(UnitIdentifier, {\n unitID,\n colID: unit?.col_id,\n name: unit?.unit_name,\n onClick,\n }),\n );\n }),\n ),\n );\n}\n\nexport function SurfaceStatusTag({\n status,\n inferred = false,\n className,\n}: {\n status: SurfaceStatus;\n /** The status was inferred rather than recorded (see\n * `inferTiePointStatuses`); the tag says so. */\n inferred?: boolean;\n className?: string;\n}) {\n let label: ReactNode = surfaceStatusLabels[status] ?? status;\n let title = surfaceStatusDescriptions[status];\n if (inferred) {\n label = [label, h(\"span.inferred-marker\", \"*\")];\n title = INFERRED_STATUS_DESCRIPTION;\n }\n\n return h(\n Tag,\n {\n variant: \"minimal\",\n className: classNames(\n \"surface-tag\",\n className,\n surfaceClasses({ status }),\n { inferred },\n ),\n title,\n },\n label,\n );\n}\n\nconst INFERRED_STATUS_DESCRIPTION =\n \"Recorded as modeled, but this surface cannot have been interpolated — it \" +\n \"sits on the base or top of its interval, or is the edge of a gap-bound \" +\n \"package — so it constrains the age model rather than falling out of it\";\n\nexport function SurfaceTypeTag({\n type,\n className,\n}: {\n type: BoundaryType | null | undefined;\n className?: string;\n}) {\n if (type == null || type === \"\") return null;\n return h(\n Tag,\n {\n variant: \"minimal\",\n className: classNames(\"surface-tag\", \"surface-type-tag\", className),\n },\n type,\n );\n}\n\nexport interface SurfaceStatusLegendProps {\n statuses?: SurfaceStatus[];\n showDescriptions?: boolean;\n className?: string;\n}\n\n/** A legend of surface line styles, one entry per boundary status. */\nexport function SurfaceStatusLegend(props: SurfaceStatusLegendProps) {\n const {\n statuses = surfaceStatuses,\n showDescriptions = false,\n className,\n } = props;\n return h(\n \"ul.surface-status-legend\",\n {\n className: classNames(className, {\n \"with-descriptions\": showDescriptions,\n }),\n },\n statuses.map((status) => {\n let description: ReactNode = null;\n if (showDescriptions) {\n description = h(\n \"div.legend-description\",\n surfaceStatusDescriptions[status],\n );\n }\n return h(\n \"li.legend-item\",\n { key: status, className: surfaceClasses({ status }) },\n [\n h(\"div.surface-label-marker\"),\n h(\"div.legend-text\", [\n h(\"div.legend-label\", surfaceStatusLabels[status]),\n description,\n ]),\n ],\n );\n }),\n );\n}\n"],"names":["hyper","surfaceStyles","styles","Button","DataField","Identifier","ReferencesField","classNames","surfaceClasses","AgeLabel","useMemo","useMacrostratDefs","IntervalTag","Proportion","useColumnUnitsMap","UnitIdentifier","surfaceStatusLabels","surfaceStatusDescriptions","Tag","surfaceStatuses"],"mappings":"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"}
|