@macrostrat/column-views 3.11.0 → 3.12.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.
Files changed (138) hide show
  1. package/CHANGELOG.md +184 -0
  2. package/dist/age-axis.cjs +1 -2
  3. package/dist/age-axis.cjs.map +1 -1
  4. package/dist/age-axis.js +1 -2
  5. package/dist/age-axis.js.map +1 -1
  6. package/dist/age-model/data.cjs +57 -0
  7. package/dist/age-model/data.cjs.map +1 -0
  8. package/dist/age-model/data.d.ts +29 -0
  9. package/dist/age-model/data.js +57 -0
  10. package/dist/age-model/data.js.map +1 -0
  11. package/dist/age-model/details.cjs +260 -0
  12. package/dist/age-model/details.cjs.map +1 -0
  13. package/dist/age-model/details.d.ts +39 -0
  14. package/dist/age-model/details.js +257 -0
  15. package/dist/age-model/details.js.map +1 -0
  16. package/dist/age-model/details.module.sass.cjs +42 -0
  17. package/dist/age-model/details.module.sass.cjs.map +1 -0
  18. package/dist/age-model/details.module.sass.js +40 -0
  19. package/dist/age-model/details.module.sass.js.map +1 -0
  20. package/dist/age-model/index.d.ts +5 -0
  21. package/dist/age-model/legacy.cjs +28 -0
  22. package/dist/age-model/legacy.cjs.map +1 -0
  23. package/dist/age-model/legacy.d.ts +6 -0
  24. package/dist/age-model/legacy.js +26 -0
  25. package/dist/age-model/legacy.js.map +1 -0
  26. package/dist/age-model/surfaces.cjs +354 -0
  27. package/dist/age-model/surfaces.cjs.map +1 -0
  28. package/dist/age-model/surfaces.d.ts +68 -0
  29. package/dist/age-model/surfaces.js +351 -0
  30. package/dist/age-model/surfaces.js.map +1 -0
  31. package/dist/age-model/surfaces.module.sass.cjs +45 -0
  32. package/dist/age-model/surfaces.module.sass.cjs.map +1 -0
  33. package/dist/age-model/surfaces.module.sass.js +43 -0
  34. package/dist/age-model/surfaces.module.sass.js.map +1 -0
  35. package/dist/age-model/types.cjs +229 -0
  36. package/dist/age-model/types.cjs.map +1 -0
  37. package/dist/age-model/types.d.ts +112 -0
  38. package/dist/age-model/types.js +229 -0
  39. package/dist/age-model/types.js.map +1 -0
  40. package/dist/column-views.css +406 -74
  41. package/dist/column.cjs +20 -13
  42. package/dist/column.cjs.map +1 -1
  43. package/dist/column.d.ts +21 -6
  44. package/dist/column.js +21 -14
  45. package/dist/column.js.map +1 -1
  46. package/dist/column.module.sass.cjs +19 -15
  47. package/dist/column.module.sass.cjs.map +1 -1
  48. package/dist/column.module.sass.js +19 -15
  49. package/dist/column.module.sass.js.map +1 -1
  50. package/dist/data-provider/store.cjs +34 -1
  51. package/dist/data-provider/store.cjs.map +1 -1
  52. package/dist/data-provider/store.d.ts +5 -0
  53. package/dist/data-provider/store.js +35 -2
  54. package/dist/data-provider/store.js.map +1 -1
  55. package/dist/index.cjs +78 -18
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.ts +3 -1
  58. package/dist/index.js +55 -4
  59. package/dist/index.js.map +1 -1
  60. package/dist/notes.cjs +11 -2
  61. package/dist/notes.cjs.map +1 -1
  62. package/dist/notes.d.ts +11 -1
  63. package/dist/notes.js +11 -2
  64. package/dist/notes.js.map +1 -1
  65. package/dist/prepare-units/composite-scale.cjs +18 -16
  66. package/dist/prepare-units/composite-scale.cjs.map +1 -1
  67. package/dist/prepare-units/composite-scale.js +18 -16
  68. package/dist/prepare-units/composite-scale.js.map +1 -1
  69. package/dist/prepare-units/density.cjs +83 -0
  70. package/dist/prepare-units/density.cjs.map +1 -0
  71. package/dist/prepare-units/density.d.ts +92 -0
  72. package/dist/prepare-units/density.js +83 -0
  73. package/dist/prepare-units/density.js.map +1 -0
  74. package/dist/prepare-units/index.cjs +15 -7
  75. package/dist/prepare-units/index.cjs.map +1 -1
  76. package/dist/prepare-units/index.d.ts +1 -0
  77. package/dist/prepare-units/index.js +15 -7
  78. package/dist/prepare-units/index.js.map +1 -1
  79. package/dist/prepare-units/types.cjs.map +1 -1
  80. package/dist/prepare-units/types.d.ts +34 -13
  81. package/dist/prepare-units/types.js.map +1 -1
  82. package/dist/section.cjs +108 -24
  83. package/dist/section.cjs.map +1 -1
  84. package/dist/section.d.ts +66 -6
  85. package/dist/section.js +109 -25
  86. package/dist/section.js.map +1 -1
  87. package/dist/timescale-zoom.cjs +191 -0
  88. package/dist/timescale-zoom.cjs.map +1 -0
  89. package/dist/timescale-zoom.d.ts +74 -0
  90. package/dist/timescale-zoom.js +191 -0
  91. package/dist/timescale-zoom.js.map +1 -0
  92. package/dist/unit-details/age-range.cjs +14 -43
  93. package/dist/unit-details/age-range.cjs.map +1 -1
  94. package/dist/unit-details/age-range.d.ts +1 -13
  95. package/dist/unit-details/age-range.js +6 -43
  96. package/dist/unit-details/age-range.js.map +1 -1
  97. package/dist/unit-details/utils.cjs +0 -5
  98. package/dist/unit-details/utils.cjs.map +1 -1
  99. package/dist/unit-details/utils.js +0 -5
  100. package/dist/unit-details/utils.js.map +1 -1
  101. package/dist/units/composite.cjs +4 -1
  102. package/dist/units/composite.cjs.map +1 -1
  103. package/dist/units/composite.d.ts +2 -0
  104. package/dist/units/composite.js +4 -1
  105. package/dist/units/composite.js.map +1 -1
  106. package/package.json +8 -8
  107. package/src/age-model/data.ts +98 -0
  108. package/src/age-model/details.module.sass +108 -0
  109. package/src/age-model/details.ts +333 -0
  110. package/src/age-model/index.ts +5 -0
  111. package/src/age-model/legacy.ts +30 -0
  112. package/src/age-model/surfaces.module.sass +168 -0
  113. package/src/age-model/surfaces.ts +568 -0
  114. package/src/age-model/types.ts +392 -0
  115. package/src/column.module.sass +59 -8
  116. package/src/column.ts +49 -23
  117. package/src/data-provider/store.ts +50 -1
  118. package/src/index.ts +5 -1
  119. package/src/notes.ts +20 -2
  120. package/src/prepare-units/composite-scale.ts +34 -31
  121. package/src/prepare-units/density.ts +197 -0
  122. package/src/prepare-units/index.ts +25 -6
  123. package/src/prepare-units/types.ts +34 -13
  124. package/src/section.ts +219 -33
  125. package/src/timescale-zoom.ts +341 -0
  126. package/src/unit-details/age-range.ts +12 -58
  127. package/src/units/composite.ts +11 -0
  128. package/dist/age-model-overlay.cjs +0 -50
  129. package/dist/age-model-overlay.cjs.map +0 -1
  130. package/dist/age-model-overlay.d.ts +0 -24
  131. package/dist/age-model-overlay.js +0 -48
  132. package/dist/age-model-overlay.js.map +0 -1
  133. package/dist/age-model-overlay.module.sass.cjs +0 -12
  134. package/dist/age-model-overlay.module.sass.cjs.map +0 -1
  135. package/dist/age-model-overlay.module.sass.js +0 -11
  136. package/dist/age-model-overlay.module.sass.js.map +0 -1
  137. package/src/age-model-overlay.module.sass +0 -11
  138. package/src/age-model-overlay.ts +0 -96
@@ -32,19 +32,6 @@ function AgeRange({
32
32
  className
33
33
  });
34
34
  }
35
- function AgeLabel({
36
- age,
37
- maximumFractionDigits = 2,
38
- minimumFractionDigits = 0,
39
- className
40
- }) {
41
- const [value, unit] = getAge(age);
42
- const _value = value.toLocaleString("en-US", {
43
- maximumFractionDigits,
44
- minimumFractionDigits
45
- });
46
- return ageRange_module.default(dataComponents.Value, { value: _value, unit, className });
47
- }
48
35
  function Duration({
49
36
  value,
50
37
  maximumFractionDigits = 2,
@@ -110,9 +97,9 @@ function IntervalProportions({
110
97
  let p0 = null;
111
98
  let p1 = null;
112
99
  if (_showProps !== false) {
113
- p1 = ageRange_module.default(Proportion, { value: t_prop });
100
+ p1 = ageRange_module.default(dataComponents.IntervalProportion, { value: t_prop });
114
101
  if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {
115
- p0 = ageRange_module.default(Proportion, { value: b_prop });
102
+ p0 = ageRange_module.default(dataComponents.IntervalProportion, { value: b_prop });
116
103
  }
117
104
  if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
118
105
  p0 = ageRange_module.default("span.joint-proportion", [p0, " ", ageRange_module.default("span.sep", "to"), " ", p1]);
@@ -145,17 +132,6 @@ function IntervalProportions({
145
132
  function getProportion(age, interval) {
146
133
  return (interval.b_age - age) / (interval.b_age - interval.t_age);
147
134
  }
148
- function Proportion({ value }) {
149
- let content = null;
150
- if (value == 0) {
151
- content = "base";
152
- } else if (value == 1) {
153
- content = "top";
154
- } else {
155
- content = utils.formatProportion(value * 100) + "%";
156
- }
157
- return ageRange_module.default("span.proportion", content);
158
- }
159
135
  function getAgeRange(_unit) {
160
136
  let b_age = _unit.b_age;
161
137
  let t_age = _unit.t_age;
@@ -171,26 +147,21 @@ function getAgeRange(_unit) {
171
147
  }
172
148
  return [b_age, t_age, unit];
173
149
  }
174
- function getAge(value) {
175
- let unit = "Ma";
176
- if (value < 0.8) {
177
- unit = "ka";
178
- value *= 1e3;
179
- if (value < 5) {
180
- unit = "yr";
181
- value *= 1e3;
182
- }
183
- } else if (value > 1e3) {
184
- unit = "Ga";
185
- value /= 1e3;
186
- }
187
- return [value, unit];
188
- }
150
+ Object.defineProperty(exports, "AgeLabel", {
151
+ enumerable: true,
152
+ get: () => dataComponents.AgeLabel
153
+ });
154
+ Object.defineProperty(exports, "Proportion", {
155
+ enumerable: true,
156
+ get: () => dataComponents.IntervalProportion
157
+ });
158
+ Object.defineProperty(exports, "getAge", {
159
+ enumerable: true,
160
+ get: () => dataComponents.getAge
161
+ });
189
162
  exports.AgeField = AgeField;
190
- exports.AgeLabel = AgeLabel;
191
163
  exports.AgeRange = AgeRange;
192
164
  exports.Duration = Duration;
193
165
  exports.IntervalProportions = IntervalProportions;
194
- exports.getAge = getAge;
195
166
  exports.getAgeRange = getAgeRange;
196
167
  //# sourceMappingURL=age-range.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"age-range.cjs","sources":["../../src/unit-details/age-range.ts"],"sourcesContent":["import {\n DataField,\n IntervalShort,\n IntervalTag,\n type IntervalTagProps,\n ItemList,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useMacrostratDefs } from \"@macrostrat/data-provider\";\nimport h from \"./age-range.module.sass\";\nimport { formatProportion, formatRange } from \"./utils\";\nimport classNames from \"classnames\";\nimport { useMemo } from \"react\";\n\nexport function AgeField({ unit, children, ...rest }) {\n const [_b_age, _t_age, _unit] = getAgeRange(unit);\n\n return h(\n DataField,\n {\n label: \"Age\",\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n ...rest,\n },\n children,\n );\n}\n\nexport function AgeRange({\n data,\n className,\n}: {\n data: {\n t_age: number;\n b_age: number;\n };\n className?: string;\n}) {\n const [_b_age, _t_age, _unit] = getAgeRange(data);\n\n return h(Value, {\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n className,\n });\n}\n\nexport function AgeLabel({\n age,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n className,\n}: {\n age: number;\n className?: string;\n maximumFractionDigits?: number;\n minimumFractionDigits?: number;\n}) {\n /** Component to display a single age value with unit conversion from\n * Ma to ka or Ga as appropriate.\n */\n const [value, unit] = getAge(age);\n\n const _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit, className });\n}\n\nexport function Duration({\n value,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n}) {\n let unit = \"Myr\";\n if (value < 0.8) {\n unit = \"kyr\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Gyr\";\n value /= 1000;\n }\n\n let _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit });\n}\n\ninterface UnitIntervalConstraints {\n b_int_id?: number;\n t_int_id?: number;\n b_prop?: number;\n t_prop?: number;\n b_int_name?: string;\n t_int_name?: string;\n b_age?: number;\n t_age?: number;\n}\n\nexport interface IntervalProportionsProps extends Omit<\n IntervalTagProps,\n \"interval\"\n> {\n unit: UnitIntervalConstraints;\n showProportions?: boolean;\n calculateProportionsFromAges?: boolean;\n onClickItem?: any;\n}\n\nexport function IntervalProportions({\n unit,\n className,\n showProportions,\n calculateProportionsFromAges = true,\n ...rest\n}: IntervalProportionsProps) {\n /** Display the proportions of the unit that belong to the base and top intervals, if they are different */\n if (unit.b_int_id == null && unit.t_int_id == null) return null;\n\n let _showProps = showProportions;\n\n const i0 = unit.b_int_id;\n const i1 = unit.t_int_id;\n\n const ints = new Set([i0, i1]);\n\n /** Get interval information */\n const intervalMap = useMacrostratDefs(\"intervals\", Array.from(ints), null);\n const [int0, int1] = useMemo(() => {\n const int0 = intervalMap?.get(i0) ?? {};\n if (i0 === i1) {\n return [int0, int0];\n }\n const int1 = intervalMap?.get(i1) ?? {};\n return [int0, int1];\n }, [intervalMap, i0, i1]);\n\n const interval0: IntervalShort = {\n id: i0,\n name: unit.b_int_name,\n ...int0,\n };\n\n let b_prop = unit.b_prop;\n let t_prop = unit.t_prop;\n\n // If we have b_age and t_age, then we can calculate proportions if they are not given\n if (b_prop == null && unit.b_age != null && calculateProportionsFromAges) {\n b_prop = getProportion(unit.b_age, int0);\n }\n if (t_prop == null && unit.t_age != null && calculateProportionsFromAges) {\n t_prop = getProportion(unit.t_age, int1);\n }\n\n // If there are no proportions given and we are not explicitly directed to show them,\n // then we set them to hidden.\n if (b_prop == null && t_prop == null) {\n _showProps ??= false;\n }\n\n /*\n Set default proportions to 0 and 1 if they are not given,\n so that we can display \"base\" and \"top\" labels\n */\n b_prop ??= 0;\n t_prop ??= 1;\n\n let p0: any = null;\n let p1: any = null;\n\n if (_showProps !== false) {\n p1 = h(Proportion, { value: t_prop });\n\n if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {\n // We have a single interval with undefined proportions\n p0 = h(Proportion, { value: b_prop });\n }\n\n if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {\n p0 = h(\"span.joint-proportion\", [p0, \" \", h(\"span.sep\", \"to\"), \" \", p1]);\n }\n }\n\n return h(\n ItemList,\n { className: classNames(\"interval-proportions\", className) },\n [\n h(IntervalTag, {\n interval: interval0,\n prefix: p0,\n ...rest,\n }),\n h.if(i0 != i1)(\"span.discourage-break\", [\n h(\"span.sep\", \" to \"),\n h(IntervalTag, {\n interval: {\n id: i1,\n name: unit.t_int_name,\n ...int1,\n },\n prefix: p1,\n ...rest,\n }),\n ]),\n ],\n );\n}\n\nfunction getProportion(age: number, interval: IntervalShort): number | null {\n /** Get proportion with the age */\n return (interval.b_age - age) / (interval.b_age - interval.t_age);\n}\n\nfunction Proportion({ value }) {\n let content = null;\n if (value == 0) {\n content = \"base\";\n } else if (value == 1) {\n content = \"top\";\n } else {\n content = formatProportion(value * 100) + \"%\";\n }\n\n return h(\"span.proportion\", content);\n}\n\nexport function getAgeRange(_unit) {\n let b_age = _unit.b_age;\n let t_age = _unit.t_age;\n let unit = \"Ma\";\n\n if (b_age < 0.8 && t_age < 1.2) {\n b_age *= 1000;\n t_age *= 1000;\n unit = \"ka\";\n } else if (b_age > 800 && t_age > 1200) {\n b_age /= 1000;\n t_age /= 1000;\n unit = \"Ga\";\n }\n\n return [b_age, t_age, unit];\n}\n\nexport function getAge(value) {\n /** Get the age value in Ma, ka, or Ga as appropriate */\n let unit = \"Ma\";\n if (value < 0.8) {\n unit = \"ka\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Ga\";\n value /= 1000;\n }\n\n return [value, unit];\n}\n"],"names":["h","DataField","formatRange","Value","useMacrostratDefs","useMemo","int0","int1","ItemList","classNames","IntervalTag","formatProportion"],"mappings":"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"}
1
+ {"version":3,"file":"age-range.cjs","sources":["../../src/unit-details/age-range.ts"],"sourcesContent":["import {\n DataField,\n IntervalProportion,\n IntervalShort,\n IntervalTag,\n type IntervalTagProps,\n ItemList,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useMacrostratDefs } from \"@macrostrat/data-provider\";\nimport h from \"./age-range.module.sass\";\nimport { formatRange } from \"./utils\";\nimport classNames from \"classnames\";\nimport { useMemo } from \"react\";\n\n// The interval tag, its proportion and single-age label live in\n// `@macrostrat/data-components`; re-exported under their names here.\nexport {\n AgeLabel,\n getAge,\n IntervalProportion as Proportion,\n} from \"@macrostrat/data-components\";\n\nexport function AgeField({ unit, children, ...rest }) {\n const [_b_age, _t_age, _unit] = getAgeRange(unit);\n\n return h(\n DataField,\n {\n label: \"Age\",\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n ...rest,\n },\n children,\n );\n}\n\nexport function AgeRange({\n data,\n className,\n}: {\n data: {\n t_age: number;\n b_age: number;\n };\n className?: string;\n}) {\n const [_b_age, _t_age, _unit] = getAgeRange(data);\n\n return h(Value, {\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n className,\n });\n}\n\nexport function Duration({\n value,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n}) {\n let unit = \"Myr\";\n if (value < 0.8) {\n unit = \"kyr\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Gyr\";\n value /= 1000;\n }\n\n let _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit });\n}\n\ninterface UnitIntervalConstraints {\n b_int_id?: number;\n t_int_id?: number;\n b_prop?: number;\n t_prop?: number;\n b_int_name?: string;\n t_int_name?: string;\n b_age?: number;\n t_age?: number;\n}\n\nexport interface IntervalProportionsProps extends Omit<\n IntervalTagProps,\n \"interval\"\n> {\n unit: UnitIntervalConstraints;\n showProportions?: boolean;\n calculateProportionsFromAges?: boolean;\n onClickItem?: any;\n}\n\nexport function IntervalProportions({\n unit,\n className,\n showProportions,\n calculateProportionsFromAges = true,\n ...rest\n}: IntervalProportionsProps) {\n /** Display the proportions of the unit that belong to the base and top intervals, if they are different */\n if (unit.b_int_id == null && unit.t_int_id == null) return null;\n\n let _showProps = showProportions;\n\n const i0 = unit.b_int_id;\n const i1 = unit.t_int_id;\n\n const ints = new Set([i0, i1]);\n\n /** Get interval information */\n const intervalMap = useMacrostratDefs(\"intervals\", Array.from(ints), null);\n const [int0, int1] = useMemo(() => {\n const int0 = intervalMap?.get(i0) ?? {};\n if (i0 === i1) {\n return [int0, int0];\n }\n const int1 = intervalMap?.get(i1) ?? {};\n return [int0, int1];\n }, [intervalMap, i0, i1]);\n\n const interval0: IntervalShort = {\n id: i0,\n name: unit.b_int_name,\n ...int0,\n };\n\n let b_prop = unit.b_prop;\n let t_prop = unit.t_prop;\n\n // If we have b_age and t_age, then we can calculate proportions if they are not given\n if (b_prop == null && unit.b_age != null && calculateProportionsFromAges) {\n b_prop = getProportion(unit.b_age, int0);\n }\n if (t_prop == null && unit.t_age != null && calculateProportionsFromAges) {\n t_prop = getProportion(unit.t_age, int1);\n }\n\n // If there are no proportions given and we are not explicitly directed to show them,\n // then we set them to hidden.\n if (b_prop == null && t_prop == null) {\n _showProps ??= false;\n }\n\n /*\n Set default proportions to 0 and 1 if they are not given,\n so that we can display \"base\" and \"top\" labels\n */\n b_prop ??= 0;\n t_prop ??= 1;\n\n let p0: any = null;\n let p1: any = null;\n\n if (_showProps !== false) {\n p1 = h(IntervalProportion, { value: t_prop });\n\n if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {\n // We have a single interval with undefined proportions\n p0 = h(IntervalProportion, { value: b_prop });\n }\n\n if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {\n p0 = h(\"span.joint-proportion\", [p0, \" \", h(\"span.sep\", \"to\"), \" \", p1]);\n }\n }\n\n return h(\n ItemList,\n { className: classNames(\"interval-proportions\", className) },\n [\n h(IntervalTag, {\n interval: interval0,\n prefix: p0,\n ...rest,\n }),\n h.if(i0 != i1)(\"span.discourage-break\", [\n h(\"span.sep\", \" to \"),\n h(IntervalTag, {\n interval: {\n id: i1,\n name: unit.t_int_name,\n ...int1,\n },\n prefix: p1,\n ...rest,\n }),\n ]),\n ],\n );\n}\n\nfunction getProportion(age: number, interval: IntervalShort): number | null {\n /** Get proportion with the age */\n return (interval.b_age - age) / (interval.b_age - interval.t_age);\n}\n\nexport function getAgeRange(_unit) {\n let b_age = _unit.b_age;\n let t_age = _unit.t_age;\n let unit = \"Ma\";\n\n if (b_age < 0.8 && t_age < 1.2) {\n b_age *= 1000;\n t_age *= 1000;\n unit = \"ka\";\n } else if (b_age > 800 && t_age > 1200) {\n b_age /= 1000;\n t_age /= 1000;\n unit = \"Ga\";\n }\n\n return [b_age, t_age, unit];\n}\n"],"names":["h","DataField","formatRange","Value","useMacrostratDefs","useMemo","int0","int1","IntervalProportion","ItemList","classNames","IntervalTag"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { IntervalTagProps } from '@macrostrat/data-components';
2
+ export { AgeLabel, getAge, IntervalProportion as Proportion, } from '@macrostrat/data-components';
2
3
  export declare function AgeField({ unit, children, ...rest }: {
3
4
  [x: string]: any;
4
5
  unit: any;
@@ -25,17 +26,6 @@ export declare function AgeRange({ data, className, }: {
25
26
  children?: any;
26
27
  className?: string;
27
28
  }>;
28
- export declare function AgeLabel({ age, maximumFractionDigits, minimumFractionDigits, className, }: {
29
- age: number;
30
- className?: string;
31
- maximumFractionDigits?: number;
32
- minimumFractionDigits?: number;
33
- }): import('react').FunctionComponentElement<{
34
- value?: any;
35
- unit?: string;
36
- children?: any;
37
- className?: string;
38
- }>;
39
29
  export declare function Duration({ value, maximumFractionDigits, minimumFractionDigits, }: {
40
30
  value: any;
41
31
  maximumFractionDigits?: number | undefined;
@@ -67,5 +57,3 @@ export declare function IntervalProportions({ unit, className, showProportions,
67
57
  className: string;
68
58
  }> | null;
69
59
  export declare function getAgeRange(_unit: any): any[];
70
- export declare function getAge(value: any): any[];
71
- export {};
@@ -1,7 +1,8 @@
1
- import { DataField, Value, ItemList, IntervalTag } from "@macrostrat/data-components";
1
+ import { DataField, Value, IntervalProportion, ItemList, IntervalTag } from "@macrostrat/data-components";
2
+ import { AgeLabel, IntervalProportion as IntervalProportion2, getAge } from "@macrostrat/data-components";
2
3
  import { useMacrostratDefs } from "@macrostrat/data-provider";
3
4
  import h from "./age-range.module.sass.js";
4
- import { formatRange, formatProportion } from "./utils.js";
5
+ import { formatRange } from "./utils.js";
5
6
  import classNames from "classnames";
6
7
  import { useMemo } from "react";
7
8
  function AgeField({ unit, children, ...rest }) {
@@ -28,19 +29,6 @@ function AgeRange({
28
29
  className
29
30
  });
30
31
  }
31
- function AgeLabel({
32
- age,
33
- maximumFractionDigits = 2,
34
- minimumFractionDigits = 0,
35
- className
36
- }) {
37
- const [value, unit] = getAge(age);
38
- const _value = value.toLocaleString("en-US", {
39
- maximumFractionDigits,
40
- minimumFractionDigits
41
- });
42
- return h(Value, { value: _value, unit, className });
43
- }
44
32
  function Duration({
45
33
  value,
46
34
  maximumFractionDigits = 2,
@@ -106,9 +94,9 @@ function IntervalProportions({
106
94
  let p0 = null;
107
95
  let p1 = null;
108
96
  if (_showProps !== false) {
109
- p1 = h(Proportion, { value: t_prop });
97
+ p1 = h(IntervalProportion, { value: t_prop });
110
98
  if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {
111
- p0 = h(Proportion, { value: b_prop });
99
+ p0 = h(IntervalProportion, { value: b_prop });
112
100
  }
113
101
  if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
114
102
  p0 = h("span.joint-proportion", [p0, " ", h("span.sep", "to"), " ", p1]);
@@ -141,17 +129,6 @@ function IntervalProportions({
141
129
  function getProportion(age, interval) {
142
130
  return (interval.b_age - age) / (interval.b_age - interval.t_age);
143
131
  }
144
- function Proportion({ value }) {
145
- let content = null;
146
- if (value == 0) {
147
- content = "base";
148
- } else if (value == 1) {
149
- content = "top";
150
- } else {
151
- content = formatProportion(value * 100) + "%";
152
- }
153
- return h("span.proportion", content);
154
- }
155
132
  function getAgeRange(_unit) {
156
133
  let b_age = _unit.b_age;
157
134
  let t_age = _unit.t_age;
@@ -167,27 +144,13 @@ function getAgeRange(_unit) {
167
144
  }
168
145
  return [b_age, t_age, unit];
169
146
  }
170
- function getAge(value) {
171
- let unit = "Ma";
172
- if (value < 0.8) {
173
- unit = "ka";
174
- value *= 1e3;
175
- if (value < 5) {
176
- unit = "yr";
177
- value *= 1e3;
178
- }
179
- } else if (value > 1e3) {
180
- unit = "Ga";
181
- value /= 1e3;
182
- }
183
- return [value, unit];
184
- }
185
147
  export {
186
148
  AgeField,
187
149
  AgeLabel,
188
150
  AgeRange,
189
151
  Duration,
190
152
  IntervalProportions,
153
+ IntervalProportion2 as Proportion,
191
154
  getAge,
192
155
  getAgeRange
193
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"age-range.js","sources":["../../src/unit-details/age-range.ts"],"sourcesContent":["import {\n DataField,\n IntervalShort,\n IntervalTag,\n type IntervalTagProps,\n ItemList,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useMacrostratDefs } from \"@macrostrat/data-provider\";\nimport h from \"./age-range.module.sass\";\nimport { formatProportion, formatRange } from \"./utils\";\nimport classNames from \"classnames\";\nimport { useMemo } from \"react\";\n\nexport function AgeField({ unit, children, ...rest }) {\n const [_b_age, _t_age, _unit] = getAgeRange(unit);\n\n return h(\n DataField,\n {\n label: \"Age\",\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n ...rest,\n },\n children,\n );\n}\n\nexport function AgeRange({\n data,\n className,\n}: {\n data: {\n t_age: number;\n b_age: number;\n };\n className?: string;\n}) {\n const [_b_age, _t_age, _unit] = getAgeRange(data);\n\n return h(Value, {\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n className,\n });\n}\n\nexport function AgeLabel({\n age,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n className,\n}: {\n age: number;\n className?: string;\n maximumFractionDigits?: number;\n minimumFractionDigits?: number;\n}) {\n /** Component to display a single age value with unit conversion from\n * Ma to ka or Ga as appropriate.\n */\n const [value, unit] = getAge(age);\n\n const _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit, className });\n}\n\nexport function Duration({\n value,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n}) {\n let unit = \"Myr\";\n if (value < 0.8) {\n unit = \"kyr\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Gyr\";\n value /= 1000;\n }\n\n let _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit });\n}\n\ninterface UnitIntervalConstraints {\n b_int_id?: number;\n t_int_id?: number;\n b_prop?: number;\n t_prop?: number;\n b_int_name?: string;\n t_int_name?: string;\n b_age?: number;\n t_age?: number;\n}\n\nexport interface IntervalProportionsProps extends Omit<\n IntervalTagProps,\n \"interval\"\n> {\n unit: UnitIntervalConstraints;\n showProportions?: boolean;\n calculateProportionsFromAges?: boolean;\n onClickItem?: any;\n}\n\nexport function IntervalProportions({\n unit,\n className,\n showProportions,\n calculateProportionsFromAges = true,\n ...rest\n}: IntervalProportionsProps) {\n /** Display the proportions of the unit that belong to the base and top intervals, if they are different */\n if (unit.b_int_id == null && unit.t_int_id == null) return null;\n\n let _showProps = showProportions;\n\n const i0 = unit.b_int_id;\n const i1 = unit.t_int_id;\n\n const ints = new Set([i0, i1]);\n\n /** Get interval information */\n const intervalMap = useMacrostratDefs(\"intervals\", Array.from(ints), null);\n const [int0, int1] = useMemo(() => {\n const int0 = intervalMap?.get(i0) ?? {};\n if (i0 === i1) {\n return [int0, int0];\n }\n const int1 = intervalMap?.get(i1) ?? {};\n return [int0, int1];\n }, [intervalMap, i0, i1]);\n\n const interval0: IntervalShort = {\n id: i0,\n name: unit.b_int_name,\n ...int0,\n };\n\n let b_prop = unit.b_prop;\n let t_prop = unit.t_prop;\n\n // If we have b_age and t_age, then we can calculate proportions if they are not given\n if (b_prop == null && unit.b_age != null && calculateProportionsFromAges) {\n b_prop = getProportion(unit.b_age, int0);\n }\n if (t_prop == null && unit.t_age != null && calculateProportionsFromAges) {\n t_prop = getProportion(unit.t_age, int1);\n }\n\n // If there are no proportions given and we are not explicitly directed to show them,\n // then we set them to hidden.\n if (b_prop == null && t_prop == null) {\n _showProps ??= false;\n }\n\n /*\n Set default proportions to 0 and 1 if they are not given,\n so that we can display \"base\" and \"top\" labels\n */\n b_prop ??= 0;\n t_prop ??= 1;\n\n let p0: any = null;\n let p1: any = null;\n\n if (_showProps !== false) {\n p1 = h(Proportion, { value: t_prop });\n\n if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {\n // We have a single interval with undefined proportions\n p0 = h(Proportion, { value: b_prop });\n }\n\n if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {\n p0 = h(\"span.joint-proportion\", [p0, \" \", h(\"span.sep\", \"to\"), \" \", p1]);\n }\n }\n\n return h(\n ItemList,\n { className: classNames(\"interval-proportions\", className) },\n [\n h(IntervalTag, {\n interval: interval0,\n prefix: p0,\n ...rest,\n }),\n h.if(i0 != i1)(\"span.discourage-break\", [\n h(\"span.sep\", \" to \"),\n h(IntervalTag, {\n interval: {\n id: i1,\n name: unit.t_int_name,\n ...int1,\n },\n prefix: p1,\n ...rest,\n }),\n ]),\n ],\n );\n}\n\nfunction getProportion(age: number, interval: IntervalShort): number | null {\n /** Get proportion with the age */\n return (interval.b_age - age) / (interval.b_age - interval.t_age);\n}\n\nfunction Proportion({ value }) {\n let content = null;\n if (value == 0) {\n content = \"base\";\n } else if (value == 1) {\n content = \"top\";\n } else {\n content = formatProportion(value * 100) + \"%\";\n }\n\n return h(\"span.proportion\", content);\n}\n\nexport function getAgeRange(_unit) {\n let b_age = _unit.b_age;\n let t_age = _unit.t_age;\n let unit = \"Ma\";\n\n if (b_age < 0.8 && t_age < 1.2) {\n b_age *= 1000;\n t_age *= 1000;\n unit = \"ka\";\n } else if (b_age > 800 && t_age > 1200) {\n b_age /= 1000;\n t_age /= 1000;\n unit = \"Ga\";\n }\n\n return [b_age, t_age, unit];\n}\n\nexport function getAge(value) {\n /** Get the age value in Ma, ka, or Ga as appropriate */\n let unit = \"Ma\";\n if (value < 0.8) {\n unit = \"ka\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Ga\";\n value /= 1000;\n }\n\n return [value, unit];\n}\n"],"names":["int0","int1"],"mappings":"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"}
1
+ {"version":3,"file":"age-range.js","sources":["../../src/unit-details/age-range.ts"],"sourcesContent":["import {\n DataField,\n IntervalProportion,\n IntervalShort,\n IntervalTag,\n type IntervalTagProps,\n ItemList,\n Value,\n} from \"@macrostrat/data-components\";\nimport { useMacrostratDefs } from \"@macrostrat/data-provider\";\nimport h from \"./age-range.module.sass\";\nimport { formatRange } from \"./utils\";\nimport classNames from \"classnames\";\nimport { useMemo } from \"react\";\n\n// The interval tag, its proportion and single-age label live in\n// `@macrostrat/data-components`; re-exported under their names here.\nexport {\n AgeLabel,\n getAge,\n IntervalProportion as Proportion,\n} from \"@macrostrat/data-components\";\n\nexport function AgeField({ unit, children, ...rest }) {\n const [_b_age, _t_age, _unit] = getAgeRange(unit);\n\n return h(\n DataField,\n {\n label: \"Age\",\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n ...rest,\n },\n children,\n );\n}\n\nexport function AgeRange({\n data,\n className,\n}: {\n data: {\n t_age: number;\n b_age: number;\n };\n className?: string;\n}) {\n const [_b_age, _t_age, _unit] = getAgeRange(data);\n\n return h(Value, {\n value: formatRange(_b_age, _t_age),\n unit: _unit,\n className,\n });\n}\n\nexport function Duration({\n value,\n maximumFractionDigits = 2,\n minimumFractionDigits = 0,\n}) {\n let unit = \"Myr\";\n if (value < 0.8) {\n unit = \"kyr\";\n value *= 1000;\n if (value < 5) {\n unit = \"yr\";\n value *= 1000;\n }\n } else if (value > 1000) {\n unit = \"Gyr\";\n value /= 1000;\n }\n\n let _value = value.toLocaleString(\"en-US\", {\n maximumFractionDigits,\n minimumFractionDigits,\n });\n\n return h(Value, { value: _value, unit });\n}\n\ninterface UnitIntervalConstraints {\n b_int_id?: number;\n t_int_id?: number;\n b_prop?: number;\n t_prop?: number;\n b_int_name?: string;\n t_int_name?: string;\n b_age?: number;\n t_age?: number;\n}\n\nexport interface IntervalProportionsProps extends Omit<\n IntervalTagProps,\n \"interval\"\n> {\n unit: UnitIntervalConstraints;\n showProportions?: boolean;\n calculateProportionsFromAges?: boolean;\n onClickItem?: any;\n}\n\nexport function IntervalProportions({\n unit,\n className,\n showProportions,\n calculateProportionsFromAges = true,\n ...rest\n}: IntervalProportionsProps) {\n /** Display the proportions of the unit that belong to the base and top intervals, if they are different */\n if (unit.b_int_id == null && unit.t_int_id == null) return null;\n\n let _showProps = showProportions;\n\n const i0 = unit.b_int_id;\n const i1 = unit.t_int_id;\n\n const ints = new Set([i0, i1]);\n\n /** Get interval information */\n const intervalMap = useMacrostratDefs(\"intervals\", Array.from(ints), null);\n const [int0, int1] = useMemo(() => {\n const int0 = intervalMap?.get(i0) ?? {};\n if (i0 === i1) {\n return [int0, int0];\n }\n const int1 = intervalMap?.get(i1) ?? {};\n return [int0, int1];\n }, [intervalMap, i0, i1]);\n\n const interval0: IntervalShort = {\n id: i0,\n name: unit.b_int_name,\n ...int0,\n };\n\n let b_prop = unit.b_prop;\n let t_prop = unit.t_prop;\n\n // If we have b_age and t_age, then we can calculate proportions if they are not given\n if (b_prop == null && unit.b_age != null && calculateProportionsFromAges) {\n b_prop = getProportion(unit.b_age, int0);\n }\n if (t_prop == null && unit.t_age != null && calculateProportionsFromAges) {\n t_prop = getProportion(unit.t_age, int1);\n }\n\n // If there are no proportions given and we are not explicitly directed to show them,\n // then we set them to hidden.\n if (b_prop == null && t_prop == null) {\n _showProps ??= false;\n }\n\n /*\n Set default proportions to 0 and 1 if they are not given,\n so that we can display \"base\" and \"top\" labels\n */\n b_prop ??= 0;\n t_prop ??= 1;\n\n let p0: any = null;\n let p1: any = null;\n\n if (_showProps !== false) {\n p1 = h(IntervalProportion, { value: t_prop });\n\n if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {\n // We have a single interval with undefined proportions\n p0 = h(IntervalProportion, { value: b_prop });\n }\n\n if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {\n p0 = h(\"span.joint-proportion\", [p0, \" \", h(\"span.sep\", \"to\"), \" \", p1]);\n }\n }\n\n return h(\n ItemList,\n { className: classNames(\"interval-proportions\", className) },\n [\n h(IntervalTag, {\n interval: interval0,\n prefix: p0,\n ...rest,\n }),\n h.if(i0 != i1)(\"span.discourage-break\", [\n h(\"span.sep\", \" to \"),\n h(IntervalTag, {\n interval: {\n id: i1,\n name: unit.t_int_name,\n ...int1,\n },\n prefix: p1,\n ...rest,\n }),\n ]),\n ],\n );\n}\n\nfunction getProportion(age: number, interval: IntervalShort): number | null {\n /** Get proportion with the age */\n return (interval.b_age - age) / (interval.b_age - interval.t_age);\n}\n\nexport function getAgeRange(_unit) {\n let b_age = _unit.b_age;\n let t_age = _unit.t_age;\n let unit = \"Ma\";\n\n if (b_age < 0.8 && t_age < 1.2) {\n b_age *= 1000;\n t_age *= 1000;\n unit = \"ka\";\n } else if (b_age > 800 && t_age > 1200) {\n b_age /= 1000;\n t_age /= 1000;\n unit = \"Ga\";\n }\n\n return [b_age, t_age, unit];\n}\n"],"names":["int0","int1"],"mappings":"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"}
@@ -1,9 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const formatProportion = (d) => {
4
- if (d == null) return null;
5
- return d.toFixed(1);
6
- };
7
3
  function formatRange(min, max, precision = null) {
8
4
  if (min == null || max == null) return null;
9
5
  if (min === max) {
@@ -25,7 +21,6 @@ function formatSignificance(value, precision = null) {
25
21
  return (value / Math.pow(10, -precision)).toFixed(0) + "0".repeat(-precision);
26
22
  }
27
23
  }
28
- exports.formatProportion = formatProportion;
29
24
  exports.formatRange = formatRange;
30
25
  exports.formatSignificance = formatSignificance;
31
26
  //# sourceMappingURL=utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sources":["../../src/unit-details/utils.ts"],"sourcesContent":["export const formatProportion = (d) => {\n if (d == null) return null;\n return d.toFixed(1);\n};\n\nexport function formatRange(min, max, precision = null) {\n if (min == null || max == null) return null;\n if (min === max) {\n return min.toFixed(precision);\n }\n\n return `${formatSignificance(min, precision)}–${formatSignificance(\n max,\n precision,\n )}`;\n}\n\nexport function formatSignificance(value, precision = null) {\n // Format to preserve a reasonable number of significant figures\n // this could be done with an easier algorithm, probably:\n\n if (precision == null) {\n return value.toLocaleString();\n }\n if (precision >= 0) {\n return value.toFixed(precision);\n }\n if (precision < 0) {\n return (\n (value / Math.pow(10, -precision)).toFixed(0) + \"0\".repeat(-precision)\n );\n }\n}\n"],"names":[],"mappings":";;AAAO,MAAM,mBAAmB,CAAC,MAAM;AACrC,MAAI,KAAK,KAAM,QAAO;AACtB,SAAO,EAAE,QAAQ,CAAC;AACpB;AAEO,SAAS,YAAY,KAAK,KAAK,YAAY,MAAM;AACtD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AACvC,MAAI,QAAQ,KAAK;AACf,WAAO,IAAI,QAAQ,SAAS;AAAA,EAC9B;AAEA,SAAO,GAAG,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,EAAA,CACD;AACH;AAEO,SAAS,mBAAmB,OAAO,YAAY,MAAM;AAI1D,MAAI,aAAa,MAAM;AACrB,WAAO,MAAM,eAAA;AAAA,EACf;AACA,MAAI,aAAa,GAAG;AAClB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAChC;AACA,MAAI,YAAY,GAAG;AACjB,YACG,QAAQ,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS;AAAA,EAEzE;AACF;;;;"}
1
+ {"version":3,"file":"utils.cjs","sources":["../../src/unit-details/utils.ts"],"sourcesContent":["export const formatProportion = (d) => {\n if (d == null) return null;\n return d.toFixed(1);\n};\n\nexport function formatRange(min, max, precision = null) {\n if (min == null || max == null) return null;\n if (min === max) {\n return min.toFixed(precision);\n }\n\n return `${formatSignificance(min, precision)}–${formatSignificance(\n max,\n precision,\n )}`;\n}\n\nexport function formatSignificance(value, precision = null) {\n // Format to preserve a reasonable number of significant figures\n // this could be done with an easier algorithm, probably:\n\n if (precision == null) {\n return value.toLocaleString();\n }\n if (precision >= 0) {\n return value.toFixed(precision);\n }\n if (precision < 0) {\n return (\n (value / Math.pow(10, -precision)).toFixed(0) + \"0\".repeat(-precision)\n );\n }\n}\n"],"names":[],"mappings":";;AAKO,SAAS,YAAY,KAAK,KAAK,YAAY,MAAM;AACtD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AACvC,MAAI,QAAQ,KAAK;AACf,WAAO,IAAI,QAAQ,SAAS;AAAA,EAC9B;AAEA,SAAO,GAAG,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,EAAA,CACD;AACH;AAEO,SAAS,mBAAmB,OAAO,YAAY,MAAM;AAI1D,MAAI,aAAa,MAAM;AACrB,WAAO,MAAM,eAAA;AAAA,EACf;AACA,MAAI,aAAa,GAAG;AAClB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAChC;AACA,MAAI,YAAY,GAAG;AACjB,YACG,QAAQ,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS;AAAA,EAEzE;AACF;;;"}
@@ -1,7 +1,3 @@
1
- const formatProportion = (d) => {
2
- if (d == null) return null;
3
- return d.toFixed(1);
4
- };
5
1
  function formatRange(min, max, precision = null) {
6
2
  if (min == null || max == null) return null;
7
3
  if (min === max) {
@@ -24,7 +20,6 @@ function formatSignificance(value, precision = null) {
24
20
  }
25
21
  }
26
22
  export {
27
- formatProportion,
28
23
  formatRange,
29
24
  formatSignificance
30
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/unit-details/utils.ts"],"sourcesContent":["export const formatProportion = (d) => {\n if (d == null) return null;\n return d.toFixed(1);\n};\n\nexport function formatRange(min, max, precision = null) {\n if (min == null || max == null) return null;\n if (min === max) {\n return min.toFixed(precision);\n }\n\n return `${formatSignificance(min, precision)}–${formatSignificance(\n max,\n precision,\n )}`;\n}\n\nexport function formatSignificance(value, precision = null) {\n // Format to preserve a reasonable number of significant figures\n // this could be done with an easier algorithm, probably:\n\n if (precision == null) {\n return value.toLocaleString();\n }\n if (precision >= 0) {\n return value.toFixed(precision);\n }\n if (precision < 0) {\n return (\n (value / Math.pow(10, -precision)).toFixed(0) + \"0\".repeat(-precision)\n );\n }\n}\n"],"names":[],"mappings":"AAAO,MAAM,mBAAmB,CAAC,MAAM;AACrC,MAAI,KAAK,KAAM,QAAO;AACtB,SAAO,EAAE,QAAQ,CAAC;AACpB;AAEO,SAAS,YAAY,KAAK,KAAK,YAAY,MAAM;AACtD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AACvC,MAAI,QAAQ,KAAK;AACf,WAAO,IAAI,QAAQ,SAAS;AAAA,EAC9B;AAEA,SAAO,GAAG,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,EAAA,CACD;AACH;AAEO,SAAS,mBAAmB,OAAO,YAAY,MAAM;AAI1D,MAAI,aAAa,MAAM;AACrB,WAAO,MAAM,eAAA;AAAA,EACf;AACA,MAAI,aAAa,GAAG;AAClB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAChC;AACA,MAAI,YAAY,GAAG;AACjB,YACG,QAAQ,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS;AAAA,EAEzE;AACF;"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/unit-details/utils.ts"],"sourcesContent":["export const formatProportion = (d) => {\n if (d == null) return null;\n return d.toFixed(1);\n};\n\nexport function formatRange(min, max, precision = null) {\n if (min == null || max == null) return null;\n if (min === max) {\n return min.toFixed(precision);\n }\n\n return `${formatSignificance(min, precision)}–${formatSignificance(\n max,\n precision,\n )}`;\n}\n\nexport function formatSignificance(value, precision = null) {\n // Format to preserve a reasonable number of significant figures\n // this could be done with an easier algorithm, probably:\n\n if (precision == null) {\n return value.toLocaleString();\n }\n if (precision >= 0) {\n return value.toFixed(precision);\n }\n if (precision < 0) {\n return (\n (value / Math.pow(10, -precision)).toFixed(0) + \"0\".repeat(-precision)\n );\n }\n}\n"],"names":[],"mappings":"AAKO,SAAS,YAAY,KAAK,KAAK,YAAY,MAAM;AACtD,MAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AACvC,MAAI,QAAQ,KAAK;AACf,WAAO,IAAI,QAAQ,SAAS;AAAA,EAC9B;AAEA,SAAO,GAAG,mBAAmB,KAAK,SAAS,CAAC,IAAI;AAAA,IAC9C;AAAA,IACA;AAAA,EAAA,CACD;AACH;AAEO,SAAS,mBAAmB,OAAO,YAAY,MAAM;AAI1D,MAAI,aAAa,MAAM;AACrB,WAAO,MAAM,eAAA;AAAA,EACf;AACA,MAAI,aAAa,GAAG;AAClB,WAAO,MAAM,QAAQ,SAAS;AAAA,EAChC;AACA,MAAI,YAAY,GAAG;AACjB,YACG,QAAQ,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS;AAAA,EAEzE;AACF;"}
@@ -83,13 +83,15 @@ function AnnotatedUnitsColumn(props) {
83
83
  }, []);
84
84
  return null;
85
85
  }
86
+ const DEFAULT_LABEL_SUPPRESS_HEIGHT = 2;
86
87
  function SectionLabelsColumn(props) {
87
88
  const {
88
89
  width = 300,
89
90
  noteMode = "unlabeled",
90
91
  labelOffset = 30,
91
92
  noteComponent,
92
- shouldRenderNote
93
+ shouldRenderNote,
94
+ labelSuppressHeight = DEFAULT_LABEL_SUPPRESS_HEIGHT
93
95
  } = props;
94
96
  const { totalHeight, axisType } = store.useMacrostratColumnData();
95
97
  const _compositeScale = store.useCompositeScale();
@@ -117,6 +119,7 @@ function SectionLabelsColumn(props) {
117
119
  divisions: unitsToLabel,
118
120
  paddingLeft: labelOffset,
119
121
  width,
122
+ minimumHeight: labelSuppressHeight,
120
123
  noteComponent,
121
124
  shouldRenderNote,
122
125
  scale: _compositeScale,
@@ -1 +1 @@
1
- {"version":3,"file":"composite.cjs","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n\n const recompute = useCallback(() => {\n // Recompute over the *current* unit set (which changes as the column zooms).\n // The tracker ref accumulates entries for units seen at any zoom level, so\n // we gate on whether every currently-visible unit has reported — not on the\n // total number of tracked units, which would go stale and freeze the notes.\n const tracker = labelTrackerRef.current;\n const allReported = units.every((d) => findUnitID(d) in tracker);\n if (!allReported) return;\n setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));\n }, [units, findUnitID]);\n\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n labelTrackerRef.current[findUnitID(div)] = visible;\n recompute();\n },\n [recompute, findUnitID],\n );\n\n // Re-sync when the visible unit set changes (e.g. on zoom), so a unit whose\n // label now fits inline stops also rendering as a note, and vice versa.\n useEffect(() => {\n recompute();\n }, [recompute]);\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["hyperStyled","styles","createContext","useState","useRef","useCallback","useEffect","defaultNameFunction","useContext","LabeledUnit","LithologyColumn","UnitBoxes","useMacrostratColumnData","useCompositeScale","useUnitSelectionDispatch","SVG","UnitNamesColumn","ColumnContext"],"mappings":"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"}
1
+ {"version":3,"file":"composite.cjs","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n\n const recompute = useCallback(() => {\n // Recompute over the *current* unit set (which changes as the column zooms).\n // The tracker ref accumulates entries for units seen at any zoom level, so\n // we gate on whether every currently-visible unit has reported — not on the\n // total number of tracked units, which would go stale and freeze the notes.\n const tracker = labelTrackerRef.current;\n const allReported = units.every((d) => findUnitID(d) in tracker);\n if (!allReported) return;\n setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));\n }, [units, findUnitID]);\n\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n labelTrackerRef.current[findUnitID(div)] = visible;\n recompute();\n },\n [recompute, findUnitID],\n );\n\n // Re-sync when the visible unit set changes (e.g. on zoom), so a unit whose\n // label now fits inline stops also rendering as a note, and vice versa.\n useEffect(() => {\n recompute();\n }, [recompute]);\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels */\n labelSuppressHeight?: number;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\n/** A unit drawn thinner than this gets no label. The notes column can place\n * a label away from its unit and run a leader line back, so a thin unit is\n * labelable in principle — but below a pixel or two there is nothing on the\n * page to lead back to, and a dense column spends its labels on units the\n * reader cannot see. */\nconst DEFAULT_LABEL_SUPPRESS_HEIGHT = 2;\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n labelSuppressHeight = DEFAULT_LABEL_SUPPRESS_HEIGHT,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n minimumHeight: labelSuppressHeight,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["hyperStyled","styles","createContext","useState","useRef","useCallback","useEffect","defaultNameFunction","useContext","LabeledUnit","LithologyColumn","UnitBoxes","useMacrostratColumnData","useCompositeScale","useUnitSelectionDispatch","SVG","UnitNamesColumn","ColumnContext"],"mappings":"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"}
@@ -24,6 +24,8 @@ type ICompositeUnitProps = BaseUnitProps & {
24
24
  showLabelColumn?: boolean;
25
25
  noteComponent?: React.FC<any>;
26
26
  shouldRenderNote?: (d: any) => boolean;
27
+ /** Suppress the label for a unit drawn thinner than this many pixels */
28
+ labelSuppressHeight?: number;
27
29
  };
28
30
  interface CompositeUnitProps {
29
31
  unitComponent: React.FC<any>;
@@ -81,13 +81,15 @@ function AnnotatedUnitsColumn(props) {
81
81
  }, []);
82
82
  return null;
83
83
  }
84
+ const DEFAULT_LABEL_SUPPRESS_HEIGHT = 2;
84
85
  function SectionLabelsColumn(props) {
85
86
  const {
86
87
  width = 300,
87
88
  noteMode = "unlabeled",
88
89
  labelOffset = 30,
89
90
  noteComponent,
90
- shouldRenderNote
91
+ shouldRenderNote,
92
+ labelSuppressHeight = DEFAULT_LABEL_SUPPRESS_HEIGHT
91
93
  } = props;
92
94
  const { totalHeight, axisType } = useMacrostratColumnData();
93
95
  const _compositeScale = useCompositeScale();
@@ -115,6 +117,7 @@ function SectionLabelsColumn(props) {
115
117
  divisions: unitsToLabel,
116
118
  paddingLeft: labelOffset,
117
119
  width,
120
+ minimumHeight: labelSuppressHeight,
118
121
  noteComponent,
119
122
  shouldRenderNote,
120
123
  scale: _compositeScale,
@@ -1 +1 @@
1
- {"version":3,"file":"composite.js","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n\n const recompute = useCallback(() => {\n // Recompute over the *current* unit set (which changes as the column zooms).\n // The tracker ref accumulates entries for units seen at any zoom level, so\n // we gate on whether every currently-visible unit has reported — not on the\n // total number of tracked units, which would go stale and freeze the notes.\n const tracker = labelTrackerRef.current;\n const allReported = units.every((d) => findUnitID(d) in tracker);\n if (!allReported) return;\n setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));\n }, [units, findUnitID]);\n\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n labelTrackerRef.current[findUnitID(div)] = visible;\n recompute();\n },\n [recompute, findUnitID],\n );\n\n // Re-sync when the visible unit set changes (e.g. on zoom), so a unit whose\n // label now fits inline stops also rendering as a note, and vice versa.\n useEffect(() => {\n recompute();\n }, [recompute]);\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["styles"],"mappings":"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"}
1
+ {"version":3,"file":"composite.js","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n\n const recompute = useCallback(() => {\n // Recompute over the *current* unit set (which changes as the column zooms).\n // The tracker ref accumulates entries for units seen at any zoom level, so\n // we gate on whether every currently-visible unit has reported — not on the\n // total number of tracked units, which would go stale and freeze the notes.\n const tracker = labelTrackerRef.current;\n const allReported = units.every((d) => findUnitID(d) in tracker);\n if (!allReported) return;\n setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));\n }, [units, findUnitID]);\n\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n labelTrackerRef.current[findUnitID(div)] = visible;\n recompute();\n },\n [recompute, findUnitID],\n );\n\n // Re-sync when the visible unit set changes (e.g. on zoom), so a unit whose\n // label now fits inline stops also rendering as a note, and vice versa.\n useEffect(() => {\n recompute();\n }, [recompute]);\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n /** Suppress the label for a unit drawn thinner than this many pixels */\n labelSuppressHeight?: number;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\n/** A unit drawn thinner than this gets no label. The notes column can place\n * a label away from its unit and run a leader line back, so a thin unit is\n * labelable in principle — but below a pixel or two there is nothing on the\n * page to lead back to, and a dense column spends its labels on units the\n * reader cannot see. */\nconst DEFAULT_LABEL_SUPPRESS_HEIGHT = 2;\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n labelSuppressHeight = DEFAULT_LABEL_SUPPRESS_HEIGHT,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n minimumHeight: labelSuppressHeight,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["styles"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@macrostrat/column-views",
3
- "version": "3.11.0",
3
+ "version": "3.12.1",
4
4
  "description": "Data views for Macrostrat stratigraphic columns",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,16 +46,16 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@blueprintjs/core": "^6.14.0",
49
- "@macrostrat/api-types": "^1.3.0",
49
+ "@macrostrat/api-types": "^1.4.0",
50
50
  "@macrostrat/color-utils": "^1.2.2",
51
- "@macrostrat/column-components": "^2.1.0",
52
- "@macrostrat/data-components": "^1.5.1",
53
- "@macrostrat/data-provider": "^1.2.0",
51
+ "@macrostrat/column-components": "^2.2.0",
52
+ "@macrostrat/data-components": "^1.7.0",
53
+ "@macrostrat/data-provider": "^1.4.0",
54
54
  "@macrostrat/hyper": "^3.1.1",
55
- "@macrostrat/map-views": "^1.0.0",
55
+ "@macrostrat/map-views": "^1.1.1",
56
56
  "@macrostrat/scoped-store": "^1.1.0",
57
- "@macrostrat/stratigraphy-utils": "^1.4.0",
58
- "@macrostrat/timescale": "^3.2.0",
57
+ "@macrostrat/stratigraphy-utils": "^1.4.2",
58
+ "@macrostrat/timescale": "^3.3.0",
59
59
  "@macrostrat/ui-components": "^5.2.0",
60
60
  "@types/chroma-js": "^3.1.1",
61
61
  "@types/d3-format": "^3.0.4",