@macrostrat/column-views 3.3.5 → 3.4.1
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 +45 -0
- package/dist/column.cjs +2 -1
- package/dist/column.cjs.map +1 -1
- package/dist/column.js +2 -1
- package/dist/column.js.map +1 -1
- package/dist/data-provider/unit-selection.cjs +7 -3
- package/dist/data-provider/unit-selection.cjs.map +1 -1
- package/dist/data-provider/unit-selection.d.ts +1 -0
- package/dist/data-provider/unit-selection.js +7 -3
- package/dist/data-provider/unit-selection.js.map +1 -1
- package/dist/facets/carbon-isotopes/data-area.cjs +0 -3
- package/dist/facets/carbon-isotopes/data-area.cjs.map +1 -1
- package/dist/facets/carbon-isotopes/data-area.js +0 -3
- package/dist/facets/carbon-isotopes/data-area.js.map +1 -1
- package/dist/index.cjs +13 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/prepare-units/composite-scale.cjs +0 -1
- package/dist/prepare-units/composite-scale.cjs.map +1 -1
- package/dist/prepare-units/composite-scale.js +0 -1
- package/dist/prepare-units/composite-scale.js.map +1 -1
- package/dist/prepare-units/helpers.cjs +83 -49
- package/dist/prepare-units/helpers.cjs.map +1 -1
- package/dist/prepare-units/helpers.d.ts +19 -2
- package/dist/prepare-units/helpers.js +84 -50
- package/dist/prepare-units/helpers.js.map +1 -1
- package/dist/prepare-units/index.cjs.map +1 -1
- package/dist/prepare-units/index.js.map +1 -1
- package/dist/section.cjs +1 -2
- package/dist/section.cjs.map +1 -1
- package/dist/section.js +1 -2
- package/dist/section.js.map +1 -1
- package/dist/unit-details/identifiers.cjs +56 -0
- package/dist/unit-details/identifiers.cjs.map +1 -0
- package/dist/unit-details/identifiers.d.ts +31 -0
- package/dist/unit-details/identifiers.js +54 -0
- package/dist/unit-details/identifiers.js.map +1 -0
- package/dist/unit-details/index.d.ts +2 -0
- package/dist/unit-details/panel.cjs +11 -88
- package/dist/unit-details/panel.cjs.map +1 -1
- package/dist/unit-details/panel.d.ts +3 -19
- package/dist/unit-details/panel.js +10 -87
- package/dist/unit-details/panel.js.map +1 -1
- package/dist/unit-details/popover.cjs +1 -2
- package/dist/unit-details/popover.cjs.map +1 -1
- package/dist/unit-details/popover.js +2 -3
- package/dist/unit-details/popover.js.map +1 -1
- package/dist/unit-details/strat-names.cjs +44 -0
- package/dist/unit-details/strat-names.cjs.map +1 -0
- package/dist/unit-details/strat-names.d.ts +14 -0
- package/dist/unit-details/strat-names.js +42 -0
- package/dist/unit-details/strat-names.js.map +1 -0
- package/dist/units/index.cjs +19 -6
- package/dist/units/index.cjs.map +1 -1
- package/dist/units/index.d.ts +11 -20
- package/dist/units/index.js +19 -6
- package/dist/units/index.js.map +1 -1
- package/package.json +14 -14
- package/src/column.ts +1 -1
- package/src/data-provider/unit-selection.ts +8 -4
- package/src/facets/carbon-isotopes/data-area.ts +0 -3
- package/src/prepare-units/composite-scale.ts +1 -1
- package/src/prepare-units/helpers.ts +121 -72
- package/src/prepare-units/index.ts +1 -1
- package/src/section.ts +0 -1
- package/src/unit-details/identifiers.ts +67 -0
- package/src/unit-details/index.ts +2 -0
- package/src/unit-details/panel.ts +13 -126
- package/src/unit-details/popover.ts +2 -7
- package/src/unit-details/strat-names.ts +57 -0
- package/src/units/index.ts +28 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.4.1] - 2026-05-22 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.4.0...@macrostrat/column-views-v3.4.1)
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Remove stray console log statements
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @macrostrat/data-components@1.1.11
|
|
10
|
+
|
|
11
|
+
## [3.4.0] - 2026-05-20 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.3.5...@macrostrat/column-views-v3.4.0)
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- Update layout for column units overlaps
|
|
16
|
+
[01048d6f](https://github.com/UW-Macrostrat/web-components/commit/01048d6ffa1335f58334c5c855b86e7a97b3e9c1)
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Fixed error with strat name viewer
|
|
21
|
+
[239c0292](https://github.com/UW-Macrostrat/web-components/commit/239c0292ce143f642cf05ec934f246798d89a54f)
|
|
22
|
+
- Update blueprintjs dependencies
|
|
23
|
+
[239c0292](https://github.com/UW-Macrostrat/web-components/commit/239c0292ce143f642cf05ec934f246798d89a54f)
|
|
24
|
+
- Improved types for API outputs
|
|
25
|
+
[225ed9a4](https://github.com/UW-Macrostrat/web-components/commit/225ed9a4534b2d1f8be8af6ab7e4035352825614)
|
|
26
|
+
- Updated `jotai` and `jotai-scope` dependencies
|
|
27
|
+
[fb1c5ceb](https://github.com/UW-Macrostrat/web-components/commit/fb1c5ceb37c59aba5ee8dab1cca1d7a09b5b5fb3)
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
[239c0292](https://github.com/UW-Macrostrat/web-components/commit/239c0292ce143f642cf05ec934f246798d89a54f)
|
|
30
|
+
- Updated dependencies
|
|
31
|
+
[239c0292](https://github.com/UW-Macrostrat/web-components/commit/239c0292ce143f642cf05ec934f246798d89a54f)
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
[225ed9a4](https://github.com/UW-Macrostrat/web-components/commit/225ed9a4534b2d1f8be8af6ab7e4035352825614)
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
[01048d6f](https://github.com/UW-Macrostrat/web-components/commit/01048d6ffa1335f58334c5c855b86e7a97b3e9c1)
|
|
36
|
+
- Updated dependencies
|
|
37
|
+
[fb1c5ceb](https://github.com/UW-Macrostrat/web-components/commit/fb1c5ceb37c59aba5ee8dab1cca1d7a09b5b5fb3)
|
|
38
|
+
- @macrostrat/data-provider@1.0.4
|
|
39
|
+
- @macrostrat/column-components@2.0.8
|
|
40
|
+
- @macrostrat/data-components@1.1.10
|
|
41
|
+
- @macrostrat/map-interface@2.2.6
|
|
42
|
+
- @macrostrat/ui-components@5.0.10
|
|
43
|
+
- @macrostrat/mapbox-react@3.2.2
|
|
44
|
+
- @macrostrat/api-types@1.2.0
|
|
45
|
+
- @macrostrat/stratigraphy-utils@1.3.0
|
|
46
|
+
- @macrostrat/map-styles@2.2.3
|
|
47
|
+
|
|
3
48
|
## [3.3.5] - 2026-05-19 [_changes_](https://github.com/UW-Macrostrat/web-components/compare/@macrostrat/column-views-v3.3.4...@macrostrat/column-views-v3.3.5)
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/dist/column.cjs
CHANGED
|
@@ -16,6 +16,7 @@ const types = require("./prepare-units/types.cjs");
|
|
|
16
16
|
const store = require("./data-provider/store.cjs");
|
|
17
17
|
const popover = require("./unit-details/popover.cjs");
|
|
18
18
|
const unitSelection = require("./data-provider/unit-selection.cjs");
|
|
19
|
+
const identifiers = require("./unit-details/identifiers.cjs");
|
|
19
20
|
const panel = require("./unit-details/panel.cjs");
|
|
20
21
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
21
22
|
const classNames__default = /* @__PURE__ */ _interopDefault(classNames);
|
|
@@ -232,7 +233,7 @@ function ColumnBasicInfo({
|
|
|
232
233
|
return h("div.column-info", [
|
|
233
234
|
h("div.column-title-row", [
|
|
234
235
|
h("h2", data.col_name),
|
|
235
|
-
h.if(showColumnID)("h4", h(
|
|
236
|
+
h.if(showColumnID)("h4", h(identifiers.Identifier, { id: data.col_id }))
|
|
236
237
|
]),
|
|
237
238
|
h(dataComponents.DataField, { row: true, label: "Group", value: data.col_group }),
|
|
238
239
|
h.if(showReferences)(panel.ReferencesField, {
|
package/dist/column.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column.cjs","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport { hyperStyled } from \"@macrostrat/hyper\";\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} from \"react\";\nimport styles from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\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 useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\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\nconst h = hyperStyled(styles);\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\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}\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 pixelScale,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n ...rest\n } = props;\n\n /* Make pixelScale and targetUnitHeight mutually exclusive. PixelScale implies\n * standardization of scales in all sections */\n let _targetUnitHeight = targetUnitHeight;\n let _minSectionHeight = minSectionHeight;\n let _minPixelScale = minPixelScale;\n if (pixelScale != null) {\n _targetUnitHeight = null;\n _minSectionHeight = 0;\n _minPixelScale = pixelScale;\n }\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 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: _targetUnitHeight,\n unconformityHeight,\n pixelScale,\n minPixelScale: _minPixelScale,\n minSectionHeight: _minSectionHeight,\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 },\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 className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n maxInternalColumns,\n onMouseOver,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\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) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != 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 unconformityLabels: _timescaleUnconformityLabels,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\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":["hyperStyled","styles","ColumnAxisType","CompositeAgeAxis","HybridScaleType","ApproximateHeightAxis","usePreparedColumnUnits","NonIdealState","MacrostratColumnDataProvider","UnitSelectionPopover","UnitKeyboardNavigation","extractPadding","UnitComponent","useMacrostratColumnData","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 { hyperStyled } from \"@macrostrat/hyper\";\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} from \"react\";\nimport styles from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\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 useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\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\nconst h = hyperStyled(styles);\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\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}\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 pixelScale,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n ...rest\n } = props;\n\n /* Make pixelScale and targetUnitHeight mutually exclusive. PixelScale implies\n * standardization of scales in all sections */\n let _targetUnitHeight: number | null = targetUnitHeight;\n let _minSectionHeight = minSectionHeight;\n let _minPixelScale = minPixelScale;\n if (pixelScale != null) {\n _targetUnitHeight = null;\n _minSectionHeight = 0;\n _minPixelScale = pixelScale;\n }\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 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: _targetUnitHeight,\n unconformityHeight,\n pixelScale,\n minPixelScale: _minPixelScale,\n minSectionHeight: _minSectionHeight,\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 },\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 className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n maxInternalColumns,\n onMouseOver,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\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) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != 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 unconformityLabels: _timescaleUnconformityLabels,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\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":["hyperStyled","styles","ColumnAxisType","CompositeAgeAxis","HybridScaleType","ApproximateHeightAxis","usePreparedColumnUnits","NonIdealState","MacrostratColumnDataProvider","UnitSelectionPopover","UnitKeyboardNavigation","extractPadding","UnitComponent","useMacrostratColumnData","useColumnRef","CompositeTimescale","SectionsColumn","useUnitSelectionDispatch","useCallback","useCompositeScale","useDarkMode","Box","classNames","Identifier","DataField","ReferencesField"],"mappings":"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"}
|
package/dist/column.js
CHANGED
|
@@ -14,7 +14,8 @@ import { HybridScaleType } from "./prepare-units/types.js";
|
|
|
14
14
|
import { MacrostratColumnDataProvider, useMacrostratColumnData, useCompositeScale } from "./data-provider/store.js";
|
|
15
15
|
import { UnitSelectionPopover } from "./unit-details/popover.js";
|
|
16
16
|
import { UnitKeyboardNavigation, useColumnRef, useUnitSelectionDispatch } from "./data-provider/unit-selection.js";
|
|
17
|
-
import { Identifier
|
|
17
|
+
import { Identifier } from "./unit-details/identifiers.js";
|
|
18
|
+
import { ReferencesField } from "./unit-details/panel.js";
|
|
18
19
|
const h = hyperStyled(h$1);
|
|
19
20
|
function Column(props) {
|
|
20
21
|
const {
|
package/dist/column.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column.js","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport { hyperStyled } from \"@macrostrat/hyper\";\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} from \"react\";\nimport styles from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\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 useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\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\nconst h = hyperStyled(styles);\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\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}\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 pixelScale,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n ...rest\n } = props;\n\n /* Make pixelScale and targetUnitHeight mutually exclusive. PixelScale implies\n * standardization of scales in all sections */\n let _targetUnitHeight = targetUnitHeight;\n let _minSectionHeight = minSectionHeight;\n let _minPixelScale = minPixelScale;\n if (pixelScale != null) {\n _targetUnitHeight = null;\n _minSectionHeight = 0;\n _minPixelScale = pixelScale;\n }\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 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: _targetUnitHeight,\n unconformityHeight,\n pixelScale,\n minPixelScale: _minPixelScale,\n minSectionHeight: _minSectionHeight,\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 },\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 className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n maxInternalColumns,\n onMouseOver,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\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) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != 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 unconformityLabels: _timescaleUnconformityLabels,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\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":["styles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"column.js","sources":["../src/column.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport { hyperStyled } from \"@macrostrat/hyper\";\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} from \"react\";\nimport styles from \"./column.module.sass\";\nimport { UnitComponent } from \"./units\";\nimport {\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 useMacrostratColumnData,\n} from \"./data-provider\";\nimport {\n SectionSharedProps,\n CompositeTimescale,\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\nconst h = hyperStyled(styles);\n\ninterface BaseColumnProps extends Omit<\n SectionSharedProps,\n \"unconformityLabels\"\n> {\n className?: string;\n showLabelColumn?: boolean;\n keyboardNavigation?: boolean;\n showLabels?: boolean;\n maxInternalColumns?: number;\n // Timescale properties\n showTimescale?: boolean;\n timescaleLevels?: number | [number, number];\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}\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 pixelScale,\n minPixelScale = 0.2,\n minSectionHeight = 50,\n collapseSmallUnconformities = true,\n allowUnitSelection = false,\n hybridScale,\n scale,\n axisType,\n ...rest\n } = props;\n\n /* Make pixelScale and targetUnitHeight mutually exclusive. PixelScale implies\n * standardization of scales in all sections */\n let _targetUnitHeight: number | null = targetUnitHeight;\n let _minSectionHeight = minSectionHeight;\n let _minPixelScale = minPixelScale;\n if (pixelScale != null) {\n _targetUnitHeight = null;\n _minSectionHeight = 0;\n _minPixelScale = pixelScale;\n }\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 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: _targetUnitHeight,\n unconformityHeight,\n pixelScale,\n minPixelScale: _minPixelScale,\n minSectionHeight: _minSectionHeight,\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 },\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 className,\n clipUnits = false,\n children,\n showTimescale,\n timescaleLevels,\n maxInternalColumns,\n onMouseOver,\n ageAxisComponent = CompositeAgeAxis,\n } = props;\n\n const { axisType } = useMacrostratColumnData();\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) {\n showLabelColumn = false;\n }\n\n let _showTimescale = showTimescale ?? true;\n if (timescaleLevels != 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 unconformityLabels: _timescaleUnconformityLabels,\n }),\n h(SectionsColumn, {\n unitComponent,\n showLabels,\n width,\n columnWidth,\n showLabelColumn,\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":["styles"],"mappings":"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"}
|
|
@@ -5,6 +5,9 @@ const React = require("react");
|
|
|
5
5
|
const jotai = require("jotai");
|
|
6
6
|
const store = require("./store.cjs");
|
|
7
7
|
const stratigraphyUtils = require("@macrostrat/stratigraphy-utils");
|
|
8
|
+
function useUnitSelection() {
|
|
9
|
+
return store.scope.use(selectedUnitAtom);
|
|
10
|
+
}
|
|
8
11
|
function useUnitSelectionDispatch() {
|
|
9
12
|
return store.scope.useSetAtom(selectedUnitAtom);
|
|
10
13
|
}
|
|
@@ -29,6 +32,7 @@ const selectedUnitAtom = jotai.atom(
|
|
|
29
32
|
(get, set, selectedUnit, target = null) => {
|
|
30
33
|
if (!get(allowUnitSelectionAtom)) {
|
|
31
34
|
console.error("Unit selection is disabled.");
|
|
35
|
+
return null;
|
|
32
36
|
}
|
|
33
37
|
let unitID = null;
|
|
34
38
|
let unit = null;
|
|
@@ -78,9 +82,8 @@ function UnitSelectionCallbackManager({
|
|
|
78
82
|
return null;
|
|
79
83
|
}
|
|
80
84
|
function useUnitSelectionTarget(unit) {
|
|
81
|
-
const ref = React.useRef();
|
|
82
|
-
const selectedUnit =
|
|
83
|
-
const selectUnit = useUnitSelectionDispatch();
|
|
85
|
+
const ref = React.useRef(null);
|
|
86
|
+
const [selectedUnit, selectUnit] = useUnitSelection();
|
|
84
87
|
const selected = selectedUnit?.unit_id == unit.unit_id;
|
|
85
88
|
const onClick = React.useCallback(
|
|
86
89
|
(evt) => {
|
|
@@ -220,6 +223,7 @@ exports.selectedUnitIDAtom = selectedUnitIDAtom;
|
|
|
220
223
|
exports.useAtomOverlayPosition = useAtomOverlayPosition;
|
|
221
224
|
exports.useColumnRef = useColumnRef;
|
|
222
225
|
exports.useSelectedUnit = useSelectedUnit;
|
|
226
|
+
exports.useUnitSelection = useUnitSelection;
|
|
223
227
|
exports.useUnitSelectionDispatch = useUnitSelectionDispatch;
|
|
224
228
|
exports.useUnitSelectionTarget = useUnitSelectionTarget;
|
|
225
229
|
//# sourceMappingURL=unit-selection.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unit-selection.cjs","sources":["../../src/data-provider/unit-selection.ts"],"sourcesContent":["import type { BaseUnit, UnitLong } from \"@macrostrat/api-types\";\nimport { useKeyHandler } from \"@macrostrat/ui-components\";\nimport { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { RectBounds, IUnit } from \"../units/types\";\nimport { atom } from \"jotai\";\nimport { scope, columnUnitsMapAtom } from \"./store\";\nimport {\n AgeRangeQuantifiedDifference,\n ageRangeQuantifiedDifference,\n AgeRangeRelationship,\n} from \"@macrostrat/stratigraphy-utils\";\nimport type { ColumnData } from \"@macrostrat/data-provider\";\n\ntype UnitSelectDispatch = (\n unit: number | BaseUnit | null,\n target: HTMLElement | null,\n) => void;\n\nexport function useUnitSelectionDispatch(): UnitSelectDispatch {\n return scope.useSetAtom(selectedUnitAtom);\n}\n\nexport function useSelectedUnit() {\n return scope.useAtomValue(selectedUnitAtom);\n}\n\nexport interface ColumnClickData {\n unitID: number | null;\n unit: BaseUnit | null;\n target: HTMLElement | null;\n height: number;\n // Room for boundary IDs eventually\n}\n\nexport interface UnitSelectionCallbacks {\n // It's sort of unfortunate that we need to pass in the column ref here\n onClickedColumn?: (columnClickData: ColumnClickData, event: Event) => void;\n onUnitSelected?: <T extends BaseUnit>(\n unitID: number | null,\n unit: T | null,\n ) => void;\n}\n\nexport const allowUnitSelectionAtom = atom<boolean>(true);\n\nexport const selectedUnitIDAtom = atom<number | null>();\n\nconst overlayPositionAtom = atom<RectBounds | null>();\n\nconst columnRefAtom = atom<{ current: HTMLElement | null }>({ current: null });\n\nexport function useColumnRef() {\n return scope.useAtomValue(columnRefAtom);\n}\n\nconst selectedUnitAtom = atom(\n (get) => {\n if (!get(allowUnitSelectionAtom)) return null;\n\n const unitID = get(selectedUnitIDAtom);\n if (unitID == null) return null;\n const unitsMap = get(columnUnitsMapAtom);\n return unitsMap?.get(unitID) || null;\n },\n (\n get,\n set,\n selectedUnit: number | BaseUnit | null,\n target: HTMLElement | null = null,\n ): BaseUnit | null => {\n if (!get(allowUnitSelectionAtom)) {\n console.error(\"Unit selection is disabled.\");\n }\n\n let unitID: number | null = null;\n let unit: BaseUnit | null = null;\n if (selectedUnit == null) {\n unitID = null;\n } else if (typeof selectedUnit === \"number\") {\n unitID = selectedUnit;\n } else if (\"unit_id\" in selectedUnit) {\n unitID = selectedUnit.unit_id;\n }\n\n if (unitID != null) {\n // Verify that the unit exists in the current colum, else throw\n const unitsMap = get(columnUnitsMapAtom);\n if (!unitsMap?.has(unitID)) {\n throw new Error(\n `Unit with ID ${unitID} not found in current column units.`,\n );\n }\n unit = unitsMap.get(unitID) ?? null;\n }\n\n let overlayPosition: RectBounds | null = null;\n\n const columnEl = get(columnRefAtom)?.current;\n\n if (unit != null && columnEl != null && target != null) {\n const rect = columnEl.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n overlayPosition = {\n x: targetRect.left - rect.left,\n y: targetRect.top - rect.top,\n width: targetRect.width,\n height: targetRect.height,\n };\n }\n\n set(selectedUnitIDAtom, unitID);\n set(overlayPositionAtom, overlayPosition);\n\n return unit;\n },\n);\n\nexport function useAtomOverlayPosition() {\n return scope.useAtomValue(overlayPositionAtom);\n}\n\nexport function UnitSelectionCallbackManager({\n onUnitSelected,\n}: UnitSelectionCallbacks) {\n const selectedUnit = scope.useAtomValue(selectedUnitAtom);\n useEffect(() => {\n onUnitSelected?.(selectedUnit?.unit_id ?? null, selectedUnit ?? null);\n }, [selectedUnit?.unit_id]);\n return null;\n}\n\n/** TODO: figure out if onClickedColumn is still needed\n /** This is not the natural place to get positions within the column,\n * but it will work for now.\nif (props.onClickedColumn) {\n // Infer height from top and bottom height of unit (because that's passed back with the call)\n //const py = event.y;\n //const [bottom, top] = getUnitHeightRange(unit, axisType);\n //const height = Math.abs(bottom - top);\n\n const columnClickData: ColumnClickData = {\n unitID: unit?.unit_id,\n unit,\n target,\n height: el?.getBoundingClientRect().height || 0,\n };\n props.onClickedColumn(columnClickData, event);\n}*/\n\nexport function useUnitSelectionTarget(\n unit: IUnit,\n): [React.RefObject<HTMLElement>, boolean, (evt: Event) => void] {\n const ref = useRef<HTMLElement>();\n const selectedUnit = useSelectedUnit();\n const selectUnit = useUnitSelectionDispatch();\n const selected = selectedUnit?.unit_id == unit.unit_id;\n\n const onClick = useCallback(\n (evt: Event) => {\n selectUnit?.(unit, ref.current);\n evt.stopPropagation();\n },\n [unit, selectUnit],\n );\n\n useEffect(() => {\n if (!selected || selectUnit == null) return;\n // In case we haven't set the position of the unit (if we don't have a target), set the selected unit\n selectUnit(unit, ref.current);\n\n // Scroll the unit into view\n ref.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }, [selected, selectUnit]);\n\n return [ref, selected, onClick];\n}\n\nexport function UnitKeyboardNavigation({\n columnData,\n units,\n allowHorizontalNavigation,\n}: {\n columnData?: ColumnData[];\n units?: UnitLong[];\n allowHorizontalNavigation?: boolean;\n}) {\n if (units == null && columnData == null) {\n throw new Error(\"Either units or columnData must be provided.\");\n }\n\n let _columnData: ColumnData[] = useMemo(() => {\n if (columnData != null) return columnData;\n // Build column data from units\n const colMap = new Map<number, UnitLong[]>();\n for (const unit of units!) {\n if (!colMap.has(unit.col_id)) {\n colMap.set(unit.col_id, []);\n }\n colMap.get(unit.col_id)!.push(unit);\n }\n const cols: ColumnData[] = [];\n for (const [colID, units] of colMap) {\n cols.push({ columnID: colID, units });\n }\n // Sort columns by columnID\n cols.sort((a, b) => a.columnID - b.columnID);\n return cols;\n }, [columnData, units]);\n\n // Default to allowing horizontal navigation only if columnData is provided\n const _allowHorizontalNavigation =\n allowHorizontalNavigation ?? columnData != null;\n\n const selectedUnit = useSelectedUnit() as UnitLong | null;\n const selectUnit = useUnitSelectionDispatch();\n\n const keyMap: Record<number, Direction> = {\n 38: \"up\",\n 40: \"down\",\n };\n if (_allowHorizontalNavigation) {\n keyMap[37] = \"left\";\n keyMap[39] = \"right\";\n }\n\n useKeyHandler(\n (event) => {\n const direction = keyMap[event.keyCode];\n if (direction == null) return;\n const nextUnit = getBestUnit(_columnData, selectedUnit, direction);\n if (nextUnit == null) return;\n selectUnit(nextUnit, null);\n event.stopPropagation();\n },\n [_columnData, selectedUnit],\n );\n return null;\n}\n\ntype Direction = \"up\" | \"down\" | \"left\" | \"right\";\n\nfunction getBestUnit(\n columnData: ColumnData[],\n targetUnit: UnitLong,\n direction: Direction,\n): UnitLong | null {\n const thisColIndex = columnData.findIndex(\n (col) => col.columnID === targetUnit.col_id,\n );\n if (thisColIndex === -1) return null;\n\n // If up or down, stay in the same column\n if (direction === \"up\" || direction === \"down\") {\n const units = columnData[thisColIndex].units;\n const ix = units.findIndex((unit) => unit.unit_id === targetUnit.unit_id);\n if (ix === -1) return null;\n if (direction === \"up\") {\n return units[ix - 1] || null;\n } else {\n return units[ix + 1] || null;\n }\n }\n\n // If left or right, move to adjacent column\n let adjacentColIndex: number;\n if (direction === \"left\") {\n adjacentColIndex =\n (thisColIndex - 1 + columnData.length) % columnData.length;\n } else {\n adjacentColIndex = (thisColIndex + 1) % columnData.length;\n }\n\n const adjacentColUnits = columnData[adjacentColIndex].units;\n return getMostOverlappingUnit(targetUnit, adjacentColUnits);\n}\n\ntype UnitAgeRangeRelationship = AgeRangeQuantifiedDifference & {\n unit: UnitLong;\n};\n\nfunction getMostOverlappingUnit(\n targetUnit: UnitLong,\n candidateUnits: UnitLong[],\n): UnitLong | null {\n const targetAgeRange = [targetUnit.b_age, targetUnit.t_age];\n\n const overlaps: UnitAgeRangeRelationship[] = [];\n for (const candidate of candidateUnits) {\n const candidateAgeRange = [candidate.b_age, candidate.t_age];\n\n const rel = ageRangeQuantifiedDifference(targetAgeRange, candidateAgeRange);\n if (rel.type === AgeRangeRelationship.Identical) {\n return candidate;\n }\n overlaps.push({ ...rel, unit: candidate });\n }\n\n let bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Containing,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Contained,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.PartialOverlap,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Disjoint,\n );\n bestOverlaps.sort((a, b) => a.distance - b.distance);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n return null;\n}\n"],"names":["scope","atom","columnUnitsMapAtom","useEffect","useRef","useCallback","useMemo","units","useKeyHandler","ageRangeQuantifiedDifference","AgeRangeRelationship"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unit-selection.cjs","sources":["../../src/data-provider/unit-selection.ts"],"sourcesContent":["import type { BaseUnit, UnitLong } from \"@macrostrat/api-types\";\nimport { useKeyHandler } from \"@macrostrat/ui-components\";\nimport { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { RectBounds, IUnit } from \"../units/types\";\nimport { atom } from \"jotai\";\nimport { scope, columnUnitsMapAtom } from \"./store\";\nimport {\n AgeRangeQuantifiedDifference,\n ageRangeQuantifiedDifference,\n AgeRangeRelationship,\n} from \"@macrostrat/stratigraphy-utils\";\nimport type { ColumnData } from \"@macrostrat/data-provider\";\n\ntype UnitSelectDispatch = (\n unit: number | BaseUnit | null,\n target: HTMLElement | null,\n) => void;\n\nexport function useUnitSelection() {\n return scope.use(selectedUnitAtom);\n}\n\nexport function useUnitSelectionDispatch(): UnitSelectDispatch {\n return scope.useSetAtom(selectedUnitAtom);\n}\n\nexport function useSelectedUnit() {\n return scope.useAtomValue(selectedUnitAtom);\n}\n\nexport interface ColumnClickData {\n unitID: number | null;\n unit: BaseUnit | null;\n target: HTMLElement | null;\n height: number;\n // Room for boundary IDs eventually\n}\n\nexport interface UnitSelectionCallbacks {\n // It's sort of unfortunate that we need to pass in the column ref here\n onClickedColumn?: (columnClickData: ColumnClickData, event: Event) => void;\n onUnitSelected?: <T extends BaseUnit>(\n unitID: number | null,\n unit: T | null,\n ) => void;\n}\n\nexport const allowUnitSelectionAtom = atom<boolean>(true);\n\nexport const selectedUnitIDAtom = atom<number | null>();\n\nconst overlayPositionAtom = atom<RectBounds | null>();\n\nconst columnRefAtom = atom<{ current: HTMLElement | null }>({ current: null });\n\nexport function useColumnRef() {\n return scope.useAtomValue(columnRefAtom);\n}\n\nconst selectedUnitAtom = atom(\n (get) => {\n if (!get(allowUnitSelectionAtom)) return null;\n\n const unitID = get(selectedUnitIDAtom);\n if (unitID == null) return null;\n const unitsMap = get(columnUnitsMapAtom);\n return unitsMap?.get(unitID) || null;\n },\n (\n get,\n set,\n selectedUnit: number | BaseUnit | null,\n target: HTMLElement | null = null,\n ): BaseUnit | null => {\n if (!get(allowUnitSelectionAtom)) {\n console.error(\"Unit selection is disabled.\");\n return null;\n }\n\n let unitID: number | null = null;\n let unit: BaseUnit | null = null;\n if (selectedUnit == null) {\n unitID = null;\n } else if (typeof selectedUnit === \"number\") {\n unitID = selectedUnit;\n } else if (\"unit_id\" in selectedUnit) {\n unitID = selectedUnit.unit_id;\n }\n\n if (unitID != null) {\n const unitsMap = get(columnUnitsMapAtom);\n // Verify that the unit exists in the current colum, else throw\n if (!unitsMap?.has(unitID)) {\n throw new Error(\n `Unit with ID ${unitID} not found in current column units.`,\n );\n }\n unit = unitsMap.get(unitID) ?? null;\n }\n\n let overlayPosition: RectBounds | null = null;\n\n const columnEl = get(columnRefAtom)?.current;\n\n if (unit != null && columnEl != null && target != null) {\n const rect = columnEl.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n overlayPosition = {\n x: targetRect.left - rect.left,\n y: targetRect.top - rect.top,\n width: targetRect.width,\n height: targetRect.height,\n };\n }\n\n set(selectedUnitIDAtom, unitID);\n set(overlayPositionAtom, overlayPosition);\n\n return unit;\n },\n);\n\nexport function useAtomOverlayPosition() {\n return scope.useAtomValue(overlayPositionAtom);\n}\n\nexport function UnitSelectionCallbackManager({\n onUnitSelected,\n}: UnitSelectionCallbacks) {\n const selectedUnit = scope.useAtomValue(selectedUnitAtom);\n useEffect(() => {\n onUnitSelected?.(selectedUnit?.unit_id ?? null, selectedUnit ?? null);\n }, [selectedUnit?.unit_id]);\n return null;\n}\n\n/** TODO: figure out if onClickedColumn is still needed\n /** This is not the natural place to get positions within the column,\n * but it will work for now.\nif (props.onClickedColumn) {\n // Infer height from top and bottom height of unit (because that's passed back with the call)\n //const py = event.y;\n //const [bottom, top] = getUnitHeightRange(unit, axisType);\n //const height = Math.abs(bottom - top);\n\n const columnClickData: ColumnClickData = {\n unitID: unit?.unit_id,\n unit,\n target,\n height: el?.getBoundingClientRect().height || 0,\n };\n props.onClickedColumn(columnClickData, event);\n}*/\n\nexport function useUnitSelectionTarget(\n unit: IUnit,\n): [React.RefObject<HTMLElement>, boolean, (evt: Event) => void] {\n const ref = useRef<HTMLElement>(null);\n const [selectedUnit, selectUnit] = useUnitSelection();\n const selected = selectedUnit?.unit_id == unit.unit_id;\n\n const onClick = useCallback(\n (evt: Event) => {\n selectUnit?.(unit, ref.current);\n evt.stopPropagation();\n },\n [unit, selectUnit],\n );\n\n useEffect(() => {\n if (!selected || selectUnit == null) return;\n // In case we haven't set the position of the unit (if we don't have a target), set the selected unit\n selectUnit(unit, ref.current);\n\n // Scroll the unit into view\n ref.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }, [selected, selectUnit]);\n\n return [ref, selected, onClick];\n}\n\nexport function UnitKeyboardNavigation({\n columnData,\n units,\n allowHorizontalNavigation,\n}: {\n columnData?: ColumnData[];\n units?: UnitLong[];\n allowHorizontalNavigation?: boolean;\n}) {\n if (units == null && columnData == null) {\n throw new Error(\"Either units or columnData must be provided.\");\n }\n\n let _columnData: ColumnData[] = useMemo(() => {\n if (columnData != null) return columnData;\n // Build column data from units\n const colMap = new Map<number, UnitLong[]>();\n for (const unit of units!) {\n if (!colMap.has(unit.col_id)) {\n colMap.set(unit.col_id, []);\n }\n colMap.get(unit.col_id)!.push(unit);\n }\n const cols: ColumnData[] = [];\n for (const [colID, units] of colMap) {\n cols.push({ columnID: colID, units });\n }\n // Sort columns by columnID\n cols.sort((a, b) => a.columnID - b.columnID);\n return cols;\n }, [columnData, units]);\n\n // Default to allowing horizontal navigation only if columnData is provided\n const _allowHorizontalNavigation =\n allowHorizontalNavigation ?? columnData != null;\n\n const selectedUnit = useSelectedUnit() as UnitLong | null;\n const selectUnit = useUnitSelectionDispatch();\n\n const keyMap: Record<number, Direction> = {\n 38: \"up\",\n 40: \"down\",\n };\n if (_allowHorizontalNavigation) {\n keyMap[37] = \"left\";\n keyMap[39] = \"right\";\n }\n\n useKeyHandler(\n (event) => {\n const direction = keyMap[event.keyCode];\n if (direction == null) return;\n const nextUnit = getBestUnit(_columnData, selectedUnit, direction);\n if (nextUnit == null) return;\n selectUnit(nextUnit, null);\n event.stopPropagation();\n },\n [_columnData, selectedUnit],\n );\n return null;\n}\n\ntype Direction = \"up\" | \"down\" | \"left\" | \"right\";\n\nfunction getBestUnit(\n columnData: ColumnData[],\n targetUnit: UnitLong,\n direction: Direction,\n): UnitLong | null {\n const thisColIndex = columnData.findIndex(\n (col) => col.columnID === targetUnit.col_id,\n );\n if (thisColIndex === -1) return null;\n\n // If up or down, stay in the same column\n if (direction === \"up\" || direction === \"down\") {\n const units = columnData[thisColIndex].units;\n const ix = units.findIndex((unit) => unit.unit_id === targetUnit.unit_id);\n if (ix === -1) return null;\n if (direction === \"up\") {\n return units[ix - 1] || null;\n } else {\n return units[ix + 1] || null;\n }\n }\n\n // If left or right, move to adjacent column\n let adjacentColIndex: number;\n if (direction === \"left\") {\n adjacentColIndex =\n (thisColIndex - 1 + columnData.length) % columnData.length;\n } else {\n adjacentColIndex = (thisColIndex + 1) % columnData.length;\n }\n\n const adjacentColUnits = columnData[adjacentColIndex].units;\n return getMostOverlappingUnit(targetUnit, adjacentColUnits);\n}\n\ntype UnitAgeRangeRelationship = AgeRangeQuantifiedDifference & {\n unit: UnitLong;\n};\n\nfunction getMostOverlappingUnit(\n targetUnit: UnitLong,\n candidateUnits: UnitLong[],\n): UnitLong | null {\n const targetAgeRange = [targetUnit.b_age, targetUnit.t_age];\n\n const overlaps: UnitAgeRangeRelationship[] = [];\n for (const candidate of candidateUnits) {\n const candidateAgeRange = [candidate.b_age, candidate.t_age];\n\n const rel = ageRangeQuantifiedDifference(targetAgeRange, candidateAgeRange);\n if (rel.type === AgeRangeRelationship.Identical) {\n return candidate;\n }\n overlaps.push({ ...rel, unit: candidate });\n }\n\n let bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Containing,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Contained,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.PartialOverlap,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Disjoint,\n );\n bestOverlaps.sort((a, b) => a.distance - b.distance);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n return null;\n}\n"],"names":["scope","atom","columnUnitsMapAtom","useEffect","useRef","useCallback","useMemo","units","useKeyHandler","ageRangeQuantifiedDifference","AgeRangeRelationship"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { BaseUnit, UnitLong } from '@macrostrat/api-types';
|
|
|
2
2
|
import { IUnit } from '../units/types';
|
|
3
3
|
import { ColumnData } from '@macrostrat/data-provider';
|
|
4
4
|
type UnitSelectDispatch = (unit: number | BaseUnit | null, target: HTMLElement | null) => void;
|
|
5
|
+
export declare function useUnitSelection(): any;
|
|
5
6
|
export declare function useUnitSelectionDispatch(): UnitSelectDispatch;
|
|
6
7
|
export declare function useSelectedUnit(): any;
|
|
7
8
|
export interface ColumnClickData {
|
|
@@ -3,6 +3,9 @@ import { useMemo, useEffect, useRef, useCallback } from "react";
|
|
|
3
3
|
import { atom } from "jotai";
|
|
4
4
|
import { scope, columnUnitsMapAtom } from "./store.js";
|
|
5
5
|
import { ageRangeQuantifiedDifference, AgeRangeRelationship } from "@macrostrat/stratigraphy-utils";
|
|
6
|
+
function useUnitSelection() {
|
|
7
|
+
return scope.use(selectedUnitAtom);
|
|
8
|
+
}
|
|
6
9
|
function useUnitSelectionDispatch() {
|
|
7
10
|
return scope.useSetAtom(selectedUnitAtom);
|
|
8
11
|
}
|
|
@@ -27,6 +30,7 @@ const selectedUnitAtom = atom(
|
|
|
27
30
|
(get, set, selectedUnit, target = null) => {
|
|
28
31
|
if (!get(allowUnitSelectionAtom)) {
|
|
29
32
|
console.error("Unit selection is disabled.");
|
|
33
|
+
return null;
|
|
30
34
|
}
|
|
31
35
|
let unitID = null;
|
|
32
36
|
let unit = null;
|
|
@@ -76,9 +80,8 @@ function UnitSelectionCallbackManager({
|
|
|
76
80
|
return null;
|
|
77
81
|
}
|
|
78
82
|
function useUnitSelectionTarget(unit) {
|
|
79
|
-
const ref = useRef();
|
|
80
|
-
const selectedUnit =
|
|
81
|
-
const selectUnit = useUnitSelectionDispatch();
|
|
83
|
+
const ref = useRef(null);
|
|
84
|
+
const [selectedUnit, selectUnit] = useUnitSelection();
|
|
82
85
|
const selected = selectedUnit?.unit_id == unit.unit_id;
|
|
83
86
|
const onClick = useCallback(
|
|
84
87
|
(evt) => {
|
|
@@ -219,6 +222,7 @@ export {
|
|
|
219
222
|
useAtomOverlayPosition,
|
|
220
223
|
useColumnRef,
|
|
221
224
|
useSelectedUnit,
|
|
225
|
+
useUnitSelection,
|
|
222
226
|
useUnitSelectionDispatch,
|
|
223
227
|
useUnitSelectionTarget
|
|
224
228
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unit-selection.js","sources":["../../src/data-provider/unit-selection.ts"],"sourcesContent":["import type { BaseUnit, UnitLong } from \"@macrostrat/api-types\";\nimport { useKeyHandler } from \"@macrostrat/ui-components\";\nimport { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { RectBounds, IUnit } from \"../units/types\";\nimport { atom } from \"jotai\";\nimport { scope, columnUnitsMapAtom } from \"./store\";\nimport {\n AgeRangeQuantifiedDifference,\n ageRangeQuantifiedDifference,\n AgeRangeRelationship,\n} from \"@macrostrat/stratigraphy-utils\";\nimport type { ColumnData } from \"@macrostrat/data-provider\";\n\ntype UnitSelectDispatch = (\n unit: number | BaseUnit | null,\n target: HTMLElement | null,\n) => void;\n\nexport function useUnitSelectionDispatch(): UnitSelectDispatch {\n return scope.useSetAtom(selectedUnitAtom);\n}\n\nexport function useSelectedUnit() {\n return scope.useAtomValue(selectedUnitAtom);\n}\n\nexport interface ColumnClickData {\n unitID: number | null;\n unit: BaseUnit | null;\n target: HTMLElement | null;\n height: number;\n // Room for boundary IDs eventually\n}\n\nexport interface UnitSelectionCallbacks {\n // It's sort of unfortunate that we need to pass in the column ref here\n onClickedColumn?: (columnClickData: ColumnClickData, event: Event) => void;\n onUnitSelected?: <T extends BaseUnit>(\n unitID: number | null,\n unit: T | null,\n ) => void;\n}\n\nexport const allowUnitSelectionAtom = atom<boolean>(true);\n\nexport const selectedUnitIDAtom = atom<number | null>();\n\nconst overlayPositionAtom = atom<RectBounds | null>();\n\nconst columnRefAtom = atom<{ current: HTMLElement | null }>({ current: null });\n\nexport function useColumnRef() {\n return scope.useAtomValue(columnRefAtom);\n}\n\nconst selectedUnitAtom = atom(\n (get) => {\n if (!get(allowUnitSelectionAtom)) return null;\n\n const unitID = get(selectedUnitIDAtom);\n if (unitID == null) return null;\n const unitsMap = get(columnUnitsMapAtom);\n return unitsMap?.get(unitID) || null;\n },\n (\n get,\n set,\n selectedUnit: number | BaseUnit | null,\n target: HTMLElement | null = null,\n ): BaseUnit | null => {\n if (!get(allowUnitSelectionAtom)) {\n console.error(\"Unit selection is disabled.\");\n }\n\n let unitID: number | null = null;\n let unit: BaseUnit | null = null;\n if (selectedUnit == null) {\n unitID = null;\n } else if (typeof selectedUnit === \"number\") {\n unitID = selectedUnit;\n } else if (\"unit_id\" in selectedUnit) {\n unitID = selectedUnit.unit_id;\n }\n\n if (unitID != null) {\n // Verify that the unit exists in the current colum, else throw\n const unitsMap = get(columnUnitsMapAtom);\n if (!unitsMap?.has(unitID)) {\n throw new Error(\n `Unit with ID ${unitID} not found in current column units.`,\n );\n }\n unit = unitsMap.get(unitID) ?? null;\n }\n\n let overlayPosition: RectBounds | null = null;\n\n const columnEl = get(columnRefAtom)?.current;\n\n if (unit != null && columnEl != null && target != null) {\n const rect = columnEl.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n overlayPosition = {\n x: targetRect.left - rect.left,\n y: targetRect.top - rect.top,\n width: targetRect.width,\n height: targetRect.height,\n };\n }\n\n set(selectedUnitIDAtom, unitID);\n set(overlayPositionAtom, overlayPosition);\n\n return unit;\n },\n);\n\nexport function useAtomOverlayPosition() {\n return scope.useAtomValue(overlayPositionAtom);\n}\n\nexport function UnitSelectionCallbackManager({\n onUnitSelected,\n}: UnitSelectionCallbacks) {\n const selectedUnit = scope.useAtomValue(selectedUnitAtom);\n useEffect(() => {\n onUnitSelected?.(selectedUnit?.unit_id ?? null, selectedUnit ?? null);\n }, [selectedUnit?.unit_id]);\n return null;\n}\n\n/** TODO: figure out if onClickedColumn is still needed\n /** This is not the natural place to get positions within the column,\n * but it will work for now.\nif (props.onClickedColumn) {\n // Infer height from top and bottom height of unit (because that's passed back with the call)\n //const py = event.y;\n //const [bottom, top] = getUnitHeightRange(unit, axisType);\n //const height = Math.abs(bottom - top);\n\n const columnClickData: ColumnClickData = {\n unitID: unit?.unit_id,\n unit,\n target,\n height: el?.getBoundingClientRect().height || 0,\n };\n props.onClickedColumn(columnClickData, event);\n}*/\n\nexport function useUnitSelectionTarget(\n unit: IUnit,\n): [React.RefObject<HTMLElement>, boolean, (evt: Event) => void] {\n const ref = useRef<HTMLElement>();\n const selectedUnit = useSelectedUnit();\n const selectUnit = useUnitSelectionDispatch();\n const selected = selectedUnit?.unit_id == unit.unit_id;\n\n const onClick = useCallback(\n (evt: Event) => {\n selectUnit?.(unit, ref.current);\n evt.stopPropagation();\n },\n [unit, selectUnit],\n );\n\n useEffect(() => {\n if (!selected || selectUnit == null) return;\n // In case we haven't set the position of the unit (if we don't have a target), set the selected unit\n selectUnit(unit, ref.current);\n\n // Scroll the unit into view\n ref.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }, [selected, selectUnit]);\n\n return [ref, selected, onClick];\n}\n\nexport function UnitKeyboardNavigation({\n columnData,\n units,\n allowHorizontalNavigation,\n}: {\n columnData?: ColumnData[];\n units?: UnitLong[];\n allowHorizontalNavigation?: boolean;\n}) {\n if (units == null && columnData == null) {\n throw new Error(\"Either units or columnData must be provided.\");\n }\n\n let _columnData: ColumnData[] = useMemo(() => {\n if (columnData != null) return columnData;\n // Build column data from units\n const colMap = new Map<number, UnitLong[]>();\n for (const unit of units!) {\n if (!colMap.has(unit.col_id)) {\n colMap.set(unit.col_id, []);\n }\n colMap.get(unit.col_id)!.push(unit);\n }\n const cols: ColumnData[] = [];\n for (const [colID, units] of colMap) {\n cols.push({ columnID: colID, units });\n }\n // Sort columns by columnID\n cols.sort((a, b) => a.columnID - b.columnID);\n return cols;\n }, [columnData, units]);\n\n // Default to allowing horizontal navigation only if columnData is provided\n const _allowHorizontalNavigation =\n allowHorizontalNavigation ?? columnData != null;\n\n const selectedUnit = useSelectedUnit() as UnitLong | null;\n const selectUnit = useUnitSelectionDispatch();\n\n const keyMap: Record<number, Direction> = {\n 38: \"up\",\n 40: \"down\",\n };\n if (_allowHorizontalNavigation) {\n keyMap[37] = \"left\";\n keyMap[39] = \"right\";\n }\n\n useKeyHandler(\n (event) => {\n const direction = keyMap[event.keyCode];\n if (direction == null) return;\n const nextUnit = getBestUnit(_columnData, selectedUnit, direction);\n if (nextUnit == null) return;\n selectUnit(nextUnit, null);\n event.stopPropagation();\n },\n [_columnData, selectedUnit],\n );\n return null;\n}\n\ntype Direction = \"up\" | \"down\" | \"left\" | \"right\";\n\nfunction getBestUnit(\n columnData: ColumnData[],\n targetUnit: UnitLong,\n direction: Direction,\n): UnitLong | null {\n const thisColIndex = columnData.findIndex(\n (col) => col.columnID === targetUnit.col_id,\n );\n if (thisColIndex === -1) return null;\n\n // If up or down, stay in the same column\n if (direction === \"up\" || direction === \"down\") {\n const units = columnData[thisColIndex].units;\n const ix = units.findIndex((unit) => unit.unit_id === targetUnit.unit_id);\n if (ix === -1) return null;\n if (direction === \"up\") {\n return units[ix - 1] || null;\n } else {\n return units[ix + 1] || null;\n }\n }\n\n // If left or right, move to adjacent column\n let adjacentColIndex: number;\n if (direction === \"left\") {\n adjacentColIndex =\n (thisColIndex - 1 + columnData.length) % columnData.length;\n } else {\n adjacentColIndex = (thisColIndex + 1) % columnData.length;\n }\n\n const adjacentColUnits = columnData[adjacentColIndex].units;\n return getMostOverlappingUnit(targetUnit, adjacentColUnits);\n}\n\ntype UnitAgeRangeRelationship = AgeRangeQuantifiedDifference & {\n unit: UnitLong;\n};\n\nfunction getMostOverlappingUnit(\n targetUnit: UnitLong,\n candidateUnits: UnitLong[],\n): UnitLong | null {\n const targetAgeRange = [targetUnit.b_age, targetUnit.t_age];\n\n const overlaps: UnitAgeRangeRelationship[] = [];\n for (const candidate of candidateUnits) {\n const candidateAgeRange = [candidate.b_age, candidate.t_age];\n\n const rel = ageRangeQuantifiedDifference(targetAgeRange, candidateAgeRange);\n if (rel.type === AgeRangeRelationship.Identical) {\n return candidate;\n }\n overlaps.push({ ...rel, unit: candidate });\n }\n\n let bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Containing,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Contained,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.PartialOverlap,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Disjoint,\n );\n bestOverlaps.sort((a, b) => a.distance - b.distance);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n return null;\n}\n"],"names":["units"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unit-selection.js","sources":["../../src/data-provider/unit-selection.ts"],"sourcesContent":["import type { BaseUnit, UnitLong } from \"@macrostrat/api-types\";\nimport { useKeyHandler } from \"@macrostrat/ui-components\";\nimport { useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { RectBounds, IUnit } from \"../units/types\";\nimport { atom } from \"jotai\";\nimport { scope, columnUnitsMapAtom } from \"./store\";\nimport {\n AgeRangeQuantifiedDifference,\n ageRangeQuantifiedDifference,\n AgeRangeRelationship,\n} from \"@macrostrat/stratigraphy-utils\";\nimport type { ColumnData } from \"@macrostrat/data-provider\";\n\ntype UnitSelectDispatch = (\n unit: number | BaseUnit | null,\n target: HTMLElement | null,\n) => void;\n\nexport function useUnitSelection() {\n return scope.use(selectedUnitAtom);\n}\n\nexport function useUnitSelectionDispatch(): UnitSelectDispatch {\n return scope.useSetAtom(selectedUnitAtom);\n}\n\nexport function useSelectedUnit() {\n return scope.useAtomValue(selectedUnitAtom);\n}\n\nexport interface ColumnClickData {\n unitID: number | null;\n unit: BaseUnit | null;\n target: HTMLElement | null;\n height: number;\n // Room for boundary IDs eventually\n}\n\nexport interface UnitSelectionCallbacks {\n // It's sort of unfortunate that we need to pass in the column ref here\n onClickedColumn?: (columnClickData: ColumnClickData, event: Event) => void;\n onUnitSelected?: <T extends BaseUnit>(\n unitID: number | null,\n unit: T | null,\n ) => void;\n}\n\nexport const allowUnitSelectionAtom = atom<boolean>(true);\n\nexport const selectedUnitIDAtom = atom<number | null>();\n\nconst overlayPositionAtom = atom<RectBounds | null>();\n\nconst columnRefAtom = atom<{ current: HTMLElement | null }>({ current: null });\n\nexport function useColumnRef() {\n return scope.useAtomValue(columnRefAtom);\n}\n\nconst selectedUnitAtom = atom(\n (get) => {\n if (!get(allowUnitSelectionAtom)) return null;\n\n const unitID = get(selectedUnitIDAtom);\n if (unitID == null) return null;\n const unitsMap = get(columnUnitsMapAtom);\n return unitsMap?.get(unitID) || null;\n },\n (\n get,\n set,\n selectedUnit: number | BaseUnit | null,\n target: HTMLElement | null = null,\n ): BaseUnit | null => {\n if (!get(allowUnitSelectionAtom)) {\n console.error(\"Unit selection is disabled.\");\n return null;\n }\n\n let unitID: number | null = null;\n let unit: BaseUnit | null = null;\n if (selectedUnit == null) {\n unitID = null;\n } else if (typeof selectedUnit === \"number\") {\n unitID = selectedUnit;\n } else if (\"unit_id\" in selectedUnit) {\n unitID = selectedUnit.unit_id;\n }\n\n if (unitID != null) {\n const unitsMap = get(columnUnitsMapAtom);\n // Verify that the unit exists in the current colum, else throw\n if (!unitsMap?.has(unitID)) {\n throw new Error(\n `Unit with ID ${unitID} not found in current column units.`,\n );\n }\n unit = unitsMap.get(unitID) ?? null;\n }\n\n let overlayPosition: RectBounds | null = null;\n\n const columnEl = get(columnRefAtom)?.current;\n\n if (unit != null && columnEl != null && target != null) {\n const rect = columnEl.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n overlayPosition = {\n x: targetRect.left - rect.left,\n y: targetRect.top - rect.top,\n width: targetRect.width,\n height: targetRect.height,\n };\n }\n\n set(selectedUnitIDAtom, unitID);\n set(overlayPositionAtom, overlayPosition);\n\n return unit;\n },\n);\n\nexport function useAtomOverlayPosition() {\n return scope.useAtomValue(overlayPositionAtom);\n}\n\nexport function UnitSelectionCallbackManager({\n onUnitSelected,\n}: UnitSelectionCallbacks) {\n const selectedUnit = scope.useAtomValue(selectedUnitAtom);\n useEffect(() => {\n onUnitSelected?.(selectedUnit?.unit_id ?? null, selectedUnit ?? null);\n }, [selectedUnit?.unit_id]);\n return null;\n}\n\n/** TODO: figure out if onClickedColumn is still needed\n /** This is not the natural place to get positions within the column,\n * but it will work for now.\nif (props.onClickedColumn) {\n // Infer height from top and bottom height of unit (because that's passed back with the call)\n //const py = event.y;\n //const [bottom, top] = getUnitHeightRange(unit, axisType);\n //const height = Math.abs(bottom - top);\n\n const columnClickData: ColumnClickData = {\n unitID: unit?.unit_id,\n unit,\n target,\n height: el?.getBoundingClientRect().height || 0,\n };\n props.onClickedColumn(columnClickData, event);\n}*/\n\nexport function useUnitSelectionTarget(\n unit: IUnit,\n): [React.RefObject<HTMLElement>, boolean, (evt: Event) => void] {\n const ref = useRef<HTMLElement>(null);\n const [selectedUnit, selectUnit] = useUnitSelection();\n const selected = selectedUnit?.unit_id == unit.unit_id;\n\n const onClick = useCallback(\n (evt: Event) => {\n selectUnit?.(unit, ref.current);\n evt.stopPropagation();\n },\n [unit, selectUnit],\n );\n\n useEffect(() => {\n if (!selected || selectUnit == null) return;\n // In case we haven't set the position of the unit (if we don't have a target), set the selected unit\n selectUnit(unit, ref.current);\n\n // Scroll the unit into view\n ref.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }, [selected, selectUnit]);\n\n return [ref, selected, onClick];\n}\n\nexport function UnitKeyboardNavigation({\n columnData,\n units,\n allowHorizontalNavigation,\n}: {\n columnData?: ColumnData[];\n units?: UnitLong[];\n allowHorizontalNavigation?: boolean;\n}) {\n if (units == null && columnData == null) {\n throw new Error(\"Either units or columnData must be provided.\");\n }\n\n let _columnData: ColumnData[] = useMemo(() => {\n if (columnData != null) return columnData;\n // Build column data from units\n const colMap = new Map<number, UnitLong[]>();\n for (const unit of units!) {\n if (!colMap.has(unit.col_id)) {\n colMap.set(unit.col_id, []);\n }\n colMap.get(unit.col_id)!.push(unit);\n }\n const cols: ColumnData[] = [];\n for (const [colID, units] of colMap) {\n cols.push({ columnID: colID, units });\n }\n // Sort columns by columnID\n cols.sort((a, b) => a.columnID - b.columnID);\n return cols;\n }, [columnData, units]);\n\n // Default to allowing horizontal navigation only if columnData is provided\n const _allowHorizontalNavigation =\n allowHorizontalNavigation ?? columnData != null;\n\n const selectedUnit = useSelectedUnit() as UnitLong | null;\n const selectUnit = useUnitSelectionDispatch();\n\n const keyMap: Record<number, Direction> = {\n 38: \"up\",\n 40: \"down\",\n };\n if (_allowHorizontalNavigation) {\n keyMap[37] = \"left\";\n keyMap[39] = \"right\";\n }\n\n useKeyHandler(\n (event) => {\n const direction = keyMap[event.keyCode];\n if (direction == null) return;\n const nextUnit = getBestUnit(_columnData, selectedUnit, direction);\n if (nextUnit == null) return;\n selectUnit(nextUnit, null);\n event.stopPropagation();\n },\n [_columnData, selectedUnit],\n );\n return null;\n}\n\ntype Direction = \"up\" | \"down\" | \"left\" | \"right\";\n\nfunction getBestUnit(\n columnData: ColumnData[],\n targetUnit: UnitLong,\n direction: Direction,\n): UnitLong | null {\n const thisColIndex = columnData.findIndex(\n (col) => col.columnID === targetUnit.col_id,\n );\n if (thisColIndex === -1) return null;\n\n // If up or down, stay in the same column\n if (direction === \"up\" || direction === \"down\") {\n const units = columnData[thisColIndex].units;\n const ix = units.findIndex((unit) => unit.unit_id === targetUnit.unit_id);\n if (ix === -1) return null;\n if (direction === \"up\") {\n return units[ix - 1] || null;\n } else {\n return units[ix + 1] || null;\n }\n }\n\n // If left or right, move to adjacent column\n let adjacentColIndex: number;\n if (direction === \"left\") {\n adjacentColIndex =\n (thisColIndex - 1 + columnData.length) % columnData.length;\n } else {\n adjacentColIndex = (thisColIndex + 1) % columnData.length;\n }\n\n const adjacentColUnits = columnData[adjacentColIndex].units;\n return getMostOverlappingUnit(targetUnit, adjacentColUnits);\n}\n\ntype UnitAgeRangeRelationship = AgeRangeQuantifiedDifference & {\n unit: UnitLong;\n};\n\nfunction getMostOverlappingUnit(\n targetUnit: UnitLong,\n candidateUnits: UnitLong[],\n): UnitLong | null {\n const targetAgeRange = [targetUnit.b_age, targetUnit.t_age];\n\n const overlaps: UnitAgeRangeRelationship[] = [];\n for (const candidate of candidateUnits) {\n const candidateAgeRange = [candidate.b_age, candidate.t_age];\n\n const rel = ageRangeQuantifiedDifference(targetAgeRange, candidateAgeRange);\n if (rel.type === AgeRangeRelationship.Identical) {\n return candidate;\n }\n overlaps.push({ ...rel, unit: candidate });\n }\n\n let bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Containing,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Contained,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.PartialOverlap,\n );\n bestOverlaps.sort((a, b) => b.overlap - a.overlap);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n\n bestOverlaps = overlaps.filter(\n (d) => d.type === AgeRangeRelationship.Disjoint,\n );\n bestOverlaps.sort((a, b) => a.distance - b.distance);\n if (bestOverlaps.length > 0) {\n return bestOverlaps[0].unit;\n }\n return null;\n}\n"],"names":["units"],"mappings":";;;;;AAkBO,SAAS,mBAAmB;AACjC,SAAO,MAAM,IAAI,gBAAgB;AACnC;AAEO,SAAS,2BAA+C;AAC7D,SAAO,MAAM,WAAW,gBAAgB;AAC1C;AAEO,SAAS,kBAAkB;AAChC,SAAO,MAAM,aAAa,gBAAgB;AAC5C;AAmBO,MAAM,yBAAyB,KAAc,IAAI;AAEjD,MAAM,qBAAqB,KAAA;AAElC,MAAM,sBAAsB,KAAA;AAE5B,MAAM,gBAAgB,KAAsC,EAAE,SAAS,MAAM;AAEtE,SAAS,eAAe;AAC7B,SAAO,MAAM,aAAa,aAAa;AACzC;AAEA,MAAM,mBAAmB;AAAA,EACvB,CAAC,QAAQ;AACP,QAAI,CAAC,IAAI,sBAAsB,EAAG,QAAO;AAEzC,UAAM,SAAS,IAAI,kBAAkB;AACrC,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,WAAW,IAAI,kBAAkB;AACvC,WAAO,UAAU,IAAI,MAAM,KAAK;AAAA,EAClC;AAAA,EACA,CACE,KACA,KACA,cACA,SAA6B,SACT;AACpB,QAAI,CAAC,IAAI,sBAAsB,GAAG;AAChC,cAAQ,MAAM,6BAA6B;AAC3C,aAAO;AAAA,IACT;AAEA,QAAI,SAAwB;AAC5B,QAAI,OAAwB;AAC5B,QAAI,gBAAgB,MAAM;AACxB,eAAS;AAAA,IACX,WAAW,OAAO,iBAAiB,UAAU;AAC3C,eAAS;AAAA,IACX,WAAW,aAAa,cAAc;AACpC,eAAS,aAAa;AAAA,IACxB;AAEA,QAAI,UAAU,MAAM;AAClB,YAAM,WAAW,IAAI,kBAAkB;AAEvC,UAAI,CAAC,UAAU,IAAI,MAAM,GAAG;AAC1B,cAAM,IAAI;AAAA,UACR,gBAAgB,MAAM;AAAA,QAAA;AAAA,MAE1B;AACA,aAAO,SAAS,IAAI,MAAM,KAAK;AAAA,IACjC;AAEA,QAAI,kBAAqC;AAEzC,UAAM,WAAW,IAAI,aAAa,GAAG;AAErC,QAAI,QAAQ,QAAQ,YAAY,QAAQ,UAAU,MAAM;AACtD,YAAM,OAAO,SAAS,sBAAA;AACtB,YAAM,aAAa,OAAO,sBAAA;AAC1B,wBAAkB;AAAA,QAChB,GAAG,WAAW,OAAO,KAAK;AAAA,QAC1B,GAAG,WAAW,MAAM,KAAK;AAAA,QACzB,OAAO,WAAW;AAAA,QAClB,QAAQ,WAAW;AAAA,MAAA;AAAA,IAEvB;AAEA,QAAI,oBAAoB,MAAM;AAC9B,QAAI,qBAAqB,eAAe;AAExC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,yBAAyB;AACvC,SAAO,MAAM,aAAa,mBAAmB;AAC/C;AAEO,SAAS,6BAA6B;AAAA,EAC3C;AACF,GAA2B;AACzB,QAAM,eAAe,MAAM,aAAa,gBAAgB;AACxD,YAAU,MAAM;AACd,qBAAiB,cAAc,WAAW,MAAM,gBAAgB,IAAI;AAAA,EACtE,GAAG,CAAC,cAAc,OAAO,CAAC;AAC1B,SAAO;AACT;AAoBO,SAAS,uBACd,MAC+D;AAC/D,QAAM,MAAM,OAAoB,IAAI;AACpC,QAAM,CAAC,cAAc,UAAU,IAAI,iBAAA;AACnC,QAAM,WAAW,cAAc,WAAW,KAAK;AAE/C,QAAM,UAAU;AAAA,IACd,CAAC,QAAe;AACd,mBAAa,MAAM,IAAI,OAAO;AAC9B,UAAI,gBAAA;AAAA,IACN;AAAA,IACA,CAAC,MAAM,UAAU;AAAA,EAAA;AAGnB,YAAU,MAAM;AACd,QAAI,CAAC,YAAY,cAAc,KAAM;AAErC,eAAW,MAAM,IAAI,OAAO;AAG5B,QAAI,SAAS,eAAe;AAAA,MAC1B,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,CACT;AAAA,EACH,GAAG,CAAC,UAAU,UAAU,CAAC;AAEzB,SAAO,CAAC,KAAK,UAAU,OAAO;AAChC;AAEO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,SAAS,QAAQ,cAAc,MAAM;AACvC,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAEA,MAAI,cAA4B,QAAQ,MAAM;AAC5C,QAAI,cAAc,KAAM,QAAO;AAE/B,UAAM,6BAAa,IAAA;AACnB,eAAW,QAAQ,OAAQ;AACzB,UAAI,CAAC,OAAO,IAAI,KAAK,MAAM,GAAG;AAC5B,eAAO,IAAI,KAAK,QAAQ,CAAA,CAAE;AAAA,MAC5B;AACA,aAAO,IAAI,KAAK,MAAM,EAAG,KAAK,IAAI;AAAA,IACpC;AACA,UAAM,OAAqB,CAAA;AAC3B,eAAW,CAAC,OAAOA,MAAK,KAAK,QAAQ;AACnC,WAAK,KAAK,EAAE,UAAU,OAAO,OAAAA,QAAO;AAAA,IACtC;AAEA,SAAK,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAC3C,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,KAAK,CAAC;AAGtB,QAAM,6BACJ,6BAA6B,cAAc;AAE7C,QAAM,eAAe,gBAAA;AACrB,QAAM,aAAa,yBAAA;AAEnB,QAAM,SAAoC;AAAA,IACxC,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA;AAEN,MAAI,4BAA4B;AAC9B,WAAO,EAAE,IAAI;AACb,WAAO,EAAE,IAAI;AAAA,EACf;AAEA;AAAA,IACE,CAAC,UAAU;AACT,YAAM,YAAY,OAAO,MAAM,OAAO;AACtC,UAAI,aAAa,KAAM;AACvB,YAAM,WAAW,YAAY,aAAa,cAAc,SAAS;AACjE,UAAI,YAAY,KAAM;AACtB,iBAAW,UAAU,IAAI;AACzB,YAAM,gBAAA;AAAA,IACR;AAAA,IACA,CAAC,aAAa,YAAY;AAAA,EAAA;AAE5B,SAAO;AACT;AAIA,SAAS,YACP,YACA,YACA,WACiB;AACjB,QAAM,eAAe,WAAW;AAAA,IAC9B,CAAC,QAAQ,IAAI,aAAa,WAAW;AAAA,EAAA;AAEvC,MAAI,iBAAiB,GAAI,QAAO;AAGhC,MAAI,cAAc,QAAQ,cAAc,QAAQ;AAC9C,UAAM,QAAQ,WAAW,YAAY,EAAE;AACvC,UAAM,KAAK,MAAM,UAAU,CAAC,SAAS,KAAK,YAAY,WAAW,OAAO;AACxE,QAAI,OAAO,GAAI,QAAO;AACtB,QAAI,cAAc,MAAM;AACtB,aAAO,MAAM,KAAK,CAAC,KAAK;AAAA,IAC1B,OAAO;AACL,aAAO,MAAM,KAAK,CAAC,KAAK;AAAA,IAC1B;AAAA,EACF;AAGA,MAAI;AACJ,MAAI,cAAc,QAAQ;AACxB,wBACG,eAAe,IAAI,WAAW,UAAU,WAAW;AAAA,EACxD,OAAO;AACL,wBAAoB,eAAe,KAAK,WAAW;AAAA,EACrD;AAEA,QAAM,mBAAmB,WAAW,gBAAgB,EAAE;AACtD,SAAO,uBAAuB,YAAY,gBAAgB;AAC5D;AAMA,SAAS,uBACP,YACA,gBACiB;AACjB,QAAM,iBAAiB,CAAC,WAAW,OAAO,WAAW,KAAK;AAE1D,QAAM,WAAuC,CAAA;AAC7C,aAAW,aAAa,gBAAgB;AACtC,UAAM,oBAAoB,CAAC,UAAU,OAAO,UAAU,KAAK;AAE3D,UAAM,MAAM,6BAA6B,gBAAgB,iBAAiB;AAC1E,QAAI,IAAI,SAAS,qBAAqB,WAAW;AAC/C,aAAO;AAAA,IACT;AACA,aAAS,KAAK,EAAE,GAAG,KAAK,MAAM,WAAW;AAAA,EAC3C;AAEA,MAAI,eAAe,SAAS;AAAA,IAC1B,CAAC,MAAM,EAAE,SAAS,qBAAqB;AAAA,EAAA;AAEzC,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;AACjD,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,aAAa,CAAC,EAAE;AAAA,EACzB;AAEA,iBAAe,SAAS;AAAA,IACtB,CAAC,MAAM,EAAE,SAAS,qBAAqB;AAAA,EAAA;AAEzC,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;AACjD,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,aAAa,CAAC,EAAE;AAAA,EACzB;AAEA,iBAAe,SAAS;AAAA,IACtB,CAAC,MAAM,EAAE,SAAS,qBAAqB;AAAA,EAAA;AAEzC,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;AACjD,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,aAAa,CAAC,EAAE;AAAA,EACzB;AAEA,iBAAe,SAAS;AAAA,IACtB,CAAC,MAAM,EAAE,SAAS,qBAAqB;AAAA,EAAA;AAEzC,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACnD,MAAI,aAAa,SAAS,GAAG;AAC3B,WAAO,aAAa,CAAC,EAAE;AAAA,EACzB;AACA,SAAO;AACT;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-area.cjs","sources":["../../../src/facets/carbon-isotopes/data-area.ts"],"sourcesContent":["import { line } from \"d3-shape\";\nimport { createContext, useContext } from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { ColumnLayoutContext } from \"@macrostrat/column-components\";\nimport { useCompositeScale } from \"../../data-provider\";\n\nconst inDomain = (scale, num) => {\n const domain = scale.domain();\n return domain[0] < num < domain[1];\n};\n\nconst createPointLocator = function (opts) {\n const { xScale, scale, getHeight, ...rest } = opts;\n return function (d, s = 0) {\n const height = getHeight(d);\n if (!inDomain(scale, height)) return null;\n return [xScale(d.value), scale(height)];\n };\n};\n\nconst IsotopesDataContext = createContext(null);\n\nexport interface DataAreaProps {\n clipY: boolean;\n parameter: string;\n corrected: boolean;\n system: string;\n children: React.ReactNode;\n getHeight?: Function;\n}\n\nconst IsotopesDataArea = function (props: DataAreaProps) {\n const xScale = useContext(ColumnLayoutContext)?.xScale;\n\n const scale = useCompositeScale();\n\n let { corrected, system, children, getHeight, clipY = false } = props;\n if (getHeight == null) {\n getHeight = function (d) {\n
|
|
1
|
+
{"version":3,"file":"data-area.cjs","sources":["../../../src/facets/carbon-isotopes/data-area.ts"],"sourcesContent":["import { line } from \"d3-shape\";\nimport { createContext, useContext } from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { ColumnLayoutContext } from \"@macrostrat/column-components\";\nimport { useCompositeScale } from \"../../data-provider\";\n\nconst inDomain = (scale, num) => {\n const domain = scale.domain();\n return domain[0] < num < domain[1];\n};\n\nconst createPointLocator = function (opts) {\n const { xScale, scale, getHeight, ...rest } = opts;\n return function (d, s = 0) {\n const height = getHeight(d);\n if (!inDomain(scale, height)) return null;\n return [xScale(d.value), scale(height)];\n };\n};\n\nconst IsotopesDataContext = createContext(null);\n\nexport interface DataAreaProps {\n clipY: boolean;\n parameter: string;\n corrected: boolean;\n system: string;\n children: React.ReactNode;\n getHeight?: Function;\n}\n\nconst IsotopesDataArea = function (props: DataAreaProps) {\n const xScale = useContext(ColumnLayoutContext)?.xScale;\n\n const scale = useCompositeScale();\n\n let { corrected, system, children, getHeight, clipY = false } = props;\n if (getHeight == null) {\n getHeight = function (d) {\n return d.height;\n };\n }\n\n // Handlers for creating points and lines\n const pointLocator = createPointLocator({\n xScale,\n scale,\n corrected,\n system,\n getHeight,\n });\n\n let column = \"avg_\" + system;\n if (corrected) {\n column += \"_corr\";\n }\n const lineLocator = line()\n .x((d) => xScale(d[column]))\n // @ts-ignore\n .y((d) => scale(d.height));\n\n const value = { pointLocator, lineLocator, corrected, system, clipY };\n return h(IsotopesDataContext.Provider, { value }, h(\"g.data\", children));\n};\n\nconst IsotopeDataPoint = function (props) {\n const { pointLocator } = useContext(IsotopesDataContext);\n const { datum, strokeWidth, ...rest } = props;\n const loc = pointLocator(datum);\n if (loc == null) return null;\n const [cx, cy] = loc;\n\n return h(\"circle\", {\n key: datum.sample_id,\n cx,\n cy,\n r: 2,\n ...rest,\n });\n};\n\nconst IsotopeDataLine = function (props) {\n const { values: lineValues, ...rest } = props;\n const { lineLocator } = useContext(IsotopesDataContext);\n return h(\"path\", {\n d: lineLocator(lineValues),\n fill: \"transparent\",\n ...rest,\n });\n};\n\nconst useDataLocator = () => useContext(IsotopesDataContext);\n\nexport { IsotopesDataArea, IsotopeDataPoint, IsotopeDataLine, useDataLocator };\n"],"names":["createContext","useContext","ColumnLayoutContext","useCompositeScale","line","h"],"mappings":";;;;;;;;;AAMA,MAAM,WAAW,CAAC,OAAO,QAAQ;AAC/B,QAAM,SAAS,MAAM,OAAA;AACrB,SAAO,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC;AACnC;AAEA,MAAM,qBAAqB,SAAU,MAAM;AACzC,QAAM,EAAE,QAAQ,OAAO,WAAW,GAAG,SAAS;AAC9C,SAAO,SAAU,GAAG,IAAI,GAAG;AACzB,UAAM,SAAS,UAAU,CAAC;AAC1B,QAAI,CAAC,SAAS,OAAO,MAAM,EAAG,QAAO;AACrC,WAAO,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,MAAM,CAAC;AAAA,EACxC;AACF;AAEA,MAAM,sBAAsBA,MAAAA,cAAc,IAAI;AAW9C,MAAM,mBAAmB,SAAU,OAAsB;AACvD,QAAM,SAASC,MAAAA,WAAWC,iBAAAA,mBAAmB,GAAG;AAEhD,QAAM,QAAQC,MAAAA,kBAAA;AAEd,MAAI,EAAE,WAAW,QAAQ,UAAU,WAAW,QAAQ,UAAU;AAChE,MAAI,aAAa,MAAM;AACrB,gBAAY,SAAU,GAAG;AACvB,aAAO,EAAE;AAAA,IACX;AAAA,EACF;AAGA,QAAM,eAAe,mBAAmB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,MAAI,SAAS,SAAS;AACtB,MAAI,WAAW;AACb,cAAU;AAAA,EACZ;AACA,QAAM,cAAcC,QAAAA,KAAA,EACjB,EAAE,CAAC,MAAM,OAAO,EAAE,MAAM,CAAC,CAAC,EAE1B,EAAE,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;AAE3B,QAAM,QAAQ,EAAE,cAAc,aAAa,WAAW,QAAQ,MAAA;AAC9D,SAAOC,WAAAA,QAAE,oBAAoB,UAAU,EAAE,SAASA,WAAAA,QAAE,UAAU,QAAQ,CAAC;AACzE;AAEA,MAAM,mBAAmB,SAAU,OAAO;AACxC,QAAM,EAAE,aAAA,IAAiBJ,MAAAA,WAAW,mBAAmB;AACvD,QAAM,EAAE,OAAO,aAAa,GAAG,SAAS;AACxC,QAAM,MAAM,aAAa,KAAK;AAC9B,MAAI,OAAO,KAAM,QAAO;AACxB,QAAM,CAAC,IAAI,EAAE,IAAI;AAEjB,SAAOI,WAAAA,QAAE,UAAU;AAAA,IACjB,KAAK,MAAM;AAAA,IACX;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,GAAG;AAAA,EAAA,CACJ;AACH;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-area.js","sources":["../../../src/facets/carbon-isotopes/data-area.ts"],"sourcesContent":["import { line } from \"d3-shape\";\nimport { createContext, useContext } from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { ColumnLayoutContext } from \"@macrostrat/column-components\";\nimport { useCompositeScale } from \"../../data-provider\";\n\nconst inDomain = (scale, num) => {\n const domain = scale.domain();\n return domain[0] < num < domain[1];\n};\n\nconst createPointLocator = function (opts) {\n const { xScale, scale, getHeight, ...rest } = opts;\n return function (d, s = 0) {\n const height = getHeight(d);\n if (!inDomain(scale, height)) return null;\n return [xScale(d.value), scale(height)];\n };\n};\n\nconst IsotopesDataContext = createContext(null);\n\nexport interface DataAreaProps {\n clipY: boolean;\n parameter: string;\n corrected: boolean;\n system: string;\n children: React.ReactNode;\n getHeight?: Function;\n}\n\nconst IsotopesDataArea = function (props: DataAreaProps) {\n const xScale = useContext(ColumnLayoutContext)?.xScale;\n\n const scale = useCompositeScale();\n\n let { corrected, system, children, getHeight, clipY = false } = props;\n if (getHeight == null) {\n getHeight = function (d) {\n
|
|
1
|
+
{"version":3,"file":"data-area.js","sources":["../../../src/facets/carbon-isotopes/data-area.ts"],"sourcesContent":["import { line } from \"d3-shape\";\nimport { createContext, useContext } from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { ColumnLayoutContext } from \"@macrostrat/column-components\";\nimport { useCompositeScale } from \"../../data-provider\";\n\nconst inDomain = (scale, num) => {\n const domain = scale.domain();\n return domain[0] < num < domain[1];\n};\n\nconst createPointLocator = function (opts) {\n const { xScale, scale, getHeight, ...rest } = opts;\n return function (d, s = 0) {\n const height = getHeight(d);\n if (!inDomain(scale, height)) return null;\n return [xScale(d.value), scale(height)];\n };\n};\n\nconst IsotopesDataContext = createContext(null);\n\nexport interface DataAreaProps {\n clipY: boolean;\n parameter: string;\n corrected: boolean;\n system: string;\n children: React.ReactNode;\n getHeight?: Function;\n}\n\nconst IsotopesDataArea = function (props: DataAreaProps) {\n const xScale = useContext(ColumnLayoutContext)?.xScale;\n\n const scale = useCompositeScale();\n\n let { corrected, system, children, getHeight, clipY = false } = props;\n if (getHeight == null) {\n getHeight = function (d) {\n return d.height;\n };\n }\n\n // Handlers for creating points and lines\n const pointLocator = createPointLocator({\n xScale,\n scale,\n corrected,\n system,\n getHeight,\n });\n\n let column = \"avg_\" + system;\n if (corrected) {\n column += \"_corr\";\n }\n const lineLocator = line()\n .x((d) => xScale(d[column]))\n // @ts-ignore\n .y((d) => scale(d.height));\n\n const value = { pointLocator, lineLocator, corrected, system, clipY };\n return h(IsotopesDataContext.Provider, { value }, h(\"g.data\", children));\n};\n\nconst IsotopeDataPoint = function (props) {\n const { pointLocator } = useContext(IsotopesDataContext);\n const { datum, strokeWidth, ...rest } = props;\n const loc = pointLocator(datum);\n if (loc == null) return null;\n const [cx, cy] = loc;\n\n return h(\"circle\", {\n key: datum.sample_id,\n cx,\n cy,\n r: 2,\n ...rest,\n });\n};\n\nconst IsotopeDataLine = function (props) {\n const { values: lineValues, ...rest } = props;\n const { lineLocator } = useContext(IsotopesDataContext);\n return h(\"path\", {\n d: lineLocator(lineValues),\n fill: \"transparent\",\n ...rest,\n });\n};\n\nconst useDataLocator = () => useContext(IsotopesDataContext);\n\nexport { IsotopesDataArea, IsotopeDataPoint, IsotopeDataLine, useDataLocator };\n"],"names":[],"mappings":";;;;;AAMA,MAAM,WAAW,CAAC,OAAO,QAAQ;AAC/B,QAAM,SAAS,MAAM,OAAA;AACrB,SAAO,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC;AACnC;AAEA,MAAM,qBAAqB,SAAU,MAAM;AACzC,QAAM,EAAE,QAAQ,OAAO,WAAW,GAAG,SAAS;AAC9C,SAAO,SAAU,GAAG,IAAI,GAAG;AACzB,UAAM,SAAS,UAAU,CAAC;AAC1B,QAAI,CAAC,SAAS,OAAO,MAAM,EAAG,QAAO;AACrC,WAAO,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,MAAM,CAAC;AAAA,EACxC;AACF;AAEA,MAAM,sBAAsB,cAAc,IAAI;AAW9C,MAAM,mBAAmB,SAAU,OAAsB;AACvD,QAAM,SAAS,WAAW,mBAAmB,GAAG;AAEhD,QAAM,QAAQ,kBAAA;AAEd,MAAI,EAAE,WAAW,QAAQ,UAAU,WAAW,QAAQ,UAAU;AAChE,MAAI,aAAa,MAAM;AACrB,gBAAY,SAAU,GAAG;AACvB,aAAO,EAAE;AAAA,IACX;AAAA,EACF;AAGA,QAAM,eAAe,mBAAmB;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAED,MAAI,SAAS,SAAS;AACtB,MAAI,WAAW;AACb,cAAU;AAAA,EACZ;AACA,QAAM,cAAc,KAAA,EACjB,EAAE,CAAC,MAAM,OAAO,EAAE,MAAM,CAAC,CAAC,EAE1B,EAAE,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;AAE3B,QAAM,QAAQ,EAAE,cAAc,aAAa,WAAW,QAAQ,MAAA;AAC9D,SAAO,EAAE,oBAAoB,UAAU,EAAE,SAAS,EAAE,UAAU,QAAQ,CAAC;AACzE;AAEA,MAAM,mBAAmB,SAAU,OAAO;AACxC,QAAM,EAAE,aAAA,IAAiB,WAAW,mBAAmB;AACvD,QAAM,EAAE,OAAO,aAAa,GAAG,SAAS;AACxC,QAAM,MAAM,aAAa,KAAK;AAC9B,MAAI,OAAO,KAAM,QAAO;AACxB,QAAM,CAAC,IAAI,EAAE,IAAI;AAEjB,SAAO,EAAE,UAAU;AAAA,IACjB,KAAK,MAAM;AAAA,IACX;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH,GAAG;AAAA,EAAA,CACJ;AACH;"}
|
package/dist/index.cjs
CHANGED
|
@@ -10,7 +10,7 @@ const ageRange = require("./unit-details/age-range.cjs");
|
|
|
10
10
|
const composite = require("./units/composite.cjs");
|
|
11
11
|
const columns = require("./maps/layers/columns.cjs");
|
|
12
12
|
const base = require("./facets/measurements/base.cjs");
|
|
13
|
-
const
|
|
13
|
+
const identifiers = require("./unit-details/identifiers.cjs");
|
|
14
14
|
const layers = require("./maps/column-navigation/svg/layers.cjs");
|
|
15
15
|
const core = require("./maps/column-correlation/core.cjs");
|
|
16
16
|
const state = require("./maps/column-correlation/state.cjs");
|
|
@@ -23,6 +23,7 @@ const provider = require("./facets/fossils/provider.cjs");
|
|
|
23
23
|
const types = require("./prepare-units/types.cjs");
|
|
24
24
|
const index$4 = require("./maps/inset-map/index.cjs");
|
|
25
25
|
const isotopesColumn = require("./facets/carbon-isotopes/isotopes-column.cjs");
|
|
26
|
+
const panel = require("./unit-details/panel.cjs");
|
|
26
27
|
const store = require("./data-provider/store.cjs");
|
|
27
28
|
const units = require("./maps/layers/units.cjs");
|
|
28
29
|
const dataProvider = require("./facets/carbon-isotopes/data-provider.cjs");
|
|
@@ -30,6 +31,7 @@ const utils = require("./prepare-units/utils.cjs");
|
|
|
30
31
|
const index$5 = require("./facets/fossils/index.cjs");
|
|
31
32
|
const taxonRanges = require("./facets/fossils/taxon-ranges.cjs");
|
|
32
33
|
const sgp = require("./facets/measurements/sgp.cjs");
|
|
34
|
+
const stratNames = require("./unit-details/strat-names.cjs");
|
|
33
35
|
const modalPanel = require("./unit-details/modal-panel.cjs");
|
|
34
36
|
const popover = require("./unit-details/popover.cjs");
|
|
35
37
|
const unitSelection = require("./data-provider/unit-selection.cjs");
|
|
@@ -79,13 +81,9 @@ exports.TruncatedList = base.TruncatedList;
|
|
|
79
81
|
exports.groupNotesByPixelDistance = base.groupNotesByPixelDistance;
|
|
80
82
|
exports.mergeHeightRanges = base.mergeHeightRanges;
|
|
81
83
|
exports.standardizeMeasurementHeight = base.standardizeMeasurementHeight;
|
|
82
|
-
exports.ClickableText =
|
|
83
|
-
exports.Identifier =
|
|
84
|
-
exports.
|
|
85
|
-
exports.ReferencesField = panel.ReferencesField;
|
|
86
|
-
exports.ThicknessField = panel.ThicknessField;
|
|
87
|
-
exports.UnitDetailsFeature = panel.UnitDetailsFeature;
|
|
88
|
-
exports.UnitDetailsPanel = panel.UnitDetailsPanel;
|
|
84
|
+
exports.ClickableText = identifiers.ClickableText;
|
|
85
|
+
exports.Identifier = identifiers.Identifier;
|
|
86
|
+
exports.UnitIdentifier = identifiers.UnitIdentifier;
|
|
89
87
|
exports.ColumnCenters = layers.ColumnCenters;
|
|
90
88
|
exports.ColumnFeatures = layers.ColumnFeatures;
|
|
91
89
|
exports.ColumnKeyboardNavigation = layers.ColumnKeyboardNavigation;
|
|
@@ -113,6 +111,11 @@ exports.HybridScaleType = types.HybridScaleType;
|
|
|
113
111
|
exports.InsetMap = index$4.InsetMap;
|
|
114
112
|
exports.IsotopesColumn = isotopesColumn.IsotopesColumn;
|
|
115
113
|
exports.IsotopesDataset = isotopesColumn.IsotopesDataset;
|
|
114
|
+
exports.LegendPanelHeader = panel.LegendPanelHeader;
|
|
115
|
+
exports.ReferencesField = panel.ReferencesField;
|
|
116
|
+
exports.ThicknessField = panel.ThicknessField;
|
|
117
|
+
exports.UnitDetailsFeature = panel.UnitDetailsFeature;
|
|
118
|
+
exports.UnitDetailsPanel = panel.UnitDetailsPanel;
|
|
116
119
|
exports.LithologiesProvider = store.LithologiesProvider;
|
|
117
120
|
exports.MacrostratColumnDataProvider = store.MacrostratColumnDataProvider;
|
|
118
121
|
exports.MacrostratColumnProvider = store.MacrostratColumnProvider;
|
|
@@ -141,6 +144,7 @@ exports.unitsOverlap = utils.unitsOverlap;
|
|
|
141
144
|
exports.PBDBFossilsColumn = index$5.PBDBFossilsColumn;
|
|
142
145
|
exports.PBDBOccurrencesMatrix = taxonRanges.PBDBOccurrencesMatrix;
|
|
143
146
|
exports.SGPMeasurementsColumn = sgp.SGPMeasurementsColumn;
|
|
147
|
+
exports.StratNameField = stratNames.StratNameField;
|
|
144
148
|
exports.UnitDetailsPanelWithNavigation = modalPanel.UnitDetailsPanelWithNavigation;
|
|
145
149
|
exports.UnitDetailsPopover = popover.UnitDetailsPopover;
|
|
146
150
|
exports.UnitSelectionPopover = popover.UnitSelectionPopover;
|
|
@@ -151,6 +155,7 @@ exports.selectedUnitIDAtom = unitSelection.selectedUnitIDAtom;
|
|
|
151
155
|
exports.useAtomOverlayPosition = unitSelection.useAtomOverlayPosition;
|
|
152
156
|
exports.useColumnRef = unitSelection.useColumnRef;
|
|
153
157
|
exports.useSelectedUnit = unitSelection.useSelectedUnit;
|
|
158
|
+
exports.useUnitSelection = unitSelection.useUnitSelection;
|
|
154
159
|
exports.useUnitSelectionDispatch = unitSelection.useUnitSelectionDispatch;
|
|
155
160
|
exports.useUnitSelectionTarget = unitSelection.useUnitSelectionTarget;
|
|
156
161
|
exports.flattenLithologies = colors.flattenLithologies;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|