@macrostrat/column-views 3.8.0 → 3.9.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 (68) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/animated-age-window.cjs +51 -0
  3. package/dist/animated-age-window.cjs.map +1 -0
  4. package/dist/animated-age-window.d.ts +51 -0
  5. package/dist/animated-age-window.js +51 -0
  6. package/dist/animated-age-window.js.map +1 -0
  7. package/dist/column.cjs +11 -1
  8. package/dist/column.cjs.map +1 -1
  9. package/dist/column.d.ts +11 -0
  10. package/dist/column.js +11 -1
  11. package/dist/column.js.map +1 -1
  12. package/dist/correlation-chart/main.cjs +24 -12
  13. package/dist/correlation-chart/main.cjs.map +1 -1
  14. package/dist/correlation-chart/main.d.ts +8 -1
  15. package/dist/correlation-chart/main.js +24 -12
  16. package/dist/correlation-chart/main.js.map +1 -1
  17. package/dist/data-provider/store.cjs +17 -4
  18. package/dist/data-provider/store.cjs.map +1 -1
  19. package/dist/data-provider/store.d.ts +6 -1
  20. package/dist/data-provider/store.js +17 -4
  21. package/dist/data-provider/store.js.map +1 -1
  22. package/dist/index.cjs +2 -0
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/prepare-units/composite-scale.cjs +94 -8
  28. package/dist/prepare-units/composite-scale.cjs.map +1 -1
  29. package/dist/prepare-units/composite-scale.d.ts +39 -0
  30. package/dist/prepare-units/composite-scale.js +96 -10
  31. package/dist/prepare-units/composite-scale.js.map +1 -1
  32. package/dist/prepare-units/helpers.cjs +0 -1
  33. package/dist/prepare-units/helpers.cjs.map +1 -1
  34. package/dist/prepare-units/helpers.js +0 -1
  35. package/dist/prepare-units/helpers.js.map +1 -1
  36. package/dist/prepare-units/index.cjs +33 -12
  37. package/dist/prepare-units/index.cjs.map +1 -1
  38. package/dist/prepare-units/index.js +34 -13
  39. package/dist/prepare-units/index.js.map +1 -1
  40. package/dist/prepare-units/types.cjs.map +1 -1
  41. package/dist/prepare-units/types.d.ts +13 -0
  42. package/dist/prepare-units/types.js.map +1 -1
  43. package/dist/section.cjs +4 -2
  44. package/dist/section.cjs.map +1 -1
  45. package/dist/section.d.ts +4 -1
  46. package/dist/section.js +4 -2
  47. package/dist/section.js.map +1 -1
  48. package/dist/units/boxes.cjs +19 -36
  49. package/dist/units/boxes.cjs.map +1 -1
  50. package/dist/units/boxes.js +21 -38
  51. package/dist/units/boxes.js.map +1 -1
  52. package/dist/units/composite.cjs +12 -12
  53. package/dist/units/composite.cjs.map +1 -1
  54. package/dist/units/composite.js +12 -12
  55. package/dist/units/composite.js.map +1 -1
  56. package/package.json +6 -6
  57. package/src/animated-age-window.ts +120 -0
  58. package/src/column.ts +24 -0
  59. package/src/correlation-chart/main.ts +30 -8
  60. package/src/data-provider/store.ts +21 -2
  61. package/src/index.ts +1 -0
  62. package/src/prepare-units/composite-scale.ts +210 -10
  63. package/src/prepare-units/helpers.ts +0 -2
  64. package/src/prepare-units/index.ts +68 -14
  65. package/src/prepare-units/types.ts +13 -0
  66. package/src/section.ts +6 -0
  67. package/src/units/boxes.ts +30 -52
  68. package/src/units/composite.ts +21 -12
@@ -1 +1 @@
1
- {"version":3,"file":"section.cjs","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport { ReactNode, FunctionComponent, useMemo } from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n TimescaleClickHandler,\n useMacrostratIntervals,\n} from \"@macrostrat/timescale\";\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport {\n useMacrostratBaseURL,\n useMacrostratData,\n} from \"@macrostrat/data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight } = useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\ninterface CompositeTimescaleProps {\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n onClickInterval?: TimescaleClickHandler;\n};\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n levels = 3,\n packages,\n unconformityLabels = false,\n onClickInterval,\n } = props;\n\n // Use intervals from Macrostrat API\n const baseURL = useMacrostratBaseURL();\n const intervals = useMacrostratIntervals({ baseURL });\n\n let _levels: [number, number];\n if (typeof levels === \"number\") {\n // If levels is a number, use the most common starting level\n _levels = [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n } else {\n _levels = levels;\n }\n\n const nCols = _levels[1] - _levels[0] + 1;\n\n return h(\"div.timescale-column\", [\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.timescale-container\",\n { style: { paddingTop, \"--timescale-level-count\": nCols }, key },\n [\n h(Timescale, {\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: _levels,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals,\n onClick: onClickInterval,\n }),\n ],\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles","useMacrostratUnits","LabelTrackerProvider","SectionLabelsColumn","useMacrostratColumnData","SVG","useMemo","MacrostratColumnProvider","CompositeUnitsColumn","useMacrostratBaseURL","useMacrostratIntervals","Timescale","TimescaleOrientation","ColumnAxisType","Value","Duration"],"mappings":";;;;;;;;;;;;;;AA4BA,MAAM,IAAIA,WAAAA,QAAM,OAAOC,qBAAM;AAyBtB,SAAS,eAAe,OAA2B;AACxD,QAAM;AAAA,IACJ,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ;AAAA,EAAA,IACE;AAEJ,QAAM,QAAQC,MAAAA,mBAAA;AAGd,QAAM,MAAM,MAAM,CAAC,GAAG;AAEtB,SAAO,EAAEC,UAAAA,sBAAsB,EAAE,OAAO,OAAO;AAAA,IAC7C,EAAE,oBAAoB;AAAA,MACpB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAAA,IACD,EAAE,GAAG,eAAe,EAAEC,+BAAqB;AAAA,MACzC,OAAO,QAAQ;AAAA,IAAA,CAChB;AAAA,EAAA,CACF;AACH;AAEA,SAAS,mBAAmB,OAA2B;AACrD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,EAAA,IACnB;AAEJ,QAAM,EAAE,UAAU,YAAA,IAAgBC,8BAAA;AAElC,QAAM,YAAsC,SAAS,IAAI,CAAC,YAAY;AACpE,WAAO,QAAQ;AAAA,EACjB,CAAC;AAED,QAAM,aAAa,QAAQ;AAE3B,SAAO,EAAE,+BAA+B,EAAE,OAAO,EAAE,MAAA,KAAW;AAAA,IAC5D;AAAA,MACEC,iBAAAA;AAAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,QAAQ;AAAA,QACR;AAAA,QACA,UAAU;AAAA,MAAA;AAAA,MAEZ,SAAS,IAAI,CAAC,UAAU;AACtB,cAAM,EAAE,OAAO,WAAW,WAAA,IAAe;AAEzC,cAAM,MAAM,WAAW,UAAU;AACjC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,OAAO;AAAA,YACP;AAAA,YACA;AAAA,UAAA;AAAA;AAAA,QACF;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,IAEH,EAAE,GAAG,kBAAkB,EAAE,oBAAoB;AAAA,MAC3C;AAAA,MACA,UAAU;AAAA,MACV,SAAS;AAAA,IAAA,CACV;AAAA,EAAA,CACF;AACH;AAEA,SAAS,aAAa,OAAqB;AAEzC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,EAAA,IACE;AAEJ,QAAM,EAAE,QAAQ,YAAY,aAAa,UAAU;AAMnD,QAAM,sBAAsBC,MAAAA,QAAQ,MAAM;AACxC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,KAAK;AAAA,QACb,sBAAsB,KAAK,MAAM,QAAQ,EAAE;AAAA,QAC3C,oBAAoB,YAAY;AAAA,MAAA;AAAA;AAAA,IAClC;AAAA,EAGJ,GAAG,CAAC,OAAO,oBAAoB,oBAAoB,KAAK,CAAC;AAEzD,QAAM,QAAQ;AAAA,IACZ,oBAAoB,GAAG,WAAW;AAAA,IAClC,mBAAmB,GAAG,KAAK;AAAA,EAAA;AAG7B,SAAO;AAAA,IACL;AAAA,IACA,EAAE,WAAW,OAAO,WAAW,eAAe,UAAU,MAAM,IAAA;AAAA,IAC9D;AAAA,MACEC,MAAAA;AAAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,EAAEC,UAAAA,sBAAsB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB,aAAa;AAAA,MAAA,CACd;AAAA,IAAA;AAAA,EACH;AAEJ;AAOO,SAAS,mBAAmB,OAAgC;AACjE,QAAM,EAAE,SAAA,IAAaJ,8BAAA;AACrB,QAAM,gBAAgB,SAAS,IAAI,CAAC,YAAY;AAC9C,WAAO,QAAQ;AAAA,EACjB,CAAC;AAED,SAAO,EAAE,wBAAwB;AAAA,IAC/B,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,CACJ;AACH;AAOO,SAAS,uBAAuB,OAAoC;AACzE,QAAM;AAAA,IACJ,SAAS;AAAA,IACT;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,EAAA,IACE;AAGJ,QAAM,UAAUK,aAAAA,qBAAA;AAChB,QAAM,YAAYC,UAAAA,uBAAuB,EAAE,SAAS;AAEpD,MAAI;AACJ,MAAI,OAAO,WAAW,UAAU;AAE9B,cAAU,CAAC,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;AAAA,EACxD,OAAO;AACL,cAAU;AAAA,EACZ;AAEA,QAAM,QAAQ,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI;AAExC,SAAO,EAAE,wBAAwB;AAAA,IAC/B;AAAA,MACE;AAAA,MACA,SAAS,IAAI,CAAC,UAAU;AACtB,cAAM,EAAE,aAAa,YAAY,KAAK,UAAU;AAChD,eAAO;AAAA,UACL;AAAA,UACA,EAAE,OAAO,EAAE,YAAY,2BAA2B,MAAA,GAAS,IAAA;AAAA,UAC3D;AAAA,YACE,EAAEC,UAAAA,WAAW;AAAA,cACX,aAAaC,UAAAA,qBAAqB;AAAA,cAClC,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,kBAAkB;AAAA,cAClB,aAAa;AAAA,cACb;AAAA,cACA;AAAA,cACA,SAAS;AAAA,YAAA,CACV;AAAA,UAAA;AAAA,QACH;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,IAEH,EAAE,GAAG,kBAAkB,EAAE,oBAAoB;AAAA,MAC3C,OAAO;AAAA,MACP,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAUC,iBAAAA,eAAe;AAAA,IAAA,CAC1B;AAAA,EAAA,CACF;AACH;AAEO,SAAS,mBAAmB,OAMhC;AACD,QAAM,EAAE,OAAO,UAAU,WAAW,UAAU,YAAY;AAE1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,QACL;AAAA,MAAA;AAAA,MAEF;AAAA,IAAA;AAAA,IAEF,SAAS,IAAI,CAAC,WAAW,MAAM;AAC7B,YAAM,YAAY,SAAS,IAAI,CAAC;AAChC,YAAM,MAAM,UAAU,SAAS,UAAU;AACzC,YAAM,WAAW,WAAW,OAAO,CAAC;AACpC,YAAM,WAAW,UAAU,OAAO,CAAC;AACnC,aAAO,EAAE,cAAc;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACL;AAAA,UACA,QAAQ,UAAU;AAAA,UAClB;AAAA,QAAA;AAAA,QAEF;AAAA,MAAA,CACD;AAAA,IACH,CAAC;AAAA,EAAA;AAEL;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AACZ,GAAG;AACD,MAAI,YAAY,QAAQ,YAAY,MAAM;AACxC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,KAAK,IAAI,WAAW,QAAQ;AAE3C,MAAI,wBAAwB;AAE5B,MAAI,YAAoB;AACxB,MAAI,SAAS,KAAM;AACjB,gBAAY;AAAA,EACd,WAAW,SAAS,KAAK;AACvB,gBAAY;AAAA,EACd,WAAW,SAAS,IAAI;AACtB,gBAAY;AAAA,EACd,WAAW,SAAS,GAAG;AACrB,gBAAY;AACZ,4BAAwB;AAAA,EAC1B,OAAO;AACL,4BAAwB;AAAA,EAC1B;AAEA,MAAI;AACJ,MAAI,aAAaA,iBAAAA,eAAe,SAAS,aAAaA,iBAAAA,eAAe,QAAQ;AAC3E,UAAM,OAAO,OAAO,eAAe,SAAS,EAAE,uBAAuB;AACrE,UAAM,EAAEC,sBAAO,EAAE,OAAO,MAAM,MAAM,KAAK;AAAA,EAC3C,OAAO;AACL,UAAM,EAAEC,SAAAA,UAAU,EAAE,OAAO,QAAQ,uBAAuB;AAAA,EAC5D;AAEA,MAAI,SAAoB;AACxB,MAAI,SAAS;AACX,aAAS,EAAE,CAAC,KAAK,EAAE,eAAe,MAAM,CAAC,CAAC;AAAA,EAC5C;AAEA,SAAO,EAAE,oBAAoB,EAAE,OAAO,aAAa;AAAA,IACjD,EAAE,0BAA0B,EAAE,yBAAyB,CAAC,KAAK,MAAM,CAAC,CAAC;AAAA,EAAA,CACtE;AACH;;;;;"}
1
+ {"version":3,"file":"section.cjs","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport { ReactNode, FunctionComponent, useMemo } from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n TimescaleClickHandler,\n useMacrostratIntervals,\n type IntervalStyleBuilder,\n} from \"@macrostrat/timescale\";\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport {\n useMacrostratBaseURL,\n useMacrostratData,\n} from \"@macrostrat/data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight } = useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\ninterface CompositeTimescaleProps {\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n onClickInterval?: TimescaleClickHandler;\n /** Per-interval style (e.g. to highlight the currently selected interval). */\n intervalStyle?: IntervalStyleBuilder;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n onClickInterval?: TimescaleClickHandler;\n};\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n levels = 3,\n packages,\n unconformityLabels = false,\n onClickInterval,\n intervalStyle,\n } = props;\n\n // Use intervals from Macrostrat API\n const baseURL = useMacrostratBaseURL();\n const intervals = useMacrostratIntervals({ baseURL });\n\n let _levels: [number, number];\n if (typeof levels === \"number\") {\n // If levels is a number, use the most common starting level\n _levels = [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n } else {\n _levels = levels;\n }\n\n const nCols = _levels[1] - _levels[0] + 1;\n\n return h(\"div.timescale-column\", [\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.timescale-container\",\n { style: { paddingTop, \"--timescale-level-count\": nCols }, key },\n [\n h(Timescale, {\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: _levels,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals,\n onClick: onClickInterval,\n intervalStyle,\n }),\n ],\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles","useMacrostratUnits","LabelTrackerProvider","SectionLabelsColumn","useMacrostratColumnData","SVG","useMemo","MacrostratColumnProvider","CompositeUnitsColumn","useMacrostratBaseURL","useMacrostratIntervals","Timescale","TimescaleOrientation","ColumnAxisType","Value","Duration"],"mappings":"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"}
package/dist/section.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, FunctionComponent } from 'react';
2
- import { TimescaleClickHandler } from '@macrostrat/timescale';
2
+ import { TimescaleClickHandler, IntervalStyleBuilder } from '@macrostrat/timescale';
3
3
  import { ColumnAxisType } from '@macrostrat/column-components';
