Examples: jQuery plugin

directly calling the plugin

Some selected previews of the examples (shown in detail further down in this document), to give you a first idea of the plugin's customizability:

25 % 30 % 40 % 45 % 55 % 65 % 100 %

1:55

80
%
20
sec.

General usage

The following examples each show a JavaScript line of the kind:

$(selector).progressPie(options)

or alternatively:

$(selector).setupProgressPie(options).progressPie()
  • The first way is usually used for a one-time drawing without dynamic updates. The second kind (setupProgressPie) stores the options, enabling you to repeatedly call the parameterless progressPie() method to redraw / update the chart with a new value but otherwise unchanged settings.

  • selector is a jQuery selector string, depending on the actual HTML document. In these cases it's a selector specific to this actual HTML page, selecting the span elements corresponding to the respective example.

  • The actually interesting bit is thus the options portion of each example.

  • Please note, that these lines have to be executed after the DOM tree has been created by the browser. Typically, using jQuery, this is done in the following way:

    <head>
        …
        <script type="text/javascript">
            $(function() {
                $(selector).progressPie(options);
            });
        </script>
    </head>
    

Default mode

$(".pp.default").progressPie();

applied to elements like:

<span class="pp default">100</span> %

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Predefined modes

Color mode (dynamic color)

$(".pp.dyncolor").progressPie({mode:$.fn.progressPie.Mode.COLOR});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Green mode (static color)

$(".pp.green").progressPie({mode:$.fn.progressPie.Mode.GREEN});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Red mode (static color)

$(".pp.red").progressPie({mode:$.fn.progressPie.Mode.RED});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Ring instead of full pie

Add the ringWidth option in order to draw a ring segment instead of a pie.
It's recommended to combine this with either a very small strokeWidth (defining the stroke of the full surrounding circle)…

$(".pr.dyncolor").progressPie({mode:$.fn.progressPie.Mode.COLOR, strokeWidth: 1, ringWidth: 3});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

… or with a strokeWidth identical to the ringWidth but setting a different, constant color for the outer circle's stroke via the strokeColor option:

$(".pr.onsilver").progressPie({mode:$.fn.progressPie.Mode.COLOR, ringWidth: 4, strokeWidth: 4, strokeColor: '#ddd'});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

User-defined colors

User-defined static color (via color option)

$(".pp.navy").progressPie({color:"navy"});
$(".pp.yellow").progressPie({color:"#eee000"});
$(".pp.rgb").progressPie({color:"rgb(0,150,100)"});
$(".pp.rgba").progressPie({color:"rgba(0,150,100,0.6)"});

The following pies are each assigned one of the four classes ‘navy’, ‘yellow’, ‘rgb’, or ‘rgba’. The option set is always the same (color), the difference (beside from the color itself) is the color notation syntax. The ‘rgba’ example demonstrates an alpha channel, setting a transparancy level for the pie graph.

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Notice that the foreground pie overlaps the background circle. In this case, using an alpha channel, i.e. semi-transparent strokes, this causes the opacity of the doubly covered area to increase, the background circle remains visible behind the foreground. If you don't want that, set the overlap option (see below) to false:

$(".pp.rgbanooverlap").progressPie({color:"rgba(0,150,100,0.6)", overlap: false});
$(".pr.rgbanooverlap").progressPie({color:"rgba(0,150,100,0.6)", overlap: false, ringWidth: 3});

25 % 50 % 65 % 80 % 99 % 100 %

Local Color Function (via color option)

Example 1: Inline function

$(".pp.myfunc").progressPie({color:function(percent) {
    return percent >= 50 ? "#3f3" : "#f33";
}});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Example 2: Function reference

function blueGt25(percent) {
    var blue = percent < 25 ? 0 : (percent-25)*3; //range from 0 to 3*75 = 225 ( = max brightness for value of 100%)
    return "rgb(0,0," + blue + ")";
}
…
$(function(){
    $(".pp.myblue").progressPie({color:blueGt25});
});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Example 3: A function (referenced) re-using/adapting the internal function colorByPercent

function colorGt50(percent) {
    var p = percent <= 50 ? 0 : 2 * (percent - 50);
    return $.fn.progressPie.colorByPercent(p);
}
…
$(function(){
    $(".pp.gt50").progressPie({color:colorGt50});
});

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

CSS formatting

