11import { BaseUnit , UnitLong } from "@macrostrat/api-types" ;
2+ import { IUnit } from "./units" ;
3+ import { group } from "d3-array" ;
24
35// Time resolution is 100 years
46const dt = 0.0001 ;
@@ -13,7 +15,7 @@ interface ExtUnit extends UnitLong {
1315 column ?: number ;
1416}
1517
16- function extendDivision (
18+ export function extendDivision (
1719 unit : UnitLong ,
1820 i : number ,
1921 divisions : UnitLong [ ]
@@ -39,7 +41,7 @@ function extendDivision(
3941 } ;
4042}
4143
42- function preprocessUnits ( units : UnitLong [ ] ) {
44+ export function preprocessUnits ( units : UnitLong [ ] ) {
4345 let divisions = units . map ( extendDivision ) ;
4446 for ( let d of divisions ) {
4547 const overlappingUnits = divisions . filter ( ( u ) =>
@@ -74,4 +76,55 @@ function preprocessUnits(units: UnitLong[]) {
7476 return divisions ;
7577}
7678
77- export { extendDivision , preprocessUnits } ;
79+ export interface SectionInfo {
80+ section_id : number | number [ ] ;
81+ t_age : number ;
82+ b_age : number ;
83+ units : IUnit [ ] ;
84+ }
85+
86+ export function groupUnitsIntoSections ( units : IUnit [ ] ) : SectionInfo [ ] {
87+ let groups = Array . from ( group ( units , ( d ) => d . section_id ) ) ;
88+ return groups . map ( ( [ section_id , units ] ) => {
89+ const t_age = Math . min ( ...units . map ( ( d ) => d . t_age ) ) ;
90+ const b_age = Math . max ( ...units . map ( ( d ) => d . b_age ) ) ;
91+ return { section_id, t_age, b_age, units } ;
92+ } ) ;
93+ }
94+
95+ export function _mergeOverlappingSections (
96+ sections : SectionInfo [ ]
97+ ) : SectionInfo [ ] {
98+ /** Columns can have sections that overlap in time. Here, we merge overlapping
99+ * sections into a single section to correctly render gap-bound packages.
100+ */
101+ const [ firstSection , ...rest ] = sections ;
102+ const newSections = [ firstSection ] ;
103+ for ( const section of rest ) {
104+ const lastSection = newSections [ newSections . length - 1 ] ;
105+ if (
106+ lastSection . b_age < section . t_age ||
107+ lastSection . t_age > section . b_age
108+ ) {
109+ // No overlap, add the section as normal
110+ newSections . push ( section ) ;
111+ continue ;
112+ }
113+ // Overlap, merge the sections
114+ lastSection . section_id = [
115+ ...ensureArray ( lastSection . section_id ) ,
116+ ...ensureArray ( section . section_id ) ,
117+ ] ;
118+ lastSection . units . push ( ...section . units ) ;
119+ lastSection . b_age = Math . max ( lastSection . b_age , section . b_age ) ;
120+ lastSection . t_age = Math . min ( lastSection . t_age , section . t_age ) ;
121+ }
122+ return newSections ;
123+ }
124+
125+ export function ensureArray < T > ( x : T | T [ ] ) : T [ ] {
126+ if ( Array . isArray ( x ) ) {
127+ return x ;
128+ }
129+ return [ x ] ;
130+ }
0 commit comments