home / skills / dennisadriaans / vue-chrts / common-patterns

common-patterns skill

/.claude/skills/common-patterns

This skill helps you apply common patterns and best practices in vue-chrts for data formatting, legends, and chart styling across types.

npx playbooks add skill dennisadriaans/vue-chrts --skill common-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.0 KB
---
name: common-patterns
description: Common patterns and best practices for vue-chrts. Use for general guidance on data formatting, styling, and chart configuration.
---

# Common Patterns & Best Practices

This guide covers patterns that apply across all vue-chrts chart types.

## The Categories Object Pattern

Every chart uses a `categories` object to define how data series are displayed.

```typescript
// Structure: Record<DataKey, BulletLegendItemInterface>
const categories = {
  dataKey1: { name: 'Display Name', color: '#hexcolor' },
  dataKey2: { name: 'Another Series', color: '#hexcolor2' }
}

// BulletLegendItemInterface full options:
interface BulletLegendItemInterface {
  name: string | number       // Legend label
  color?: string | string[]   // Fill color(s)
  className?: string          // CSS class
  inactive?: boolean          // Dim in legend
  hidden?: boolean            // Hide from legend
  pointer?: boolean           // Show pointer cursor
}
```

## Formatter Functions

Formatters control how axis labels and tooltips display values.

### X-Axis Formatter

```typescript
// IMPORTANT: xFormatter receives the INDEX, not the data item!
const data = [
  { month: 'Jan', value: 100 },
  { month: 'Feb', value: 150 },
]

// ❌ WRONG - this receives index (0, 1, 2...)
const xFormatter = (tick) => tick.month

// ✅ CORRECT - use index to access data
const xFormatter = (tick: number) => data[tick].month

// ✅ ALSO CORRECT - with additional params
const xFormatter = (tick: number, i?: number, ticks?: number[]) => {
  return data[tick].month
}
```

### Y-Axis Formatter

```typescript
// yFormatter receives the actual tick VALUE
const yFormatter = (tick: number) => {
  // Format as currency
  return `$${tick.toLocaleString()}`
}

// Format as percentage
const yFormatter = (tick: number) => `${tick}%`

// Format large numbers
const yFormatter = (tick: number) => {
  if (tick >= 1000000) return `${(tick / 1000000).toFixed(1)}M`
  if (tick >= 1000) return `${(tick / 1000).toFixed(0)}K`
  return tick.toString()
}
```

### Tooltip Title Formatter

```typescript
// Receives the actual data item, not an index
const tooltipTitleFormatter = (dataItem) => {
  return `${dataItem.month} 2024`
}
```

## Common Styling Props

These props are available on most chart types:

```vue
<ChartComponent
  <!-- Axes -->
  xLabel="X Axis Title"
  yLabel="Y Axis Title"
  :xDomainLine="true"
  :yDomainLine="true"
  :xTickLine="false"
  :yTickLine="false"
  :xGridLine="false"
  :yGridLine="true"
  
  <!-- Ticks -->
  :xNumTicks="5"
  :yNumTicks="4"
  :minMaxTicksOnly="false"
  :xExplicitTicks="[0, 50, 100]"
  
  <!-- Legend -->
  :hideLegend="false"
  :legendPosition="LegendPosition.TopRight"
  :legendStyle="{ padding: '8px' }"
  
  <!-- Tooltip -->
  :hideTooltip="false"
  :tooltip="{ followCursor: true, hideDelay: 100 }"
  
  <!-- Animation -->
  :duration="300"
  
  <!-- Padding -->
  :padding="{ top: 20, right: 20, bottom: 40, left: 50 }"
/>
```

## Legend Positions

```typescript
import { LegendPosition } from 'vue-chrts'

// Available positions
LegendPosition.TopLeft
LegendPosition.TopCenter
LegendPosition.TopRight
LegendPosition.BottomLeft
LegendPosition.BottomCenter
LegendPosition.BottomRight
```

## Curve Types (Line/Area Charts)

```typescript
import { CurveType } from 'vue-chrts'

// Common choices
CurveType.Linear       // Straight lines
CurveType.MonotoneX    // Smooth, preserves monotonicity
CurveType.Step         // Stepped/staircase
CurveType.Natural      // Natural cubic spline
CurveType.Basis        // B-spline, very smooth
CurveType.Cardinal     // Cardinal spline
```

## Orientation (Bar Charts)