4
4
  import { ExtUnit, PackageScaleLayoutData } from './prepare-units/types';
5
5
  export interface SectionSharedProps {
@@ -25,6 +25,9 @@ export declare function SectionsColumn(props: SectionSharedProps): import('react
25
25
  interface CompositeTimescaleProps {
26
26
  levels?: [number, number] | number;
27
27
  unconformityLabels?: boolean;
28
+ onClickInterval?: TimescaleClickHandler;
29
+ /** Per-interval style (e.g. to highlight the currently selected interval). */
30
+ intervalStyle?: IntervalStyleBuilder;
28
31
  }
29
32
  export declare function CompositeTimescale(props: CompositeTimescaleProps): import('react').FunctionComponentElement<CompositeTimescaleCoreProps>;
30
33
  type CompositeTimescaleCoreProps = CompositeTimescaleProps & {
package/dist/section.js CHANGED
@@ -154,7 +154,8 @@ function CompositeTimescaleCore(props) {
154
154
  levels = 3,
155
155
  packages,
156
156
  unconformityLabels = false,
157
- onClickInterval
157
+ onClickInterval,
158
+ intervalStyle
158
159
  } = props;
159
160
  const baseURL = useMacrostratBaseURL();
160
161
  const intervals = useMacrostratIntervals({ baseURL });
@@ -182,7 +183,8 @@ function CompositeTimescaleCore(props) {
182
183
  showAgeAxis: false,
183
184
  scale,
184
185
  intervals,
185
- onClick: onClickInterval
186
+ onClick: onClickInterval,
187
+ intervalStyle
186
188
  })
187
189
  ]
188
190
  );
