@macrostrat/column-views 3.8.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/animated-age-window.cjs +51 -0
  3. package/dist/animated-age-window.cjs.map +1 -0
  4. package/dist/animated-age-window.d.ts +51 -0
  5. package/dist/animated-age-window.js +51 -0
  6. package/dist/animated-age-window.js.map +1 -0
  7. package/dist/column.cjs +11 -1
  8. package/dist/column.cjs.map +1 -1
  9. package/dist/column.d.ts +11 -0
  10. package/dist/column.js +11 -1
  11. package/dist/column.js.map +1 -1
  12. package/dist/correlation-chart/main.cjs +24 -12
  13. package/dist/correlation-chart/main.cjs.map +1 -1
  14. package/dist/correlation-chart/main.d.ts +8 -1
  15. package/dist/correlation-chart/main.js +24 -12
  16. package/dist/correlation-chart/main.js.map +1 -1
  17. package/dist/data-provider/store.cjs +17 -4
  18. package/dist/data-provider/store.cjs.map +1 -1
  19. package/dist/data-provider/store.d.ts +6 -1
  20. package/dist/data-provider/store.js +17 -4
  21. package/dist/data-provider/store.js.map +1 -1
  22. package/dist/index.cjs +17 -42
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +3 -1
  25. package/dist/index.js +3 -34
  26. package/dist/index.js.map +1 -1
  27. package/dist/prepare-units/composite-scale.cjs +94 -8
  28. package/dist/prepare-units/composite-scale.cjs.map +1 -1
  29. package/dist/prepare-units/composite-scale.d.ts +39 -0
  30. package/dist/prepare-units/composite-scale.js +96 -10
  31. package/dist/prepare-units/composite-scale.js.map +1 -1
  32. package/dist/prepare-units/helpers.cjs +0 -1
  33. package/dist/prepare-units/helpers.cjs.map +1 -1
  34. package/dist/prepare-units/helpers.js +0 -1
  35. package/dist/prepare-units/helpers.js.map +1 -1
  36. package/dist/prepare-units/index.cjs +33 -12
  37. package/dist/prepare-units/index.cjs.map +1 -1
  38. package/dist/prepare-units/index.js +34 -13
  39. package/dist/prepare-units/index.js.map +1 -1
  40. package/dist/prepare-units/types.cjs.map +1 -1
  41. package/dist/prepare-units/types.d.ts +13 -0
  42. package/dist/prepare-units/types.js.map +1 -1
  43. package/dist/section.cjs +4 -2
  44. package/dist/section.cjs.map +1 -1
  45. package/dist/section.d.ts +4 -1
  46. package/dist/section.js +4 -2
  47. package/dist/section.js.map +1 -1
  48. package/dist/units/boxes.cjs +22 -39
  49. package/dist/units/boxes.cjs.map +1 -1
  50. package/dist/units/boxes.js +24 -41
  51. package/dist/units/boxes.js.map +1 -1
  52. package/dist/units/composite.cjs +12 -12
  53. package/dist/units/composite.cjs.map +1 -1
  54. package/dist/units/composite.js +12 -12
  55. package/dist/units/composite.js.map +1 -1
  56. package/dist/units/index.cjs +7 -11
  57. package/dist/units/index.cjs.map +1 -1
  58. package/dist/units/index.d.ts +0 -1
  59. package/dist/units/index.js +4 -9
  60. package/dist/units/index.js.map +1 -1
  61. package/package.json +10 -31
  62. package/src/animated-age-window.ts +120 -0
  63. package/src/column.ts +24 -0
  64. package/src/correlation-chart/main.ts +30 -8
  65. package/src/data-provider/store.ts +21 -2
  66. package/src/index.ts +4 -1
  67. package/src/prepare-units/composite-scale.ts +210 -10
  68. package/src/prepare-units/helpers.ts +0 -2
  69. package/src/prepare-units/index.ts +68 -14
  70. package/src/prepare-units/types.ts +13 -0
  71. package/src/section.ts +6 -0
  72. package/src/units/boxes.ts +37 -56
  73. package/src/units/composite.ts +21 -12
  74. package/src/units/index.ts +9 -26
  75. package/dist/maps/column-correlation/core.cjs +0 -288
  76. package/dist/maps/column-correlation/core.cjs.map +0 -1
  77. package/dist/maps/column-correlation/core.d.ts +0 -9
  78. package/dist/maps/column-correlation/core.js +0 -286
  79. package/dist/maps/column-correlation/core.js.map +0 -1
  80. package/dist/maps/column-correlation/index.d.ts +0 -2
  81. package/dist/maps/column-correlation/state.cjs +0 -193
  82. package/dist/maps/column-correlation/state.cjs.map +0 -1
  83. package/dist/maps/column-correlation/state.d.ts +0 -62
  84. package/dist/maps/column-correlation/state.js +0 -190
  85. package/dist/maps/column-correlation/state.js.map +0 -1
  86. package/dist/maps/column-navigation/index.d.ts +0 -2
  87. package/dist/maps/column-navigation/mapbox/index.cjs +0 -215
  88. package/dist/maps/column-navigation/mapbox/index.cjs.map +0 -1
  89. package/dist/maps/column-navigation/mapbox/index.d.ts +0 -38
  90. package/dist/maps/column-navigation/mapbox/index.js +0 -213
  91. package/dist/maps/column-navigation/mapbox/index.js.map +0 -1
  92. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs +0 -105
  93. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs.map +0 -1
  94. package/dist/maps/column-navigation/mapbox/keyboard-navigation.d.ts +0 -8
  95. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js +0 -105
  96. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js.map +0 -1
  97. package/dist/maps/column-navigation/mapbox/state.cjs +0 -73
  98. package/dist/maps/column-navigation/mapbox/state.cjs.map +0 -1
  99. package/dist/maps/column-navigation/mapbox/state.d.ts +0 -23
  100. package/dist/maps/column-navigation/mapbox/state.js +0 -71
  101. package/dist/maps/column-navigation/mapbox/state.js.map +0 -1
  102. package/dist/maps/column-navigation/svg/animated.d.ts +0 -1
  103. package/dist/maps/column-navigation/svg/data-fetcher.cjs +0 -25
  104. package/dist/maps/column-navigation/svg/data-fetcher.cjs.map +0 -1
  105. package/dist/maps/column-navigation/svg/data-fetcher.d.ts +0 -6
  106. package/dist/maps/column-navigation/svg/data-fetcher.js +0 -25
  107. package/dist/maps/column-navigation/svg/data-fetcher.js.map +0 -1
  108. package/dist/maps/column-navigation/svg/index.cjs +0 -94
  109. package/dist/maps/column-navigation/svg/index.cjs.map +0 -1
  110. package/dist/maps/column-navigation/svg/index.d.ts +0 -9
  111. package/dist/maps/column-navigation/svg/index.js +0 -93
  112. package/dist/maps/column-navigation/svg/index.js.map +0 -1
  113. package/dist/maps/column-navigation/svg/layers.cjs +0 -177
  114. package/dist/maps/column-navigation/svg/layers.cjs.map +0 -1
  115. package/dist/maps/column-navigation/svg/layers.d.ts +0 -54
  116. package/dist/maps/column-navigation/svg/layers.js +0 -174
  117. package/dist/maps/column-navigation/svg/layers.js.map +0 -1
  118. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs +0 -50
  119. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs.map +0 -1
  120. package/dist/maps/column-navigation/utils/keyboard-navigation.d.ts +0 -10
  121. package/dist/maps/column-navigation/utils/keyboard-navigation.js +0 -50
  122. package/dist/maps/column-navigation/utils/keyboard-navigation.js.map +0 -1
  123. package/dist/maps/index.d.ts +0 -4
  124. package/dist/maps/inset-map/index.cjs +0 -71
  125. package/dist/maps/inset-map/index.cjs.map +0 -1
  126. package/dist/maps/inset-map/index.d.ts +0 -16
  127. package/dist/maps/inset-map/index.js +0 -69
  128. package/dist/maps/inset-map/index.js.map +0 -1
  129. package/dist/maps/layers/columns.cjs +0 -165
  130. package/dist/maps/layers/columns.cjs.map +0 -1
  131. package/dist/maps/layers/columns.d.ts +0 -28
  132. package/dist/maps/layers/columns.js +0 -165
  133. package/dist/maps/layers/columns.js.map +0 -1
  134. package/dist/maps/layers/index.d.ts +0 -2
  135. package/dist/maps/layers/units.cjs +0 -207
  136. package/dist/maps/layers/units.cjs.map +0 -1
  137. package/dist/maps/layers/units.d.ts +0 -14
  138. package/dist/maps/layers/units.js +0 -204
  139. package/dist/maps/layers/units.js.map +0 -1
  140. package/dist/units/colors.cjs +0 -115
  141. package/dist/units/colors.cjs.map +0 -1
  142. package/dist/units/colors.d.ts +0 -20
  143. package/dist/units/colors.js +0 -113
  144. package/dist/units/colors.js.map +0 -1
  145. package/dist/units/resolvers.cjs +0 -125
  146. package/dist/units/resolvers.cjs.map +0 -1
  147. package/dist/units/resolvers.d.ts +0 -8
  148. package/dist/units/resolvers.js +0 -125
  149. package/dist/units/resolvers.js.map +0 -1
  150. package/src/maps/column-correlation/column-correlation-map.stories.ts +0 -108
  151. package/src/maps/column-correlation/core.ts +0 -342
  152. package/src/maps/column-correlation/index.ts +0 -2
  153. package/src/maps/column-correlation/state.ts +0 -315
  154. package/src/maps/column-navigation/index.ts +0 -2
  155. package/src/maps/column-navigation/mapbox/column-navigation-map.stories.ts +0 -278
  156. package/src/maps/column-navigation/mapbox/index.ts +0 -276
  157. package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +0 -133
  158. package/src/maps/column-navigation/mapbox/state.ts +0 -119
  159. package/src/maps/column-navigation/svg/animated.ts +0 -78
  160. package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +0 -46
  161. package/src/maps/column-navigation/svg/data-fetcher.ts +0 -34
  162. package/src/maps/column-navigation/svg/index.ts +0 -96
  163. package/src/maps/column-navigation/svg/layers.ts +0 -233
  164. package/src/maps/column-navigation/utils/keyboard-navigation.ts +0 -58
  165. package/src/maps/index.ts +0 -4
  166. package/src/maps/inset-map/index.ts +0 -87
  167. package/src/maps/inset-map/inset-map.stories.ts +0 -20
  168. package/src/maps/layers/columns.ts +0 -216
  169. package/src/maps/layers/index.ts +0 -2
  170. package/src/maps/layers/units.ts +0 -286
  171. package/src/maps/unit-map.stories.ts +0 -79
  172. package/src/units/colors.ts +0 -183
  173. package/src/units/resolvers.ts +0 -141