```typescript
import { Orientation } from 'vue-chrts'

Orientation.Vertical    // Bars go up
Orientation.Horizontal  // Bars go sideways
```

## Responsive Charts

Charts are responsive by default. Container width is automatic, but height must be specified:

```vue
<template>
  <!-- Chart fills container width, fixed height -->
  <div class="chart-container">
    <LineChart :data="data" :categories="categories" :height="300" />
  </div>
</template>

<style>
.chart-container {
  width: 100%;
  max-width: 800px;
}
</style>
```

## TypeScript Generics

Charts are generic over your data type:

```typescript
interface MyDataItem {
  label: string
  value1: number
  value2: number
}

const data: MyDataItem[] = [...]

// Type-safe accessors
const xFormatter = (tick: number): string => data[tick].label
const tooltipFormatter = (d: MyDataItem): string => d.label
```

## Color Recommendations

```typescript
// Recommended color palettes

// Blue-based (professional)
const blueScale = ['#bfdbfe', '#60a5fa', '#3b82f6', '#2563eb', '#1d4ed8']

// Multi-series (distinct)
const categorical = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6']

// Sequential (for ordered data)
const sequential = ['#dcfce7', '#86efac', '#22c55e', '#16a34a', '#166534']

// Diverging (for +/- values)
const diverging = ['#ef4444', '#fca5a5', '#e5e7eb', '#86efac', '#22c55e']
```

## Performance Tips

1. **Limit data points**: Charts work best with < 1000 data points
2. **Use `duration: 0`** to disable animations for large datasets
3. **Memoize formatters**: Wrap formatters in `computed()` if they depend on reactive data
4. **Lazy load maps**: TopoJSON files are large; import dynamically

```typescript
// Lazy load TopoJSON
const topoJson = ref(null)
onMounted(async () => {
  topoJson.value = await import('./data/map.topo.json')
})
```

## Debugging Checklist

When a chart isn't working:

1. **No data showing?**
   - Check that `categories` keys match your data object keys
   - For BarChart, verify `yAxis` array is correct

2. **X-axis shows numbers?**
   - Add `xFormatter` function
   - Remember it receives an INDEX

3. **Wrong colors?**
   - Categories object keys must exactly match data keys
   - Check for typos in key names

4. **Legend missing items?**
   - Ensure all data series have category entries
   - Check `hideLegend` isn't true

5. **Tooltip not showing?**
   - Check `hideTooltip` isn't true
   - Verify chart has `height` prop set

Overview

This skill documents common patterns and best practices for using vue-chrts. It focuses on data shaping, formatter behavior, styling props, and performance tips so you can build reliable, readable charts in Vue 3. Use it to avoid common mistakes and speed up chart configuration.

How this skill works

The guide explains the categories object pattern that maps data keys to legend labels and colors, and it details how different formatter functions receive parameters (notably the x-axis formatter receives an index). It lists common props for axes, legends, tooltips, animation, and padding, and describes available enums for legend position, curve types, and orientation. It also covers responsive behavior, TypeScript generics, color palettes, and a debugging checklist.

When to use it

  • When mapping raw data keys to display names and colors via the categories object
  • When you need precise control over axis labels, tooltips, or legend visibility
  • When configuring responsive charts that fill container width but need fixed height
  • When optimizing performance for larger datasets or lazy-loading heavy assets
  • When using TypeScript and you want type-safe formatter functions

Best practices

  • Define a categories object with exact data keys to control legend labels and colors
  • Remember x-axis formatters receive an index; use it to reference your data array
  • Memoize formatter functions with computed() when they depend on reactive state
  • Limit data points (<1000) and set duration: 0 to disable animations for large datasets
  • Specify height on the chart container to ensure proper rendering and tooltips

Example use cases

  • Multi-series line chart with categories mapping keys to a distinct color palette
  • Bar chart switching orientation between vertical and horizontal based on screen layout
  • Area chart using CurveType.MonotoneX for smooth trends and a currency yFormatter
  • Responsive dashboard widget that fills container width with height: 300 and a compact legend
  • Map visualization that lazy-loads TopoJSON only when the component mounts

FAQ

Why does my x-axis show numbers instead of labels?

The x-axis formatter receives an index, not the data item. Use the index to look up the label in your data array or provide an xFormatter that returns the desired string.

Legend colors or items are wrong or missing — what should I check?

Ensure the categories object keys exactly match your data keys, check for typos, and confirm hideLegend is not enabled. Also verify each series has a corresponding category entry.