@@ -1 +1 @@
1
- {"version":3,"file":"section.js","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport { ReactNode, FunctionComponent, useMemo } from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n TimescaleClickHandler,\n useMacrostratIntervals,\n} from \"@macrostrat/timescale\";\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport {\n useMacrostratBaseURL,\n useMacrostratData,\n} from \"@macrostrat/data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight } = useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\ninterface CompositeTimescaleProps {\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n onClickInterval?: TimescaleClickHandler;\n};\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n levels = 3,\n packages,\n unconformityLabels = false,\n onClickInterval,\n } = props;\n\n // Use intervals from Macrostrat API\n const baseURL = useMacrostratBaseURL();\n const intervals = useMacrostratIntervals({ baseURL });\n\n let _levels: [number, number];\n if (typeof levels === \"number\") {\n // If levels is a number, use the most common starting level\n _levels = [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n } else {\n _levels = levels;\n }\n\n const nCols = _levels[1] - _levels[0] + 1;\n\n return h(\"div.timescale-column\", [\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.timescale-container\",\n { style: { paddingTop, \"--timescale-level-count\": nCols }, key },\n [\n h(Timescale, {\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: _levels,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals,\n onClick: onClickInterval,\n }),\n ],\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles"],"mappings":"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"}
1
+ {"version":3,"file":"section.js","sources":["../src/section.ts"],"sourcesContent":["import {\n CompositeUnitsColumn,\n LabelTrackerProvider,\n SectionLabelsColumn,\n} from \"./units\";\nimport { ReactNode, FunctionComponent, useMemo } from \"react\";\nimport {\n Timescale,\n TimescaleOrientation,\n TimescaleClickHandler,\n useMacrostratIntervals,\n type IntervalStyleBuilder,\n} from \"@macrostrat/timescale\";\nimport { ColumnAxisType, SVG } from \"@macrostrat/column-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport styles from \"./column.module.sass\";\nimport {\n useMacrostratColumnData,\n useMacrostratUnits,\n MacrostratColumnProvider,\n} from \"./data-provider\";\nimport {\n useMacrostratBaseURL,\n useMacrostratData,\n} from \"@macrostrat/data-provider\";\nimport { Duration } from \"./unit-details\";\nimport { Value } from \"@macrostrat/data-components\";\nimport type { ExtUnit, PackageScaleLayoutData } from \"./prepare-units/types\";\n\nconst h = hyper.styled(styles);\n\nexport interface SectionSharedProps {\n unitComponent?: FunctionComponent<any>;\n unitComponentProps?: any;\n showLabels?: boolean;\n width?: number;\n columnWidth?: number;\n children?: ReactNode;\n showLabelColumn?: boolean;\n axisType?: ColumnAxisType;\n className?: string;\n clipUnits?: boolean;\n maxInternalColumns?: number;\n // Space between sections\n verticalSpacing?: number;\n // Whether to render unconformity labels\n unconformityLabels?: boolean;\n}\n\nexport interface SectionProps extends SectionSharedProps {\n units: ExtUnit[];\n scaleInfo: PackageScaleLayoutData;\n}\n\nexport function SectionsColumn(props: SectionSharedProps) {\n const {\n unconformityLabels = true,\n unitComponent,\n unitComponentProps,\n showLabels = true,\n width = 300,\n columnWidth = 150,\n showLabelColumn = true,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const units = useMacrostratUnits();\n\n // Get a unique key for the column\n const key = units[0]?.col_id;\n\n return h(LabelTrackerProvider, { units, key }, [\n h(SectionUnitsColumn, {\n width: columnWidth,\n unitComponent,\n unitComponentProps,\n showLabels,\n clipUnits,\n maxInternalColumns,\n unconformityLabels,\n }),\n h.if(showLabelColumn)(SectionLabelsColumn, {\n width: width - columnWidth,\n }),\n ]);\n}\n\nfunction SectionUnitsColumn(props: SectionSharedProps) {\n const {\n width,\n showLabels,\n unitComponent,\n unitComponentProps,\n clipUnits,\n maxInternalColumns,\n axisType,\n unconformityLabels = true,\n } = props;\n\n const { sections, totalHeight } = useMacrostratColumnData();\n\n const scaleData: PackageScaleLayoutData[] = sections.map((section) => {\n return section.scaleInfo;\n });\n\n const innerWidth = width - 2;\n\n return h(\"div.section-units-container\", { style: { width } }, [\n h(\n SVG,\n {\n className: \"sections\",\n height: totalHeight,\n innerWidth,\n paddingH: 1,\n },\n sections.map((group) => {\n const { units, scaleInfo, section_id } = group;\n\n const key = `section-${section_id}`;\n return h(\n SectionUnits,\n {\n units,\n scaleInfo,\n key,\n unitComponent,\n unitComponentProps,\n showLabels,\n width: innerWidth,\n clipUnits,\n maxInternalColumns,\n }, // This unconformity is with the section _above_\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width,\n sections: scaleData,\n verbose: false,\n }),\n ]);\n}\n\nfunction SectionUnits(props: SectionProps) {\n // Section with \"squishy\" timescale\n const {\n units,\n scaleInfo,\n unitComponent,\n showLabels = true,\n width = 300,\n unitComponentProps,\n className,\n clipUnits = true,\n maxInternalColumns,\n } = props;\n\n const { domain, pixelScale, pixelHeight, scale } = scaleInfo;\n\n /** Ensure that we can arrange units into the maximum number\n * of columns defined by unitComponentProps, but that we don't\n * use more than necessary.\n */\n const _unitComponentProps = useMemo(() => {\n return {\n ...unitComponentProps,\n nColumns: Math.min(\n maxInternalColumns ?? Math.floor(width / 10),\n unitComponentProps?.nColumns ?? Infinity,\n ),\n //axisType,\n };\n }, [units, unitComponentProps, maxInternalColumns, width]);\n\n const style = {\n \"--section-height\": `${pixelHeight}px`,\n \"--section-width\": `${width}px`,\n };\n\n return h(\n \"g.section\",\n { className, style, transform: `translate(0 ${scaleInfo.offset})` },\n h(\n MacrostratColumnProvider,\n {\n units,\n domain,\n pixelScale, // Actually pixels per myr,\n scale,\n },\n h(CompositeUnitsColumn, {\n width,\n showLabels,\n unitComponent,\n unitComponentProps: _unitComponentProps,\n clipToFrame: clipUnits,\n }),\n ),\n );\n}\n\ninterface CompositeTimescaleProps {\n levels?: [number, number] | number;\n unconformityLabels?: boolean;\n onClickInterval?: TimescaleClickHandler;\n /** Per-interval style (e.g. to highlight the currently selected interval). */\n intervalStyle?: IntervalStyleBuilder;\n}\n\nexport function CompositeTimescale(props: CompositeTimescaleProps) {\n const { sections } = useMacrostratColumnData();\n const sectionScales = sections.map((section) => {\n return section.scaleInfo;\n });\n\n return h(CompositeTimescaleCore, {\n packages: sectionScales,\n ...props,\n });\n}\n\ntype CompositeTimescaleCoreProps = CompositeTimescaleProps & {\n packages: PackageScaleLayoutData[];\n onClickInterval?: TimescaleClickHandler;\n};\n\nexport function CompositeTimescaleCore(props: CompositeTimescaleCoreProps) {\n const {\n levels = 3,\n packages,\n unconformityLabels = false,\n onClickInterval,\n intervalStyle,\n } = props;\n\n // Use intervals from Macrostrat API\n const baseURL = useMacrostratBaseURL();\n const intervals = useMacrostratIntervals({ baseURL });\n\n let _levels: [number, number];\n if (typeof levels === \"number\") {\n // If levels is a number, use the most common starting level\n _levels = [2, Math.max(2 + Math.min(levels, 5) - 1, 1)];\n } else {\n _levels = levels;\n }\n\n const nCols = _levels[1] - _levels[0] + 1;\n\n return h(\"div.timescale-column\", [\n h(\n \"div.timescales\",\n packages.map((group) => {\n const { pixelHeight, paddingTop, key, scale } = group;\n return h(\n \"div.timescale-container\",\n { style: { paddingTop, \"--timescale-level-count\": nCols }, key },\n [\n h(Timescale, {\n orientation: TimescaleOrientation.VERTICAL,\n length: pixelHeight,\n levels: _levels,\n absoluteAgeScale: true,\n showAgeAxis: false,\n scale,\n intervals,\n onClick: onClickInterval,\n intervalStyle,\n }),\n ],\n );\n }),\n ),\n h.if(unconformityLabels)(UnconformityLabels, {\n width: \"100%\",\n sections: packages,\n className: \"unconformity-labels\",\n axisType: ColumnAxisType.AGE,\n }),\n ]);\n}\n\nexport function UnconformityLabels(props: {\n width: string | number;\n sections: PackageScaleLayoutData[];\n axisType?: ColumnAxisType;\n className?: string;\n verbose?: boolean;\n}) {\n const { width, sections, className, axisType, verbose } = props;\n\n return h(\n \"div.unconformity-labels\",\n {\n style: {\n width,\n },\n className,\n },\n sections.map((scaleInfo, i) => {\n const lastGroup = sections[i - 1];\n const top = scaleInfo.offset - scaleInfo.paddingTop;\n const upperAge = lastGroup?.domain[0];\n const lowerAge = scaleInfo.domain[1];\n return h(Unconformity, {\n axisType,\n upperAge,\n lowerAge,\n style: {\n width,\n height: scaleInfo.paddingTop,\n top,\n },\n verbose,\n });\n }),\n );\n}\n\nfunction Unconformity({\n upperAge,\n lowerAge,\n style,\n axisType,\n verbose = false,\n}) {\n if (upperAge == null || lowerAge == null) {\n return null;\n }\n\n const ageGap = Math.abs(upperAge - lowerAge);\n\n let maximumFractionDigits = 0;\n\n let className: string = null;\n if (ageGap > 1000) {\n className = \"giga\";\n } else if (ageGap > 100) {\n className = \"mega\";\n } else if (ageGap > 10) {\n className = \"large\";\n } else if (ageGap < 1) {\n className = \"small\";\n maximumFractionDigits = 2;\n } else {\n maximumFractionDigits = 1;\n }\n\n let val: ReactNode;\n if (axisType === ColumnAxisType.DEPTH || axisType === ColumnAxisType.HEIGHT) {\n const _txt = ageGap.toLocaleString(\"en-US\", { maximumFractionDigits });\n val = h(Value, { value: _txt, unit: \"m\" });\n } else {\n val = h(Duration, { value: ageGap, maximumFractionDigits });\n }\n\n let prefix: ReactNode = null;\n if (verbose) {\n prefix = h([\" \", h(\"span.prefix\", \" gap\")]);\n }\n\n return h(\"div.unconformity\", { style, className }, [\n h(\"div.unconformity-inner\", h(\"div.unconformity-text\", [val, prefix])),\n ]);\n}\n"],"names":["hyper","styles"],"mappings":"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"}
@@ -14,6 +14,7 @@ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
14
14
  const h__default = /* @__PURE__ */ _interopDefault(h$1);
15
15
  const classNames__default = /* @__PURE__ */ _interopDefault(classNames);
16
16
  const h = h__default.default.styled(boxes_module.default);
