Categories
Plugins

progresspiesvg

progresspieSVG
jQuery plug-in for dynamically rendering a pie or circle diagram comparable to a progress bar, depicting a progress, countdown, percent value or similar.
Project home page
What is this?
This software module contains a jQuery plug-in for drawing a partially filled circle (pie-chart with only one slice of the pie) for visualizing a single value between 0% and 100% inclusive, i.e. a kind of progress bar, but not in form of a bar but of a pie. The graphic is rendered inside a web page as SVG. In difference to e.g. the HTML canvas element, SVGs are scalable and render sharply on high resolution displays with device-pixel-ratio > 1 (e.g. Apple’s “retina displays”).
As the name suggests, this component may be used to display a progress, starting at 0%, incrementing until 100% are reached. For this purpose the graphic may be dynamically updated (or, more precisely, replaced).
But just like progress bars these pies may actually be used to depict any percentual value, including static ones like e.g. percents of points achieved in a test. Mainly for this purpose, the pie may be dynamically colored based on the percentual value with colors like red hinting at a “bad” result, yellow for “mediocre” and green for “good”. There are default color schemes (always grey, green or red or dynamically calculated red/yellow/gree-shade as described above), but you may also assign any static color or your own JavaScript function mapping the value into a color.
This jQuery-Plug-in supports a wide range of options for customizability, so you may style the pie or ring charts in various ways, define value adapter functions for converting any raw value into a percent value to be displayed, even render more than one value in one chart (typically by arranging smaller rings or pies inside one outer ring). A content plug-in architecture allows for additional content to be added to a chart, like control icons, error or warning icons (e.g. if the diagram is used to depict the progress of some job which will not always terminate successfully but might produce errors or warnings), background icons, value display etc. Various content plug-ins are included (see separate example page), and you can also create your own ones.
The basic usage is to add static charts to a page already containing the values, so these get displayed graphically. If the value is not static but the user’s input in a form field, the plug-in can automatically update the chart when the input’s value changes.
Via JavaScript, it’s also possible to dynamically updated charts (even with smooth transition/animation), e.g. for building a real progress indicator for some process running in the background (maybe even a server’s progress monitored by Ajax status requests).
Examples
See the examples pages to get an impression of the looks and for different demo scenarios.

examples.html: Examples for direct usage of the plug-in
examplesAppl.html: Examples for indirect use with progresspiesvlAppl.js
examplesContentPlugins.html: Examples for usage of the bundled content plug-ins (control icons, check complete, value display, background images, …)
examplesAnimation.html: Examples for configuring animated value transitions

You’ll also find an online live view of these examples on the project’s home page.
JavaScripts
This package contains several JavaScript files.

The script files in folder js are the source files. Please note that—starting with version 2.4.0—these use ECMAScript-6-Syntax and are not compatible with older browsers wich only support up to ECMAScript 5! For better browser compatiblity use the following minified versions!
The folder js/min contains the production versions. These have been transpiled (with Babel) to ECMAScript 5 and minified (with UglifyJS), so they are smaller and may be run on more, older browsers that the source scripts.

The individual script files (file names of source versions, production versions’ names end with -min.js):

jquery-progresspiesvg.js: The jQuery plug-in itself. It may be used stand-alone.
jquery-progresspiesvg-controlIcons.js: A content plug-in as an addition to the jQuery plug-in above. Loading this file on top of jquery-progresspiesvg.js enables you to draw control icons (play, stop, pause) inside ring graphs using the svgContentPlugin option of the progresspiesvg plug-in.
jquery-progresspiesvg-checkComplete.js: A content plug-in which may add a check mark to a pie or ring graph for value 100%.
jquery-progresspiesvg-errorIcons.js: A content plug-in for adding warning or error icons to a chart, e.g. in case a monitored progress crashes or terminates with an error or warning message.
jquery-progresspiesvg-image.js: A content plug-in for adding content from external image files (preferrably SVG, but other browser-supported formats like PNG or JPEG will also work). Images may be used in fore- or background or even be masked by the pie chart, see examples.
jquery-progresspiesvg-valueDisplay.js: A content plug-in for displaying values (percent numbers or other values converted to percent, e.g. seconds of a minute) in the center of a ring graph.
progresspiesvgAppl.js: This is meant to simplify the use for those who do not want to write JavaScript code to apply and configure the plug-in. This script file may be included into your HTML (in addition to jQuery and the plug-in above). If you do so, you may insert progresspie charts simply by writing HTML, inserting the percent values and assigning some predefined CSS classes or data-Attributes.

