@@ -16,6 +16,19 @@ const MIN_PLOT_HEIGHT = 280;
1616/** Min horizontal pixels per x-axis date label so they never overlap */
1717const MIN_PX_PER_X_LABEL = 72 ;
1818
19+ const PAIR_COLORS = [
20+ '#a78bfa' , // violet
21+ '#f472b6' , // pink
22+ '#34d399' , // emerald
23+ '#fbbf24' , // amber
24+ '#60a5fa' , // blue
25+ '#f97316' , // orange
26+ '#22d3ee' , // cyan
27+ '#c084fc' , // purple
28+ '#4ade80' , // green
29+ '#fb923c' , // orange-2
30+ ] ;
31+
1932function pairKey ( p1 : string , p2 : string ) : string {
2033 return [ p1 , p2 ] . sort ( ) . join ( '–' ) ;
2134}
@@ -192,14 +205,12 @@ export function ConjunctionPlot({ defaultStart, defaultEnd, hideDateControls = f
192205
193206 const ORB_DEG = 10 ;
194207
195- const { pairs, pairIndex , seriesByPair } = useMemo ( ( ) => {
208+ const { pairs, seriesByPair } = useMemo ( ( ) => {
196209 const set = new Set < string > ( ) ;
197210 for ( const e of events ) {
198211 set . add ( pairKey ( e . planet1 , e . planet2 ) ) ;
199212 }
200213 const pairs = Array . from ( set ) . sort ( ) ;
201- const pairIndex = new Map < string , number > ( ) ;
202- pairs . forEach ( ( p , i ) => pairIndex . set ( p , i ) ) ;
203214 const seriesByPair = new Map < string , { date : Date ; separationDeg : number } [ ] > ( ) ;
204215 for ( const e of events ) {
205216 const key = pairKey ( e . planet1 , e . planet2 ) ;
@@ -209,7 +220,7 @@ export function ConjunctionPlot({ defaultStart, defaultEnd, hideDateControls = f
209220 for ( const arr of seriesByPair . values ( ) ) {
210221 arr . sort ( ( a , b ) => a . date . getTime ( ) - b . date . getTime ( ) ) ;
211222 }
212- return { pairs, pairIndex , seriesByPair } ;
223+ return { pairs, seriesByPair } ;
213224 } , [ events ] ) ;
214225
215226 // Add an interpolated point at exact conjunction (sep=0) so the curve peaks at the right time
@@ -425,21 +436,9 @@ export function ConjunctionPlot({ defaultStart, defaultEnd, hideDateControls = f
425436 }
426437 while ( out . length > maxTicks ) out . pop ( ) ;
427438 return { xTicks : out } ;
428- } , [ startDate , endDate , innerWidth ] ) ;
439+ } , [ startDate , endDate , innerWidth , marginLeft ] ) ;
429440
430441 const clipId = useId ( ) ;
431- const PAIR_COLORS = [
432- '#a78bfa' , // violet
433- '#f472b6' , // pink
434- '#34d399' , // emerald
435- '#fbbf24' , // amber
436- '#60a5fa' , // blue
437- '#f97316' , // orange
438- '#22d3ee' , // cyan
439- '#c084fc' , // purple
440- '#4ade80' , // green
441- '#fb923c' , // orange-2
442- ] ;
443442
444443 function smoothPathThrough ( points : { x : number ; y : number } [ ] ) : string {
445444 if ( points . length === 0 ) return '' ;
@@ -572,9 +571,9 @@ export function ConjunctionPlot({ defaultStart, defaultEnd, hideDateControls = f
572571 < div className = "flex flex-wrap items-center justify-center gap-1.5 md:gap-2 font-bold" >
573572 < span className = "text-sm font-bold text-violet-400 mr-1 uppercase tracking-wide" > From</ span >
574573 < div className = "flex items-center gap-1.5" >
575- < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustStart ( 'day' , - 1 ) } title = { copy . today . prevDay } aria-label = { copy . today . prevDay } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > day</ span > </ Button >
576- < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustStart ( 'month' , - 1 ) } title = { copy . today . prevMonth } aria-label = { copy . today . prevMonth } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > month</ span > </ Button >
577574 < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustStart ( 'year' , - 1 ) } title = { copy . today . prevYear } aria-label = { copy . today . prevYear } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > year</ span > </ Button >
575+ < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustStart ( 'month' , - 1 ) } title = { copy . today . prevMonth } aria-label = { copy . today . prevMonth } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > month</ span > </ Button >
576+ < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustStart ( 'day' , - 1 ) } title = { copy . today . prevDay } aria-label = { copy . today . prevDay } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > day</ span > </ Button >
578577 </ div >
579578 < span className = "min-w-[140px] text-lg text-foreground font-bold tabular-nums text-center" >
580579 { formatChartDate ( startDate ) }
@@ -591,9 +590,9 @@ export function ConjunctionPlot({ defaultStart, defaultEnd, hideDateControls = f
591590 < div className = "flex flex-wrap items-center justify-center gap-1.5 md:gap-2 font-bold" >
592591 < span className = "text-sm font-bold text-violet-400 mr-1 uppercase tracking-wide" > To</ span >
593592 < div className = "flex items-center gap-1.5" >
594- < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustEnd ( 'day' , - 1 ) } title = { copy . today . prevDay } aria-label = { copy . today . prevDay } disabled = { arrowDisabled . toDayBack } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > day</ span > </ Button >
595- < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustEnd ( 'month' , - 1 ) } title = { copy . today . prevMonth } aria-label = { copy . today . prevMonth } disabled = { arrowDisabled . toMonthBack } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > month</ span > </ Button >
596593 < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustEnd ( 'year' , - 1 ) } title = { copy . today . prevYear } aria-label = { copy . today . prevYear } disabled = { arrowDisabled . toYearBack } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > year</ span > </ Button >
594+ < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustEnd ( 'month' , - 1 ) } title = { copy . today . prevMonth } aria-label = { copy . today . prevMonth } disabled = { arrowDisabled . toMonthBack } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > month</ span > </ Button >
595+ < Button variant = "ghost" className = "!py-2 !px-3 text-xl leading-none font-bold" onClick = { ( ) => adjustEnd ( 'day' , - 1 ) } title = { copy . today . prevDay } aria-label = { copy . today . prevDay } disabled = { arrowDisabled . toDayBack } > < span className = "text-foreground" > ←</ span > < span className = "text-sm text-muted-foreground ml-0.5" > day</ span > </ Button >
597596 </ div >
598597 < span className = "min-w-[140px] text-lg text-foreground font-bold tabular-nums text-center" >
599598 { formatChartDate ( endDate ) }
0 commit comments