@macrostrat/column-views 3.2.0 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/age-axis.cjs +2 -2
- package/dist/age-axis.cjs.map +1 -1
- package/dist/age-axis.js +1 -1
- package/dist/column-views.css +130 -125
- package/dist/index.cjs +15 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/section.cjs +2 -2
- package/dist/section.cjs.map +1 -1
- package/dist/section.js +1 -1
- package/dist/unit-details/age-range.cjs +153 -0
- package/dist/unit-details/age-range.cjs.map +1 -0
- package/dist/unit-details/age-range.d.ts +43 -0
- package/dist/unit-details/age-range.js +153 -0
- package/dist/unit-details/age-range.js.map +1 -0
- package/dist/unit-details/age-range.module.sass.cjs +16 -0
- package/dist/unit-details/age-range.module.sass.cjs.map +1 -0
- package/dist/unit-details/age-range.module.sass.js +14 -0
- package/dist/unit-details/age-range.module.sass.js.map +1 -0
- package/dist/unit-details/index.d.ts +1 -0
- package/dist/unit-details/panel.cjs +17 -173
- package/dist/unit-details/panel.cjs.map +1 -1
- package/dist/unit-details/panel.js +12 -168
- package/dist/unit-details/panel.js.map +1 -1
- package/dist/unit-details/panel.module.sass.cjs +20 -22
- package/dist/unit-details/panel.module.sass.cjs.map +1 -1
- package/dist/unit-details/panel.module.sass.js +20 -22
- package/dist/unit-details/panel.module.sass.js.map +1 -1
- package/dist/unit-details/utils.cjs +31 -0
- package/dist/unit-details/utils.cjs.map +1 -0
- package/dist/unit-details/utils.d.ts +3 -0
- package/dist/unit-details/utils.js +31 -0
- package/dist/unit-details/utils.js.map +1 -0
- package/package.json +5 -5
- package/src/unit-details/age-range.module.sass +15 -0
- package/src/unit-details/age-range.ts +191 -0
- package/src/unit-details/index.ts +1 -0
- package/src/unit-details/panel.module.sass +0 -9
- package/src/unit-details/panel.ts +13 -227
- package/src/unit-details/utils.ts +33 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
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
|
+
function formatRange(min, max, precision = null) {
|
|
8
|
+
if (min == null || max == null) return null;
|
|
9
|
+
if (min === max) {
|
|
10
|
+
return min.toFixed(precision);
|
|
11
|
+
}
|
|
12
|
+
return `${formatSignificance(min, precision)}–${formatSignificance(
|
|
13
|
+
max,
|
|
14
|
+
precision
|
|
15
|
+
)}`;
|
|
16
|
+
}
|
|
17
|
+
function formatSignificance(value, precision = null) {
|
|
18
|
+
if (precision == null) {
|
|
19
|
+
return value.toLocaleString();
|
|
20
|
+
}
|
|
21
|
+
if (precision >= 0) {
|
|
22
|
+
return value.toFixed(precision);
|
|
23
|
+
}
|
|
24
|
+
if (precision < 0) {
|
|
25
|
+
return (value / Math.pow(10, -precision)).toFixed(0) + "0".repeat(-precision);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.formatProportion = formatProportion;
|
|
29
|
+
exports.formatRange = formatRange;
|
|
30
|
+
exports.formatSignificance = formatSignificance;
|
|
31
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const formatProportion = (d) => {
|
|
2
|
+
if (d == null) return null;
|
|
3
|
+
return d.toFixed(1);
|
|
4
|
+
};
|
|
5
|
+
function formatRange(min, max, precision = null) {
|
|
6
|
+
if (min == null || max == null) return null;
|
|
7
|
+
if (min === max) {
|
|
8
|
+
return min.toFixed(precision);
|
|
9
|
+
}
|
|
10
|
+
return `${formatSignificance(min, precision)}–${formatSignificance(
|
|
11
|
+
max,
|
|
12
|
+
precision
|
|
13
|
+
)}`;
|
|
14
|
+
}
|
|
15
|
+
function formatSignificance(value, precision = null) {
|
|
16
|
+
if (precision == null) {
|
|
17
|
+
return value.toLocaleString();
|
|
18
|
+
}
|
|
19
|
+
if (precision >= 0) {
|
|
20
|
+
return value.toFixed(precision);
|
|
21
|
+
}
|
|
22
|
+
if (precision < 0) {
|
|
23
|
+
return (value / Math.pow(10, -precision)).toFixed(0) + "0".repeat(-precision);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
formatProportion,
|
|
28
|
+
formatRange,
|
|
29
|
+
formatSignificance
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +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;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@macrostrat/column-views",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Data views for Macrostrat stratigraphic columns",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"@macrostrat/api-types": "^1.1.5",
|
|
50
50
|
"@macrostrat/color-utils": "^1.2.1",
|
|
51
51
|
"@macrostrat/column-components": "^2.0.4",
|
|
52
|
-
"@macrostrat/data-components": "^1.1.
|
|
53
|
-
"@macrostrat/data-provider": "^1.0.
|
|
52
|
+
"@macrostrat/data-components": "^1.1.2",
|
|
53
|
+
"@macrostrat/data-provider": "^1.0.1",
|
|
54
54
|
"@macrostrat/hyper": "^3.0.6",
|
|
55
|
-
"@macrostrat/map-interface": "^2.0
|
|
55
|
+
"@macrostrat/map-interface": "^2.1.0",
|
|
56
56
|
"@macrostrat/map-styles": "^2.1.0",
|
|
57
57
|
"@macrostrat/mapbox-react": "^3.0.2",
|
|
58
58
|
"@macrostrat/mapbox-utils": "^1.7.2",
|
|
59
59
|
"@macrostrat/stratigraphy-utils": "^1.2.1",
|
|
60
60
|
"@macrostrat/svg-map-components": "^2.0.1",
|
|
61
|
-
"@macrostrat/timescale": "^3.
|
|
61
|
+
"@macrostrat/timescale": "^3.1.1",
|
|
62
62
|
"@macrostrat/ui-components": "^5.0.5",
|
|
63
63
|
"@turf/boolean-point-in-polygon": "^7.3.2",
|
|
64
64
|
"@turf/buffer": "^7.3.2",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.interval-proportions
|
|
2
|
+
display: inline-flex
|
|
3
|
+
flex-flow: row wrap
|
|
4
|
+
gap: 0.5em
|
|
5
|
+
text-align: right
|
|
6
|
+
align-items: baseline
|
|
7
|
+
|
|
8
|
+
.interval-proportions, .discourage-break
|
|
9
|
+
align-items: baseline
|
|
10
|
+
white-space: nowrap
|
|
11
|
+
display: inline-flex
|
|
12
|
+
gap: 0.5em
|
|
13
|
+
|
|
14
|
+
.sep
|
|
15
|
+
color: var(--secondary-color)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataField,
|
|
3
|
+
IntervalShort,
|
|
4
|
+
IntervalTag,
|
|
5
|
+
ItemList,
|
|
6
|
+
Value,
|
|
7
|
+
} from "@macrostrat/data-components";
|
|
8
|
+
import { useMacrostratDefs } from "@macrostrat/data-provider";
|
|
9
|
+
import h from "./age-range.module.sass";
|
|
10
|
+
import { formatProportion, formatRange } from "./utils";
|
|
11
|
+
|
|
12
|
+
export function AgeField({ unit, children }) {
|
|
13
|
+
const [b_age, t_age, _unit] = getAgeRange(unit);
|
|
14
|
+
|
|
15
|
+
return h(
|
|
16
|
+
DataField,
|
|
17
|
+
{
|
|
18
|
+
label: "Age",
|
|
19
|
+
value: formatRange(b_age, t_age),
|
|
20
|
+
unit: _unit,
|
|
21
|
+
},
|
|
22
|
+
children,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function AgeLabel({
|
|
27
|
+
age,
|
|
28
|
+
maximumFractionDigits = 2,
|
|
29
|
+
minimumFractionDigits = 0,
|
|
30
|
+
className,
|
|
31
|
+
}: {
|
|
32
|
+
age: number;
|
|
33
|
+
className?: string;
|
|
34
|
+
maximumFractionDigits?: number;
|
|
35
|
+
minimumFractionDigits?: number;
|
|
36
|
+
}) {
|
|
37
|
+
/** Component to display a single age value with unit conversion from
|
|
38
|
+
* Ma to ka or Ga as appropriate.
|
|
39
|
+
*/
|
|
40
|
+
const [value, unit] = getAge(age);
|
|
41
|
+
|
|
42
|
+
const _value = value.toLocaleString("en-US", {
|
|
43
|
+
maximumFractionDigits,
|
|
44
|
+
minimumFractionDigits,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return h(Value, { value: _value, unit, className });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function Duration({
|
|
51
|
+
value,
|
|
52
|
+
maximumFractionDigits = 2,
|
|
53
|
+
minimumFractionDigits = 0,
|
|
54
|
+
}) {
|
|
55
|
+
let unit = "Myr";
|
|
56
|
+
if (value < 0.8) {
|
|
57
|
+
unit = "kyr";
|
|
58
|
+
value *= 1000;
|
|
59
|
+
if (value < 5) {
|
|
60
|
+
unit = "yr";
|
|
61
|
+
value *= 1000;
|
|
62
|
+
}
|
|
63
|
+
} else if (value > 1000) {
|
|
64
|
+
unit = "Gyr";
|
|
65
|
+
value /= 1000;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let _value = value.toLocaleString("en-US", {
|
|
69
|
+
maximumFractionDigits,
|
|
70
|
+
minimumFractionDigits,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return h(Value, { value: _value, unit });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function IntervalProportions({ unit, onClickItem }) {
|
|
77
|
+
/** Display the proportions of the unit that belong to the base and top intervals, if they are different */
|
|
78
|
+
if (
|
|
79
|
+
unit.b_int_id == null &&
|
|
80
|
+
unit.t_int_id == null &&
|
|
81
|
+
unit.b_prop == null &&
|
|
82
|
+
unit.t_prop == null
|
|
83
|
+
)
|
|
84
|
+
return null;
|
|
85
|
+
|
|
86
|
+
const i0 = unit.b_int_id;
|
|
87
|
+
const i1 = unit.t_int_id;
|
|
88
|
+
let b_prop = unit.b_prop ?? 0;
|
|
89
|
+
let t_prop = unit.t_prop ?? 1;
|
|
90
|
+
|
|
91
|
+
const intervalMap = useMacrostratDefs("intervals");
|
|
92
|
+
const int0 = intervalMap?.get(i0) ?? {};
|
|
93
|
+
|
|
94
|
+
const interval0: IntervalShort = {
|
|
95
|
+
...int0,
|
|
96
|
+
id: i0,
|
|
97
|
+
name: unit.b_int_name,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
let p0: any = null;
|
|
101
|
+
const int1 = intervalMap?.get(i1) ?? {};
|
|
102
|
+
const p1: any = h(Proportion, { value: t_prop });
|
|
103
|
+
|
|
104
|
+
if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {
|
|
105
|
+
// We have a single interval with undefined proportions
|
|
106
|
+
p0 = h(Proportion, { value: b_prop });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
|
|
110
|
+
p0 = h("span.joint-proportion", [p0, " ", h("span.sep", "to"), " ", p1]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const clickable = onClickItem != null;
|
|
114
|
+
|
|
115
|
+
const handleClick = (event: MouseEvent) => {
|
|
116
|
+
if (onClickItem) {
|
|
117
|
+
onClickItem(event, interval0);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return h(ItemList, { className: "interval-proportions" }, [
|
|
122
|
+
h(IntervalTag, {
|
|
123
|
+
className: clickable ? "clickable" : "",
|
|
124
|
+
onClick: clickable ? handleClick : undefined,
|
|
125
|
+
interval: interval0,
|
|
126
|
+
prefix: p0,
|
|
127
|
+
}),
|
|
128
|
+
h.if(i0 != i1)("span.discourage-break", [
|
|
129
|
+
h("span.sep", " to "),
|
|
130
|
+
h(IntervalTag, {
|
|
131
|
+
className: clickable ? "clickable" : "",
|
|
132
|
+
onClick: clickable ? handleClick : undefined,
|
|
133
|
+
interval: {
|
|
134
|
+
...int1,
|
|
135
|
+
id: i1,
|
|
136
|
+
name: unit.t_int_name,
|
|
137
|
+
},
|
|
138
|
+
prefix: p1,
|
|
139
|
+
}),
|
|
140
|
+
]),
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
|
|
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
|
+
|
|
154
|
+
return h("span.proportion", content);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function getAgeRange(_unit) {
|
|
158
|
+
let b_age = _unit.b_age;
|
|
159
|
+
let t_age = _unit.t_age;
|
|
160
|
+
let unit = "Ma";
|
|
161
|
+
|
|
162
|
+
if (b_age < 0.8 && t_age < 1.2) {
|
|
163
|
+
b_age *= 1000;
|
|
164
|
+
t_age *= 1000;
|
|
165
|
+
unit = "ka";
|
|
166
|
+
} else if (b_age > 800 && t_age > 1200) {
|
|
167
|
+
b_age /= 1000;
|
|
168
|
+
t_age /= 1000;
|
|
169
|
+
unit = "Ga";
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return [b_age, t_age, unit];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function getAge(value) {
|
|
176
|
+
/** Get the age value in Ma, ka, or Ga as appropriate */
|
|
177
|
+
let unit = "Ma";
|
|
178
|
+
if (value < 0.8) {
|
|
179
|
+
unit = "ka";
|
|
180
|
+
value *= 1000;
|
|
181
|
+
if (value < 5) {
|
|
182
|
+
unit = "yr";
|
|
183
|
+
value *= 1000;
|
|
184
|
+
}
|
|
185
|
+
} else if (value > 1000) {
|
|
186
|
+
unit = "Ga";
|
|
187
|
+
value /= 1000;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return [value, unit];
|
|
191
|
+
}
|
|
@@ -2,24 +2,22 @@ import hyper from "@macrostrat/hyper";
|
|
|
2
2
|
import styles from "./panel.module.sass";
|
|
3
3
|
import { JSONView } from "@macrostrat/ui-components";
|
|
4
4
|
import { Button, ButtonGroup } from "@blueprintjs/core";
|
|
5
|
-
import { ReactNode,
|
|
5
|
+
import { ReactNode, useMemo, useState } from "react";
|
|
6
6
|
import {
|
|
7
7
|
DataField,
|
|
8
8
|
EnvironmentsList,
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
isClickable,
|
|
10
|
+
ItemInteractionProps,
|
|
11
11
|
ItemList,
|
|
12
12
|
LithologyList,
|
|
13
13
|
LithologyTagFeature,
|
|
14
|
-
Parenthetical,
|
|
15
|
-
Value,
|
|
16
14
|
MacrostratInteractionManager,
|
|
17
|
-
useInteractionProps,
|
|
18
|
-
ItemInteractionProps,
|
|
19
|
-
useInteractionManager,
|
|
20
|
-
MacrostratItemIdentifier,
|
|
21
15
|
MacrostratInteractionProvider,
|
|
22
|
-
|
|
16
|
+
MacrostratItemIdentifier,
|
|
17
|
+
Parenthetical,
|
|
18
|
+
useInteractionManager,
|
|
19
|
+
useInteractionProps,
|
|
20
|
+
Value,
|
|
23
21
|
} from "@macrostrat/data-components";
|
|
24
22
|
import { useColumnUnitsMap } from "../data-provider";
|
|
25
23
|
import {
|
|
@@ -30,13 +28,15 @@ import {
|
|
|
30
28
|
} from "@macrostrat/data-provider";
|
|
31
29
|
import type {
|
|
32
30
|
Environment,
|
|
31
|
+
Interval,
|
|
32
|
+
Lithology,
|
|
33
33
|
UnitLong,
|
|
34
34
|
UnitLongFull,
|
|
35
|
-
Lithology,
|
|
36
|
-
Interval,
|
|
37
35
|
} from "@macrostrat/api-types";
|
|
38
36
|
import { defaultNameFunction } from "../units/names";
|
|
39
37
|
import classNames from "classnames";
|
|
38
|
+
import { AgeField, Duration, IntervalProportions } from "./age-range";
|
|
39
|
+
import { formatRange, formatSignificance } from "./utils.ts";
|
|
40
40
|
|
|
41
41
|
const h = hyper.styled(styles);
|
|
42
42
|
|
|
@@ -437,7 +437,7 @@ function getThickness(unit): [string, string] {
|
|
|
437
437
|
return [formatRange(minThickness, maxThickness), _unit];
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
function ThicknessField({ unit, label = "Thickness" }) {
|
|
440
|
+
export function ThicknessField({ unit, label = "Thickness" }) {
|
|
441
441
|
const [value, thicknessUnit] = getThickness(unit);
|
|
442
442
|
return h(DataField, {
|
|
443
443
|
label,
|
|
@@ -479,106 +479,6 @@ function Citation({ data, tag = "p" }) {
|
|
|
479
479
|
]);
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
-
function AgeField({ unit, children }) {
|
|
483
|
-
const [b_age, t_age, _unit] = getAgeRange(unit);
|
|
484
|
-
|
|
485
|
-
return h(
|
|
486
|
-
DataField,
|
|
487
|
-
{
|
|
488
|
-
label: "Age",
|
|
489
|
-
value: formatRange(b_age, t_age),
|
|
490
|
-
unit: _unit,
|
|
491
|
-
},
|
|
492
|
-
children,
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function getAgeRange(_unit) {
|
|
497
|
-
let b_age = _unit.b_age;
|
|
498
|
-
let t_age = _unit.t_age;
|
|
499
|
-
let unit = "Ma";
|
|
500
|
-
|
|
501
|
-
if (b_age < 0.8 && t_age < 1.2) {
|
|
502
|
-
b_age *= 1000;
|
|
503
|
-
t_age *= 1000;
|
|
504
|
-
unit = "ka";
|
|
505
|
-
} else if (b_age > 800 && t_age > 1200) {
|
|
506
|
-
b_age /= 1000;
|
|
507
|
-
t_age /= 1000;
|
|
508
|
-
unit = "Ga";
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
return [b_age, t_age, unit];
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
function getAge(value) {
|
|
515
|
-
/** Get the age value in Ma, ka, or Ga as appropriate */
|
|
516
|
-
let unit = "Ma";
|
|
517
|
-
if (value < 0.8) {
|
|
518
|
-
unit = "ka";
|
|
519
|
-
value *= 1000;
|
|
520
|
-
if (value < 5) {
|
|
521
|
-
unit = "yr";
|
|
522
|
-
value *= 1000;
|
|
523
|
-
}
|
|
524
|
-
} else if (value > 1000) {
|
|
525
|
-
unit = "Ga";
|
|
526
|
-
value /= 1000;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return [value, unit];
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
export function AgeLabel({
|
|
533
|
-
age,
|
|
534
|
-
maximumFractionDigits = 2,
|
|
535
|
-
minimumFractionDigits = 0,
|
|
536
|
-
className,
|
|
537
|
-
}: {
|
|
538
|
-
age: number;
|
|
539
|
-
className?: string;
|
|
540
|
-
maximumFractionDigits?: number;
|
|
541
|
-
minimumFractionDigits?: number;
|
|
542
|
-
}) {
|
|
543
|
-
/** Component to display a single age value with unit conversion from
|
|
544
|
-
* Ma to ka or Ga as appropriate.
|
|
545
|
-
*/
|
|
546
|
-
const [value, unit] = getAge(age);
|
|
547
|
-
|
|
548
|
-
const _value = value.toLocaleString("en-US", {
|
|
549
|
-
maximumFractionDigits,
|
|
550
|
-
minimumFractionDigits,
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
return h(Value, { value: _value, unit, className });
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
export function Duration({
|
|
557
|
-
value,
|
|
558
|
-
maximumFractionDigits = 2,
|
|
559
|
-
minimumFractionDigits = 0,
|
|
560
|
-
}) {
|
|
561
|
-
let unit = "Myr";
|
|
562
|
-
if (value < 0.8) {
|
|
563
|
-
unit = "kyr";
|
|
564
|
-
value *= 1000;
|
|
565
|
-
if (value < 5) {
|
|
566
|
-
unit = "yr";
|
|
567
|
-
value *= 1000;
|
|
568
|
-
}
|
|
569
|
-
} else if (value > 1000) {
|
|
570
|
-
unit = "Gyr";
|
|
571
|
-
value /= 1000;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
let _value = value.toLocaleString("en-US", {
|
|
575
|
-
maximumFractionDigits,
|
|
576
|
-
minimumFractionDigits,
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
return h(Value, { value: _value, unit });
|
|
580
|
-
}
|
|
581
|
-
|
|
582
482
|
function enhanceEnvironments(
|
|
583
483
|
environments: Partial<Environment>[] | null,
|
|
584
484
|
envMap: Map<number, Environment>,
|
|
@@ -711,117 +611,3 @@ function UnitIdentifier({
|
|
|
711
611
|
...interactionProps,
|
|
712
612
|
});
|
|
713
613
|
}
|
|
714
|
-
|
|
715
|
-
function IntervalProportions({ unit, onClickItem }) {
|
|
716
|
-
if (
|
|
717
|
-
unit.b_int_id == null &&
|
|
718
|
-
unit.t_int_id == null &&
|
|
719
|
-
unit.b_prop == null &&
|
|
720
|
-
unit.t_prop == null
|
|
721
|
-
)
|
|
722
|
-
return null;
|
|
723
|
-
|
|
724
|
-
const i0 = unit.b_int_id;
|
|
725
|
-
const i1 = unit.t_int_id;
|
|
726
|
-
let b_prop = unit.b_prop ?? 0;
|
|
727
|
-
let t_prop = unit.t_prop ?? 1;
|
|
728
|
-
|
|
729
|
-
const intervalMap = useMacrostratDefs("intervals");
|
|
730
|
-
const int0 = intervalMap?.get(i0) ?? {};
|
|
731
|
-
|
|
732
|
-
const interval0: IntervalShort = {
|
|
733
|
-
...int0,
|
|
734
|
-
id: i0,
|
|
735
|
-
name: unit.b_int_name,
|
|
736
|
-
};
|
|
737
|
-
|
|
738
|
-
let p0: ReactNode = null;
|
|
739
|
-
const int1 = intervalMap?.get(i1) ?? {};
|
|
740
|
-
const p1: ReactNode = h(Proportion, { value: t_prop });
|
|
741
|
-
|
|
742
|
-
if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {
|
|
743
|
-
// We have a single interval with undefined proportions
|
|
744
|
-
p0 = h(Proportion, { value: b_prop });
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
|
|
748
|
-
p0 = h("span.joint-proportion", [p0, h("span.sep", "to"), p1]);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
const clickable = onClickItem != null;
|
|
752
|
-
|
|
753
|
-
const handleClick = (event: MouseEvent) => {
|
|
754
|
-
if (onClickItem) {
|
|
755
|
-
onClickItem(event, interval0);
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
return h("div.interval-proportions", [
|
|
760
|
-
h(IntervalTag, {
|
|
761
|
-
className: clickable ? "clickable" : "",
|
|
762
|
-
onClick: clickable ? handleClick : undefined,
|
|
763
|
-
interval: interval0,
|
|
764
|
-
prefix: p0,
|
|
765
|
-
}),
|
|
766
|
-
h.if(i0 != i1)("span.discourage-break", [
|
|
767
|
-
h("span.sep", "to"),
|
|
768
|
-
h(IntervalTag, {
|
|
769
|
-
className: clickable ? "clickable" : "",
|
|
770
|
-
onClick: clickable ? handleClick : undefined,
|
|
771
|
-
interval: {
|
|
772
|
-
...int1,
|
|
773
|
-
id: i1,
|
|
774
|
-
name: unit.t_int_name,
|
|
775
|
-
},
|
|
776
|
-
prefix: p1,
|
|
777
|
-
}),
|
|
778
|
-
]),
|
|
779
|
-
]);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
const formatProportion = (d) => {
|
|
783
|
-
if (d == null) return null;
|
|
784
|
-
return d.toFixed(1);
|
|
785
|
-
};
|
|
786
|
-
|
|
787
|
-
function Proportion({ value }) {
|
|
788
|
-
let content = null;
|
|
789
|
-
if (value == 0) {
|
|
790
|
-
content = "base";
|
|
791
|
-
} else if (value == 1) {
|
|
792
|
-
content = "top";
|
|
793
|
-
} else {
|
|
794
|
-
content = formatProportion(value * 100) + "%";
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
return h("span.proportion", content);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
function formatRange(min, max, precision = null) {
|
|
801
|
-
if (min == null || max == null) return null;
|
|
802
|
-
if (min === max) {
|
|
803
|
-
return min.toFixed(precision);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
return `${formatSignificance(min, precision)}–${formatSignificance(
|
|
807
|
-
max,
|
|
808
|
-
precision,
|
|
809
|
-
)}`;
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function formatSignificance(value, precision = null) {
|
|
813
|
-
// Format to preserve a reasonable number of significant figures
|
|
814
|
-
// this could be done with an easier algorithm, probably:
|
|
815
|
-
|
|
816
|
-
if (precision == null) {
|
|
817
|
-
return value.toLocaleString();
|
|
818
|
-
}
|
|
819
|
-
if (precision >= 0) {
|
|
820
|
-
return value.toFixed(precision);
|
|
821
|
-
}
|
|
822
|
-
if (precision < 0) {
|
|
823
|
-
return (
|
|
824
|
-
(value / Math.pow(10, -precision)).toFixed(0) + "0".repeat(-precision)
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const formatProportion = (d) => {
|
|
2
|
+
if (d == null) return null;
|
|
3
|
+
return d.toFixed(1);
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export function formatRange(min, max, precision = null) {
|
|
7
|
+
if (min == null || max == null) return null;
|
|
8
|
+
if (min === max) {
|
|
9
|
+
return min.toFixed(precision);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return `${formatSignificance(min, precision)}–${formatSignificance(
|
|
13
|
+
max,
|
|
14
|
+
precision,
|
|
15
|
+
)}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function formatSignificance(value, precision = null) {
|
|
19
|
+
// Format to preserve a reasonable number of significant figures
|
|
20
|
+
// this could be done with an easier algorithm, probably:
|
|
21
|
+
|
|
22
|
+
if (precision == null) {
|
|
23
|
+
return value.toLocaleString();
|
|
24
|
+
}
|
|
25
|
+
if (precision >= 0) {
|
|
26
|
+
return value.toFixed(precision);
|
|
27
|
+
}
|
|
28
|
+
if (precision < 0) {
|
|
29
|
+
return (
|
|
30
|
+
(value / Math.pow(10, -precision)).toFixed(0) + "0".repeat(-precision)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|