Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions packages/app/src/components/evaluation/ui/ChartDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { useCallback } from 'react';

import { useEvaluation } from '@/components/evaluation/EvaluationContext';
import { Card } from '@/components/ui/card';
import { ChartShareActions } from '@/components/ui/chart-display-helpers';
import { ChartSection } from '@/components/ui/chart-section';
import { ShareButton } from '@/components/ui/share-button';
import { ShareTwitterButton, ShareLinkedInButton } from '@/components/share-buttons';
import { getPrecisionLabel, isModelExperimental, Model, Precision } from '@/lib/data-mappings';
import { exportToCsv } from '@/lib/csv-export';
import { evaluationChartToCsv } from '@/lib/csv-export-helpers';
Expand Down Expand Up @@ -43,13 +42,7 @@ export default function EvaluationChartDisplay() {
different GPUs, quantization levels, and inference configurations.
</p>
</div>
<div className="flex items-center gap-1.5">
<ShareButton />
<div className="hidden sm:flex items-center gap-1.5">
<ShareTwitterButton />
<ShareLinkedInButton />
</div>
</div>
<ChartShareActions />
</div>
<EvaluationChartControls />
</div>
Expand Down
229 changes: 5 additions & 224 deletions packages/app/src/components/inference/ui/ChartDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
'use client';
import { track } from '@/lib/analytics';
import Link from 'next/link';
import { useMemo, useState } from 'react';
import { ChevronDown, X } from 'lucide-react';

import { useInference } from '@/components/inference/InferenceContext';
import { InferenceData, OverlayData, TrendDataPoint } from '@/components/inference/types';
import { processOverlayChartData } from '@/components/inference/utils';
import ScatterGraph from '@/components/inference/ui/ScatterGraph';
import { Badge } from '@/components/ui/badge';
import { Card } from '@/components/ui/card';
import { ChartButtons } from '@/components/ui/chart-buttons';
import { ChartShareActions, MetricAssumptionNotes } from '@/components/ui/chart-display-helpers';
import { exportToCsv } from '@/lib/csv-export';
import { inferenceChartToCsv } from '@/lib/csv-export-helpers';
import {
Expand All @@ -20,13 +19,9 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { ExternalLinkIcon } from '@/components/ui/external-link-icon';
import { ShareButton } from '@/components/ui/share-button';
import { ShareTwitterButton, ShareLinkedInButton } from '@/components/share-buttons';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Skeleton } from '@/components/ui/skeleton';
import { useUnofficialRun } from '@/components/unofficial-run-provider';
import { GPU_SPECS } from '@/lib/constants';
import {
getModelLabel,
getPrecisionLabel,
Expand Down Expand Up @@ -95,10 +90,8 @@ function E2eXAxisDropdown({
}

/**
* Renders a display of scatter charts based on filtered graph data.
* It maps through the filtered graphs from the InferenceChartContext and renders a Card for each,
* containing a heading and a ScatterGraph component.
* @returns {JSX.Element[]} An array of JSX.Element representing the chart displays.
* Renders the inference chart cards, captions, overlay controls, and trend drill-down dialog for
* the current filtered benchmark data.
*/
export default function ChartDisplay() {
const {
Expand Down Expand Up @@ -380,213 +373,7 @@ export default function ChartDisplay() {
</>
)}
</p>
{(selectedYAxisMetric === 'y_tpPerMw' ||
selectedYAxisMetric === 'y_inputTputPerMw' ||
selectedYAxisMetric === 'y_outputTputPerMw') && (
<>
<p className="text-muted-foreground mb-2 flex flex-wrap gap-2 items-center">
All in Power/GPU:{' '}
{Object.entries(GPU_SPECS).map(([base, specs]) => (
<Badge key={base} variant="outline">
{base.toUpperCase()}: {specs.power}kW
</Badge>
))}
</p>
<p className="text-muted-foreground">
<small>
Source:{' '}
<Link
target="_blank"
className="underline hover:text-foreground"
href="https://semianalysis.com/datacenter-industry-model/"
>
SemiAnalysis Datacenter Industry Model
<ExternalLinkIcon />
</Link>
</small>
</p>
</>
)}
{(selectedYAxisMetric === 'y_costh' ||
selectedYAxisMetric === 'y_costn' ||
selectedYAxisMetric === 'y_costr') && (
<>
<p className="text-muted-foreground mb-2 flex flex-wrap gap-2 items-center">
TCO $/GPU/hr:{' '}
{Object.entries(GPU_SPECS).map(([base, specs]) => (
<Badge key={base} variant="outline">
{base.toUpperCase()}:{' '}
{selectedYAxisMetric === 'y_costh'
? specs.costh
: selectedYAxisMetric === 'y_costn'
? specs.costn
: specs.costr}
</Badge>
))}
</p>
<p className="text-muted-foreground">
<small>
Source:{' '}
<Link
target="_blank"
className="underline hover:text-foreground"
href="https://semianalysis.com/ai-cloud-tco-model/"
>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
<ExternalLinkIcon />
</Link>
</small>
</p>
</>
)}
{(selectedYAxisMetric === 'y_costhOutput' ||
selectedYAxisMetric === 'y_costnOutput' ||
selectedYAxisMetric === 'y_costrOutput') && (
<>
<p className="text-muted-foreground mb-2 flex flex-wrap gap-2 items-center">
TCO $/GPU/hr:{' '}
{Object.entries(GPU_SPECS).map(([base, specs]) => (
<Badge key={base} variant="outline">
{base.toUpperCase()}:{' '}
{selectedYAxisMetric === 'y_costhOutput'
? specs.costh
: selectedYAxisMetric === 'y_costnOutput'
? specs.costn
: specs.costr}
</Badge>
))}
</p>
<p className="text-muted-foreground">
<small>
Source:{' '}
<Link
target="_blank"
className="underline hover:text-foreground"
href="https://semianalysis.com/ai-cloud-tco-model/"
>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
<ExternalLinkIcon />
</Link>
</small>
</p>
</>
)}
{(selectedYAxisMetric === 'y_costhi' ||
selectedYAxisMetric === 'y_costni' ||
selectedYAxisMetric === 'y_costri') && (
<>
<p className="text-muted-foreground mb-2 flex flex-wrap gap-2 items-center">
TCO $/GPU/hr:{' '}
{Object.entries(GPU_SPECS).map(([base, specs]) => (
<Badge key={base} variant="outline">
{base.toUpperCase()}:{' '}
{selectedYAxisMetric === 'y_costhi'
? specs.costh
: selectedYAxisMetric === 'y_costni'
? specs.costn
: specs.costr}
</Badge>
))}
</p>
<p className="text-muted-foreground">
<small>
Source:{' '}
<Link
target="_blank"
className="underline hover:text-foreground"
href="https://semianalysis.com/ai-cloud-tco-model/"
>
SemiAnalysis Market August 2025 Pricing Surveys & AI Cloud TCO Model
<ExternalLinkIcon />
</Link>
</small>
</p>
</>
)}
<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${
selectedYAxisMetric.startsWith('y_cost')
? 'max-h-20 opacity-100'
: 'max-h-0 opacity-0'
}`}
>
<p className="text-muted-foreground text-xs mt-2 border-l-2 border-amber-500 pl-2 bg-amber-500/5 py-1">
<strong>Note:</strong> Disaggregated inference configurations (e.g., MoRI
SGLang, Dynamo TRT) calculate cost per decode GPU or per prefill GPU,
rather than per total GPU count. This makes direct cost comparison with
aggregated configs not an apples-to-apples comparison.
</p>
</div>
<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${
selectedYAxisMetric === 'y_inputTputPerGpu' ||
selectedYAxisMetric === 'y_outputTputPerGpu'
? 'max-h-20 opacity-100'
: 'max-h-0 opacity-0'
}`}
>
<p className="text-muted-foreground text-xs mt-2 border-l-2 border-amber-500 pl-2 bg-amber-500/5 py-1">
<strong>Note:</strong> Disaggregated inference configurations (e.g., MoRI
SGLang, Dynamo TRT) calculate cost per decode GPU or per prefill GPU,
rather than per total GPU count. This makes direct cost comparison with
aggregated configs not an apples-to-apples comparison.
</p>
</div>
<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${
selectedYAxisMetric === 'y_tpPerMw' ||
selectedYAxisMetric === 'y_inputTputPerMw' ||
selectedYAxisMetric === 'y_outputTputPerMw'
? 'max-h-20 opacity-100'
: 'max-h-0 opacity-0'
}`}
>
<p className="text-muted-foreground text-xs mt-2 border-l-2 border-amber-500 pl-2 bg-amber-500/5 py-1">
<strong>Note:</strong> Disaggregated inference configurations (e.g., MoRI
SGLang, Dynamo TRT) calculate power per decode GPU or per prefill GPU,
rather than per total GPU count. This makes direct power comparison with
aggregated configs not an apples-to-apples comparison.
</p>
</div>
{selectedYAxisMetric.startsWith('y_j') && (
<>
<p className="text-muted-foreground mb-2 flex flex-wrap gap-2 items-center">
All in Power/GPU:{' '}
{Object.entries(GPU_SPECS).map(([base, specs]) => (
<Badge key={base} variant="outline">
{base.toUpperCase()}: {specs.power}kW
</Badge>
))}
</p>
<p className="text-muted-foreground">
<small>
Source:{' '}
<Link
target="_blank"
className="underline hover:text-foreground"
href="https://semianalysis.com/datacenter-industry-model/"
>
SemiAnalysis Datacenter Industry Model
<ExternalLinkIcon />
</Link>
</small>
</p>
</>
)}
<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${
selectedYAxisMetric.startsWith('y_j')
? 'max-h-20 opacity-100'
: 'max-h-0 opacity-0'
}`}
>
<p className="text-muted-foreground text-xs mt-2 border-l-2 border-amber-500 pl-2 bg-amber-500/5 py-1">
<strong>Note:</strong> Disaggregated inference configurations (e.g., MoRI
SGLang, Dynamo TRT) calculate Joules per decode GPU or per prefill GPU,
rather than per total GPU count. This makes direct Joules per token
comparison with aggregated configs not an apples-to-apples comparison.
</p>
</div>
<MetricAssumptionNotes selectedYAxisMetric={selectedYAxisMetric} />
<div
className={`overflow-hidden transition-all duration-200 ease-in-out ${
isModelExperimental(selectedModel)
Expand Down Expand Up @@ -670,13 +457,7 @@ export default function ChartDisplay() {
and serving parameters.
</p>
</div>
<div className="flex items-center gap-1.5">
<ShareButton />
<div className="hidden sm:flex items-center gap-1.5">
<ShareTwitterButton />
<ShareLinkedInButton />
</div>
</div>
<ChartShareActions />
</div>
<ChartControls />
<ModelArchitectureDiagram model={selectedModel} />
Expand Down
11 changes: 2 additions & 9 deletions packages/app/src/components/reliability/ui/ChartDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { useCallback } from 'react';

import { useReliabilityContext } from '@/components/reliability/ReliabilityContext';
import { Card } from '@/components/ui/card';
import { ChartShareActions } from '@/components/ui/chart-display-helpers';
import { ChartSection } from '@/components/ui/chart-section';
import { ShareButton } from '@/components/ui/share-button';
import { ShareTwitterButton, ShareLinkedInButton } from '@/components/share-buttons';
import { exportToCsv } from '@/lib/csv-export';
import { reliabilityChartToCsv } from '@/lib/csv-export-helpers';

Expand Down Expand Up @@ -35,13 +34,7 @@ export default function ReliabilityChartDisplay() {
reliability for inference runs over time.
</p>
</div>
<div className="flex items-center gap-1.5">
<ShareButton />
<div className="hidden sm:flex items-center gap-1.5">
<ShareTwitterButton />
<ShareLinkedInButton />
</div>
</div>
<ChartShareActions />
</div>
<ReliabilityChartControls />
</div>
Expand Down
Loading
Loading