Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/dev.void/llms.txt

Use this file to discover all available pages before exploring further.

The TelemetryRadar component (TelemetryRadar.js) renders an animated radar screen where each skill appears as a glowing dot at a position defined by an angle and a distance from the centre. A sweeping arc rotates continuously around the radar; when the sweep passes within 30° of a skill’s angle, that dot pulses bright green and scales up. Below the radar, a responsive grid displays each skill alongside an animated progress bar. All of this is driven by a single data array called d.

The Skills Data Array

Each skill is a plain object in the d array at the top of TelemetryRadar.js:
// TelemetryRadar.js — skills data array
const d = [
  {
    name: "React",    // Label shown in the hover tooltip and in the grid below the radar
    angle: 30,        // Position on the radar in degrees (0 = right, 90 = bottom, 180 = left, 270 = top)
    distance: 40,     // Distance from the centre as a percentage of the radar's half-radius (0–100)
    strength: 95,     // Proficiency percentage shown in the tooltip and used to fill the progress bar
  },
  // ... more entries
];
angle and distance control only visual placement on the radar. strength is the number that appears in the tooltip (React 95%) and drives the animated progress bar in the grid — it has no effect on where the dot appears on the radar.

Existing Skills

The eight default entries and their current positions:
NameAngleDistanceStrength
React30°4095%
TypeScript75°6090%
Tailwind120°3598%
Framer Motion160°7085%
Node.js210°5580%
Three.js260°8070%
GraphQL310°6575%
UI/UX Design345°4588%

Understanding Angle and Distance

The radar uses standard polar-to-Cartesian conversion to place each dot:
x = 50 + (distance / 2) × cos(angle_in_radians)
y = 50 + (distance / 2) × sin(angle_in_radians)
Both x and y are expressed as percentages of the radar container, with (50, 50) being the exact centre.

Angle (0–360°)

0° places a dot at the rightmost point of the horizontal axis. Values increase clockwise: 90° is at the bottom, 180° is left, 270° is top. The radar grid lines sit at 0°/90°/180°/270°, so angles near those values place dots on the crosshairs.

Distance (0–100)

A distance of 0 places the dot at the dead centre. A distance of 100 places it at the very edge of the radar circle. Values between 20–40 cluster near the core; values between 70–90 push dots toward the outer ring.

Angle Spacing Tips

Keeping angle values spread apart prevents dots and hover tooltips from overlapping. The default entries use roughly 40–50° of separation between adjacent skills.
Divide 360° by the number of skills to find an even baseline spacing. For eight skills that is 45° per skill. Start at 30° for the first skill, then increment by 45° for each subsequent one: 30, 75, 120, 165, 210, 255, 300, 345.
  • Too close (< 25° apart): Tooltips overlap on hover; the sweep ping fires multiple skills at once.
  • Sweet spot (35–60° apart): Each skill has its own clear sector; the sweep hits one dot at a time.
  • Spread out (> 70° apart): Fine for six or fewer skills, but leaves large silent arcs on the radar.
The sweep ping fires when (sweepAngle - skillAngle + 360) % 360 is between 0 and 30. This means the glow triggers for 30° of the full rotation, so skills within 30° of each other will both light up during the same sweep pass.

Distance Placement Guide

Distance valueVisual position
0–20Inner core — right at the centre
25–45First ring — inside the innermost concentric circle
50–65Mid-range — between the second and third rings
70–85Outer zone — near the third ring
90–100Edge — flush with the outermost ring
Vary distance to avoid all dots sitting on the same concentric circle, which makes the radar look like a ring rather than a scatter plot.

Adding a New Skill

Append a new object to the d array. Choose an angle that is at least 30° away from any existing entry to avoid ping collisions:
// TelemetryRadar.js — adding a ninth skill
const d = [
  { name: "React",        angle: 30,  distance: 40, strength: 95 },
  { name: "TypeScript",   angle: 75,  distance: 60, strength: 90 },
  { name: "Tailwind",     angle: 120, distance: 35, strength: 98 },
  { name: "Framer Motion",angle: 160, distance: 70, strength: 85 },
  { name: "Node.js",      angle: 210, distance: 55, strength: 80 },
  { name: "Three.js",     angle: 260, distance: 80, strength: 70 },
  { name: "GraphQL",      angle: 310, distance: 65, strength: 75 },
  { name: "UI/UX Design", angle: 345, distance: 45, strength: 88 },

  // ↓ new entry — 38° gap before React at 30° wraps around to here
  { name: "Next.js",      angle: 352, distance: 58, strength: 92 },
];
If you add many skills, recalculate all angles using the even-spacing formula (360 ÷ total skills) so the radar stays readable. Cramming ten or more skills without adjusting existing angles leads to overlapping dots and tooltips.

Replacing the Default Skill Set

To completely swap out the defaults for your own stack, replace the entire array. Here is an example for a backend-focused developer:
// TelemetryRadar.js — fully custom skill set
const d = [
  { name: "Python",       angle: 0,   distance: 40, strength: 96 },
  { name: "Django",       angle: 45,  distance: 60, strength: 90 },
  { name: "PostgreSQL",   angle: 90,  distance: 50, strength: 88 },
  { name: "Docker",       angle: 135, distance: 70, strength: 82 },
  { name: "Kubernetes",   angle: 180, distance: 65, strength: 75 },
  { name: "AWS",          angle: 225, distance: 55, strength: 80 },
  { name: "Go",           angle: 270, distance: 45, strength: 70 },
  { name: "Redis",        angle: 315, distance: 75, strength: 85 },
];
The grid below the radar regenerates automatically from the same array — adding or removing entries updates both the radar dots and the progress-bar grid simultaneously with no additional changes required.

How the Progress Bars Animate

Each progress bar in the grid uses Framer Motion’s whileInView to animate from width: 0 to width: {strength}% as the grid scrolls into view:
// TelemetryRadar.js — progress bar animation (read-only reference)
<motion.div
  className="h-full bg-gradient-to-r from-aurora-teal to-aurora-mint"
  initial={{ width: 0 }}
  whileInView={{ width: `${e.strength}%` }}
  viewport={{ once: true }}
  transition={{ duration: 1, delay: 0.2 }}
/>
The animation plays once (once: true) — refreshing the page will replay it, but scrolling back up and down will not re-trigger it. Remove viewport={{ once: true }} if you want it to replay every time the grid enters the viewport.

Build docs developers (and LLMs) love