UNPKG

@macrostrat/column-components

Version:

React rendering primitives for stratigraphic columns

1 lines 9.78 kB
{"version":3,"file":"frame.cjs","sources":["../src/frame.ts"],"sourcesContent":["import {\n Component,\n createElement,\n createContext,\n useContext,\n useRef,\n ReactNode,\n} from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { path } from \"d3-path\";\nimport {\n ColumnLayoutContext,\n ColumnLayoutCtx,\n useColumnLayout,\n} from \"./context\";\nimport { drawZigZagAtConstantHeight } from \"./util\";\n\nlet sequence = 0; // Initialize a sequence counter\nfunction getUniqueIdentifier() {\n // Generate a unique identifier using a sequential method that is stable across repeated\n // re-renders. This evolves from a UUID-based approach for SSR (server-side rendering) compatibility.\n const id = `uuid-${sequence}`;\n sequence += 1; // Increment the sequence for the next call\n return id;\n}\n\nclass UUIDComponent<T> extends Component<T> {\n UUID: string;\n constructor(props: T) {\n super(props);\n this.UUID = getUniqueIdentifier();\n }\n}\n\nconst UUIDContext = createContext<string | null>(null);\n\nfunction useBasicUUID() {\n const ref = useRef<string>(getUniqueIdentifier());\n return ref.current;\n}\n\nconst useUUID = function () {\n const uuid = useContext(UUIDContext);\n if (uuid == null) {\n return useBasicUUID();\n }\n return uuid;\n};\n\nfunction UUIDProvider({ children }) {\n const ref = useRef<string>(getUniqueIdentifier());\n return h(UUIDContext.Provider, { value: ref.current, children });\n}\n\ninterface FrameProps {\n id: string;\n className?: string;\n}\n\nfunction SimpleFrame(props: FrameProps) {\n const { pixelHeight: height, width } = useContext(ColumnLayoutContext);\n let { id: frameID, className } = props;\n if (frameID.startsWith(\"#\")) {\n frameID = frameID.slice(1);\n }\n return h(\"rect\", {\n id: frameID,\n x: 0,\n y: 0,\n width,\n height,\n className,\n });\n}\n\ninterface GrainsizeFrameProps {\n id: string;\n zigZagBottom?: boolean;\n zigZagTop?: boolean;\n}\n\nfunction GrainsizeFrame(props: GrainsizeFrameProps) {\n let { id: frameID, zigZagBottom = false, zigZagTop = false } = props;\n\n const { scale, divisions, grainsizeScale: gs } = useColumnLayout();\n if (frameID.startsWith(\"#\")) {\n frameID = frameID.slice(1);\n }\n if (divisions.length === 0) {\n return null;\n }\n\n const [bottomOfSection, topOfSection] = scale.domain();\n\n const topOf = function (d) {\n let { top } = d;\n if (top > topOfSection) {\n top = topOfSection;\n }\n return scale(top);\n };\n const bottomOf = function (d) {\n let { bottom } = d;\n if (bottom < bottomOfSection) {\n bottom = bottomOfSection;\n }\n return scale(bottom);\n };\n\n const filteredDivisions = Array.from(divisions).filter(function (d) {\n if (d.top <= bottomOfSection) {\n return false;\n }\n if (d.bottom > topOfSection) {\n return false;\n }\n return true;\n });\n\n let d = path();\n let currentGrainsize = \"m\";\n let i = 0;\n for (const div of filteredDivisions) {\n if (i === 0) {\n // First division\n // start the path at the bottom\n const y = bottomOf(div);\n d.moveTo(0, y);\n }\n if (div.grainsize != null) {\n currentGrainsize = div.grainsize;\n }\n const x1 = gs(currentGrainsize);\n if (i === 0 && zigZagBottom) {\n // Draw zig-zag at bottom\n drawZigZagAtConstantHeight(d, 0, x1, bottomOf(div));\n } else {\n // Draw a normal line\n d.lineTo(x1, bottomOf(div));\n }\n\n d.lineTo(x1, bottomOf(div));\n d.lineTo(x1, topOf(div));\n\n if (i === filteredDivisions.length - 1) {\n // Last division\n // Draw top\n if (zigZagTop) {\n drawZigZagAtConstantHeight(d, x1, 0, topOf(div));\n } else {\n d.lineTo(0, topOf(div));\n }\n }\n\n i++;\n }\n\n d.closePath();\n\n return h(\"path\", {\n id: frameID,\n key: frameID,\n d: d.toString(),\n });\n}\n\nconst ClipPath = function (props) {\n let { id, children, ...rest } = props;\n if (id.startsWith(\"#\")) {\n id = id.slice(1);\n }\n return createElement(\"clipPath\", { id, key: id, ...rest }, children);\n};\n\nconst UseFrame = function (props) {\n const { id: frameID, ...rest } = props;\n return h(\"use.frame\", {\n xlinkHref: frameID,\n fill: \"transparent\",\n key: \"frame\",\n ...rest,\n });\n};\n\nconst prefixID = function (\n uuid: string,\n prefixes: string[],\n): Record<string, string> {\n const res = {};\n for (let prefix of Array.from(prefixes)) {\n res[prefix + \"ID\"] = `#${uuid}-${prefix}`;\n }\n return res;\n};\n\nexport interface ClipToFrameProps {\n left: number;\n shiftY: number;\n onClick?: () => void;\n frame?: any;\n width?: number;\n className?: string;\n children?: ReactNode;\n clip?: boolean;\n}\n\nexport function ClippingFrame(props: ClipToFrameProps) {\n const {\n left = 0,\n shiftY = 0,\n className,\n onClick,\n children,\n frame = SimpleFrame,\n clip = true,\n } = props;\n\n const uuid = useUUID();\n\n const { frameID, clipID } = prefixID(uuid, [\"frame\", \"clip\"]);\n\n let transform = null;\n if (left != null) {\n transform = `translate(${left} ${shiftY})`;\n }\n\n const frameClassName = \"clip-frame column-clip-frame\";\n\n let _frame: ReactNode = h(frame, { id: frameID, className: frameClassName });\n let defs = null;\n let clipPath = null;\n if (clip) {\n defs = h(\"defs\", { key: \"defs\" }, [\n _frame,\n h(ClipPath, { id: clipID }, h(UseFrame, { id: frameID })),\n ]);\n clipPath = `url(${clipID})`;\n _frame = h(UseFrame, { id: frameID, className: frameClassName });\n }\n\n return h(\"g\", { className, transform, onClick }, [\n defs,\n h(\"g.inner\", { clipPath }, children),\n // Frame must go last\n _frame,\n ]);\n}\n\nexport {\n SimpleFrame,\n GrainsizeFrame,\n ClipPath,\n UUIDComponent,\n UUIDProvider,\n useUUID,\n};\n"],"names":["Component","createContext","useRef","useContext","h","ColumnLayoutContext","useColumnLayout","d","path","drawZigZagAtConstantHeight","createElement"],"mappings":"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"}