UNPKG

@macrostrat/column-components

Version:

React rendering primitives for stratigraphic columns

186 lines (185 loc) 4.63 kB
import { useContext, Component, useRef, createContext, createElement } from "react"; import h from "@macrostrat/hyper"; import { path } from "d3-path"; import { useColumnLayout, ColumnLayoutContext } from "./context/layout.js"; import { drawZigZagAtConstantHeight } from "./util/column-box.js"; let sequence = 0; function getUniqueIdentifier() { const id = `uuid-${sequence}`; sequence += 1; return id; } class UUIDComponent extends Component { UUID; constructor(props) { super(props); this.UUID = getUniqueIdentifier(); } } const UUIDContext = createContext(null); function useBasicUUID() { const ref = useRef(getUniqueIdentifier()); return ref.current; } const useUUID = function() { const uuid = useContext(UUIDContext); if (uuid == null) { return useBasicUUID(); } return uuid; }; function UUIDProvider({ children }) { const ref = useRef(getUniqueIdentifier()); return h(UUIDContext.Provider, { value: ref.current, children }); } function SimpleFrame(props) { const { pixelHeight: height, width } = useContext(ColumnLayoutContext); let { id: frameID, className } = props; if (frameID.startsWith("#")) { frameID = frameID.slice(1); } return h("rect", { id: frameID, x: 0, y: 0, width, height, className }); } function GrainsizeFrame(props) { let { id: frameID, zigZagBottom = false, zigZagTop = false } = props; const { scale, divisions, grainsizeScale: gs } = useColumnLayout(); if (frameID.startsWith("#")) { frameID = frameID.slice(1); } if (divisions.length === 0) { return null; } const [bottomOfSection, topOfSection] = scale.domain(); const topOf = function(d2) { let { top } = d2; if (top > topOfSection) { top = topOfSection; } return scale(top); }; const bottomOf = function(d2) { let { bottom } = d2; if (bottom < bottomOfSection) { bottom = bottomOfSection; } return scale(bottom); }; const filteredDivisions = Array.from(divisions).filter(function(d2) { if (d2.top <= bottomOfSection) { return false; } if (d2.bottom > topOfSection) { return false; } return true; }); let d = path(); let currentGrainsize = "m"; let i = 0; for (const div of filteredDivisions) { if (i === 0) { const y = bottomOf(div); d.moveTo(0, y); } if (div.grainsize != null) { currentGrainsize = div.grainsize; } const x1 = gs(currentGrainsize); if (i === 0 && zigZagBottom) { drawZigZagAtConstantHeight(d, 0, x1, bottomOf(div)); } else { d.lineTo(x1, bottomOf(div)); } d.lineTo(x1, bottomOf(div)); d.lineTo(x1, topOf(div)); if (i === filteredDivisions.length - 1) { if (zigZagTop) { drawZigZagAtConstantHeight(d, x1, 0, topOf(div)); } else { d.lineTo(0, topOf(div)); } } i++; } d.closePath(); return h("path", { id: frameID, key: frameID, d: d.toString() }); } const ClipPath = function(props) { let { id, children, ...rest } = props; if (id.startsWith("#")) { id = id.slice(1); } return createElement("clipPath", { id, key: id, ...rest }, children); }; const UseFrame = function(props) { const { id: frameID, ...rest } = props; return h("use.frame", { xlinkHref: frameID, fill: "transparent", key: "frame", ...rest }); }; const prefixID = function(uuid, prefixes) { const res = {}; for (let prefix of Array.from(prefixes)) { res[prefix + "ID"] = `#${uuid}-${prefix}`; } return res; }; function ClippingFrame(props) { const { left = 0, shiftY = 0, className, onClick, children, frame = SimpleFrame, clip = true } = props; const uuid = useUUID(); const { frameID, clipID } = prefixID(uuid, ["frame", "clip"]); let transform = null; if (left != null) { transform = `translate(${left} ${shiftY})`; } const frameClassName = "clip-frame column-clip-frame"; let _frame = h(frame, { id: frameID, className: frameClassName }); let defs = null; let clipPath = null; if (clip) { defs = h("defs", { key: "defs" }, [ _frame, h(ClipPath, { id: clipID }, h(UseFrame, { id: frameID })) ]); clipPath = `url(${clipID})`; _frame = h(UseFrame, { id: frameID, className: frameClassName }); } return h("g", { className, transform, onClick }, [ defs, h("g.inner", { clipPath }, children), // Frame must go last _frame ]); } export { ClipPath, ClippingFrame, GrainsizeFrame, SimpleFrame, UUIDComponent, UUIDProvider, useUUID }; //# sourceMappingURL=frame.js.map