@macrostrat/column-views 1.0.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 (109) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -0
  3. package/dist/age-axis.7ce58d66.js +41 -0
  4. package/dist/age-axis.7ce58d66.js.map +1 -0
  5. package/dist/boxes.6d3192e6.js +164 -0
  6. package/dist/boxes.6d3192e6.js.map +1 -0
  7. package/dist/boxes.module.998ff312.js +13 -0
  8. package/dist/boxes.module.998ff312.js.map +1 -0
  9. package/dist/boxes.module.dd631fe3.css +4 -0
  10. package/dist/boxes.module.dd631fe3.css.map +1 -0
  11. package/dist/carbon-isotopes.6d9bddcf.js +11 -0
  12. package/dist/carbon-isotopes.6d9bddcf.js.map +1 -0
  13. package/dist/column.e35a471f.js +149 -0
  14. package/dist/column.e35a471f.js.map +1 -0
  15. package/dist/column.e901b5d4.js +117 -0
  16. package/dist/column.e901b5d4.js.map +1 -0
  17. package/dist/column.module.2e29259c.js +22 -0
  18. package/dist/column.module.2e29259c.js.map +1 -0
  19. package/dist/column.module.35184ea7.css +157 -0
  20. package/dist/column.module.35184ea7.css.map +1 -0
  21. package/dist/column.module.35ba04e7.js +34 -0
  22. package/dist/column.module.35ba04e7.js.map +1 -0
  23. package/dist/column.module.c9df6edf.css +138 -0
  24. package/dist/column.module.c9df6edf.css.map +1 -0
  25. package/dist/composite.494beffc.js +153 -0
  26. package/dist/composite.494beffc.js.map +1 -0
  27. package/dist/composite.module.5cc0e747.css +4 -0
  28. package/dist/composite.module.5cc0e747.css.map +1 -0
  29. package/dist/composite.module.6359deba.js +13 -0
  30. package/dist/composite.module.6359deba.js.map +1 -0
  31. package/dist/core.f3824dd8.js +89 -0
  32. package/dist/core.f3824dd8.js.map +1 -0
  33. package/dist/data-area.f9bb9ad9.js +86 -0
  34. package/dist/data-area.f9bb9ad9.js.map +1 -0
  35. package/dist/data-provider.61ef7f9a.js +25 -0
  36. package/dist/data-provider.61ef7f9a.js.map +1 -0
  37. package/dist/helpers.2af05ee4.js +94 -0
  38. package/dist/helpers.2af05ee4.js.map +1 -0
  39. package/dist/index.d.ts +363 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +19 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/index.module.8fad0020.js +37 -0
  44. package/dist/index.module.8fad0020.js.map +1 -0
  45. package/dist/index.module.de76feb2.css +65 -0
  46. package/dist/index.module.de76feb2.css.map +1 -0
  47. package/dist/isotopes-column.b5442b4d.js +163 -0
  48. package/dist/isotopes-column.b5442b4d.js.map +1 -0
  49. package/dist/layers.946aaa37.js +231 -0
  50. package/dist/layers.946aaa37.js.map +1 -0
  51. package/dist/map.e782010f.js +82 -0
  52. package/dist/map.e782010f.js.map +1 -0
  53. package/dist/names.ab14789e.js +65 -0
  54. package/dist/names.ab14789e.js.map +1 -0
  55. package/dist/providers.abcb2cbe.js +25 -0
  56. package/dist/providers.abcb2cbe.js.map +1 -0
  57. package/dist/resolvers.2949c4c0.js +83 -0
  58. package/dist/resolvers.2949c4c0.js.map +1 -0
  59. package/dist/section.6f6fc929.js +118 -0
  60. package/dist/section.6f6fc929.js.map +1 -0
  61. package/dist/selection-popover.7e008544.js +60 -0
  62. package/dist/selection-popover.7e008544.js.map +1 -0
  63. package/dist/selection-popover.module.2732ebc0.css +34 -0
  64. package/dist/selection-popover.module.2732ebc0.css.map +1 -0
  65. package/dist/selection-popover.module.fdbfb40e.js +22 -0
  66. package/dist/selection-popover.module.fdbfb40e.js.map +1 -0
  67. package/dist/selection.add9f8b0.js +117 -0
  68. package/dist/selection.add9f8b0.js.map +1 -0
  69. package/dist/store.c5271371.js +18 -0
  70. package/dist/store.c5271371.js.map +1 -0
  71. package/dist/types.ff938b22.js +18 -0
  72. package/dist/types.ff938b22.js.map +1 -0
  73. package/dist/unit-details.0c1edd00.js +209 -0
  74. package/dist/unit-details.0c1edd00.js.map +1 -0
  75. package/dist/units.5ec6a44c.js +42 -0
  76. package/dist/units.5ec6a44c.js.map +1 -0
  77. package/package.json +66 -0
  78. package/src/age-axis.ts +42 -0
  79. package/src/carbon-isotopes/column.module.sass +136 -0
  80. package/src/carbon-isotopes/column.ts +131 -0
  81. package/src/carbon-isotopes/core.ts +78 -0
  82. package/src/carbon-isotopes/data-area.ts +96 -0
  83. package/src/carbon-isotopes/data-provider.ts +19 -0
  84. package/src/carbon-isotopes/index.ts +3 -0
  85. package/src/carbon-isotopes/isotopes-column.ts +214 -0
  86. package/src/column.module.sass +114 -0
  87. package/src/column.ts +185 -0
  88. package/src/helpers.ts +133 -0
  89. package/src/index.ts +7 -0
  90. package/src/map/animated.ts +78 -0
  91. package/src/map/index.ts +86 -0
  92. package/src/map/layers.ts +316 -0
  93. package/src/providers.ts +34 -0
  94. package/src/section.ts +129 -0
  95. package/src/selection-popover.module.sass +27 -0
  96. package/src/selection-popover.ts +71 -0
  97. package/src/store.ts +12 -0
  98. package/src/unit-details/index.module.sass +51 -0
  99. package/src/unit-details/index.ts +215 -0
  100. package/src/units/boxes.module.sass +3 -0
  101. package/src/units/boxes.ts +221 -0
  102. package/src/units/composite.module.sass +2 -0
  103. package/src/units/composite.ts +266 -0
  104. package/src/units/index.ts +36 -0
  105. package/src/units/names.ts +118 -0
  106. package/src/units/resolvers.ts +111 -0
  107. package/src/units/selection.ts +167 -0
  108. package/src/units/types.ts +26 -0
  109. package/src/units/units.scss +16 -0
