Move into folders
This commit is contained in:
parent
ee73ab77fd
commit
5cbb180c57
24 changed files with 181 additions and 185 deletions
|
|
@ -1,109 +0,0 @@
|
|||
function downsampleBars(counts: number[], targetBars: number): number[] {
|
||||
const step = Math.max(1, Math.floor(counts.length / targetBars));
|
||||
const bars: number[] = [];
|
||||
for (let index = 0; index < counts.length; index += step) {
|
||||
let sum = 0;
|
||||
for (let offset = 0; offset < step && index + offset < counts.length; offset++) {
|
||||
sum += counts[index + offset];
|
||||
}
|
||||
bars.push(sum);
|
||||
}
|
||||
return bars;
|
||||
}
|
||||
|
||||
export function DualHistogram({
|
||||
localCounts,
|
||||
globalCounts,
|
||||
min,
|
||||
max,
|
||||
globalMean,
|
||||
}: {
|
||||
localCounts: number[];
|
||||
globalCounts: number[];
|
||||
min: number;
|
||||
max: number;
|
||||
globalMean?: number;
|
||||
}) {
|
||||
const targetBars = 25;
|
||||
const localBars = downsampleBars(localCounts, targetBars);
|
||||
const globalBars = downsampleBars(globalCounts, targetBars);
|
||||
|
||||
const barCount = Math.min(localBars.length, globalBars.length);
|
||||
const localMax = Math.max(...localBars, 1);
|
||||
const globalMax = Math.max(...globalBars, 1);
|
||||
|
||||
const meanFraction = globalMean != null && max > min ? (globalMean - min) / (max - min) : null;
|
||||
|
||||
return (
|
||||
<div className="mt-1">
|
||||
<div className="relative flex items-end gap-px h-10">
|
||||
{Array.from({ length: barCount }).map((_, index) => {
|
||||
const globalHeight = (globalBars[index] / globalMax) * 100;
|
||||
const localHeight = (localBars[index] / localMax) * 100;
|
||||
return (
|
||||
<div key={index} className="flex-1 relative min-w-[2px] h-full flex items-end">
|
||||
<div
|
||||
className="absolute bottom-0 left-0 right-0 bg-warm-300/40 dark:bg-warm-600/40 rounded-t-sm"
|
||||
style={{ height: `${globalHeight}%` }}
|
||||
/>
|
||||
<div
|
||||
className="absolute bottom-0 left-0 right-0 bg-teal-500 dark:bg-teal-400 rounded-t-sm"
|
||||
style={{
|
||||
height: `${localHeight}%`,
|
||||
opacity: localBars[index] > 0 ? 1 : 0.1,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{meanFraction != null && meanFraction >= 0 && meanFraction <= 1 && (
|
||||
<div
|
||||
className="absolute bottom-0 top-0 w-px border-l border-dashed border-warm-400 dark:border-warm-500"
|
||||
style={{ left: `${meanFraction * 100}%` }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SkeletonHistogram() {
|
||||
return (
|
||||
<div className="bg-warm-50 dark:bg-warm-800 rounded p-2 animate-pulse">
|
||||
<div className="flex justify-between items-baseline">
|
||||
<div className="h-3 w-24 bg-warm-200 dark:bg-warm-700 rounded" />
|
||||
<div className="h-3 w-10 bg-warm-200 dark:bg-warm-700 rounded" />
|
||||
</div>
|
||||
<div className="flex items-end gap-px h-10 mt-2">
|
||||
{Array.from({ length: 15 }).map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex-1 bg-warm-200 dark:bg-warm-700 rounded-t-sm min-w-[2px]"
|
||||
style={{ height: `${20 + Math.sin(i * 0.7) * 30 + 30}%` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-between mt-1">
|
||||
<div className="h-2 w-6 bg-warm-200 dark:bg-warm-700 rounded" />
|
||||
<div className="h-2 w-6 bg-warm-200 dark:bg-warm-700 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function LoadingSkeleton() {
|
||||
return (
|
||||
<div className="p-3 space-y-4">
|
||||
{[0, 1, 2].map((groupIdx) => (
|
||||
<div key={groupIdx}>
|
||||
<div className="h-3 w-20 bg-warm-200 dark:bg-warm-700 rounded animate-pulse mb-2" />
|
||||
<div className="space-y-3">
|
||||
{Array.from({ length: groupIdx === 0 ? 3 : 2 }).map((_, i) => (
|
||||
<SkeletonHistogram key={i} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue