@macrostrat/column-views 3.2.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/index.cjs +15 -9
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.js +11 -5
  5. package/dist/maps/column-correlation/core.cjs +10 -30
  6. package/dist/maps/column-correlation/core.cjs.map +1 -1
  7. package/dist/maps/column-correlation/core.d.ts +1 -1
  8. package/dist/maps/column-correlation/core.js +10 -30
  9. package/dist/maps/column-correlation/core.js.map +1 -1
  10. package/dist/maps/column-navigation/mapbox/index.cjs +156 -118
  11. package/dist/maps/column-navigation/mapbox/index.cjs.map +1 -1
  12. package/dist/maps/column-navigation/mapbox/index.d.ts +23 -2
  13. package/dist/maps/column-navigation/mapbox/index.js +158 -120
  14. package/dist/maps/column-navigation/mapbox/index.js.map +1 -1
  15. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs +7 -1
  16. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs.map +1 -1
  17. package/dist/maps/column-navigation/mapbox/keyboard-navigation.d.ts +3 -26
  18. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js +9 -3
  19. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js.map +1 -1
  20. package/dist/maps/index.d.ts +2 -2
  21. package/dist/maps/{_shared/inset-map.cjs → inset-map/index.cjs} +1 -1
  22. package/dist/maps/inset-map/index.cjs.map +1 -0
  23. package/dist/maps/{_shared/inset-map.js → inset-map/index.js} +1 -1
  24. package/dist/maps/inset-map/index.js.map +1 -0
  25. package/dist/maps/layers/columns.cjs +161 -0
  26. package/dist/maps/layers/columns.cjs.map +1 -0
  27. package/dist/maps/layers/columns.d.ts +28 -0
  28. package/dist/maps/layers/columns.js +161 -0
  29. package/dist/maps/layers/columns.js.map +1 -0
  30. package/dist/maps/layers/index.d.ts +2 -0
  31. package/dist/maps/{units-overlay/index.cjs → layers/units.cjs} +41 -88
  32. package/dist/maps/layers/units.cjs.map +1 -0
  33. package/dist/maps/{units-overlay/index.d.ts → layers/units.d.ts} +1 -1
  34. package/dist/maps/{units-overlay/index.js → layers/units.js} +34 -82
  35. package/dist/maps/layers/units.js.map +1 -0
  36. package/dist/unit-details/age-range.cjs +87 -44
  37. package/dist/unit-details/age-range.cjs.map +1 -1
  38. package/dist/unit-details/age-range.d.ts +32 -5
  39. package/dist/unit-details/age-range.js +85 -44
  40. package/dist/unit-details/age-range.js.map +1 -1
  41. package/package.json +4 -4
  42. package/src/maps/column-correlation/core.ts +9 -29
  43. package/src/maps/column-navigation/mapbox/index.ts +191 -138
  44. package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +17 -3
  45. package/src/maps/index.ts +2 -2
  46. package/src/maps/layers/columns.ts +210 -0
  47. package/src/maps/layers/index.ts +2 -0
  48. package/src/maps/{units-overlay/index.ts → layers/units.ts} +34 -84
  49. package/src/maps/unit-map.stories.ts +27 -12
  50. package/src/unit-details/age-range.ts +125 -47
  51. package/dist/maps/_shared/index.d.ts +0 -2
  52. package/dist/maps/_shared/inset-map.cjs.map +0 -1
  53. package/dist/maps/_shared/inset-map.js.map +0 -1
  54. package/dist/maps/_shared/styles.cjs +0 -73
  55. package/dist/maps/_shared/styles.cjs.map +0 -1
  56. package/dist/maps/_shared/styles.d.ts +0 -2
  57. package/dist/maps/_shared/styles.js +0 -73
  58. package/dist/maps/_shared/styles.js.map +0 -1
  59. package/dist/maps/units-overlay/index.cjs.map +0 -1
  60. package/dist/maps/units-overlay/index.js.map +0 -1
  61. package/src/maps/_shared/index.ts +0 -2
  62. package/src/maps/_shared/styles.ts +0 -76
  63. /package/dist/maps/{_shared/inset-map.d.ts → inset-map/index.d.ts} +0 -0
  64. /package/src/maps/{_shared/inset-map.ts → inset-map/index.ts} +0 -0
  65. /package/src/maps/{_shared → inset-map}/inset-map.stories.ts +0 -0
