MCPcopy Create free account
hub / github.com/Noumena-Network/code / generateTokenChart

Function generateTokenChart

src/components/Stats.tsx:941–1019  ·  view source on GitHub ↗
(dailyTokens: DailyModelTokens[], models: string[], terminalWidth: number)

Source from the content-addressed store, hash-verified

939 xAxisLabels: string;
940};
941function generateTokenChart(dailyTokens: DailyModelTokens[], models: string[], terminalWidth: number): ChartOutput | null {
942 if (dailyTokens.length < 2 || models.length === 0) {
943 return null;
944 }
945
946 // Y-axis labels take about 6 characters, plus some padding
947 // Cap at ~52 to align with heatmap width (1 year of data)
948 const yAxisWidth = 7;
949 const availableWidth = terminalWidth - yAxisWidth;
950 const chartWidth = Math.min(52, Math.max(20, availableWidth));
951
952 // Distribute data across the available chart width
953 let recentData: DailyModelTokens[];
954 if (dailyTokens.length >= chartWidth) {
955 // More data than space: take most recent N days
956 recentData = dailyTokens.slice(-chartWidth);
957 } else {
958 // Less data than space: expand by repeating each point
959 const repeatCount = Math.floor(chartWidth / dailyTokens.length);
960 recentData = [];
961 for (const day of dailyTokens) {
962 for (let i = 0; i < repeatCount; i++) {
963 recentData.push(day);
964 }
965 }
966 }
967
968 // Color palette for different models - use theme colors
969 const theme = getTheme(resolveThemeSetting(getGlobalConfig().theme));
970 const colors = [themeColorToAnsi(theme.suggestion), themeColorToAnsi(theme.success), themeColorToAnsi(theme.warning)];
971
972 // Prepare series data for each model
973 const series: number[][] = [];
974 const legend: ChartLegend[] = [];
975
976 // Only show top 3 models to keep chart readable
977 const topModels = models.slice(0, 3);
978 for (let i = 0; i < topModels.length; i++) {
979 const model = topModels[i]!;
980 const data = recentData.map(day => day.tokensByModel[model] || 0);
981
982 // Only include if there's actual data
983 if (data.some(v => v > 0)) {
984 series.push(data);
985 // Use theme colors that match the chart
986 const bulletColors = [theme.suggestion, theme.success, theme.warning];
987 legend.push({
988 model: renderModelName(model),
989 coloredBullet: applyColor(figures.bullet, bulletColors[i % bulletColors.length] as Color)
990 });
991 }
992 }
993 if (series.length === 0) {
994 return null;
995 }
996 const chart = asciichart(series, {
997 height: 8,
998 colors: colors.slice(0, series.length),

Callers 2

ModelsTabFunction · 0.85
renderModelsToAnsiFunction · 0.85

Calls 8

getThemeFunction · 0.85
resolveThemeSettingFunction · 0.85
themeColorToAnsiFunction · 0.85
renderModelNameFunction · 0.85
applyColorFunction · 0.85
generateXAxisLabelsFunction · 0.85
maxMethod · 0.80
getGlobalConfigFunction · 0.70

Tested by

no test coverage detected