@@ -0,0 +1,136 @@
1
+ @use "sass:color"
2
+
3
+ .column-ui
4
+ width: 100vw
5
+ height: 100vh
6
+ overflow-y: scroll
7
+ display: flex
8
+ flex-direction: row
9
+
10
+ .column-view
11
+ flex-grow: 1
12
+ padding: 1em
13
+ max-height: 100vh
14
+ overflow-y: scroll
15
+ h1
16
+ font-size: 1.2em
17
+ margin-bottom: 0.2em
18
+ padding-left: 35px
19
+
20
+ // Column
21
+ .column
22
+ margin-bottom: 1em
23
+ display: flex
24
+ flex-direction: row
25
+ .age-axis-label
26
+ writing-mode: vertical-lr
27
+ transform: rotate(180deg)
28
+ font-size: 12px
29
+ text-align: center
30
+ position: sticky
31
+ top: 0
32
+ max-height: 100vh
33
+
34
+ :global
35
+ .tick text
36
+ text-anchor: middle
37
+ font-weight: 400 !important
38
+ transform: rotate(-90deg) translate(8px,-12px)
39
+
40
+ rect.unit
41
+ stroke: black
42
+ stroke-width: 1px
43
+
44
+ g.lithology-column use.frame
45
+ stroke: black
46
+ stroke-width: 1.5px !important
47
+ pointer-events: none
48
+
49
+ g.isotopes-column
50
+ rect.underlay
51
+ fill: transparent
52
+
53
+ .col-note-label
54
+ font-size: 10px
55
+ margin-top: 3px
56
+ padding: 2px 2px 2px 3px
57
+ line-height: 9px
58
+ border-left: none !important
59
+
60
+ g.height-range
61
+ display: none
62
+
63
+ .note-inner
64
+ border: none
65
+
66
+ .frame rect
67
+ fill: transparent
68
+
69
+
70
+
71
+ .bp5-dark
72
+ .column :global
73
+ .lithology-column .frame
74
+ stroke: white
75
+ g.inner
76
+ rect.unit
77
+ filter: invert(100%)
78
+ g.lithology-column use.frame
79
+ stroke: white
80
+ .note
81
+ line, path.col-note-link
82
+ stroke: white
83
+ .y.axis .tick line
84
+ stroke: white
85
+
86
+ .column-nav
87
+ position: sticky
88
+ top: 2.2em
89
+ h3
90
+ color: #444
91
+ margin-bottom: 0.3em
92
+
93
+ .default-buttons
94
+ width: 100%
95
+ margin: 0 -10px
96
+
97
+ div.map-column
98
+ width: 600px
99
+ height: 100vh
100
+ display: flex
101
+ flex-direction: column
102
+
103
+ :global
104
+ .map-area
105
+ flex-grow: 1
106
+
107
+ .map-placeholder
108
+ position: relative
109
+
110
+ .macrostrat-map
111
+ .graticule
112
+ stroke-dasharray: inherit
113
+ stroke: color.adjust(#AFE6F0, $lightness: -5%)
114
+ .neatline
115
+ stroke-width: 1.5px
116
+
117
+ .context-map
118
+ position: absolute
119
+ top: 0
120
+ right: 0
121
+ width: 250px
122
+ height: 250px
123
+ cursor: pointer
124
+ z-index: 100
125
+ &.expanded
126
+ cursor: inherit
127
+ .columns path:hover
128
+ stroke: rgba(255,0,0,.4) !important
129
+
130
+ .close-button
131
+ position: absolute
132
+ top: 1em
133
+ right: 1em
134
+
135
+ .land
136
+ background-color: rgb(233, 252, 234)
@@ -0,0 +1,131 @@
1
+ import hyper from "@macrostrat/hyper";
2
+ import { group } from "d3-array";
3
+ import { useAPIResult } from "@macrostrat/ui-components";
4
+ import {
5
+ ColumnSVG,
6
+ ColumnAxis,
7
+ ColumnContext,
8
+ } from "@macrostrat/column-components";
9
+ import { SimpleUnitsColumn, IUnit, ColumnArgs } from "../units";
10
+ import { useContext } from "react";
11
+ import { IsotopesColumn } from "./isotopes-column";
12
+ import { MacrostratColumnProvider } from "../providers";
13
+ import styles from "./column.module.sass";
14
+
15
+ const h = hyper.styled(styles);
16
+
17
+ interface IColumnProps {
18
+ data: IUnit[];
19
+ pixelScale?: number;
20
+ isOldestColumn: boolean;
21
+ range?: [number, number];
22
+ }
23
+
24
+ const AgeAxis = ({ ticks }) => {
25
+ const { pixelHeight } = useContext(ColumnContext);
26
+ // A tick roughly every 40 pixels
27
+ let v = Math.max(Math.round(pixelHeight / 40), 1);
28
+
29
+ return h(ColumnAxis, {
30
+ ticks: v,
31
+ showDomain: false,
32
+ });
33
+ };
34
+
35
+ const Section = (props: IColumnProps) => {
36
+ // Section with "squishy" time scale
37
+ const {
38
+ data,
39
+ isOldestColumn = true,
40
+ range = [data[data.length - 1].b_age, data[0].t_age],
41
+ } = props;
42
+ let { pixelScale } = props;
43
+
44
+ const notesOffset = 100;
45
+
46
+ if (!pixelScale) {
47
+ // Make up a pixel scale
48
+ const dAge = range[0] - range[1];
49
+ const targetHeight = 50 * data.length;
50
+ pixelScale = Math.ceil(targetHeight / dAge);
51
+ }
52
+
53
+ return h(
54
+ MacrostratColumnProvider,
55
+ {
56
+ divisions: data,
57
+ range,
58
+ pixelsPerMeter: pixelScale, // Actually pixels per myr
59
+ },
60
+ [
61
+ h(
62
+ ColumnSVG,
63
+ {
64
+ width: 650,
65
+ padding: 20,
66
+ paddingTop: 5,
67
+ paddingBottom: 25,
68
+ },
69
+ [
70
+ h(AgeAxis),
71
+ h(SimpleUnitsColumn, {
72
+ width: 400,
73
+ columnWidth: 90,
74
+ }),
75
+ h(IsotopesColumn, {
76
+ parameter: "D13C",
77
+ label: "δ¹³C",
78
+ width: 100,
79
+ // @ts-ignore
80
+ nTicks: 4,
81
+ showAxis: isOldestColumn,
82
+ transform: "translate(250,0)",
83
+ }),
84
+ h(IsotopesColumn, {
85
+ parameter: "D18O",
86
+ label: "δ¹⁸O",
87
+ color: "red",
88
+ domain: [-40, 0],
89
+ width: 100,
90
+ // @ts-ignore
91
+ nTicks: 4,
92
+ showAxis: isOldestColumn,
93
+ transform: "translate(370,0)",
94
+ }),
95
+ ]
96
+ ),
97
+ ]
98
+ );
99
+ };
100
+
101
+ function Column(props: Omit<IColumnProps, "data"> & { params: ColumnArgs }) {
102
+ const { params } = props;
103
+ const data: IUnit[] = useAPIResult("/units", {
104
+ all: true,
105
+ ...params,
106
+ response: "long",
107
+ });
108
+ if (data == null) return null;
109
+
110
+ let sectionGroups = Array.from(group(data, (d) => d.section_id));
111
+
112
+ //sectionGroups.sort((a, b) => a.t_age - b.t_age);
113
+
114
+ return h("div.column", [
115
+ h("div.age-axis-label", "Age (Ma)"),
116
+ h(
117
+ "div.main-column",
118
+ sectionGroups.map(([id, values], i) => {
119
+ return h(`div.section-${id}`, [
120
+ h(Section, {
121
+ data: values,
122
+ isOldestColumn: i == sectionGroups.length - 1,
123
+ }),
124
+ ]);
125
+ })
126
+ ),
127
+ ]);
128
+ }
129
+
130
+ export { Section, IColumnProps };
131
+ export default Column;
@@ -0,0 +1,78 @@
1
+ import hyper from "@macrostrat/hyper";
2
+ import styles from "./column.module.sass";
3
+
4
+ import { useAPIResult } from "@macrostrat/ui-components";
5
+ import BaseColumn from "./column";
6
+ import { ColumnNavigatorMap, MeasurementsLayer } from "../map";
7
+ import { MeasurementDataProvider } from "./data-provider";
8
+ import { MacrostratAPIProvider } from "../providers";
9
+ import { ColumnArgs, useColumnNav } from "../units";
10
+ import { useMemo } from "react";
11
+ import { FeatureCollection } from "geojson";
12
+
13
+ const h = hyper.styled(styles);
14
+
15
+ const ColumnTitle = (props) => {
16
+ return h.if(props.data != null)("h1", props.data?.col_name);
17
+ };
18
+
19
+ const defaultArgs: ColumnArgs = {
20
+ col_id: 2192,
21
+ //unit_id: null,
22
+ project_id: 10,
23
+ status_code: "in process",
24
+ };
25
+
26
+ export function CarbonIsotopesColumn(columnArgs) {
27
+ return h(
28
+ MacrostratAPIProvider,
29
+ h(MeasurementDataProvider, columnArgs, [
30
+ // @ts-ignore
31
+ h(BaseColumn, { params: columnArgs }),
32
+ ])
33
+ );
34
+ }
35
+
36
+ function ColumnManager() {
37
+ const [columnArgs, setCurrentColumn] = useColumnNav(defaultArgs);
38
+ const { col_id, ...projectParams } = columnArgs;
39
+
40
+ const colParams = useMemo(
41
+ () => ({ ...columnArgs, format: "geojson" }),
42
+ [columnArgs]
43
+ );
44
+ const res: FeatureCollection = useAPIResult("/columns", colParams);
45
+ const columnFeature = res?.features[0];
46
+
47
+ return h(MeasurementDataProvider, columnArgs, [
48
+ h("div.column-ui", [
49
+ h("div.column-view", [
50
+ h(ColumnTitle, { data: columnFeature?.properties }),
51
+ // @ts-ignore
52
+ h(BaseColumn, { params: columnArgs }),
53
+ ]),
54
+ h("div.map-column", [
55
+ h(
56
+ ColumnNavigatorMap,
57
+ {
58
+ currentColumn: columnFeature,
59
+ setCurrentColumn,
60
+ margin: 0,
61
+ ...projectParams,
62
+ },
63
+ h(MeasurementsLayer, {
64
+ ...projectParams,
65
+ style: {
66
+ fill: "dodgerblue",
67
+ stroke: "blue",
68
+ },
69
+ })
70
+ ),
71
+ ]),
72
+ ]),
73
+ ]);
74
+ }
75
+
76
+ export function CarbonIsotopesApp() {
77
+ return h(MacrostratAPIProvider, h(ColumnManager));
78
+ }
@@ -0,0 +1,96 @@
1
+ import { line } from "d3-shape";
2
+ import { createContext, useContext } from "react";
3
+ import h from "@macrostrat/hyper";
4
+ import { ColumnLayoutContext } from "@macrostrat/column-components";
5
+
6
+ const inDomain = (scale, num) => {
7
+ const domain = scale.domain();
8
+ return domain[0] < num < domain[1];
9
+ };
10
+
11
+ const createPointLocator = function (opts) {
12
+ const { xScale, scale, getHeight, ...rest } = opts;
13
+ return function (d, s = 0) {
14
+ const height = getHeight(d);
15
+ if (!inDomain(scale, height)) return null;
16
+ return [xScale(d.value), scale(height)];
17
+ };
18
+ };
19
+
20
+ const IsotopesDataContext = createContext(null);
21
+
22
+ export interface DataAreaProps {
23
+ clipY: boolean;
24
+ parameter: string;
25
+ corrected: boolean;
26
+ system: string;
27
+ children: React.ReactNode;
28
+ getHeight?: Function;
29
+ }
30
+
31
+ const IsotopesDataArea = function (props: DataAreaProps) {
32
+ const { xScale, scale } = useContext(ColumnLayoutContext) ?? {};
33
+
34
+ let { corrected, system, children, getHeight, clipY } = props;
35
+ if (getHeight == null) {
36
+ getHeight = function (d) {
37
+ if (d.height == null) {
38
+ console.log(d);
39
+ }
40
+ return d.height;
41
+ };
42
+ }
43
+
44
+ // Handlers for creating points and lines
45
+ const pointLocator = createPointLocator({
46
+ xScale,
47
+ scale,
48
+ corrected,
49
+ system,
50
+ getHeight,
51
+ });
52
+
53
+ let column = "avg_" + system;
54
+ if (corrected) {
55
+ column += "_corr";
56
+ }
57
+ const lineLocator = line()
58
+ .x((d) => xScale(d[column]))
59
+ // @ts-ignore
60
+ .y((d) => scale(d.height));
61
+
62
+ const value = { pointLocator, lineLocator, corrected, system, clipY };
63
+ return h(IsotopesDataContext.Provider, { value }, h("g.data", children));
64
+ };
65
+
66
+ IsotopesDataArea.defaultProps = { clipY: false };
67
+
68
+ const IsotopeDataPoint = function (props) {
69
+ const { pointLocator } = useContext(IsotopesDataContext);
70
+ const { datum, strokeWidth, ...rest } = props;
71
+ const loc = pointLocator(datum);
72
+ if (loc == null) return null;
73
+ const [cx, cy] = loc;
74
+
75
+ return h("circle", {
76
+ key: datum.sample_id,
77
+ cx,
78
+ cy,
79
+ r: 2,
80
+ ...rest,
81
+ });
82
+ };
83
+
84
+ const IsotopeDataLine = function (props) {
85
+ const { values: lineValues, ...rest } = props;
86
+ const { lineLocator } = useContext(IsotopesDataContext);
87
+ return h("path", {
88
+ d: lineLocator(lineValues),
89
+ fill: "transparent",
90
+ ...rest,
91
+ });
92
+ };
93
+
94
+ const useDataLocator = () => useContext(IsotopesDataContext);
95
+
96
+ export { IsotopesDataArea, IsotopeDataPoint, IsotopeDataLine, useDataLocator };
@@ -0,0 +1,19 @@
1
+ import h from "@macrostrat/hyper";
2
+ import { useContext, createContext } from "react";
3
+ import { useAPIResult } from "@macrostrat/ui-components";
4
+
5
+ const MeasurementDataContext = createContext(null);
6
+
7
+ function MeasurementDataProvider(props) {
8
+ const { children, ...params } = props;
9
+ const res = useAPIResult("/measurements", {
10
+ ...params,
11
+ show_values: true,
12
+ response: "long"
13
+ });
14
+ return h(MeasurementDataContext.Provider, { value: res, children });
15
+ }
16
+
17
+ const useMeasurementData = () => useContext(MeasurementDataContext);
18
+
19
+ export { MeasurementDataProvider, useMeasurementData, MeasurementDataContext };
@@ -0,0 +1,3 @@
1
+ export * from "./isotopes-column";
2
+ export * from "./data-provider";
3
+ export * from "./core";
@@ -0,0 +1,214 @@
1
+ import { format } from "d3-format";
2
+ import { useContext } from "react";
3
+ import h from "@macrostrat/hyper";
4
+ import classNames from "classnames";
5
+ import { AxisBottom } from "@visx/axis";
6
+ import { useMeasurementData } from "./data-provider";
7
+
8
+ import {
9
+ IsotopesDataArea,
10
+ useDataLocator,
11
+ IsotopeDataPoint,
12
+ } from "./data-area";
13
+ import { referenceMeasuresToColumn } from "@macrostrat/stratigraphy-utils";
14
+ import {
15
+ CrossAxisLayoutProvider,
16
+ ColumnLayoutContext,
17
+ useColumnDivisions,
18
+ } from "@macrostrat/column-components";
19
+ import { BaseUnit } from "@macrostrat/api-types";
20
+ import { AxisProps } from "@visx/axis/lib/axis/Axis";
21
+
22
+ const fmt = format(".1f");
23
+
24
+ type IsotopesTextProps = {
25
+ datum: any;
26
+ text: string;
27
+ };
28
+
29
+ function IsotopeText({ datum, text, ...rest }: IsotopesTextProps) {
30
+ const { pointLocator } = useDataLocator();
31
+ const [x, y] = pointLocator(datum);
32
+ return h(
33
+ "text",
34
+ {
35
+ x,
36
+ y,
37
+ ...rest,
38
+ },
39
+ text
40
+ );
41
+ }
42
+
43
+ function ColumnScale(props) {
44
+ const {
45
+ label,
46
+ showAxis = true,
47
+ nTicks = 6,
48
+ tickValues: _tickVals,
49
+ ...rest
50
+ } = props;
51
+ const { xScale, pixelHeight, width } = useContext(ColumnLayoutContext);
52
+
53
+ const tickValues = _tickVals ?? xScale.ticks(nTicks);
54
+
55
+ return h("g.scale.isotope-scale-axis", [
56
+ h(
57
+ "g.scale-lines",
58
+ tickValues.map((value) => {
59
+ const strokeDasharray = value == 0 ? null : "2 6";
60
+ return h(ScaleLine, { value, stroke: "#ddd", strokeDasharray });
61
+ })
62
+ ),
63
+ h.if(showAxis)([
64
+ h("rect.underlay", {
65
+ x: 0,
66
+ y: pixelHeight,
67
+ width,
68
+ height: 30,
69
+ }),
70
+ h(AxisBottom, {
71
+ scale: xScale,
72
+ tickLength: 3,
73
+ tickValues,
74
+ ...rest,
75
+ top: pixelHeight,
76
+ tickLabelProps(tickValue, i) {
77
+ // Compensate for negative sign
78
+ let dx;
79
+ if (tickValue < 0) {
80
+ dx = -2;
81
+ }
82
+ return {
83
+ dy: "-1px",
84
+ dx,
85
+ fontSize: 10,
86
+ textAnchor: "middle",
87
+ fill: "#aaa",
88
+ };
89
+ },
90
+ labelOffset: 0,
91
+ label,
92
+ }),
93
+ ]),
94
+ ]);
95
+ }
96
+
97
+ interface ScaleLineProps {
98
+ value: number;
99
+ className?: string;
100
+ labelBottom?: boolean;
101
+ labelOffset?: number;
102
+ strokeDasharray?: string;
103
+ stroke?: string | number;
104
+ }
105
+
106
+ function ScaleLine(props: ScaleLineProps) {
107
+ let { value, className, labelBottom, labelOffset, ...rest } = props;
108
+ if (labelBottom == null) {
109
+ labelBottom = false;
110
+ }
111
+ if (labelOffset == null) {
112
+ labelOffset = 12;
113
+ }
114
+ const { xScale, pixelHeight } = useContext(ColumnLayoutContext);
115
+ const x = xScale(value);
116
+ const transform = `translate(${x})`;
117
+ className = classNames(className, { zero: value === 0 });
118
+ return h("g.tick", { transform, className, key: value }, [
119
+ h("line", { x0: 0, x1: 0, y0: 0, y1: pixelHeight, ...rest }),
120
+ h.if(labelBottom)("text", { y: pixelHeight + labelOffset }, `${value}`),
121
+ ]);
122
+ }
123
+
124
+ function unnestPoints(measures) {
125
+ let points = [];
126
+ for (const meas of measures) {
127
+ const vals = meas.measure_value.map((d, i) => {
128
+ return {
129
+ value: d,
130
+ age: meas.measure_age[i],
131
+ position: meas.measure_position[i],
132
+ unit_id: meas.unit_id,
133
+ sample_id: meas.sample_no[i],
134
+ measurement: meas.measurement,
135
+ };
136
+ });
137
+ Array.prototype.push.apply(points, vals);
138
+ }
139
+ return points;
140
+ }
141
+
142
+ interface IsotopesDatasetProps {
143
+ color: string;
144
+ parameter: string;
145
+ }
146
+
147
+ interface IsotopeColumnProps extends IsotopesDatasetProps {
148
+ width: number;
149
+ tickValues?: number[];
150
+ label: string;
151
+ domain: [number, number];
152
+ transform?: string;
153
+ getHeight?: Function;
154
+ }
155
+
156
+ function IsotopesDataset(props) {
157
+ const { parameter, color = "dodgerblue" } = props;
158
+ const divisions: BaseUnit[] = useColumnDivisions() as any;
159
+ const measures = useMeasurementData() ?? [];
160
+ const refMeasures = referenceMeasuresToColumn(divisions, measures).filter(
161
+ (d) => d.measurement == parameter
162
+ );
163
+ const points = unnestPoints(refMeasures);
164
+
165
+ return h(
166
+ IsotopesDataArea,
167
+ {
168
+ getHeight(d) {
169
+ return d.age;
170
+ },
171
+ } as any,
172
+ h(
173
+ "g.data-points",
174
+ points.map((d) => {
175
+ return h(IsotopeDataPoint, {
176
+ datum: d,
177
+ fill: color,
178
+ });
179
+ })
180
+ )
181
+ );
182
+ }
183
+
184
+ function IsotopesColumn(
185
+ props: IsotopeColumnProps & { children?: React.ReactNode } & AxisProps<any>
186
+ ) {
187
+ const {
188
+ width = 120,
189
+ domain = [-14, 6],
190
+ parameter,
191
+ label,
192
+ color = "dodgerblue",
193
+ children = null,
194
+ transform,
195
+ getHeight,
196
+ ...rest
197
+ } = props;
198
+
199
+ let _children: any = children;
200
+ if (children == null && parameter != null) {
201
+ _children = h(IsotopesDataset, { parameter, color, getHeight });
202
+ }
203
+
204
+ return h(
205
+ CrossAxisLayoutProvider,
206
+ { width, domain },
207
+ h("g.isotopes-column", { className: parameter, transform }, [
208
+ h(ColumnScale, { label: label ?? parameter, ...rest }),
209
+ _children,
210
+ ])
211
+ );
212
+ }
213
+
214
+ export { IsotopesColumn, IsotopesDataset };