@macrostrat/column-views 3.9.0 → 3.11.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 (138) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/column-views.css +10 -0
  3. package/dist/correlation-chart/main.cjs +11 -3
  4. package/dist/correlation-chart/main.cjs.map +1 -1
  5. package/dist/correlation-chart/main.d.ts +1 -1
  6. package/dist/correlation-chart/main.js +11 -3
  7. package/dist/correlation-chart/main.js.map +1 -1
  8. package/dist/index.cjs +18 -42
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.js +4 -34
  12. package/dist/index.js.map +1 -1
  13. package/dist/unit-details/age-window-tag.cjs +68 -0
  14. package/dist/unit-details/age-window-tag.cjs.map +1 -0
  15. package/dist/unit-details/age-window-tag.d.ts +26 -0
  16. package/dist/unit-details/age-window-tag.js +66 -0
  17. package/dist/unit-details/age-window-tag.js.map +1 -0
  18. package/dist/unit-details/age-window-tag.module.sass.cjs +12 -0
  19. package/dist/unit-details/age-window-tag.module.sass.cjs.map +1 -0
  20. package/dist/unit-details/age-window-tag.module.sass.js +11 -0
  21. package/dist/unit-details/age-window-tag.module.sass.js.map +1 -0
  22. package/dist/unit-details/index.d.ts +1 -0
  23. package/dist/units/boxes.cjs +3 -3
  24. package/dist/units/boxes.cjs.map +1 -1
  25. package/dist/units/boxes.js +3 -3
  26. package/dist/units/boxes.js.map +1 -1
  27. package/dist/units/index.cjs +7 -11
  28. package/dist/units/index.cjs.map +1 -1
  29. package/dist/units/index.d.ts +0 -1
  30. package/dist/units/index.js +4 -9
  31. package/dist/units/index.js.map +1 -1
  32. package/package.json +6 -27
  33. package/src/correlation-chart/main.ts +14 -2
  34. package/src/index.ts +3 -1
  35. package/src/unit-details/age-window-tag.module.sass +10 -0
  36. package/src/unit-details/age-window-tag.ts +102 -0
  37. package/src/unit-details/index.ts +1 -0
  38. package/src/units/boxes.ts +7 -4
  39. package/src/units/index.ts +9 -26
  40. package/dist/maps/column-correlation/core.cjs +0 -288
  41. package/dist/maps/column-correlation/core.cjs.map +0 -1
  42. package/dist/maps/column-correlation/core.d.ts +0 -9
  43. package/dist/maps/column-correlation/core.js +0 -286
  44. package/dist/maps/column-correlation/core.js.map +0 -1
  45. package/dist/maps/column-correlation/index.d.ts +0 -2
  46. package/dist/maps/column-correlation/state.cjs +0 -193
  47. package/dist/maps/column-correlation/state.cjs.map +0 -1
  48. package/dist/maps/column-correlation/state.d.ts +0 -62
  49. package/dist/maps/column-correlation/state.js +0 -190
  50. package/dist/maps/column-correlation/state.js.map +0 -1
  51. package/dist/maps/column-navigation/index.d.ts +0 -2
  52. package/dist/maps/column-navigation/mapbox/index.cjs +0 -215
  53. package/dist/maps/column-navigation/mapbox/index.cjs.map +0 -1
  54. package/dist/maps/column-navigation/mapbox/index.d.ts +0 -38
  55. package/dist/maps/column-navigation/mapbox/index.js +0 -213
  56. package/dist/maps/column-navigation/mapbox/index.js.map +0 -1
  57. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs +0 -105
  58. package/dist/maps/column-navigation/mapbox/keyboard-navigation.cjs.map +0 -1
  59. package/dist/maps/column-navigation/mapbox/keyboard-navigation.d.ts +0 -8
  60. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js +0 -105
  61. package/dist/maps/column-navigation/mapbox/keyboard-navigation.js.map +0 -1
  62. package/dist/maps/column-navigation/mapbox/state.cjs +0 -73
  63. package/dist/maps/column-navigation/mapbox/state.cjs.map +0 -1
  64. package/dist/maps/column-navigation/mapbox/state.d.ts +0 -23
  65. package/dist/maps/column-navigation/mapbox/state.js +0 -71
  66. package/dist/maps/column-navigation/mapbox/state.js.map +0 -1
  67. package/dist/maps/column-navigation/svg/animated.d.ts +0 -1
  68. package/dist/maps/column-navigation/svg/data-fetcher.cjs +0 -25
  69. package/dist/maps/column-navigation/svg/data-fetcher.cjs.map +0 -1
  70. package/dist/maps/column-navigation/svg/data-fetcher.d.ts +0 -6
  71. package/dist/maps/column-navigation/svg/data-fetcher.js +0 -25
  72. package/dist/maps/column-navigation/svg/data-fetcher.js.map +0 -1
  73. package/dist/maps/column-navigation/svg/index.cjs +0 -94
  74. package/dist/maps/column-navigation/svg/index.cjs.map +0 -1
  75. package/dist/maps/column-navigation/svg/index.d.ts +0 -9
  76. package/dist/maps/column-navigation/svg/index.js +0 -93
  77. package/dist/maps/column-navigation/svg/index.js.map +0 -1
  78. package/dist/maps/column-navigation/svg/layers.cjs +0 -177
  79. package/dist/maps/column-navigation/svg/layers.cjs.map +0 -1
  80. package/dist/maps/column-navigation/svg/layers.d.ts +0 -54
  81. package/dist/maps/column-navigation/svg/layers.js +0 -174
  82. package/dist/maps/column-navigation/svg/layers.js.map +0 -1
  83. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs +0 -50
  84. package/dist/maps/column-navigation/utils/keyboard-navigation.cjs.map +0 -1
  85. package/dist/maps/column-navigation/utils/keyboard-navigation.d.ts +0 -10
  86. package/dist/maps/column-navigation/utils/keyboard-navigation.js +0 -50
  87. package/dist/maps/column-navigation/utils/keyboard-navigation.js.map +0 -1
  88. package/dist/maps/index.d.ts +0 -4
  89. package/dist/maps/inset-map/index.cjs +0 -71
  90. package/dist/maps/inset-map/index.cjs.map +0 -1
  91. package/dist/maps/inset-map/index.d.ts +0 -16
  92. package/dist/maps/inset-map/index.js +0 -69
  93. package/dist/maps/inset-map/index.js.map +0 -1
  94. package/dist/maps/layers/columns.cjs +0 -165
  95. package/dist/maps/layers/columns.cjs.map +0 -1
  96. package/dist/maps/layers/columns.d.ts +0 -28
  97. package/dist/maps/layers/columns.js +0 -165
  98. package/dist/maps/layers/columns.js.map +0 -1
  99. package/dist/maps/layers/index.d.ts +0 -2
  100. package/dist/maps/layers/units.cjs +0 -207
  101. package/dist/maps/layers/units.cjs.map +0 -1
  102. package/dist/maps/layers/units.d.ts +0 -14
  103. package/dist/maps/layers/units.js +0 -204
  104. package/dist/maps/layers/units.js.map +0 -1
  105. package/dist/units/colors.cjs +0 -115
  106. package/dist/units/colors.cjs.map +0 -1
  107. package/dist/units/colors.d.ts +0 -20
  108. package/dist/units/colors.js +0 -113
  109. package/dist/units/colors.js.map +0 -1
  110. package/dist/units/resolvers.cjs +0 -125
  111. package/dist/units/resolvers.cjs.map +0 -1
  112. package/dist/units/resolvers.d.ts +0 -8
  113. package/dist/units/resolvers.js +0 -125
  114. package/dist/units/resolvers.js.map +0 -1
  115. package/src/maps/column-correlation/column-correlation-map.stories.ts +0 -108
  116. package/src/maps/column-correlation/core.ts +0 -342
  117. package/src/maps/column-correlation/index.ts +0 -2
  118. package/src/maps/column-correlation/state.ts +0 -315
  119. package/src/maps/column-navigation/index.ts +0 -2
  120. package/src/maps/column-navigation/mapbox/column-navigation-map.stories.ts +0 -278
  121. package/src/maps/column-navigation/mapbox/index.ts +0 -276
  122. package/src/maps/column-navigation/mapbox/keyboard-navigation.ts +0 -133
  123. package/src/maps/column-navigation/mapbox/state.ts +0 -119
  124. package/src/maps/column-navigation/svg/animated.ts +0 -78
  125. package/src/maps/column-navigation/svg/column-navigation-svg-map.stories.ts +0 -46
  126. package/src/maps/column-navigation/svg/data-fetcher.ts +0 -34
  127. package/src/maps/column-navigation/svg/index.ts +0 -96
  128. package/src/maps/column-navigation/svg/layers.ts +0 -233
  129. package/src/maps/column-navigation/utils/keyboard-navigation.ts +0 -58
  130. package/src/maps/index.ts +0 -4
  131. package/src/maps/inset-map/index.ts +0 -87
  132. package/src/maps/inset-map/inset-map.stories.ts +0 -20
  133. package/src/maps/layers/columns.ts +0 -216
  134. package/src/maps/layers/index.ts +0 -2
  135. package/src/maps/layers/units.ts +0 -286
  136. package/src/maps/unit-map.stories.ts +0 -79
  137. package/src/units/colors.ts +0 -183
  138. package/src/units/resolvers.ts +0 -141
