This technical breakdown covers how I built the custom WakaTime dashboard on this site using Astro, TypeScript, and Chart.js. Iβll walk through the architecture decisions, component design, and the iterative development process.
The Goal: Creating Interactive Data Visualizations
The objective was to replace WakaTimeβs standard embeds with a more flexible, customizable dashboard. This meant fetching data directly from WakaTimeβs API and rendering it with Chart.js to create responsive, interactive visualizations that integrate seamlessly with the siteβs design.
Key Technologies
- Astro: For the overall site structure and component model.
- TypeScript: For robust client-side data fetching and chart logic.
- Chart.js: For creating interactive, responsive data visualizations.
- WakaTime API: As the source for all coding statistics.
The Process: From Concept to Components
The development process was iterative, evolving from simple embeds to a modular set of Astro components.
1. Initial Proof of Concept
The first step was to simply fetch data from WakaTimeβs JSON endpoints and log it to the console. This confirmed that the data was accessible and provided a clear picture of the data structures.
Tip: When working with a new API, always start by inspecting the raw response. console.log() is your best friend.
2. Introducing Chart.js
Once data fetching was established, Chart.js was integrated to create the visualizations. The initial implementation was a single, monolithic WakaTimeDashboard.astro component.
Challenge: This single-component approach quickly became difficult to manage. The component was responsible for fetching data, processing it, and rendering multiple charts, leading to a large and complex file.
3. Refactoring into Modular Components
The solution was to deconstruct the dashboard into smaller, focused components. This resulted in the following structure:
WakaTimeInsights.astro: Displays key stats like daily average and best day.WakaTimeActivityChart.astro: Renders the main activity chart.WakaTimeLanguagesChart.astro: Shows the language breakdown.WakaTimeCalendar.astro: Displays the calendar heatmap.
This modularity made the code easier to maintain and allowed for greater flexibility in laying out the dashboard.
4. Centralizing Logic in a TypeScript Module
To support the new component structure, all the data fetching, processing, and Chart.js configuration logic was moved into a dedicated TypeScript module at src/lib/wakatime-dashboard.ts.
This module exports individual initialization functions for each component, like initActivityChart() and initLanguagesChart(). Each Astro component then calls its corresponding initialization function in a client-side script.
// src/lib/wakatime-dashboard.ts
import { Chart, registerables } from 'chart.js';
// ...
export function initActivityChart() {
// ... logic to fetch data and render chart ...
}// src/components/WakaTimeActivityChart.astro
<script>
import { initActivityChart } from '../lib/wakatime-dashboard.ts';
initActivityChart();
</script>Best Practice: For complex client-side logic in Astro, itβs best to keep it in separate .ts or .js files and import them into your components. This improves organization and allows for better tooling support.
Final Architecture
The final architecture is a set of modular Astro components, each with a minimal client-side script that imports its logic from a central TypeScript module. This approach provides a clean separation of concerns, making the dashboard both maintainable and extensible.
π¬ Deep Dive: Building the WakaTime Dashboard
Developer & Creator | View Profile | Forum Home
