DEV Community

Cover image for How to add a sparkline to your Vue.js app
Corentin for Mailmeteor

Posted on • Edited on

9 3

How to add a sparkline to your Vue.js app

Very recently, I was looking to add a neat sparkline to a Vue.js application of my own.

As always, I googled just that, looking for sparkline vue.js or sparkline npm. But I couldn't find something that was easy, with a small footprint and yet customizable.

After playing a bit with Chart.js, I just stopped and considered how I could build a decent, yet very simple, sparkline component (i.e. without any dependency).

If you look at how npm's sparkline works as well as the ones from Stripe's dashboard, you will quickly realize that it's just a SVG element that you customize with JavaScript.

So bear with me, I'll show you how to do just that.

Demo

Behind the scene

The sparkline is just a Vue.js component where you provide the coordinates of the sparkline as an array. Here's how I've rendered the sparkline in the example above:

<sparkline v-bind:data="[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]"></sparkline>
Enter fullscreen mode Exit fullscreen mode

The source code of the component is the following:

<template>
<svg class="sparkline" :width="width" :height="height" :stroke-width="stroke">
<path class="sparkline--line" :d="shape" fill="none"></path>
<path
class="sparkline--fill"
:d="[shape, fillEndPath].join(' ')"
stroke="none"
></path>
</svg>
</template>
<script>
export default {
props: ["data"],
data() {
return {
stroke: 3,
width: 256,
height: 80,
};
},
computed: {
shape() {
const stroke = this.stroke;
const width = this.width;
const height = this.height - stroke * 2;
const data = this.data || [];
const highestPoint = Math.max.apply(null, data) + 1;
const coordinates = [];
const totalPoints = this.data.length - 1;
data.forEach((item, n) => {
const x = (n / totalPoints) * width + stroke;
const y = height - (item / highestPoint) * height + stroke;
coordinates.push({ x, y });
});
if (!coordinates[0]) {
return (
"M 0 " +
this.stroke +
" L 0 " +
this.stroke +
" L " +
this.width +
" " +
this.stroke
);
}
const path = [];
coordinates.forEach((point) =>
path.push(["L", point.x, point.y].join(" "))
);
return ["M" + coordinates[0].x, coordinates[0].y, ...path].join(" ");
},
fillEndPath() {
return `V ${this.height} L 4 ${this.height} Z`;
},
},
};
</script>
<style>
svg {
stroke: #1f8ceb;
fill: rgba(31, 140, 235, 0.06);
transition: all 1s ease-in-out;
}
svg path {
box-sizing: border-box;
}
</style>
view raw Sparkline.vue hosted with ❤ by GitHub

As you might have noticed, the code renders an <svg> HTML element by computing the coordinates of the different <path>.

There are two <path>. One for the blue line. And another one for the blue background. I've used the color #1f8ceb but of course this is totally customizable, just like the width/height of the sparkline.

That component is pretty basic and contrary to NPM or Stripe, it doesn't handle when a mouse hovers the <svg>. I didn't need that for my use case, but if ever you implement it, feel free to edit the gist and share it with the community.

The Fastest, Most Accurate API for Voice AI

Ad Image

Power your Conversational AI with the most accurate real-time speech-to-text API. Available in 50 languages and at <1-second latency. Perfect for building seamless and emotionally intelligent voice experiences.

Start building today 🛠️

Top comments (2)

Collapse
 
cuireuncroco profile image
Jean

Clever use of Vue!

Collapse
 
frenchcooc profile image
Corentin • Edited

As always, feel free to share your thoughts/improvements in the comment 🤗

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay