A Vue.js component to create beautiful and animated circular progress bars, implemented with SVG. The purpose of this plugin is to combine the best properties of other available libraries and to add unique features, delivered in a simple to use component with friendly interface. With the available options you can create simple circles very quickly. But playing with the combinations of props and with a bit of imagination you can create really exciting things.
Take a look at some interesting examples on the Demo page
Install the library via npm
npm i vue-ellipse-progress
The library is provided as a Vue.js plugin. So just initialize it in your main.js
:
import VueEllipseProgress from 'vue-ellipse-progress';
Vue.use(VueEllipseProgress);
// Vue.use(VueEllipseProgress, "vep"); you can define a name and use the plugin like <vep/>
Now use the component
<vue-ellipse-progress
:data="circles"
:progress="progress"
:angle="-90"
color="blue"
:colorFill="colorFillGradient"
emptyColor="#8ec5fc"
:emptyColorFill="emptyColorFillGradient"
:size="300"
:thickness="10"
emptyThickness="10%"
lineMode="in 10"
:legend="true"
:legendValue="180"
legendClass="legend-custom-style"
dash="60 0.9"
animation="reverse 700 400"
:noData="false"
:loading="false"
fontColor="white"
:half="false"
:gap="10"
dot="10 blue"
fontSize="5rem">
<span slot="legend-value">/200</span>
<p slot="legend-caption">GOOD JOB</p>
</vue-ellipse-progress>
You are ready to go with just following line:
<vue-ellipse-progress :progress="progress"/>
The progress
is the only required property. However, in order to create unique circles that match your design needs, you can use all the properties explained below.
This table below provides a quick overview over all available options. To gain more information in general and concerning the creation of exclusive circles please read below the table.
Also make sure to check slot options
Prop | Type | Values | Default |
---|---|---|---|
progress |
Number | 0 - 100 | |
size |
Number | >=0 | 200 |
line |
String | "round | square |
thickness |
Number | String | >=0 as Number or percent value as String |
lineMode |
String | "normal | out |
emptyThickness |
Number | String | >=0 as Number or percent value as String |
color |
String | Object | any color as String or Object to specify gradient (see details) |
colorFill |
String | Object | same as color |
emptyColor |
String | Object | same as color |
emptyColorFill |
String | Object | same as color |
legend |
Boolean | true | |
legendValue |
Number | any Number | |
animation |
String | "default | rs |
loading |
Boolean | false | |
determinate |
Boolean | false | |
noData |
Boolean | false | |
angle |
Number | any Number | -90 |
fontSize |
String | any valid CSS value | “1rem” |
fontColor |
String | any valid CSS value | “gray” |
legendClass |
String | any | |
dash |
String | “[strict] count spacing” | |
half |
Boolean | false | |
dot |
String | Number | Object |
gap |
Number | defines the gap between multiple circles | 0 |
data |
Array | defines multiple circles, takes as values Objects with all props defined above |
progress
Is any Number from 0 to 100 (including decimals). This property defines the filled area from progress circle line in percent. progress
is animated and counts up or down on any value changes with duration defined in animation.duration
property. The calculation of the progress is up to you. The progress is shown by default as the legend in the middle of the circle.
this.progress = 55.5;
this.progress = this.tasksDone * 100 / maxTasks; // the percentage of done tasks
The progress
is always used to fill the progress circle line. So you cannot customize this value. All values below 0 and above 100 are ignored. For customization purpose please use legendValue
. If legendValue
is defined the progress will NOT be displayed as circle legend.
size
Is any number from >=0. It defines the width and height of the circle. The calculation of the circumference of the circle depends on the properties lineMode
, thickness
and emptyThickness
so the progress circle never exceeds the size
value!
Check lineMode
property to understand how the progress circle behaves depending on the line mode and offset.
line
Is a string value from round | square | butt
. Defines the progress circle line cap. Internally is used the css property stroke-linecap
.
line="round"
thickness
Is any number or percent value >=0. It defines the progress circle line thickness. If you define the value in percent, the thickness will be calculated in relation to size
. Internally is used the css property stroke-width
.
lineMode
Descriptive string in form "mode [offset]"
that defines how the progress line is aligned in relation to empty line. The first value ist the mode
and the optional second is the offset
. You can understand the modes as the presets that help you to align lines as you want to.
mode
:
normal
: this is the default value and both lines are aligned at the base line (centered).in
: the progress line is inside the empty circlein-over
: the progress line is both inside the empty circle and overlaps the empty circleout
: the progress line is outside the empty circleout-over
: the progress line is both outside the empty circle and overlaps the empty circlebottom
: the progress line is aligned at the bottom of the empty circletop
: the progress line is aligned at the top of the empty circleoffset
: is any negative or positive number and defines the distance between the progress and empty lines. It can be only combined with the in
and out
modes
Let’s take a look at few examples
line-mode="in 10" |
line-mode="in 10" |
line-mode="out 10" |
line-mode="out 15" |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
As you can see the second and fourth examples are similar to the modes bottom
and top
. Only with the modes in
and out
and the offset
you can achieve the same result. But the provided modes like a presets take care about annoying calculations and do the job for you.
emptyThickness
Is any number or percent value >=0. It defines the empty circle line thickness. If you define the value in percent, thickness will be calculated in relation to size
. Internally is used the CSS property stroke-width
.
color
Defines the color of progress circle line. Is any CSS color like #123
or lime
or an object that defines the gradient.
color="#3f79ff"
- as String
:color="{...}"
- as Object
radial
- default false
. Defines whether the gradient is radial or linearcolors
- Array that contains the gradient colors as objects { color: "#6546f7", offset: 0 [, opacity: 1] }
Now you are ready for an example.
:color="gradient"
gradient: {
radial: false,
colors: [
{
color: '#6546f7',
offset: 0,
opacity: '1',
},
{
color: 'lime',
offset: 100,
opacity: '0.6',
},
]
}
colorFill
Defines the fill color of the progress circle. Takes the same value as color
emptyColor
Defines the color of the empty circle line. Takes the same value as color
emptyColorFill
Defines the fill color of the empty circle. Takes the same value as color
legend
Is a Boolean. It defines whether the progress
or from you defined legendValue
is displayed as the legend of the circle.
legendValue
Is any number. Use this property if you want to customize the shown progress as the legend of the circle. If defined, legendValue
will replace progress
as the circle legend!
Let’s say you need to display a rating from 0 to 5 of a product with 3.5 stars. Since progress
can take values only from 0 to 100 your need an additional property legendValue
. Now you can set legendValue = 3.5
and calculate the progress something like that:
this.progress = 3.5 * 100 / 5; // the rating percentage
Now you can display custom progress value that still animated and circle progress fills properly!
note that legendValue
excludes progress
but not vice versa.
animation
Descriptive string in form "type [duration delay]"
that defines the initial animation of progress circle line filling. type
is one from predefined animations and the optional duration
and delay
are number values. Note that the order is important and that you can only define the delay
after duration
.
type
- is one of the predefined animations: default | rs | reverse | bounce| loop
duration
- number in milliseconds, default 1000
delay
- number in milliseconds, default 400
animation="rs 700 200"
animation="bounce 1000"
loading
Forces loading state. The component provides an indeterminate loading state for the case that your data is not available immediately. With this property set to true
you can use the component as the indeterminate progress.
determinate
Provides a determinate loading state that indicates that your data loading is still in progress but allows to show the progress
.
noData
Forces no data state. The component provides a no data state for the case that your data is not available. The circle progress is still empty.
The component will take the no data state even if you provide an invalid progress
value
angle
Is any number. It defines the starting point of the progress circle line.
fontSize
Is any valid CSS size value. It defines the font size of the circle legend. You will have to use legendClass
if you want to apply more specific styles.
fontColor
Is any valid CSS color value. It defines the color of the circle legend. You will have to use legendClass
if you want to apply more specific styles.
legendClass
Adds class to the circles legend to give you the possibility to style it.
dash
Descriptive string in form "[strict] count spacing"
that adds dashed empty progress line. This property provides the optional strict
mode. In this mode you can define the explicit number of dashes as count
with the given relative spacing
as number in range >= 0 and < 1. Without strict
the default behavior of the SVG stroke-dasharray
property is used, where the size and spacings of the dashes are defined.
dash="strict 60 0.5"
- 60 dashes with 0.5 relative spacing
dash="10 10"
- 10 pixels big dashes with 10 pixels spacing, the number of dashes depends on the empty circle circumference
Boolean value that specifies the type of the circle. If it is set to true, only the half of the circle will be drawn like a gauge chart.
dot
The dot property lets you define a point indicator at the end of the progress line. You have a lot of freedom to customize the dot using a Number, descriptive String, or an Object to inject any CSS styles.
Number: :dot="10"
- specifies a round dot with 10px width and height and default #713dfd
color
Descriptive string: dot="size [color]"
- size
can be just a Number or a percent value like 5%
, the calculation for percent values is similar to thickness
and depends on the size
. color
is optional and lets you quickly define the color of the dot. The order of properties is important for parsing the String and you can set the color
only if the size
is defined.
Object: :dot="{ size: Number | String [, any CSS inline style with Vue syntax] }"
- to customize the point, you can define the prop as an Object. size
is required and can be just a Number or a String to define a percent value. Only defining the prop as an Object you have the possibility to add any styles to the dot you want to, using Vue syntax for defining inline styles, you can even completely break the positioning of the dot, if you need. You cannot override the height
of the dot since it is important for internal calculation and must be controllable.
The examples will provide more clarity
:dot="10" // just a Number defining size in pixel
dot="10" // the same as above
dot="10%" // 10% from the circle size will be converted to pixel
dot="5% red" // adds red dot
// defines same dot as above
:dot={
"5%" // required
"red" // add any inline CSS using Vue syntax,
"10px" // you can even move the dot, but it is not recommended
}
data
You can specify 2 or more circles as objects in an array as data
. For each circle you can use almost every available property. It is not necessary to specify all properties, they will be merged with global props and the specified props will overwrite the global. The circles are rendered inside each other.
Excluded props: lineMode
, emptyThickness
, legend
. These properties will be ignored, if data
is specified. The legend of this circle is also not shown.
<!-- this props are applied to all circles, if not overwritten in "data"-->
<vue-ellipse-progres color="blue" animation="loop 500" ... :data="data"/>
data: [
{
progress: 50, // required for each circle
color: "red" // will overwrite global progress color
... // other options will be merged with global
},
{
progress: 50, // required for each circle
animation: "rs 1500 500" // you can set almost any option that will be specific to this circle
}
}
gap
Defines the gap in pixels from one circle to the previous circle. It will be applied only if data
prop is used.
:gap="10"
legend-value
In this slot you can put an additional element that you want to display beside the progress
legend-caption
In this slot you can put any HTML and style it on your own. This slot is aligned below the progress.
This code …
<vue-ellipse-progress ....>
<span slot="legend-value">/200</span>
<p slot="legend-caption">TASKS DONE</p>
</vue-ellipse-progress>
… produces following result. The slots are marked corresponding:
The plugin was tested in all major modern mobile and desktop browsers. It should also work properly in older browsers. In old browsers issues can arise by animations since they are implemented using CSS custom properties. Basic SVG renders even in IE 11.
npm i
npm run serve
npm run lint
npm run test:unit
npm run build
Author: setaman
Live Demo: https://vue-ellipse-progress-demo.netlify.com/
GitHub: https://github.com/setaman/vue-ellipse-progress
#vuejs #vue #javascript #vue-js