@macrostrat/column-views 3.12.2 → 3.13.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.13.0] - 2026-09-27 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.12.2...@macrostrat/column-views-v3.13.0)
4
+
5
+ ### Minor Changes
6
+
7
+ - - `Column` takes `showAgeAxis` (default `true`), to leave out the axis for a
8
+ column whose coordinates aren't a measure
9
+ [ccb88cad](https://github.com/UW-Macrostrat/web-components/commit/ccb88cad7400784437d346c1d3e3c4f969f3fa2a)
10
+ - An explicit `showTimescale: false` wins over `timescaleLevels` /
11
+ `timescales`, which used to turn the timescale back on
12
+ - The unit details panel skips references `/defs/refs` doesn't know instead of
13
+ throwing
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+ [ccb88cad](https://github.com/UW-Macrostrat/web-components/commit/ccb88cad7400784437d346c1d3e3c4f969f3fa2a)
19
+ - Updated dependencies
20
+ [e9f9084e](https://github.com/UW-Macrostrat/web-components/commit/e9f9084ee66e5a8da3ff4bcaeba1eee17b986042)
21
+ - @macrostrat/data-components@1.8.0
22
+
3
23
  ## [3.12.2] - 2026-09-25 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.12.1...@macrostrat/column-views-v3.12.2)
4
24
 
5
25
  ### Patch Changes
package/dist/column.cjs CHANGED
@@ -146,7 +146,8 @@ function ColumnInner(props) {
146
146
  onMouseOver,
147
147
  onClickTimescaleInterval,
148
148
  timescaleIntervalStyle,
149
- ageAxisComponent = ageAxis.CompositeAgeAxis
149
+ ageAxisComponent = ageAxis.CompositeAgeAxis,
150
+ showAgeAxis = true
150
151
  } = props;
151
152
  const { axisType } = store.useMacrostratColumnData();
152
153
  const labelColumnClaimed = store.useLabelColumnClaimed();
@@ -167,11 +168,7 @@ function ColumnInner(props) {
167
168
  if (columnWidth > width - 10 || labelColumnClaimed) {
168
169
  showLabelColumn = false;
169
170
  }
170
- let _showTimescale = showTimescale ?? true;
171
- if (timescaleLevels != null || timescales != null) {
172
- _showTimescale = true;
173
- }
174
- _showTimescale = axisType == columnComponents.ColumnAxisType.AGE && _showTimescale;
171
+ const _showTimescale = axisType == columnComponents.ColumnAxisType.AGE && (showTimescale ?? true);
175
172
  return column_module.default(
176
173
  ColumnContainer,
177
174
  {
@@ -180,7 +177,7 @@ function ColumnInner(props) {
180
177
  className
181
178
  },
182
179
  column_module.default("div.column", { ref: columnRef }, [
183
- column_module.default(ageAxisComponent),
180
+ column_module.default.if(showAgeAxis)(ageAxisComponent),
184
181
  column_module.default.if(_showTimescale)(section.CompositeTimescale, {
185
182
  levels: timescaleLevels,
186
183
  additionalTimescales,
@@ -1 +1 @@
1
- {"version":3,"file":"column.cjs","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport {\n Box,\n extractPadding,\n Padding,\n useDarkMode,\n} from \"@macrostrat/ui-components\";\nimport classNames from \"classnames\";\nimport {\n HTMLAttributes,\n useCallback,\n CSSProperties,\n ComponentType,\n RefObject,\n} from \"react\";\nimport h from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\n ColumnRef,\n UnitKeyboardNavigation,\n useColumnRef,\n useUnitSelectionDispatch,\n} from \"./data-provider\";\n\nimport {\n Identifier,\n ReferencesField,\n UnitSelectionPopover,\n} from \"./unit-details\";\nimport {\n MacrostratColumnDataProvider,\n useCompositeScale,\n useLabelColumnClaimed,\n useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\n type ColumnIntervalStyleBuilder,\n type ColumnTimescaleClickHandler,\n type ColumnTimescaleLike,\n SectionsColumn,\n} from \"./section\";\nimport { ApproximateHeightAxis, CompositeAgeAxis } from \"./age-axis\";\nimport {\n MergeSectionsMode,\n usePreparedColumnUnits,\n HybridScaleType,\n ColumnHeightScaleOptions,\n} from \"./prepare-units\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { NonIdealState } from \"@blueprintjs/core\";\nimport { DataField } from \"@macrostrat/data-components\";\nimport { ScaleContinuousNumeric } from \"d3-scale\";\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels\n * (default 2) */\n labelSuppressHeight?: number;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\n /** Regional or project timescales drawn as extra columns beside the\n * international one (see `CompositeTimescale`). Narrow `timescaleLevels` by\n * as many to swap the finest level for them rather than widen the column. */\n additionalTimescales?: number[];\n /** Every timescale to draw beside the column, in order: a Macrostrat\n * timescale ID, or a timescale with its own intervals (see\n * `CompositeTimescale`). Supersedes `timescaleLevels` and\n * `additionalTimescales`. */\n timescales?: ColumnTimescaleLike[];\n /** Draw each timescale's name above it */\n showTimescaleLabels?: boolean;\n /** Called when a timescale interval is clicked (e.g. to zoom the age range).\n * The data says which timescale it was clicked in. */\n onClickTimescaleInterval?: ColumnTimescaleClickHandler;\n /** Per-interval style for the timescale (e.g. to bold the selected\n * interval), by interval and the timescale it was drawn from. */\n timescaleIntervalStyle?: ColumnIntervalStyleBuilder;\n unconformityLabels?: boolean | UnconformityLabelPlacement;\n onMouseOver?: (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n ) => void;\n}\n\nexport type UnconformityLabelPlacement = \"minimal\" | \"prominent\" | \"none\";\n\nexport interface ColumnProps\n extends Padding, BaseColumnProps, ColumnHeightScaleOptions {\n // Macrostrat units\n units: UnitLong[];\n t_age?: number;\n b_age?: number;\n t_pos?: number;\n b_pos?: number;\n mergeSections?: MergeSectionsMode;\n showUnitPopover?: boolean;\n allowUnitSelection?: boolean;\n selectedUnit?: number | null;\n onUnitSelected?: (unitID: number | null, unit: any) => void;\n // Unconformity height in pixels\n unconformityHeight?: number;\n scale?: ScaleContinuousNumeric<number, number>;\n /** True while the age window is animating (e.g. from `useAnimatedAgeWindow`),\n * so per-frame label/pattern recalculation can be skipped. */\n isTransitioning?: boolean;\n /** Hide unit labels while transitioning (perf escape hatch; default false —\n * labels stay visible through the animation). */\n hideLabelsWhileTransitioning?: boolean;\n ref?: RefObject<ColumnRef>;\n}\n\nexport function Column(props: ColumnProps) {\n const {\n showUnitPopover = false,\n keyboardNavigation = false,\n mergeSections,\n onUnitSelected,\n selectedUnit,\n children,\n units: rawUnits,\n t_age,\n b_age,\n t_pos,\n b_pos,\n unconformityHeight = 30,\n targetUnitHeight = 20,\n sectionOptions,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n windowPadding = 0,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n ...rest\n } = props;\n\n /* `pixelScale` and `targetUnitHeight` are alternatives: a density stated\n * outright takes over from the one a section's units imply, floors and all.\n * That is settled in `prepare-units/density`, so nothing is adjusted here. */\n\n // Handle special cases for hybrid scales (WIP, we need to regularize this)\n let _axisType = axisType ?? ColumnAxisType.AGE;\n let ageAxisComponent = CompositeAgeAxis;\n if (\n hybridScale?.type === HybridScaleType.ApproximateHeight &&\n _axisType != ColumnAxisType.AGE\n ) {\n // Use approximate height axis for non-age columns if a non-age axis type is requested\n ageAxisComponent = ApproximateHeightAxis;\n _axisType = ColumnAxisType.AGE;\n }\n\n let _sectionOptions = sectionOptions;\n if (_sectionOptions == undefined) {\n // Build our own section options function based on targetUnitHeight\n _sectionOptions = (ctx) => {\n /** Scale targetUnitHeight by the number of units, so that a section with just a few units\n * is drawn taller than a section with many units.\n */\n const n = ctx.units.length;\n const expansionFactor = 8 / Math.min(Math.max(n, 1), 8);\n\n return {\n targetUnitHeight: targetUnitHeight * expansionFactor,\n };\n };\n }\n\n const { sections, units, totalHeight } = usePreparedColumnUnits(rawUnits, {\n axisType: _axisType,\n t_age,\n b_age,\n t_pos,\n b_pos,\n mergeSections,\n targetUnitHeight,\n sectionOptions: _sectionOptions,\n unconformityHeight,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale,\n minSectionHeight,\n windowPadding,\n collapseSmallUnconformities,\n // TODO: consider unifying scale and hybridScale options\n scale,\n hybridScale,\n });\n\n if (sections.length === 0) {\n return h(\n \"div.column-container.empty\",\n h(NonIdealState, {\n title: \"Empty column\",\n description: \"No sections found in this column.\",\n icon: \"warning-sign\",\n }),\n );\n }\n\n return h(\n MacrostratColumnDataProvider,\n {\n units,\n sections,\n totalHeight,\n axisType: _axisType,\n allowUnitSelection: showUnitPopover || allowUnitSelection,\n onUnitSelected,\n selectedUnit,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n },\n h(ColumnInner, { ageAxisComponent, ...rest }, [\n children,\n h.if(showUnitPopover)(UnitSelectionPopover),\n h.if(keyboardNavigation)(UnitKeyboardNavigation, { units }),\n ]),\n );\n}\n\ninterface ColumnInnerProps extends BaseColumnProps {\n ageAxisComponent?: ComponentType;\n}\n\nfunction ColumnInner(props: ColumnInnerProps) {\n const padding = extractPadding(props);\n\n // TODO: integrate padding vars more closely with the rest of the spacing (right now padding is a bit ad-hoc)\n const paddingVars: any = {\n \"--column-padding-top\": `${padding.paddingTop}px`,\n \"--column-padding-bottom\": `${padding.paddingBottom}px`,\n \"--column-padding-left\": `${padding.paddingLeft}px`,\n \"--column-padding-right\": `${padding.paddingRight}px`,\n };\n\n const {\n unitComponent = UnitComponent,\n unconformityLabels = \"minimal\",\n showLabels = true,\n width: _width = 300,\n columnWidth: _columnWidth = 150,\n showLabelColumn: _showLabelColumn = true,\n labelSuppressHeight,\n className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n additionalTimescales,\n timescales,\n showTimescaleLabels,\n maxInternalColumns,\n onMouseOver,\n onClickTimescaleInterval,\n timescaleIntervalStyle,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\n // A child layer drawing its own labels (the surfaces view) takes the label\n // column over from the unit labels\n const labelColumnClaimed = useLabelColumnClaimed();\n\n const columnRef = useColumnRef();\n\n // Coalesce unconformity label setting to a boolean\n let _timescaleUnconformityLabels = false;\n let _sectionUnconformityLabels = false;\n if (unconformityLabels === true || unconformityLabels === \"prominent\") {\n _sectionUnconformityLabels = true;\n } else if (unconformityLabels === \"minimal\") {\n _timescaleUnconformityLabels = true;\n }\n\n let width = _width;\n let columnWidth = _columnWidth;\n if (columnWidth > width) {\n columnWidth = width;\n }\n let showLabelColumn = _showLabelColumn;\n if (columnWidth > width - 10 || labelColumnClaimed) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != null || timescales != null) {\n _showTimescale = true;\n }\n _showTimescale = axisType == ColumnAxisType.AGE && _showTimescale;\n\n return h(\n ColumnContainer,\n {\n ...useMouseEventHandlers(onMouseOver),\n style: paddingVars,\n className,\n },\n h(\"div.column\", { ref: columnRef }, [\n h(ageAxisComponent),\n h.if(_showTimescale)(CompositeTimescale, {\n levels: timescaleLevels,\n additionalTimescales,\n timescales,\n showLabels: showTimescaleLabels,\n unconformityLabels: _timescaleUnconformityLabels,\n onClickInterval: onClickTimescaleInterval,\n intervalStyle: timescaleIntervalStyle,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\n labelSuppressHeight,\n clipUnits,\n unconformityLabels: _sectionUnconformityLabels,\n maxInternalColumns,\n }),\n children,\n ]),\n );\n}\n\ntype ColumnMouseOverHandler = (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n) => void;\n\nfunction useMouseEventHandlers(\n _onMouseOver: ColumnMouseOverHandler | null = null,\n) {\n /** Click event handler */\n\n // Click handler for unit selection\n const dispatch = useUnitSelectionDispatch();\n const onClick = useCallback(\n (evt) => {\n dispatch?.(null, null);\n },\n [dispatch],\n );\n\n /** Hover event handlers */\n const scale = useCompositeScale();\n\n const onMouseOver = useCallback(\n (evt) => {\n const height = scale.invert(\n evt.clientY - evt.currentTarget.getBoundingClientRect().top,\n );\n _onMouseOver?.(null, height, evt);\n },\n [scale, _onMouseOver],\n );\n\n const onMouseOut = useCallback(() => {\n _onMouseOver?.(null, null, null);\n }, [_onMouseOver]);\n\n if (_onMouseOver == null) {\n return {\n onClick,\n onMouseOver: undefined,\n onMouseMove: undefined,\n onMouseOut: undefined,\n };\n }\n\n return { onMouseOver, onMouseMove: onMouseOver, onMouseOut, onClick };\n}\n\nexport interface ColumnContainerProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n style?: CSSProperties;\n}\n\nexport function ColumnContainer(props: ColumnContainerProps) {\n const { className, ...rest } = props;\n const darkMode = useDarkMode();\n\n return h(Box, {\n className: classNames(\n className,\n {\n \"dark-mode\": darkMode?.isEnabled ?? false,\n },\n \"column-container\",\n ),\n ...rest,\n });\n}\n\nexport function ColumnBasicInfo({\n data,\n showColumnID = true,\n showReferences = true,\n}) {\n if (data == null) return null;\n return h(\"div.column-info\", [\n h(\"div.column-title-row\", [\n h(\"h2\", data.col_name),\n h.if(showColumnID)(\"h4\", h(Identifier, { id: data.col_id })),\n ]),\n h(DataField, { row: true, label: \"Group\", value: data.col_group }),\n h.if(showReferences)(ReferencesField, {\n refs: data.refs,\n inline: false,\n row: false,\n className: \"column-refs\",\n }),\n ]);\n}\n"],"names":["ColumnAxisType","CompositeAgeAxis","HybridScaleType","ApproximateHeightAxis","usePreparedColumnUnits","h","NonIdealState","MacrostratColumnDataProvider","UnitSelectionPopover","UnitKeyboardNavigation","extractPadding","UnitComponent","useMacrostratColumnData","useLabelColumnClaimed","useColumnRef","CompositeTimescale","SectionsColumn","useUnitSelectionDispatch","useCallback","useCompositeScale","useDarkMode","Box","classNames","Identifier","DataField","ReferencesField"],"mappings":"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"}
1
+ {"version":3,"file":"column.cjs","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport {\n Box,\n extractPadding,\n Padding,\n useDarkMode,\n} from \"@macrostrat/ui-components\";\nimport classNames from \"classnames\";\nimport {\n HTMLAttributes,\n useCallback,\n CSSProperties,\n ComponentType,\n RefObject,\n} from \"react\";\nimport h from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\n ColumnRef,\n UnitKeyboardNavigation,\n useColumnRef,\n useUnitSelectionDispatch,\n} from \"./data-provider\";\n\nimport {\n Identifier,\n ReferencesField,\n UnitSelectionPopover,\n} from \"./unit-details\";\nimport {\n MacrostratColumnDataProvider,\n useCompositeScale,\n useLabelColumnClaimed,\n useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\n type ColumnIntervalStyleBuilder,\n type ColumnTimescaleClickHandler,\n type ColumnTimescaleLike,\n SectionsColumn,\n} from \"./section\";\nimport { ApproximateHeightAxis, CompositeAgeAxis } from \"./age-axis\";\nimport {\n MergeSectionsMode,\n usePreparedColumnUnits,\n HybridScaleType,\n ColumnHeightScaleOptions,\n} from \"./prepare-units\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { NonIdealState } from \"@blueprintjs/core\";\nimport { DataField } from \"@macrostrat/data-components\";\nimport { ScaleContinuousNumeric } from \"d3-scale\";\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels\n * (default 2) */\n labelSuppressHeight?: number;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n /** Draw the age (or height) axis beside the column (default). Off for a\n * column whose coordinates aren't a measure — one laid out by surface order\n * alone, say. */\n showAgeAxis?: boolean;\n // Timescale properties\n /** Draw the timescale. Defaults to on for an age column; an explicit value\n * wins over `timescaleLevels` / `timescales`, which otherwise turn it on. */\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\n /** Regional or project timescales drawn as extra columns beside the\n * international one (see `CompositeTimescale`). Narrow `timescaleLevels` by\n * as many to swap the finest level for them rather than widen the column. */\n additionalTimescales?: number[];\n /** Every timescale to draw beside the column, in order: a Macrostrat\n * timescale ID, or a timescale with its own intervals (see\n * `CompositeTimescale`). Supersedes `timescaleLevels` and\n * `additionalTimescales`. */\n timescales?: ColumnTimescaleLike[];\n /** Draw each timescale's name above it */\n showTimescaleLabels?: boolean;\n /** Called when a timescale interval is clicked (e.g. to zoom the age range).\n * The data says which timescale it was clicked in. */\n onClickTimescaleInterval?: ColumnTimescaleClickHandler;\n /** Per-interval style for the timescale (e.g. to bold the selected\n * interval), by interval and the timescale it was drawn from. */\n timescaleIntervalStyle?: ColumnIntervalStyleBuilder;\n unconformityLabels?: boolean | UnconformityLabelPlacement;\n onMouseOver?: (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n ) => void;\n}\n\nexport type UnconformityLabelPlacement = \"minimal\" | \"prominent\" | \"none\";\n\nexport interface ColumnProps\n extends Padding, BaseColumnProps, ColumnHeightScaleOptions {\n // Macrostrat units\n units: UnitLong[];\n t_age?: number;\n b_age?: number;\n t_pos?: number;\n b_pos?: number;\n mergeSections?: MergeSectionsMode;\n showUnitPopover?: boolean;\n allowUnitSelection?: boolean;\n selectedUnit?: number | null;\n onUnitSelected?: (unitID: number | null, unit: any) => void;\n // Unconformity height in pixels\n unconformityHeight?: number;\n scale?: ScaleContinuousNumeric<number, number>;\n /** True while the age window is animating (e.g. from `useAnimatedAgeWindow`),\n * so per-frame label/pattern recalculation can be skipped. */\n isTransitioning?: boolean;\n /** Hide unit labels while transitioning (perf escape hatch; default false —\n * labels stay visible through the animation). */\n hideLabelsWhileTransitioning?: boolean;\n ref?: RefObject<ColumnRef>;\n}\n\nexport function Column(props: ColumnProps) {\n const {\n showUnitPopover = false,\n keyboardNavigation = false,\n mergeSections,\n onUnitSelected,\n selectedUnit,\n children,\n units: rawUnits,\n t_age,\n b_age,\n t_pos,\n b_pos,\n unconformityHeight = 30,\n targetUnitHeight = 20,\n sectionOptions,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n windowPadding = 0,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n ...rest\n } = props;\n\n /* `pixelScale` and `targetUnitHeight` are alternatives: a density stated\n * outright takes over from the one a section's units imply, floors and all.\n * That is settled in `prepare-units/density`, so nothing is adjusted here. */\n\n // Handle special cases for hybrid scales (WIP, we need to regularize this)\n let _axisType = axisType ?? ColumnAxisType.AGE;\n let ageAxisComponent = CompositeAgeAxis;\n if (\n hybridScale?.type === HybridScaleType.ApproximateHeight &&\n _axisType != ColumnAxisType.AGE\n ) {\n // Use approximate height axis for non-age columns if a non-age axis type is requested\n ageAxisComponent = ApproximateHeightAxis;\n _axisType = ColumnAxisType.AGE;\n }\n\n let _sectionOptions = sectionOptions;\n if (_sectionOptions == undefined) {\n // Build our own section options function based on targetUnitHeight\n _sectionOptions = (ctx) => {\n /** Scale targetUnitHeight by the number of units, so that a section with just a few units\n * is drawn taller than a section with many units.\n */\n const n = ctx.units.length;\n const expansionFactor = 8 / Math.min(Math.max(n, 1), 8);\n\n return {\n targetUnitHeight: targetUnitHeight * expansionFactor,\n };\n };\n }\n\n const { sections, units, totalHeight } = usePreparedColumnUnits(rawUnits, {\n axisType: _axisType,\n t_age,\n b_age,\n t_pos,\n b_pos,\n mergeSections,\n targetUnitHeight,\n sectionOptions: _sectionOptions,\n unconformityHeight,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale,\n minSectionHeight,\n windowPadding,\n collapseSmallUnconformities,\n // TODO: consider unifying scale and hybridScale options\n scale,\n hybridScale,\n });\n\n if (sections.length === 0) {\n return h(\n \"div.column-container.empty\",\n h(NonIdealState, {\n title: \"Empty column\",\n description: \"No sections found in this column.\",\n icon: \"warning-sign\",\n }),\n );\n }\n\n return h(\n MacrostratColumnDataProvider,\n {\n units,\n sections,\n totalHeight,\n axisType: _axisType,\n allowUnitSelection: showUnitPopover || allowUnitSelection,\n onUnitSelected,\n selectedUnit,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n },\n h(ColumnInner, { ageAxisComponent, ...rest }, [\n children,\n h.if(showUnitPopover)(UnitSelectionPopover),\n h.if(keyboardNavigation)(UnitKeyboardNavigation, { units }),\n ]),\n );\n}\n\ninterface ColumnInnerProps extends BaseColumnProps {\n ageAxisComponent?: ComponentType;\n}\n\nfunction ColumnInner(props: ColumnInnerProps) {\n const padding = extractPadding(props);\n\n // TODO: integrate padding vars more closely with the rest of the spacing (right now padding is a bit ad-hoc)\n const paddingVars: any = {\n \"--column-padding-top\": `${padding.paddingTop}px`,\n \"--column-padding-bottom\": `${padding.paddingBottom}px`,\n \"--column-padding-left\": `${padding.paddingLeft}px`,\n \"--column-padding-right\": `${padding.paddingRight}px`,\n };\n\n const {\n unitComponent = UnitComponent,\n unconformityLabels = \"minimal\",\n showLabels = true,\n width: _width = 300,\n columnWidth: _columnWidth = 150,\n showLabelColumn: _showLabelColumn = true,\n labelSuppressHeight,\n className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n additionalTimescales,\n timescales,\n showTimescaleLabels,\n maxInternalColumns,\n onMouseOver,\n onClickTimescaleInterval,\n timescaleIntervalStyle,\n ageAxisComponent = CompositeAgeAxis,\n showAgeAxis = true,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\n // A child layer drawing its own labels (the surfaces view) takes the label\n // column over from the unit labels\n const labelColumnClaimed = useLabelColumnClaimed();\n\n const columnRef = useColumnRef();\n\n // Coalesce unconformity label setting to a boolean\n let _timescaleUnconformityLabels = false;\n let _sectionUnconformityLabels = false;\n if (unconformityLabels === true || unconformityLabels === \"prominent\") {\n _sectionUnconformityLabels = true;\n } else if (unconformityLabels === \"minimal\") {\n _timescaleUnconformityLabels = true;\n }\n\n let width = _width;\n let columnWidth = _columnWidth;\n if (columnWidth > width) {\n columnWidth = width;\n }\n let showLabelColumn = _showLabelColumn;\n if (columnWidth > width - 10 || labelColumnClaimed) {\n showLabelColumn = false;\n }\n\n // On unless turned off outright: passing levels or timescales no longer\n // overrides an explicit `false`\n const _showTimescale = axisType == ColumnAxisType.AGE && (showTimescale ?? true);\n\n return h(\n ColumnContainer,\n {\n ...useMouseEventHandlers(onMouseOver),\n style: paddingVars,\n className,\n },\n h(\"div.column\", { ref: columnRef }, [\n h.if(showAgeAxis)(ageAxisComponent),\n h.if(_showTimescale)(CompositeTimescale, {\n levels: timescaleLevels,\n additionalTimescales,\n timescales,\n showLabels: showTimescaleLabels,\n unconformityLabels: _timescaleUnconformityLabels,\n onClickInterval: onClickTimescaleInterval,\n intervalStyle: timescaleIntervalStyle,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\n labelSuppressHeight,\n clipUnits,\n unconformityLabels: _sectionUnconformityLabels,\n maxInternalColumns,\n }),\n children,\n ]),\n );\n}\n\ntype ColumnMouseOverHandler = (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n) => void;\n\nfunction useMouseEventHandlers(\n _onMouseOver: ColumnMouseOverHandler | null = null,\n) {\n /** Click event handler */\n\n // Click handler for unit selection\n const dispatch = useUnitSelectionDispatch();\n const onClick = useCallback(\n (evt) => {\n dispatch?.(null, null);\n },\n [dispatch],\n );\n\n /** Hover event handlers */\n const scale = useCompositeScale();\n\n const onMouseOver = useCallback(\n (evt) => {\n const height = scale.invert(\n evt.clientY - evt.currentTarget.getBoundingClientRect().top,\n );\n _onMouseOver?.(null, height, evt);\n },\n [scale, _onMouseOver],\n );\n\n const onMouseOut = useCallback(() => {\n _onMouseOver?.(null, null, null);\n }, [_onMouseOver]);\n\n if (_onMouseOver == null) {\n return {\n onClick,\n onMouseOver: undefined,\n onMouseMove: undefined,\n onMouseOut: undefined,\n };\n }\n\n return { onMouseOver, onMouseMove: onMouseOver, onMouseOut, onClick };\n}\n\nexport interface ColumnContainerProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n style?: CSSProperties;\n}\n\nexport function ColumnContainer(props: ColumnContainerProps) {\n const { className, ...rest } = props;\n const darkMode = useDarkMode();\n\n return h(Box, {\n className: classNames(\n className,\n {\n \"dark-mode\": darkMode?.isEnabled ?? false,\n },\n \"column-container\",\n ),\n ...rest,\n });\n}\n\nexport function ColumnBasicInfo({\n data,\n showColumnID = true,\n showReferences = true,\n}) {\n if (data == null) return null;\n return h(\"div.column-info\", [\n h(\"div.column-title-row\", [\n h(\"h2\", data.col_name),\n h.if(showColumnID)(\"h4\", h(Identifier, { id: data.col_id })),\n ]),\n h(DataField, { row: true, label: \"Group\", value: data.col_group }),\n h.if(showReferences)(ReferencesField, {\n refs: data.refs,\n inline: false,\n row: false,\n className: \"column-refs\",\n }),\n ]);\n}\n"],"names":["ColumnAxisType","CompositeAgeAxis","HybridScaleType","ApproximateHeightAxis","usePreparedColumnUnits","h","NonIdealState","MacrostratColumnDataProvider","UnitSelectionPopover","UnitKeyboardNavigation","extractPadding","UnitComponent","useMacrostratColumnData","useLabelColumnClaimed","useColumnRef","CompositeTimescale","SectionsColumn","useUnitSelectionDispatch","useCallback","useCompositeScale","useDarkMode","Box","classNames","Identifier","DataField","ReferencesField"],"mappings":"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"}
package/dist/column.d.ts CHANGED
@@ -14,6 +14,12 @@ interface BaseColumnProps extends Omit<SectionSharedProps, "unconformityLabels">
14
14
  keyboardNavigation?: boolean;
15
15
  showLabels?: boolean;
16
16
  maxInternalColumns?: number;
17
+ /** Draw the age (or height) axis beside the column (default). Off for a
18
+ * column whose coordinates aren't a measure — one laid out by surface order
19
+ * alone, say. */
20
+ showAgeAxis?: boolean;
21
+ /** Draw the timescale. Defaults to on for an age column; an explicit value
22
+ * wins over `timescaleLevels` / `timescales`, which otherwise turn it on. */
17
23
  showTimescale?: boolean;
18
24
  timescaleLevels?: number | [number, number];
19
25
  /** Regional or project timescales drawn as extra columns beside the
package/dist/column.js CHANGED
@@ -142,7 +142,8 @@ function ColumnInner(props) {
142
142
  onMouseOver,
143
143
  onClickTimescaleInterval,
144
144
  timescaleIntervalStyle,
145
- ageAxisComponent = CompositeAgeAxis
145
+ ageAxisComponent = CompositeAgeAxis,
146
+ showAgeAxis = true
146
147
  } = props;
147
148
  const { axisType } = useMacrostratColumnData();
148
149
  const labelColumnClaimed = useLabelColumnClaimed();
@@ -163,11 +164,7 @@ function ColumnInner(props) {
163
164
  if (columnWidth > width - 10 || labelColumnClaimed) {
164
165
  showLabelColumn = false;
165
166
  }
166
- let _showTimescale = showTimescale ?? true;
167
- if (timescaleLevels != null || timescales != null) {
168
- _showTimescale = true;
169
- }
170
- _showTimescale = axisType == ColumnAxisType.AGE && _showTimescale;
167
+ const _showTimescale = axisType == ColumnAxisType.AGE && (showTimescale ?? true);
171
168
  return h(
172
169
  ColumnContainer,
173
170
  {
@@ -176,7 +173,7 @@ function ColumnInner(props) {
176
173
  className
177
174
  },
178
175
  h("div.column", { ref: columnRef }, [
179
- h(ageAxisComponent),
176
+ h.if(showAgeAxis)(ageAxisComponent),
180
177
  h.if(_showTimescale)(CompositeTimescale, {
181
178
  levels: timescaleLevels,
182
179
  additionalTimescales,
@@ -1 +1 @@
1
- {"version":3,"file":"column.js","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport {\n Box,\n extractPadding,\n Padding,\n useDarkMode,\n} from \"@macrostrat/ui-components\";\nimport classNames from \"classnames\";\nimport {\n HTMLAttributes,\n useCallback,\n CSSProperties,\n ComponentType,\n RefObject,\n} from \"react\";\nimport h from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\n ColumnRef,\n UnitKeyboardNavigation,\n useColumnRef,\n useUnitSelectionDispatch,\n} from \"./data-provider\";\n\nimport {\n Identifier,\n ReferencesField,\n UnitSelectionPopover,\n} from \"./unit-details\";\nimport {\n MacrostratColumnDataProvider,\n useCompositeScale,\n useLabelColumnClaimed,\n useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\n type ColumnIntervalStyleBuilder,\n type ColumnTimescaleClickHandler,\n type ColumnTimescaleLike,\n SectionsColumn,\n} from \"./section\";\nimport { ApproximateHeightAxis, CompositeAgeAxis } from \"./age-axis\";\nimport {\n MergeSectionsMode,\n usePreparedColumnUnits,\n HybridScaleType,\n ColumnHeightScaleOptions,\n} from \"./prepare-units\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { NonIdealState } from \"@blueprintjs/core\";\nimport { DataField } from \"@macrostrat/data-components\";\nimport { ScaleContinuousNumeric } from \"d3-scale\";\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels\n * (default 2) */\n labelSuppressHeight?: number;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\n /** Regional or project timescales drawn as extra columns beside the\n * international one (see `CompositeTimescale`). Narrow `timescaleLevels` by\n * as many to swap the finest level for them rather than widen the column. */\n additionalTimescales?: number[];\n /** Every timescale to draw beside the column, in order: a Macrostrat\n * timescale ID, or a timescale with its own intervals (see\n * `CompositeTimescale`). Supersedes `timescaleLevels` and\n * `additionalTimescales`. */\n timescales?: ColumnTimescaleLike[];\n /** Draw each timescale's name above it */\n showTimescaleLabels?: boolean;\n /** Called when a timescale interval is clicked (e.g. to zoom the age range).\n * The data says which timescale it was clicked in. */\n onClickTimescaleInterval?: ColumnTimescaleClickHandler;\n /** Per-interval style for the timescale (e.g. to bold the selected\n * interval), by interval and the timescale it was drawn from. */\n timescaleIntervalStyle?: ColumnIntervalStyleBuilder;\n unconformityLabels?: boolean | UnconformityLabelPlacement;\n onMouseOver?: (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n ) => void;\n}\n\nexport type UnconformityLabelPlacement = \"minimal\" | \"prominent\" | \"none\";\n\nexport interface ColumnProps\n extends Padding, BaseColumnProps, ColumnHeightScaleOptions {\n // Macrostrat units\n units: UnitLong[];\n t_age?: number;\n b_age?: number;\n t_pos?: number;\n b_pos?: number;\n mergeSections?: MergeSectionsMode;\n showUnitPopover?: boolean;\n allowUnitSelection?: boolean;\n selectedUnit?: number | null;\n onUnitSelected?: (unitID: number | null, unit: any) => void;\n // Unconformity height in pixels\n unconformityHeight?: number;\n scale?: ScaleContinuousNumeric<number, number>;\n /** True while the age window is animating (e.g. from `useAnimatedAgeWindow`),\n * so per-frame label/pattern recalculation can be skipped. */\n isTransitioning?: boolean;\n /** Hide unit labels while transitioning (perf escape hatch; default false —\n * labels stay visible through the animation). */\n hideLabelsWhileTransitioning?: boolean;\n ref?: RefObject<ColumnRef>;\n}\n\nexport function Column(props: ColumnProps) {\n const {\n showUnitPopover = false,\n keyboardNavigation = false,\n mergeSections,\n onUnitSelected,\n selectedUnit,\n children,\n units: rawUnits,\n t_age,\n b_age,\n t_pos,\n b_pos,\n unconformityHeight = 30,\n targetUnitHeight = 20,\n sectionOptions,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n windowPadding = 0,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n ...rest\n } = props;\n\n /* `pixelScale` and `targetUnitHeight` are alternatives: a density stated\n * outright takes over from the one a section's units imply, floors and all.\n * That is settled in `prepare-units/density`, so nothing is adjusted here. */\n\n // Handle special cases for hybrid scales (WIP, we need to regularize this)\n let _axisType = axisType ?? ColumnAxisType.AGE;\n let ageAxisComponent = CompositeAgeAxis;\n if (\n hybridScale?.type === HybridScaleType.ApproximateHeight &&\n _axisType != ColumnAxisType.AGE\n ) {\n // Use approximate height axis for non-age columns if a non-age axis type is requested\n ageAxisComponent = ApproximateHeightAxis;\n _axisType = ColumnAxisType.AGE;\n }\n\n let _sectionOptions = sectionOptions;\n if (_sectionOptions == undefined) {\n // Build our own section options function based on targetUnitHeight\n _sectionOptions = (ctx) => {\n /** Scale targetUnitHeight by the number of units, so that a section with just a few units\n * is drawn taller than a section with many units.\n */\n const n = ctx.units.length;\n const expansionFactor = 8 / Math.min(Math.max(n, 1), 8);\n\n return {\n targetUnitHeight: targetUnitHeight * expansionFactor,\n };\n };\n }\n\n const { sections, units, totalHeight } = usePreparedColumnUnits(rawUnits, {\n axisType: _axisType,\n t_age,\n b_age,\n t_pos,\n b_pos,\n mergeSections,\n targetUnitHeight,\n sectionOptions: _sectionOptions,\n unconformityHeight,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale,\n minSectionHeight,\n windowPadding,\n collapseSmallUnconformities,\n // TODO: consider unifying scale and hybridScale options\n scale,\n hybridScale,\n });\n\n if (sections.length === 0) {\n return h(\n \"div.column-container.empty\",\n h(NonIdealState, {\n title: \"Empty column\",\n description: \"No sections found in this column.\",\n icon: \"warning-sign\",\n }),\n );\n }\n\n return h(\n MacrostratColumnDataProvider,\n {\n units,\n sections,\n totalHeight,\n axisType: _axisType,\n allowUnitSelection: showUnitPopover || allowUnitSelection,\n onUnitSelected,\n selectedUnit,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n },\n h(ColumnInner, { ageAxisComponent, ...rest }, [\n children,\n h.if(showUnitPopover)(UnitSelectionPopover),\n h.if(keyboardNavigation)(UnitKeyboardNavigation, { units }),\n ]),\n );\n}\n\ninterface ColumnInnerProps extends BaseColumnProps {\n ageAxisComponent?: ComponentType;\n}\n\nfunction ColumnInner(props: ColumnInnerProps) {\n const padding = extractPadding(props);\n\n // TODO: integrate padding vars more closely with the rest of the spacing (right now padding is a bit ad-hoc)\n const paddingVars: any = {\n \"--column-padding-top\": `${padding.paddingTop}px`,\n \"--column-padding-bottom\": `${padding.paddingBottom}px`,\n \"--column-padding-left\": `${padding.paddingLeft}px`,\n \"--column-padding-right\": `${padding.paddingRight}px`,\n };\n\n const {\n unitComponent = UnitComponent,\n unconformityLabels = \"minimal\",\n showLabels = true,\n width: _width = 300,\n columnWidth: _columnWidth = 150,\n showLabelColumn: _showLabelColumn = true,\n labelSuppressHeight,\n className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n additionalTimescales,\n timescales,\n showTimescaleLabels,\n maxInternalColumns,\n onMouseOver,\n onClickTimescaleInterval,\n timescaleIntervalStyle,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\n // A child layer drawing its own labels (the surfaces view) takes the label\n // column over from the unit labels\n const labelColumnClaimed = useLabelColumnClaimed();\n\n const columnRef = useColumnRef();\n\n // Coalesce unconformity label setting to a boolean\n let _timescaleUnconformityLabels = false;\n let _sectionUnconformityLabels = false;\n if (unconformityLabels === true || unconformityLabels === \"prominent\") {\n _sectionUnconformityLabels = true;\n } else if (unconformityLabels === \"minimal\") {\n _timescaleUnconformityLabels = true;\n }\n\n let width = _width;\n let columnWidth = _columnWidth;\n if (columnWidth > width) {\n columnWidth = width;\n }\n let showLabelColumn = _showLabelColumn;\n if (columnWidth > width - 10 || labelColumnClaimed) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != null || timescales != null) {\n _showTimescale = true;\n }\n _showTimescale = axisType == ColumnAxisType.AGE && _showTimescale;\n\n return h(\n ColumnContainer,\n {\n ...useMouseEventHandlers(onMouseOver),\n style: paddingVars,\n className,\n },\n h(\"div.column\", { ref: columnRef }, [\n h(ageAxisComponent),\n h.if(_showTimescale)(CompositeTimescale, {\n levels: timescaleLevels,\n additionalTimescales,\n timescales,\n showLabels: showTimescaleLabels,\n unconformityLabels: _timescaleUnconformityLabels,\n onClickInterval: onClickTimescaleInterval,\n intervalStyle: timescaleIntervalStyle,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\n labelSuppressHeight,\n clipUnits,\n unconformityLabels: _sectionUnconformityLabels,\n maxInternalColumns,\n }),\n children,\n ]),\n );\n}\n\ntype ColumnMouseOverHandler = (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n) => void;\n\nfunction useMouseEventHandlers(\n _onMouseOver: ColumnMouseOverHandler | null = null,\n) {\n /** Click event handler */\n\n // Click handler for unit selection\n const dispatch = useUnitSelectionDispatch();\n const onClick = useCallback(\n (evt) => {\n dispatch?.(null, null);\n },\n [dispatch],\n );\n\n /** Hover event handlers */\n const scale = useCompositeScale();\n\n const onMouseOver = useCallback(\n (evt) => {\n const height = scale.invert(\n evt.clientY - evt.currentTarget.getBoundingClientRect().top,\n );\n _onMouseOver?.(null, height, evt);\n },\n [scale, _onMouseOver],\n );\n\n const onMouseOut = useCallback(() => {\n _onMouseOver?.(null, null, null);\n }, [_onMouseOver]);\n\n if (_onMouseOver == null) {\n return {\n onClick,\n onMouseOver: undefined,\n onMouseMove: undefined,\n onMouseOut: undefined,\n };\n }\n\n return { onMouseOver, onMouseMove: onMouseOver, onMouseOut, onClick };\n}\n\nexport interface ColumnContainerProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n style?: CSSProperties;\n}\n\nexport function ColumnContainer(props: ColumnContainerProps) {\n const { className, ...rest } = props;\n const darkMode = useDarkMode();\n\n return h(Box, {\n className: classNames(\n className,\n {\n \"dark-mode\": darkMode?.isEnabled ?? false,\n },\n \"column-container\",\n ),\n ...rest,\n });\n}\n\nexport function ColumnBasicInfo({\n data,\n showColumnID = true,\n showReferences = true,\n}) {\n if (data == null) return null;\n return h(\"div.column-info\", [\n h(\"div.column-title-row\", [\n h(\"h2\", data.col_name),\n h.if(showColumnID)(\"h4\", h(Identifier, { id: data.col_id })),\n ]),\n h(DataField, { row: true, label: \"Group\", value: data.col_group }),\n h.if(showReferences)(ReferencesField, {\n refs: data.refs,\n inline: false,\n row: false,\n className: \"column-refs\",\n }),\n ]);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"column.js","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport {\n Box,\n extractPadding,\n Padding,\n useDarkMode,\n} from \"@macrostrat/ui-components\";\nimport classNames from \"classnames\";\nimport {\n HTMLAttributes,\n useCallback,\n CSSProperties,\n ComponentType,\n RefObject,\n} from \"react\";\nimport h from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\n ColumnRef,\n UnitKeyboardNavigation,\n useColumnRef,\n useUnitSelectionDispatch,\n} from \"./data-provider\";\n\nimport {\n Identifier,\n ReferencesField,\n UnitSelectionPopover,\n} from \"./unit-details\";\nimport {\n MacrostratColumnDataProvider,\n useCompositeScale,\n useLabelColumnClaimed,\n useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\n type ColumnIntervalStyleBuilder,\n type ColumnTimescaleClickHandler,\n type ColumnTimescaleLike,\n SectionsColumn,\n} from \"./section\";\nimport { ApproximateHeightAxis, CompositeAgeAxis } from \"./age-axis\";\nimport {\n MergeSectionsMode,\n usePreparedColumnUnits,\n HybridScaleType,\n ColumnHeightScaleOptions,\n} from \"./prepare-units\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { NonIdealState } from \"@blueprintjs/core\";\nimport { DataField } from \"@macrostrat/data-components\";\nimport { ScaleContinuousNumeric } from \"d3-scale\";\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels\n * (default 2) */\n labelSuppressHeight?: number;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n /** Draw the age (or height) axis beside the column (default). Off for a\n * column whose coordinates aren't a measure — one laid out by surface order\n * alone, say. */\n showAgeAxis?: boolean;\n // Timescale properties\n /** Draw the timescale. Defaults to on for an age column; an explicit value\n * wins over `timescaleLevels` / `timescales`, which otherwise turn it on. */\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\n /** Regional or project timescales drawn as extra columns beside the\n * international one (see `CompositeTimescale`). Narrow `timescaleLevels` by\n * as many to swap the finest level for them rather than widen the column. */\n additionalTimescales?: number[];\n /** Every timescale to draw beside the column, in order: a Macrostrat\n * timescale ID, or a timescale with its own intervals (see\n * `CompositeTimescale`). Supersedes `timescaleLevels` and\n * `additionalTimescales`. */\n timescales?: ColumnTimescaleLike[];\n /** Draw each timescale's name above it */\n showTimescaleLabels?: boolean;\n /** Called when a timescale interval is clicked (e.g. to zoom the age range).\n * The data says which timescale it was clicked in. */\n onClickTimescaleInterval?: ColumnTimescaleClickHandler;\n /** Per-interval style for the timescale (e.g. to bold the selected\n * interval), by interval and the timescale it was drawn from. */\n timescaleIntervalStyle?: ColumnIntervalStyleBuilder;\n unconformityLabels?: boolean | UnconformityLabelPlacement;\n onMouseOver?: (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n ) => void;\n}\n\nexport type UnconformityLabelPlacement = \"minimal\" | \"prominent\" | \"none\";\n\nexport interface ColumnProps\n extends Padding, BaseColumnProps, ColumnHeightScaleOptions {\n // Macrostrat units\n units: UnitLong[];\n t_age?: number;\n b_age?: number;\n t_pos?: number;\n b_pos?: number;\n mergeSections?: MergeSectionsMode;\n showUnitPopover?: boolean;\n allowUnitSelection?: boolean;\n selectedUnit?: number | null;\n onUnitSelected?: (unitID: number | null, unit: any) => void;\n // Unconformity height in pixels\n unconformityHeight?: number;\n scale?: ScaleContinuousNumeric<number, number>;\n /** True while the age window is animating (e.g. from `useAnimatedAgeWindow`),\n * so per-frame label/pattern recalculation can be skipped. */\n isTransitioning?: boolean;\n /** Hide unit labels while transitioning (perf escape hatch; default false —\n * labels stay visible through the animation). */\n hideLabelsWhileTransitioning?: boolean;\n ref?: RefObject<ColumnRef>;\n}\n\nexport function Column(props: ColumnProps) {\n const {\n showUnitPopover = false,\n keyboardNavigation = false,\n mergeSections,\n onUnitSelected,\n selectedUnit,\n children,\n units: rawUnits,\n t_age,\n b_age,\n t_pos,\n b_pos,\n unconformityHeight = 30,\n targetUnitHeight = 20,\n sectionOptions,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n windowPadding = 0,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n ...rest\n } = props;\n\n /* `pixelScale` and `targetUnitHeight` are alternatives: a density stated\n * outright takes over from the one a section's units imply, floors and all.\n * That is settled in `prepare-units/density`, so nothing is adjusted here. */\n\n // Handle special cases for hybrid scales (WIP, we need to regularize this)\n let _axisType = axisType ?? ColumnAxisType.AGE;\n let ageAxisComponent = CompositeAgeAxis;\n if (\n hybridScale?.type === HybridScaleType.ApproximateHeight &&\n _axisType != ColumnAxisType.AGE\n ) {\n // Use approximate height axis for non-age columns if a non-age axis type is requested\n ageAxisComponent = ApproximateHeightAxis;\n _axisType = ColumnAxisType.AGE;\n }\n\n let _sectionOptions = sectionOptions;\n if (_sectionOptions == undefined) {\n // Build our own section options function based on targetUnitHeight\n _sectionOptions = (ctx) => {\n /** Scale targetUnitHeight by the number of units, so that a section with just a few units\n * is drawn taller than a section with many units.\n */\n const n = ctx.units.length;\n const expansionFactor = 8 / Math.min(Math.max(n, 1), 8);\n\n return {\n targetUnitHeight: targetUnitHeight * expansionFactor,\n };\n };\n }\n\n const { sections, units, totalHeight } = usePreparedColumnUnits(rawUnits, {\n axisType: _axisType,\n t_age,\n b_age,\n t_pos,\n b_pos,\n mergeSections,\n targetUnitHeight,\n sectionOptions: _sectionOptions,\n unconformityHeight,\n pixelScale,\n pixelsPerMyr,\n pixelsPerMeter,\n minPixelScale,\n minSectionHeight,\n windowPadding,\n collapseSmallUnconformities,\n // TODO: consider unifying scale and hybridScale options\n scale,\n hybridScale,\n });\n\n if (sections.length === 0) {\n return h(\n \"div.column-container.empty\",\n h(NonIdealState, {\n title: \"Empty column\",\n description: \"No sections found in this column.\",\n icon: \"warning-sign\",\n }),\n );\n }\n\n return h(\n MacrostratColumnDataProvider,\n {\n units,\n sections,\n totalHeight,\n axisType: _axisType,\n allowUnitSelection: showUnitPopover || allowUnitSelection,\n onUnitSelected,\n selectedUnit,\n isTransitioning,\n hideLabelsWhileTransitioning,\n ref,\n },\n h(ColumnInner, { ageAxisComponent, ...rest }, [\n children,\n h.if(showUnitPopover)(UnitSelectionPopover),\n h.if(keyboardNavigation)(UnitKeyboardNavigation, { units }),\n ]),\n );\n}\n\ninterface ColumnInnerProps extends BaseColumnProps {\n ageAxisComponent?: ComponentType;\n}\n\nfunction ColumnInner(props: ColumnInnerProps) {\n const padding = extractPadding(props);\n\n // TODO: integrate padding vars more closely with the rest of the spacing (right now padding is a bit ad-hoc)\n const paddingVars: any = {\n \"--column-padding-top\": `${padding.paddingTop}px`,\n \"--column-padding-bottom\": `${padding.paddingBottom}px`,\n \"--column-padding-left\": `${padding.paddingLeft}px`,\n \"--column-padding-right\": `${padding.paddingRight}px`,\n };\n\n const {\n unitComponent = UnitComponent,\n unconformityLabels = \"minimal\",\n showLabels = true,\n width: _width = 300,\n columnWidth: _columnWidth = 150,\n showLabelColumn: _showLabelColumn = true,\n labelSuppressHeight,\n className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n additionalTimescales,\n timescales,\n showTimescaleLabels,\n maxInternalColumns,\n onMouseOver,\n onClickTimescaleInterval,\n timescaleIntervalStyle,\n ageAxisComponent = CompositeAgeAxis,\n showAgeAxis = true,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\n // A child layer drawing its own labels (the surfaces view) takes the label\n // column over from the unit labels\n const labelColumnClaimed = useLabelColumnClaimed();\n\n const columnRef = useColumnRef();\n\n // Coalesce unconformity label setting to a boolean\n let _timescaleUnconformityLabels = false;\n let _sectionUnconformityLabels = false;\n if (unconformityLabels === true || unconformityLabels === \"prominent\") {\n _sectionUnconformityLabels = true;\n } else if (unconformityLabels === \"minimal\") {\n _timescaleUnconformityLabels = true;\n }\n\n let width = _width;\n let columnWidth = _columnWidth;\n if (columnWidth > width) {\n columnWidth = width;\n }\n let showLabelColumn = _showLabelColumn;\n if (columnWidth > width - 10 || labelColumnClaimed) {\n showLabelColumn = false;\n }\n\n // On unless turned off outright: passing levels or timescales no longer\n // overrides an explicit `false`\n const _showTimescale = axisType == ColumnAxisType.AGE && (showTimescale ?? true);\n\n return h(\n ColumnContainer,\n {\n ...useMouseEventHandlers(onMouseOver),\n style: paddingVars,\n className,\n },\n h(\"div.column\", { ref: columnRef }, [\n h.if(showAgeAxis)(ageAxisComponent),\n h.if(_showTimescale)(CompositeTimescale, {\n levels: timescaleLevels,\n additionalTimescales,\n timescales,\n showLabels: showTimescaleLabels,\n unconformityLabels: _timescaleUnconformityLabels,\n onClickInterval: onClickTimescaleInterval,\n intervalStyle: timescaleIntervalStyle,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\n labelSuppressHeight,\n clipUnits,\n unconformityLabels: _sectionUnconformityLabels,\n maxInternalColumns,\n }),\n children,\n ]),\n );\n}\n\ntype ColumnMouseOverHandler = (\n unit: UnitLong | null,\n height: number | null,\n evt: MouseEvent,\n) => void;\n\nfunction useMouseEventHandlers(\n _onMouseOver: ColumnMouseOverHandler | null = null,\n) {\n /** Click event handler */\n\n // Click handler for unit selection\n const dispatch = useUnitSelectionDispatch();\n const onClick = useCallback(\n (evt) => {\n dispatch?.(null, null);\n },\n [dispatch],\n );\n\n /** Hover event handlers */\n const scale = useCompositeScale();\n\n const onMouseOver = useCallback(\n (evt) => {\n const height = scale.invert(\n evt.clientY - evt.currentTarget.getBoundingClientRect().top,\n );\n _onMouseOver?.(null, height, evt);\n },\n [scale, _onMouseOver],\n );\n\n const onMouseOut = useCallback(() => {\n _onMouseOver?.(null, null, null);\n }, [_onMouseOver]);\n\n if (_onMouseOver == null) {\n return {\n onClick,\n onMouseOver: undefined,\n onMouseMove: undefined,\n onMouseOut: undefined,\n };\n }\n\n return { onMouseOver, onMouseMove: onMouseOver, onMouseOut, onClick };\n}\n\nexport interface ColumnContainerProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n style?: CSSProperties;\n}\n\nexport function ColumnContainer(props: ColumnContainerProps) {\n const { className, ...rest } = props;\n const darkMode = useDarkMode();\n\n return h(Box, {\n className: classNames(\n className,\n {\n \"dark-mode\": darkMode?.isEnabled ?? false,\n },\n \"column-container\",\n ),\n ...rest,\n });\n}\n\nexport function ColumnBasicInfo({\n data,\n showColumnID = true,\n showReferences = true,\n}) {\n if (data == null) return null;\n return h(\"div.column-info\", [\n h(\"div.column-title-row\", [\n h(\"h2\", data.col_name),\n h.if(showColumnID)(\"h4\", h(Identifier, { id: data.col_id })),\n ]),\n h(DataField, { row: true, label: \"Group\", value: data.col_group }),\n h.if(showReferences)(ReferencesField, {\n refs: data.refs,\n inline: false,\n row: false,\n className: \"column-refs\",\n }),\n ]);\n}\n"],"names":[],"mappings":"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"}
@@ -324,7 +324,7 @@ function ThicknessField({ unit, label = "Thickness" }) {
324
324
  });
325
325
  }
326
326
  function BibInfo({ refs }) {
327
- const refData = dataProvider.useMacrostratData("refs", refs);
327
+ const refData = dataProvider.useMacrostratData("refs", refs)?.filter((d) => d != null);
328
328
  if (refData == null || refData.length === 0) {
329
329
  return null;
330
330
  }
@@ -1 +1 @@
1
- {"version":3,"file":"panel.cjs","sources":["../../src/unit-details/panel.ts"],"sourcesContent":["import { JSONView } from \"@macrostrat/ui-components\";\nimport { Button, ButtonGroup } from \"@blueprintjs/core\";\nimport { ReactNode, useMemo, useState } from \"react\";\nimport {\n DataField,\n EnvironmentsList,\n ItemList,\n LithologyList,\n LithologyTagFeature,\n MacrostratInteractionManager,\n MacrostratInteractionProvider,\n MacrostratItemIdentifier,\n Parenthetical,\n useInteractionManager,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useColumnUnitsMap } from \"../data-provider\";\nimport {\n useMacrostratColumnInfo,\n useMacrostratData,\n useMacrostratDefs,\n} from \"@macrostrat/data-provider\";\nimport type {\n Environment,\n EnvironmentIdentifier,\n Interval,\n Lithology,\n UnitLong,\n UnitLongFull,\n} from \"@macrostrat/api-types\";\nimport { defaultNameFunction } from \"../units/names\";\nimport classNames from \"classnames\";\nimport { AgeField, Duration, IntervalProportions } from \"./age-range\";\nimport { formatRange, formatSignificance } from \"./utils.ts\";\nimport h from \"./panel.module.sass\";\nimport { StratNameField } from \"./strat-names.ts\";\nimport {\n Identifier,\n UnitIdentifier,\n UnitInfo,\n} from \"@macrostrat/data-components\";\nimport { LithologyIdentifier } from \"@macrostrat/api-types/src/lithologies\";\n\nexport interface UnitDetailsPanelProps {\n unit: any;\n onClose?: any;\n className?: string;\n actions?: ReactNode;\n hiddenActions?: ReactNode;\n features?: Set<UnitDetailsFeature>;\n lithologyFeatures?: Set<LithologyTagFeature>;\n onSelectUnit?: (unitID: number) => void;\n onClickItem?: MacrostratItemClickHandler;\n interactionManager?: MacrostratInteractionManager;\n showJSON?: boolean;\n}\n\nexport function UnitDetailsPanel({\n unit,\n onClose,\n className,\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n UnitDetailsFeature.JSONToggle,\n UnitDetailsFeature.DepthRange,\n ]),\n lithologyFeatures,\n actions,\n hiddenActions = null,\n onSelectUnit,\n onClickItem,\n showJSON,\n}: UnitDetailsPanelProps) {\n const [_showJSON, setShowJSON] = useState(false);\n\n let content: ReactNode = null;\n if (showJSON ?? _showJSON) {\n content = h(JSONView, { data: unit, showRoot: false });\n } else {\n content = h(UnitDetailsContent, {\n unit,\n features,\n lithologyFeatures,\n onClickItem,\n });\n }\n\n let title = defaultNameFunction(unit);\n\n if (features.has(UnitDetailsFeature.JSONToggle)) {\n hiddenActions = h([\n h(Button, {\n icon: \"code\",\n small: true,\n minimal: true,\n key: \"json-view-toggle\",\n className: classNames(\"json-view-toggle\", { enabled: setShowJSON }),\n onClick(evt) {\n setShowJSON(!_showJSON);\n evt.stopPropagation();\n },\n }),\n hiddenActions,\n ]);\n }\n\n const main = h(\"div.unit-details-panel\", { className }, [\n h(LegendPanelHeader, {\n onClose,\n title,\n id: unit.unit_id,\n actions,\n hiddenActions,\n }),\n h(\"div.unit-details-content-holder\", content),\n ]);\n\n /** Handle unit selection clicks */\n const clickHandlerForItem = useMemo(() => {\n if (onSelectUnit == null && onClickItem == null) return null;\n return (item: MacrostratItemIdentifier) => {\n if (\"unit_id\" in item && !(\"col_id\" in item)) {\n // We are selecting a unit within the column\n return (event: MouseEvent) => {\n if (onSelectUnit != null) {\n onSelectUnit(item.unit_id);\n } else if (onClickItem != null) {\n console.warn(\n \"Unit selection: onClickItem is defined but onSelectUnit is not; ignoring click\",\n );\n }\n // Don't allow event to propagate further (e.g., to open a link)\n event.preventDefault();\n };\n }\n return undefined;\n };\n }, [onSelectUnit, onClickItem]);\n\n if (clickHandlerForItem != null) {\n // We wrap this in a MacrostratInteractionManager to handle unit selection\n return h(\n MacrostratInteractionProvider,\n {\n clickHandlerForItem,\n inherit: true,\n },\n main,\n );\n }\n\n return main;\n}\n\nexport function LegendPanelHeader({\n title,\n id,\n onClose,\n actions = null,\n hiddenActions,\n}: {\n title?: string | null;\n id?: number | null;\n onClose?: () => void;\n actions?: ReactNode | null;\n hiddenActions?: ReactNode | null;\n}) {\n return h(\"header.legend-panel-header\", [\n h(\"div.title-container\", [\n h.if(title != null)(\"h3\", title),\n h.if(hiddenActions != null)(\n \"span.hidden-actions-container\",\n h(\"div.hidden-actions\", hiddenActions),\n ),\n ]),\n h(\"div.spacer\"),\n h.if(id != null)(\"code.unit-id\", id),\n h.if(actions != null)(ButtonGroup, { minimal: true }, actions),\n h.if(onClose != null)(Button, {\n icon: \"cross\",\n minimal: true,\n small: true,\n onClick() {\n onClose?.();\n },\n }),\n ]);\n}\n\nexport enum UnitDetailsFeature {\n AdjacentUnits = \"adjacent-units\",\n Color = \"color\",\n OutcropType = \"outcrop-type\",\n JSONToggle = \"json-toggle\",\n DepthRange = \"depth-range\",\n ColumnName = \"column-name\",\n}\n\nexport type MacrostratItemClickHandler = (\n event: MouseEvent,\n item:\n Lithology | Environment | UnitLong | Interval | { strat_name_id: number },\n) => void;\n\nfunction UnitDetailsContent({\n unit,\n lithologyFeatures = new Set([\n LithologyTagFeature.Proportion,\n LithologyTagFeature.Attributes,\n ]),\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n ]),\n onClickItem,\n getItemHref,\n}: {\n unit: UnitLong;\n lithologyFeatures?: Set<LithologyTagFeature>;\n features?: Set<UnitDetailsFeature>;\n onClickItem?: MacrostratItemClickHandler;\n getItemHref?: (item: Lithology | Environment | UnitLong) => string | null;\n}) {\n const lithMap = useMacrostratDefs(\"lithologies\");\n const envMap = useMacrostratDefs(\"environments\");\n\n const environments = enhanceEnvironments(unit.environ, envMap);\n const lithologies = enhanceLithologies(unit.lith ?? [], lithMap);\n\n let outcropField: ReactNode = null;\n if (features.has(UnitDetailsFeature.OutcropType)) {\n // Determine outcrop type\n let outcrop = unit.outcrop;\n if (outcrop == \"both\") {\n outcrop = \"surface and subsurface\";\n }\n outcropField = h(DataField, {\n label: \"Outcrop\",\n value: outcrop,\n });\n }\n\n let thicknessOrHeightRange: ReactNode = null;\n const [thickness, thicknessUnit] = getThickness(unit);\n // Proxy for actual heights in t_pos and b_pos\n if (\n features.has(UnitDetailsFeature.DepthRange) &&\n unit.t_pos != null &&\n unit.b_pos != null &&\n unit.min_thick == unit.max_thick && // We have an actual fixed height\n unit.min_thick != 0 // Not a zero thickness\n ) {\n const label = unit.t_pos < unit.b_pos ? \"Depth\" : \"Height\";\n const u1 = \"m\";\n\n thicknessOrHeightRange = h(DataField, {\n unit: u1,\n label,\n value: formatRange(unit.b_pos, unit.t_pos),\n children: h(\n Parenthetical,\n h(Value, { value: thickness, unit: thicknessUnit }),\n ),\n });\n }\n thicknessOrHeightRange ??= h(DataField, {\n label: \"Thickness\",\n value: thickness,\n unit: thicknessUnit,\n });\n\n /** We are trying to move away from passing the \"color\" parameter in the API */\n let colorSwatch: ReactNode = null;\n if (\"color\" in unit && features.has(UnitDetailsFeature.Color)) {\n const unit1 = unit as UnitLongFull;\n colorSwatch = h(\"div.color-swatch\", {\n style: { backgroundColor: unit1.color },\n });\n }\n\n return h(\"div.unit-details-content\", [\n h.if(features.has(UnitDetailsFeature.ColumnName))(ColumnNameField, {\n col_id: unit.col_id,\n }),\n thicknessOrHeightRange,\n h.if(lithologies != null)(LithologyList, {\n label: \"Lithology\",\n lithologies: lithologies ?? [],\n features: lithologyFeatures,\n }),\n h(AgeField, { unit }, [\n h(Parenthetical, h(Duration, { value: unit.b_age - unit.t_age })),\n h(IntervalProportions, {\n unit,\n onClickItem,\n }),\n ]),\n h.if(environments != null)(EnvironmentsList, {\n environments,\n }),\n h.if(unit.strat_name_id != null)(StratNameField, {\n strat_name_id: unit.strat_name_id,\n }),\n outcropField,\n h.if(features.has(UnitDetailsFeature.AdjacentUnits))([\n h.if(unit.units_above != null)(\n DataField,\n { label: \"Above\" },\n h(UnitIDList, {\n units: unit.units_above,\n showNames: true,\n }),\n ),\n h.if(unit.units_below != null)(\n DataField,\n { label: \"Below\" },\n h(UnitIDList, {\n units: unit.units_below,\n showNames: true,\n }),\n ),\n ]),\n colorSwatch,\n h(ReferencesField, { refs: unit.refs, inline: true }),\n ]);\n}\n\nfunction ColumnNameField({\n col_id,\n showIdentifier = false,\n}: {\n col_id: number;\n showIdentifier?: boolean;\n}) {\n const colData = useMacrostratColumnInfo(col_id);\n let inner: any = h(Identifier, { id: col_id });\n const name = colData?.col_name;\n if (name != null) {\n inner = h(\"span.value\", [\n h(\"span.col-name\", name),\n h.if(showIdentifier)([\" \", h(Parenthetical, inner)]),\n ]);\n }\n\n return h(\n DataField,\n {\n label: \"Column\",\n },\n inner,\n );\n}\n\nexport function ReferencesField({ refs, className = null, ...rest }) {\n if (refs == null || refs.length === 0) {\n return null;\n }\n\n return h(\n DataField,\n {\n label: \"References\",\n className: classNames(\"refs-field\", className),\n ...rest,\n },\n h(BibInfo, { refs }),\n );\n}\n\nfunction getThickness(unit): [string, string | null] {\n let minThickness = unit.min_thick ?? 0;\n let maxThickness = unit.max_thick ?? unit.min_thick ?? 0;\n let _unit = \"m\";\n\n if (minThickness == 0 && maxThickness == 0) {\n return [\"Unknown\", null];\n }\n\n if (minThickness < 0.8 && maxThickness < 1.2) {\n // Convert to cm\n minThickness = minThickness * 100;\n maxThickness = maxThickness * 100;\n _unit = \"cm\";\n } else if (minThickness > 800 && maxThickness > 1200) {\n // Convert to km\n minThickness = minThickness / 1000;\n maxThickness = maxThickness / 1000;\n _unit = \"km\";\n }\n\n if (minThickness == maxThickness) {\n return [formatSignificance(minThickness), _unit];\n }\n\n return [formatRange(minThickness, maxThickness), _unit];\n}\n\nexport function ThicknessField({ unit, label = \"Thickness\" }) {\n const [value, thicknessUnit] = getThickness(unit);\n return h(DataField, {\n label,\n value,\n unit: thicknessUnit,\n });\n}\n\nfunction BibInfo({ refs }) {\n const refData = useMacrostratData(\"refs\", refs);\n\n if (refData == null || refData.length === 0) {\n return null;\n }\n\n if (refData.length == 1) {\n return h(Citation, {\n data: refData[0],\n tag: \"span\",\n key: refData[0].ref_id,\n });\n }\n\n return h(\n \"ul.refs\",\n refData.map((data, i) =>\n h(Citation, { data, tag: \"li\", key: data.ref_id }),\n ),\n );\n}\n\nfunction Citation({ data, tag = \"p\" }) {\n return h(tag, { className: \"citation\" }, [\n h(\"span.authors\", data.author),\n \", \",\n h(\"span.year\", data.pub_year),\n \", \",\n h(\"span.title\", data.ref),\n ]);\n}\n\nfunction enhanceEnvironments(\n environments?: EnvironmentIdentifier[] | null,\n envMap?: Map<number, Environment> | null,\n) {\n return environments?.map((env) => {\n return {\n ...(envMap?.get(env.environ_id) ?? {}),\n ...env,\n };\n });\n}\n\nfunction enhanceLithologies(\n lithologies?: LithologyIdentifier[] | null,\n lithMap?: Map<number, any> | null,\n) {\n return lithologies?.map((lith) => {\n return {\n ...(lithMap?.get(lith.lith_id) ?? {}), // get lithology details\n ...lith, // override with the unit's specific lithology data\n };\n });\n}\n\nfunction UnitIDList({ units, showNames = false }) {\n const unitsMap = useColumnUnitsMap();\n\n const interactionManager = useInteractionManager();\n\n const extUnits: UnitInfo[] = useMemo(() => {\n const u1 = units.filter((d) => d != 0);\n if (showNames) {\n return u1.map((unitID) => {\n const unitData = unitsMap?.get(unitID);\n let name: string | null = null;\n if (unitData != null) {\n name = defaultNameFunction(unitData);\n }\n return {\n unitID,\n colID: unitData?.col_id,\n name,\n };\n });\n } else {\n return u1.map((unitID) => ({ unitID }));\n }\n }, [units, unitsMap]);\n\n if (extUnits.length === 0) {\n return h(\"span.no-units\", \"None\");\n }\n\n return h(\n ItemList,\n { className: \"units-list\" },\n extUnits.map((info) => {\n return h(\n \"span.item\",\n h(UnitIdentifier, {\n ...info,\n ...interactionManager?.interactionPropsForItem({\n unit_id: info.unitID,\n }),\n }),\n );\n }),\n );\n}\n"],"names":["useState","h","JSONView","defaultNameFunction","Button","classNames","useMemo","MacrostratInteractionProvider","ButtonGroup","UnitDetailsFeature","LithologyTagFeature","useMacrostratDefs","DataField","formatRange","Parenthetical","Value","LithologyList","AgeField","Duration","IntervalProportions","EnvironmentsList","StratNameField","useMacrostratColumnInfo","Identifier","formatSignificance","useMacrostratData","useColumnUnitsMap","useInteractionManager","ItemList","UnitIdentifier"],"mappings":"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"}
1
+ {"version":3,"file":"panel.cjs","sources":["../../src/unit-details/panel.ts"],"sourcesContent":["import { JSONView } from \"@macrostrat/ui-components\";\nimport { Button, ButtonGroup } from \"@blueprintjs/core\";\nimport { ReactNode, useMemo, useState } from \"react\";\nimport {\n DataField,\n EnvironmentsList,\n ItemList,\n LithologyList,\n LithologyTagFeature,\n MacrostratInteractionManager,\n MacrostratInteractionProvider,\n MacrostratItemIdentifier,\n Parenthetical,\n useInteractionManager,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useColumnUnitsMap } from \"../data-provider\";\nimport {\n useMacrostratColumnInfo,\n useMacrostratData,\n useMacrostratDefs,\n} from \"@macrostrat/data-provider\";\nimport type {\n Environment,\n EnvironmentIdentifier,\n Interval,\n Lithology,\n UnitLong,\n UnitLongFull,\n} from \"@macrostrat/api-types\";\nimport { defaultNameFunction } from \"../units/names\";\nimport classNames from \"classnames\";\nimport { AgeField, Duration, IntervalProportions } from \"./age-range\";\nimport { formatRange, formatSignificance } from \"./utils.ts\";\nimport h from \"./panel.module.sass\";\nimport { StratNameField } from \"./strat-names.ts\";\nimport {\n Identifier,\n UnitIdentifier,\n UnitInfo,\n} from \"@macrostrat/data-components\";\nimport { LithologyIdentifier } from \"@macrostrat/api-types/src/lithologies\";\n\nexport interface UnitDetailsPanelProps {\n unit: any;\n onClose?: any;\n className?: string;\n actions?: ReactNode;\n hiddenActions?: ReactNode;\n features?: Set<UnitDetailsFeature>;\n lithologyFeatures?: Set<LithologyTagFeature>;\n onSelectUnit?: (unitID: number) => void;\n onClickItem?: MacrostratItemClickHandler;\n interactionManager?: MacrostratInteractionManager;\n showJSON?: boolean;\n}\n\nexport function UnitDetailsPanel({\n unit,\n onClose,\n className,\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n UnitDetailsFeature.JSONToggle,\n UnitDetailsFeature.DepthRange,\n ]),\n lithologyFeatures,\n actions,\n hiddenActions = null,\n onSelectUnit,\n onClickItem,\n showJSON,\n}: UnitDetailsPanelProps) {\n const [_showJSON, setShowJSON] = useState(false);\n\n let content: ReactNode = null;\n if (showJSON ?? _showJSON) {\n content = h(JSONView, { data: unit, showRoot: false });\n } else {\n content = h(UnitDetailsContent, {\n unit,\n features,\n lithologyFeatures,\n onClickItem,\n });\n }\n\n let title = defaultNameFunction(unit);\n\n if (features.has(UnitDetailsFeature.JSONToggle)) {\n hiddenActions = h([\n h(Button, {\n icon: \"code\",\n small: true,\n minimal: true,\n key: \"json-view-toggle\",\n className: classNames(\"json-view-toggle\", { enabled: setShowJSON }),\n onClick(evt) {\n setShowJSON(!_showJSON);\n evt.stopPropagation();\n },\n }),\n hiddenActions,\n ]);\n }\n\n const main = h(\"div.unit-details-panel\", { className }, [\n h(LegendPanelHeader, {\n onClose,\n title,\n id: unit.unit_id,\n actions,\n hiddenActions,\n }),\n h(\"div.unit-details-content-holder\", content),\n ]);\n\n /** Handle unit selection clicks */\n const clickHandlerForItem = useMemo(() => {\n if (onSelectUnit == null && onClickItem == null) return null;\n return (item: MacrostratItemIdentifier) => {\n if (\"unit_id\" in item && !(\"col_id\" in item)) {\n // We are selecting a unit within the column\n return (event: MouseEvent) => {\n if (onSelectUnit != null) {\n onSelectUnit(item.unit_id);\n } else if (onClickItem != null) {\n console.warn(\n \"Unit selection: onClickItem is defined but onSelectUnit is not; ignoring click\",\n );\n }\n // Don't allow event to propagate further (e.g., to open a link)\n event.preventDefault();\n };\n }\n return undefined;\n };\n }, [onSelectUnit, onClickItem]);\n\n if (clickHandlerForItem != null) {\n // We wrap this in a MacrostratInteractionManager to handle unit selection\n return h(\n MacrostratInteractionProvider,\n {\n clickHandlerForItem,\n inherit: true,\n },\n main,\n );\n }\n\n return main;\n}\n\nexport function LegendPanelHeader({\n title,\n id,\n onClose,\n actions = null,\n hiddenActions,\n}: {\n title?: string | null;\n id?: number | null;\n onClose?: () => void;\n actions?: ReactNode | null;\n hiddenActions?: ReactNode | null;\n}) {\n return h(\"header.legend-panel-header\", [\n h(\"div.title-container\", [\n h.if(title != null)(\"h3\", title),\n h.if(hiddenActions != null)(\n \"span.hidden-actions-container\",\n h(\"div.hidden-actions\", hiddenActions),\n ),\n ]),\n h(\"div.spacer\"),\n h.if(id != null)(\"code.unit-id\", id),\n h.if(actions != null)(ButtonGroup, { minimal: true }, actions),\n h.if(onClose != null)(Button, {\n icon: \"cross\",\n minimal: true,\n small: true,\n onClick() {\n onClose?.();\n },\n }),\n ]);\n}\n\nexport enum UnitDetailsFeature {\n AdjacentUnits = \"adjacent-units\",\n Color = \"color\",\n OutcropType = \"outcrop-type\",\n JSONToggle = \"json-toggle\",\n DepthRange = \"depth-range\",\n ColumnName = \"column-name\",\n}\n\nexport type MacrostratItemClickHandler = (\n event: MouseEvent,\n item:\n Lithology | Environment | UnitLong | Interval | { strat_name_id: number },\n) => void;\n\nfunction UnitDetailsContent({\n unit,\n lithologyFeatures = new Set([\n LithologyTagFeature.Proportion,\n LithologyTagFeature.Attributes,\n ]),\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n ]),\n onClickItem,\n getItemHref,\n}: {\n unit: UnitLong;\n lithologyFeatures?: Set<LithologyTagFeature>;\n features?: Set<UnitDetailsFeature>;\n onClickItem?: MacrostratItemClickHandler;\n getItemHref?: (item: Lithology | Environment | UnitLong) => string | null;\n}) {\n const lithMap = useMacrostratDefs(\"lithologies\");\n const envMap = useMacrostratDefs(\"environments\");\n\n const environments = enhanceEnvironments(unit.environ, envMap);\n const lithologies = enhanceLithologies(unit.lith ?? [], lithMap);\n\n let outcropField: ReactNode = null;\n if (features.has(UnitDetailsFeature.OutcropType)) {\n // Determine outcrop type\n let outcrop = unit.outcrop;\n if (outcrop == \"both\") {\n outcrop = \"surface and subsurface\";\n }\n outcropField = h(DataField, {\n label: \"Outcrop\",\n value: outcrop,\n });\n }\n\n let thicknessOrHeightRange: ReactNode = null;\n const [thickness, thicknessUnit] = getThickness(unit);\n // Proxy for actual heights in t_pos and b_pos\n if (\n features.has(UnitDetailsFeature.DepthRange) &&\n unit.t_pos != null &&\n unit.b_pos != null &&\n unit.min_thick == unit.max_thick && // We have an actual fixed height\n unit.min_thick != 0 // Not a zero thickness\n ) {\n const label = unit.t_pos < unit.b_pos ? \"Depth\" : \"Height\";\n const u1 = \"m\";\n\n thicknessOrHeightRange = h(DataField, {\n unit: u1,\n label,\n value: formatRange(unit.b_pos, unit.t_pos),\n children: h(\n Parenthetical,\n h(Value, { value: thickness, unit: thicknessUnit }),\n ),\n });\n }\n thicknessOrHeightRange ??= h(DataField, {\n label: \"Thickness\",\n value: thickness,\n unit: thicknessUnit,\n });\n\n /** We are trying to move away from passing the \"color\" parameter in the API */\n let colorSwatch: ReactNode = null;\n if (\"color\" in unit && features.has(UnitDetailsFeature.Color)) {\n const unit1 = unit as UnitLongFull;\n colorSwatch = h(\"div.color-swatch\", {\n style: { backgroundColor: unit1.color },\n });\n }\n\n return h(\"div.unit-details-content\", [\n h.if(features.has(UnitDetailsFeature.ColumnName))(ColumnNameField, {\n col_id: unit.col_id,\n }),\n thicknessOrHeightRange,\n h.if(lithologies != null)(LithologyList, {\n label: \"Lithology\",\n lithologies: lithologies ?? [],\n features: lithologyFeatures,\n }),\n h(AgeField, { unit }, [\n h(Parenthetical, h(Duration, { value: unit.b_age - unit.t_age })),\n h(IntervalProportions, {\n unit,\n onClickItem,\n }),\n ]),\n h.if(environments != null)(EnvironmentsList, {\n environments,\n }),\n h.if(unit.strat_name_id != null)(StratNameField, {\n strat_name_id: unit.strat_name_id,\n }),\n outcropField,\n h.if(features.has(UnitDetailsFeature.AdjacentUnits))([\n h.if(unit.units_above != null)(\n DataField,\n { label: \"Above\" },\n h(UnitIDList, {\n units: unit.units_above,\n showNames: true,\n }),\n ),\n h.if(unit.units_below != null)(\n DataField,\n { label: \"Below\" },\n h(UnitIDList, {\n units: unit.units_below,\n showNames: true,\n }),\n ),\n ]),\n colorSwatch,\n h(ReferencesField, { refs: unit.refs, inline: true }),\n ]);\n}\n\nfunction ColumnNameField({\n col_id,\n showIdentifier = false,\n}: {\n col_id: number;\n showIdentifier?: boolean;\n}) {\n const colData = useMacrostratColumnInfo(col_id);\n let inner: any = h(Identifier, { id: col_id });\n const name = colData?.col_name;\n if (name != null) {\n inner = h(\"span.value\", [\n h(\"span.col-name\", name),\n h.if(showIdentifier)([\" \", h(Parenthetical, inner)]),\n ]);\n }\n\n return h(\n DataField,\n {\n label: \"Column\",\n },\n inner,\n );\n}\n\nexport function ReferencesField({ refs, className = null, ...rest }) {\n if (refs == null || refs.length === 0) {\n return null;\n }\n\n return h(\n DataField,\n {\n label: \"References\",\n className: classNames(\"refs-field\", className),\n ...rest,\n },\n h(BibInfo, { refs }),\n );\n}\n\nfunction getThickness(unit): [string, string | null] {\n let minThickness = unit.min_thick ?? 0;\n let maxThickness = unit.max_thick ?? unit.min_thick ?? 0;\n let _unit = \"m\";\n\n if (minThickness == 0 && maxThickness == 0) {\n return [\"Unknown\", null];\n }\n\n if (minThickness < 0.8 && maxThickness < 1.2) {\n // Convert to cm\n minThickness = minThickness * 100;\n maxThickness = maxThickness * 100;\n _unit = \"cm\";\n } else if (minThickness > 800 && maxThickness > 1200) {\n // Convert to km\n minThickness = minThickness / 1000;\n maxThickness = maxThickness / 1000;\n _unit = \"km\";\n }\n\n if (minThickness == maxThickness) {\n return [formatSignificance(minThickness), _unit];\n }\n\n return [formatRange(minThickness, maxThickness), _unit];\n}\n\nexport function ThicknessField({ unit, label = \"Thickness\" }) {\n const [value, thicknessUnit] = getThickness(unit);\n return h(DataField, {\n label,\n value,\n unit: thicknessUnit,\n });\n}\n\nfunction BibInfo({ refs }) {\n // A reference the server doesn't know comes back as a hole, not a record\n const refData = useMacrostratData(\"refs\", refs)?.filter((d) => d != null);\n\n if (refData == null || refData.length === 0) {\n return null;\n }\n\n if (refData.length == 1) {\n return h(Citation, {\n data: refData[0],\n tag: \"span\",\n key: refData[0].ref_id,\n });\n }\n\n return h(\n \"ul.refs\",\n refData.map((data, i) =>\n h(Citation, { data, tag: \"li\", key: data.ref_id }),\n ),\n );\n}\n\nfunction Citation({ data, tag = \"p\" }) {\n return h(tag, { className: \"citation\" }, [\n h(\"span.authors\", data.author),\n \", \",\n h(\"span.year\", data.pub_year),\n \", \",\n h(\"span.title\", data.ref),\n ]);\n}\n\nfunction enhanceEnvironments(\n environments?: EnvironmentIdentifier[] | null,\n envMap?: Map<number, Environment> | null,\n) {\n return environments?.map((env) => {\n return {\n ...(envMap?.get(env.environ_id) ?? {}),\n ...env,\n };\n });\n}\n\nfunction enhanceLithologies(\n lithologies?: LithologyIdentifier[] | null,\n lithMap?: Map<number, any> | null,\n) {\n return lithologies?.map((lith) => {\n return {\n ...(lithMap?.get(lith.lith_id) ?? {}), // get lithology details\n ...lith, // override with the unit's specific lithology data\n };\n });\n}\n\nfunction UnitIDList({ units, showNames = false }) {\n const unitsMap = useColumnUnitsMap();\n\n const interactionManager = useInteractionManager();\n\n const extUnits: UnitInfo[] = useMemo(() => {\n const u1 = units.filter((d) => d != 0);\n if (showNames) {\n return u1.map((unitID) => {\n const unitData = unitsMap?.get(unitID);\n let name: string | null = null;\n if (unitData != null) {\n name = defaultNameFunction(unitData);\n }\n return {\n unitID,\n colID: unitData?.col_id,\n name,\n };\n });\n } else {\n return u1.map((unitID) => ({ unitID }));\n }\n }, [units, unitsMap]);\n\n if (extUnits.length === 0) {\n return h(\"span.no-units\", \"None\");\n }\n\n return h(\n ItemList,\n { className: \"units-list\" },\n extUnits.map((info) => {\n return h(\n \"span.item\",\n h(UnitIdentifier, {\n ...info,\n ...interactionManager?.interactionPropsForItem({\n unit_id: info.unitID,\n }),\n }),\n );\n }),\n );\n}\n"],"names":["useState","h","JSONView","defaultNameFunction","Button","classNames","useMemo","MacrostratInteractionProvider","ButtonGroup","UnitDetailsFeature","LithologyTagFeature","useMacrostratDefs","DataField","formatRange","Parenthetical","Value","LithologyList","AgeField","Duration","IntervalProportions","EnvironmentsList","StratNameField","useMacrostratColumnInfo","Identifier","formatSignificance","useMacrostratData","useColumnUnitsMap","useInteractionManager","ItemList","UnitIdentifier"],"mappings":"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"}
@@ -320,7 +320,7 @@ function ThicknessField({ unit, label = "Thickness" }) {
320
320
  });
321
321
  }
322
322
  function BibInfo({ refs }) {
323
- const refData = useMacrostratData("refs", refs);
323
+ const refData = useMacrostratData("refs", refs)?.filter((d) => d != null);
324
324
  if (refData == null || refData.length === 0) {
325
325
  return null;
326
326
  }
@@ -1 +1 @@
1
- {"version":3,"file":"panel.js","sources":["../../src/unit-details/panel.ts"],"sourcesContent":["import { JSONView } from \"@macrostrat/ui-components\";\nimport { Button, ButtonGroup } from \"@blueprintjs/core\";\nimport { ReactNode, useMemo, useState } from \"react\";\nimport {\n DataField,\n EnvironmentsList,\n ItemList,\n LithologyList,\n LithologyTagFeature,\n MacrostratInteractionManager,\n MacrostratInteractionProvider,\n MacrostratItemIdentifier,\n Parenthetical,\n useInteractionManager,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useColumnUnitsMap } from \"../data-provider\";\nimport {\n useMacrostratColumnInfo,\n useMacrostratData,\n useMacrostratDefs,\n} from \"@macrostrat/data-provider\";\nimport type {\n Environment,\n EnvironmentIdentifier,\n Interval,\n Lithology,\n UnitLong,\n UnitLongFull,\n} from \"@macrostrat/api-types\";\nimport { defaultNameFunction } from \"../units/names\";\nimport classNames from \"classnames\";\nimport { AgeField, Duration, IntervalProportions } from \"./age-range\";\nimport { formatRange, formatSignificance } from \"./utils.ts\";\nimport h from \"./panel.module.sass\";\nimport { StratNameField } from \"./strat-names.ts\";\nimport {\n Identifier,\n UnitIdentifier,\n UnitInfo,\n} from \"@macrostrat/data-components\";\nimport { LithologyIdentifier } from \"@macrostrat/api-types/src/lithologies\";\n\nexport interface UnitDetailsPanelProps {\n unit: any;\n onClose?: any;\n className?: string;\n actions?: ReactNode;\n hiddenActions?: ReactNode;\n features?: Set<UnitDetailsFeature>;\n lithologyFeatures?: Set<LithologyTagFeature>;\n onSelectUnit?: (unitID: number) => void;\n onClickItem?: MacrostratItemClickHandler;\n interactionManager?: MacrostratInteractionManager;\n showJSON?: boolean;\n}\n\nexport function UnitDetailsPanel({\n unit,\n onClose,\n className,\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n UnitDetailsFeature.JSONToggle,\n UnitDetailsFeature.DepthRange,\n ]),\n lithologyFeatures,\n actions,\n hiddenActions = null,\n onSelectUnit,\n onClickItem,\n showJSON,\n}: UnitDetailsPanelProps) {\n const [_showJSON, setShowJSON] = useState(false);\n\n let content: ReactNode = null;\n if (showJSON ?? _showJSON) {\n content = h(JSONView, { data: unit, showRoot: false });\n } else {\n content = h(UnitDetailsContent, {\n unit,\n features,\n lithologyFeatures,\n onClickItem,\n });\n }\n\n let title = defaultNameFunction(unit);\n\n if (features.has(UnitDetailsFeature.JSONToggle)) {\n hiddenActions = h([\n h(Button, {\n icon: \"code\",\n small: true,\n minimal: true,\n key: \"json-view-toggle\",\n className: classNames(\"json-view-toggle\", { enabled: setShowJSON }),\n onClick(evt) {\n setShowJSON(!_showJSON);\n evt.stopPropagation();\n },\n }),\n hiddenActions,\n ]);\n }\n\n const main = h(\"div.unit-details-panel\", { className }, [\n h(LegendPanelHeader, {\n onClose,\n title,\n id: unit.unit_id,\n actions,\n hiddenActions,\n }),\n h(\"div.unit-details-content-holder\", content),\n ]);\n\n /** Handle unit selection clicks */\n const clickHandlerForItem = useMemo(() => {\n if (onSelectUnit == null && onClickItem == null) return null;\n return (item: MacrostratItemIdentifier) => {\n if (\"unit_id\" in item && !(\"col_id\" in item)) {\n // We are selecting a unit within the column\n return (event: MouseEvent) => {\n if (onSelectUnit != null) {\n onSelectUnit(item.unit_id);\n } else if (onClickItem != null) {\n console.warn(\n \"Unit selection: onClickItem is defined but onSelectUnit is not; ignoring click\",\n );\n }\n // Don't allow event to propagate further (e.g., to open a link)\n event.preventDefault();\n };\n }\n return undefined;\n };\n }, [onSelectUnit, onClickItem]);\n\n if (clickHandlerForItem != null) {\n // We wrap this in a MacrostratInteractionManager to handle unit selection\n return h(\n MacrostratInteractionProvider,\n {\n clickHandlerForItem,\n inherit: true,\n },\n main,\n );\n }\n\n return main;\n}\n\nexport function LegendPanelHeader({\n title,\n id,\n onClose,\n actions = null,\n hiddenActions,\n}: {\n title?: string | null;\n id?: number | null;\n onClose?: () => void;\n actions?: ReactNode | null;\n hiddenActions?: ReactNode | null;\n}) {\n return h(\"header.legend-panel-header\", [\n h(\"div.title-container\", [\n h.if(title != null)(\"h3\", title),\n h.if(hiddenActions != null)(\n \"span.hidden-actions-container\",\n h(\"div.hidden-actions\", hiddenActions),\n ),\n ]),\n h(\"div.spacer\"),\n h.if(id != null)(\"code.unit-id\", id),\n h.if(actions != null)(ButtonGroup, { minimal: true }, actions),\n h.if(onClose != null)(Button, {\n icon: \"cross\",\n minimal: true,\n small: true,\n onClick() {\n onClose?.();\n },\n }),\n ]);\n}\n\nexport enum UnitDetailsFeature {\n AdjacentUnits = \"adjacent-units\",\n Color = \"color\",\n OutcropType = \"outcrop-type\",\n JSONToggle = \"json-toggle\",\n DepthRange = \"depth-range\",\n ColumnName = \"column-name\",\n}\n\nexport type MacrostratItemClickHandler = (\n event: MouseEvent,\n item:\n Lithology | Environment | UnitLong | Interval | { strat_name_id: number },\n) => void;\n\nfunction UnitDetailsContent({\n unit,\n lithologyFeatures = new Set([\n LithologyTagFeature.Proportion,\n LithologyTagFeature.Attributes,\n ]),\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n ]),\n onClickItem,\n getItemHref,\n}: {\n unit: UnitLong;\n lithologyFeatures?: Set<LithologyTagFeature>;\n features?: Set<UnitDetailsFeature>;\n onClickItem?: MacrostratItemClickHandler;\n getItemHref?: (item: Lithology | Environment | UnitLong) => string | null;\n}) {\n const lithMap = useMacrostratDefs(\"lithologies\");\n const envMap = useMacrostratDefs(\"environments\");\n\n const environments = enhanceEnvironments(unit.environ, envMap);\n const lithologies = enhanceLithologies(unit.lith ?? [], lithMap);\n\n let outcropField: ReactNode = null;\n if (features.has(UnitDetailsFeature.OutcropType)) {\n // Determine outcrop type\n let outcrop = unit.outcrop;\n if (outcrop == \"both\") {\n outcrop = \"surface and subsurface\";\n }\n outcropField = h(DataField, {\n label: \"Outcrop\",\n value: outcrop,\n });\n }\n\n let thicknessOrHeightRange: ReactNode = null;\n const [thickness, thicknessUnit] = getThickness(unit);\n // Proxy for actual heights in t_pos and b_pos\n if (\n features.has(UnitDetailsFeature.DepthRange) &&\n unit.t_pos != null &&\n unit.b_pos != null &&\n unit.min_thick == unit.max_thick && // We have an actual fixed height\n unit.min_thick != 0 // Not a zero thickness\n ) {\n const label = unit.t_pos < unit.b_pos ? \"Depth\" : \"Height\";\n const u1 = \"m\";\n\n thicknessOrHeightRange = h(DataField, {\n unit: u1,\n label,\n value: formatRange(unit.b_pos, unit.t_pos),\n children: h(\n Parenthetical,\n h(Value, { value: thickness, unit: thicknessUnit }),\n ),\n });\n }\n thicknessOrHeightRange ??= h(DataField, {\n label: \"Thickness\",\n value: thickness,\n unit: thicknessUnit,\n });\n\n /** We are trying to move away from passing the \"color\" parameter in the API */\n let colorSwatch: ReactNode = null;\n if (\"color\" in unit && features.has(UnitDetailsFeature.Color)) {\n const unit1 = unit as UnitLongFull;\n colorSwatch = h(\"div.color-swatch\", {\n style: { backgroundColor: unit1.color },\n });\n }\n\n return h(\"div.unit-details-content\", [\n h.if(features.has(UnitDetailsFeature.ColumnName))(ColumnNameField, {\n col_id: unit.col_id,\n }),\n thicknessOrHeightRange,\n h.if(lithologies != null)(LithologyList, {\n label: \"Lithology\",\n lithologies: lithologies ?? [],\n features: lithologyFeatures,\n }),\n h(AgeField, { unit }, [\n h(Parenthetical, h(Duration, { value: unit.b_age - unit.t_age })),\n h(IntervalProportions, {\n unit,\n onClickItem,\n }),\n ]),\n h.if(environments != null)(EnvironmentsList, {\n environments,\n }),\n h.if(unit.strat_name_id != null)(StratNameField, {\n strat_name_id: unit.strat_name_id,\n }),\n outcropField,\n h.if(features.has(UnitDetailsFeature.AdjacentUnits))([\n h.if(unit.units_above != null)(\n DataField,\n { label: \"Above\" },\n h(UnitIDList, {\n units: unit.units_above,\n showNames: true,\n }),\n ),\n h.if(unit.units_below != null)(\n DataField,\n { label: \"Below\" },\n h(UnitIDList, {\n units: unit.units_below,\n showNames: true,\n }),\n ),\n ]),\n colorSwatch,\n h(ReferencesField, { refs: unit.refs, inline: true }),\n ]);\n}\n\nfunction ColumnNameField({\n col_id,\n showIdentifier = false,\n}: {\n col_id: number;\n showIdentifier?: boolean;\n}) {\n const colData = useMacrostratColumnInfo(col_id);\n let inner: any = h(Identifier, { id: col_id });\n const name = colData?.col_name;\n if (name != null) {\n inner = h(\"span.value\", [\n h(\"span.col-name\", name),\n h.if(showIdentifier)([\" \", h(Parenthetical, inner)]),\n ]);\n }\n\n return h(\n DataField,\n {\n label: \"Column\",\n },\n inner,\n );\n}\n\nexport function ReferencesField({ refs, className = null, ...rest }) {\n if (refs == null || refs.length === 0) {\n return null;\n }\n\n return h(\n DataField,\n {\n label: \"References\",\n className: classNames(\"refs-field\", className),\n ...rest,\n },\n h(BibInfo, { refs }),\n );\n}\n\nfunction getThickness(unit): [string, string | null] {\n let minThickness = unit.min_thick ?? 0;\n let maxThickness = unit.max_thick ?? unit.min_thick ?? 0;\n let _unit = \"m\";\n\n if (minThickness == 0 && maxThickness == 0) {\n return [\"Unknown\", null];\n }\n\n if (minThickness < 0.8 && maxThickness < 1.2) {\n // Convert to cm\n minThickness = minThickness * 100;\n maxThickness = maxThickness * 100;\n _unit = \"cm\";\n } else if (minThickness > 800 && maxThickness > 1200) {\n // Convert to km\n minThickness = minThickness / 1000;\n maxThickness = maxThickness / 1000;\n _unit = \"km\";\n }\n\n if (minThickness == maxThickness) {\n return [formatSignificance(minThickness), _unit];\n }\n\n return [formatRange(minThickness, maxThickness), _unit];\n}\n\nexport function ThicknessField({ unit, label = \"Thickness\" }) {\n const [value, thicknessUnit] = getThickness(unit);\n return h(DataField, {\n label,\n value,\n unit: thicknessUnit,\n });\n}\n\nfunction BibInfo({ refs }) {\n const refData = useMacrostratData(\"refs\", refs);\n\n if (refData == null || refData.length === 0) {\n return null;\n }\n\n if (refData.length == 1) {\n return h(Citation, {\n data: refData[0],\n tag: \"span\",\n key: refData[0].ref_id,\n });\n }\n\n return h(\n \"ul.refs\",\n refData.map((data, i) =>\n h(Citation, { data, tag: \"li\", key: data.ref_id }),\n ),\n );\n}\n\nfunction Citation({ data, tag = \"p\" }) {\n return h(tag, { className: \"citation\" }, [\n h(\"span.authors\", data.author),\n \", \",\n h(\"span.year\", data.pub_year),\n \", \",\n h(\"span.title\", data.ref),\n ]);\n}\n\nfunction enhanceEnvironments(\n environments?: EnvironmentIdentifier[] | null,\n envMap?: Map<number, Environment> | null,\n) {\n return environments?.map((env) => {\n return {\n ...(envMap?.get(env.environ_id) ?? {}),\n ...env,\n };\n });\n}\n\nfunction enhanceLithologies(\n lithologies?: LithologyIdentifier[] | null,\n lithMap?: Map<number, any> | null,\n) {\n return lithologies?.map((lith) => {\n return {\n ...(lithMap?.get(lith.lith_id) ?? {}), // get lithology details\n ...lith, // override with the unit's specific lithology data\n };\n });\n}\n\nfunction UnitIDList({ units, showNames = false }) {\n const unitsMap = useColumnUnitsMap();\n\n const interactionManager = useInteractionManager();\n\n const extUnits: UnitInfo[] = useMemo(() => {\n const u1 = units.filter((d) => d != 0);\n if (showNames) {\n return u1.map((unitID) => {\n const unitData = unitsMap?.get(unitID);\n let name: string | null = null;\n if (unitData != null) {\n name = defaultNameFunction(unitData);\n }\n return {\n unitID,\n colID: unitData?.col_id,\n name,\n };\n });\n } else {\n return u1.map((unitID) => ({ unitID }));\n }\n }, [units, unitsMap]);\n\n if (extUnits.length === 0) {\n return h(\"span.no-units\", \"None\");\n }\n\n return h(\n ItemList,\n { className: \"units-list\" },\n extUnits.map((info) => {\n return h(\n \"span.item\",\n h(UnitIdentifier, {\n ...info,\n ...interactionManager?.interactionPropsForItem({\n unit_id: info.unitID,\n }),\n }),\n );\n }),\n );\n}\n"],"names":["UnitDetailsFeature"],"mappings":"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"}
1
+ {"version":3,"file":"panel.js","sources":["../../src/unit-details/panel.ts"],"sourcesContent":["import { JSONView } from \"@macrostrat/ui-components\";\nimport { Button, ButtonGroup } from \"@blueprintjs/core\";\nimport { ReactNode, useMemo, useState } from \"react\";\nimport {\n DataField,\n EnvironmentsList,\n ItemList,\n LithologyList,\n LithologyTagFeature,\n MacrostratInteractionManager,\n MacrostratInteractionProvider,\n MacrostratItemIdentifier,\n Parenthetical,\n useInteractionManager,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useColumnUnitsMap } from \"../data-provider\";\nimport {\n useMacrostratColumnInfo,\n useMacrostratData,\n useMacrostratDefs,\n} from \"@macrostrat/data-provider\";\nimport type {\n Environment,\n EnvironmentIdentifier,\n Interval,\n Lithology,\n UnitLong,\n UnitLongFull,\n} from \"@macrostrat/api-types\";\nimport { defaultNameFunction } from \"../units/names\";\nimport classNames from \"classnames\";\nimport { AgeField, Duration, IntervalProportions } from \"./age-range\";\nimport { formatRange, formatSignificance } from \"./utils.ts\";\nimport h from \"./panel.module.sass\";\nimport { StratNameField } from \"./strat-names.ts\";\nimport {\n Identifier,\n UnitIdentifier,\n UnitInfo,\n} from \"@macrostrat/data-components\";\nimport { LithologyIdentifier } from \"@macrostrat/api-types/src/lithologies\";\n\nexport interface UnitDetailsPanelProps {\n unit: any;\n onClose?: any;\n className?: string;\n actions?: ReactNode;\n hiddenActions?: ReactNode;\n features?: Set<UnitDetailsFeature>;\n lithologyFeatures?: Set<LithologyTagFeature>;\n onSelectUnit?: (unitID: number) => void;\n onClickItem?: MacrostratItemClickHandler;\n interactionManager?: MacrostratInteractionManager;\n showJSON?: boolean;\n}\n\nexport function UnitDetailsPanel({\n unit,\n onClose,\n className,\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n UnitDetailsFeature.JSONToggle,\n UnitDetailsFeature.DepthRange,\n ]),\n lithologyFeatures,\n actions,\n hiddenActions = null,\n onSelectUnit,\n onClickItem,\n showJSON,\n}: UnitDetailsPanelProps) {\n const [_showJSON, setShowJSON] = useState(false);\n\n let content: ReactNode = null;\n if (showJSON ?? _showJSON) {\n content = h(JSONView, { data: unit, showRoot: false });\n } else {\n content = h(UnitDetailsContent, {\n unit,\n features,\n lithologyFeatures,\n onClickItem,\n });\n }\n\n let title = defaultNameFunction(unit);\n\n if (features.has(UnitDetailsFeature.JSONToggle)) {\n hiddenActions = h([\n h(Button, {\n icon: \"code\",\n small: true,\n minimal: true,\n key: \"json-view-toggle\",\n className: classNames(\"json-view-toggle\", { enabled: setShowJSON }),\n onClick(evt) {\n setShowJSON(!_showJSON);\n evt.stopPropagation();\n },\n }),\n hiddenActions,\n ]);\n }\n\n const main = h(\"div.unit-details-panel\", { className }, [\n h(LegendPanelHeader, {\n onClose,\n title,\n id: unit.unit_id,\n actions,\n hiddenActions,\n }),\n h(\"div.unit-details-content-holder\", content),\n ]);\n\n /** Handle unit selection clicks */\n const clickHandlerForItem = useMemo(() => {\n if (onSelectUnit == null && onClickItem == null) return null;\n return (item: MacrostratItemIdentifier) => {\n if (\"unit_id\" in item && !(\"col_id\" in item)) {\n // We are selecting a unit within the column\n return (event: MouseEvent) => {\n if (onSelectUnit != null) {\n onSelectUnit(item.unit_id);\n } else if (onClickItem != null) {\n console.warn(\n \"Unit selection: onClickItem is defined but onSelectUnit is not; ignoring click\",\n );\n }\n // Don't allow event to propagate further (e.g., to open a link)\n event.preventDefault();\n };\n }\n return undefined;\n };\n }, [onSelectUnit, onClickItem]);\n\n if (clickHandlerForItem != null) {\n // We wrap this in a MacrostratInteractionManager to handle unit selection\n return h(\n MacrostratInteractionProvider,\n {\n clickHandlerForItem,\n inherit: true,\n },\n main,\n );\n }\n\n return main;\n}\n\nexport function LegendPanelHeader({\n title,\n id,\n onClose,\n actions = null,\n hiddenActions,\n}: {\n title?: string | null;\n id?: number | null;\n onClose?: () => void;\n actions?: ReactNode | null;\n hiddenActions?: ReactNode | null;\n}) {\n return h(\"header.legend-panel-header\", [\n h(\"div.title-container\", [\n h.if(title != null)(\"h3\", title),\n h.if(hiddenActions != null)(\n \"span.hidden-actions-container\",\n h(\"div.hidden-actions\", hiddenActions),\n ),\n ]),\n h(\"div.spacer\"),\n h.if(id != null)(\"code.unit-id\", id),\n h.if(actions != null)(ButtonGroup, { minimal: true }, actions),\n h.if(onClose != null)(Button, {\n icon: \"cross\",\n minimal: true,\n small: true,\n onClick() {\n onClose?.();\n },\n }),\n ]);\n}\n\nexport enum UnitDetailsFeature {\n AdjacentUnits = \"adjacent-units\",\n Color = \"color\",\n OutcropType = \"outcrop-type\",\n JSONToggle = \"json-toggle\",\n DepthRange = \"depth-range\",\n ColumnName = \"column-name\",\n}\n\nexport type MacrostratItemClickHandler = (\n event: MouseEvent,\n item:\n Lithology | Environment | UnitLong | Interval | { strat_name_id: number },\n) => void;\n\nfunction UnitDetailsContent({\n unit,\n lithologyFeatures = new Set([\n LithologyTagFeature.Proportion,\n LithologyTagFeature.Attributes,\n ]),\n features = new Set<UnitDetailsFeature>([\n UnitDetailsFeature.AdjacentUnits,\n UnitDetailsFeature.OutcropType,\n ]),\n onClickItem,\n getItemHref,\n}: {\n unit: UnitLong;\n lithologyFeatures?: Set<LithologyTagFeature>;\n features?: Set<UnitDetailsFeature>;\n onClickItem?: MacrostratItemClickHandler;\n getItemHref?: (item: Lithology | Environment | UnitLong) => string | null;\n}) {\n const lithMap = useMacrostratDefs(\"lithologies\");\n const envMap = useMacrostratDefs(\"environments\");\n\n const environments = enhanceEnvironments(unit.environ, envMap);\n const lithologies = enhanceLithologies(unit.lith ?? [], lithMap);\n\n let outcropField: ReactNode = null;\n if (features.has(UnitDetailsFeature.OutcropType)) {\n // Determine outcrop type\n let outcrop = unit.outcrop;\n if (outcrop == \"both\") {\n outcrop = \"surface and subsurface\";\n }\n outcropField = h(DataField, {\n label: \"Outcrop\",\n value: outcrop,\n });\n }\n\n let thicknessOrHeightRange: ReactNode = null;\n const [thickness, thicknessUnit] = getThickness(unit);\n // Proxy for actual heights in t_pos and b_pos\n if (\n features.has(UnitDetailsFeature.DepthRange) &&\n unit.t_pos != null &&\n unit.b_pos != null &&\n unit.min_thick == unit.max_thick && // We have an actual fixed height\n unit.min_thick != 0 // Not a zero thickness\n ) {\n const label = unit.t_pos < unit.b_pos ? \"Depth\" : \"Height\";\n const u1 = \"m\";\n\n thicknessOrHeightRange = h(DataField, {\n unit: u1,\n label,\n value: formatRange(unit.b_pos, unit.t_pos),\n children: h(\n Parenthetical,\n h(Value, { value: thickness, unit: thicknessUnit }),\n ),\n });\n }\n thicknessOrHeightRange ??= h(DataField, {\n label: \"Thickness\",\n value: thickness,\n unit: thicknessUnit,\n });\n\n /** We are trying to move away from passing the \"color\" parameter in the API */\n let colorSwatch: ReactNode = null;\n if (\"color\" in unit && features.has(UnitDetailsFeature.Color)) {\n const unit1 = unit as UnitLongFull;\n colorSwatch = h(\"div.color-swatch\", {\n style: { backgroundColor: unit1.color },\n });\n }\n\n return h(\"div.unit-details-content\", [\n h.if(features.has(UnitDetailsFeature.ColumnName))(ColumnNameField, {\n col_id: unit.col_id,\n }),\n thicknessOrHeightRange,\n h.if(lithologies != null)(LithologyList, {\n label: \"Lithology\",\n lithologies: lithologies ?? [],\n features: lithologyFeatures,\n }),\n h(AgeField, { unit }, [\n h(Parenthetical, h(Duration, { value: unit.b_age - unit.t_age })),\n h(IntervalProportions, {\n unit,\n onClickItem,\n }),\n ]),\n h.if(environments != null)(EnvironmentsList, {\n environments,\n }),\n h.if(unit.strat_name_id != null)(StratNameField, {\n strat_name_id: unit.strat_name_id,\n }),\n outcropField,\n h.if(features.has(UnitDetailsFeature.AdjacentUnits))([\n h.if(unit.units_above != null)(\n DataField,\n { label: \"Above\" },\n h(UnitIDList, {\n units: unit.units_above,\n showNames: true,\n }),\n ),\n h.if(unit.units_below != null)(\n DataField,\n { label: \"Below\" },\n h(UnitIDList, {\n units: unit.units_below,\n showNames: true,\n }),\n ),\n ]),\n colorSwatch,\n h(ReferencesField, { refs: unit.refs, inline: true }),\n ]);\n}\n\nfunction ColumnNameField({\n col_id,\n showIdentifier = false,\n}: {\n col_id: number;\n showIdentifier?: boolean;\n}) {\n const colData = useMacrostratColumnInfo(col_id);\n let inner: any = h(Identifier, { id: col_id });\n const name = colData?.col_name;\n if (name != null) {\n inner = h(\"span.value\", [\n h(\"span.col-name\", name),\n h.if(showIdentifier)([\" \", h(Parenthetical, inner)]),\n ]);\n }\n\n return h(\n DataField,\n {\n label: \"Column\",\n },\n inner,\n );\n}\n\nexport function ReferencesField({ refs, className = null, ...rest }) {\n if (refs == null || refs.length === 0) {\n return null;\n }\n\n return h(\n DataField,\n {\n label: \"References\",\n className: classNames(\"refs-field\", className),\n ...rest,\n },\n h(BibInfo, { refs }),\n );\n}\n\nfunction getThickness(unit): [string, string | null] {\n let minThickness = unit.min_thick ?? 0;\n let maxThickness = unit.max_thick ?? unit.min_thick ?? 0;\n let _unit = \"m\";\n\n if (minThickness == 0 && maxThickness == 0) {\n return [\"Unknown\", null];\n }\n\n if (minThickness < 0.8 && maxThickness < 1.2) {\n // Convert to cm\n minThickness = minThickness * 100;\n maxThickness = maxThickness * 100;\n _unit = \"cm\";\n } else if (minThickness > 800 && maxThickness > 1200) {\n // Convert to km\n minThickness = minThickness / 1000;\n maxThickness = maxThickness / 1000;\n _unit = \"km\";\n }\n\n if (minThickness == maxThickness) {\n return [formatSignificance(minThickness), _unit];\n }\n\n return [formatRange(minThickness, maxThickness), _unit];\n}\n\nexport function ThicknessField({ unit, label = \"Thickness\" }) {\n const [value, thicknessUnit] = getThickness(unit);\n return h(DataField, {\n label,\n value,\n unit: thicknessUnit,\n });\n}\n\nfunction BibInfo({ refs }) {\n // A reference the server doesn't know comes back as a hole, not a record\n const refData = useMacrostratData(\"refs\", refs)?.filter((d) => d != null);\n\n if (refData == null || refData.length === 0) {\n return null;\n }\n\n if (refData.length == 1) {\n return h(Citation, {\n data: refData[0],\n tag: \"span\",\n key: refData[0].ref_id,\n });\n }\n\n return h(\n \"ul.refs\",\n refData.map((data, i) =>\n h(Citation, { data, tag: \"li\", key: data.ref_id }),\n ),\n );\n}\n\nfunction Citation({ data, tag = \"p\" }) {\n return h(tag, { className: \"citation\" }, [\n h(\"span.authors\", data.author),\n \", \",\n h(\"span.year\", data.pub_year),\n \", \",\n h(\"span.title\", data.ref),\n ]);\n}\n\nfunction enhanceEnvironments(\n environments?: EnvironmentIdentifier[] | null,\n envMap?: Map<number, Environment> | null,\n) {\n return environments?.map((env) => {\n return {\n ...(envMap?.get(env.environ_id) ?? {}),\n ...env,\n };\n });\n}\n\nfunction enhanceLithologies(\n lithologies?: LithologyIdentifier[] | null,\n lithMap?: Map<number, any> | null,\n) {\n return lithologies?.map((lith) => {\n return {\n ...(lithMap?.get(lith.lith_id) ?? {}), // get lithology details\n ...lith, // override with the unit's specific lithology data\n };\n });\n}\n\nfunction UnitIDList({ units, showNames = false }) {\n const unitsMap = useColumnUnitsMap();\n\n const interactionManager = useInteractionManager();\n\n const extUnits: UnitInfo[] = useMemo(() => {\n const u1 = units.filter((d) => d != 0);\n if (showNames) {\n return u1.map((unitID) => {\n const unitData = unitsMap?.get(unitID);\n let name: string | null = null;\n if (unitData != null) {\n name = defaultNameFunction(unitData);\n }\n return {\n unitID,\n colID: unitData?.col_id,\n name,\n };\n });\n } else {\n return u1.map((unitID) => ({ unitID }));\n }\n }, [units, unitsMap]);\n\n if (extUnits.length === 0) {\n return h(\"span.no-units\", \"None\");\n }\n\n return h(\n ItemList,\n { className: \"units-list\" },\n extUnits.map((info) => {\n return h(\n \"span.item\",\n h(UnitIdentifier, {\n ...info,\n ...interactionManager?.interactionPropsForItem({\n unit_id: info.unitID,\n }),\n }),\n );\n }),\n );\n}\n"],"names":["UnitDetailsFeature"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@macrostrat/column-views",
3
- "version": "3.12.2",
3
+ "version": "3.13.0",
4
4
  "description": "Data views for Macrostrat stratigraphic columns",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,7 +49,7 @@
49
49
  "@macrostrat/api-types": "^1.4.0",
50
50
  "@macrostrat/color-utils": "^1.2.2",
51
51
  "@macrostrat/column-components": "^2.2.0",
52
- "@macrostrat/data-components": "^1.7.0",
52
+ "@macrostrat/data-components": "^1.8.0",
53
53
  "@macrostrat/data-provider": "^1.4.1",
54
54
  "@macrostrat/hyper": "^3.1.1",
55
55
  "@macrostrat/map-views": "^1.1.1",
package/src/column.ts CHANGED
@@ -65,7 +65,13 @@ interface BaseColumnProps extends Omit<
65
65
  keyboardNavigation?: boolean;
66
66
  showLabels?: boolean;
67
67
  maxInternalColumns?: number;
68
+ /** Draw the age (or height) axis beside the column (default). Off for a
69
+ * column whose coordinates aren't a measure — one laid out by surface order
70
+ * alone, say. */
71
+ showAgeAxis?: boolean;
68
72
  // Timescale properties
73
+ /** Draw the timescale. Defaults to on for an age column; an explicit value
74
+ * wins over `timescaleLevels` / `timescales`, which otherwise turn it on. */
69
75
  showTimescale?: boolean;
70
76
  timescaleLevels?: number | [number, number];
71
77
  /** Regional or project timescales drawn as extra columns beside the
@@ -276,6 +282,7 @@ function ColumnInner(props: ColumnInnerProps) {
276
282
  onClickTimescaleInterval,
277
283
  timescaleIntervalStyle,
278
284
  ageAxisComponent = CompositeAgeAxis,
285
+ showAgeAxis = true,
279
286
  } = props;
280
287
 
281
288
  const { axisType } = useMacrostratColumnData();
@@ -304,11 +311,9 @@ function ColumnInner(props: ColumnInnerProps) {
304
311
  showLabelColumn = false;
305
312
  }
306
313
 
307
- let _showTimescale = showTimescale ?? true;
308
- if (timescaleLevels != null || timescales != null) {
309
- _showTimescale = true;
310
- }
311
- _showTimescale = axisType == ColumnAxisType.AGE && _showTimescale;
314
+ // On unless turned off outright: passing levels or timescales no longer
315
+ // overrides an explicit `false`
316
+ const _showTimescale = axisType == ColumnAxisType.AGE && (showTimescale ?? true);
312
317
 
313
318
  return h(
314
319
  ColumnContainer,
@@ -318,7 +323,7 @@ function ColumnInner(props: ColumnInnerProps) {
318
323
  className,
319
324
  },
320
325
  h("div.column", { ref: columnRef }, [
321
- h(ageAxisComponent),
326
+ h.if(showAgeAxis)(ageAxisComponent),
322
327
  h.if(_showTimescale)(CompositeTimescale, {
323
328
  levels: timescaleLevels,
324
329
  additionalTimescales,
@@ -406,7 +406,8 @@ export function ThicknessField({ unit, label = "Thickness" }) {
406
406
  }
407
407
 
408
408
  function BibInfo({ refs }) {
409
- const refData = useMacrostratData("refs", refs);
409
+ // A reference the server doesn't know comes back as a hole, not a record
410
+ const refData = useMacrostratData("refs", refs)?.filter((d) => d != null);
410
411
 
411
412
  if (refData == null || refData.length === 0) {
412
413
  return null;