Skip to content

Commit

Permalink
chore: minor chart fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasgriffintn committed Dec 14, 2024
1 parent d630393 commit 4f8811d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 77 deletions.
161 changes: 85 additions & 76 deletions apps/web/app/ai-metrics/components/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,59 @@ export function CombinedMetricsChart({
data,
interval = 60,
}: CombinedMetricsChartProps) {
const extendedData = [...data];
const lastEntry = data[data.length - 1];
if (!data?.length) {
return (
<div className="flex h-full w-full items-center justify-center text-muted-foreground">
No data available
</div>
);
}

const sanitizedData = data.map((point) => ({
timestamp: point.timestamp || "",
provider: point.provider || "unknown",
latency: typeof point.latency === "number" ? point.latency : 0,
promptTokens:
typeof point.promptTokens === "number" ? point.promptTokens : 0,
completionTokens:
typeof point.completionTokens === "number" ? point.completionTokens : 0,
totalTokens: typeof point.totalTokens === "number" ? point.totalTokens : 0,
}));

const extendedData = [...sanitizedData];
const lastEntry = sanitizedData[sanitizedData.length - 1];

if (lastEntry) {
if (lastEntry?.timestamp) {
const currentDate = new Date();
const lastEntryDate = new Date(lastEntry.timestamp.replace(" ", "T"));

while (lastEntryDate < currentDate) {
lastEntryDate.setMinutes(lastEntryDate.getMinutes() + interval);
if (!Number.isNaN(lastEntryDate.getTime())) {
while (lastEntryDate < currentDate) {
lastEntryDate.setMinutes(lastEntryDate.getMinutes() + interval);

if (lastEntryDate < currentDate) {
const interpolatedTimestamp = `${lastEntryDate.toISOString().split("T")[0]} ${lastEntryDate.getHours().toString().padStart(2, "0")}:${lastEntryDate.getMinutes().toString().padStart(2, "0")}`;

extendedData.push({
timestamp: interpolatedTimestamp,
provider: lastEntry.provider,
latency: 0,
promptTokens: 0,
completionTokens: 0,
totalTokens: 0,
});
}
}

const currentMinutes = currentDate.getMinutes();
const roundedMinutes = Math.floor(currentMinutes / interval) * interval;
currentDate.setMinutes(roundedMinutes);

if (lastEntryDate < currentDate) {
const interpolatedTimestamp = `${lastEntryDate.toISOString().split("T")[0]} ${lastEntryDate.getHours().toString().padStart(2, "0")}:${lastEntryDate.getMinutes().toString().padStart(2, "0")}`;
const currentTimestamp = `${currentDate.toISOString().split("T")[0]} ${currentDate.getHours().toString().padStart(2, "0")}:${currentDate.getMinutes().toString().padStart(2, "0")}`;

if (currentTimestamp > lastEntry.timestamp) {
extendedData.push({
timestamp: interpolatedTimestamp,
timestamp: currentTimestamp,
provider: lastEntry.provider,
latency: 0,
promptTokens: 0,
Expand All @@ -60,23 +98,6 @@ export function CombinedMetricsChart({
});
}
}

const currentMinutes = currentDate.getMinutes();
const roundedMinutes = Math.floor(currentMinutes / interval) * interval;
currentDate.setMinutes(roundedMinutes);

const currentTimestamp = `${currentDate.toISOString().split("T")[0]} ${currentDate.getHours().toString().padStart(2, "0")}:${currentDate.getMinutes().toString().padStart(2, "0")}`;

if (currentTimestamp > lastEntry.timestamp) {
extendedData.push({
timestamp: currentTimestamp,
provider: lastEntry.provider,
latency: 0,
promptTokens: 0,
completionTokens: 0,
totalTokens: 0,
});
}
}

const formatLatency = (value: number) => `${value.toLocaleString()}ms`;
Expand All @@ -88,12 +109,11 @@ export function CombinedMetricsChart({
if (!time) return "";
const [hours, minutes] = time.split(":");

const index = data.findIndex((d) => d.timestamp === timestamp);

const prevDate =
index > 0 ? data[index - 1]?.timestamp?.split(" ")[0] : null;

if (index === 0 || (prevDate && prevDate !== date)) {
if (
(hours === "00" && minutes === "00") ||
timestamp === extendedData[0]?.timestamp ||
timestamp === extendedData[extendedData.length - 1]?.timestamp
) {
return `${date} ${hours}:${minutes}`;
}

Expand All @@ -104,13 +124,6 @@ export function CombinedMetricsChart({
}
};

const isDayChange = (currentTimestamp: string, index: number) => {
if (index === 0 || !data[index - 1]?.timestamp) return false;
const [currentDate] = currentTimestamp.split(" ");
const [previousDate] = data[index - 1]?.timestamp?.split(" ") || [];
return currentDate !== previousDate;
};

const providerColors: { [key: string]: string } = {
openai: "#6A5ACD",
anthropic: "#FF6B6B",
Expand All @@ -127,6 +140,7 @@ export function CombinedMetricsChart({
};

const getProviderColor = (provider: string) => {
if (!provider) return "#0071f1";
const normalizedProvider = provider.toLowerCase();
return providerColors[normalizedProvider] || "#0071f1";
};
Expand Down Expand Up @@ -203,7 +217,7 @@ export function CombinedMetricsChart({
name="Latency (ms)"
opacity={0.9}
>
{data.map((entry, index) => (
{extendedData.map((entry, index) => (
<Cell
key={`cell-${index}-${entry.timestamp}`}
fill={getProviderColor(entry.provider)}
Expand All @@ -213,43 +227,38 @@ export function CombinedMetricsChart({
/>
))}
</Bar>
<Line
yAxisId="right"
type="monotone"
dataKey="promptTokens"
stroke="#00F5D4"
strokeWidth={2}
name="Prompt Tokens"
dot={false}
/>
<Line
yAxisId="right"
type="monotone"
dataKey="completionTokens"
stroke="#FF6B6B"
strokeWidth={2}
name="Completion Tokens"
dot={false}
/>
<Line
yAxisId="right"
type="monotone"
dataKey="totalTokens"
stroke="#FEE440"
strokeWidth={2}
name="Total Tokens"
dot={false}
/>
{data.map((entry, index) =>
isDayChange(entry.timestamp, index) ? (
<ReferenceLine
key={`ref-${entry.timestamp}`}
x={entry.timestamp}
stroke="var(--foreground)"
strokeDasharray="3 3"
opacity={0.5}
/>
) : null,
{extendedData.some((d) => d.promptTokens > 0) && (
<Line
yAxisId="right"
type="monotone"
dataKey="promptTokens"
stroke="#00F5D4"
strokeWidth={2}
name="Prompt Tokens"
dot={false}
/>
)}
{extendedData.some((d) => d.completionTokens > 0) && (
<Line
yAxisId="right"
type="monotone"
dataKey="completionTokens"
stroke="#FF6B6B"
strokeWidth={2}
name="Completion Tokens"
dot={false}
/>
)}
{extendedData.some((d) => d.totalTokens > 0) && (
<Line
yAxisId="right"
type="monotone"
dataKey="totalTokens"
stroke="#FEE440"
strokeWidth={2}
name="Total Tokens"
dot={false}
/>
)}
</ComposedChart>
</ResponsiveContainer>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/data/ai/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export async function getAiMetrics({
return;
}

return data.metrics;
return data.metrics.reverse();
} catch (error) {
console.error("Error getting AI metrics", error);
}
Expand Down

0 comments on commit 4f8811d

Please sign in to comment.