package/dist/index.cjs CHANGED
@@ -2,40 +2,33 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const index = require("./units/index.cjs");
4
4
  const ageAxis = require("./age-axis.cjs");
5
- const index$6 = require("./prepare-units/index.cjs");
5
+ const index$3 = require("./prepare-units/index.cjs");
6
+ const animatedAgeWindow = require("./animated-age-window.cjs");
6
7
  const column = require("./column.cjs");
7
8
  const ageModelOverlay = require("./age-model-overlay.cjs");
8
9
  const notes = require("./notes.cjs");
10
+ const mapViews = require("@macrostrat/map-views");
9
11
  const ageRange = require("./unit-details/age-range.cjs");
10
12
  const composite = require("./units/composite.cjs");
11
- const columns = require("./maps/layers/columns.cjs");
12
13
  const base = require("./facets/measurements/base.cjs");
13
14
  const dataComponents = require("@macrostrat/data-components");
14
- const layers = require("./maps/column-navigation/svg/layers.cjs");
15
- const core = require("./maps/column-correlation/core.cjs");
16
- const state = require("./maps/column-correlation/state.cjs");
17
- const index$1 = require("./maps/column-navigation/mapbox/index.cjs");
18
15
  const columnNav = require("./data-provider/column-nav.cjs");
19
- const index$2 = require("./maps/column-navigation/svg/index.cjs");
20
16
  const main = require("./correlation-chart/main.cjs");
21
- const index$3 = require("./facets/detrital-zircon/index.cjs");
17
+ const index$1 = require("./facets/detrital-zircon/index.cjs");
22
18
  const provider = require("./facets/fossils/provider.cjs");
23
19
  const types = require("./prepare-units/types.cjs");
24
- const index$4 = require("./maps/inset-map/index.cjs");
25
20
  const isotopesColumn = require("./facets/carbon-isotopes/isotopes-column.cjs");
26
21
  const panel = require("./unit-details/panel.cjs");
27
22
  const store = require("./data-provider/store.cjs");
28
- const units = require("./maps/layers/units.cjs");
29
23
  const dataProvider = require("./facets/carbon-isotopes/data-provider.cjs");
30
24
  const utils = require("./prepare-units/utils.cjs");
31
- const index$5 = require("./facets/fossils/index.cjs");
25
+ const index$2 = require("./facets/fossils/index.cjs");
32
26
  const taxonRanges = require("./facets/fossils/taxon-ranges.cjs");
33
27
  const sgp = require("./facets/measurements/sgp.cjs");
34
28
  const stratNames = require("./unit-details/strat-names.cjs");
35
29
  const modalPanel = require("./unit-details/modal-panel.cjs");
36
30
  const popover = require("./unit-details/popover.cjs");
37
31
  const unitSelection = require("./data-provider/unit-selection.cjs");
38
- const colors = require("./units/colors.cjs");
39
32
  const hashString = require("./correlation-chart/hash-string.cjs");
40
33
  const helpers = require("./prepare-units/helpers.cjs");
41
34
  exports.BasicUnitComponent = index.BasicUnitComponent;
@@ -51,8 +44,9 @@ exports.ApproximateHeightAxis = ageAxis.ApproximateHeightAxis;
51
44
  exports.CompositeAgeAxis = ageAxis.CompositeAgeAxis;
52
45
  exports.CompositeAgeAxisCore = ageAxis.CompositeAgeAxisCore;
53
46
  exports.VerticalAxisLabel = ageAxis.VerticalAxisLabel;
54
- exports.prepareColumnUnits = index$6.prepareColumnUnits;
55
- exports.usePreparedColumnUnits = index$6.usePreparedColumnUnits;
47
+ exports.prepareColumnUnits = index$3.prepareColumnUnits;
48
+ exports.usePreparedColumnUnits = index$3.usePreparedColumnUnits;
49
+ exports.useAnimatedAgeWindow = animatedAgeWindow.useAnimatedAgeWindow;
56
50
  exports.Column = column.Column;
57
51
  exports.ColumnBasicInfo = column.ColumnBasicInfo;
58
52
  exports.ColumnContainer = column.ColumnContainer;
@@ -73,9 +67,6 @@ exports.CompositeUnitsColumn = composite.CompositeUnitsColumn;
73
67
  exports.LabelTrackerProvider = composite.LabelTrackerProvider;
74
68
  exports.SectionLabelsColumn = composite.SectionLabelsColumn;
75
69
  exports.TrackedLabeledUnit = composite.TrackedLabeledUnit;
76
- exports.BaseColumnsLayer = columns.BaseColumnsLayer;
77
- exports.SelectedColumnOverlay = columns.SelectedColumnOverlay;
78
- exports.buildColumnsStyle = columns.buildColumnsStyle;
79
70
  exports.BaseMeasurementsColumn = base.BaseMeasurementsColumn;
80
71
  exports.TruncatedList = base.TruncatedList;
81
72
  exports.groupNotesByPixelDistance = base.groupNotesByPixelDistance;
@@ -93,32 +84,15 @@ Object.defineProperty(exports, "UnitIdentifier", {
93
84
  enumerable: true,
94
85
  get: () => dataComponents.UnitIdentifier
95
86
  });
96
- exports.ColumnCenters = layers.ColumnCenters;
97
- exports.ColumnFeatures = layers.ColumnFeatures;
98
- exports.ColumnKeyboardNavigation = layers.ColumnKeyboardNavigation;
99
- exports.Columns = layers.Columns;
100
- exports.CurrentColumn = layers.CurrentColumn;
101
- exports.MeasurementsLayer = layers.MeasurementsLayer;
102
- exports.ColumnCorrelationMap = core.ColumnCorrelationMap;
103
- exports.ColumnCorrelationProvider = state.ColumnCorrelationProvider;
104
- exports.useColumnMapLink = state.useColumnMapLink;
105
- exports.useCorrelationMapStore = state.useCorrelationMapStore;
106
- exports.ColumnHoverInteraction = index$1.ColumnHoverInteraction;
107
- exports.ColumnNavigationMap = index$1.ColumnNavigationMap;
108
- exports.ColumnSelectionManager = index$1.ColumnSelectionManager;
109
- exports.ColumnsNavigationLayer = index$1.ColumnsNavigationLayer;
110
87
  exports.ColumnNavProvider = columnNav.ColumnNavProvider;
111
88
  exports.useColumnNav = columnNav.useColumnNav;
112
- exports.ColumnNavigationSVGMap = index$2.ColumnNavigationSVGMap;
113
- exports.ResizableMapFrame = index$2.ResizableMapFrame;
114
89
  exports.CorrelationChart = main.CorrelationChart;
115
- exports.DetritalColumn = index$3.DetritalColumn;
116
- exports.DetritalGroup = index$3.DetritalGroup;
90
+ exports.DetritalColumn = index$1.DetritalColumn;
91
+ exports.DetritalGroup = index$1.DetritalGroup;
117
92
  exports.FossilDataType = provider.FossilDataType;
118
93
  exports.useFossilData = provider.useFossilData;
119
94
  exports.HeightMethod = types.HeightMethod;
120
95
  exports.HybridScaleType = types.HybridScaleType;
121
- exports.InsetMap = index$4.InsetMap;
122
96
  exports.IsotopesColumn = isotopesColumn.IsotopesColumn;
123
97
  exports.IsotopesDataset = isotopesColumn.IsotopesDataset;
124
98
  exports.LegendPanelHeader = panel.LegendPanelHeader;
@@ -138,8 +112,6 @@ exports.useColumnUnitsMap = store.useColumnUnitsMap;
138
112
  exports.useCompositeScale = store.useCompositeScale;
139
113
  exports.useMacrostratColumnData = store.useMacrostratColumnData;
140
114
  exports.useMacrostratUnits = store.useMacrostratUnits;
141
- exports.MacrostratUnitsOverlay = units.MacrostratUnitsOverlay;
142
- exports.buildUnitsStyle = units.buildUnitsStyle;
143
115
  exports.MeasurementDataContext = dataProvider.MeasurementDataContext;