@@ -1,119 +0,0 @@
1
- import { create, StoreApi, useStore } from "zustand";
2
- import type { ColumnGeoJSONRecordWithID } from "@macrostrat/api-types";
3
- import {
4
- createContext,
5
- useState,
6
- useContext,
7
- ReactNode,
8
- useEffect,
9
- useMemo,
10
- } from "react";
11
- import h from "@macrostrat/hyper";
12
- import {
13
- useMacrostratColumns,
14
- useMacrostratStore,
15
- } from "@macrostrat/data-provider";
16
-
17
- export interface NavigationStore {
18
- columns: ColumnGeoJSONRecordWithID[];
19
- selectedColumn: number | null;
20
- hoveredColumn: number | null;
21
- selectColumn: (columnID: number | null) => void;
22
- setHoveredColumn: (columnID: number | null) => void;
23
- }
24
-
25
- export interface NavigationProviderProps {
26
- projectID?: number;
27
- inProcess?: boolean;
28
- selectedColumn?: number | null;
29
- hoveredColumn?: number | null;
30
- columns?: ColumnGeoJSONRecordWithID[] | null;
31
- columnIDs?: number[] | null;
32
- children: ReactNode;
33
- onSelectColumn?: (col_id: number | null, column: any) => void;
34
- onHoverColumn?: (col_id: number | null, column: any) => void;
35
- }
36
-
37
- const NavigationStoreContext = createContext<StoreApi<NavigationStore> | null>(
38
- null,
39
- );
40
-
41
- export function ColumnNavigationProvider({
42
- children,
43
- columns,
44
- columnIDs,
45
- selectedColumn,
46
- projectID,
47
- inProcess,
48
- onSelectColumn,
49
- onHoverColumn,
50
- }: NavigationProviderProps) {
51
- const getColumns = useMacrostratStore((s) => s.getColumns);
52
-
53
- const [store] = useState(() => {
54
- return create<NavigationStore>((set, get): NavigationStore => {
55
- return {
56
- columns: null,
57
- selectedColumn: null,
58
- hoveredColumn: null,
59
- selectColumn(columnID: number | null) {
60
- set({ selectedColumn: columnID, hoveredColumn: null });
61
- const { columns } = get();
62
- const column = columns?.find((d) => d.id == columnID);
63
- onSelectColumn?.(columnID, column);
64
- },
65
- setHoveredColumn(columnID: number | null) {
66
- set({ hoveredColumn: columnID });
67
- const { columns } = get();
68
- const column = columns?.find((d) => d.id == columnID);
69
- onHoverColumn?.(columnID, column);
70
- },
71
- };
72
- });
73
- });
74
-
75
- // Set up the store
76
- /** TODO: unify handling of columns between parts of application */
77
- // useAsyncEffect(async () => {
78
- // let _columns = columns ?? (await getColumns(projectID, inProcess));
79
- // store.setState({ columns: _columns, selectedColumn });
80
- // }, [projectID, inProcess, columns, getColumns]);
81
-
82
- let _columns = columns ?? useMacrostratColumns(projectID, inProcess);
83
-
84
- // filter columns if specified
85
- if (columnIDs?.length > 0) {
86
- _columns = useMemo(() => {
87
- return _columns?.filter((d) => columnIDs.includes(d.properties.col_id));
88
- }, [columnIDs, _columns]);
89
- }
90
-
91
- useEffect(() => {
92
- if (_columns?.length > 0) {
93
- store.setState({ columns: _columns, selectedColumn });
94
- }
95
- }, [_columns]);
96
- // Update selected column if it is changed externally
97
-
98
- // Kind of an awkward way to do this but we need to allow the selector to run
99
- useEffect(() => {
100
- const { selectColumn, selectedColumn: _internalSelectedColumn } =
101
- store.getState();
102
- if (selectedColumn == _internalSelectedColumn) {
103
- return;
104
- }
105
- selectColumn(selectedColumn);
106
- }, [selectedColumn]);
107
-
108
- return h(NavigationStoreContext.Provider, { value: store }, children);
109
- }
110
-
111
- export function useColumnNavigationStore(
112
- selector: (state: NavigationStore) => any,
113
- ) {
114
- const storeApi = useContext(NavigationStoreContext);
115
- if (storeApi == null) {
116
- throw new Error("Missing ColumnNavigationProvider");
117
- }
118
- return useStore(storeApi, selector);
119
- }
@@ -1,78 +0,0 @@
1
- import { useState } from "react";
2
- import h from "@macrostrat/hyper";
3
- import { Globe } from "@macrostrat/svg-map-components";
4
- import { Button } from "@blueprintjs/core";
5
- import { geoCentroid } from "d3-geo";
6
- import { LandLayer } from "@macrostrat/svg-map-components";
7
- import { Columns, CurrentColumn } from "./layers";
8
- import classNames from "classnames";
9
- import { useSpring, animated } from "react-spring";
10
-
11
- const AnimatedGlobe = animated(Globe);
12
-
13
- const MapViewFrame = (props) => {
14
- const [expanded, setExpanded] = useState(false);
15
- const className = classNames({ expanded }, "context-map");
16
- const { children, center, margin = 10 } = props;
17
- const baseSize = 250;
18
- const sz = expanded ? 450 : baseSize;
19
-
20
- let scale = sz / 2 - margin;
21
- if (expanded) {
22
- scale *= 3;
23
- }
24
-
25
- const targetProps = {
26
- width: sz,
27
- height: sz,
28
- scale,
29
- };
30
-
31
- const animationProps = useSpring(targetProps);
32
-
33
- return h(
34
- "div.map-placeholder",
35
- { style: { width: baseSize, height: baseSize } },
36
- [
37
- h(animated.div, { className, style: animationProps }, [
38
- h(
39
- AnimatedGlobe,
40
- {
41
- ...targetProps,
42
- margin,
43
- center,
44
- allowDrag: expanded,
45
- allowZoom: false,
46
- keepNorthUp: true,
47
- onClick() {
48
- setExpanded(true);
49
- },
50
- },
51
- [h(LandLayer), children],
52
- ),
53
- h.if(expanded)(Button, {
54
- className: "close-button",
55
- icon: "cross",
56
- minimal: true,
57
- onClick() {
58
- setExpanded(false);
59
- },
60
- intent: "danger",
61
- }),
62
- ]),
63
- ],
64
- );
65
- };
66
-
67
- export const AnimatedMapView = (props) => {
68
- const { currentColumn, setCurrentColumn, children, ...rest } = props;
69
- const center = geoCentroid(currentColumn);
70
-
71
- return h(MapViewFrame, { center, ...rest }, [
72
- h(Columns, { onClick: setCurrentColumn, ...rest }),
73
- children,
74
- h.if(currentColumn != null)(CurrentColumn, {
75
- feature: currentColumn,
76
- }),
77
- ]);
78
- };
@@ -1,46 +0,0 @@
1
- import h from "@macrostrat/hyper";
2
-
3
- import { Meta } from "@storybook/react-vite";
4
- import { ColumnNavigationSVGMap, ColumnNavigationSVGMapProps } from ".";
5
- import { MacrostratDataProvider } from "@macrostrat/data-provider";
6
- import { useState } from "react";
7
-
8
- interface ColumnIndexMapProps extends ColumnNavigationSVGMapProps {
9
- col_id: number;
10
- }
11
-
12
- function BasicColumnNavigationSVGMap(props: ColumnIndexMapProps) {
13
- return h(
14
- MacrostratDataProvider,
15
- h(ColumnNavigationSVGMap, { style: { width: 500, height: 500 }, ...props }),
16
- );
17
- }
18
-
19
- // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
20
- export default {
21
- title: "Column views/Maps/Column navigation (SVG)",
22
- component: BasicColumnNavigationSVGMap,
23
- } as Meta<typeof ColumnNavigationSVGMap>;
24
-
25
- export const StaticColumnView = {
26
- args: {
27
- center: [-100, 38],
28
- },
29
- };
30
-
31
- export function Interactive() {
32
- const [currentColumn, setCurrentColumn] = useState(null);
33
- return h(BasicColumnNavigationSVGMap, {
34
- currentColumn,
35
- setCurrentColumn,
36
- });
37
- }
38
-
39
- export function ShowingTriangulation() {
40
- const [currentColumn, setCurrentColumn] = useState(null);
41
- return h(BasicColumnNavigationSVGMap, {
42
- currentColumn,
43
- setCurrentColumn,
44
- showDebugLayers: true,
45
- });
46
- }
@@ -1,34 +0,0 @@
1
- import {
2
- ColumnStatusCode,
3
- fetchAllColumns,
4
- useMacrostratFetch,
5
- } from "@macrostrat/data-provider";
6
- import { useAsyncMemo } from "@macrostrat/ui-components";
7
-
8
- export function useColumnFeatures({
9
- status_code,
10
- project_id,
11
- format = "geojson",
12
- }: {
13
- apiRoute?: string;
14
- status_code?: string;
15
- project_id?: number;
16
- format?: "geojson" | "topojson" | "geojson_bare";
17
- }) {
18
- /** Legacy fetcher for column features */
19
- const fetch = useMacrostratFetch();
20
-
21
- let statusCode: ColumnStatusCode[] = ["active"];
22
- if (status_code == "in process") {
23
- statusCode.push("in process");
24
- }
25
-
26
- return useAsyncMemo(async () => {
27
- return await fetchAllColumns({
28
- projectID: project_id,
29
- statusCode: statusCode,
30
- format,
31
- fetch,
32
- });
33
- }, [project_id, status_code, format]);
34
- }
@@ -1,96 +0,0 @@
1
- import { useRef } from "react";
2
- import h from "@macrostrat/hyper";
3
- import { Globe, LandLayer } from "@macrostrat/svg-map-components";
4
- import { geoCentroid } from "d3-geo";
5
- import { useElementSize } from "@macrostrat/ui-components";
6
- import { Columns, CurrentColumn } from "./layers";
7
- import type { LngLatLike } from "mapbox-gl";
8
-
9
- export function ResizableMapFrame(props) {
10
- const { center, children, style, margin, className, allowZoom, ...rest } =
11
- props;
12
- let { scale } = props;
13
- const ref = useRef(null);
14
- const sz = useElementSize(ref);
15
- const { width, height } = sz ?? { width: 0, height: 0 };
16
- if (scale == null) {
17
- scale = Math.min(width, height) + 2 * margin;
18
- }
19
-
20
- let zoomScaleExtent = null;
21
-
22
- if (allowZoom) {
23
- zoomScaleExtent = [
24
- 0.1 * Math.min(width, height),
25
- 2 * Math.max(width, height),
26
- ];
27
- }
28
-
29
- return h("div.map-area", { ref, style, className }, [
30
- h(
31
- Globe,
32
- {
33
- width,
34
- height,
35
- margin,
36
- center,
37
- allowDrag: true,
38
- allowZoom,
39
- keepNorthUp: true,
40
- zoomScaleExtent,
41
- ...rest,
42
- scale,
43
- },
44
- [h(LandLayer), children],
45
- ),
46
- ]);
47
- }
48
-
49
- type ColumnNavigationSVGMapProps = any;
50
- export type { ColumnNavigationSVGMapProps };
51
-
52
- export function ColumnNavigationSVGMap(props) {
53
- const {
54
- currentColumn,
55
- setCurrentColumn,
56
- children,
57
- style,
58
- margin = 10,
59
- scale,
60
- className,
61
- showInProcessColumns = false,
62
- showDebugLayers = false,
63
- center,
64
- ...rest
65
- } = props;
66
-
67
- let _center: LngLatLike | null = center ?? [-100, 38];
68
- // Override center if currentColumn is set
69
- if (currentColumn != null) {
70
- _center = geoCentroid(currentColumn);
71
- }
72
-
73
- return h(
74
- ResizableMapFrame,
75
- { center: _center, style, margin, scale, className },
76
- [
77
- children,
78
- h(Columns, {
79
- onChange: setCurrentColumn,
80
- col_id: currentColumn?.properties.col_id,
81
- showDebugLayers,
82
- ...rest,
83
- }),
84
- h.if(showInProcessColumns)(Columns, {
85
- onChange: setCurrentColumn,
86
- col_id: currentColumn?.properties.col_id,
87
- status_code: "in process",
88
- color: "rgba(200,150,150, 0.5)",
89
- ...rest,
90
- }),
91
- h.if(currentColumn != null)(CurrentColumn, { feature: currentColumn }),
92
- ],
93
- );
94
- }
95
-
96
- export * from "./layers";
@@ -1,233 +0,0 @@
1
- import h from "@macrostrat/hyper";
2
- import {
3
- Feature,
4
- FeatureLayer,
5
- MapContext,
6
- } from "@macrostrat/svg-map-components";
7
- import { useAPIResult, useKeyHandler } from "@macrostrat/ui-components";
8
- import chroma from "chroma-js";
9
- import { ExtendedFeature } from "d3-geo";
10
- import { Polygon } from "geojson";
11
- import { useContext, useMemo } from "react";
12
- import { useColumnFeatures } from "./data-fetcher";
13
- import {
14
- buildKeyMapping,
15
- buildTriangulation,
16
- } from "../utils/keyboard-navigation";
17
-
18
- const defaultStyle = {
19
- fill: "rgb(239, 180, 249)",
20
- stroke: "magenta",
21
- };
22
-
23
- export function MeasurementsLayer(props) {
24
- const { style = defaultStyle, ...params } = props;
25
- const res: any = useAPIResult("/measurements", {
26
- ...params,
27
- format: "geojson",
28
- response: "light",
29
- });
30
- if (res == null) return null;
31
-
32
- return h(FeatureLayer, {
33
- useCanvas: false,
34
- style,
35
- features: res.features?.filter((d) => d.properties.unit_id != null) ?? [],
36
- });
37
- }
38
-
39
- type ColumnProps = { col_id: number };
40
-
41
- type ColumnFeature = ExtendedFeature<Polygon, ColumnProps>;
42
-
43
- function ColumnFeatures(props) {
44
- const {
45
- features,
46
- onClick,
47
- color = "rgba(150,150,150, 1)",
48
- singleFeature = true,
49
- } = props;
50
-
51
- const c = chroma(color);
52
-
53
- return h(
54
- FeatureLayer,
55
- {
56
- className: "columns",
57
- useCanvas: onClick == null,
58
- style: {
59
- fill: c.alpha(0.2).css(),
60
- stroke: c.alpha(0.4).css(),
61
- },
62
- },
63
- features?.map((f) => {
64
- return h(Feature, {
65
- id: f.id ?? f.properties.col_id,
66
- onClick,
67
- feature: f,
68
- });
69
- }),
70
- );
71
- }
72
-
73
- enum MacrostratStatusCode {
74
- InProcess = "in process",
75
- }
76
-
77
- interface ColumnNavProps {
78
- col_id: number;
79
- status_code?: MacrostratStatusCode;
80
- project_id?: number;
81
- onChange(col_id: number): void;
82
- }
83
-
84
- interface KeyboardNavProps extends ColumnNavProps {
85
- features: ColumnFeature[];
86
- showLayers: boolean;
87
- }
88
-
89
- function ColumnKeyboardNavigation(props: KeyboardNavProps) {
90
- /** Keyboard navigation of columns using a Delaunay triangulation */
91
- const {
92
- features = [],
93
- col_id = null,
94
- onChange,
95
- showLayers = false,
96
- ...projectArgs
97
- } = props;
98
- const { projection } = useContext(MapContext);
99
- const { centroids, tri } = useMemo(
100
- () => buildTriangulation(features),
101
- [features],
102
- );
103
-
104
- const currentIndex = useMemo(() => {
105
- return features.findIndex((d) => d.properties.col_id == col_id);
106
- }, [features, col_id]);
107
-
108
- const neighbors = tri.delaunay.neighbors[currentIndex];
109
-
110
- const keyMapping = useMemo(() => {
111
- return buildKeyMapping(neighbors, centroids, currentIndex, projection);
112
- }, [neighbors, currentIndex]);
113
-
114
- useKeyHandler(
115
- (event) => {
116
- const nextColumnIx = keyMapping[event.keyCode];
117
- if (nextColumnIx == null) return;
118
- // @ts-ignore
119
- onChange(features[nextColumnIx]);
120
- },
121
- [keyMapping],
122
- );
123
-
124
- if (neighbors == null) return null;
125
- const neighborFeatures = neighbors.map((d) => features[d]);
126
-
127
- return h.if(showLayers)([
128
- h(FeatureLayer, {
129
- features: tri.links().features,
130
- useCanvas: false,
131
- style: {
132
- stroke: "purple",
133
- fill: "transparent",
134
- },
135
- }),
136
- h(FeatureLayer, {
137
- features: neighborFeatures,
138
- useCanvas: false,
139
- style: {
140
- stroke: "rgb(93, 101, 212)",
141
- strokeWidth: 3,
142
- fill: "rgba(93, 101, 212, 0.5)",
143
- },
144
- }),
145
- h(FeatureLayer, {
146
- features: [
147
- {
148
- type: "Feature",
149
- geometry: {
150
- type: "MultiPoint",
151
- coordinates: centroids,
152
- },
153
- },
154
- ],
155
- useCanvas: false,
156
- style: {
157
- r: 1,
158
- fill: "purple",
159
- },
160
- }),
161
- ]);
162
- }
163
-
164
- interface ColumnExtraInfo {
165
- apiRoute?: string;
166
- color?: string;
167
- filterColumns?(d: ColumnFeature): boolean;
168
- showDebugLayers?: boolean;
169
- format?: "topojson" | "geojson";
170
- }
171
-
172
- const Columns = (props: ColumnNavProps & ColumnExtraInfo) => {
173
- const {
174
- apiRoute = "/columns",
175
- onChange,
176
- col_id = null,
177
- status_code,
178
- project_id,
179
- color,
180
- filterColumns,
181
- showDebugLayers = false,
182
- format = "topojson",
183
- } = props;
184
-
185
- let features: any[] = useColumnFeatures({
186
- apiRoute,
187
- status_code,
188
- project_id,
189
- format,
190
- }) as any;
191
-
192
- if (features == null) return null;
193
-
194
- if (filterColumns != null) {
195
- features = features.filter(filterColumns);
196
- }
197
-
198
- return h([
199
- h(ColumnKeyboardNavigation, {
200
- features,
201
- col_id,
202
- onChange,
203
- status_code,
204
- project_id,
205
- showLayers: showDebugLayers,
206
- }),
207
- h(ColumnFeatures, { features, onClick: onChange, color }),
208
- ]);
209
- };
210
-
211
- const ColumnCenters = (props: ColumnNavProps) => {
212
- return h(Columns, { apiRoute: "/defs/columns", ...props });
213
- };
214
-
215
- const CurrentColumn = (props) => {
216
- const { feature } = props;
217
- return h(FeatureLayer, {
218
- features: [feature],
219
- style: {
220
- fill: "rgba(255,0,0,0.4)",
221
- stroke: "rgba(255,0,0,0.6)",
222
- strokeWidth: 2,
223
- },
224
- });
225
- };
226
-
227
- export {
228
- Columns,
229
- CurrentColumn,
230
- ColumnCenters,
231
- ColumnFeatures,
232
- ColumnKeyboardNavigation,
233
- };
@@ -1,58 +0,0 @@
1
- import { geoCentroid } from "d3-geo";
2
- import { geoVoronoi } from "d3-geo-voronoi";
3
-
4
- export function buildKeyMapping(
5
- neighbors,
6
- centroids,
7
- currentIndex,
8
- projection,
9
- ) {
10
- if (neighbors == null) return;
11
-
12
- const currentCentroid = projection(centroids[currentIndex]);
13
-
14
- let edgeAngles = neighbors.map((index) => {
15
- const centroid = projection(centroids[index]);
16
- const dx = centroid[0] - currentCentroid[0];
17
- const dy = centroid[1] - currentCentroid[1];
18
- return { col_index: index, angle: Math.atan2(dy, dx) };
19
- });
20
-
21
- edgeAngles.sort((d) => d.angle);
22
-
23
- function closestAngle(num) {
24
- // Find closest angle in array of neighbors
25
- let curr = edgeAngles[0];
26
- for (let next of edgeAngles) {
27
- if (
28
- Math.abs(normalize(num - next.angle)) <
29
- Math.abs(normalize(num - curr.angle))
30
- ) {
31
- curr = next;
32
- }
33
- }
34
- return curr.col_index;
35
- }
36
-
37
- return {
38
- 37: closestAngle(Math.PI), // left
39
- 38: closestAngle((3 * Math.PI) / 2), // up
40
- 39: closestAngle(0), // right
41
- 40: closestAngle(Math.PI / 2), // down
42
- };
43
- }
44
-
45
- function normalize(angle) {
46
- if (angle > Math.PI) {
47
- angle -= 2 * Math.PI;
48
- } else if (angle <= -Math.PI) {
49
- angle += 2 * Math.PI;
50
- }
51
- return angle;
52
- }
53
-
54
- export function buildTriangulation(features) {
55
- const centroids = features.map(geoCentroid);
56
- const tri = geoVoronoi(centroids);
57
- return { centroids, tri };
58
- }
package/src/maps/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./column-navigation";
2
- export * from "./column-correlation";
3
- export * from "./inset-map";
4
- export * from "./layers";