@@ -0,0 +1,210 @@
1
+ import { useMapStyleOperator, useOverlayStyle } from "@macrostrat/mapbox-react";
2
+ import { setGeoJSON } from "@macrostrat/mapbox-utils";
3
+ import GeoJSON, { FeatureCollection } from "geojson";
4
+ import { GeoJSONFeature } from "mapbox-gl";
5
+ import { getCSSVariable } from "@macrostrat/color-utils";
6
+ import { buildGeoJSONSource } from "@macrostrat/mapbox-utils";
7
+ import { StyleFragment } from "@macrostrat/mapbox-react";
8
+
9
+ export interface ColumnsStyleOptions {
10
+ color?: string | any[];
11
+ selectedColor?: string | any[];
12
+ opacity?: number | any[];
13
+ circleRadius?: number | any[];
14
+ lineOpacity?: number | any[];
15
+ lineWidth?: number | any[];
16
+ lineColor?: string | any[];
17
+ }
18
+
19
+ interface ColumnLayerOptions extends ColumnsStyleOptions {
20
+ enabled: boolean;
21
+ columns: FeatureCollection | GeoJSONFeature[];
22
+ }
23
+
24
+ export function BaseColumnsLayer({
25
+ enabled = true,
26
+ columns,
27
+ ...rest
28
+ }: ColumnLayerOptions) {
29
+ useOverlayStyle(() => (enabled ? buildColumnsStyle(rest) : null), [enabled]);
30
+
31
+ useMapStyleOperator(
32
+ (map) => {
33
+ if (columns == null) {
34
+ return;
35
+ }
36
+
37
+ setGeoJSON(map, "columns", promoteToFeatureCollection(columns));
38
+ },
39
+ [columns, enabled],
40
+ );
41
+ return null;
42
+ }
43
+
44
+ function promoteToFeatureCollection(
45
+ data: FeatureCollection | GeoJSONFeature | GeoJSONFeature[] | null,
46
+ ): FeatureCollection | null {
47
+ if (data == null) return null;
48
+ if ("type" in data && data.type == "Feature") {
49
+ return {
50
+ type: "FeatureCollection",
51
+ features: [data],
52
+ };
53
+ }
54
+ if (
55
+ "type" in data &&
56
+ data.type == "FeatureCollection" &&
57
+ "features" in data
58
+ ) {
59
+ return data;
60
+ }
61
+ return {
62
+ type: "FeatureCollection",
63
+ features: data,
64
+ };
65
+ }
66
+
67
+ export function buildColumnsStyle(
68
+ opts: ColumnsStyleOptions = {},
69
+ ): StyleFragment {
70
+ const { color } = opts;
71
+ const columnBaseColor =
72
+ color ?? getCSSVariable("--text-subtle-color", "black");
73
+ let columnColor: any = columnBaseColor;
74
+ const columnSelectedColor =
75
+ opts.selectedColor ?? getCSSVariable("--selection-color", "purple");
76
+
77
+ const lineColor = opts.lineColor ?? columnBaseColor;
78
+ const isHovered = ["boolean", ["feature-state", "hover"], false];
79
+ // If color is in the feature state or geojson properties, use that as second choice
80
+ if (typeof columnColor === "string") {
81
+ columnColor = [
82
+ "coalesce",
83
+ ["feature-state", "color"],
84
+ ["get", "color"],
85
+ columnColor,
86
+ ];
87
+ }
88
+
89
+ const fillOpacity = opts.opacity ?? 0.1;
90
+
91
+ const lineOpacity = opts.lineOpacity ?? 0.5;
92
+ const lineWidth = opts.lineWidth ?? 2;
93
+
94
+ const circleRadius = opts.circleRadius ?? 4;
95
+
96
+ return {
97
+ sources: {
98
+ columns: buildGeoJSONSource(),
99
+ },
100
+ version: 8,
101
+ layers: [
102
+ {
103
+ id: "columns-fill",
104
+ type: "fill",
105
+ source: "columns",
106
+ paint: {
107
+ "fill-color": columnColor,
108
+ "fill-opacity": fillOpacity,
109
+ },
110
+ },
111
+ {
112
+ id: "columns-points",
113
+ type: "circle",
114
+ source: "columns",
115
+ paint: {
116
+ "circle-radius": circleRadius,
117
+ "circle-color": columnColor,
118
+ "circle-opacity": fillOpacity,
119
+ },
120
+ filter: ["==", "$type", "Point"],
121
+ },
122
+ {
123
+ id: "columns-line",
124
+ type: "line",
125
+ source: "columns",
126
+ paint: {
127
+ "line-color": ["case", isHovered, columnSelectedColor, lineColor],
128
+ "line-width": lineWidth,
129
+ "line-opacity": ["case", isHovered, 1.0, lineOpacity],
130
+ },
131
+ },
132
+ ],
133
+ };
134
+ }
135
+
136
+ export type ColumnFeature = GeoJSON.Feature & { id: number };
137
+
138
+ const selectedColumnSourceID = "selectedColumn";
139
+
140
+ export function SelectedColumnOverlay({
141
+ selectedColumn,
142
+ ...styleOpts
143
+ }: { selectedColumn: ColumnFeature | null } & SelectedColumnStyleOpts) {
144
+ useOverlayStyle(() => buildSelectedColumnStyle(styleOpts), []);
145
+
146
+ useMapStyleOperator(
147
+ (map) => {
148
+ setGeoJSON(
149
+ map,
150
+ selectedColumnSourceID,
151
+ promoteToFeatureCollection(selectedColumn as GeoJSONFeature | null),
152
+ );
153
+ },
154
+ [selectedColumn],
155
+ );
156
+
157
+ return null;
158
+ }
159
+
160
+ interface SelectedColumnStyleOpts {
161
+ color?: string | any[];
162
+ }
163
+
164
+ function buildSelectedColumnStyle(
165
+ opts: SelectedColumnStyleOpts = {},
166
+ ): StyleFragment {
167
+ const columnSelectedColor: any =
168
+ opts.color ?? getCSSVariable("--selection-color", "purple");
169
+
170
+ return {
171
+ sources: {
172
+ selectedColumn: buildGeoJSONSource(),
173
+ },
174
+ version: 8,
175
+ layers: [
176
+ {
177
+ id: "selected-column-highlight",
178
+ type: "fill",
179
+ source: selectedColumnSourceID,
180
+ paint: {
181
+ "fill-color": columnSelectedColor,
182
+ "fill-opacity": 0.5,
183
+ },
184
+ filter: ["==", "$type", "Polygon"],
185
+ },
186
+ {
187
+ id: "selected-column-edge",
188
+ type: "line",
189
+ source: selectedColumnSourceID,
190
+ paint: {
191
+ "line-color": columnSelectedColor,
192
+ "line-width": 2,
193
+ "line-opacity": 1.0,
194
+ },
195
+ filter: ["==", "$type", "Polygon"],
196
+ },
197
+ {
198
+ id: "selected-column-point",
199
+ type: "circle",
200
+ source: selectedColumnSourceID,
201
+ paint: {
202
+ "circle-radius": 6,
203
+ "circle-color": columnSelectedColor,
204
+ "circle-opacity": 1.0,
205
+ },
206
+ filter: ["==", "$type", "Point"],
207
+ },
208
+ ],
209
+ };
210
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./columns";
2
+ export * from "./units";
@@ -3,7 +3,7 @@ import {
3
3
  useMacrostratColumns,
4
4
  } from "@macrostrat/data-provider";
5
5
  import { useAPIResult } from "@macrostrat/ui-components";
6
- import { useMapStyleOperator } from "@macrostrat/mapbox-react";
6
+ import { useMapStyleOperator, useOverlayStyle } from "@macrostrat/mapbox-react";
7
7
  import { FeatureCollection } from "geojson";
8
8
  import { useMemo } from "react";
9
9
  import { mergeStyles, setGeoJSON } from "@macrostrat/mapbox-utils";
@@ -15,9 +15,11 @@ import {
15
15
  loadStyleImage,
16
16
  StyleFragment,
17
17
  } from "@macrostrat/map-styles";
18
- import { asChromaColor, getCSSVariable } from "@macrostrat/color-utils";
18
+ import { asChromaColor } from "@macrostrat/color-utils";
19
19
  import { buildGeoJSONSource } from "@macrostrat/mapbox-utils";
20
20
  import pMap from "p-map";
21
+ import { BaseColumnsLayer } from "./columns";
22
+ import h from "@macrostrat/hyper";
21
23
 
22
24
  export interface UnitsOverlayProps {
23
25
  time: number;
@@ -30,6 +32,10 @@ export function MacrostratUnitsOverlay(props: UnitsOverlayProps) {
30
32
  const { time, ageSpan = 0.05, patterns = false } = props;
31
33
  const lithMap = useLithologies();
32
34
 
35
+ useOverlayStyle(() => {
36
+ return buildUnitsStyle({ patterns });
37
+ }, [patterns]);
38
+
33
39
  useMapStyleOperator(
34
40
  (map) => {
35
41
  if (!patterns) return;
@@ -60,21 +66,6 @@ export function MacrostratUnitsOverlay(props: UnitsOverlayProps) {
60
66
  const units: UnitLong[] = useAPIResult("/units", params);
61
67
  const columns = useMacrostratColumns(params.project, false);
62
68
 
63
- // Set up basic columns layer
64
- useMapStyleOperator(
65
- (map) => {
66
- if (columns == null) {
67
- return;
68
- }
69
- const data: FeatureCollection = {
70
- type: "FeatureCollection",
71
- features: columns,
72
- };
73
- setGeoJSON(map, "columns", data);
74
- },
75
- [columns],
76
- );
77
-
78
69
  useMapStyleOperator(
79
70
  (map) => {
80
71
  if (units == null || columns == null || lithMap == null) {
@@ -99,7 +90,30 @@ export function MacrostratUnitsOverlay(props: UnitsOverlayProps) {
99
90
  [units, lithMap, columns, patterns],
100
91
  );
101
92
 
102
- return null;
93
+ const isHovered = ["boolean", ["feature-state", "hover"], false];
94
+ const isShown = ["boolean", ["feature-state", "shown"], false];
95
+
96
+ const opacity = [
97
+ "case",
98
+ ["all", isHovered, isShown],
99
+ 0.9,
100
+ isShown,
101
+ 0.8,
102
+ isHovered,
103
+ 0.3,
104
+ 0.0,
105
+ ];
106
+
107
+ return h([
108
+ h(BaseColumnsLayer, {
109
+ enabled: true,
110
+ columns,
111
+ opacity,
112
+ lineOpacity: 0.2,
113
+ lineColor: "lightgray",
114
+ color: "transparent",
115
+ }),
116
+ ]);
103
117
  }
104
118
 
105
119
  function handleUnitsLayerUpdate(
@@ -238,77 +252,13 @@ type UnitsStyleOptions = {
238
252
  };
239
253
 
240
254
  export function buildUnitsStyle(opts: UnitsStyleOptions = {}): StyleFragment {
241
- const { color = null, patterns = false } = opts;
242
-
243
- let columnBaseColor: any =
244
- color ?? getCSSVariable("--text-subtle-color", "black");
245
- const columnSelectedColor = getCSSVariable("--selection-color", "purple");
255
+ const { patterns = false } = opts;
246
256
 
247
257
  // If color is in the feature state or geojson properties, use that as second choice
248
258
 
249
- let columnColor: any = [
250
- "coalesce",
251
- ["feature-state", "color"],
252
- ["get", "color"],
253
- columnBaseColor,
254
- ];
255
-
256
259
  const baseStyle: StyleFragment = {
257
- sources: {
258
- columns: buildGeoJSONSource(),
259
- },
260
+ sources: {},
260
261
  version: 8,
261
- layers: [
262
- {
263
- id: "columns-fill",
264
- type: "fill",
265
- source: "columns",
266
- paint: {
267
- "fill-color": columnColor,
268
- "fill-opacity": [
269
- "case",
270
- ["boolean", ["feature-state", "shown"], false],
271
- 0.8,
272
- ["boolean", ["feature-state", "hover"], false],
273
- 0.3,
274
- 0.1,
275
- ],
276
- },
277
- },
278
- {
279
- id: "columns-line",
280
- type: "line",
281
- source: "columns",
282
- paint: {
283
- "line-color": columnColor,
284
- "line-width": 1,
285
- "line-opacity": 0.5,
286
- },
287
- },
288
- {
289
- id: "columns-points",
290
- type: "circle",
291
- source: "columns",
292
- paint: {
293
- "circle-radius": 4,
294
- "circle-color": [
295
- "case",
296
- ["boolean", ["feature-state", "shown"], false],
297
- columnColor,
298
- columnBaseColor,
299
- ],
300
- "circle-opacity": [
301
- "case",
302
- ["boolean", ["feature-state", "shown"], false],
303
- 0.8,
304
- ["boolean", ["feature-state", "hover"], false],
305
- 0.3,
306
- 0.1,
307
- ],
308
- },
309
- filter: ["==", "$type", "Point"],
310
- },
311
- ],
312
262
  };
313
263
 
314
264
  if (!patterns) {
@@ -1,9 +1,13 @@
1
1
  import h from "@macrostrat/hyper";
2
2
  import { Meta } from "@storybook/react-vite";
3
- import { InsetMap } from "./_shared";
3
+ import { InsetMap } from "./inset-map";
4
4
  import { MacrostratDataProvider } from "@macrostrat/data-provider";
5
- import { useMemo } from "react";
6
- import { buildUnitsStyle, MacrostratUnitsOverlay } from "./units-overlay";
5
+ import { MacrostratUnitsOverlay } from "./layers/units";
6
+ import {
7
+ ColumnHoverInteraction,
8
+ ColumnSelectionManager,
9
+ } from "./column-navigation";
10
+ import { useState } from "react";
7
11
 
8
12
  // @ts-ignore
9
13
  const mapboxToken = import.meta.env.VITE_MAPBOX_API_TOKEN;
@@ -21,13 +25,7 @@ export default {
21
25
  } as Meta<typeof InsetMap>;
22
26
 
23
27
  function UnitMapComponent(props) {
24
- const overlayStyles = useMemo(() => {
25
- let styles: any[] = [
26
- buildUnitsStyle({ color: "#444", patterns: props.patterns }),
27
- ];
28
- return styles;
29
- }, []);
30
-
28
+ const { children, ...rest } = props;
31
29
  return h(
32
30
  MacrostratDataProvider,
33
31
  {
@@ -40,9 +38,8 @@ function UnitMapComponent(props) {
40
38
  {
41
39
  style: { width: "800px", height: "600px" },
42
40
  accessToken: mapboxToken,
43
- overlayStyles,
44
41
  },
45
- h(MacrostratUnitsOverlay, props),
42
+ [h(MacrostratUnitsOverlay, rest), children],
46
43
  ),
47
44
  ),
48
45
  );
@@ -62,3 +59,21 @@ export const WithPatterns = {
62
59
  patterns: true,
63
60
  },
64
61
  };
62
+
63
+ export const WithColumnSelection = {
64
+ args: {
65
+ time: 100,
66
+ ageSpan: 0.05,
67
+ patterns: false,
68
+ },
69
+ render(args) {
70
+ const [selectedColumn, setSelectedColumn] = useState(null);
71
+ return h(UnitMapComponent, args, [
72
+ h(ColumnHoverInteraction),
73
+ h(ColumnSelectionManager, {
74
+ selectedColumn,
75
+ onSelectColumn: setSelectedColumn,
76
+ }),
77
+ ]);
78
+ },
79
+ };
@@ -2,27 +2,50 @@ import {
2
2
  DataField,
3
3
  IntervalShort,
4
4
  IntervalTag,
5
+ type IntervalTagProps,
5
6
  ItemList,
6
7
  Value,
7
8
  } from "@macrostrat/data-components";
8
9
  import { useMacrostratDefs } from "@macrostrat/data-provider";
9
10
  import h from "./age-range.module.sass";
10
11
  import { formatProportion, formatRange } from "./utils";
12
+ import classNames from "classnames";
13
+ import { useMemo } from "react";
11
14
 
12
- export function AgeField({ unit, children }) {
13
- const [b_age, t_age, _unit] = getAgeRange(unit);
15
+ export function AgeField({ unit, children, ...rest }) {
16
+ const [_b_age, _t_age, _unit] = getAgeRange(unit);
14
17
 
15
18
  return h(
16
19
  DataField,
17
20
  {
18
21
  label: "Age",
19
- value: formatRange(b_age, t_age),
22
+ value: formatRange(_b_age, _t_age),
20
23
  unit: _unit,
24
+ ...rest,
21
25
  },
22
26
  children,
23
27
  );
24
28
  }
25
29
 
30
+ export function AgeRange({
31
+ data,
32
+ className,
33
+ }: {
34
+ data: {
35
+ t_age: number;
36
+ b_age: number;
37
+ };
38
+ className?: string;
39
+ }) {
40
+ const [_b_age, _t_age, _unit] = getAgeRange(data);
41
+
42
+ return h(Value, {
43
+ value: formatRange(_b_age, _t_age),
44
+ unit: _unit,
45
+ className,
46
+ });
47
+ }
48
+
26
49
  export function AgeLabel({
27
50
  age,
28
51
  maximumFractionDigits = 2,
@@ -73,72 +96,127 @@ export function Duration({
73
96
  return h(Value, { value: _value, unit });
74
97
  }
75
98
 
76
- export function IntervalProportions({ unit, onClickItem }) {
99
+ interface UnitIntervalConstraints {
100
+ b_int_id?: number;
101
+ t_int_id?: number;
102
+ b_prop?: number;
103
+ t_prop?: number;
104
+ b_int_name?: string;
105
+ t_int_name?: string;
106
+ b_age?: number;
107
+ t_age?: number;
108
+ }
109
+
110
+ export interface IntervalProportionsProps extends Omit<
111
+ IntervalTagProps,
112
+ "interval"
113
+ > {
114
+ unit: UnitIntervalConstraints;
115
+ showProportions?: boolean;
116
+ calculateProportionsFromAges?: boolean;
117
+ }
118
+
119
+ export function IntervalProportions({
120
+ unit,
121
+ className,
122
+ showProportions,
123
+ calculateProportionsFromAges = true,
124
+ ...rest
125
+ }: IntervalProportionsProps) {
77
126
  /** 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;
127
+ if (unit.b_int_id == null && unit.t_int_id == null) return null;
128
+
129
+ let _showProps = showProportions;
85
130
 
86
131
  const i0 = unit.b_int_id;
87
132
  const i1 = unit.t_int_id;
88
- let b_prop = unit.b_prop ?? 0;
89
- let t_prop = unit.t_prop ?? 1;
90
133
 
134
+ /** Get interval information */
91
135
  const intervalMap = useMacrostratDefs("intervals");
92
- const int0 = intervalMap?.get(i0) ?? {};
136
+ const [int0, int1] = useMemo(() => {
137
+ const int0 = intervalMap?.get(i0) ?? {};
138
+ if (i0 === i1) {
139
+ return [int0, int0];
140
+ }
141
+ const int1 = intervalMap?.get(i1) ?? {};
142
+ return [int0, int1];
143
+ }, [intervalMap, i0, i1]);
93
144
 
94
145
  const interval0: IntervalShort = {
95
- ...int0,
96
146
  id: i0,
97
147
  name: unit.b_int_name,
148
+ ...int0,
98
149
  };
99
150
 
100
- let p0: any = null;
101
- const int1 = intervalMap?.get(i1) ?? {};
102
- const p1: any = h(Proportion, { value: t_prop });
151
+ let b_prop = unit.b_prop;
152
+ let t_prop = unit.t_prop;
103
153
 
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 });
154
+ // If we have b_age and t_age, then we can calculate proportions if they are not given
155
+ if (b_prop == null && unit.b_age != null && calculateProportionsFromAges) {
156
+ b_prop = getProportion(unit.b_age, int0);
157
+ }
158
+ if (t_prop == null && unit.t_age != null && calculateProportionsFromAges) {
159
+ t_prop = getProportion(unit.t_age, int1);
107
160
  }
108
161
 
109
- if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
110
- p0 = h("span.joint-proportion", [p0, " ", h("span.sep", "to"), " ", p1]);
162
+ // If there are no proportions given and we are not explicitly directed to show them,
163
+ // then we set them to hidden.
164
+ if (b_prop == null && t_prop == null) {
165
+ _showProps ??= false;
111
166
  }
112
167
 
113
- const clickable = onClickItem != null;
168
+ /*
169
+ Set default proportions to 0 and 1 if they are not given,
170
+ so that we can display "base" and "top" labels
171
+ */
172
+ b_prop ??= 0;
173
+ t_prop ??= 1;
174
+
175
+ let p0: any = null;
176
+ let p1: any = null;
177
+
178
+ if (_showProps !== false) {
179
+ p1 = h(Proportion, { value: t_prop });
114
180
 
115
- const handleClick = (event: MouseEvent) => {
116
- if (onClickItem) {
117
- onClickItem(event, interval0);
181
+ if (i0 !== i1 || b_prop !== 0 || t_prop !== 1) {
182
+ // We have a single interval with undefined proportions
183
+ p0 = h(Proportion, { value: b_prop });
118
184
  }
119
- };
120
185
 
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 "),
186
+ if (i0 === i1 && (b_prop !== 0 || t_prop !== 1)) {
187
+ p0 = h("span.joint-proportion", [p0, " ", h("span.sep", "to"), " ", p1]);
188
+ }
189
+ }
190
+
191
+ return h(
192
+ ItemList,
193
+ { className: classNames("interval-proportions", className) },
194
+ [
130
195
  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,
196
+ interval: interval0,
197
+ prefix: p0,
198
+ ...rest,
139
199
  }),
140
- ]),
141
- ]);
200
+ h.if(i0 != i1)("span.discourage-break", [
201
+ h("span.sep", " to "),
202
+ h(IntervalTag, {
203
+ interval: {
204
+ id: i1,
205
+ name: unit.t_int_name,
206
+ ...int1,
207
+ },
208
+ prefix: p1,
209
+ ...rest,
210
+ }),
211
+ ]),
212
+ ],
213
+ );
214
+ }
215
+
216
+ function getProportion(age: number, interval: IntervalShort): number | null {
217
+ /** Get proportion with the age */
218
+ console.log(age, interval);
219
+ return (interval.b_age - age) / (interval.b_age - interval.t_age);
142
220
  }
143
221
 
144
222
  function Proportion({ value }) {
@@ -1,2 +0,0 @@
1
- export * from './inset-map';
2
- export * from './styles';
@@ -1 +0,0 @@
1
- {"version":3,"file":"inset-map.cjs","sources":["../../../src/maps/_shared/inset-map.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n MapView,\n getBasicMapStyle,\n MapViewProps,\n} from \"@macrostrat/map-interface\";\nimport h from \"@macrostrat/hyper\";\nimport { MapboxMapProvider } from \"@macrostrat/mapbox-react\";\nimport { useInDarkMode } from \"@macrostrat/ui-components\";\nimport {\n removeMapLabels,\n removeSourceFromStyle,\n} from \"@macrostrat/mapbox-utils\";\nimport type { ReactNode, CSSProperties } from \"react\";\n\nexport interface InsetMapProps extends Omit<MapViewProps, \"style\"> {\n controls?: ReactNode;\n className?: string;\n children?: ReactNode;\n style?: CSSProperties;\n mapStyle?: mapboxgl.Style | string;\n showLabels?: boolean;\n showAdmin?: boolean;\n showRoads?: boolean;\n}\n\nexport function InsetMap({\n controls,\n className,\n children,\n style,\n mapStyle,\n accessToken,\n showLabels = false,\n showAdmin = false,\n showRoads = false,\n ...rest\n}: InsetMapProps) {\n const inDarkMode = useInDarkMode();\n const _style = useMemo((): mapboxgl.Style | string => {\n return mapStyle ?? getBasicMapStyle({ inDarkMode });\n }, [mapStyle, inDarkMode]);\n\n const transformStyle = useCallback(\n (style) => {\n let newStyle = style;\n if (!showLabels) {\n newStyle = removeMapLabels(newStyle);\n }\n if (!showAdmin) {\n newStyle = removeSourceFromStyle(newStyle, null, \"admin\");\n }\n if (!showRoads) {\n newStyle = removeSourceFromStyle(newStyle, null, \"road\");\n newStyle = removeSourceFromStyle(newStyle, null, \"aeroway\");\n }\n return newStyle;\n },\n [mapStyle, showLabels, showRoads, showAdmin],\n );\n\n return h(\"div.inset-map\", { className, style }, [\n h(MapboxMapProvider, [\n controls,\n h(\n MapView,\n {\n style: _style,\n accessToken,\n standalone: true,\n /* Default map position that centers on the bulk of Macrostrat columns\n */\n mapPosition: {\n camera: {\n lng: -100,\n lat: 38,\n altitude: 5000000,\n },\n },\n transformStyle,\n ...rest,\n },\n children,\n ),\n ]),\n ]);\n}\n"],"names":["useInDarkMode","useMemo","getBasicMapStyle","useCallback","style","removeMapLabels","removeSourceFromStyle","h","MapboxMapProvider","MapView"],"mappings":";;;;;;;;;;AA0BO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,GAAG;AACL,GAAkB;AAChB,QAAM,aAAaA,aAAAA,cAAA;AACnB,QAAM,SAASC,MAAAA,QAAQ,MAA+B;AACpD,WAAO,YAAYC,aAAAA,iBAAiB,EAAE,YAAY;AAAA,EACpD,GAAG,CAAC,UAAU,UAAU,CAAC;AAEzB,QAAM,iBAAiBC,MAAAA;AAAAA,IACrB,CAACC,WAAU;AACT,UAAI,WAAWA;AACf,UAAI,CAAC,YAAY;AACf,mBAAWC,YAAAA,gBAAgB,QAAQ;AAAA,MACrC;AACA,UAAI,CAAC,WAAW;AACd,mBAAWC,YAAAA,sBAAsB,UAAU,MAAM,OAAO;AAAA,MAC1D;AACA,UAAI,CAAC,WAAW;AACd,mBAAWA,YAAAA,sBAAsB,UAAU,MAAM,MAAM;AACvD,mBAAWA,YAAAA,sBAAsB,UAAU,MAAM,SAAS;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,UAAU,YAAY,WAAW,SAAS;AAAA,EAAA;AAG7C,SAAOC,WAAAA,QAAE,iBAAiB,EAAE,WAAW,SAAS;AAAA,IAC9CA,WAAAA,QAAEC,YAAAA,mBAAmB;AAAA,MACnB;AAAA,MACAD,WAAAA;AAAAA,QACEE,aAAAA;AAAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP;AAAA,UACA,YAAY;AAAA;AAAA;AAAA,UAGZ,aAAa;AAAA,YACX,QAAQ;AAAA,cACN,KAAK;AAAA,cACL,KAAK;AAAA,cACL,UAAU;AAAA,YAAA;AAAA,UACZ;AAAA,UAEF;AAAA,UACA,GAAG;AAAA,QAAA;AAAA,QAEL;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EAAA,CACF;AACH;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"inset-map.js","sources":["../../../src/maps/_shared/inset-map.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n MapView,\n getBasicMapStyle,\n MapViewProps,\n} from \"@macrostrat/map-interface\";\nimport h from \"@macrostrat/hyper\";\nimport { MapboxMapProvider } from \"@macrostrat/mapbox-react\";\nimport { useInDarkMode } from \"@macrostrat/ui-components\";\nimport {\n removeMapLabels,\n removeSourceFromStyle,\n} from \"@macrostrat/mapbox-utils\";\nimport type { ReactNode, CSSProperties } from \"react\";\n\nexport interface InsetMapProps extends Omit<MapViewProps, \"style\"> {\n controls?: ReactNode;\n className?: string;\n children?: ReactNode;\n style?: CSSProperties;\n mapStyle?: mapboxgl.Style | string;\n showLabels?: boolean;\n showAdmin?: boolean;\n showRoads?: boolean;\n}\n\nexport function InsetMap({\n controls,\n className,\n children,\n style,\n mapStyle,\n accessToken,\n showLabels = false,\n showAdmin = false,\n showRoads = false,\n ...rest\n}: InsetMapProps) {\n const inDarkMode = useInDarkMode();\n const _style = useMemo((): mapboxgl.Style | string => {\n return mapStyle ?? getBasicMapStyle({ inDarkMode });\n }, [mapStyle, inDarkMode]);\n\n const transformStyle = useCallback(\n (style) => {\n let newStyle = style;\n if (!showLabels) {\n newStyle = removeMapLabels(newStyle);\n }\n if (!showAdmin) {\n newStyle = removeSourceFromStyle(newStyle, null, \"admin\");\n }\n if (!showRoads) {\n newStyle = removeSourceFromStyle(newStyle, null, \"road\");\n newStyle = removeSourceFromStyle(newStyle, null, \"aeroway\");\n }\n return newStyle;\n },\n [mapStyle, showLabels, showRoads, showAdmin],\n );\n\n return h(\"div.inset-map\", { className, style }, [\n h(MapboxMapProvider, [\n controls,\n h(\n MapView,\n {\n style: _style,\n accessToken,\n standalone: true,\n /* Default map position that centers on the bulk of Macrostrat columns\n */\n mapPosition: {\n camera: {\n lng: -100,\n lat: 38,\n altitude: 5000000,\n },\n },\n transformStyle,\n ...rest,\n },\n children,\n ),\n ]),\n ]);\n}\n"],"names":["style"],"mappings":";;;;;;AA0BO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,GAAG;AACL,GAAkB;AAChB,QAAM,aAAa,cAAA;AACnB,QAAM,SAAS,QAAQ,MAA+B;AACpD,WAAO,YAAY,iBAAiB,EAAE,YAAY;AAAA,EACpD,GAAG,CAAC,UAAU,UAAU,CAAC;AAEzB,QAAM,iBAAiB;AAAA,IACrB,CAACA,WAAU;AACT,UAAI,WAAWA;AACf,UAAI,CAAC,YAAY;AACf,mBAAW,gBAAgB,QAAQ;AAAA,MACrC;AACA,UAAI,CAAC,WAAW;AACd,mBAAW,sBAAsB,UAAU,MAAM,OAAO;AAAA,MAC1D;AACA,UAAI,CAAC,WAAW;AACd,mBAAW,sBAAsB,UAAU,MAAM,MAAM;AACvD,mBAAW,sBAAsB,UAAU,MAAM,SAAS;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,UAAU,YAAY,WAAW,SAAS;AAAA,EAAA;AAG7C,SAAO,EAAE,iBAAiB,EAAE,WAAW,SAAS;AAAA,IAC9C,EAAE,mBAAmB;AAAA,MACnB;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP;AAAA,UACA,YAAY;AAAA;AAAA;AAAA,UAGZ,aAAa;AAAA,YACX,QAAQ;AAAA,cACN,KAAK;AAAA,cACL,KAAK;AAAA,cACL,UAAU;AAAA,YAAA;AAAA,UACZ;AAAA,UAEF;AAAA,UACA,GAAG;AAAA,QAAA;AAAA,QAEL;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EAAA,CACF;AACH;"}