144
116
  exports.MeasurementDataProvider = dataProvider.MeasurementDataProvider;
145
117
  exports.useMeasurementData = dataProvider.useMeasurementData;
@@ -151,7 +123,7 @@ exports.ensureRealFloat = utils.ensureRealFloat;
151
123
  exports.getPositionWithinUnit = utils.getPositionWithinUnit;
152
124
  exports.getUnitHeightRange = utils.getUnitHeightRange;
153
125
  exports.unitsOverlap = utils.unitsOverlap;
154
- exports.PBDBFossilsColumn = index$5.PBDBFossilsColumn;
126
+ exports.PBDBFossilsColumn = index$2.PBDBFossilsColumn;
155
127
  exports.PBDBOccurrencesMatrix = taxonRanges.PBDBOccurrencesMatrix;
156
128
  exports.SGPMeasurementsColumn = sgp.SGPMeasurementsColumn;
157
129
  exports.StratNameField = stratNames.StratNameField;
@@ -169,10 +141,13 @@ exports.useSelectedUnit = unitSelection.useSelectedUnit;
169
141
  exports.useUnitSelection = unitSelection.useUnitSelection;
170
142
  exports.useUnitSelectionDispatch = unitSelection.useUnitSelectionDispatch;
171
143
  exports.useUnitSelectionTarget = unitSelection.useUnitSelectionTarget;
172
- exports.flattenLithologies = colors.flattenLithologies;
173
- exports.getMixedColorForData = colors.getMixedColorForData;
174
- exports.getMixedUnitColor = colors.getMixedUnitColor;
175
144
  exports.parseLineFromString = hashString.parseLineFromString;
176
145
  exports.stringifyLine = hashString.stringifyLine;
177
146
  exports.preprocessUnits = helpers.preprocessUnits;
147
+ Object.keys(mapViews).forEach((k) => {
148
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
149
+ enumerable: true,
150
+ get: () => mapViews[k]
151
+ });
152
+ });
178
153
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -2,10 +2,12 @@ export * from './units';
2
2
  export * from './data-provider';
3
3
  export * from './age-axis';
4
4
  export * from './prepare-units';
5
+ export * from './animated-age-window';
5
6
  export * from './column';
6
7
  export * from './unit-details';
7
- export * from './maps';
8
8
  export * from './age-model-overlay';
9
9
  export * from './correlation-chart';
10
10
  export * from './notes';
11
11
  export * from './facets';
12
+ /** Legacy views */
13
+ export * from '@macrostrat/map-views';
package/dist/index.js CHANGED
@@ -1,29 +1,23 @@
1
1
  import { BasicUnitComponent, ColoredUnitComponent, EnvironmentColoredUnitComponent, SimpleUnitsColumn, UnitComponent, UnitsColumn, useUnitColor, useUnitColorByEnvironment } from "./units/index.js";
2
2
  import { AgeCursor, ApproximateHeightAxis, CompositeAgeAxis, CompositeAgeAxisCore, VerticalAxisLabel } from "./age-axis.js";
3
3
  import { prepareColumnUnits, usePreparedColumnUnits } from "./prepare-units/index.js";
4
+ import { useAnimatedAgeWindow } from "./animated-age-window.js";
4
5
  import { Column, ColumnBasicInfo, ColumnContainer } from "./column.js";
5
6
  import { BoundaryAgeModelOverlay, ComputedSurfacesOverlay } from "./age-model-overlay.js";
6
7
  import { ColumnNotes } from "./notes.js";
8
+ export * from "@macrostrat/map-views";
7
9
  import { AgeField, AgeLabel, AgeRange, Duration, IntervalProportions, getAge, getAgeRange } from "./unit-details/age-range.js";
8
10
  import { AnnotatedUnitsColumn, ColumnNotesProvider, CompositeUnitComponent, CompositeUnitsColumn, LabelTrackerProvider, SectionLabelsColumn, TrackedLabeledUnit } from "./units/composite.js";
9
- import { BaseColumnsLayer, SelectedColumnOverlay, buildColumnsStyle } from "./maps/layers/columns.js";
10
11
  import { BaseMeasurementsColumn, TruncatedList, groupNotesByPixelDistance, mergeHeightRanges, standardizeMeasurementHeight } from "./facets/measurements/base.js";
11
12
  import { ClickableText, Identifier, UnitIdentifier } from "@macrostrat/data-components";
12
- import { ColumnCenters, ColumnFeatures, ColumnKeyboardNavigation, Columns, CurrentColumn, MeasurementsLayer } from "./maps/column-navigation/svg/layers.js";
13
- import { ColumnCorrelationMap } from "./maps/column-correlation/core.js";
14
- import { ColumnCorrelationProvider, useColumnMapLink, useCorrelationMapStore } from "./maps/column-correlation/state.js";
15
- import { ColumnHoverInteraction, ColumnNavigationMap, ColumnSelectionManager, ColumnsNavigationLayer } from "./maps/column-navigation/mapbox/index.js";
16
13
  import { ColumnNavProvider, useColumnNav } from "./data-provider/column-nav.js";
17
- import { ColumnNavigationSVGMap, ResizableMapFrame } from "./maps/column-navigation/svg/index.js";
18
14
  import { CorrelationChart } from "./correlation-chart/main.js";
19
15
  import { DetritalColumn, DetritalGroup } from "./facets/detrital-zircon/index.js";
20
16
  import { FossilDataType, useFossilData } from "./facets/fossils/provider.js";
21
17
  import { HeightMethod, HybridScaleType } from "./prepare-units/types.js";
22
- import { InsetMap } from "./maps/inset-map/index.js";
23
18
  import { IsotopesColumn, IsotopesDataset } from "./facets/carbon-isotopes/isotopes-column.js";
24
19
  import { LegendPanelHeader, ReferencesField, ThicknessField, UnitDetailsFeature, UnitDetailsPanel } from "./unit-details/panel.js";
25
20
  import { LithologiesProvider, MacrostratColumnDataProvider, MacrostratColumnProvider, MacrostratColumnStateProvider, UnitSelectionProvider, columnUnitsAtom, columnUnitsMapAtom, scope, useColumnUnitsMap, useCompositeScale, useMacrostratColumnData, useMacrostratUnits } from "./data-provider/store.js";
26
- import { MacrostratUnitsOverlay, buildUnitsStyle } from "./maps/layers/units.js";
27
21
  import { MeasurementDataContext, MeasurementDataProvider, useMeasurementData } from "./facets/carbon-isotopes/data-provider.js";
28
22
  import { MergeSectionsMode, agesOverlap, createUnitSorter, ensureArray, ensureRealFloat, getPositionWithinUnit, getUnitHeightRange, unitsOverlap } from "./prepare-units/utils.js";
29
23
  import { PBDBFossilsColumn } from "./facets/fossils/index.js";
@@ -33,7 +27,6 @@ import { StratNameField } from "./unit-details/strat-names.js";
33
27
  import { UnitDetailsPanelWithNavigation } from "./unit-details/modal-panel.js";
34
28
  import { UnitDetailsPopover, UnitSelectionPopover } from "./unit-details/popover.js";
35
29
  import { UnitKeyboardNavigation, UnitSelectionCallbackManager, allowUnitSelectionAtom, selectedUnitElementAtom, selectedUnitIDAtom, useAtomOverlayPosition, useColumnRef, useSelectedUnit, useUnitSelection, useUnitSelectionDispatch, useUnitSelectionTarget } from "./data-provider/unit-selection.js";
36
- import { flattenLithologies, getMixedColorForData, getMixedUnitColor } from "./units/colors.js";
37
30
  import { parseLineFromString, stringifyLine } from "./correlation-chart/hash-string.js";
38
31
  import { preprocessUnits } from "./prepare-units/helpers.js";
