1 // Peity jQuery plugin version 1.2.0
2 // (c) 2013 Ben Pickles
4 // http://benpickles.github.com/peity
6 // Released under MIT license.
7 (function($, document, Math, devicePixelRatio) {
8 var canvasSupported = document.createElement("canvas").getContext
10 var peity = $.fn.peity = function(type, options) {
11 if (canvasSupported) {
12 this.each(function() {
14 var chart = $this.data("peity")
17 if (type) chart.type = type
18 $.extend(chart.opts, options)
21 var defaults = peity.defaults[type]
24 $.each($this.data(), function(name, value) {
25 if (name in defaults) data[name] = value
28 var opts = $.extend({}, defaults, data, options)
29 var chart = new Peity($this, type, opts)
33 .change(function() { chart.draw() })
42 var Peity = function($el, type, opts) {
48 var PeityPrototype = Peity.prototype
50 PeityPrototype.colours = function() {
51 var colours = this.opts.colours
54 if (!$.isFunction(func)) {
55 func = function(_, i) {
56 return colours[i % colours.length]
63 PeityPrototype.draw = function() {
64 peity.graphers[this.type].call(this, this.opts)
67 PeityPrototype.prepareCanvas = function(width, height) {
68 var canvas = this.canvas
72 this.context.clearRect(0, 0, canvas.width, canvas.height)
75 $canvas = $("<canvas>").css({
78 }).addClass("peity").data("peity", this)
80 this.canvas = canvas = $canvas[0]
81 this.context = canvas.getContext("2d")
82 this.$el.hide().after(canvas)
85 canvas.height = $canvas.height() * devicePixelRatio
86 canvas.width = $canvas.width() * devicePixelRatio
91 PeityPrototype.values = function() {
92 return $.map(this.$el.text().split(this.opts.delimiter), function(value) {
93 return parseFloat(value)
100 peity.register = function(type, defaults, grapher) {
101 this.defaults[type] = defaults
102 this.graphers[type] = grapher
108 colours: ["#ff9900", "#fff4dd", "#ffc66e"],
113 if (!opts.delimiter) {
114 var delimiter = this.$el.text().match(/[^0-9\.]/)
115 opts.delimiter = delimiter ? delimiter[0] : ","
118 var values = this.values()
120 if (opts.delimiter == "/") {
123 values = [v1, v2 - v1]
127 var length = values.length
130 for (; i < length; i++) {
134 var canvas = this.prepareCanvas(opts.width || opts.diameter, opts.height || opts.diameter)
135 var context = this.context
136 var width = canvas.width
137 var height = canvas.height
138 var radius = Math.min(width, height) / 2
140 var colours = this.colours()
143 context.translate(width / 2, height / 2)
144 context.rotate(-pi / 2)
146 for (i = 0; i < length; i++) {
147 var value = values[i]
148 var slice = (value / sum) * pi * 2
152 context.arc(0, 0, radius, 0, slice, false)
153 context.fillStyle = colours.call(this, value, i, values)
155 context.rotate(slice)
166 strokeColour: "#4d89f9",
175 var values = this.values()
176 if (values.length == 1) values.push(values[0])
177 var max = Math.max.apply(Math, values.concat([opts.max]));
178 var min = Math.min.apply(Math, values.concat([opts.min]))
180 var canvas = this.prepareCanvas(opts.width, opts.height)
181 var context = this.context
182 var width = canvas.width
183 var height = canvas.height
184 var xQuotient = width / (values.length - 1)
185 var yQuotient = height / (max - min)
191 context.moveTo(0, height + (min * yQuotient))
193 for (i = 0; i < values.length; i++) {
194 var x = i * xQuotient
195 var y = height - (yQuotient * (values[i] - min))
197 coords.push({ x: x, y: y });
198 context.lineTo(x, y);
201 context.lineTo(width, height + (min * yQuotient))
202 context.fillStyle = opts.colour;
205 if (opts.strokeWidth) {
207 context.moveTo(0, coords[0].y);
208 for (i = 0; i < coords.length; i++) {
209 context.lineTo(coords[i].x, coords[i].y);
211 context.lineWidth = opts.strokeWidth * devicePixelRatio;
212 context.strokeStyle = opts.strokeColour;
221 colours: ["#4D89F9"],
226 spacing: devicePixelRatio,
230 var values = this.values()
231 var max = Math.max.apply(Math, values.concat([opts.max]));
232 var min = Math.min.apply(Math, values.concat([opts.min]))
234 var canvas = this.prepareCanvas(opts.width, opts.height)
235 var context = this.context
237 var width = canvas.width
238 var height = canvas.height
239 var yQuotient = height / (max - min)
240 var space = opts.spacing
241 var xQuotient = (width + space) / values.length
242 var colours = this.colours()
244 for (var i = 0; i < values.length; i++) {
245 var value = values[i]
246 var y = height - (yQuotient * (value - min))
250 if (min >= 0 || max > 0) y -= 1
253 h = yQuotient * values[i]
256 context.fillStyle = colours.call(this, value, i, values)
257 context.fillRect(i * xQuotient, y, xQuotient - space, h)
261 })(jQuery, document, Math, window.devicePixelRatio || 1);