episteme 0.3.9

Knowledge graph for software engineering — design patterns, refactorings, and laws for AI agents
Documentation
<script lang="ts">
  type Segment = { label: string; value: number; color: string };

  let {
    segments,
    size = 192,
    strokeWidth = 14,
    centerLabel,
    centerValue,
  }: {
    segments: Segment[];
    size?: number;
    strokeWidth?: number;
    centerLabel?: string;
    centerValue?: string;
  } = $props();

  let radius = $derived((size - strokeWidth) / 2);
  let circumference = $derived(2 * Math.PI * radius);
  let total = $derived(segments.reduce((sum, s) => sum + s.value, 0));

  let offsets = $derived.by(() => {
    let offset = 0;
    return segments.map((s) => {
      const dash = (s.value / total) * circumference;
      const gap = circumference - dash;
      const entry = { dash, gap, offset };
      offset += dash;
      return entry;
    });
  });
</script>

<div class="relative inline-flex items-center justify-center" style="width: {size}px; height: {size}px;">
  <svg width={size} height={size} class="transform -rotate-90">
    <!-- background track -->
    <circle
      cx={size / 2} cy={size / 2} r={radius}
      fill="transparent"
      stroke="var(--color-surface-container-high)"
      stroke-width={strokeWidth}
    />
    {#each segments as seg, i}
      <circle
        cx={size / 2} cy={size / 2} r={radius}
        fill="transparent"
        stroke={seg.color}
        stroke-width={strokeWidth}
        stroke-dasharray="{offsets[i].dash} {offsets[i].gap}"
        stroke-dashoffset={-offsets[i].offset}
        stroke-linecap="round"
      />
    {/each}
  </svg>
  <div class="absolute inset-0 flex flex-col items-center justify-center">
    {#if centerValue}
      <span class="text-2xl font-bold text-[var(--color-on-surface)]">{centerValue}</span>
    {/if}
    {#if centerLabel}
      <span class="text-[10px] uppercase font-semibold text-[var(--color-on-surface-variant)]">{centerLabel}</span>
    {/if}
  </div>
</div>