@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/dist/section.cjs
CHANGED
|
@@ -5,13 +5,13 @@ const timescale = require("@macrostrat/timescale");
|
|
|
5
5
|
const columnComponents = require("@macrostrat/column-components");
|
|
6
6
|
const h$1 = require("@macrostrat/hyper");
|
|
7
7
|
const column_module = require("./column.module.sass.cjs");
|
|
8
|
-
const dataProvider = require("@macrostrat/data-provider");
|
|
9
8
|
const dataComponents = require("@macrostrat/data-components");
|
|
10
9
|
const store = require("./data-provider/store.cjs");
|
|
11
10
|
const composite = require("./units/composite.cjs");
|
|
12
11
|
const ageRange = require("./unit-details/age-range.cjs");
|
|
13
12
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
14
13
|
const h__default = /* @__PURE__ */ _interopDefault(h$1);
|
|
14
|
+
const INTERNATIONAL_TIMESCALE_ID = 11;
|
|
15
15
|
const h = h__default.default.styled(column_module.default);
|
|
16
16
|
function SectionsColumn(props) {
|
|
17
17
|
const {
|
|
@@ -23,7 +23,8 @@ function SectionsColumn(props) {
|
|
|
23
23
|
columnWidth = 150,
|
|
24
24
|
showLabelColumn = true,
|
|
25
25
|
clipUnits = true,
|
|
26
|
-
maxInternalColumns
|
|
26
|
+
maxInternalColumns,
|
|
27
|
+
labelSuppressHeight
|
|
27
28
|
} = props;
|
|
28
29
|
const units = store.useMacrostratUnits();
|
|
29
30
|
const key = units[0]?.col_id;
|
|
@@ -38,7 +39,8 @@ function SectionsColumn(props) {
|
|
|
38
39
|
unconformityLabels
|
|
39
40
|
}),
|
|
40
41
|
h.if(showLabelColumn)(composite.SectionLabelsColumn, {
|
|
41
|
-
width: width - columnWidth
|
|
42
|
+
width: width - columnWidth,
|
|
43
|
+
labelSuppressHeight
|
|
42
44
|
})
|
|
43
45
|
]);
|
|
44
46
|
}
|
|
@@ -53,7 +55,7 @@ function SectionUnitsColumn(props) {
|
|
|
53
55
|
axisType,
|
|
54
56
|
unconformityLabels = true
|
|
55
57
|
} = props;
|
|
56
|
-
const { sections, totalHeight } = store.useMacrostratColumnData();
|
|
58
|
+
const { sections, totalHeight, axisType: columnAxisType } = store.useMacrostratColumnData();
|
|
57
59
|
const scaleData = sections.map((section) => {
|
|
58
60
|
return section.scaleInfo;
|
|
59
61
|
});
|
|
@@ -90,6 +92,9 @@ function SectionUnitsColumn(props) {
|
|
|
90
92
|
h.if(unconformityLabels)(UnconformityLabels, {
|
|
91
93
|
width,
|
|
92
94
|
sections: scaleData,
|
|
95
|
+
// A gap between sections is measured in whatever the axis is: metres
|
|
96
|
+
// down a core, Myr across a time column
|
|
97
|
+
axisType: axisType ?? columnAxisType,
|
|
93
98
|
verbose: false
|
|
94
99
|
})
|
|
95
100
|
]);
|
|
@@ -153,44 +158,71 @@ function CompositeTimescale(props) {
|
|
|
153
158
|
...props
|
|
154
159
|
});
|
|
155
160
|
}
|
|
161
|
+
function TimescaleLabel({ timescale: timescale2 }) {
|
|
162
|
+
const { label, name } = timescale2;
|
|
163
|
+
const style = levelCountStyle(levelCount(timescale2));
|
|
164
|
+
let content = label;
|
|
165
|
+
if (label == null && name != null) {
|
|
166
|
+
content = h("span.timescale-label-text", name);
|
|
167
|
+
}
|
|
168
|
+
if (content == null) return h("div.timescale-label", { style });
|
|
169
|
+
return h("div.timescale-label", { style }, content);
|
|
170
|
+
}
|
|
171
|
+
function levelCountStyle(levelCount2) {
|
|
172
|
+
return { "--timescale-level-count": levelCount2 };
|
|
173
|
+
}
|
|
156
174
|
function CompositeTimescaleCore(props) {
|
|
157
175
|
const {
|
|
158
|
-
levels = 3,
|
|
159
176
|
packages,
|
|
160
177
|
unconformityLabels = false,
|
|
161
178
|
onClickInterval,
|
|
162
|
-
intervalStyle
|
|
179
|
+
intervalStyle,
|
|
180
|
+
showLabels = false,
|
|
181
|
+
className
|
|
163
182
|
} = props;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
const timescales = useColumnTimescales(props);
|
|
184
|
+
function forTimescale(id) {
|
|
185
|
+
let onClick = null;
|
|
186
|
+
if (onClickInterval != null) {
|
|
187
|
+
onClick = (event, data) => {
|
|
188
|
+
onClickInterval(event, { ...data, timescaleID: id });
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
let style = intervalStyle;
|
|
192
|
+
if (typeof intervalStyle === "function") {
|
|
193
|
+
style = (interval) => intervalStyle(interval, id);
|
|
194
|
+
}
|
|
195
|
+
return { onClick, intervalStyle: style };
|
|
171
196
|
}
|
|
172
|
-
|
|
173
|
-
|
|
197
|
+
return h("div.timescale-column", { className }, [
|
|
198
|
+
h.if(showLabels)(
|
|
199
|
+
"div.timescale-labels",
|
|
200
|
+
timescales.map(
|
|
201
|
+
(timescale2) => h(TimescaleLabel, { key: timescale2.id, timescale: timescale2 })
|
|
202
|
+
)
|
|
203
|
+
),
|
|
174
204
|
h(
|
|
175
205
|
"div.timescales",
|
|
176
206
|
packages.map((group) => {
|
|
177
207
|
const { pixelHeight, paddingTop, key, scale } = group;
|
|
178
208
|
return h(
|
|
179
|
-
"div.
|
|
180
|
-
{ style: { paddingTop
|
|
181
|
-
|
|
182
|
-
h(timescale.Timescale, {
|
|
209
|
+
"div.section-timescales",
|
|
210
|
+
{ style: { paddingTop }, key },
|
|
211
|
+
timescales.map(
|
|
212
|
+
(timescale$1) => h(timescale.Timescale, {
|
|
213
|
+
key: timescale$1.id,
|
|
183
214
|
orientation: timescale.TimescaleOrientation.VERTICAL,
|
|
184
215
|
length: pixelHeight,
|
|
185
|
-
levels:
|
|
216
|
+
levels: timescale$1.levels,
|
|
217
|
+
rootInterval: timescale$1.rootInterval,
|
|
186
218
|
absoluteAgeScale: true,
|
|
187
219
|
showAgeAxis: false,
|
|
188
220
|
scale,
|
|
189
|
-
intervals,
|
|
190
|
-
|
|
191
|
-
|
|
221
|
+
intervals: timescale$1.intervals,
|
|
222
|
+
style: levelCountStyle(levelCount(timescale$1)),
|
|
223
|
+
...forTimescale(timescale$1.id)
|
|
192
224
|
})
|
|
193
|
-
|
|
225
|
+
)
|
|
194
226
|
);
|
|
195
227
|
})
|
|
196
228
|
),
|
|
@@ -202,6 +234,58 @@ function CompositeTimescaleCore(props) {
|
|
|
202
234
|
})
|
|
203
235
|
]);
|
|
204
236
|
}
|
|
237
|
+
function useColumnTimescales(props) {
|
|
238
|
+
const { timescales, levels = 3, timescaleID, additionalTimescales } = props;
|
|
239
|
+
const specs = React.useMemo(
|
|
240
|
+
() => timescaleSpecs({ timescales, levels, timescaleID, additionalTimescales }),
|
|
241
|
+
[
|
|
242
|
+
timescales,
|
|
243
|
+
levels,
|
|
244
|
+
timescaleID,
|
|
245
|
+
additionalTimescales?.join(",")
|
|
246
|
+
]
|
|
247
|
+
);
|
|
248
|
+
const fetchIDs = React.useMemo(
|
|
249
|
+
() => specs.filter((d) => d.intervals == null).map((d) => d.id),
|
|
250
|
+
[specs]
|
|
251
|
+
);
|
|
252
|
+
const intervalSets = timescale.useMacrostratTimescales(fetchIDs);
|
|
253
|
+
return React.useMemo(
|
|
254
|
+
() => specs.map((spec) => ({
|
|
255
|
+
...spec,
|
|
256
|
+
intervals: spec.intervals ?? intervalSets.get(spec.id) ?? []
|
|
257
|
+
})),
|
|
258
|
+
[specs, intervalSets]
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
function timescaleSpecs(props) {
|
|
262
|
+
const { timescales, levels = 3, timescaleID, additionalTimescales = [] } = props;
|
|
263
|
+
if (timescales != null) {
|
|
264
|
+
return timescales.map(normalizeTimescale);
|
|
265
|
+
}
|
|
266
|
+
return [
|
|
267
|
+
{
|
|
268
|
+
id: timescaleID ?? INTERNATIONAL_TIMESCALE_ID,
|
|
269
|
+
levels: levelRange(levels)
|
|
270
|
+
},
|
|
271
|
+
...additionalTimescales.map(normalizeTimescale)
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
function normalizeTimescale(timescale2) {
|
|
275
|
+
if (typeof timescale2 === "number") {
|
|
276
|
+
return { id: timescale2, levels: FLAT_TIMESCALE_LEVELS };
|
|
277
|
+
}
|
|
278
|
+
return { levels: FLAT_TIMESCALE_LEVELS, ...timescale2 };
|
|
279
|
+
}
|
|
280
|
+
const FLAT_TIMESCALE_LEVELS = [1, 1];
|
|
281
|
+
function levelRange(levels) {
|
|
282
|
+
if (typeof levels !== "number") return levels;
|
|
283
|
+
return [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];
|
|
284
|
+
}
|
|
285
|
+
function levelCount(timescale2) {
|
|
286
|
+
const [min, max] = timescale2.levels ?? FLAT_TIMESCALE_LEVELS;
|
|
287
|
+
return Math.max(max - min + 1, 1);
|
|
288
|
+
}
|
|
205
289
|
function UnconformityLabels(props) {
|
|
206
290
|
const { width, sections, className, axisType, verbose } = props;
|
|
207
291
|
return h(
|
package/dist/section.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.cjs","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport { ReactNode, FunctionComponent, useMemo } from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n TimescaleClickHandler,\n useMacrostratIntervals,\n type IntervalStyleBuilder,\n} from \"@macrostrat/timescale\";\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport {\n useMacrostratBaseURL,\n useMacrostratData,\n} from \"@macrostrat/data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight } = useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\ninterface CompositeTimescaleProps {\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n onClickInterval?: TimescaleClickHandler;\n /** Per-interval style (e.g. to highlight the currently selected interval). */\n intervalStyle?: IntervalStyleBuilder;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n onClickInterval?: TimescaleClickHandler;\n};\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n levels = 3,\n packages,\n unconformityLabels = false,\n onClickInterval,\n intervalStyle,\n } = props;\n\n // Use intervals from Macrostrat API\n const baseURL = useMacrostratBaseURL();\n const intervals = useMacrostratIntervals({ baseURL });\n\n let _levels: [number, number];\n if (typeof levels === \"number\") {\n // If levels is a number, use the most common starting level\n _levels = [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n } else {\n _levels = levels;\n }\n\n const nCols = _levels[1] - _levels[0] + 1;\n\n return h(\"div.timescale-column\", [\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.timescale-container\",\n { style: { paddingTop, \"--timescale-level-count\": nCols }, key },\n [\n h(Timescale, {\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: _levels,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals,\n onClick: onClickInterval,\n intervalStyle,\n }),\n ],\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles","useMacrostratUnits","LabelTrackerProvider","SectionLabelsColumn","useMacrostratColumnData","SVG","useMemo","MacrostratColumnProvider","CompositeUnitsColumn","useMacrostratBaseURL","useMacrostratIntervals","Timescale","TimescaleOrientation","ColumnAxisType","Value","Duration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"section.cjs","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport {\n type CSSProperties,\n ReactNode,\n FunctionComponent,\n useMemo,\n} from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n useMacrostratTimescales,\n type Interval,\n type IntervalStyleBuilder,\n type TimescaleClickData,\n} from \"@macrostrat/timescale\";\n\n/** Macrostrat's international timescale, the default for a column */\nconst INTERNATIONAL_TIMESCALE_ID = 11;\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels */\n labelSuppressHeight?: number;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n labelSuppressHeight,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n labelSuppressHeight,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight, axisType: columnAxisType } =\n useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n // A gap between sections is measured in whatever the axis is: metres\n // down a core, Myr across a time column\n axisType: axisType ?? columnAxisType,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\n/** A per-interval style that also knows which timescale the interval was\n * drawn from. The same interval often appears in several of the timescales\n * beside each other, and they aren't interchangeable — only one of them is\n * the one a selection was made in. */\nexport type ColumnIntervalStyleBuilder =\n | CSSProperties\n | ((interval: Interval, timescaleID: number) => CSSProperties)\n | null;\n\n/** A timescale click, reporting which timescale was clicked in */\nexport type ColumnTimescaleClickHandler = (\n event: Event,\n data: TimescaleClickData & { timescaleID: number },\n) => void;\n\n/** A timescale to draw beside a column.\n *\n * The international timescale is one of these, not a special case: it is the\n * one that happens to be nested several levels deep. Anything with the same\n * shape can take its place or sit beside it — a regional set from the API, a\n * zonation assembled locally, or a hierarchy that isn't a timescale at all,\n * so long as its \"intervals\" carry ages.\n */\nexport interface ColumnTimescale {\n /** Integer identifier. Clicks and per-interval styles report it, so a\n * consumer can tell one column's copy of an interval from another's. For a\n * Macrostrat timescale it is the `timescale_id`. */\n id: number;\n /** Shown above the column, unless `label` says otherwise */\n name?: string;\n /** The intervals themselves, flat or already nested by `pid`. Left out,\n * the timescale `id` is fetched from the Macrostrat API. */\n intervals?: Interval[];\n /** Levels to draw, and so how many slots wide the column is (default\n * `[1, 1]`: one level, which is what a flat timescale has) */\n levels?: [number, number];\n /** `oid` of the interval the tree hangs from (default 0) */\n rootInterval?: number;\n /** Drawn above the column in place of the name — any node, so a consumer\n * can put a control or a legend there instead of text */\n label?: ReactNode;\n}\n\nexport type ColumnTimescaleLike = number | ColumnTimescale;\n\ninterface CompositeTimescaleProps {\n /** Every timescale to draw, in order. A bare number is a Macrostrat\n * timescale to fetch and draw as a single level.\n *\n * Given this, `levels`, `timescaleID` and `additionalTimescales` are\n * ignored: it says what they say and more. */\n timescales?: ColumnTimescaleLike[];\n /** Levels of the ICS hierarchy to show. If a number, the finest level is\n * `levels[0]`, the second-finest is `levels[1]`, etc. If an array, the\n * first element is the starting level, the second is the ending level. */\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n onClickInterval?: ColumnTimescaleClickHandler;\n /** Per-interval style (e.g. to highlight the currently selected interval). */\n intervalStyle?: ColumnIntervalStyleBuilder;\n /** The timescale to draw. Defaults to the international one; any other\n * Macrostrat timescale (a regional or project-specific set of intervals)\n * can be drawn in its place. */\n timescaleID?: number;\n /** Further timescales drawn as extra level columns beside the main one,\n * against the same scale. Shorthand for listing them in `timescales`. */\n additionalTimescales?: number[];\n /** Draw the names above the columns. They sit above the column proper, so\n * leave top padding for them. */\n showLabels?: boolean;\n className?: string;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n};\n\n/** What is drawn above a timescale: its name, reading up the page, or\n * whatever node the consumer gave instead. */\nfunction TimescaleLabel({ timescale }: { timescale: ColumnTimescale }) {\n const { label, name } = timescale;\n const style = levelCountStyle(levelCount(timescale));\n\n let content: ReactNode = label;\n if (label == null && name != null) {\n content = h(\"span.timescale-label-text\", name);\n }\n if (content == null) return h(\"div.timescale-label\", { style });\n\n return h(\"div.timescale-label\", { style }, content);\n}\n\n/** How wide a timescale draws: one slot per level it shows. */\nfunction levelCountStyle(levelCount: number): CSSProperties {\n return { \"--timescale-level-count\": levelCount } as CSSProperties;\n}\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n packages,\n unconformityLabels = false,\n onClickInterval,\n intervalStyle,\n showLabels = false,\n className,\n } = props;\n\n const timescales = useColumnTimescales(props);\n\n /** Clicks and styles carry the timescale they came from, so a consumer can\n * tell one column's copy of an interval from another's. */\n function forTimescale(id: number) {\n let onClick = null;\n if (onClickInterval != null) {\n onClick = (event: Event, data: TimescaleClickData) => {\n onClickInterval(event, { ...data, timescaleID: id });\n };\n }\n let style = intervalStyle as IntervalStyleBuilder;\n if (typeof intervalStyle === \"function\") {\n style = (interval: Interval) => intervalStyle(interval, id);\n }\n return { onClick, intervalStyle: style };\n }\n\n return h(\"div.timescale-column\", { className }, [\n h.if(showLabels)(\n \"div.timescale-labels\",\n timescales.map((timescale) =>\n h(TimescaleLabel, { key: timescale.id, timescale }),\n ),\n ),\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.section-timescales\",\n { style: { paddingTop }, key },\n timescales.map((timescale) =>\n h(Timescale, {\n key: timescale.id,\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: timescale.levels,\n rootInterval: timescale.rootInterval,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals: timescale.intervals,\n style: levelCountStyle(levelCount(timescale)),\n ...forTimescale(timescale.id),\n }),\n ),\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\n/** The timescales to draw, with their intervals.\n *\n * Every timescale a column draws is fetched in one place: a column is split\n * into sections, and fetching per section would ask for the same timescale\n * once per section per timescale.\n */\nfunction useColumnTimescales(props: CompositeTimescaleProps): ColumnTimescale[] {\n const { timescales, levels = 3, timescaleID, additionalTimescales } = props;\n\n const specs = useMemo(\n () => timescaleSpecs({ timescales, levels, timescaleID, additionalTimescales }),\n [\n timescales,\n levels,\n timescaleID,\n additionalTimescales?.join(\",\"),\n ],\n );\n\n // Only the ones that didn't come with their own intervals need fetching\n const fetchIDs = useMemo(\n () => specs.filter((d) => d.intervals == null).map((d) => d.id),\n [specs],\n );\n const intervalSets = useMacrostratTimescales(fetchIDs);\n\n return useMemo(\n () =>\n specs.map((spec) => ({\n ...spec,\n intervals: spec.intervals ?? intervalSets.get(spec.id) ?? [],\n })),\n [specs, intervalSets],\n );\n}\n\n/** The `timescales` list, or one built from the older props that name the\n * leveled timescale and the flat ones beside it. */\nfunction timescaleSpecs(props: CompositeTimescaleProps): ColumnTimescale[] {\n const { timescales, levels = 3, timescaleID, additionalTimescales = [] } = props;\n\n if (timescales != null) {\n return timescales.map(normalizeTimescale);\n }\n\n return [\n {\n id: timescaleID ?? INTERNATIONAL_TIMESCALE_ID,\n levels: levelRange(levels),\n },\n ...additionalTimescales.map(normalizeTimescale),\n ];\n}\n\nfunction normalizeTimescale(timescale: ColumnTimescaleLike): ColumnTimescale {\n if (typeof timescale === \"number\") {\n return { id: timescale, levels: FLAT_TIMESCALE_LEVELS };\n }\n return { levels: FLAT_TIMESCALE_LEVELS, ...timescale };\n}\n\n/** Regional and project timescales come back flat: one level of intervals. */\nconst FLAT_TIMESCALE_LEVELS: [number, number] = [1, 1];\n\nfunction levelRange(levels: [number, number] | number): [number, number] {\n if (typeof levels !== \"number\") return levels;\n // A count, rather than a range: start at the level most columns start at\n return [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n}\n\n/** How many slots wide a timescale draws: one per level it shows. */\nfunction levelCount(timescale: ColumnTimescale): number {\n const [min, max] = timescale.levels ?? FLAT_TIMESCALE_LEVELS;\n return Math.max(max - min + 1, 1);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles","useMacrostratUnits","LabelTrackerProvider","SectionLabelsColumn","useMacrostratColumnData","SVG","useMemo","MacrostratColumnProvider","CompositeUnitsColumn","timescale","levelCount","Timescale","TimescaleOrientation","ColumnAxisType","useMacrostratTimescales","Value","Duration"],"mappings":"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"}
|
package/dist/section.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReactNode, FunctionComponent } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { CSSProperties, ReactNode, FunctionComponent } from 'react';
|
|
2
|
+
import { Interval, TimescaleClickData } from '@macrostrat/timescale';
|
|
3
3
|
import { ColumnAxisType } from '@macrostrat/column-components';
|
|
4
4
|
import { ExtUnit, PackageScaleLayoutData } from './prepare-units/types';
|
|
5
5
|
export interface SectionSharedProps {
|
|
@@ -10,6 +10,8 @@ export interface SectionSharedProps {
|
|
|
10
10
|
columnWidth?: number;
|
|
11
11
|
children?: ReactNode;
|
|
12
12
|
showLabelColumn?: boolean;
|
|
13
|
+
/** Suppress the label for a unit drawn thinner than this many pixels */
|
|
14
|
+
labelSuppressHeight?: number;
|
|
13
15
|
axisType?: ColumnAxisType;
|
|
14
16
|
className?: string;
|
|
15
17
|
clipUnits?: boolean;
|
|
@@ -22,19 +24,77 @@ export interface SectionProps extends SectionSharedProps {
|
|
|
22
24
|
scaleInfo: PackageScaleLayoutData;
|
|
23
25
|
}
|
|
24
26
|
export declare function SectionsColumn(props: SectionSharedProps): import('react').FunctionComponentElement<any>;
|
|
27
|
+
/** A per-interval style that also knows which timescale the interval was
|
|
28
|
+
* drawn from. The same interval often appears in several of the timescales
|
|
29
|
+
* beside each other, and they aren't interchangeable — only one of them is
|
|
30
|
+
* the one a selection was made in. */
|
|
31
|
+
export type ColumnIntervalStyleBuilder = CSSProperties | ((interval: Interval, timescaleID: number) => CSSProperties) | null;
|
|
32
|
+
/** A timescale click, reporting which timescale was clicked in */
|
|
33
|
+
export type ColumnTimescaleClickHandler = (event: Event, data: TimescaleClickData & {
|
|
34
|
+
timescaleID: number;
|
|
35
|
+
}) => void;
|
|
36
|
+
/** A timescale to draw beside a column.
|
|
37
|
+
*
|
|
38
|
+
* The international timescale is one of these, not a special case: it is the
|
|
39
|
+
* one that happens to be nested several levels deep. Anything with the same
|
|
40
|
+
* shape can take its place or sit beside it — a regional set from the API, a
|
|
41
|
+
* zonation assembled locally, or a hierarchy that isn't a timescale at all,
|
|
42
|
+
* so long as its "intervals" carry ages.
|
|
43
|
+
*/
|
|
44
|
+
export interface ColumnTimescale {
|
|
45
|
+
/** Integer identifier. Clicks and per-interval styles report it, so a
|
|
46
|
+
* consumer can tell one column's copy of an interval from another's. For a
|
|
47
|
+
* Macrostrat timescale it is the `timescale_id`. */
|
|
48
|
+
id: number;
|
|
49
|
+
/** Shown above the column, unless `label` says otherwise */
|
|
50
|
+
name?: string;
|
|
51
|
+
/** The intervals themselves, flat or already nested by `pid`. Left out,
|
|
52
|
+
* the timescale `id` is fetched from the Macrostrat API. */
|
|
53
|
+
intervals?: Interval[];
|
|
54
|
+
/** Levels to draw, and so how many slots wide the column is (default
|
|
55
|
+
* `[1, 1]`: one level, which is what a flat timescale has) */
|
|
56
|
+
levels?: [number, number];
|
|
57
|
+
/** `oid` of the interval the tree hangs from (default 0) */
|
|
58
|
+
rootInterval?: number;
|
|
59
|
+
/** Drawn above the column in place of the name — any node, so a consumer
|
|
60
|
+
* can put a control or a legend there instead of text */
|
|
61
|
+
label?: ReactNode;
|
|
62
|
+
}
|
|
63
|
+
export type ColumnTimescaleLike = number | ColumnTimescale;
|
|
25
64
|
interface CompositeTimescaleProps {
|
|
65
|
+
/** Every timescale to draw, in order. A bare number is a Macrostrat
|
|
66
|
+
* timescale to fetch and draw as a single level.
|
|
67
|
+
*
|
|
68
|
+
* Given this, `levels`, `timescaleID` and `additionalTimescales` are
|
|
69
|
+
* ignored: it says what they say and more. */
|
|
70
|
+
timescales?: ColumnTimescaleLike[];
|
|
71
|
+
/** Levels of the ICS hierarchy to show. If a number, the finest level is
|
|
72
|
+
* `levels[0]`, the second-finest is `levels[1]`, etc. If an array, the
|
|
73
|
+
* first element is the starting level, the second is the ending level. */
|
|
26
74
|
levels?: [number, number] | number;
|
|
27
75
|
unconformityLabels?: boolean;
|
|
28
|
-
onClickInterval?:
|
|
76
|
+
onClickInterval?: ColumnTimescaleClickHandler;
|
|
29
77
|
/** Per-interval style (e.g. to highlight the currently selected interval). */
|
|
30
|
-
intervalStyle?:
|
|
78
|
+
intervalStyle?: ColumnIntervalStyleBuilder;
|
|
79
|
+
/** The timescale to draw. Defaults to the international one; any other
|
|
80
|
+
* Macrostrat timescale (a regional or project-specific set of intervals)
|
|
81
|
+
* can be drawn in its place. */
|
|
82
|
+
timescaleID?: number;
|
|
83
|
+
/** Further timescales drawn as extra level columns beside the main one,
|
|
84
|
+
* against the same scale. Shorthand for listing them in `timescales`. */
|
|
85
|
+
additionalTimescales?: number[];
|
|
86
|
+
/** Draw the names above the columns. They sit above the column proper, so
|
|
87
|
+
* leave top padding for them. */
|
|
88
|
+
showLabels?: boolean;
|
|
89
|
+
className?: string;
|
|
31
90
|
}
|
|
32
91
|
export declare function CompositeTimescale(props: CompositeTimescaleProps): import('react').FunctionComponentElement<CompositeTimescaleCoreProps>;
|
|
33
92
|
type CompositeTimescaleCoreProps = CompositeTimescaleProps & {
|
|
34
93
|
packages: PackageScaleLayoutData[];
|
|
35
|
-
onClickInterval?: TimescaleClickHandler;
|
|
36
94
|
};
|
|
37
|
-
export declare function CompositeTimescaleCore(props: CompositeTimescaleCoreProps): import('react').
|
|
95
|
+
export declare function CompositeTimescaleCore(props: CompositeTimescaleCoreProps): import('react').ReactElement<{
|
|
96
|
+
className: string | undefined;
|
|
97
|
+
}, string | import('react').JSXElementConstructor<any>>;
|
|
38
98
|
export declare function UnconformityLabels(props: {
|
|
39
99
|
width: string | number;
|
|
40
100
|
sections: PackageScaleLayoutData[];
|
package/dist/section.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { Timescale, TimescaleOrientation, useMacrostratTimescales } from "@macrostrat/timescale";
|
|
3
3
|
import { ColumnAxisType, SVG } from "@macrostrat/column-components";
|
|
4
4
|
import h$1 from "@macrostrat/hyper";
|
|
5
5
|
import h$2 from "./column.module.sass.js";
|
|
6
|
-
import { useMacrostratBaseURL } from "@macrostrat/data-provider";
|
|
7
6
|
import { Value } from "@macrostrat/data-components";
|
|
8
7
|
import { useMacrostratColumnData, useMacrostratUnits, MacrostratColumnProvider } from "./data-provider/store.js";
|
|
9
8
|
import { LabelTrackerProvider, SectionLabelsColumn, CompositeUnitsColumn } from "./units/composite.js";
|
|
10
9
|
import { Duration } from "./unit-details/age-range.js";
|
|
10
|
+
const INTERNATIONAL_TIMESCALE_ID = 11;
|
|
11
11
|
const h = h$1.styled(h$2);
|
|
12
12
|
function SectionsColumn(props) {
|
|
13
13
|
const {
|
|
@@ -19,7 +19,8 @@ function SectionsColumn(props) {
|
|
|
19
19
|
columnWidth = 150,
|
|
20
20
|
showLabelColumn = true,
|
|
21
21
|
clipUnits = true,
|
|
22
|
-
maxInternalColumns
|
|
22
|
+
maxInternalColumns,
|
|
23
|
+
labelSuppressHeight
|
|
23
24
|
} = props;
|
|
24
25
|
const units = useMacrostratUnits();
|
|
25
26
|
const key = units[0]?.col_id;
|
|
@@ -34,7 +35,8 @@ function SectionsColumn(props) {
|
|
|
34
35
|
unconformityLabels
|
|
35
36
|
}),
|
|
36
37
|
h.if(showLabelColumn)(SectionLabelsColumn, {
|
|
37
|
-
width: width - columnWidth
|
|
38
|
+
width: width - columnWidth,
|
|
39
|
+
labelSuppressHeight
|
|
38
40
|
})
|
|
39
41
|
]);
|
|
40
42
|
}
|
|
@@ -49,7 +51,7 @@ function SectionUnitsColumn(props) {
|
|
|
49
51
|
axisType,
|
|
50
52
|
unconformityLabels = true
|
|
51
53
|
} = props;
|
|
52
|
-
const { sections, totalHeight } = useMacrostratColumnData();
|
|
54
|
+
const { sections, totalHeight, axisType: columnAxisType } = useMacrostratColumnData();
|
|
53
55
|
const scaleData = sections.map((section) => {
|
|
54
56
|
return section.scaleInfo;
|
|
55
57
|
});
|
|
@@ -86,6 +88,9 @@ function SectionUnitsColumn(props) {
|
|
|
86
88
|
h.if(unconformityLabels)(UnconformityLabels, {
|
|
87
89
|
width,
|
|
88
90
|
sections: scaleData,
|
|
91
|
+
// A gap between sections is measured in whatever the axis is: metres
|
|
92
|
+
// down a core, Myr across a time column
|
|
93
|
+
axisType: axisType ?? columnAxisType,
|
|
89
94
|
verbose: false
|
|
90
95
|
})
|
|
91
96
|
]);
|
|
@@ -149,44 +154,71 @@ function CompositeTimescale(props) {
|
|
|
149
154
|
...props
|
|
150
155
|
});
|
|
151
156
|
}
|
|
157
|
+
function TimescaleLabel({ timescale }) {
|
|
158
|
+
const { label, name } = timescale;
|
|
159
|
+
const style = levelCountStyle(levelCount(timescale));
|
|
160
|
+
let content = label;
|
|
161
|
+
if (label == null && name != null) {
|
|
162
|
+
content = h("span.timescale-label-text", name);
|
|
163
|
+
}
|
|
164
|
+
if (content == null) return h("div.timescale-label", { style });
|
|
165
|
+
return h("div.timescale-label", { style }, content);
|
|
166
|
+
}
|
|
167
|
+
function levelCountStyle(levelCount2) {
|
|
168
|
+
return { "--timescale-level-count": levelCount2 };
|
|
169
|
+
}
|
|
152
170
|
function CompositeTimescaleCore(props) {
|
|
153
171
|
const {
|
|
154
|
-
levels = 3,
|
|
155
172
|
packages,
|
|
156
173
|
unconformityLabels = false,
|
|
157
174
|
onClickInterval,
|
|
158
|
-
intervalStyle
|
|
175
|
+
intervalStyle,
|
|
176
|
+
showLabels = false,
|
|
177
|
+
className
|
|
159
178
|
} = props;
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
179
|
+
const timescales = useColumnTimescales(props);
|
|
180
|
+
function forTimescale(id) {
|
|
181
|
+
let onClick = null;
|
|
182
|
+
if (onClickInterval != null) {
|
|
183
|
+
onClick = (event, data) => {
|
|
184
|
+
onClickInterval(event, { ...data, timescaleID: id });
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
let style = intervalStyle;
|
|
188
|
+
if (typeof intervalStyle === "function") {
|
|
189
|
+
style = (interval) => intervalStyle(interval, id);
|
|
190
|
+
}
|
|
191
|
+
return { onClick, intervalStyle: style };
|
|
167
192
|
}
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
return h("div.timescale-column", { className }, [
|
|
194
|
+
h.if(showLabels)(
|
|
195
|
+
"div.timescale-labels",
|
|
196
|
+
timescales.map(
|
|
197
|
+
(timescale) => h(TimescaleLabel, { key: timescale.id, timescale })
|
|
198
|
+
)
|
|
199
|
+
),
|
|
170
200
|
h(
|
|
171
201
|
"div.timescales",
|
|
172
202
|
packages.map((group) => {
|
|
173
203
|
const { pixelHeight, paddingTop, key, scale } = group;
|
|
174
204
|
return h(
|
|
175
|
-
"div.
|
|
176
|
-
{ style: { paddingTop
|
|
177
|
-
|
|
178
|
-
h(Timescale, {
|
|
205
|
+
"div.section-timescales",
|
|
206
|
+
{ style: { paddingTop }, key },
|
|
207
|
+
timescales.map(
|
|
208
|
+
(timescale) => h(Timescale, {
|
|
209
|
+
key: timescale.id,
|
|
179
210
|
orientation: TimescaleOrientation.VERTICAL,
|
|
180
211
|
length: pixelHeight,
|
|
181
|
-
levels:
|
|
212
|
+
levels: timescale.levels,
|
|
213
|
+
rootInterval: timescale.rootInterval,
|
|
182
214
|
absoluteAgeScale: true,
|
|
183
215
|
showAgeAxis: false,
|
|
184
216
|
scale,
|
|
185
|
-
intervals,
|
|
186
|
-
|
|
187
|
-
|
|
217
|
+
intervals: timescale.intervals,
|
|
218
|
+
style: levelCountStyle(levelCount(timescale)),
|
|
219
|
+
...forTimescale(timescale.id)
|
|
188
220
|
})
|
|
189
|
-
|
|
221
|
+
)
|
|
190
222
|
);
|
|
191
223
|
})
|
|
192
224
|
),
|
|
@@ -198,6 +230,58 @@ function CompositeTimescaleCore(props) {
|
|
|
198
230
|
})
|
|
199
231
|
]);
|
|
200
232
|
}
|
|
233
|
+
function useColumnTimescales(props) {
|
|
234
|
+
const { timescales, levels = 3, timescaleID, additionalTimescales } = props;
|
|
235
|
+
const specs = useMemo(
|
|
236
|
+
() => timescaleSpecs({ timescales, levels, timescaleID, additionalTimescales }),
|
|
237
|
+
[
|
|
238
|
+
timescales,
|
|
239
|
+
levels,
|
|
240
|
+
timescaleID,
|
|
241
|
+
additionalTimescales?.join(",")
|
|
242
|
+
]
|
|
243
|
+
);
|
|
244
|
+
const fetchIDs = useMemo(
|
|
245
|
+
() => specs.filter((d) => d.intervals == null).map((d) => d.id),
|
|
246
|
+
[specs]
|
|
247
|
+
);
|
|
248
|
+
const intervalSets = useMacrostratTimescales(fetchIDs);
|
|
249
|
+
return useMemo(
|
|
250
|
+
() => specs.map((spec) => ({
|
|
251
|
+
...spec,
|
|
252
|
+
intervals: spec.intervals ?? intervalSets.get(spec.id) ?? []
|
|
253
|
+
})),
|
|
254
|
+
[specs, intervalSets]
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
function timescaleSpecs(props) {
|
|
258
|
+
const { timescales, levels = 3, timescaleID, additionalTimescales = [] } = props;
|
|
259
|
+
if (timescales != null) {
|
|
260
|
+
return timescales.map(normalizeTimescale);
|
|
261
|
+
}
|
|
262
|
+
return [
|
|
263
|
+
{
|
|
264
|
+
id: timescaleID ?? INTERNATIONAL_TIMESCALE_ID,
|
|
265
|
+
levels: levelRange(levels)
|
|
266
|
+
},
|
|
267
|
+
...additionalTimescales.map(normalizeTimescale)
|
|
268
|
+
];
|
|
269
|
+
}
|
|
270
|
+
function normalizeTimescale(timescale) {
|
|
271
|
+
if (typeof timescale === "number") {
|
|
272
|
+
return { id: timescale, levels: FLAT_TIMESCALE_LEVELS };
|
|
273
|
+
}
|
|
274
|
+
return { levels: FLAT_TIMESCALE_LEVELS, ...timescale };
|
|
275
|
+
}
|
|
276
|
+
const FLAT_TIMESCALE_LEVELS = [1, 1];
|
|
277
|
+
function levelRange(levels) {
|
|
278
|
+
if (typeof levels !== "number") return levels;
|
|
279
|
+
return [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];
|
|
280
|
+
}
|
|
281
|
+
function levelCount(timescale) {
|
|
282
|
+
const [min, max] = timescale.levels ?? FLAT_TIMESCALE_LEVELS;
|
|
283
|
+
return Math.max(max - min + 1, 1);
|
|
284
|
+
}
|
|
201
285
|
function UnconformityLabels(props) {
|
|
202
286
|
const { width, sections, className, axisType, verbose } = props;
|
|
203
287
|
return h(
|