17
+ const cls = (name) => boxes_module.default[name] ?? name;
17
18
  function useUnitRect(division, options = {}) {
18
19
  const {
19
20
  widthFraction = 1,
@@ -70,55 +71,33 @@ function Unit(props) {
70
71
  }
71
72
  },
72
73
  [
73
- h(UnitRect, {
74
+ h(columnComponents.ClippableRect, {
74
75
  ...bounds,
75
76
  fill: backgroundColor,
76
77
  onClick,
77
- className: "background"
78
+ className: cls("background")
78
79
  }),
79
- h(UnitRect, {
80
+ h(columnComponents.ClippableRect, {
80
81
  ref,
81
82
  ...bounds,
82
83
  fill: _fill,
83
84
  //mask,
84
85
  onClick,
85
- className: "unit"
86
+ className: cls("unit")
87
+ }),
88
+ h.if(linked)(columnComponents.ClippableRect, {
89
+ ...bounds,
90
+ className: cls("linked-overlay")
91
+ }),
92
+ h.if(selected)(columnComponents.ClippableRect, {
93
+ ...bounds,
94
+ className: cls("selection-overlay")
86
95
  }),
87
- h.if(linked)(UnitRect, { ...bounds, className: "linked-overlay" }),
88
- h.if(selected)(UnitRect, { ...bounds, className: "selection-overlay" }),
89
96
  //defs,
90
97
  children
91
98
  ]
92
99
  );
93
100
  }
94
- const UnitRect = React.forwardRef((props, ref) => {
95
- const {
96
- x,
97
- y,
98
- width,
99
- height,
100
- overflowTop = false,
101
- overflowBottom = false,
102
- ...rest
103
- } = props;
104
- if (!overflowTop && !overflowBottom) {
105
- return h("rect", {
106
- x,
107
- y,
108
- width,
109
- height,
110
- ref,
111
- ...rest
112
- });
113
- } else {
114
- const d = columnComponents.zigZagBoxPath(x, y, width, height, overflowTop, overflowBottom);
115
- return h("path", {
116
- d,
117
- ref,
118
- ...rest
119
- });
120
- }
121
- });
122
101
  function LabeledUnit(props) {
123
102
  const {
124
103
  division,
@@ -132,12 +111,13 @@ function LabeledUnit(props) {
132
111
  // not sure why this is brought in...
133
112
  ...baseBounds
134
113
  } = props;
135
- const { axisType } = columnComponents.useColumn();
114
+ const { axisType, isTransitioning, hideLabelsWhileTransitioning } = columnComponents.useColumn();
136
115
  const bounds = {
137
116
  ...useUnitRect(division, { widthFraction, axisType }),
138
117
  ...baseBounds
139
118
  };
140
119
  const { width, height } = bounds;
120
+ const skipLabel = isTransitioning && hideLabelsWhileTransitioning;
141
121
  return h(
142
122
  Unit,
143
123
  {
@@ -148,7 +128,7 @@ function LabeledUnit(props) {
148
128
  ...bounds
149
129
  },
150
130
  [
151
- h.if(showLabel)(
131
+ h.if(showLabel && !skipLabel)(
152
132
  columnComponents.ForeignObject,
153
133
  { ...bounds, className: "unit-label-container" },
154
134
  h(uiComponents.SizeAwareLabel, {
@@ -156,6 +136,9 @@ function LabeledUnit(props) {
156
136
  labelClassName: "unit-label",
157
137
  style: { width, height },
158
138
  label,
139
+ // Re-fit the label when a transition settles (isTransitioning flips),
140
+ // not on every intermediate frame.
141
+ remeasureKey: isTransitioning,
159
142
  onVisibilityChanged(viz) {
160
143
  onLabelUpdated(label, viz);
161
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"boxes.cjs","sources":["../../src/units/boxes.ts"],"sourcesContent":["import {\n ColumnAxisType,\n ColumnContext,\n ColumnLayoutContext,\n ForeignObject,\n PatternDefsProvider,\n useColumn,\n useGeologicPattern,\n zigZagBoxPath,\n} from \"@macrostrat/column-components\";\nimport { SizeAwareLabel, Clickable } from \"@macrostrat/ui-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport { forwardRef, ReactNode, useContext, useMemo } from \"react\";\nimport { resolveID, scalePattern } from \"./resolvers\";\nimport { useUnitSelectionTarget } from \"../data-provider\";\nimport { useLithologies } from \"@macrostrat/data-provider\";\nimport { IUnit } from \"./types\";\nimport styles from \"./boxes.module.sass\";\nimport classNames from \"classnames\";\nimport { getUnitHeightRange } from \"../prepare-units/utils\";\nimport { getMixedUnitColor } from \"./colors\";\nimport type { RectBounds } from \"./types\";\n\nconst h = hyper.styled(styles);\n\ninterface UnitRectOptions {\n widthFraction?: number;\n axisType?: ColumnAxisType;\n // Padding to create overflow for zig-zags or other ornamented edges\n padding?: number;\n}\n\ninterface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {\n division: IUnit;\n resolveID?(IUnit): string;\n UUID?: string;\n defaultFill?: string;\n widthFraction?: number;\n children?: ReactNode;\n className?: string;\n fill?: string;\n backgroundColor?: string;\n patternColor?: string;\n patternID?: string | number;\n}\n\nexport interface LabeledUnitProps\n extends UnitRectOptions, Clickable, Partial<RectBounds> {\n division: IUnit;\n patternID?: string | number;\n label: string;\n onLabelUpdated?(label: string, shown: boolean);\n halfWidth?: boolean;\n showLabel?: boolean;\n backgroundColor?: string;\n}\n\nfunction useUnitRect(\n division: IUnit,\n options: UnitRectOptions = {},\n): RectBounds {\n const {\n widthFraction = 1,\n axisType = ColumnAxisType.AGE,\n padding = 0,\n } = options;\n const { scale } = useContext(ColumnContext);\n const { width } = useContext(ColumnLayoutContext);\n\n const [bottomHeight, topHeight] = getUnitHeightRange(division, axisType);\n\n const y = scale(topHeight);\n const height = Math.abs(scale(bottomHeight) - y);\n\n return {\n x: width * (1 - widthFraction) - padding,\n y: y - padding,\n height: height + padding * 2,\n width: widthFraction * width + padding * 2,\n };\n}\n\nexport function MinimalUnit(props) {\n const {\n division: d,\n children,\n className,\n widthFraction = 1,\n axisType: _, // not sure why this is brought in...\n nColumns: __,\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const lithMap = useLithologies();\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n };\n\n const backgroundColor = getMixedUnitColor(d, lithMap, null, false);\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n \"--column-stroke-color\": backgroundColor,\n },\n },\n [\n h(\"rect.unit.background\", {\n ref,\n ...bounds,\n fill: backgroundColor,\n fillOpacity: 0.8,\n stroke: backgroundColor,\n onClick,\n }),\n h.if(linked)(\"rect.linked-overlay\", bounds),\n h.if(selected)(\"rect.selection-overlay\", bounds),\n ],\n );\n}\n\nfunction Unit(props: UnitProps) {\n const {\n division: d,\n children,\n fill,\n defaultFill = \"transparent\",\n className,\n widthFraction = 1,\n backgroundColor,\n patternColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n\n const hasOverflowTop = d.t_clip_pos != null;\n const hasOverflowBottom = d.b_clip_pos != null;\n\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n overflowTop: hasOverflowTop,\n overflowBottom: hasOverflowBottom,\n };\n const _patternID = patternID ?? resolveID(d);\n let _fill = fill ?? useGeologicPattern(_patternID, defaultFill);\n\n const hasBackgroundColor = backgroundColor != null;\n\n const _className = classNames(className, { colored: hasBackgroundColor });\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className: _className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n },\n },\n [\n h(UnitRect, {\n ...bounds,\n fill: backgroundColor,\n onClick,\n className: \"background\",\n }),\n h(UnitRect, {\n ref,\n ...bounds,\n fill: _fill,\n //mask,\n onClick,\n className: \"unit\",\n }),\n h.if(linked)(UnitRect, { ...bounds, className: \"linked-overlay\" }),\n h.if(selected)(UnitRect, { ...bounds, className: \"selection-overlay\" }),\n //defs,\n children,\n ],\n );\n}\n\ninterface UnitRectProps {\n x: number;\n y: number;\n width: number;\n height: number;\n className: string;\n // Used to determine if the rect should have a zig-zag edge on the top or bottom\n overflowTop?: boolean;\n overflowBottom?: boolean;\n [key: string]: any;\n}\n\nconst UnitRect = forwardRef((props: UnitRectProps, ref) => {\n const {\n x,\n y,\n width,\n height,\n overflowTop = false,\n overflowBottom = false,\n ...rest\n } = props;\n\n if (!overflowTop && !overflowBottom) {\n return h(\"rect\", {\n x,\n y,\n width,\n height,\n ref,\n ...rest,\n });\n } else {\n const d = zigZagBoxPath(x, y, width, height, overflowTop, overflowBottom);\n return h(\"path\", {\n d,\n ref,\n ...rest,\n });\n }\n});\n\nfunction LabeledUnit(props: LabeledUnitProps) {\n const {\n division,\n label,\n onLabelUpdated,\n widthFraction,\n showLabel = true,\n backgroundColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const bounds = {\n ...useUnitRect(division, { widthFraction, axisType }),\n ...baseBounds,\n };\n const { width, height } = bounds;\n return h(\n Unit,\n {\n className: \"labeled-unit\",\n division,\n backgroundColor,\n patternID,\n ...bounds,\n },\n [\n h.if(showLabel)(\n ForeignObject,\n { ...bounds, className: \"unit-label-container\" },\n h(SizeAwareLabel, {\n className: \"unit-overlay\",\n labelClassName: \"unit-label\",\n style: { width, height },\n label,\n onVisibilityChanged(viz) {\n onLabelUpdated(label, viz);\n },\n }),\n ),\n ],\n );\n}\n\nfunction UnitBoxes<T>(props: {\n unitComponent: React.FunctionComponent<{ division: T }>;\n unitComponentProps?: any;\n transformDivisions?(divisions: T[]): T[];\n transformDivision?: (\n division: any,\n index: number,\n divisions: any[],\n ) => T | null;\n}) {\n const { unitComponent = Unit, unitComponentProps = {} } = props;\n const { divisions } = useContext(ColumnContext);\n\n if (divisions.length == 0) {\n console.warn(\"No divisions found in column context\");\n return null;\n }\n\n const children = useMemo(() => {\n return divisions.map((division: any, i) => {\n // @ts-ignore\n return h(unitComponent, {\n division,\n key: division.unit_id,\n ...unitComponentProps,\n });\n });\n }, [divisions, unitComponent, unitComponentProps]);\n\n return h(\n PatternDefsProvider,\n { resolveID, scalePattern },\n h(\"g.divisions\", children),\n );\n}\n\nexport { LabeledUnit, Unit, UnitBoxes, UnitProps };\n"],"names":["hyper","styles","ColumnAxisType","useContext","ColumnContext","ColumnLayoutContext","getUnitHeightRange","useColumn","resolveID","useGeologicPattern","classNames","useUnitSelectionTarget","forwardRef","zigZagBoxPath","ForeignObject","SizeAwareLabel","useMemo","PatternDefsProvider","scalePattern"],"mappings":"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"}
1
+ {"version":3,"file":"boxes.cjs","sources":["../../src/units/boxes.ts"],"sourcesContent":["import {\n ColumnAxisType,\n ColumnContext,\n ColumnLayoutContext,\n ClippableRect,\n ForeignObject,\n PatternDefsProvider,\n useColumn,\n useGeologicPattern,\n} from \"@macrostrat/column-components\";\nimport { SizeAwareLabel, Clickable } from \"@macrostrat/ui-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport { ReactNode, useContext, useMemo } from \"react\";\nimport { resolveID, scalePattern } from \"./resolvers\";\nimport { useUnitSelectionTarget } from \"../data-provider\";\nimport { useLithologies } from \"@macrostrat/data-provider\";\nimport { IUnit } from \"./types\";\nimport styles from \"./boxes.module.sass\";\nimport classNames from \"classnames\";\nimport { getUnitHeightRange } from \"../prepare-units/utils\";\nimport { getMixedUnitColor } from \"./colors\";\nimport type { RectBounds } from \"./types\";\n\nconst h = hyper.styled(styles);\n\n/** Resolve a class name through this file's CSS module exactly as the styled\n * `h` would (module-scoped classes are hashed; unknown/global classes pass\n * through). Needed because `ClippableRect` renders the element in\n * `@macrostrat/column-components`, so class resolution must happen here. */\nconst cls = (name: string): string => (styles as any)[name] ?? name;\n\ninterface UnitRectOptions {\n widthFraction?: number;\n axisType?: ColumnAxisType;\n // Padding to create overflow for zig-zags or other ornamented edges\n padding?: number;\n}\n\ninterface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {\n division: IUnit;\n resolveID?(IUnit): string;\n UUID?: string;\n defaultFill?: string;\n widthFraction?: number;\n children?: ReactNode;\n className?: string;\n fill?: string;\n backgroundColor?: string;\n patternColor?: string;\n patternID?: string | number;\n}\n\nexport interface LabeledUnitProps\n extends UnitRectOptions, Clickable, Partial<RectBounds> {\n division: IUnit;\n patternID?: string | number;\n label: string;\n onLabelUpdated?(label: string, shown: boolean);\n halfWidth?: boolean;\n showLabel?: boolean;\n backgroundColor?: string;\n}\n\nfunction useUnitRect(\n division: IUnit,\n options: UnitRectOptions = {},\n): RectBounds {\n const {\n widthFraction = 1,\n axisType = ColumnAxisType.AGE,\n padding = 0,\n } = options;\n const { scale } = useContext(ColumnContext);\n const { width } = useContext(ColumnLayoutContext);\n\n const [bottomHeight, topHeight] = getUnitHeightRange(division, axisType);\n\n const y = scale(topHeight);\n const height = Math.abs(scale(bottomHeight) - y);\n\n return {\n x: width * (1 - widthFraction) - padding,\n y: y - padding,\n height: height + padding * 2,\n width: widthFraction * width + padding * 2,\n };\n}\n\nexport function MinimalUnit(props) {\n const {\n division: d,\n children,\n className,\n widthFraction = 1,\n axisType: _, // not sure why this is brought in...\n nColumns: __,\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const lithMap = useLithologies();\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n };\n\n const backgroundColor = getMixedUnitColor(d, lithMap, null, false);\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n \"--column-stroke-color\": backgroundColor,\n },\n },\n [\n h(\"rect.unit.background\", {\n ref,\n ...bounds,\n fill: backgroundColor,\n fillOpacity: 0.8,\n stroke: backgroundColor,\n onClick,\n }),\n h.if(linked)(\"rect.linked-overlay\", bounds),\n h.if(selected)(\"rect.selection-overlay\", bounds),\n ],\n );\n}\n\nfunction Unit(props: UnitProps) {\n const {\n division: d,\n children,\n fill,\n defaultFill = \"transparent\",\n className,\n widthFraction = 1,\n backgroundColor,\n patternColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n\n const hasOverflowTop = d.t_clip_pos != null;\n const hasOverflowBottom = d.b_clip_pos != null;\n\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n overflowTop: hasOverflowTop,\n overflowBottom: hasOverflowBottom,\n };\n const _patternID = patternID ?? resolveID(d);\n let _fill = fill ?? useGeologicPattern(_patternID, defaultFill);\n\n const hasBackgroundColor = backgroundColor != null;\n\n const _className = classNames(className, { colored: hasBackgroundColor });\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className: _className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n },\n },\n [\n h(ClippableRect, {\n ...bounds,\n fill: backgroundColor,\n onClick,\n className: cls(\"background\"),\n }),\n h(ClippableRect, {\n ref,\n ...bounds,\n fill: _fill,\n //mask,\n onClick,\n className: cls(\"unit\"),\n }),\n h.if(linked)(ClippableRect, {\n ...bounds,\n className: cls(\"linked-overlay\"),\n }),\n h.if(selected)(ClippableRect, {\n ...bounds,\n className: cls(\"selection-overlay\"),\n }),\n //defs,\n children,\n ],\n );\n}\n\nfunction LabeledUnit(props: LabeledUnitProps) {\n const {\n division,\n label,\n onLabelUpdated,\n widthFraction,\n showLabel = true,\n backgroundColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType, isTransitioning, hideLabelsWhileTransitioning } =\n useColumn();\n const bounds = {\n ...useUnitRect(division, { widthFraction, axisType }),\n ...baseBounds,\n };\n const { width, height } = bounds;\n // Labels stay visible through the animation by default. `hideLabelsWhileTransitioning`\n // is a perf escape hatch: when set, the `foreignObject` label (whose HTML\n // reflows on every size change) is skipped mid-transition and restored on settle.\n const skipLabel = isTransitioning && hideLabelsWhileTransitioning;\n return h(\n Unit,\n {\n className: \"labeled-unit\",\n division,\n backgroundColor,\n patternID,\n ...bounds,\n },\n [\n h.if(showLabel && !skipLabel)(\n ForeignObject,\n { ...bounds, className: \"unit-label-container\" },\n h(SizeAwareLabel, {\n className: \"unit-overlay\",\n labelClassName: \"unit-label\",\n style: { width, height },\n label,\n // Re-fit the label when a transition settles (isTransitioning flips),\n // not on every intermediate frame.\n remeasureKey: isTransitioning,\n onVisibilityChanged(viz) {\n onLabelUpdated(label, viz);\n },\n }),\n ),\n ],\n );\n}\n\nfunction UnitBoxes<T>(props: {\n unitComponent: React.FunctionComponent<{ division: T }>;\n unitComponentProps?: any;\n transformDivisions?(divisions: T[]): T[];\n transformDivision?: (\n division: any,\n index: number,\n divisions: any[],\n ) => T | null;\n}) {\n const { unitComponent = Unit, unitComponentProps = {} } = props;\n const { divisions } = useContext(ColumnContext);\n\n if (divisions.length == 0) {\n console.warn(\"No divisions found in column context\");\n return null;\n }\n\n const children = useMemo(() => {\n return divisions.map((division: any, i) => {\n // @ts-ignore\n return h(unitComponent, {\n division,\n key: division.unit_id,\n ...unitComponentProps,\n });\n });\n }, [divisions, unitComponent, unitComponentProps]);\n\n return h(\n PatternDefsProvider,\n { resolveID, scalePattern },\n h(\"g.divisions\", children),\n );\n}\n\nexport { LabeledUnit, Unit, UnitBoxes, UnitProps };\n"],"names":["hyper","styles","ColumnAxisType","useContext","ColumnContext","ColumnLayoutContext","getUnitHeightRange","useColumn","resolveID","useGeologicPattern","classNames","useUnitSelectionTarget","ClippableRect","ForeignObject","SizeAwareLabel","useMemo","PatternDefsProvider","scalePattern"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { useColumn, ForeignObject, ColumnContext, PatternDefsProvider, ColumnAxisType, ColumnLayoutContext, useGeologicPattern, zigZagBoxPath } from "@macrostrat/column-components";
1
+ import { useColumn, ForeignObject, ColumnContext, PatternDefsProvider, ColumnAxisType, ColumnLayoutContext, useGeologicPattern, ClippableRect } from "@macrostrat/column-components";
2
2
  import { SizeAwareLabel } from "@macrostrat/ui-components";
3
3
  import h$1 from "@macrostrat/hyper";
4
- import { useContext, useMemo, forwardRef } from "react";
4
+ import { useContext, useMemo } from "react";
5
5
  import { scalePattern, resolveID } from "./resolvers.js";
6
6
  import "@macrostrat/data-provider";
7
7
  import h$2 from "./boxes.module.sass.js";
@@ -9,6 +9,7 @@ import classNames from "classnames";
9
9
  import { getUnitHeightRange } from "../prepare-units/utils.js";
10
10
  import { useUnitSelectionTarget } from "../data-provider/unit-selection.js";
11
11
  const h = h$1.styled(h$2);
12
+ const cls = (name) => h$2[name] ?? name;
12
13
  function useUnitRect(division, options = {}) {
13
14
  const {
14
15
  widthFraction = 1,
@@ -65,55 +66,33 @@ function Unit(props) {
65
66
  }
66
67
  },
67
68
  [
68
- h(UnitRect, {
69
+ h(ClippableRect, {
69
70
  ...bounds,
70
71
  fill: backgroundColor,
71
72
  onClick,
72
- className: "background"
73
+ className: cls("background")
73
74
  }),
74
- h(UnitRect, {
75
+ h(ClippableRect, {
75
76
  ref,
76
77
  ...bounds,
77
78
  fill: _fill,
78
79
  //mask,
79
80
  onClick,
80
- className: "unit"
81
+ className: cls("unit")
82
+ }),
83
+ h.if(linked)(ClippableRect, {
84
+ ...bounds,
85
+ className: cls("linked-overlay")
86
+ }),
87
+ h.if(selected)(ClippableRect, {
88
+ ...bounds,
89
+ className: cls("selection-overlay")
81
90
  }),
82
- h.if(linked)(UnitRect, { ...bounds, className: "linked-overlay" }),
83
- h.if(selected)(UnitRect, { ...bounds, className: "selection-overlay" }),
84
91
  //defs,
85
92
  children
86
93
  ]
87
94
  );
88
95
  }
89
- const UnitRect = forwardRef((props, ref) => {
90
- const {
91
- x,
92
- y,
93
- width,
94
- height,
95
- overflowTop = false,
96
- overflowBottom = false,
97
- ...rest
98
- } = props;
99
- if (!overflowTop && !overflowBottom) {
100
- return h("rect", {
101
- x,
102
- y,
103
- width,
104
- height,
105
- ref,
106
- ...rest
107
- });
108
- } else {
109
- const d = zigZagBoxPath(x, y, width, height, overflowTop, overflowBottom);
110
- return h("path", {
111
- d,
112
- ref,
113
- ...rest
114
- });
115
- }
116
- });
117
96
  function LabeledUnit(props) {
118
97
  const {
119
98
  division,
@@ -127,12 +106,13 @@ function LabeledUnit(props) {
127
106
  // not sure why this is brought in...
128
107
  ...baseBounds
129
108
  } = props;
130
- const { axisType } = useColumn();
109
+ const { axisType, isTransitioning, hideLabelsWhileTransitioning } = useColumn();
131
110
  const bounds = {
132
111
  ...useUnitRect(division, { widthFraction, axisType }),
133
112
  ...baseBounds
134
113
  };
135
114
  const { width, height } = bounds;
115
+ const skipLabel = isTransitioning && hideLabelsWhileTransitioning;
136
116
  return h(
137
117
  Unit,
138
118
  {
@@ -143,7 +123,7 @@ function LabeledUnit(props) {
143
123
  ...bounds
144
124
  },
145
125
  [
146
- h.if(showLabel)(
126
+ h.if(showLabel && !skipLabel)(
147
127
  ForeignObject,
148
128
  { ...bounds, className: "unit-label-container" },
149
129
  h(SizeAwareLabel, {
@@ -151,6 +131,9 @@ function LabeledUnit(props) {
151
131
  labelClassName: "unit-label",
152
132
  style: { width, height },
153
133
  label,
134
+ // Re-fit the label when a transition settles (isTransitioning flips),
135
+ // not on every intermediate frame.
136
+ remeasureKey: isTransitioning,
154
137
  onVisibilityChanged(viz) {
155
138
  onLabelUpdated(label, viz);
156
139
  }
@@ -1 +1 @@
1
- {"version":3,"file":"boxes.js","sources":["../../src/units/boxes.ts"],"sourcesContent":["import {\n ColumnAxisType,\n ColumnContext,\n ColumnLayoutContext,\n ForeignObject,\n PatternDefsProvider,\n useColumn,\n useGeologicPattern,\n zigZagBoxPath,\n} from \"@macrostrat/column-components\";\nimport { SizeAwareLabel, Clickable } from \"@macrostrat/ui-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport { forwardRef, ReactNode, useContext, useMemo } from \"react\";\nimport { resolveID, scalePattern } from \"./resolvers\";\nimport { useUnitSelectionTarget } from \"../data-provider\";\nimport { useLithologies } from \"@macrostrat/data-provider\";\nimport { IUnit } from \"./types\";\nimport styles from \"./boxes.module.sass\";\nimport classNames from \"classnames\";\nimport { getUnitHeightRange } from \"../prepare-units/utils\";\nimport { getMixedUnitColor } from \"./colors\";\nimport type { RectBounds } from \"./types\";\n\nconst h = hyper.styled(styles);\n\ninterface UnitRectOptions {\n widthFraction?: number;\n axisType?: ColumnAxisType;\n // Padding to create overflow for zig-zags or other ornamented edges\n padding?: number;\n}\n\ninterface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {\n division: IUnit;\n resolveID?(IUnit): string;\n UUID?: string;\n defaultFill?: string;\n widthFraction?: number;\n children?: ReactNode;\n className?: string;\n fill?: string;\n backgroundColor?: string;\n patternColor?: string;\n patternID?: string | number;\n}\n\nexport interface LabeledUnitProps\n extends UnitRectOptions, Clickable, Partial<RectBounds> {\n division: IUnit;\n patternID?: string | number;\n label: string;\n onLabelUpdated?(label: string, shown: boolean);\n halfWidth?: boolean;\n showLabel?: boolean;\n backgroundColor?: string;\n}\n\nfunction useUnitRect(\n division: IUnit,\n options: UnitRectOptions = {},\n): RectBounds {\n const {\n widthFraction = 1,\n axisType = ColumnAxisType.AGE,\n padding = 0,\n } = options;\n const { scale } = useContext(ColumnContext);\n const { width } = useContext(ColumnLayoutContext);\n\n const [bottomHeight, topHeight] = getUnitHeightRange(division, axisType);\n\n const y = scale(topHeight);\n const height = Math.abs(scale(bottomHeight) - y);\n\n return {\n x: width * (1 - widthFraction) - padding,\n y: y - padding,\n height: height + padding * 2,\n width: widthFraction * width + padding * 2,\n };\n}\n\nexport function MinimalUnit(props) {\n const {\n division: d,\n children,\n className,\n widthFraction = 1,\n axisType: _, // not sure why this is brought in...\n nColumns: __,\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const lithMap = useLithologies();\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n };\n\n const backgroundColor = getMixedUnitColor(d, lithMap, null, false);\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n \"--column-stroke-color\": backgroundColor,\n },\n },\n [\n h(\"rect.unit.background\", {\n ref,\n ...bounds,\n fill: backgroundColor,\n fillOpacity: 0.8,\n stroke: backgroundColor,\n onClick,\n }),\n h.if(linked)(\"rect.linked-overlay\", bounds),\n h.if(selected)(\"rect.selection-overlay\", bounds),\n ],\n );\n}\n\nfunction Unit(props: UnitProps) {\n const {\n division: d,\n children,\n fill,\n defaultFill = \"transparent\",\n className,\n widthFraction = 1,\n backgroundColor,\n patternColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n\n const hasOverflowTop = d.t_clip_pos != null;\n const hasOverflowBottom = d.b_clip_pos != null;\n\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n overflowTop: hasOverflowTop,\n overflowBottom: hasOverflowBottom,\n };\n const _patternID = patternID ?? resolveID(d);\n let _fill = fill ?? useGeologicPattern(_patternID, defaultFill);\n\n const hasBackgroundColor = backgroundColor != null;\n\n const _className = classNames(className, { colored: hasBackgroundColor });\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className: _className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n },\n },\n [\n h(UnitRect, {\n ...bounds,\n fill: backgroundColor,\n onClick,\n className: \"background\",\n }),\n h(UnitRect, {\n ref,\n ...bounds,\n fill: _fill,\n //mask,\n onClick,\n className: \"unit\",\n }),\n h.if(linked)(UnitRect, { ...bounds, className: \"linked-overlay\" }),\n h.if(selected)(UnitRect, { ...bounds, className: \"selection-overlay\" }),\n //defs,\n children,\n ],\n );\n}\n\ninterface UnitRectProps {\n x: number;\n y: number;\n width: number;\n height: number;\n className: string;\n // Used to determine if the rect should have a zig-zag edge on the top or bottom\n overflowTop?: boolean;\n overflowBottom?: boolean;\n [key: string]: any;\n}\n\nconst UnitRect = forwardRef((props: UnitRectProps, ref) => {\n const {\n x,\n y,\n width,\n height,\n overflowTop = false,\n overflowBottom = false,\n ...rest\n } = props;\n\n if (!overflowTop && !overflowBottom) {\n return h(\"rect\", {\n x,\n y,\n width,\n height,\n ref,\n ...rest,\n });\n } else {\n const d = zigZagBoxPath(x, y, width, height, overflowTop, overflowBottom);\n return h(\"path\", {\n d,\n ref,\n ...rest,\n });\n }\n});\n\nfunction LabeledUnit(props: LabeledUnitProps) {\n const {\n division,\n label,\n onLabelUpdated,\n widthFraction,\n showLabel = true,\n backgroundColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const bounds = {\n ...useUnitRect(division, { widthFraction, axisType }),\n ...baseBounds,\n };\n const { width, height } = bounds;\n return h(\n Unit,\n {\n className: \"labeled-unit\",\n division,\n backgroundColor,\n patternID,\n ...bounds,\n },\n [\n h.if(showLabel)(\n ForeignObject,\n { ...bounds, className: \"unit-label-container\" },\n h(SizeAwareLabel, {\n className: \"unit-overlay\",\n labelClassName: \"unit-label\",\n style: { width, height },\n label,\n onVisibilityChanged(viz) {\n onLabelUpdated(label, viz);\n },\n }),\n ),\n ],\n );\n}\n\nfunction UnitBoxes<T>(props: {\n unitComponent: React.FunctionComponent<{ division: T }>;\n unitComponentProps?: any;\n transformDivisions?(divisions: T[]): T[];\n transformDivision?: (\n division: any,\n index: number,\n divisions: any[],\n ) => T | null;\n}) {\n const { unitComponent = Unit, unitComponentProps = {} } = props;\n const { divisions } = useContext(ColumnContext);\n\n if (divisions.length == 0) {\n console.warn(\"No divisions found in column context\");\n return null;\n }\n\n const children = useMemo(() => {\n return divisions.map((division: any, i) => {\n // @ts-ignore\n return h(unitComponent, {\n division,\n key: division.unit_id,\n ...unitComponentProps,\n });\n });\n }, [divisions, unitComponent, unitComponentProps]);\n\n return h(\n PatternDefsProvider,\n { resolveID, scalePattern },\n h(\"g.divisions\", children),\n );\n}\n\nexport { LabeledUnit, Unit, UnitBoxes, UnitProps };\n"],"names":["hyper","styles"],"mappings":"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"}
1
+ {"version":3,"file":"boxes.js","sources":["../../src/units/boxes.ts"],"sourcesContent":["import {\n ColumnAxisType,\n ColumnContext,\n ColumnLayoutContext,\n ClippableRect,\n ForeignObject,\n PatternDefsProvider,\n useColumn,\n useGeologicPattern,\n} from \"@macrostrat/column-components\";\nimport { SizeAwareLabel, Clickable } from \"@macrostrat/ui-components\";\nimport hyper from \"@macrostrat/hyper\";\nimport { ReactNode, useContext, useMemo } from \"react\";\nimport { resolveID, scalePattern } from \"./resolvers\";\nimport { useUnitSelectionTarget } from \"../data-provider\";\nimport { useLithologies } from \"@macrostrat/data-provider\";\nimport { IUnit } from \"./types\";\nimport styles from \"./boxes.module.sass\";\nimport classNames from \"classnames\";\nimport { getUnitHeightRange } from \"../prepare-units/utils\";\nimport { getMixedUnitColor } from \"./colors\";\nimport type { RectBounds } from \"./types\";\n\nconst h = hyper.styled(styles);\n\n/** Resolve a class name through this file's CSS module exactly as the styled\n * `h` would (module-scoped classes are hashed; unknown/global classes pass\n * through). Needed because `ClippableRect` renders the element in\n * `@macrostrat/column-components`, so class resolution must happen here. */\nconst cls = (name: string): string => (styles as any)[name] ?? name;\n\ninterface UnitRectOptions {\n widthFraction?: number;\n axisType?: ColumnAxisType;\n // Padding to create overflow for zig-zags or other ornamented edges\n padding?: number;\n}\n\ninterface UnitProps extends Clickable, Partial<RectBounds>, UnitRectOptions {\n division: IUnit;\n resolveID?(IUnit): string;\n UUID?: string;\n defaultFill?: string;\n widthFraction?: number;\n children?: ReactNode;\n className?: string;\n fill?: string;\n backgroundColor?: string;\n patternColor?: string;\n patternID?: string | number;\n}\n\nexport interface LabeledUnitProps\n extends UnitRectOptions, Clickable, Partial<RectBounds> {\n division: IUnit;\n patternID?: string | number;\n label: string;\n onLabelUpdated?(label: string, shown: boolean);\n halfWidth?: boolean;\n showLabel?: boolean;\n backgroundColor?: string;\n}\n\nfunction useUnitRect(\n division: IUnit,\n options: UnitRectOptions = {},\n): RectBounds {\n const {\n widthFraction = 1,\n axisType = ColumnAxisType.AGE,\n padding = 0,\n } = options;\n const { scale } = useContext(ColumnContext);\n const { width } = useContext(ColumnLayoutContext);\n\n const [bottomHeight, topHeight] = getUnitHeightRange(division, axisType);\n\n const y = scale(topHeight);\n const height = Math.abs(scale(bottomHeight) - y);\n\n return {\n x: width * (1 - widthFraction) - padding,\n y: y - padding,\n height: height + padding * 2,\n width: widthFraction * width + padding * 2,\n };\n}\n\nexport function MinimalUnit(props) {\n const {\n division: d,\n children,\n className,\n widthFraction = 1,\n axisType: _, // not sure why this is brought in...\n nColumns: __,\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n const lithMap = useLithologies();\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n };\n\n const backgroundColor = getMixedUnitColor(d, lithMap, null, false);\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n \"--column-stroke-color\": backgroundColor,\n },\n },\n [\n h(\"rect.unit.background\", {\n ref,\n ...bounds,\n fill: backgroundColor,\n fillOpacity: 0.8,\n stroke: backgroundColor,\n onClick,\n }),\n h.if(linked)(\"rect.linked-overlay\", bounds),\n h.if(selected)(\"rect.selection-overlay\", bounds),\n ],\n );\n}\n\nfunction Unit(props: UnitProps) {\n const {\n division: d,\n children,\n fill,\n defaultFill = \"transparent\",\n className,\n widthFraction = 1,\n backgroundColor,\n patternColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType } = useColumn();\n\n const hasOverflowTop = d.t_clip_pos != null;\n const hasOverflowBottom = d.b_clip_pos != null;\n\n const bounds = {\n ...useUnitRect(d, { widthFraction, axisType }),\n ...baseBounds,\n overflowTop: hasOverflowTop,\n overflowBottom: hasOverflowBottom,\n };\n const _patternID = patternID ?? resolveID(d);\n let _fill = fill ?? useGeologicPattern(_patternID, defaultFill);\n\n const hasBackgroundColor = backgroundColor != null;\n\n const _className = classNames(className, { colored: hasBackgroundColor });\n\n const [ref, selected, onClick, linked] = useUnitSelectionTarget(d);\n\n return h(\n \"g.unit\",\n {\n className: _className,\n style: {\n \"--column-unit-background-color\": backgroundColor,\n },\n },\n [\n h(ClippableRect, {\n ...bounds,\n fill: backgroundColor,\n onClick,\n className: cls(\"background\"),\n }),\n h(ClippableRect, {\n ref,\n ...bounds,\n fill: _fill,\n //mask,\n onClick,\n className: cls(\"unit\"),\n }),\n h.if(linked)(ClippableRect, {\n ...bounds,\n className: cls(\"linked-overlay\"),\n }),\n h.if(selected)(ClippableRect, {\n ...bounds,\n className: cls(\"selection-overlay\"),\n }),\n //defs,\n children,\n ],\n );\n}\n\nfunction LabeledUnit(props: LabeledUnitProps) {\n const {\n division,\n label,\n onLabelUpdated,\n widthFraction,\n showLabel = true,\n backgroundColor,\n patternID,\n axisType: _, // not sure why this is brought in...\n ...baseBounds\n } = props;\n\n const { axisType, isTransitioning, hideLabelsWhileTransitioning } =\n useColumn();\n const bounds = {\n ...useUnitRect(division, { widthFraction, axisType }),\n ...baseBounds,\n };\n const { width, height } = bounds;\n // Labels stay visible through the animation by default. `hideLabelsWhileTransitioning`\n // is a perf escape hatch: when set, the `foreignObject` label (whose HTML\n // reflows on every size change) is skipped mid-transition and restored on settle.\n const skipLabel = isTransitioning && hideLabelsWhileTransitioning;\n return h(\n Unit,\n {\n className: \"labeled-unit\",\n division,\n backgroundColor,\n patternID,\n ...bounds,\n },\n [\n h.if(showLabel && !skipLabel)(\n ForeignObject,\n { ...bounds, className: \"unit-label-container\" },\n h(SizeAwareLabel, {\n className: \"unit-overlay\",\n labelClassName: \"unit-label\",\n style: { width, height },\n label,\n // Re-fit the label when a transition settles (isTransitioning flips),\n // not on every intermediate frame.\n remeasureKey: isTransitioning,\n onVisibilityChanged(viz) {\n onLabelUpdated(label, viz);\n },\n }),\n ),\n ],\n );\n}\n\nfunction UnitBoxes<T>(props: {\n unitComponent: React.FunctionComponent<{ division: T }>;\n unitComponentProps?: any;\n transformDivisions?(divisions: T[]): T[];\n transformDivision?: (\n division: any,\n index: number,\n divisions: any[],\n ) => T | null;\n}) {\n const { unitComponent = Unit, unitComponentProps = {} } = props;\n const { divisions } = useContext(ColumnContext);\n\n if (divisions.length == 0) {\n console.warn(\"No divisions found in column context\");\n return null;\n }\n\n const children = useMemo(() => {\n return divisions.map((division: any, i) => {\n // @ts-ignore\n return h(unitComponent, {\n division,\n key: division.unit_id,\n ...unitComponentProps,\n });\n });\n }, [divisions, unitComponent, unitComponentProps]);\n\n return h(\n PatternDefsProvider,\n { resolveID, scalePattern },\n h(\"g.divisions\", children),\n );\n}\n\nexport { LabeledUnit, Unit, UnitBoxes, UnitProps };\n"],"names":["hyper","styles"],"mappings":"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"}
@@ -16,22 +16,22 @@ function LabelTrackerProvider(props) {
16
16
  const { children, units, findUnitID = findMacrostratUnitID } = props;
17
17
  const [unlabeledDivisions, setUnlabeledDivisions] = React.useState(null);
18
18
  const labelTrackerRef = React.useRef({});
19
+ const recompute = React.useCallback(() => {
20
+ const tracker = labelTrackerRef.current;
21
+ const allReported = units.every((d) => findUnitID(d) in tracker);
22
+ if (!allReported) return;
23
+ setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));
24
+ }, [units, findUnitID]);
19
25
  const trackLabelVisibility = React.useCallback(
20
26
  (div, visible) => {
21
- const id = findUnitID(div);
22
- labelTrackerRef.current[id] = visible;
23
- if (Object.keys(labelTrackerRef.current).length == units.length) {
24
- setUnlabeledDivisions(
25
- // @ts-ignore
26
- units.filter((d) => {
27
- const id2 = findUnitID(d);
28
- return labelTrackerRef.current[id2] == false;
29
- })
30
- );
31
- }
27
+ labelTrackerRef.current[findUnitID(div)] = visible;
28
+ recompute();
32
29
  },
33
- [labelTrackerRef, units, findUnitID]
30
+ [recompute, findUnitID]
34
31
  );
32
+ React.useEffect(() => {
33
+ recompute();
34
+ }, [recompute]);
35
35
  const value = trackLabelVisibility;
36
36
  return h(
37
37
  LabelTrackerContext.Provider,
@@ -1 +1 @@
1
- {"version":3,"file":"composite.cjs","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n const id = findUnitID(div);\n labelTrackerRef.current[id] = visible;\n if (Object.keys(labelTrackerRef.current).length == units.length) {\n setUnlabeledDivisions(\n // @ts-ignore\n units.filter((d) => {\n const id = findUnitID(d);\n return labelTrackerRef.current[id] == false;\n }),\n );\n }\n },\n [labelTrackerRef, units, findUnitID],\n );\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["hyperStyled","styles","createContext","useState","useRef","useCallback","id","defaultNameFunction","useContext","LabeledUnit","LithologyColumn","UnitBoxes","useEffect","useMacrostratColumnData","useCompositeScale","useUnitSelectionDispatch","SVG","UnitNamesColumn","ColumnContext"],"mappings":"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"}
1
+ {"version":3,"file":"composite.cjs","sources":["../../src/units/composite.ts"],"sourcesContent":["import { hyperStyled } from \"@macrostrat/hyper\";\nimport {\n ColumnContext,\n LithologyColumn,\n SVG,\n} from \"@macrostrat/column-components\";\nimport { defaultNameFunction, UnitNamesColumn } from \"./names\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BaseUnit } from \"@macrostrat/api-types\";\nimport { LabeledUnit, UnitBoxes } from \"./boxes\";\nimport styles from \"./composite.module.sass\";\nimport {\n useCompositeScale,\n useMacrostratColumnData,\n useUnitSelectionDispatch,\n} from \"../data-provider\";\n\nconst h = hyperStyled(styles);\n\ninterface LabelTracker {\n [key: number]: boolean;\n}\n\nconst LabelTrackerContext = createContext(null);\nconst UnlabeledDivisionsContext = createContext(null);\n\nconst findMacrostratUnitID = (u) => u.unit_id;\n\nexport function LabelTrackerProvider(props) {\n /** Tracker for units to handle state for whether their labels fit inline or not.\n * Designed to work for single or composite columns.\n */\n const { children, units, findUnitID = findMacrostratUnitID } = props;\n const [unlabeledDivisions, setUnlabeledDivisions] = useState<\n BaseUnit[] | null\n >(null);\n const labelTrackerRef = useRef<LabelTracker>({});\n\n const recompute = useCallback(() => {\n // Recompute over the *current* unit set (which changes as the column zooms).\n // The tracker ref accumulates entries for units seen at any zoom level, so\n // we gate on whether every currently-visible unit has reported — not on the\n // total number of tracked units, which would go stale and freeze the notes.\n const tracker = labelTrackerRef.current;\n const allReported = units.every((d) => findUnitID(d) in tracker);\n if (!allReported) return;\n setUnlabeledDivisions(units.filter((d) => tracker[findUnitID(d)] === false));\n }, [units, findUnitID]);\n\n const trackLabelVisibility = useCallback(\n (div, visible) => {\n labelTrackerRef.current[findUnitID(div)] = visible;\n recompute();\n },\n [recompute, findUnitID],\n );\n\n // Re-sync when the visible unit set changes (e.g. on zoom), so a unit whose\n // label now fits inline stops also rendering as a note, and vice versa.\n useEffect(() => {\n recompute();\n }, [recompute]);\n\n const value = trackLabelVisibility;\n return h(\n LabelTrackerContext.Provider,\n { value },\n h(\n UnlabeledDivisionsContext.Provider,\n { value: unlabeledDivisions },\n children,\n ),\n );\n}\n\nfunction TrackedLabeledUnit({\n division,\n nameForDivision = defaultNameFunction,\n ...rest\n}) {\n const trackLabelVisibility = useContext(LabelTrackerContext);\n return h(LabeledUnit, {\n division,\n label: nameForDivision(division),\n onLabelUpdated(label, visible) {\n // If there is al LabelTrackerContext, update the label visibility\n trackLabelVisibility?.(division, visible);\n },\n ...rest,\n });\n}\n\nexport const CompositeUnitComponent = TrackedLabeledUnit;\n\ntype BaseUnitProps = {\n width: number;\n showLabels?: boolean;\n columnWidth?: number;\n clipToFrame?: boolean;\n};\n\ntype ICompositeUnitProps = BaseUnitProps & {\n gutterWidth?: number;\n labelOffset?: number;\n paddingLeft?: number;\n nameForDivision?: (division: BaseUnit) => string;\n children?: React.ReactNode;\n unitComponent?: React.FC<any>;\n unitComponentProps?: any;\n noteMode?: \"labeled\" | \"unlabeled\";\n showLabelColumn?: boolean;\n noteComponent?: React.FC<any>;\n shouldRenderNote?: (d: any) => boolean;\n};\n\ninterface CompositeUnitProps {\n unitComponent: React.FC<any>;\n unitComponentProps?: any;\n width: number;\n showLabels?: boolean;\n clipToFrame?: boolean;\n}\n\nexport function CompositeUnitsColumn(props: CompositeUnitProps) {\n /*\n A column with units and names either\n overlapping or offset to the right\n */\n const {\n width,\n unitComponent = TrackedLabeledUnit,\n unitComponentProps,\n clipToFrame,\n ...rest\n } = props;\n\n return h(LithologyColumn, { width, clipToFrame }, [\n h(UnitBoxes, {\n unitComponent,\n unitComponentProps,\n ...rest,\n }),\n ]);\n}\n\nexport function AnnotatedUnitsColumn(props: ICompositeUnitProps) {\n useEffect(() => {\n console.warn(\n \"AnnotatedUnitsColumn is deprecated and currently renders a no-op for transition purposes\",\n );\n }, []);\n return null;\n}\n\nexport function SectionLabelsColumn(props: ICompositeUnitProps) {\n // Section with \"squishy\" time scale\n const {\n width = 300,\n noteMode = \"unlabeled\",\n labelOffset = 30,\n noteComponent,\n shouldRenderNote,\n } = props;\n\n const { totalHeight, axisType } = useMacrostratColumnData();\n const _compositeScale = useCompositeScale();\n\n const unlabeledUnits = useContext(UnlabeledDivisionsContext);\n const unitsToLabel = noteMode == \"unlabeled\" ? unlabeledUnits : undefined;\n\n const selectUnit = useUnitSelectionDispatch();\n\n return h(\"div.section-labels-column\", [\n h(\n ColumnNotesProvider,\n {\n units: [],\n scale: _compositeScale,\n totalHeight,\n axisType,\n },\n h(\n SVG,\n {\n height: totalHeight,\n innerWidth: width - 4,\n paddingH: 1,\n paddingLeft: 3,\n },\n h(UnitNamesColumn, {\n divisions: unitsToLabel,\n paddingLeft: labelOffset,\n width,\n noteComponent,\n shouldRenderNote,\n scale: _compositeScale,\n onClickNote(note) {\n selectUnit(note.data, null, null);\n },\n }),\n ),\n ),\n ]);\n}\n\nexport function ColumnNotesProvider(props) {\n // A fake column axis provider that allows scales to cross\n const { children, scale, totalHeight, pixelScale } = props;\n\n const { axisType } = useMacrostratColumnData();\n\n return h(\n ColumnContext.Provider,\n {\n value: {\n divisions: [],\n scale,\n scaleClamped: scale,\n pixelHeight: totalHeight,\n pixelsPerMeter: pixelScale,\n axisType,\n zoom: 1,\n },\n },\n children,\n );\n}\n\nexport { TrackedLabeledUnit, ICompositeUnitProps };\n"],"names":["hyperStyled","styles","createContext","useState","useRef","useCallback","useEffect","defaultNameFunction","useContext","LabeledUnit","LithologyColumn","UnitBoxes","useMacrostratColumnData","useCompositeScale","useUnitSelectionDispatch","SVG","UnitNamesColumn","ColumnContext"],"mappings":";;;;;;;;;;AAwBA,MAAM,IAAIA,IAAAA,YAAYC,gBAAM;AAM5B,MAAM,sBAAsBC,MAAAA,cAAc,IAAI;AAC9C,MAAM,4BAA4BA,MAAAA,cAAc,IAAI;AAEpD,MAAM,uBAAuB,CAAC,MAAM,EAAE;AAE/B,SAAS,qBAAqB,OAAO;AAI1C,QAAM,EAAE,UAAU,OAAO,aAAa,yBAAyB;AAC/D,QAAM,CAAC,oBAAoB,qBAAqB,IAAIC,MAAAA,SAElD,IAAI;AACN,QAAM,kBAAkBC,MAAAA,OAAqB,EAAE;AAE/C,QAAM,YAAYC,MAAAA,YAAY,MAAM;AAKlC,UAAM,UAAU,gBAAgB;AAChC,UAAM,cAAc,MAAM,MAAM,CAAC,MAAM,WAAW,CAAC,KAAK,OAAO;AAC/D,QAAI,CAAC,YAAa;AAClB,0BAAsB,MAAM,OAAO,CAAC,MAAM,QAAQ,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC;AAAA,EAC7E,GAAG,CAAC,OAAO,UAAU,CAAC;AAEtB,QAAM,uBAAuBA,MAAAA;AAAAA,IAC3B,CAAC,KAAK,YAAY;AAChB,sBAAgB,QAAQ,WAAW,GAAG,CAAC,IAAI;AAC3C,gBAAA;AAAA,IACF;AAAA,IACA,CAAC,WAAW,UAAU;AAAA,EAAA;AAKxBC,QAAAA,UAAU,MAAM;AACd,cAAA;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,QAAQ;AACd,SAAO;AAAA,IACL,oBAAoB;AAAA,IACpB,EAAE,MAAA;AAAA,IACF;AAAA,MACE,0BAA0B;AAAA,MAC1B,EAAE,OAAO,mBAAA;AAAA,MACT;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA,kBAAkBC,MAAAA;AAAAA,EAClB,GAAG;AACL,GAAG;AACD,QAAM,uBAAuBC,MAAAA,WAAW,mBAAmB;AAC3D,SAAO,EAAEC,MAAAA,aAAa;AAAA,IACpB;AAAA,IACA,OAAO,gBAAgB,QAAQ;AAAA,IAC/B,eAAe,OAAO,SAAS;AAE7B,6BAAuB,UAAU,OAAO;AAAA,IAC1C;AAAA,IACA,GAAG;AAAA,EAAA,CACJ;AACH;AAEO,MAAM,yBAAyB;AA+B/B,SAAS,qBAAqB,OAA2B;AAK9D,QAAM;AAAA,IACJ;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,IACD;AAEJ,SAAO,EAAEC,iBAAAA,iBAAiB,EAAE,OAAO,eAAe;AAAA,IAChD,EAAEC,MAAAA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IAAA,CACJ;AAAA,EAAA,CACF;AACH;AAEO,SAAS,qBAAqB,OAA4B;AAC/DL,QAAAA,UAAU,MAAM;AACd,YAAQ;AAAA,MACN;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAA,CAAE;AACL,SAAO;AACT;AAEO,SAAS,oBAAoB,OAA4B;AAE9D,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,QAAM,EAAE,aAAa,SAAA,IAAaM,8BAAA;AAClC,QAAM,kBAAkBC,MAAAA,kBAAA;AAExB,QAAM,iBAAiBL,MAAAA,WAAW,yBAAyB;AAC3D,QAAM,eAAe,YAAY,cAAc,iBAAiB;AAEhE,QAAM,aAAaM,cAAAA,yBAAA;AAEnB,SAAO,EAAE,6BAA6B;AAAA,IACpC;AAAA,MACE;AAAA,MACA;AAAA,QACE,OAAO,CAAA;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MAAA;AAAA,MAEF;AAAA,QACEC,iBAAAA;AAAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,YAAY,QAAQ;AAAA,UACpB,UAAU;AAAA,UACV,aAAa;AAAA,QAAA;AAAA,QAEf,EAAEC,MAAAA,iBAAiB;AAAA,UACjB,WAAW;AAAA,UACX,aAAa;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,YAAY,MAAM;AAChB,uBAAW,KAAK,MAAM,MAAM,IAAI;AAAA,UAClC;AAAA,QAAA,CACD;AAAA,MAAA;AAAA,IACH;AAAA,EACF,CACD;AACH;AAEO,SAAS,oBAAoB,OAAO;AAEzC,QAAM,EAAE,UAAU,OAAO,aAAa,eAAe;AAErD,QAAM,EAAE,SAAA,IAAaJ,8BAAA;AAErB,SAAO;AAAA,IACLK,iBAAAA,cAAc;AAAA,IACd;AAAA,MACE,OAAO;AAAA,QACL,WAAW,CAAA;AAAA,QACX;AAAA,QACA,cAAc;AAAA,QACd,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB;AAAA,QACA,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF;AAAA,EAAA;AAEJ;;;;;;;;"}