Charts in Nuxt with ECharts: Visualizing My Coding Journey
Charts in Nuxt with ECharts: Visualizing My Coding Journey
Have you ever wondered how much time you actually spend coding? Or which languages dominate your workflow? For my latest portfolio update, I didn’t just want to claim I’m active—I wanted to prove it.
The solution: A seamless integration of WakaTime data, visualized through the power of Apache ECharts in a Nuxt 3 environment.
Why ECharts?
While there are many charting libraries (Chart.js, D3.js, etc.), ECharts won me over for several reasons:
-
High Performance: It handles large datasets with ease.
-
Declarative Configuration: You describe the “what,” not the “how.”
-
Nuxt Ecosystem: Thanks to the
nuxt-echartsmodule, it integrates perfectly with SSR and hydration.
The Architecture: From API to Pixels
The workflow behind my portfolio looks like this:
-
Data Source: WakaTime tracks my coding hours directly in VS Code.
-
Server-Side: I use a Nuxt Server Route (
/server/api/wakatime.ts) to fetch data securely without exposing my API key to the frontend. -
Visualization: The component uses ECharts to transform raw JSON data into an interactive doughnut chart.
Step-by-Step Integration
1. Installation & Setup
First, we add the module:
npx nuxi@latest module add echarts
In nuxt.config.ts, I registered only the components I actually need (Tree-shaking!) to keep the bundle size lean:
export default defineNuxtConfig({
modules: ['nuxt-echarts'],
echarts: {
renderer: 'svg', // SVG is often cleaner for simple UI charts
charts: ['PieChart'],
components: ['DatasetComponent', 'GridComponent', 'TooltipComponent', 'LegendComponent']
}
})
2. The WakaTime Component
In my portfolio, I use useFetch to retrieve my stats. Here is a simplified version of my implementation:
<script setup lang="ts">
// Fetching data from my own API route
const { data: stats, pending } = await useFetch('/api/wakatime')
const chartOption = computed(() => ({
backgroundColor: 'transparent',
tooltip: { trigger: 'item', formatter: '{b}: {d}%' },
legend: { bottom: '0', textStyle: { color: '#888' } },
series: [
{
name: 'Languages',
type: 'pie',
radius: ['50%', '80%'],
avoidLabelOverlap: false,
itemStyle: { borderRadius: 10 },
label: { show: false },
data: stats.value?.languages.map(lang => ({
name: lang.name,
value: lang.total_seconds
})) || []
}
]
}))
</script>
<template>
<div class="chart-container">
<div v-if="pending">Loading Stats...</div>
<VChart v-else :option="chartOption" autoresize class="h-[400px]" />
</div>
</template>
The Result
This integration adds massive value to my portfolio. Instead of static text, visitors see real-time data on the technologies I use most. It’s a “Proof of Work” that builds trust and demonstrates my ability to process and present data effectively.
Pro Tips:
-
Client-Only: Since ECharts needs access to the DOM, wrapping your chart in
<ClientOnly>can prevent hydration mismatches. -
Theme Matching: Use CSS variables within your ECharts options so the chart automatically toggles between Dark and Light mode along with your site.
How do you track your progress? Let me know in the comments!
Comments
Post a Comment