Changes in V2.0.0, backwards compatibility
Version 2 mostly adds new features like especially:

Rendering rewritten to produce more compact SVG markup. (Rings and pies are now only a single elliptic stroke with instead of a filled area.) This was also precondition for the next feature:
optional SMIL animation/transition (see examplesAnimation.html)
More features for the inner option (second value/pie/ring):

background circle now also supported for inner rings/pies
“Double pies” extended to “multiple pies”: The inner option may itself contain an inner option (recursive)

CSS support:

background circles and foreground pie or ring segments now always get a class attribute so you can define external CSS rules to modify or enhance their formatting.
new predefined CSS mode disables some inline formatting like colors in the generated SVG code or the inline style vertical-align in the svg node, in which case the formatting should be defined externally via CSS rules.

overlap option
Extended content plug-in API able to suppress the output of the actual pie or ring chart, especially if the content plug-in would totally cover/occlude it. This generates more compact SVG (without needlessly rendering effectively invisible graphics) and also draws “cleaner” edges around full size filled backgrounds of content plug-ins.

But some changes have been made which could affect backwards compatibility in a few cases. This is the main reason for the major version increase (see [semantic versioning][https://docs.npmjs.com/getting-started/semantic-versioning]): When updating to V2.0.0, you should make sure the following changes don’t affect your current uses, otherwise you might have to (slightly) change them.

The separator option is now ignored when inserting an SVG into a hitherto empty HTML element (e.g. ). In Versions 1.x.x, the separator (wich actually only serves to separate the prepended or appended SVG from the content of the node) was still appended, even if there was nothing to separate. This could have had some unwanted effects, e.g. if the target element was CSS-formatted to have a background color and the SVG should be centered inside, but was not due to the space appended to it. On the other hand: If you’ve been relying on this separator being inserted even into empty documents, you’ll now have to put it into the document by yourself. Example: If you had some markup like and relied on a space being inserted after the SVG into the #pie element so that the pie and the content of #X were separated, you’d best now insert a space directly between the two span elements.
The default valueAdapter function now uses parseFloat instead of parseInt for parsing string numbers, meaning that it now supports decimal digits if the dot (.) is used as decimal separator.

Changes like having a separator only separate the newly inserted and old content and not (any more) adding a ‘separator’ that’s actually not separating anything, these are more kind of a fix than a new feature. They IMHO make sense, but sadly they affect backwards compatibility. Other than that, I’ve strived to retain backwards compatibility as far as possible, and most users won’t probably have to change anything.
Usage
Direct usage of the plug-in (without progresspiesvgAppl.js)
Basics

Include jQuery (tested with jQuery 1.11, but should work with jQuery 2 and 3, too) and the script file jquery-progresspiesvg.js into the head of your HTML file.

Insert the percent values into your HTML body that are to be visualized. This may be done in several ways:

Should the number be visible and a pie in text height should be inserted before or behind the acutal number? This is the default. In this case, for each progresspie to insert, write the number (and only the up to three digits) into an HTML element like span and make sure this element may be selected via jQuery (e.g. by adding a classname like “percent” or “progresspie”). Example: 42 %.
Should the number / digits be invisible and only a pie is to be inserted? In this case create an empty HTML element where the pie chart is to be inserted and write the number into an attribute of this element (usually prefixed with data-), e.g.: .

In this case, you’ll have to include an option when calling the progressPie() plug-in defining where to find the value, preferrably the valueData option, alternatively the valueAttr option.

Should the value actually be the value of a form input element editable in the browser by the user, that’s also possible.

In this case you’ll have to use the setupProgressPie() plug-in function to setup an updateable chart (see below). The valueInput option can be used to specify the value source as well as setup an event handler for automatic update of the chart when the input value changes.

Write and include some script code that gets executed after rendering the HTML (generating the DOM). This code is to select the (span-) elements you created in the second step with a jQuery query and to apply the plug-in to the selection/query result.
Example corresponding to both data elements above:

For each selected element, the script will try to read the number (from the element’s content or from a data attribute, if the option valueData is given and the element provides a data attribute, prefixed with data-, of that name or the data is set by calling jQuery’s data() method) and render the piechart SVG, which will be inserted into the selected element.

By default the SVG image gets prepended to the content, optionally it may also be appended. Also, a separator string may be inserted between the pie and the original content (by default this is a non-breaking space:  ). If the target element is empty (like in the second example with the data attribute), the SVG is simply inserted into that element without the separator.

In case the values aren’t static but should be updatable, the initialization should be done with the setupProgressPie() method and the parameterless progressPie() method can be used multiple times to (re)draw die graph:

If the value should be taken from a form input element (see above), you’ll not even have to write an update trigger function, the valueInput option will automatically register an event handler for updating the chart (by calling progressPie()) on the input.
Example:
The HTML:

The JavaScript call:
$(“#pie1”).setupProgressPie({
valueInput: $(“#inp1″)
}).progressPie();

See the main examples page for more detailed examples including the additional valueInputEvents option.

Options
If you simply call progressPie(), the plug-in will be used with default options. This includes that the percent number is expected to be the (only) content of the selected element, the pie will be prependet to this content (separated with an  ), it will be rendered in line-height and in a shade of grey (#888). It will only be inserted, if the element does not yet contain any SVG content: repetetive calling of the function will therefore neither insert the SVG multiple times nor will it update the graphic.
To modify the looks or behaviour, the function takes exactly one argument, which has to be a JavaScript object which defines options via its properties. The following option properties are defined:

mode: constant of enum type $.fn.progressPie.Mode. Default is $.fn.progressPie.Mode.GREY. Possible values are:

$.fn.progressPie.Mode.GREY: Default Mode, pie is drawn in a shade of grey.
$.fn.progressPie.Mode.RED: The pie is drawn in red color regardless of the percentual value.
$.fn.progressPie.Mode.GREEN: The pie is drawn in green color regardless of the percentual value.
$.fn.progressPie.Mode.COLOR: The color of the pie is depending on the percentual value (see above). The color is the same green color as in mode GREEN for a value of 100 percent, the same red color as in mode RED for a value of 0%, a yellowish mix of both for 50% and a gradient in between green and yellow for values greater than 50% resp. between red and yellow for values less than 50%.
$.fn.progressPie.Mode.CSS: The colors (stroke of foreground and background and fill of background) as well as the vertical-align style of the root svg element are left unspecified. If this mode is chosen, you have to define the colors and vertical alignment via CSS rules (see examples)! Note: If the mode option is set to CSS mode, any color option will be ignored!
$.fn.progressPie.Mode.MASK: The pie or ring chart is not added to the main, visible area of the SVG but is instead inserted as a mask which is then applied to the topmost background layer. This requires at least one background layer to be present: Any layer other than the pie layer (which is inserted in any mode but MASK or IMASK) can only be inserted by a content plug-in, i.e. this mode is only made to be combined with at least one content plug-in (see the contentPlugin option). Since content plug-ins may insert either a foreground layer (draw on top of the chart) or a background layer, the contentPlugin option must hold at least one plug-in drawing into the background.
As has already been said, the mask defined by the pie chart gets applied to the topmost background layer. By default that means that the output of the first content plug-in drawing into the background will only be visible in those parts of the graphic which would normally be covered by the pie chart.
In MASK mode the space around the pie or ring chart is always transparent, the pie itself is white by default. If you understand masking and wish to change that, you may alter the colors of the chart and its background (filled background inside the circle) by using using options like strokeColor, color, backgroundColor etc., the space outside the chart’s circle is always transparent in this mode.
See JSDoc for these Mode constants and the examples page on content plug-ins!
$.fn.progressPie.Mode.IMASK: Inverted Mask Mode: This resembles the MASK mode above, only the mask in inverted: By default, the foreground of the pie is black and all the background (inside and outside of the chart) is white, meaning any part of the first background layer which would be visible in normal mode will still be visible, but the chart is not drawn on top of that background layer, but it’s “cut out of” the background, leaving a pie-/ring-shaped transparent hole in the background layer.
In this mode, too, you may alter the default colors of the mask (defining a grade of transparency) by other options.
See JSDoc for these Mode constants and the examples page on content plug-ins!

strokeWidth: number. Default is 2. Determines the stroke with of the background circle.
strokeColor: string, color code. Default is undefined. If undefined, the background circle is drawn in the same color as the rest of the pie. If set to a color code like #ddd or silver, this defines the color of the background circle.
strokeDashes: number or object. Default is undefined. This defines an optional dash pattern for the background circle’s stroke. A number value is simply a short hand syntax for an object with only the sub-option count. If this is an object, it must at least contain the count property. Allowed properties are as follows:

count: number, mandatory. Defines into how many dashes (and gaps) the background circle is to be divided. By default dashes and gaps are equally long (circumference/(2*count)).
length: number or string. Defaults to undefined. If set to a number, this defines the length of each dash in pixels. This should only be used if the total size of the graph and thus the circumference in pixels is known to be longer than length * count! Alternatively this may be set to a string literal containing a number followed by a percent sign, e.g. length: ‘10%’. This defines a relative length of each dash and is applicable independently of the graph’s size. If you use count and length, the length of the gaps between the dashes is auto-sized in order to equally distribute the dashes around the circle.
centered: boolean. Defaults to undefined. If falsy (e.g. undefined or false), the first dash will start at (end the last gap will end at) exactly the circle’s top (12 o’clock position). If true (or truthy), the first dash will be horizontally centered around that position.
inverted: boolean. Defaults to undefined. If true (or truthy), the pattern is inverted such that the gaps are replaced by dashes and vice versa. I.e. in inverted mode the length property will define the length of the gaps and the dashes will be auto-sized, and the first gap will start at (or, if centered is set, be centered around) the 12 o’clock position.

overlap: boolean, defaults to true. If true, the foreground (pie/ring segment) is drawn full size, i.e. with the same radius as the background circle, so the foreground overlaps the background. This is usually only visible, if the strokeColor (color of the background circle) is set and differs from the foreground’s color. Set this to false in order to fit the foreground (pie/ring) inside the blank space of the background circle.
ringWidth: number. Default is undefined. If undefined, a portion of the pie will be filled, cut out just to the center of the circle (like a partial sweep of a radar). If ringWidth is a number, only the outer rim of this piece of the pie is drawn, leaving an empty circle in the middle with diameter size-2*ringWidth. If no strokeColor is defined (and overlap is true) ringWidth must be greater than strokeWidth in order for the (partial) ring to be visible. (See examples)
ringEndsRounded: boolean. Default is false. Only applicable if ringWidth is defined, ignored in pie mode. If a ring is drawn, both ends of the ring are normally cut rectangularly. Enabling this option draws a semicircle cap on each end. This might look prettier especially for very large graphics with usually strokeWidth === 0. Note however that, the higher the ringWidth value, the longer the ring seems, for the semicircles are added to the ring. Very high values like 99% will then look like a full 100% (for the semi circle ends overlap).
ringAlign: constant of enum type $.fn.progressPie.RingAlign. Defaults to $.fn.progressPie.RingAlign.OUTER. This option is only applied if ringWidth and strokeWidth are both defined and both greater than zero. Its meaning correlates with the overlap option. Possible values are:

$.fn.progressPie.RingAlign.OUTER: The ring’s outer edge is aligned with the background circle. If overlap is true, it is drawn on top of the background circle and both circles outer edges are aligned. If overlap is false, i.e. both circles don’t overlap, the ring is drawn inside the background circle, the ring’s outer edge touches the inner edge of the background circle.
$.fn.progressPie.RingAlign.INNER: The ring’s inner edge is aligned with the background circle. If overlap is true, the ring is drawn on top of the background circle such that they are both aligned on the inside. If overlap is false, the background circle will be drawn inside the ring, the ring outside around the background circle.
$.fn.progressPie.RingAlign.CENTER: In this mode, both circles share the same radius, i.e. they are both centered on the same circle, the wider stroke will expand further to the inside as well as to the outside of that circle. (This is only applicable if overlap is true, without overlap, no centering is possible.)

prepend: boolean. Default is true. If true, the pie will be inserted at the beginning of the element’s content, followed by the separator string. If false, the separator string followed by the pie will be appended to the element’s content. If the target element is completely empty, the pie will become the sole content, this option (as well as the separator option, see below, will be ignored).
separator: string. Default is ” “. Will separate the inserted pie from the rest of the content (usually the number), see prepend. Ignored for empty elements.
verticalAlign: string. Default is “bottom”. Defines the CSS-property vertical-align of the inserted SVG element and thus the vertical alignment. By default, the image is aligned with the bottom of a line. In certain circumstances (like setting a line-height style greater than 1em) you might want to vertically center the image by setting this option to “middle”. (This option is ignored in CSS mode, see above, since in that mode no local vertical-align style will be defined at all, but it’s left to you to define a global CSS rule for the alignment!)
update: boolean. Default is false. If false, the function will do nothing if the target element already contains an svg element. Set to true if repeated calls are meant to update the graphic. If true, the function will remove an existing svg before inserting a new one. Typically only needed in combination with valueData or valueAttr, see also: Dynamically updating pies
size: number. Default is undefined. If undefined, the plug-in will try to draw the pie in the actual height of the parent element. Beware: If the element is empty, the browser may have calculated a height of 0! In this case, a default size will be used. Defining this option disables auto-sizing: the provided number will be used as height and width of the svg. It has to be a number (in pixels), not a string with a unit! This is typically used on empty elements in combination with valueData, valueAttr or valueSelector.
sizeFactor: number. Default is 1. The size (either given by size option or auto-calculated, if no size is explicitly specified) is multiplied by this factor to get the “final” diameter before drawing the chart.
scale: number. Default is 1. The already rendered SVG is finally scaled by this factor. In difference to sizeFactor this does not simply change the diameter/radius of the chart, but scales all other aspects, such as strokeWidth, ringWidth etc., too.
valueAttr: string. Default is undefined. Name of a value attribute: If defined, the function will look for an attribute of this name inside the opening tag of the found element, and if found, it will parse this attribute’s value instead of the element’s content as the percent value. (If defined but not of type “string”, the function will throw an exception.) For accessing data-* attributes, the next option valueData is usually preferred, use valueAttr only if you want to read other attributes (not beginning with data-) or if you really want to react to updates to the attribute in the DOM tree.
valueData: string. Default is undefined. Mutually exclusive with valueAttr, valueSelector and valueInput! Name of a jQuery data object. When parsing, jQuery will create data objects for each data-* attribute, e.g. for an attribute data-percent=”50″ in the HTML, the jQuery function data(“percent”) will return the number 50 (not a string). In this example, you may specify the option valueData: “percent” to access the data from the data-percent attribute. This is nearly equivalent to valueAttr: “data-percent”, but differs in two important respects: Firstly, numbers are automatically recognized and parsed, so the valueAdapter does not have to parse the string itself, secondly (and most important), value updates set by calling the jQuery function data(id, newValue) (e.g. $(selector).data(“percent”, oldvalue++)) will be recognized when updating the pies. Be aware that jQuery does not update data-attributes upon calling the data-setter-function. Attributes and stored data objects only match initially, but updates to the data objects are not propagated to the string attributes in the DOM tree. So if you were using option valueAttr: “data-percent” instead of valueData and wanted to dynamically update the pie, you’d have to explicitly update the data attribute via jQuery function attr(“data-percent”, newValueAsString), whereas use of valueData enables you to simply update the value via data(“percent”, newValueAsNumber), which is simpler and more efficient. (If this option is defined but not of type “string”, the function will throw an exception.)
valueSelector: jQuery-Selector (string). Default is undefined. Mutually exclusive with valueAttr, valueData and valueInput! If defined, the function will apply a jQuery search within the selected element to find a sub-element whose text content is to be used as a value. Usually, the whole text content of the node previously selected (to which the progresspie plug-in is applied) is interpreted as the value. If you want to have more content, maybe for CSS styling reasons, and the actual value is in a sub-element, but the pie should not be inserted into that sub-element but into the previously selected main element, then this option is for you. The examples page demonstrates an application of this option.
valueInput: jQuery result set containing an input element or alternatively a jQuery-selector (string) referring to an input element. Default is undefined. Mutually exculsive with valueAttr, valueData and valueSelector. If this option is defined, the value for the pie will be read from that input (from the jQuery result set passed in this option or, in case a selector string was passed, from the resultset obtained by $(selector)) via jQuery’s .val() method. This option is only available in the setupProgressPie() function and not with progressPie({…options…})! The setup will then not only define the options for the progress pie (or ring), but it will also add an event listener to that input (via jQuery’s .on() method executed on the result set), which will update the pie upon changes to the input (by simply calling progressPie() on the associated result set). More specifically, by default the event handler listens to the change event, but you can override that default with the following option:

valueInputEvents: String, default is “change”. Space-separated list of event names the input event listener (added by setupProgressPie() when the valueInput option is given) will react to (by updating the pie). If valueInput is undefined, this option will be ignored.
Please note that, if you should later change the setup by a succeeding call of setupProgressPie and change the valueInput or valueInputEvents option, this will not deregister the event handlers registered by the first call! If needed, the .off() method has to be called manually!)

valueAdapter: function. Default: see below. The valueAdapter function is executed when interpreting the value, i.e. either the element’s content (string), the value of the attribute denoted by the valueAttr option (also a string) or the data object denoted by the valueData option. It has to map the value (string or number) to a number within the range [0..100], which is then used to calculate the pie graphic. So if you have raw data that’s not a percent value (for example an hour value out of [0..12]), you may write an own valueAdapter reading this value and returning an int in [0..100]. (See examples page.)

If you use the valueData option, the type of the argument is the type of the object stored in the data model. This is usually a string or a number, but your own script code controls the type of objects stored there.
If you don’t use the valueData option, the type of the argument is always string.
The default valueAdapter $.fn.progressPie.defaults.valueAdapter (which is used whenever this option valueAdapteris undefined) applies parseInt to any string argument, returns any number argument unchanged and returns 0 for an argument of any other type.

color: string or function. Default is undefined. If undefined, the color of the pie depends on the mode option, see above. A valid string value of this option would be a color name like navy or color code like #888, #FF00BC, rgb(10,20,255). If the value is a function, this function has to read one parameter of type number (0..100) and return a color code (string). If the option is neiter undefined nor a string nor a function, the plug-in will throw an exception.
colorAttr: string. Default is undefined. Only evaluated if color is undefined. Name of a color attribute: If defined, the function will look for an attribute of this name inside the opening tag of the found element, and if found, will try to use the attribute’s content (string) to set the pie color. The attribute must contain a color name or code (see color).
colorFunctionAttr: string. Default is undefined. Only evaluated if no color has already been set with color or colorAttr. Name of an attribute containing JavaScript code (as string literal) for calculating a color.
animate: boolean or object. Default is undefined. May be set to true for default animation options (defined in jQuery.fn.progressPie.defaultAnimationAttributes) or to an object containing valid SMIL options (key-value-pairs like dur for the animation duration) in order to set up a customized animation. Animation is applied for static pies when rendering the page (the animation then starts at 0% and gradually fills the chart up to the assigned percent value) and is also applied for each redraw of the chart (animating the transition from the previous to the newly set value). See separate animation examples page and jsDoc for the defaultAnimationAttributes object.

If you use the inner option (see below) to add a second or even more values, these inner options inherit the animate option in case they don’t define it themselves. To disable an inherited animation for an inner value, inner.animate may simply be set to false.

animateColor: boolean. Default is undefined. Effectless if the animate option is not set (or false) or if the color of the chart is constant. So let’s assume you use a color function, so that a value change also may cause a change of the diagram’s color:

If this option is set to false, the chart will immediately be drawn in the final color, the animate option will only add a value transition. Especially when incrementing or decrementing the value and redrawing/updating the pie, the color will change abruptly even before the value change transition starts.
If this option is set to true, in addition to the value transition also a color transition is added. Note that t

GitHub Repo