nix-evaluator-stats/packages/web/src/components/OperationsChart.tsx
NotAShelf 33ec901788
treewide: adapt for monorepo layout; initial TUI work
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id40b5f5ccb55a8a1ea2793192a38f0256a6a6964
2026-04-09 08:28:48 +03:00

45 lines
1.5 KiB
TypeScript

import { Component, For, createMemo } from 'solid-js';
import { StatsData } from '@ns/core';
import { formatNumber } from '@ns/ui-utils';
interface OperationsChartProps {
stats: StatsData;
}
const OperationsChart: Component<OperationsChartProps> = props => {
const operations = createMemo(() =>
[
{ label: 'Lookups', value: props.stats.nrLookups, colorClass: 'chart-1' },
{ label: 'Function Calls', value: props.stats.nrFunctionCalls, colorClass: 'chart-2' },
{ label: 'PrimOp Calls', value: props.stats.nrPrimOpCalls, colorClass: 'chart-3' },
{ label: 'Op Updates', value: props.stats.nrOpUpdates, colorClass: 'chart-4' },
{ label: 'Values Copied', value: props.stats.nrOpUpdateValuesCopied, colorClass: 'chart-5' },
].sort((a, b) => b.value - a.value),
);
const maxValue = createMemo(() => Math.max(...operations().map(o => o.value)));
return (
<div class="operations-chart">
<For each={operations()}>
{item => (
<div class="op-row">
<div class="op-label">{item.label}</div>
<div class="op-bar-container">
<div
class="op-bar"
classList={{ [item.colorClass]: true }}
style={{
width: `${maxValue() > 0 ? (item.value / maxValue()) * 100 : 0}%`,
}}
/>
</div>
<div class="op-value">{formatNumber(item.value)}</div>
</div>
)}
</For>
</div>
);
};
export default OperationsChart;