(data: DailyModelTokens[], _chartWidth: number, yAxisOffset: number)
| 785 | } |
| 786 | |
| 787 | function generateXAxisLabels(data: DailyModelTokens[], _chartWidth: number, yAxisOffset: number): string { |
| 788 | if (data.length === 0) return ''; |
| 789 | |
| 790 | // Show 3-4 date labels evenly spaced, but leave room for last label |
| 791 | const numLabels = Math.min(4, Math.max(2, Math.floor(data.length / 8))); |
| 792 | // Don't use the very last position - leave room for the label text |
| 793 | const usableLength = data.length - 6; // Reserve ~6 chars for last label (e.g., "Dec 7") |
| 794 | const step = Math.floor(usableLength / (numLabels - 1)) || 1; |
| 795 | |
| 796 | const labelPositions: { pos: number; label: string }[] = []; |
| 797 | |
| 798 | for (let i = 0; i < numLabels; i++) { |
| 799 | const idx = Math.min(i * step, data.length - 1); |
| 800 | const date = new Date(data[idx]!.date); |
| 801 | const label = date.toLocaleDateString('en-US', { |
| 802 | month: 'short', |
| 803 | day: 'numeric', |
| 804 | }); |
| 805 | labelPositions.push({ pos: idx, label }); |
| 806 | } |
| 807 | |
| 808 | // Build the label string with proper spacing |
| 809 | let result = ' '.repeat(yAxisOffset); |
| 810 | let currentPos = 0; |
| 811 | |
| 812 | for (const { pos, label } of labelPositions) { |
| 813 | const spaces = Math.max(1, pos - currentPos); |
| 814 | result += ' '.repeat(spaces) + label; |
| 815 | currentPos = pos + label.length; |
| 816 | } |
| 817 | |
| 818 | return result; |
| 819 | } |
| 820 | |
| 821 | // Screenshot functionality |
| 822 | async function handleScreenshot( |
no test coverage detected