A Vue.js component library for creating sparkline charts, rewritten from the popular jQuery Sparkline library v2.1.2. This library provides lightweight, inline charts perfect for dashboards and data visualization.
https://iclaxton.github.io/sparkline-vue/
- 🎯 7 Chart Types: Line, Bar, Tristate, Discrete, Bullet, Pie, and Box plots
- ⚡ High Performance: Canvas-based rendering for smooth performance
- 🎨 Highly Customizable: Extensive configuration options
- 📱 Responsive: Automatic sizing and responsive design
- 🚀 Vue 3 Compatible: Built for Vue 3 Composition API
- 📦 Zero Dependencies: No jQuery required
- 🎭 TypeScript Ready: Full TypeScript support with declaration files
npm install sparkline-vue
# or
yarn add sparkline-vue
# or
pnpm add sparkline-vue<template>
<div>
<!-- Line chart -->
<Sparkline
:data="[1, 4, 6, 6, 8, 5, 3, 5]"
type="line"
:width="100"
:height="30"
/>
<!-- Bar chart -->
<Sparkline
:data="[1, 4, 6, 6, 8, 5, 3, 5]"
type="bar"
:width="100"
:height="30"
:options="{ barColor: '#3366cc' }"
/>
</div>
</template>
<script>
import Sparkline from 'sparkline-vue';
export default {
components: {
Sparkline
}
}
</script>The component is registered as Sparkline (PascalCase). In Vue templates, you can use either:
<Sparkline>(PascalCase - recommended for SFC templates)<sparkline>(kebab-case - required for in-DOM templates)
Both are equivalent, but PascalCase is recommended when using Single File Components (.vue files).
Perfect for showing trends over time.
<Sparkline
:data="[1, 4, 6, 6, 8, 5, 3, 5]"
type="line"
:options="{
lineColor: '#00f',
fillColor: '#cdf',
spotColor: '#f80',
spotRadius: 2
}"
/>Compare multiple data series on the same chart.
<Sparkline
:data="[
[10, 15, 20, 18, 25, 30, 28], // Series 1
[15, 18, 22, 20, 26, 28, 30], // Series 2
[12, 17, 21, 19, 24, 29, 27] // Series 3
]"
type="line"
:width="300"
:height="100"
:options="{
seriesNames: ['Sales', 'Target', 'Forecast'],
lineColor: ['#0066cc', '#ff6600', '#00cc66'],
fillColor: ['rgba(0,102,204,0.15)', 'rgba(255,102,0,0.15)', 'rgba(0,204,102,0.15)'],
lineWidth: [2, 2, 2],
spotRadius: 0 // Hide spots for cleaner multi-series view
}"
/>Features:
- Automatic high-contrast color palette when colors not specified
- Tooltips show all series values at cursor position
- Supports per-series customization (colors, widths, spot radii)
- Series names displayed in tooltips
- Maintains full interactivity (hover, click events)
Great for comparing discrete values.
<Sparkline
:data="[1, 4, 6, -2, 8, 5, -3, 5]"
type="bar"
:options="{
barColor: '#3366cc',
negBarColor: '#f44',
barWidth: 4,
barSpacing: 1
}"
/>Shows win/lose/draw states.
<Sparkline
:data="[1, -1, 0, 1, 1, 0, -1]"
type="tristate"
:options="{
posBarColor: '#6f6',
negBarColor: '#f44',
zeroBarColor: '#999',
stateLabels: { positive: 'Win', zero: 'Draw', negative: 'Loss' }
}"
/>Custom State Labels Example:
<!-- Use custom labels for different contexts -->
<Sparkline
:data="[1, -1, 0, 1, 1]"
type="tristate"
:options="{
stateLabels: { positive: 'Up', zero: 'Flat', negative: 'Down' }
}"
/>Vertical lines at different heights.
<Sparkline
:data="[1, 3, 4, 5, 5, 3, 4, 5]"
type="discrete"
:options="{
lineColor: '#00f',
thresholdColor: '#f00',
thresholdValue: 3
}"
/>Performance vs target visualization.
<Sparkline
:data="[10, 12, 12, 9, 7]"
type="bullet"
:options="{
targetColor: '#f33',
performanceColor: '#33f',
rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff']
}"
/>Simple proportional visualization.
<Sparkline
:data="[1, 1, 2]"
type="pie"
:options="{
sliceColors: ['#3366cc', '#dc3912', '#ff9900'],
borderWidth: 1
}"
/>Statistical data distribution.
<Sparkline
:data="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
type="box"
:options="{
boxLineColor: '#000',
boxFillColor: '#cdf',
whiskerColor: '#000'
}"
/>All chart types support these options:
| Option | Type | Default | Description |
|---|---|---|---|
width |
Number | 100 | Chart width in pixels |
height |
Number | 30 | Chart height in pixels |
lineColor |
String | '#00f' | Primary line/border color |
fillColor |
String | '#cdf' | Fill color |
disableTooltips |
Boolean | false | Disable all tooltips |
showTooltipTitle |
Boolean | true | Show title in multi-value tooltips |
tooltipPrefix |
String | '' | Text to prepend to tooltip values |
tooltipSuffix |
String | '' | Text to append to tooltip values |
| Option | Type | Default | Description |
|---|---|---|---|
spotColor |
String | '#f80' | Color of end spots |
spotRadius |
Number | 1.5 | Radius of spots |
lineWidth |
Number | 1 | Width of the line |
minSpotColor |
String | '#f80' | Color of minimum value spot |
maxSpotColor |
String | '#f80' | Color of maximum value spot |
normalRangeMin |
Number | undefined | Lower bound of normal range |
normalRangeMax |
Number | undefined | Upper bound of normal range |
normalRangeColor |
String | '#ccc' | Color of normal range |
dataLabels |
Array | undefined | Labels for each data point (e.g., ['Jan', 'Feb', 'Mar']) |
getPointDataLabel |
Function | undefined | Callback function to generate labels: (index) => string |
seriesNames |
Array | undefined | Names for each series in multi-series charts |
| Option | Type | Default | Description |
|---|---|---|---|
barColor |
String | '#3366cc' | Color for positive bars |
negBarColor |
String | '#f44' | Color for negative bars |
zeroColor |
String | undefined | Color for zero values |
barWidth |
Number | 4 | Width of each bar |
barSpacing |
Number | 1 | Space between bars |
zeroAxis |
Boolean | true | Whether to center around zero |
dataLabels |
Array | undefined | Labels for each data point (e.g., ['Q1', 'Q2', 'Q3']) |
getPointDataLabel |
Function | undefined | Callback function to generate labels: (index) => string |
seriesNames |
Array | undefined | Names for each segment in stacked bar charts |
| Option | Type | Default | Description |
|---|---|---|---|
posBarColor |
String | '#6f6' | Color for positive values |
negBarColor |
String | '#f44' | Color for negative values |
zeroBarColor |
String | '#999' | Color for zero values |
stateLabels |
Object | { positive: 'Win', zero: 'Draw', negative: 'Loss' } |
Custom labels for the three states |
barWidth |
Number | 4 | Width of each bar |
barSpacing |
Number | 1 | Space between bars |
dataLabels |
Array | undefined | Labels for each data point (e.g., ['Game 1', 'Game 2']) |
getPointDataLabel |
Function | undefined | Callback function to generate labels: (index) => string |
| Option | Type | Default | Description |
|---|---|---|---|
lineColor |
String | '#00f' | Default line color |
lineHeight |
Number | 'auto' | Height of lines |
thresholdColor |
String | undefined | Color for values above threshold |
thresholdValue |
Number | 0 | Threshold value |
dataLabels |
Array | undefined | Labels for each data point (e.g., ['Mon', 'Tue', 'Wed']) |
getPointDataLabel |
Function | undefined | Callback function to generate labels: (index) => string |
| Option | Type | Default | Description |
|---|---|---|---|
sliceColors |
Array | ['#3366cc', '#dc3912', ...] | Colors for pie slices |
borderWidth |
Number | 0 | Width of slice borders |
borderColor |
String | '#000' | Color of slice borders |
offset |
Number | 0 | Angle offset in degrees |
dataLabels |
Array | undefined | Labels for each slice (e.g., ['Category A', 'Category B']) |
getPointDataLabel |
Function | undefined | Callback function to generate labels: (index) => string |
glowIntensity |
Number | 5 | Intensity of highlight glow effect (0 to disable) |
| Option | Type | Default | Description |
|---|---|---|---|
targetColor |
String | '#f33' | Color of target marker |
performanceColor |
String | '#33f' | Color of performance bar |
rangeColors |
Array | ['#d3dafe', '#a8b6ff', '#7f94ff'] | Colors for range bands |
targetWidth |
Number | 3 | Width of target line |
| Option | Type | Default | Description |
|---|---|---|---|
boxLineColor |
String | '#000' | Color of box outline |
boxFillColor |
String | '#cdf' | Fill color of box |
whiskerColor |
String | '#000' | Color of whiskers |
outlierLineColor |
String | '#333' | Color of outlier markers |
outlierFillColor |
String | '#fff' | Fill color of outlier markers |
medianColor |
String | '#f00' | Color of median line |
showOutliers |
Boolean | true | Whether to show outliers |
target |
Number | undefined | Target value to display |
targetColor |
String | '#4a2' | Color of target marker |
You can provide coordinate pairs for line charts:
<Sparkline
:data="[[1,1], [2.7,4], [3.4,6], [5,6]]"
type="line"
/>Display multiple data series on a single line chart. Perfect for comparing trends, showing actual vs. target, or multi-region analysis.
Basic Multi-Series:
<template>
<Sparkline
:data="multiSeriesData"
type="line"
:width="300"
:height="100"
:options="multiSeriesOptions"
/>
</template>
<script setup>
import { ref } from 'vue'
const multiSeriesData = ref([
[10, 15, 20, 18, 25, 30, 28], // Actual sales
[15, 18, 22, 20, 26, 28, 30] // Target sales
])
const multiSeriesOptions = {
seriesNames: ['Actual', 'Target'],
// Colors auto-assigned if not specified (high-contrast palette)
lineColor: ['#0066cc', '#ff6600'],
fillColor: ['rgba(0,102,204,0.15)', 'rgba(255,102,0,0.15)'],
lineWidth: [2, 2],
spotRadius: 0 // Optional: hide spots for cleaner look
}
</script>Auto Colors:
<!-- Uses default high-contrast palette automatically -->
<Sparkline
:data="[[1,2,3], [4,5,6], [7,8,9]]"
type="line"
:options="{ seriesNames: ['A', 'B', 'C'] }"
/>Per-Series Customization:
<Sparkline
:data="[series1, series2, series3]"
type="line"
:options="{
seriesNames: ['North', 'South', 'West'],
lineColor: ['#e74c3c', '#3498db', '#2ecc71'], // Red, Blue, Green
lineWidth: [3, 2, 1], // Emphasize first series
spotRadius: [2, 0, 0] // Spots only on first series
}"
/>Features:
- Automatic color assignment with 8 high-contrast colors
- Tooltips show all series values at hover position
- Single vertical line highlights all series simultaneously
- Full support for null values and gaps
- Maintains chart range across all series
- Per-series customization for colors, widths, and spots
Null values create gaps in line charts or are omitted in bar charts:
<Sparkline
:data="[1, 4, 6, null, null, 5, 3, 5]"
type="line"
/>The component automatically redraws when data changes:
<template>
<Sparkline :data="dynamicData" type="line" />
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
setup() {
const dynamicData = ref([1, 2, 3, 4, 5]);
onMounted(() => {
setInterval(() => {
dynamicData.value = Array.from(
{ length: 10 },
() => Math.random() * 100
);
}, 1000);
});
return { dynamicData };
}
}
</script>If you're migrating from the original jQuery Sparkline library:
- Replace
$(selector).sparkline(data, options)with<Sparkline :data="data" :options="options" /> - Move chart type from options to the
typeprop - Move width/height from options to props
- The rest of the options remain largely the same
$('.sparkline').sparkline([1,4,6,6,8,5,3,5], {
type: 'line',
width: 100,
height: 30,
lineColor: '#00f',
fillColor: '#cdf'
});<Sparkline
:data="[1,4,6,6,8,5,3,5]"
type="line"
:width="100"
:height="30"
:options="{
lineColor: '#00f',
fillColor: '#cdf'
}"
/>Access chart methods for advanced control:
<template>
<Sparkline
ref="chartRef"
:data="chartData"
type="line"
/>
<button @click="refreshChart">Refresh</button>
</template>
<script setup>
import { ref } from 'vue'
import Sparkline from 'sparkline-vue'
const chartRef = ref(null)
const chartData = ref([1, 2, 3, 4, 5])
const refreshChart = () => {
chartRef.value?.refresh()
}
// Access chart instance
const getChartDetails = () => {
const instance = chartRef.value?.getChartInstance()
console.log('Chart instance:', instance)
}
</script>Control tooltip appearance and content:
<template>
<!-- Disable title in tooltips -->
<Sparkline
:data="multiSeriesData"
type="line"
:options="{
showTooltipTitle: false, // Hide title
tooltipPrefix: '$',
tooltipSuffix: ' USD'
}"
/>
<!-- Custom tooltip formatting -->
<Sparkline
:data="[1, 2, 3, 4, 5]"
type="bar"
:options="{
tooltipPrefix: 'Value: ',
tooltipSuffix: ' units',
tooltipFormat: '{{value.2}}' // 2 decimal places
}"
/>
</template>Tooltip Options:
showTooltipTitle: Show/hide title in multi-value tooltips (default: true)disableTooltips: Completely disable tooltips (default: false)tooltipPrefix: Text to prepend to valuestooltipSuffix: Text to append to valuestooltipFormat: Template string for formatting (e.g.,'{{value.2}}'for 2 decimals)
Listen to chart interactions:
<Sparkline
:data="[1,2,3,4,5]"
type="line"
@click="handleClick"
@region-change="handleRegionChange"
/>
<script setup>
const handleClick = (detail) => {
console.log('Clicked region:', detail.region)
console.log('Value:', detail.value)
}
const handleRegionChange = (detail) => {
console.log('Region changed:', detail.region)
console.log('Previous region:', detail.previousRegion)
}
</script>When displaying many charts (50+), enable optimized mode:
<Sparkline
:data="data"
:optimized="true"
/>Benefits:
- Object Pooling: Reuses chart instances
- Shared Tooltips: One tooltip for all charts
- Cached Defaults: Reduces memory allocations
- ~50% faster rendering with large datasets
- Batch Updates: Update data in batches rather than individual points
- Debounce Rapid Changes: Use
debouncefor frequently updating data - Appropriate Dimensions: Smaller charts render faster
- Disable Tooltips: Set
disableTooltips: trueif not needed - Live Data: Tooltips are automatically preserved during data updates for smooth UX
<script setup>
import { ref } from 'vue'
import { debounce } from 'lodash-es'
const chartData = ref([])
// Debounce rapid updates
const updateData = debounce((newData) => {
chartData.value = newData
}, 100)
</script>The component includes built-in accessibility features:
- ARIA role: Canvas has
role="img" - ARIA label: Descriptive label with chart type and data point count
- Keyboard navigation: Accessible through standard tab navigation
- Screen reader friendly: Provides context about chart content
Provide additional context when needed:
<div role="region" aria-label="Sales performance chart">
<h3 id="chart-title">Monthly Sales</h3>
<Sparkline
:data="salesData"
type="line"
aria-describedby="chart-title"
/>
<p class="sr-only">
Sales trend showing {{ salesData.length }} months of data
</p>
</div>The component includes helpful validation that will warn you in development mode.
❌ Wrong:
<Sparkline type="line" />
<!-- Console warning: [Sparkline] data prop is required -->✅ Correct:
<Sparkline :data="[1,2,3,4,5]" type="line" />❌ Wrong:
<Sparkline :data="['1', '2', '3']" />
<!-- Console warning: [Sparkline] data must be an array -->✅ Correct:
<Sparkline :data="[1, 2, 3]" />❌ Wrong:
<script setup>
const data = [1, 2, 3]
data.push(4) // Mutates directly
</script>✅ Correct:
<script setup>
import { ref } from 'vue'
const data = ref([1, 2, 3])
data.value = [...data.value, 4] // Create new array
</script>✅ Best Practice:
<template>
<div v-if="chartData.length > 0">
<Sparkline :data="chartData" />
</div>
<div v-else>
No data available
</div>
</template>❌ Wrong:
<Sparkline :data="data" width="200px" height="50px" />
<!-- Console warning: [Sparkline] width must be a positive number -->✅ Correct:
<Sparkline :data="data" :width="200" :height="50" />The component is SSR-compatible (Nuxt, VitePress, etc.):
<!-- Works in Nuxt without client-only wrapper -->
<Sparkline :data="[1,2,3,4,5]" type="line" />The component automatically detects server environment and skips canvas operations during SSR.
Full TypeScript support with comprehensive type definitions:
import { ref } from 'vue'
import Sparkline, { type SparklineProps } from 'sparkline-vue'
const props: SparklineProps = {
data: [1, 2, 3, 4, 5],
type: 'line',
width: 200,
height: 50,
options: {
lineColor: '#00f',
fillColor: '#cdf'
}
}The package includes comprehensive tests. To run them:
npm install
npm testimport { mount } from '@vue/test-utils'
import Sparkline from 'sparkline-vue'
describe('My Sparkline Usage', () => {
it('renders correctly', () => {
const wrapper = mount(Sparkline, {
props: {
data: [1, 2, 3, 4, 5],
type: 'line'
}
})
expect(wrapper.find('canvas').exists()).toBe(true)
})
})- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- Check browser console for error messages
- Verify data format is an array of numbers
- Ensure dimensions are positive numbers
- Check canvas support in your browser
- Enable optimized mode for many charts
- Reduce data points if possible
- Use appropriate chart dimensions
- Disable tooltips if not needed
- Update type definitions:
npm install sparkline-vue@latest - Check prop types match the interface
- Import types:
import type { SparklineProps } from 'sparkline-vue'
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Visit: http://localhost:5175/
Check out the /docs directory for comprehensive demos:
- 🏠 Landing Page - Overview with navigation between all examples
- 📊 Complete Demo - All 7 chart types with interactive features
- 🚀 Simple Demo - Basic implementations using Vue 3 from CDN
- 💬 Tooltip Demo - Advanced tooltip formatting examples
- ⚡ Vite Demo - Modern Vue SPA with ES modules
npm run buildThis creates distributable files in the dist/ directory.
This project is licensed under the BSD-3-Clause License - the same license as the original jQuery Sparkline library.
This library is a Vue.js rewrite of the excellent jQuery Sparkline library v2.1.2 by Gareth Watts (Splunk, Inc.). All chart rendering logic and algorithms are ported from the original implementation.
)