39
32
  export {
@@ -43,7 +36,6 @@ export {
43
36
  AgeRange,
44
37
  AnnotatedUnitsColumn,
45
38
  ApproximateHeightAxis,
46
- BaseColumnsLayer,
47
39
  BaseMeasurementsColumn,
48
40
  BasicUnitComponent,
49
41
  BoundaryAgeModelOverlay,
@@ -51,28 +43,16 @@ export {
51
43
  ColoredUnitComponent,
52
44
  Column,
53
45
  ColumnBasicInfo,
54
- ColumnCenters,
55
46
  ColumnContainer,
56
- ColumnCorrelationMap,
57
- ColumnCorrelationProvider,
58
- ColumnFeatures,
59
- ColumnHoverInteraction,
60
- ColumnKeyboardNavigation,
61
47
  ColumnNavProvider,
62
- ColumnNavigationMap,
63
- ColumnNavigationSVGMap,
64
48
  ColumnNotes,
65
49
  ColumnNotesProvider,
66
- ColumnSelectionManager,
67
- Columns,
68
- ColumnsNavigationLayer,
69
50
  CompositeAgeAxis,
70
51
  CompositeAgeAxisCore,
71
52
  CompositeUnitComponent,
72
53
  CompositeUnitsColumn,
73
54
  ComputedSurfacesOverlay,
74
55
  CorrelationChart,
75
- CurrentColumn,
76
56
  DetritalColumn,
77
57
  DetritalGroup,
78
58
  Duration,
@@ -81,7 +61,6 @@ export {
81
61
  HeightMethod,
82
62
  HybridScaleType,
83
63
  Identifier,
84
- InsetMap,
85
64
  IntervalProportions,
86
65
  IsotopesColumn,
87
66
  IsotopesDataset,
@@ -91,18 +70,14 @@ export {
91
70
  MacrostratColumnDataProvider,
92
71
  MacrostratColumnProvider,
93
72
  MacrostratColumnStateProvider,
94
- MacrostratUnitsOverlay,
95
73
  MeasurementDataContext,
96
74
  MeasurementDataProvider,
97
- MeasurementsLayer,
98
75
  MergeSectionsMode,
99
76
  PBDBFossilsColumn,
100
77
  PBDBOccurrencesMatrix,
101
78
  ReferencesField,
102
- ResizableMapFrame,
103
79
  SGPMeasurementsColumn,
104
80
  SectionLabelsColumn,
105
- SelectedColumnOverlay,
106
81
  SimpleUnitsColumn,
107
82
  StratNameField,
108
83
  ThicknessField,
@@ -122,18 +97,13 @@ export {
122
97
  VerticalAxisLabel,
123
98
  agesOverlap,
124
99
  allowUnitSelectionAtom,
125
- buildColumnsStyle,
126
- buildUnitsStyle,
127
100
  columnUnitsAtom,
128
101
  columnUnitsMapAtom,
129
102
  createUnitSorter,
130
103
  ensureArray,
131
104
  ensureRealFloat,
132
- flattenLithologies,
133
105
  getAge,
134
106
  getAgeRange,
135
- getMixedColorForData,
136
- getMixedUnitColor,
137
107
  getPositionWithinUnit,
138
108
  getUnitHeightRange,
139
109
  groupNotesByPixelDistance,
@@ -147,13 +117,12 @@ export {
147
117
  standardizeMeasurementHeight,
148
118
  stringifyLine,
149
119
  unitsOverlap,
120
+ useAnimatedAgeWindow,
150
121
  useAtomOverlayPosition,
151
- useColumnMapLink,
152
122
  useColumnNav,
153
123
  useColumnRef,
154
124
  useColumnUnitsMap,
155
125
  useCompositeScale,
156
- useCorrelationMapStore,
157
126
  useFossilData,
158
127
  useMacrostratColumnData,
159
128
  useMacrostratUnits,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -9,10 +9,11 @@ function buildCompositeScaleInfo(inputScales, unconformityHeight) {
9
9
  let totalHeight = unconformityHeight / 2;
10
10
  let lastSectionTopHeight = 0;
11
11
  const packages2 = [];
12
- for (const group of inputScales) {
12
+ for (let i = 0; i < inputScales.length; i++) {
13
+ const group = inputScales[i];
13
14
  const { domain, scale } = group;
14
15
  const [b_age, t_age] = domain;
15
- const key = `package-${b_age}-${t_age}`;
16
+ const key = `package-${i}`;
16
17
  packages2.push({
17
18
  ...createPackageScale(group, totalHeight),
18
19
  key,
@@ -79,6 +80,7 @@ function buildSectionScale(data, opts) {
79
80
  minPixelScale = 0.2,
80
81
  axisType,
81
82
  minSectionHeight,
83
+ visibleWindow,
82
84
  scale,
83
85
  hybridScale
84
86
  } = opts;
@@ -97,7 +99,7 @@ function buildSectionScale(data, opts) {
97
99
  }
98
100
  if (scale == null) {
99
101
  if (_pixelScale == null) {
100
- const avgAgeRange = findAverageUnitHeight(data, axisType);
102
+ const avgAgeRange = findAverageUnitHeight(data, axisType, visibleWindow);
101
103
  _pixelScale = Math.max(targetUnitHeight / avgAgeRange, minPixelScale);
102
104
  }
103
105
  let height = dAge * _pixelScale;
@@ -112,6 +114,78 @@ function buildSectionScale(data, opts) {
112
114
  0
113
115
  );
114
116
  }
117
+ function resolveWindowScales(sections, focalWindow, floor) {
118
+ const [b_focal, t_focal] = focalWindow;
119
+ const scales = /* @__PURE__ */ new Map();
120
+ for (const section of sections) {
121
+ const t_age = Math.max(section.t_age, t_focal);
122
+ const b_age = Math.min(section.b_age, b_focal);
123
+ if (b_age <= t_age) continue;
124
+ const natural = section.scaleInfo.pixelScale;
125
+ if (!(natural > 0)) continue;
126
+ const isClipped = b_age < section.b_age || t_age > section.t_age;
127
+ const needed = isClipped && floor > 0 ? floor / (b_age - t_age) : 0;
128
+ scales.set(section, Math.max(natural, needed));
129
+ }
130
+ return scales;
131
+ }
132
+ function padWindowByPixels(sections, window, padding, scaleFor) {
133
+ if (!(padding > 0) || sections.length === 0) return window;
134
+ const [b_age, t_age] = window;
135
+ return [
136
+ spendOutward(sections, b_age, 1, padding, scaleFor),
137
+ spendOutward(sections, t_age, -1, padding, scaleFor)
138
+ ];
139
+ }
140
+ function spendOutward(sections, edge, direction, padding, scaleFor) {
141
+ const beyond = sections.filter(
142
+ (s) => direction * (s.b_age - edge) > 0 || direction * (s.t_age - edge) > 0
143
+ ).sort((a, b) => direction * (nearEdge(a, direction) - nearEdge(b, direction)));
144
+ let bound = edge;
145
+ let budget = padding;
146
+ for (const section of beyond) {
147
+ const pixelScale = scaleFor(section);
148
+ if (!(pixelScale > 0)) continue;
149
+ const from = direction > 0 ? Math.max(section.t_age, bound) : Math.min(section.b_age, bound);
150
+ const available = direction > 0 ? section.b_age - from : from - section.t_age;
151
+ if (available <= 0) continue;
152
+ const cost = available * pixelScale;
153
+ if (budget <= cost) return from + direction * (budget / pixelScale);
154
+ bound = direction > 0 ? section.b_age : section.t_age;
155
+ budget -= cost;
156
+ }
157
+ return bound;
158
+ }
159
+ function nearEdge(section, direction) {
160
+ return direction > 0 ? section.t_age : section.b_age;
161
+ }
162
+ function trimSectionsToWindow(sections, window, scaleFor) {
163
+ const [b_win, t_win] = window;
164
+ const out = [];
165
+ for (const section of sections) {
166
+ const t_age = Math.max(section.t_age, t_win);
167
+ const b_age = Math.min(section.b_age, b_win);
168
+ if (b_age <= t_age) continue;
169
+ const pixelScale = scaleFor(section);
170
+ if (b_age === section.b_age && t_age === section.t_age && pixelScale === section.scaleInfo.pixelScale) {
171
+ out.push(section);
172
+ continue;
173
+ }
174
+ out.push({
175
+ ...section,
176
+ t_age,
177
+ b_age,
178
+ units: section.units.filter((u) => utils.agesOverlap(u, { t_age, b_age })),
179
+ scaleInfo: createPackageScale({
180
+ domain: [b_age, t_age],
181
+ pixelScale,
182
+ pixelHeight: (b_age - t_age) * pixelScale,
183
+ scale: null
184
+ })
185
+ });
186
+ }
187
+ return out;
188
+ }
115
189
  function createPackageScale(def, offset = 0) {
116
190
  const { domain, pixelScale, pixelHeight, scale, heightScale } = def;
117
191
  if (scale == null && pixelScale == null) {
@@ -159,12 +233,21 @@ function findSectionHeightRange(data, axisType) {
159
233
  return [b_pos, t_pos];
160
234
  }
161
235
  }
162
- function findAverageUnitHeight(data, axisType) {
163
- const unitHeights = data.map((d) => {
236
+ function findAverageUnitHeight(data, axisType, visibleWindow) {
237
+ const durations = (clip) => data.map((d) => {
164
238
  const [b_pos, t_pos] = utils.getUnitHeightRange(d, axisType);
165
- return Math.abs(b_pos - t_pos);
166
- });
167
- return unitHeights.reduce((a, b) => a + b, 0) / unitHeights.length;
239
+ if (!clip) return Math.abs(b_pos - t_pos);
240
+ const [b_win, t_win] = visibleWindow;
241
+ return Math.max(
242
+ 0,
243
+ Math.min(b_pos, b_win) - Math.max(t_pos, t_win)
244
+ );
245
+ }).filter((d) => d > 0);
246
+ const useWindow = visibleWindow != null && axisType === columnComponents.ColumnAxisType.AGE;
247
+ let heights = useWindow ? durations(true) : [];
248
+ if (heights.length === 0) heights = durations(false);
249
+ if (heights.length === 0) return 1;
250
+ return heights.reduce((a, b) => a + b, 0) / heights.length;
168
251
  }
169
252
  function createCompositeScale(sections, interpolateUnconformities = false) {
170
253
  const scales = [];
@@ -280,4 +363,7 @@ exports.computeSectionHeights = computeSectionHeights;
280
363
  exports.createCompositeScale = createCompositeScale;
281
364
  exports.createPackageScale = createPackageScale;
282
365
  exports.finalizeSectionHeights = finalizeSectionHeights;
366
+ exports.padWindowByPixels = padWindowByPixels;
367
+ exports.resolveWindowScales = resolveWindowScales;
368
+ exports.trimSectionsToWindow = trimSectionsToWindow;
283
369
  //# sourceMappingURL=composite-scale.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"composite-scale.cjs","sources":["../../src/prepare-units/composite-scale.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport { ensureArray, getUnitHeightRange } from \"./utils\";\nimport { ScaleContinuousNumeric, scaleLinear } from \"d3-scale\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { buildHybridScale } from \"./dynamic-scales\";\nimport { ExtUnit, HybridScaleType, SectionInfo } from \"./types\";\nimport type {\n ColumnScaleOptions,\n CompositeColumnData,\n CompositeScaleData,\n PackageLayoutData,\n PackageScaleInfo,\n PackageScaleLayoutData,\n SectionScaleOptions,\n} from \"./types\";\n\n// Composite scale information augmented with units in each package\n\nexport function buildCompositeScaleInfo(\n inputScales: PackageScaleInfo[],\n unconformityHeight: number,\n): CompositeScaleData {\n /** Finalize the heights of sections, including the heights of unconformities\n * between them.\n */\n\n let totalHeight = unconformityHeight / 2;\n let lastSectionTopHeight = 0;\n\n const packages2: PackageScaleLayoutData[] = [];\n for (const group of inputScales) {\n const { domain, scale } = group;\n const [b_age, t_age] = domain;\n const key = `package-${b_age}-${t_age}`;\n\n packages2.push({\n ...createPackageScale(group, totalHeight),\n key,\n offset: totalHeight,\n // Unconformity height above this particular section\n paddingTop: totalHeight - lastSectionTopHeight,\n });\n\n const pixelHeight = Math.abs(scale(b_age) - scale(t_age));\n lastSectionTopHeight = totalHeight + pixelHeight;\n totalHeight = lastSectionTopHeight + unconformityHeight;\n }\n totalHeight += unconformityHeight / 2;\n return {\n totalHeight,\n sections: packages2,\n };\n}\n\nexport function finalizeSectionHeights<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n unconformityHeight: number,\n): CompositeColumnData<T> {\n /** Finalize the heights of sections, including the heights of unconformities\n * between them.\n */\n\n const sectionScales = sections.map((d) => d.scaleInfo);\n\n const { totalHeight, sections: packages } = buildCompositeScaleInfo(\n sectionScales,\n unconformityHeight,\n );\n\n // This could perhaps be simplified.\n const sections1: PackageLayoutData<T>[] = [];\n for (const i in sections) {\n const group = sections[i];\n const scaleInfo = packages[i];\n sections1.push({\n ...group,\n key: scaleInfo.key,\n scaleInfo,\n });\n }\n return {\n totalHeight,\n sections: sections1,\n };\n}\n\nexport interface SectionInfoWithScale<\n T extends UnitLong = ExtUnit,\n> extends SectionInfo<T> {\n scaleInfo: PackageScaleInfo;\n}\n\nexport function computeSectionHeights<T extends UnitLong>(\n sections: SectionInfo<T>[],\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T>[] {\n return sections.map((group) => {\n return addScaleToSection<T>(group, opts);\n });\n}\n\nfunction addScaleToSection<T extends UnitLong = ExtUnit>(\n group: SectionInfo<T>,\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T> {\n const { t_age, b_age, t_pos, b_pos, units } = group;\n let _range = null;\n // if t_age and b_age are set for a group, use them to define the range...\n if (opts.axisType == ColumnAxisType.AGE) {\n _range = [b_age, t_age];\n } else {\n _range = [b_pos, t_pos];\n }\n\n const scaleInfo = buildSectionScale<T>(units, {\n ...opts,\n domain: _range,\n });\n\n return {\n ...group,\n scaleInfo,\n };\n}\n\nfunction buildSectionScale<T extends UnitLong>(\n data: T[],\n opts: SectionScaleOptions,\n): PackageScaleInfo {\n const {\n targetUnitHeight = 20,\n minPixelScale = 0.2,\n axisType,\n minSectionHeight,\n scale,\n hybridScale,\n } = opts;\n const domain = opts.domain ?? findSectionHeightRange(data, axisType);\n\n const dAge = Math.abs(domain[0] - domain[1]);\n\n let _pixelScale = opts.pixelScale;\n let pixelHeight: number;\n\n if (hybridScale != null) {\n /** In an equidistant surfaces scale, we want to determine the heights of surfaces\n * and then distribute units evenly between them.\n * This is somewhat like an ordinal scale\n */\n if (hybridScale.type === HybridScaleType.EquidistantSurfaces) {\n _pixelScale ??= targetUnitHeight;\n }\n\n return buildHybridScale(hybridScale, data, domain, {\n pixelOffset: 0,\n pixelScale: _pixelScale,\n });\n }\n\n if (scale == null) {\n if (_pixelScale == null) {\n const avgAgeRange = findAverageUnitHeight(data, axisType);\n // Get pixel height necessary to render average unit at target height\n _pixelScale = Math.max(targetUnitHeight / avgAgeRange, minPixelScale);\n\n // OLD METHOD that cares about overall section height vs. individual unit height\n // 0.2 pixel per myr is the floor scale\n //const targetHeight = targetUnitHeight * data.length;\n // 1 pixel per myr is the floor scale\n //_pixelScale = Math.max(targetHeight / dAge, minPixelScale);\n }\n\n let height = dAge * _pixelScale;\n // If height is less than minSectionHeight, set it to minSectionHeight\n const _minSectionHeight = minSectionHeight ?? targetUnitHeight ?? 0;\n pixelHeight = Math.max(height, _minSectionHeight);\n _pixelScale = pixelHeight / dAge;\n } else {\n // If a scale is provided, use it to compute pixel height\n pixelHeight = Math.abs(scale(domain[0]) - scale(domain[1]));\n }\n\n return createPackageScale(\n { scale, domain, pixelHeight, pixelScale: _pixelScale },\n 0,\n );\n}\n\nexport function createPackageScale(\n def: PackageScaleInfo,\n offset: number = 0,\n): PackageScaleInfo {\n /** Build a section scale */\n // Domain should be oriented from bottom to top, but scale is oriented from top to bottom\n const { domain, pixelScale, pixelHeight, scale, heightScale } = def;\n\n if (scale == null && pixelScale == null) {\n throw new Error(\"Either scale or pixelScale must be provided\");\n }\n\n let _scale: ScaleContinuousNumeric<number, number>;\n if (scale == null) {\n _scale = scaleLinear()\n .domain([domain[1], domain[0]])\n .range([offset, pixelHeight + offset]);\n } else {\n const domain0 = scale.domain();\n const range0 = scale.range();\n _scale = scale\n .copy()\n .domain(domain0)\n .range(range0.map((d) => d + offset));\n }\n\n _scale.clamp();\n\n let _heightScale = null;\n if (heightScale != null) {\n // Adjust height scale as well\n const range0 = scale.range();\n _heightScale = heightScale.copy().range(range0.map((d) => d + offset));\n _heightScale.clamp();\n }\n\n return {\n domain,\n pixelScale,\n pixelHeight,\n scale: _scale,\n // Internal details for hybrid scales. TODO: improve this\n heightScale: _heightScale,\n };\n}\n\nfunction findSectionHeightRange(\n data: UnitLong[],\n axisType: ColumnAxisType,\n): [number, number] {\n if (axisType == null) {\n throw new Error(\"Axis type is not set\");\n }\n if (axisType === ColumnAxisType.AGE) {\n const t_age = Math.min(...data.map((d) => d.t_age));\n const b_age = Math.max(...data.map((d) => d.b_age));\n return [b_age, t_age];\n } else if (\n axisType == ColumnAxisType.DEPTH ||\n axisType == ColumnAxisType.ORDINAL\n ) {\n const t_pos = Math.min(...data.map((d) => d.t_pos));\n const b_pos = Math.max(...data.map((d) => d.b_pos));\n return [b_pos, t_pos];\n } else if (axisType == ColumnAxisType.HEIGHT) {\n const t_pos = Math.max(...data.map((d) => d.t_pos));\n const b_pos = Math.min(...data.map((d) => d.b_pos));\n return [b_pos, t_pos];\n }\n}\n\nfunction findAverageUnitHeight(\n data: UnitLong[],\n axisType: ColumnAxisType,\n): number {\n const unitHeights = data.map((d) => {\n const [b_pos, t_pos] = getUnitHeightRange(d, axisType);\n return Math.abs(b_pos - t_pos);\n });\n return unitHeights.reduce((a, b) => a + b, 0) / unitHeights.length;\n}\n\nexport interface CompositeColumnScale {\n (age: number): number | null;\n copy(): CompositeColumnScale;\n domain(): [number, number];\n invert(pixelHeight: number): number | null;\n clamp(clamp: boolean): void;\n}\n\nexport function createCompositeScale(\n sections: PackageLayoutData[],\n interpolateUnconformities: boolean = false,\n): CompositeColumnScale {\n /** Create a scale that works across multiple packages */\n\n const scales: ScaleContinuousNumeric<number, number>[] = [];\n\n let lastScale: ScaleContinuousNumeric<number, number> | null = null;\n for (const section of sections) {\n const _scale = section.scaleInfo.scale.copy().clamp(true);\n scales.push(_scale);\n if (lastScale != null && interpolateUnconformities) {\n // Add a new scale that interpolates between lastScale and _scale\n const lastDomain = lastScale.domain();\n const lastRange = lastScale.range();\n const currentDomain = _scale.domain();\n const currentRange = _scale.range();\n\n const interpScale = scaleLinear()\n .domain([lastDomain[lastDomain.length - 1], currentDomain[0]])\n .range([lastRange[lastRange.length - 1], currentRange[0]])\n .clamp(true);\n scales.push(interpScale);\n }\n lastScale = _scale;\n }\n\n const scale: CompositeColumnScale = (age) => {\n for (const s of scales) {\n const domain = s.domain();\n if (\n domain[0] < domain[domain.length - 1] &&\n age >= domain[0] &&\n age <= domain[domain.length - 1]\n ) {\n // Age axes\n return s(age);\n } else if (age <= domain[0] && age >= domain[domain.length - 1]) {\n // Normal axes like height\n return s(age);\n }\n }\n return null;\n };\n\n scale.copy = () => {\n return createCompositeScale(sections, interpolateUnconformities);\n };\n\n scale.domain = () => {\n /** Return the domain of the scale */\n const vals = sections.flatMap((d) => d.scaleInfo.domain);\n if (vals[0] < vals[vals.length - 1]) {\n // age axes\n return [Math.min(...vals), Math.max(...vals)];\n }\n // Normal axes like height\n return [Math.max(...vals), Math.min(...vals)];\n };\n\n scale.invert = (pixelHeight) => {\n /** Invert the scale to get the age at a given pixel height */\n // Iterate through the sections to find the correct one\n for (const scale of scales) {\n const range = scale.range();\n if (\n pixelHeight > Math.min(...range) &&\n pixelHeight <= Math.max(...range)\n ) {\n //console.log(\"Inverting scale at pixel height\", pixelHeight);\n return scale.invert(pixelHeight);\n }\n }\n return null;\n };\n\n scale.clamp = (clamp: boolean) => {\n /** Clamp all constituent scales */\n for (const s of scales) {\n s.clamp(clamp);\n }\n };\n\n return scale;\n}\n\n/** Collapse sections separated by unconformities that are smaller than a given pixel height. */\nexport function collapseUnconformitiesByPixelHeight<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n threshold: number,\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T>[] {\n const newSections = [];\n let currentSection: SectionInfoWithScale<T> | null = null;\n for (const nextSection of sections) {\n if (currentSection == null) {\n currentSection = nextSection;\n continue;\n }\n let heights: [number, number];\n let pxHeights: [number, number];\n if (opts.axisType !== ColumnAxisType.AGE) {\n heights = [nextSection.t_pos, currentSection.b_pos];\n } else {\n heights = [nextSection.t_age, currentSection.b_age];\n }\n\n const _diff = (vals: number[]) => {\n return Math.abs(vals[0] - vals[1]);\n };\n\n pxHeights = [\n _diff(heights.map(nextSection.scaleInfo.scale)),\n _diff(heights.map(currentSection.scaleInfo.scale)),\n ];\n\n const pxHeight = Math.min(...pxHeights);\n\n if (pxHeight < threshold) {\n let t_pos: number;\n let b_pos: number;\n if (\n opts.axisType == ColumnAxisType.AGE ||\n opts.axisType == ColumnAxisType.DEPTH\n ) {\n t_pos = Math.min(currentSection.t_pos, nextSection.t_pos);\n b_pos = Math.max(currentSection.b_pos, nextSection.b_pos);\n } else {\n t_pos = Math.max(currentSection.t_pos, nextSection.t_pos);\n b_pos = Math.min(currentSection.b_pos, nextSection.b_pos);\n }\n\n // We need to merge the sections\n const compositeSection0: SectionInfo<T> = {\n units: [...currentSection.units, ...nextSection.units],\n section_id: [\n ...ensureArray(currentSection.section_id),\n ...ensureArray(nextSection.section_id),\n ],\n t_age: Math.min(currentSection.t_age, nextSection.t_age),\n b_age: Math.max(currentSection.b_age, nextSection.b_age),\n t_pos,\n b_pos,\n };\n\n currentSection = addScaleToSection(compositeSection0, opts);\n } else {\n // We need to keep the section\n newSections.push(currentSection);\n currentSection = nextSection;\n }\n }\n if (currentSection != null) {\n newSections.push(currentSection);\n }\n\n return newSections;\n}\n"],"names":["ColumnAxisType","HybridScaleType","buildHybridScale","scaleLinear","getUnitHeightRange","scale","ensureArray"],"mappings":"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"}
1
+ {"version":3,"file":"composite-scale.cjs","sources":["../../src/prepare-units/composite-scale.ts"],"sourcesContent":["import { ColumnAxisType } from \"@macrostrat/column-components\";\nimport { agesOverlap, ensureArray, getUnitHeightRange } from \"./utils\";\nimport { ScaleContinuousNumeric, scaleLinear } from \"d3-scale\";\nimport { UnitLong } from \"@macrostrat/api-types\";\nimport { buildHybridScale } from \"./dynamic-scales\";\nimport { ExtUnit, HybridScaleType, SectionInfo } from \"./types\";\nimport type {\n ColumnScaleOptions,\n CompositeColumnData,\n CompositeScaleData,\n PackageLayoutData,\n PackageScaleInfo,\n PackageScaleLayoutData,\n SectionScaleOptions,\n} from \"./types\";\n\n// Composite scale information augmented with units in each package\n\nexport function buildCompositeScaleInfo(\n inputScales: PackageScaleInfo[],\n unconformityHeight: number,\n): CompositeScaleData {\n /** Finalize the heights of sections, including the heights of unconformities\n * between them.\n */\n\n let totalHeight = unconformityHeight / 2;\n let lastSectionTopHeight = 0;\n\n const packages2: PackageScaleLayoutData[] = [];\n for (let i = 0; i < inputScales.length; i++) {\n const group = inputScales[i];\n const { domain, scale } = group;\n const [b_age, t_age] = domain;\n // Positionally stable key: packages are always emitted in age order, so the\n // index is a stable identity. An age-based key (`package-${b_age}-${t_age}`)\n // changes every frame while the age window animates, forcing every package,\n // column, and timescale slice in the correlation chart to remount each frame.\n const key = `package-${i}`;\n\n packages2.push({\n ...createPackageScale(group, totalHeight),\n key,\n offset: totalHeight,\n // Unconformity height above this particular section\n paddingTop: totalHeight - lastSectionTopHeight,\n });\n\n const pixelHeight = Math.abs(scale(b_age) - scale(t_age));\n lastSectionTopHeight = totalHeight + pixelHeight;\n totalHeight = lastSectionTopHeight + unconformityHeight;\n }\n totalHeight += unconformityHeight / 2;\n return {\n totalHeight,\n sections: packages2,\n };\n}\n\nexport function finalizeSectionHeights<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n unconformityHeight: number,\n): CompositeColumnData<T> {\n /** Finalize the heights of sections, including the heights of unconformities\n * between them.\n */\n\n const sectionScales = sections.map((d) => d.scaleInfo);\n\n const { totalHeight, sections: packages } = buildCompositeScaleInfo(\n sectionScales,\n unconformityHeight,\n );\n\n // This could perhaps be simplified.\n const sections1: PackageLayoutData<T>[] = [];\n for (const i in sections) {\n const group = sections[i];\n const scaleInfo = packages[i];\n sections1.push({\n ...group,\n key: scaleInfo.key,\n scaleInfo,\n });\n }\n return {\n totalHeight,\n sections: sections1,\n };\n}\n\nexport interface SectionInfoWithScale<\n T extends UnitLong = ExtUnit,\n> extends SectionInfo<T> {\n scaleInfo: PackageScaleInfo;\n}\n\nexport function computeSectionHeights<T extends UnitLong>(\n sections: SectionInfo<T>[],\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T>[] {\n return sections.map((group) => {\n return addScaleToSection<T>(group, opts);\n });\n}\n\nfunction addScaleToSection<T extends UnitLong = ExtUnit>(\n group: SectionInfo<T>,\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T> {\n const { t_age, b_age, t_pos, b_pos, units } = group;\n let _range = null;\n // if t_age and b_age are set for a group, use them to define the range...\n if (opts.axisType == ColumnAxisType.AGE) {\n _range = [b_age, t_age];\n } else {\n _range = [b_pos, t_pos];\n }\n\n const scaleInfo = buildSectionScale<T>(units, {\n ...opts,\n domain: _range,\n });\n\n return {\n ...group,\n scaleInfo,\n };\n}\n\nfunction buildSectionScale<T extends UnitLong>(\n data: T[],\n opts: SectionScaleOptions,\n): PackageScaleInfo {\n const {\n targetUnitHeight = 20,\n minPixelScale = 0.2,\n axisType,\n minSectionHeight,\n visibleWindow,\n scale,\n hybridScale,\n } = opts;\n const domain = opts.domain ?? findSectionHeightRange(data, axisType);\n\n const dAge = Math.abs(domain[0] - domain[1]);\n\n let _pixelScale = opts.pixelScale;\n let pixelHeight: number;\n\n if (hybridScale != null) {\n /** In an equidistant surfaces scale, we want to determine the heights of surfaces\n * and then distribute units evenly between them.\n * This is somewhat like an ordinal scale\n */\n if (hybridScale.type === HybridScaleType.EquidistantSurfaces) {\n _pixelScale ??= targetUnitHeight;\n }\n\n return buildHybridScale(hybridScale, data, domain, {\n pixelOffset: 0,\n pixelScale: _pixelScale,\n });\n }\n\n if (scale == null) {\n if (_pixelScale == null) {\n const avgAgeRange = findAverageUnitHeight(data, axisType, visibleWindow);\n // Get pixel height necessary to render average unit at target height\n _pixelScale = Math.max(targetUnitHeight / avgAgeRange, minPixelScale);\n\n // OLD METHOD that cares about overall section height vs. individual unit height\n // 0.2 pixel per myr is the floor scale\n //const targetHeight = targetUnitHeight * data.length;\n // 1 pixel per myr is the floor scale\n //_pixelScale = Math.max(targetHeight / dAge, minPixelScale);\n }\n\n let height = dAge * _pixelScale;\n // If height is less than minSectionHeight, set it to minSectionHeight.\n // Sections reach here at their *full* extent (the rendered window is applied\n // afterwards, by `trimSectionsToWindow`), so this floor only ever inflates a\n // genuinely small section — which is what it's for — and never a sliver that\n // the window happens to cut.\n const _minSectionHeight = minSectionHeight ?? targetUnitHeight ?? 0;\n pixelHeight = Math.max(height, _minSectionHeight);\n _pixelScale = pixelHeight / dAge;\n } else {\n // If a scale is provided, use it to compute pixel height\n pixelHeight = Math.abs(scale(domain[0]) - scale(domain[1]));\n }\n\n return createPackageScale(\n { scale, domain, pixelHeight, pixelScale: _pixelScale },\n 0,\n );\n}\n\n/**\n * The density each section will actually render at once the window is applied.\n *\n * A section the window cuts short is still being *looked at*, so\n * `minSectionHeight` applies to what remains — it's honored by expanding the\n * section's scale, not by showing more of it. Resolving this **before** padding\n * matters: padding is a pixel margin measured at the density it will render at,\n * and a section stretched to the floor afterwards would multiply the margin\n * along with everything else (a 20 px margin in a band stretched 4× renders at\n * 80 px, and asymmetrically so whenever one side is truncated).\n *\n * Sections the window leaves whole keep their laid-out density — they already\n * met the floor when they were sized.\n */\nexport function resolveWindowScales<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n focalWindow: [number, number],\n floor: number,\n): Map<SectionInfoWithScale<T>, number> {\n const [b_focal, t_focal] = focalWindow;\n const scales = new Map<SectionInfoWithScale<T>, number>();\n\n for (const section of sections) {\n const t_age = Math.max(section.t_age, t_focal);\n const b_age = Math.min(section.b_age, b_focal);\n // Sections outside the focal window are visible only as padding; they keep\n // their own density and render exactly the pixels asked for.\n if (b_age <= t_age) continue;\n\n const natural = section.scaleInfo.pixelScale;\n if (!(natural > 0)) continue;\n\n const isClipped = b_age < section.b_age || t_age > section.t_age;\n const needed = isClipped && floor > 0 ? floor / (b_age - t_age) : 0;\n scales.set(section, Math.max(natural, needed));\n }\n return scales;\n}\n\n/**\n * Expand an age window outward by `padding` **pixels** of column, spending the\n * budget against sections that are already laid out at full extent, at the\n * densities they will finally render at (`scaleFor`).\n *\n * Because the layout is done, this is exact rather than predicted: each section\n * contributes its own real pixel height. Padding collapses when the column runs\n * out on that side.\n *\n * Unconformities between sections cost nothing. They render at a fixed height\n * that's typically larger than the padding itself (30–60 px), so charging them\n * would mean padding could never reach across a gap — which is the case it\n * exists for: revealing the neighboring section keeps its timescale intervals\n * navigable. The padding is a budget of neighboring *content*.\n */\nexport function padWindowByPixels<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n window: [number, number],\n padding: number,\n scaleFor: (section: SectionInfoWithScale<T>) => number,\n): [number, number] {\n if (!(padding > 0) || sections.length === 0) return window;\n const [b_age, t_age] = window;\n return [\n spendOutward(sections, b_age, 1, padding, scaleFor),\n spendOutward(sections, t_age, -1, padding, scaleFor),\n ];\n}\n\n/** Walk out from one edge of the window through laid-out sections, spending a\n * pixel budget, and return the age it lands on. `direction` is +1 toward older\n * ages, -1 toward younger. */\nfunction spendOutward<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n edge: number,\n direction: 1 | -1,\n padding: number,\n scaleFor: (section: SectionInfoWithScale<T>) => number,\n): number {\n // Sections ordered outward from the edge, keeping only what lies beyond it.\n const beyond = sections\n .filter(\n (s) => direction * (s.b_age - edge) > 0 || direction * (s.t_age - edge) > 0,\n )\n .sort((a, b) => direction * (nearEdge(a, direction) - nearEdge(b, direction)));\n\n let bound = edge;\n let budget = padding;\n\n for (const section of beyond) {\n const pixelScale = scaleFor(section);\n if (!(pixelScale > 0)) continue;\n\n const from =\n direction > 0\n ? Math.max(section.t_age, bound)\n : Math.min(section.b_age, bound);\n const available = direction > 0 ? section.b_age - from : from - section.t_age;\n if (available <= 0) continue;\n\n const cost = available * pixelScale;\n if (budget <= cost) return from + direction * (budget / pixelScale);\n\n bound = direction > 0 ? section.b_age : section.t_age;\n budget -= cost;\n }\n return bound;\n}\n\n/** The age at which a section starts, measured from the window edge outward. */\nfunction nearEdge<T extends UnitLong>(\n section: SectionInfoWithScale<T>,\n direction: 1 | -1,\n): number {\n return direction > 0 ? section.t_age : section.b_age;\n}\n\n/**\n * Clip laid-out sections to the rendered window — the last step of layout, so\n * that every section has already been sized (and floored) at its full extent.\n * Each section renders at the density `scaleFor` resolved for it, which is what\n * keeps a padding margin the same number of pixels as the band it borders is\n * stretched to meet `minSectionHeight`.\n */\nexport function trimSectionsToWindow<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n window: [number, number],\n scaleFor: (section: SectionInfoWithScale<T>) => number,\n): SectionInfoWithScale<T>[] {\n const [b_win, t_win] = window;\n const out: SectionInfoWithScale<T>[] = [];\n\n for (const section of sections) {\n const t_age = Math.max(section.t_age, t_win);\n const b_age = Math.min(section.b_age, b_win);\n if (b_age <= t_age) continue;\n\n const pixelScale = scaleFor(section);\n if (\n b_age === section.b_age &&\n t_age === section.t_age &&\n pixelScale === section.scaleInfo.pixelScale\n ) {\n out.push(section);\n continue;\n }\n\n out.push({\n ...section,\n t_age,\n b_age,\n units: section.units.filter((u) => agesOverlap(u, { t_age, b_age })),\n scaleInfo: createPackageScale({\n domain: [b_age, t_age],\n pixelScale,\n pixelHeight: (b_age - t_age) * pixelScale,\n scale: null,\n }),\n });\n }\n return out;\n}\n\nexport function createPackageScale(\n def: PackageScaleInfo,\n offset: number = 0,\n): PackageScaleInfo {\n /** Build a section scale */\n // Domain should be oriented from bottom to top, but scale is oriented from top to bottom\n const { domain, pixelScale, pixelHeight, scale, heightScale } = def;\n\n if (scale == null && pixelScale == null) {\n throw new Error(\"Either scale or pixelScale must be provided\");\n }\n\n let _scale: ScaleContinuousNumeric<number, number>;\n if (scale == null) {\n _scale = scaleLinear()\n .domain([domain[1], domain[0]])\n .range([offset, pixelHeight + offset]);\n } else {\n const domain0 = scale.domain();\n const range0 = scale.range();\n _scale = scale\n .copy()\n .domain(domain0)\n .range(range0.map((d) => d + offset));\n }\n\n _scale.clamp();\n\n let _heightScale = null;\n if (heightScale != null) {\n // Adjust height scale as well\n const range0 = scale.range();\n _heightScale = heightScale.copy().range(range0.map((d) => d + offset));\n _heightScale.clamp();\n }\n\n return {\n domain,\n pixelScale,\n pixelHeight,\n scale: _scale,\n // Internal details for hybrid scales. TODO: improve this\n heightScale: _heightScale,\n };\n}\n\nfunction findSectionHeightRange(\n data: UnitLong[],\n axisType: ColumnAxisType,\n): [number, number] {\n if (axisType == null) {\n throw new Error(\"Axis type is not set\");\n }\n if (axisType === ColumnAxisType.AGE) {\n const t_age = Math.min(...data.map((d) => d.t_age));\n const b_age = Math.max(...data.map((d) => d.b_age));\n return [b_age, t_age];\n } else if (\n axisType == ColumnAxisType.DEPTH ||\n axisType == ColumnAxisType.ORDINAL\n ) {\n const t_pos = Math.min(...data.map((d) => d.t_pos));\n const b_pos = Math.max(...data.map((d) => d.b_pos));\n return [b_pos, t_pos];\n } else if (axisType == ColumnAxisType.HEIGHT) {\n const t_pos = Math.max(...data.map((d) => d.t_pos));\n const b_pos = Math.min(...data.map((d) => d.b_pos));\n return [b_pos, t_pos];\n }\n}\n\nfunction findAverageUnitHeight(\n data: UnitLong[],\n axisType: ColumnAxisType,\n visibleWindow?: [number, number] | null,\n): number {\n /** The typical duration of a unit, which `targetUnitHeight` sizes.\n *\n * Measured over what the render window actually *shows* — units outside it\n * are ignored and a unit it cuts through counts only for its visible part.\n * That's what makes `targetUnitHeight` mean the same thing at every zoom\n * depth: the units on screen are drawn at the target height whether they're\n * whole or slivers of something much longer.\n *\n * A section the window doesn't reach has nothing visible to measure, so it\n * falls back to its own units at full duration — it's drawn at its own scale.\n * (Deriving it from the padded window instead would be circular: padding is\n * measured in pixels, which is what we're trying to establish.)\n */\n const durations = (clip: boolean) =>\n data\n .map((d) => {\n const [b_pos, t_pos] = getUnitHeightRange(d, axisType);\n if (!clip) return Math.abs(b_pos - t_pos);\n const [b_win, t_win] = visibleWindow;\n return Math.max(\n 0,\n Math.min(b_pos, b_win) - Math.max(t_pos, t_win),\n );\n })\n .filter((d) => d > 0);\n\n const useWindow = visibleWindow != null && axisType === ColumnAxisType.AGE;\n let heights = useWindow ? durations(true) : [];\n if (heights.length === 0) heights = durations(false);\n if (heights.length === 0) return 1;\n\n return heights.reduce((a, b) => a + b, 0) / heights.length;\n}\n\nexport interface CompositeColumnScale {\n (age: number): number | null;\n copy(): CompositeColumnScale;\n domain(): [number, number];\n invert(pixelHeight: number): number | null;\n clamp(clamp: boolean): void;\n}\n\nexport function createCompositeScale(\n sections: PackageLayoutData[],\n interpolateUnconformities: boolean = false,\n): CompositeColumnScale {\n /** Create a scale that works across multiple packages */\n\n const scales: ScaleContinuousNumeric<number, number>[] = [];\n\n let lastScale: ScaleContinuousNumeric<number, number> | null = null;\n for (const section of sections) {\n const _scale = section.scaleInfo.scale.copy().clamp(true);\n scales.push(_scale);\n if (lastScale != null && interpolateUnconformities) {\n // Add a new scale that interpolates between lastScale and _scale\n const lastDomain = lastScale.domain();\n const lastRange = lastScale.range();\n const currentDomain = _scale.domain();\n const currentRange = _scale.range();\n\n const interpScale = scaleLinear()\n .domain([lastDomain[lastDomain.length - 1], currentDomain[0]])\n .range([lastRange[lastRange.length - 1], currentRange[0]])\n .clamp(true);\n scales.push(interpScale);\n }\n lastScale = _scale;\n }\n\n const scale: CompositeColumnScale = (age) => {\n for (const s of scales) {\n const domain = s.domain();\n if (\n domain[0] < domain[domain.length - 1] &&\n age >= domain[0] &&\n age <= domain[domain.length - 1]\n ) {\n // Age axes\n return s(age);\n } else if (age <= domain[0] && age >= domain[domain.length - 1]) {\n // Normal axes like height\n return s(age);\n }\n }\n return null;\n };\n\n scale.copy = () => {\n return createCompositeScale(sections, interpolateUnconformities);\n };\n\n scale.domain = () => {\n /** Return the domain of the scale */\n const vals = sections.flatMap((d) => d.scaleInfo.domain);\n if (vals[0] < vals[vals.length - 1]) {\n // age axes\n return [Math.min(...vals), Math.max(...vals)];\n }\n // Normal axes like height\n return [Math.max(...vals), Math.min(...vals)];\n };\n\n scale.invert = (pixelHeight) => {\n /** Invert the scale to get the age at a given pixel height */\n // Iterate through the sections to find the correct one\n for (const scale of scales) {\n const range = scale.range();\n if (\n pixelHeight > Math.min(...range) &&\n pixelHeight <= Math.max(...range)\n ) {\n //console.log(\"Inverting scale at pixel height\", pixelHeight);\n return scale.invert(pixelHeight);\n }\n }\n return null;\n };\n\n scale.clamp = (clamp: boolean) => {\n /** Clamp all constituent scales */\n for (const s of scales) {\n s.clamp(clamp);\n }\n };\n\n return scale;\n}\n\n/** Collapse sections separated by unconformities that are smaller than a given pixel height. */\nexport function collapseUnconformitiesByPixelHeight<T extends UnitLong>(\n sections: SectionInfoWithScale<T>[],\n threshold: number,\n opts: ColumnScaleOptions,\n): SectionInfoWithScale<T>[] {\n const newSections = [];\n let currentSection: SectionInfoWithScale<T> | null = null;\n for (const nextSection of sections) {\n if (currentSection == null) {\n currentSection = nextSection;\n continue;\n }\n let heights: [number, number];\n let pxHeights: [number, number];\n if (opts.axisType !== ColumnAxisType.AGE) {\n heights = [nextSection.t_pos, currentSection.b_pos];\n } else {\n heights = [nextSection.t_age, currentSection.b_age];\n }\n\n const _diff = (vals: number[]) => {\n return Math.abs(vals[0] - vals[1]);\n };\n\n pxHeights = [\n _diff(heights.map(nextSection.scaleInfo.scale)),\n _diff(heights.map(currentSection.scaleInfo.scale)),\n ];\n\n const pxHeight = Math.min(...pxHeights);\n\n if (pxHeight < threshold) {\n let t_pos: number;\n let b_pos: number;\n if (\n opts.axisType == ColumnAxisType.AGE ||\n opts.axisType == ColumnAxisType.DEPTH\n ) {\n t_pos = Math.min(currentSection.t_pos, nextSection.t_pos);\n b_pos = Math.max(currentSection.b_pos, nextSection.b_pos);\n } else {\n t_pos = Math.max(currentSection.t_pos, nextSection.t_pos);\n b_pos = Math.min(currentSection.b_pos, nextSection.b_pos);\n }\n\n // We need to merge the sections\n const compositeSection0: SectionInfo<T> = {\n units: [...currentSection.units, ...nextSection.units],\n section_id: [\n ...ensureArray(currentSection.section_id),\n ...ensureArray(nextSection.section_id),\n ],\n t_age: Math.min(currentSection.t_age, nextSection.t_age),\n b_age: Math.max(currentSection.b_age, nextSection.b_age),\n t_pos,\n b_pos,\n };\n\n currentSection = addScaleToSection(compositeSection0, opts);\n } else {\n // We need to keep the section\n newSections.push(currentSection);\n currentSection = nextSection;\n }\n }\n if (currentSection != null) {\n newSections.push(currentSection);\n }\n\n return newSections;\n}\n"],"names":["ColumnAxisType","HybridScaleType","buildHybridScale","agesOverlap","scaleLinear","getUnitHeightRange","scale","ensureArray"],"mappings":"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"}
@@ -6,6 +6,45 @@ export interface SectionInfoWithScale<T extends UnitLong = ExtUnit> extends Sect
6
6
  scaleInfo: PackageScaleInfo;
7
7
  }
8
8
  export declare function computeSectionHeights<T extends UnitLong>(sections: SectionInfo<T>[], opts: ColumnScaleOptions): SectionInfoWithScale<T>[];
9
+ /**
10
+ * The density each section will actually render at once the window is applied.
11
+ *
12
+ * A section the window cuts short is still being *looked at*, so
13
+ * `minSectionHeight` applies to what remains — it's honored by expanding the
14
+ * section's scale, not by showing more of it. Resolving this **before** padding
15
+ * matters: padding is a pixel margin measured at the density it will render at,
16
+ * and a section stretched to the floor afterwards would multiply the margin
17
+ * along with everything else (a 20 px margin in a band stretched 4× renders at
18
+ * 80 px, and asymmetrically so whenever one side is truncated).
19
+ *
20
+ * Sections the window leaves whole keep their laid-out density — they already
21
+ * met the floor when they were sized.
22
+ */
23
+ export declare function resolveWindowScales<T extends UnitLong>(sections: SectionInfoWithScale<T>[], focalWindow: [number, number], floor: number): Map<SectionInfoWithScale<T>, number>;
24
+ /**
25
+ * Expand an age window outward by `padding` **pixels** of column, spending the
26
+ * budget against sections that are already laid out at full extent, at the
27
+ * densities they will finally render at (`scaleFor`).
28
+ *
29
+ * Because the layout is done, this is exact rather than predicted: each section
30
+ * contributes its own real pixel height. Padding collapses when the column runs
31
+ * out on that side.
32
+ *
33
+ * Unconformities between sections cost nothing. They render at a fixed height
34
+ * that's typically larger than the padding itself (30–60 px), so charging them
35
+ * would mean padding could never reach across a gap — which is the case it
36
+ * exists for: revealing the neighboring section keeps its timescale intervals
37
+ * navigable. The padding is a budget of neighboring *content*.
38
+ */
39
+ export declare function padWindowByPixels<T extends UnitLong>(sections: SectionInfoWithScale<T>[], window: [number, number], padding: number, scaleFor: (section: SectionInfoWithScale<T>) => number): [number, number];
40
+ /**
41
+ * Clip laid-out sections to the rendered window — the last step of layout, so
42
+ * that every section has already been sized (and floored) at its full extent.
43
+ * Each section renders at the density `scaleFor` resolved for it, which is what
44
+ * keeps a padding margin the same number of pixels as the band it borders is
45
+ * stretched to meet `minSectionHeight`.
46
+ */
47
+ export declare function trimSectionsToWindow<T extends UnitLong>(sections: SectionInfoWithScale<T>[], window: [number, number], scaleFor: (section: SectionInfoWithScale<T>) => number): SectionInfoWithScale<T>[];
9
48
  export declare function createPackageScale(def: PackageScaleInfo, offset?: number): PackageScaleInfo;
10
49
  export interface CompositeColumnScale {
11
50
  (age: number): number | null;