metro4
Version:
The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style
148 lines (123 loc) • 4.78 kB
JavaScript
var Donut = {
init: function( options, elem ) {
this.options = $.extend( {}, this.options, options );
this.elem = elem;
this.element = $(elem);
this.value = 0;
this.animation_change_interval = null;
this._setOptionsFromDOM();
this._create();
Utils.exec(this.options.onDonutCreate, [this.element]);
return this;
},
options: {
size: 100,
radius: 50,
hole: .8,
value: 0,
background: "#ffffff",
color: "",
stroke: "#d1d8e7",
fill: "#49649f",
fontSize: 24,
total: 100,
cap: "%",
showText: true,
showValue: false,
animate: 0,
onChange: Metro.noop,
onDonutCreate: Metro.noop
},
_setOptionsFromDOM: function(){
var that = this, element = this.element, o = this.options;
$.each(element.data(), function(key, value){
if (key in o) {
try {
o[key] = JSON.parse(value);
} catch (e) {
o[key] = value;
}
}
});
},
_create: function(){
var that = this, element = this.element, o = this.options;
var html = "";
var r = o.radius * (1 - (1 - o.hole) / 2);
var width = o.radius * (1 - o.hole);
var circumference = 2 * Math.PI * r;
var strokeDasharray = ((o.value * circumference) / o.total) + ' ' + circumference;
var transform = 'rotate(-90 ' + o.radius + ',' + o.radius + ')';
var fontSize = r * o.hole * 0.6;
element.addClass("donut");
element.css({
width: o.size,
height: o.size,
background: o.background
});
html += "<svg>";
html += " <circle class='donut-back' r='"+(r)+"px' cx='"+(o.radius)+"px' cy='"+(o.radius)+"px' transform='"+(transform)+"' fill='none' stroke='"+(o.stroke)+"' stroke-width='"+(width)+"'/>";
html += " <circle class='donut-fill' r='"+(r)+"px' cx='"+(o.radius)+"px' cy='"+(o.radius)+"px' transform='"+(transform)+"' fill='none' stroke='"+(o.fill)+"' stroke-width='"+(width)+"'/>";
if (o.showText === true) html += " <text class='donut-title' x='"+(o.radius)+"px' y='"+(o.radius)+"px' dy='"+(fontSize/3)+"px' text-anchor='middle' fill='"+(o.color !== "" ? o.color: o.fill)+"' font-size='"+(fontSize)+"px'>0"+(o.cap)+"</text>";
html += "</svg>";
element.html(html);
this.val(o.value);
},
_setValue: function(v){
var that = this, element = this.element, o = this.options;
var fill = element.find(".donut-fill");
var title = element.find(".donut-title");
var r = o.radius * (1 - (1 - o.hole) / 2);
var circumference = 2 * Math.PI * r;
// var title_value = (o.showValue ? o.value : Math.round(((v * 1000 / o.total) / 10)))+(o.cap);
var title_value = (o.showValue ? v : Utils.percent(o.total, v, true)) + (o.cap);
var fill_value = ((v * circumference) / o.total) + ' ' + circumference;
fill.attr("stroke-dasharray", fill_value);
title.html(title_value);
},
val: function(v){
var that = this, element = this.element, o = this.options;
if (v === undefined) {
return this.value
}
if (parseInt(v) < 0 || parseInt(v) > o.total) {
return false;
}
if (o.animate > 0 && !document.hidden) {
var inc = v > that.value;
var i = that.value + (inc ? -1 : 1);
clearInterval(that.animation_change_interval);
this.animation_change_interval = setInterval(function(){
if (inc) {
that._setValue(++i);
if (i >= v) {
clearInterval(that.animation_change_interval);
}
} else {
that._setValue(--i);
if (i <= v) {
clearInterval(that.animation_change_interval);
}
}
}, o.animate);
} else {
clearInterval(that.animation_change_interval);
this._setValue(v);
}
this.value = v;
//element.attr("data-value", v);
Utils.exec(o.onChange, [this.value, element]);
},
changeValue: function(){
this.val(this.element.attr("data-value"));
},
changeAttribute: function(attributeName){
switch (attributeName) {
case "data-value": this.changeValue(); break;
}
},
destroy: function(){
this.element.removeClass("donut").html("");
}
};
Metro.plugin('donut', Donut);