GuardRateLeaderboard / src /lib /components /charts /RadarLabelsOverlay.svelte
Anton Malykhin
feat: refine leaderboard visualizations and CSV exports
236e9a2
Raw
History Blame Contribute Delete
1.49 kB
<script module lang="ts">
export type RadarLabelAnchor = 'start' | 'middle' | 'end';
export type RadarOverlayLabel = {
key: string;
text: string;
x: number;
y: number;
anchor: RadarLabelAnchor;
};
</script>
<script lang="ts">
import OverflowCursorTooltip from '$lib/components/tooltips/OverflowCursorTooltip.svelte';
import { cn } from '$lib/utils';
type Props = {
labels: readonly RadarOverlayLabel[];
viewBoxWidth: number;
viewBoxHeight: number;
labelClass?: string;
tooltipClass?: string;
position?: 'cursor' | 'label';
};
let {
labels,
viewBoxWidth,
viewBoxHeight,
labelClass,
tooltipClass,
position = 'cursor'
}: Props = $props();
function labelStyle(label: RadarOverlayLabel) {
return `left:${(label.x / viewBoxWidth) * 100}%; top:${(label.y / viewBoxHeight) * 100}%;`;
}
function labelAlignmentClass(anchor: RadarLabelAnchor) {
if (anchor === 'middle') return '-translate-x-1/2 text-center';
if (anchor === 'start') return 'text-left';
return '-translate-x-full text-right';
}
</script>
<div class="pointer-events-none absolute inset-0">
{#each labels as label (label.key)}
<OverflowCursorTooltip
text={label.text}
labelClass={cn(
'pointer-events-auto absolute block w-28 -translate-y-1/2 truncate font-mono text-[10px] leading-none text-muted-foreground',
labelAlignmentClass(label.anchor),
labelClass
)}
labelStyle={labelStyle(label)}
{tooltipClass}
{position}
/>
{/each}
</div>