Starting with V2.0.0, the ProgressPie plug-in adds class attributes to the SVG components, enabling you to define some global CSS rules to globally format some of the pie diagram's design features instead of programmatically configuring everything via plug-in options alone: The default classnames are:

  • progresspie-background for the background circle and

  • progresspie-foreground for the pie or ring drawn on top of the latter.

  • If you are drawing a double pie/ring chart, both foreground pies or rings (outer and inner) bear the progresspie-foreground class, but they get (both) fitted with a second class:

    • progresspie-outer for the outer and

    • progresspie-inner for the inner pie or ring.

    So a CSS rule like .progresspie-foreground{...} will apply to all foregrounds of single pies as well as for inner and outer displays of double pies, while a selector like .progresspie-foreground.progresspie-inner explicitly selects all inner parts of double pies.

  • Should you even add further values (triple pies or more), i.e. you have an outer ring containing an inner ring, which itself contains a further inner ring, which might again contain yet another inner ring and so on, the inner classes get postfixed with numbers:

    • The outer ring still gets marked class progresspie-outer,

    • the second ring (inner) still gets marked by class progresspie-inner,

    • the third ring (inner.inner) gets marked by class progresspie-inner2,

    • the fourth ring (inner.inner.inner) gets marked by class progresspie-inner3.

    • and so on.

Overriding CSS in „normal“ mode

Assume a regular plug-in call (programatically defining the colors, in this case using the predefined COLOR mode):

$(".pr.css1").progressPie({mode:$.fn.progressPie.Mode.COLOR, ringWidth: 4, strokeWidth: 4});

This example alone doesn't make any sense, since a ring segment is drawn on top of a full circle with the same width and the same color, i.e. the ring segment will be effectively invisible.
But we can use CSS to override style properties of the chart. Here, we firstly set a stroke-dasharray for a dashed background circle and secondly we override the background circle's color (like we could have done locally programatically via the strokeColor option, see above):

.pr.css1 .progresspie-background {
    stroke-dasharray: 1px 3px;
    stroke: #bbb !important;
}

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Keep in mind that local styles (i.e. style attributes inside the SVG markup generated by the plug-in) have priority over global styles in a CSS ruleset. Since the plug-in locally sets a color via stroke property in a style attribute, we need to add the !important directive in order to override that local stroke style.

Special CSS mode

If you really want to style the color (and alignment) of your diagrams (statically) via CSS rules, you can tell the progressPie plug-in to completely omit color and vertical-align definitions in the local styles (thus removing the need for !important directives). This is done by setting the mode option to the fourth predefined color mode: $.fn.progressPie.Mode.CSS.
Be aware, however, that in CSS mode…

  • you must define all colors yourself, i.e. you have to set the stroke and fill properties for the background and the stroke property for the foreground. (The foreground's fill property is still set locally to none by the ProgressPie plug-in even in CSS mode, since filling of a ring segment doesn't make sense),

  • and you should define the vertical-align style of the SVG node, at least if the target element is not empty, but the SVG is appended or prepended to text content: The first of the following examples omits the vertical-align rule with the result, as you can see, that the pies and the percent labels are not nicely aligned. (In any other mode, this vertical alignment is set via the plug-in's verticalAlign option, defaulting to bottom, but in CSS mode, that option is ignored.

$(".pp.css1").progressPie({mode:$.fn.progressPie.Mode.CSS});
.pp.css1 .progresspie-background {
    stroke-dasharray: 3px 1px;
    stroke: #bbb;
    fill: none;
}
.pp.css1 .progresspie-foreground {
    stroke: rgba(0, 100, 150, 0.5);
}

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

$(".pr.css2").progressPie({mode:$.fn.progressPie.Mode.CSS, ringWidth: 3, strokeWidth: 3});
.pr.css2 svg {
    vertical-align: bottom;
}
.pr.css2 .progresspie-background {
    stroke: rgb(200, 200, 200);
    fill: rgba(200, 200, 200, 0.2);
}
.pr.css2 .progresspie-foreground {
    stroke: rgb(0, 200, 0);
}

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

For an example if CSS formatting double pie/ring charts see the corresponding section.

Renaming the CSS classes

The default classes progresspie-foreground etc. have intentionally been prefixed with "progresspie-" in order to avoid name conflicts with other CSS code.

You may globally change these defaults by overwriting the properties jQuery.fn.progressPie.defaults.cssClassBackgroundCircle, jQuery.fn.progressPie.defaults.cssClassForegroundPie, jQuery.fn.progressPie.defaults.cssClassOuter and jQuery.fn.progressPie.defaults.cssClassInner.

Or you may locally set other classnames by adding the options cssClassBackgroundCircle, cssClassForegroundPie, cssClassOuter or cssClassInner to the options argument of your plug-in call.
The following example will demonstrate this (omitting the cssClassOuter and cssClassInner options, since they are only used with double pies):

$(".pp.css2").progressPie({
    mode: $.fn.progressPie.Mode.CSS, 
    strokeWidth: 0,
    cssClassBackgroundCircle: "piebg",
    cssClassForegroundPie: "piefg"
});
.pp.css2 svg {
    vertical-align: middle;
}
.pp.css2 .piebg {
    stroke-dasharray: 1,4;
    fill: silver;
}
.pp.css2 .piefg {
    stroke: navy
}

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Advanced options

append instead of prepend

By default, the pie gets prepended to the selected element's content. You may opt to appending it behind the content instead:

$(".pp.append").progressPie({prepend: false, separator: "%:&nbsp;"});

applied to elements like:

<span class="pp append">5</span>

0 5 25 42 50 65 80 99 100

Value attribute / value data, manual size and overridden outer circle's stroke:

By default, the percent value to display has to be the (only) content of the selected element and the SVG graphic gets prepended (or optionally appended) to that value (see above). But you may also provide the percent value invisibly in an attribute of the HTML element, usually (conforming to HTML) in a data-* attribute. The element's content may be left empty. (If not empty, the graphic still gets prepended or appended to that content.)

The following examples demonstrate a data-attribute on an empty span element, using the valueData option. Also, they demonstrate different uses of the strokeWidth and strokeColor options which configure the look of the surrounding circle.

And a third aspect also demonstrated is the size option: If you don't set a size option, the pies will be auto-sized. If the DOM node the SVG gets prepended or appended to also contains text, the pie is auto-sized to the line-height. If the pie is be be inserted into a text-less node, this does not work and the plug-in simply chooses a default width. By setting the size option, you may explicitly set a size (diameter) in pixels and thus turn off auto-sizing.

$(".pp.attr:not(.silverborder):not(.navyborder):not(.noborder):not(.ring):not(.filledCircle)").progressPie({
    mode:$.fn.progressPie.Mode.COLOR, valueData:"val", size:30, strokeWidth: 5});

applied to elements like:

<span class="pp attr" data-val="0"></span>

$(".pp.attr.silverborder").progressPie({mode:$.fn.progressPie.Mode.COLOR, valueData:"val", size:30, strokeWidth: 5, strokeColor: "silver"});

strokeWidth may also be zero:

$(".pp.attr.noborder").progressPie({mode:$.fn.progressPie.Mode.COLOR, valueData:"val", size:50, strokeWidth: 0});

Or the outer circle may also be filled completely (setting strokeWidth to the radius, i.e. half the diameter, defined by size), which, of course, only makes sense if the circle's strokeColor differs from the pie's color:

$(".pp.attr.filledCircle").progressPie({mode:$.fn.progressPie.Mode.COLOR, valueData:"val", size:30, strokeWidth: 15, strokeColor: "#ddd"});

Of course, this way of filling the background only works if you set the size manually! A more elegant way regardless of the size would by to set a fill color via CSS, see section on CSS formatting!

strokeWidth 1 combined with a ringWidth and use of valueAttr instead of valueData:

$(".pp.attr.ring").progressPie({mode:$.fn.progressPie.Mode.COLOR, valueAttr:"data-val", size:30, strokeWidth: 1, ringWidth: 5});

Avoid overlapping outer stroke

If you set a different stroke color for the outer circle (see example pp.attr.silverborder above) or choose a semi-transparent foreground color, you'll notice that the foreground (pie or ring) has the same radius as the background circle and thus overlaps it. You may optionally turn off that overlapping, so that the radius of the pie or ring is the total radius of the graphic minus the outer circle's strokeWidth. To do so, set the overlap option to false (it defaults to true).

$(".pp.attr.navyborder").progressPie({
    mode:$.fn.progressPie.Mode.COLOR, 
    valueData:"val", 
    size:30, 
    strokeWidth: 2,
    strokeColor: "navy",
    overlap: false
});

See above for another example (using user-defined color with alpha channel)

Dashed background circle

Strokes in an SVG graphic may be dotted or dashed. The CSS section already demonstrated the use of the stroke-dasharray CSS property. That way you may define simple or complex dash patterns, but you can only define the length of dashes and gaps in pixels. If you want the dashes to be placed at certain points of the circle (e.g. draw a clock face consisting of 12 short dashes placed), you would need to know the exact length of the circle stroke in pixels in order to calculate the correct dasharray!

This is why the ProgressPie plug-in now also offers an option to calculate a dasharray dynamically based on the calculated circle size:

The simplest way is to just specify into how many dashes the chart's background circle should be split:

$(".pp.regulardashes").progressPie({
    valueData:"val", 
    size:30, 
    strokeWidth: 2,
    strokeDashes: 6
});

In this case, the dashes and the gaps between them are equally long. You may change this by additionally setting a stroke length in pixels or in percent (of the stroke's length / circumference). Only percentual settings are really independent of the pie chart's size, since they define the length in relation to the circumference. Let's demonstrate this by drawing pies of different sizes:

$(".pp.percentdashes").progressPie({
    strokeWidth: 2,
    strokeDashes: {
        count: 8,
        length: '10%'
    }
});

0 5 25 33 45 50 70 80 100

To specify the length in percent, you have to set the strokeDashes.length option to a string literal containing a number followed by the percent sign (see above). A single number literal would be interpreted as an abloute length in pixels! Absolute length should only be used with manually sized pies, and you have to ensure that strokeDashes.length * strokeDashes.count is less than the circumference (circle stroke's length in pixels), since the circle stroke can not be divided into parts that are (in sum) greater then the whole circle.

Also note that by default the dashes start the 12 o'clock (or 0 percent) position. You may set the strokeDashes.centered option to true (it defaults to false) in order to center the first stroke around the 12 o'clock position:

$(".pp.centereddashes").progressPie({
    valueData:"val", 
    size:30, 
    strokeWidth: 2,
    strokeDashes: {
        count: 8,
        length: '10%',
        centered: true
    }
});

$(".pp.clockface").progressPie({
    mode: $.fn.progressPie.Mode.COLOR,
    strokeColor: 'silver',
    valueData: "val",
    size: 30,
    strokeWidth: 4,
    strokeDashes: {
        count: 12,
        length: 2,
        centered: true
    }
});

You may set the strokeDashes.inverted option to true in order to invert the pattern, i.e. the options count and length then refer to the transparent gaps, devided by (auto-adjusted) visible dashes between them:

$(".pp.clockfaceInverted").progressPie({
    mode: $.fn.progressPie.Mode.COLOR,
    strokeColor: 'silver',
    valueData: "val",
    size: 30,
    strokeWidth: 4,
    strokeDashes: {
        count: 12,
        length: 2,
        centered: true,
        inverted: true
    }
});

Resizing relatively: sizeFactor vs. scale

Like said above, setting the size options disables auto-sizing and sets a new absolute size. But you may also adjust auto-sizing by specifying the sizeFactor option: The calculated size (either auto-size or value of the size option) is multiplied with this factor to get the final size for the graphic.

The following example sets the size to 50% larger than the default size, and to emphasize the effect of relative sizing (in this case relative to font-size), each number is styled with a different font size:

$(".pp.sizefactor").progressPie({sizeFactor:1.5, verticalAlign:"middle"});

0 5 25 42 50 65 80 99 100

The sizeFactor option is only applied to the default size (auto-size or size) option to calculate the diameter of the pie to draw. It has no effect on other sizes like the strokeWidth or ringWith options. So in the example above, the pies get larger while the strokeWidth of the circle stays the same as it were without the sizeFactor option.

There is a second option pretty similar, but which differs in this effect: The scale option defines a factor by which to resize the otherwise already rendered SVG graphic, thus resizing every aspect of the graphic including the strokeWidth. So if, in the example above, we replace sizeFactor by scale, not only the diameter of the pies increases by 50%, but also the with of the outer circle does:

$(".pp.scale").progressPie({scale:1.5, verticalAlign:"middle"});

0 5 25 42 50 65 80 99 100

In this example of a simple pie chart, the difference between these two options is “marginal”, in more complex eamples the differences may get extremer.

If you should use “double pies” (demonstrated below), please note: Both options are “global” for outer and inner pie and may only be set in the main options object, not inside the inner option. A sizeFactor is individually applied to both graphics, outer and inner pie or ring, the gap between an outer ring and an inner ring or pie will grow when increasing the sizeFactor, while scaling with the scale option will scale outer and inner ring/pie as well the gap between them proportionally, i.e. simply scale the whole graphic.

Value Selector

If the value should still be visible, but is not the only content of the selected element, but the content of some sub-element, you may provide a jQuery selector specifying the sub-element holding the value:

$(".pp.subelem").progressPie({mode:$.fn.progressPie.Mode.COLOR, valueSelector:".valueSub"});

applied to elements like:

<span class="pp subelem">(<span class="valueSub">0</span> %)</span>

(0 %) (5 %) (25 %) (42 %) (50 %) (65 %) (80 %) (99 %) (100 %)

Note: In the first examples, the “%” label was simply placed outside (behind) the span element holding the value and (later) the SVG. But in some cases (e.g. for CSS styling reasons) you might prefer to bundle static text labels and the value inside the same element and simply mark the value by wrapping it into a sub-element like shown here.
The following example shows a special use-case for the valueSelector:

Value Selector and label displayed inside a ring with rounded ends

The following example demonstrates an application of an inner element holding the actual percent value inside the selected element. The main reason for this construct lies in the goal to display the element's content inside the ring.

Also this example demonstrates the ringEndsRounded option.

You have two possibilities to show content inside a ring graph. This example demonstrates the first one: Use the progressPie plug-in to simply render a ring graph without content as SVG image and then place some HTML container with the content on top of the image via CSS rules like those shown below.
An alternative is to use a content plug-in to render the ring content as part of the generated SVG image. See separate content plug-in examples page for a demonstration.

Advantages of the first alternative (HTML content on top of SVG) are easier styling of the content and that even older browsers not capable of rendering SVG images will still show the content, only the ring graph around the value would be missing.

Call of the plugin (the sequence of setupProgressPie() and progressPie() simplifies updates, see below):

$(".pr.around.percent").setupProgressPie({
    size: 70,
    ringWidth: 7,
    strokeWidth: 0,
    ringEndsRounded: true,
    valueSelector: "span.value",
    color: "navy"
}).progressPie();

and CSS:

.pr.around {
    position: relative;
    display: inline-block;
    margin: 1em;
}
.pr.around span {
    color: navy;
}
.pr.around span.outer {
    position: absolute;
    left: 0;
    top: 0;
    width: 70px;
    text-align: center;
    font-size: 10px;
    padding: 15px 0;
}
.pr.around span.value {
    font-size: 25px;
}

applied to elements like:

<span class="pr around percent"><span class="outer"><span class="value">0</span><br>%</span></span>

0
%
5
%
25
%
42
%
50
%
65
%
80
%
99
%
100
%

Note the option separator: "" which avoids inserting a blank space text node between the inserted SVG and the span.outer.

A variation (using the same CSS code) for a one-minute countdown, with inverted dynamic color, a strokeColor (see above) and a valueAdapter for interpreting seconds (see below):

$(".pr.around.countdown").setupProgressPie({
    size: 70,
    ringWidth: 5,
    strokeWidth: 5,
    strokeColor: "#ddd",
    strokeDashes: {
        count: 12, 
        length: 2, 
        centered: true, 
        inverted: true
    },
    valueSelector: "span.value",
    valueAdapter: function(s) {return parseInt(s)*10/6;},
    color: function(p) {return $.fn.progressPie.colorByPercent(100-p);},
    separator: ""
}).progressPie();

60
sec.
50
sec.
40
sec.
30
sec.
20
sec.
15
sec.
10
sec.
5
sec.
0
sec.

Note: Of course, you can use CSS code like in the above example not only to place the value inside the ring. You might also keep the label invisible (providing the value in a data attribute, see above) and put some other graphic (SVG or other format) over/inside the ring, e.g. a pause or stop icon clickable to halt or abort the running process whose value is displayed by the ring.

Vertical alignment

The following example shows alternating pies with and without the option verticalAlign:"middle" (default is "bottom") in a line with a line-height greater than the font-size (so that alignment makes a difference).

$(".pp.vc").progressPie({verticalAlign:"middle"});

applied to elements like:

<span class="pp default">0</span>
<span class="pp vc">5</span>
…

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

Updating (and content plug-ins)

The following examples demonstrate dynamic updating of pies or rings, using the setupProgressPie plug-in function which was introduced in V1.3.0: This function once sets up the options and stores them in each selected DOM node. For updating, now all that's needed is to update the value and call the progressPie() again, which then re-uses the same options on each update.

The setup is usually only done once, but the #timerbutton example below also demonstrates, that the setup may be updated as well: In this case, the content plugin is updated to change the displayed control icon depending on the timer's state.

One of the following examples also demonstrates updating without the setupProgressPie() method. In this case, all the options have to be initialized again for each redraw, and the update option has to be set in order to enable replacing an existent graphic (using the setupProgressPie() method, the update option automatically defaults to true).

<head>
…
<script type="text/javascript">
    var timerVal = 120;
    var timerRunning = false;
    
    function startStopTimer() {
        if (timerVal == 0) {
            timerVal = 120;
            $("#timerbutton").data("val", 0);
        } else {
            timerRunning = !timerRunning;
        }
        if (timerRunning) {     
            timer();
        } else {
            updateTimerPies();
        }
    }
    
    function updateTimerPies() {
        var percent = Math.floor((120 - timerVal) / 1.2);
        //while progressPieSVG actually supports floating point numbers as input, these calculated percent
        //values are also to be displayed inside a ring graph and are therefore intentionally truncated to integers.
        $(".pp:not(.attr).timer").each(function(){
            $(this).text(percent).progressPie();
        });
        $(".pp.attr.timer").each(function(){
            $(this).data("val", percent);
            //if you watch the element in the DOM inspector, you'll probably notice that the original attribute `data-val` is not changed,
            //the value is stored as a number in a jQuery-internal cache (`$.cache`), not in the DOM.
            //Therefore this way of updating the value requires the use of the `valueData` option, `valueAttr` will not work here!
            var size = $(this).hasClass("growing") ? 30 + (percent / 2) : 30;
            var strokeColor = $(this).hasClass("silverborder") ? "silver" : undefined;
            $(this).progressPie({mode:$.fn.progressPie.Mode.COLOR, valueData:"val", size: size, strokeWidth: 5, strokeColor: strokeColor, update: true});
        });
        $(".pr.around.percent.timer").each(function(){
            $("span.value", $(this)).text(percent);
        }).progressPie();
        if (timerVal % 2 == 0) {
            $(".pr.around.countdown.timer").each(function(){
                $("span.value", $(this)).text(timerVal/2);
            }).progressPie();
        }
        $("#timerbutton").data("val", percent)
            .setupProgressPie({contentPlugin: timerRunning ? "pause" : timerVal > 0 ? "play" : "stop"})
            .progressPie();
    }
    
    function timer() {
        if (timerRunning) {
            timerVal -= 1;
            if (timerVal > 0) {
                window.setTimeout(timer, 500);
            } else {
                timerRunning = false;
            }
        }
        updateTimerPies();
    };
    
    $(function() {
        …
        $("#timerbutton").setupProgressPie({
            color: "#00d",
            strokeWidth: 1,
            ringWidth: 3,
            valueData: "val",
            contentPlugin: "play"
        }).progressPie();
        //Setup code for the other pies: see previous examples
    });
</script>
</head>
…
<body>
    …
    <p><span class="pp default timer">0</span> %<br>
        <span class="pp attr timer" data-val="0"></span><br>
        <span class="pp attr silverborder timer growing" data-val="0"></span><br>
        <span class="pr around percent timer"><span class="outer"><span class="value">0</span><br>%</span></span><br>
        <span class="pr around countdown timer"><span class="outer"><span class="value">60</span><br>sec.</span></span><br>
        <button onclick="startStopTimer()" id="timerbutton" data-val="0">Click me!</button>
    </p>
    …
</body>

0 %


0
%

60
sec.

The control icons in the button above are a demonstration of the SVG content plug-in mechanism: You may provide special plugin modules which render additional SVG content inside a ring graph. These control plug-ins require the inclusion of an additional JavaScript file:

<script type="text/javascript" src="js/min/jquery-progresspiesvg-controlIcons-min.js"></script>

See separate example page for more on content plug-ins!

ValueAdapters: Visualize other values than percent numbers

The following example takes a value in minutes instead of percent as a value. The valueAdapter converts any positive number of minutes into percent of an hour.

ValueAdapter functions may be used regardless of the value source: Whether the values are read from the element content (default) or from an attribute makes no difference.

$(".pp.minutes").progressPie({valueAdapter: function(valueStr) {
    return parseInt(valueStr) * 10 / 6;
}})

0 5 15 20 30 35 40 45 60 80

Double / multiple pies

Taking the previous example further: The progresspie component may also display two values overlapping. This might, for example, be used to depict a countdown in hours and minutes (or minutes and seconds). The following examples both show the hours-and-minutes example in different variations. In analogy to analog watch faces, the smaller, inner pie shall display an hour value (e.g. hours of a countdown still remaining) and the outer, larger pie the minutes-of-the-hour-value.

Parsing a visible element content of pattern hh:mm

Say, you have a span element containting a time value of format "hours:minutes" like

<span class="pp hmv">6:15</span>

You might now prepend a double pie chart als follows:

$(".pp.hmv").progressPie({
    mode:$.fn.progressPie.Mode.GREY,
    valueAdapter: function(str) { 
        var m = /\d+:(\d{1,2})/.exec(str)[1];
        return parseInt(m) * 10 / 6; 
    },
    inner: {
        mode:$.fn.progressPie.Mode.RED,
        valueAdapter: function(str) { 
            var hm = /(\d+):(\d{1,2})/.exec(str);
            var m = 60*parseInt(hm[1]) + parseInt(hm[2]); //hours converted to minutes plus minutes of hour = total minutes
            //100% <-> 12 hours = 720 minutes
            return m * 100 / 720;
        }
    }
});

0:00 0:15 1:00 1:55 2:45 6:15 07:58 12:15

Note that this example uses one single value string (here: the span's content, but of course you might also use an attribute value, see above), but two valueAdapter functions in order to derive two different percent values from one string value. Here, this is done using regular expressions.

Separate value attributes

Of course, if you happen to have two separate number values “at hand” you may insert these into two separate data-attributes of the HTML element and use these directly (if they happen to be percent values) or mapped via valueAdapter functions. This example uses separate attributes for hours and minutes:

<span class="pp hma" data-hours="6" data-minutes="15">6:15</span>

Also, this example demonstrates manual sizing of both the outer and the inner pie.

$(".pp.hma:not(.ring):not(.rings)").progressPie({
    mode:$.fn.progressPie.Mode.RED,
    valueData: "minutes",
    valueAdapter: function(mins) { return mins * 10 / 6; },
    size: 30,
    inner: {
        color: "navy",
        valueData: "hours",
        valueAdapter: function(hours) { return hours * 100 / 12; },
        size: 20
    },
    verticalAlign: "middle",
    strokeWidth: 1
});

0:00 0:15 1:00 1:55 2:45 6:15 7:60 12:15

Note however, that in this example the inner hour-pie is independent of the minutes pie: for the time "1:55" it fills exactly the same area (1/12) as for "1:00". The example above, on the other hand, takes advantage of the fact that the valueAdapter for the hour value also has access to the minutes value and displays for "1:55" a pie nearly as large as for "2:00" (1/6).

Combination with rings

As for single graphics, you may also set the ringWidth option for the outer and/or the inner pie. This example is simply a modification of the example above, displaying the minutes value as a ring instead of a full pie. The ringWidth is less than the difference between inner and outer radius, so that the inner pie (hour value) does fit into the ring without overlap. (Outer size is 30, inner size is 20, i.e. difference in diameter is 10, difference in radius is 5; ringWidth is set to 4, which is smaller than 5, which leaves a 1 pixel gap between inner pie and outer ring.)

$(".pp.hma.ring").progressPie({
    mode:$.fn.progressPie.Mode.RED,
    valueData: "minutes",
    valueAdapter: function(mins) { return mins * 10 / 6; },
    size: 30,
    inner: {
        color: "navy",
        valueData: "hours",
        valueAdapter: function(hours) { return hours * 100 / 12; },
        size: 20
    },
    verticalAlign: "middle",
    strokeWidth: 1,
    ringWidth: 4
});

0:00 0:15 1:00 1:55 2:45 6:15 7:60 12:15

Of course, you may also apply the ringWidth option to the inner pie:

$(".pp.hma.rings").progressPie({
    mode:$.fn.progressPie.Mode.RED,
    valueData: "minutes",
    valueAdapter: function(mins) { return mins * 10 / 6; },
    size: 30,
    inner: {
        color: "navy",
        valueData: "hours",
        valueAdapter: function(hours) { return hours * 100 / 12; },
        size: 20,
        ringWidth: 4
    },
    verticalAlign: "middle",
    strokeWidth: 1,
    ringWidth: 4
});

0:00 0:15 1:00 1:55 2:45 6:15 7:60 12:15

Three (or more) values/rings

Starting with V2.0.0, this plug-in now supports even more than 2 pies or rings: The inner option may now itself contain another inner option for a third value, that may, yet again, contain an inner option (fourth value) and so forth. When using this feature, you should use rings instead of (overlapping) pies by setting a ringWidth in the main options object and in each inner object (only the innermost might be a pie as demonstrated above for double diagrams). And you should set the size of each ring in order to control the spacing/gap between outer and inner ring manually for a good result (auto-spacing doesn't work well with more than 2 values).

Also new is the support of stroke* options even inside inner options, i.e. for each inner ring or pie you may draw a full circle around it or (more likely, like demonstrated below) with strokeWidth equal to the ringWidth in order to draw a full background circle overlapped by the ring.

Example with three rings, all with background circles (stroke*), colors configured programatically in plug-in call:

$(".triple1").progressPie({
    size:50,
    ringWidth: 5,
    strokeWidth: 5,
    color: "rgb(200, 0, 0)",
    strokeColor: "rgba(200, 0, 0, 0.2)",
    ringEndsRounded: true,
    valueData: 'outer',
    inner: {
        size: 35,
        ringWidth: 5,
        strokeWidth: 5,
        color: "rgb(0, 200, 0)",
        strokeColor: "rgba(0, 200, 0, 0.2)",
        ringEndsRounded: true,
        valueData: 'middle',
        inner: {
            size: 20,
            ringWidth: 5,
            strokeWidth: 5,
            color: 'rgb(0, 200, 200)',
            strokeColor: 'rgba(0, 200, 200, 0.2)',
            ringEndsRounded: true,
            valueData: 'inner'
        }
    }
});

applied to:

<span class="triple1" data-outer="88" data-middle="45" data-inner="56"></span>

As explained above in section CSS formatting, you may, if you prefer, configure the color scheme by CSS rules instead of in the plug-in call options. A variation of the above example:

$(".triple2").progressPie({
    animate: true,
    size: 60,
    ringWidth: 6,
    strokeWidth: 6,
    mode: $.fn.progressPie.Mode.CSS,
    ringEndsRounded: true,
    valueData: 'outer',
    inner: {
        size: 45,
        mode: $.fn.progressPie.Mode.CSS,
        ringWidth: 6,
        strokeWidth: 6,
        ringEndsRounded: true,
        valueData: 'middle',
        inner: {
            size: 30,
            mode: $.fn.progressPie.Mode.CSS,
            ringWidth: 6,
            strokeWidth: 6,
            ringEndsRounded: true,
            valueData: 'inner'
        }
    }
});
.triple2 {
    background: black;
    border-radius: 5px;
    padding: 5px;
    margin: 1em;
    display: inline-block;
    box-shadow: 0 0 5px rgba(0,0,0,0.8)
}
.triple2 svg {
    vertical-align: middle;
}
.triple2 .progresspie-background {fill: none}
.triple2 .progresspie-background.progresspie-outer  {stroke: rgba(220, 0, 0, 0.3)}
.triple2 .progresspie-foreground.progresspie-outer  {stroke:  rgb(220, 0, 0)}
.triple2 .progresspie-background.progresspie-inner  {stroke: rgba(0, 220, 0, 0.3)}
.triple2 .progresspie-foreground.progresspie-inner  {stroke:  rgb(0, 220, 0)}
.triple2 .progresspie-background.progresspie-inner2 {stroke: rgba(0, 220, 220, 0.3)}
.triple2 .progresspie-foreground.progresspie-inner2 {stroke:  rgb(0, 220, 220)}
<span class="triple2" data-outer="40" data-middle="85" data-inner="70"></span>

Note: This example uses SMIL animation (reload to play, not supported by Internet Explorer/Edge). See separate animation example page for more on that topic.

(Note 2: Obviously, this example is inspired by the activity display of the Apple Watch. It's not exactly a copy, though, just similar. Especially note that progresspieSVG does not support displaying values greater than 100%.)

Rotation Animation

SMIL Animations are supported by most modern browsers – except Microsoft's (IE or Edge).

You may add a clockwise rotation animation to any pie or ring as shown above. For a normal value would not seem like a good idea, but if you want to indicate some waiting interval without the progress actually being measured at the time being, you might use this to build a “Busy-Indicator” like e.g. one of the following:

$('#rotate1').progressPie({
     rotation: "500ms",
     valueAdapter: function() {return 5;}
});
$('#rotate2').progressPie({
    strokeWidth: 1,
    ringWidth: 3,
    color: "#333",
    rotation: {
        duration: "2s",
        clockwise: false
    },
    valueAdapter: function() {return 50;}
});
$('#rotate3').progressPie({
    strokeWidth: 0,
    ringWidth: 1,
    color: "navy",
    rotation: true,
    valueAdapter: function() {return 90;}
});

Note the valueAdapter function in these examples, returning a constant value defining the size of the rotating pie or the size of the gap in the rotating ring.

The animation only applies to the main / outer pie or ring. The inner option does not define a rotation property (i.e. any rotation property on the inner option will be ignored). But you may combine an outer animated ring with an inner progress pie like this:

$('#rotate4').progressPie({
    size: 40,
    strokeWidth: 0,
    ringWidth: 5,
    ringEndsRounded: true,
    color: "#900",
    rotation: "1s",
    valueAdapter: function() {return 85;},
    inner: {
        color: "navy",
        valueData: "value"
    }
});

Overriding options based on percent values

Normally, you specify one set of options which gets applied regardless of the value. Most options are constant, an exception is the color: As demonstrated above, you may specify a color function setting the actual color dependent upon the percent value.

Maybe that's no enough, maybe you want to change other things dependent on the percent value, too. So, for example, you might want to show a rotaion animation (see above) as long as the percent value has not been increased yet (is still zero), but switch to a pie chart for any value greater than zero.

For static values, you might simply call the plug-in with different options depending on the static value. The “Updating” example above also already shows a way to change other options like the size by simply calling the progressPie plug-in with different, newly calculated options on each update. But if you want to set up a general rule (using the setupProgressPie plug-in function), simply define a set of default options and add an optionsByPercent function, mapping a percent value to either an object with some options or to null if the default options should not be altered for this percent value. An object returned does not have to be a complete set of options, but only to contain those options which differ from the defaults.

The following example sets some default values for a pie chart and then overrides some options only for a value of 0% in order to then show a spinning ring instead:

function greyToGreen(percent) {
    var v = percent < 50 ? 0 : percent - 50; //0..50
    var rb = 100 - (2 * v);
    var g = 100 + (2 * v);
    return "rgb(" + rb + ", " + g + ", " + rb +")";
}
…   
$(".spinThenPie").setupProgressPie({
    color: greyToGreen,
    strokeWidth: 2,
    contentPlugin: "checkComplete", //see separate examples page for details
    optionsByPercent: function(percent) {
        return percent > 0 ? null : { //return null for values > 0, meaning "no changes to the defaults"
            //for value 0: override strokeWith and color and add some more options
            strokeWidth: 0,
            ringWidth: 2,
            rotation: true,
            valueAdapter: function() { return 85; }, //takes the 0 value and returns 85 instead.
            color: greyToGreen(0) //otherwise the color would be "greenish", calculated for the value 85
        }
    }
}).progressPie();

0 % 5 % 25 % 42 % 50 % 65 % 80 % 99 % 100 %

^