@macrostrat/column-components
Version:
React rendering primitives for stratigraphic columns
186 lines (185 loc) • 4.63 kB
JavaScript
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