mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-11-13 07:11:12 +01:00
added pie chart
This commit is contained in:
parent
60eae6a697
commit
30206c1355
4 changed files with 277 additions and 1 deletions
|
@ -7,6 +7,11 @@ body {
|
|||
height: 250px;
|
||||
margin: 20px auto 0 auto;
|
||||
}
|
||||
#pie {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
margin: 20px auto 0 auto;
|
||||
}
|
||||
pre {
|
||||
height: 250px;
|
||||
overflow: auto;
|
||||
|
|
110
lib/morris.pie.coffee
Normal file
110
lib/morris.pie.coffee
Normal file
|
@ -0,0 +1,110 @@
|
|||
class Morris.Pie
|
||||
|
||||
defaults:
|
||||
|
||||
colors: [
|
||||
'#0B62A4'
|
||||
'#3980B5'
|
||||
'#679DC6'
|
||||
'#95BBD7'
|
||||
'#B0CCE1'
|
||||
'#095791'
|
||||
'#095085'
|
||||
'#083E67'
|
||||
'#052C48'
|
||||
'#042135'
|
||||
]
|
||||
|
||||
enhanceMax: false
|
||||
|
||||
|
||||
constructor: (options)->
|
||||
|
||||
return new Morris.Pie(options) if not (@ instanceof Morris.Pie)
|
||||
|
||||
if typeof options.element is 'string'
|
||||
@el = $ document.getElementById(options.element)
|
||||
else
|
||||
@el = $ options.element
|
||||
|
||||
throw new Error("Graph placeholder not found.") if @el == null || @el.length == 0
|
||||
|
||||
@options = $.extend {}, @defaults, options
|
||||
|
||||
# data
|
||||
return false if options.data is undefined or options.data.length is 0
|
||||
@data = options.data
|
||||
|
||||
@el.addClass 'graph-initialised'
|
||||
|
||||
@paper = new Raphael(@el[0])
|
||||
@segments = []
|
||||
|
||||
@draw()
|
||||
|
||||
draw: ->
|
||||
|
||||
@paper.clear()
|
||||
|
||||
total = 0
|
||||
total += x.value for x in @data
|
||||
max = Math.max.apply(null, x.value for x in @data)
|
||||
|
||||
currentAngle = 0
|
||||
|
||||
cx = @el.width() / 2
|
||||
cy = @el.height() / 2
|
||||
r = (Math.min(cx, cy) - 10) / 3
|
||||
|
||||
for labelAndValue, index in @data
|
||||
|
||||
value = labelAndValue.value
|
||||
label = labelAndValue.label
|
||||
|
||||
step = 360 * value / total
|
||||
color = @options.colors[index % @options.colors.length]
|
||||
|
||||
pieSegment = new Morris.PieSegment(@paper, cx, cy, r, currentAngle, step, labelAndValue, color)
|
||||
pieSegment.on "hover", @select
|
||||
pieSegment.render()
|
||||
|
||||
pieSegment.select() if labelAndValue.value == max && @options.enhanceMax
|
||||
|
||||
@segments.push pieSegment
|
||||
|
||||
currentAngle += step
|
||||
|
||||
select: (segmentToSelect)=>
|
||||
segment.deselect() for segment in @segments
|
||||
segmentToSelect.select()
|
||||
|
||||
class Morris.PieSegment extends Morris.EventEmitter
|
||||
|
||||
constructor: (@paper, @cx, @cy, @r, @currentAngle, @step, @labelAndValue, @color)->
|
||||
|
||||
@rad = Math.PI / 180
|
||||
|
||||
@distanceFromEdge = 30
|
||||
|
||||
@labelAngle = @currentAngle + (@step / 2)
|
||||
@endAngle = @currentAngle + @step
|
||||
|
||||
@x1 = @cx + @r * Math.cos(-@currentAngle * @rad)
|
||||
@x2 = @cx + @r * Math.cos(-@endAngle * @rad)
|
||||
@y1 = @cy + @r * Math.sin(-@currentAngle * @rad)
|
||||
@y2 = @cy + @r * Math.sin(-@endAngle * @rad)
|
||||
|
||||
render: ()->
|
||||
@segment = @paper.path(["M", @cx, @cy, "L", @x1, @y1, "A", @r, @r, 0, +(@endAngle - @currentAngle > 180), 0, @x2, @y2, "z"]).attr({ fill: @color, stroke: "#FFFFFF", "stroke-width": 2} ).hover(=> @fire('hover', @))
|
||||
@label = @paper.text(@cx + (@r + @distanceFromEdge ) * Math.cos(-@labelAngle * @rad), @cy + (@r + @distanceFromEdge ) * Math.sin(-@labelAngle * @rad), @labelAndValue.label).attr({fill: "#000000", "font-weight": "bold", stroke: "none", opacity: 1, "font-size": 12})
|
||||
@value = @paper.text(@cx + (@r + @distanceFromEdge ) * Math.cos(-@labelAngle * @rad), @cy + (@r + @distanceFromEdge ) * Math.sin(-@labelAngle * @rad) + 14, @labelAndValue.value).attr({fill: @color, stroke: "none", opacity: 1, "font-size": 12})
|
||||
|
||||
select: =>
|
||||
unless @selected
|
||||
@segment.stop().animate({transform: "s1.1 1.1 " + @cx + " " + @cy}, 150, "<>")
|
||||
@selected = true
|
||||
|
||||
deselect: =>
|
||||
if @selected
|
||||
@segment.stop().animate({transform: ""}, 150, "<>")
|
||||
@selected = false
|
161
morris.js
161
morris.js
|
@ -992,4 +992,165 @@
|
|||
|
||||
Morris.AUTO_LABEL_ORDER = ["year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
|
||||
|
||||
Morris.Pie = (function() {
|
||||
|
||||
Pie.prototype.defaults = {
|
||||
colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],
|
||||
enhanceMax: false
|
||||
};
|
||||
|
||||
function Pie(options) {
|
||||
this.select = __bind(this.select, this);
|
||||
if (!(this instanceof Morris.Pie)) {
|
||||
return new Morris.Pie(options);
|
||||
}
|
||||
if (typeof options.element === 'string') {
|
||||
this.el = $(document.getElementById(options.element));
|
||||
} else {
|
||||
this.el = $(options.element);
|
||||
}
|
||||
if (this.el === null || this.el.length === 0) {
|
||||
throw new Error("Graph placeholder not found.");
|
||||
}
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
if (options.data === void 0 || options.data.length === 0) {
|
||||
return false;
|
||||
}
|
||||
this.data = options.data;
|
||||
this.el.addClass('graph-initialised');
|
||||
this.paper = new Raphael(this.el[0]);
|
||||
this.segments = [];
|
||||
this.draw();
|
||||
}
|
||||
|
||||
Pie.prototype.draw = function() {
|
||||
var color, currentAngle, cx, cy, index, label, labelAndValue, max, pieSegment, r, step, total, value, x, _i, _j, _len, _len1, _ref, _ref1, _results;
|
||||
this.paper.clear();
|
||||
total = 0;
|
||||
_ref = this.data;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
x = _ref[_i];
|
||||
total += x.value;
|
||||
}
|
||||
max = Math.max.apply(null, (function() {
|
||||
var _j, _len1, _ref1, _results;
|
||||
_ref1 = this.data;
|
||||
_results = [];
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
x = _ref1[_j];
|
||||
_results.push(x.value);
|
||||
}
|
||||
return _results;
|
||||
}).call(this));
|
||||
currentAngle = 0;
|
||||
cx = this.el.width() / 2;
|
||||
cy = this.el.height() / 2;
|
||||
r = (Math.min(cx, cy) - 10) / 3;
|
||||
_ref1 = this.data;
|
||||
_results = [];
|
||||
for (index = _j = 0, _len1 = _ref1.length; _j < _len1; index = ++_j) {
|
||||
labelAndValue = _ref1[index];
|
||||
value = labelAndValue.value;
|
||||
label = labelAndValue.label;
|
||||
step = 360 * value / total;
|
||||
color = this.options.colors[index % this.options.colors.length];
|
||||
pieSegment = new Morris.PieSegment(this.paper, cx, cy, r, currentAngle, step, labelAndValue, color);
|
||||
pieSegment.on("hover", this.select);
|
||||
pieSegment.render();
|
||||
if (labelAndValue.value === max && this.options.enhanceMax) {
|
||||
pieSegment.select();
|
||||
}
|
||||
this.segments.push(pieSegment);
|
||||
_results.push(currentAngle += step);
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
Pie.prototype.select = function(segmentToSelect) {
|
||||
var segment, _i, _len, _ref;
|
||||
_ref = this.segments;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
segment = _ref[_i];
|
||||
segment.deselect();
|
||||
}
|
||||
return segmentToSelect.select();
|
||||
};
|
||||
|
||||
return Pie;
|
||||
|
||||
})();
|
||||
|
||||
Morris.PieSegment = (function(_super) {
|
||||
|
||||
__extends(PieSegment, _super);
|
||||
|
||||
function PieSegment(paper, cx, cy, r, currentAngle, step, labelAndValue, color) {
|
||||
this.paper = paper;
|
||||
this.cx = cx;
|
||||
this.cy = cy;
|
||||
this.r = r;
|
||||
this.currentAngle = currentAngle;
|
||||
this.step = step;
|
||||
this.labelAndValue = labelAndValue;
|
||||
this.color = color;
|
||||
this.deselect = __bind(this.deselect, this);
|
||||
|
||||
this.select = __bind(this.select, this);
|
||||
|
||||
this.rad = Math.PI / 180;
|
||||
this.distanceFromEdge = 30;
|
||||
this.labelAngle = this.currentAngle + (this.step / 2);
|
||||
this.endAngle = this.currentAngle + this.step;
|
||||
this.x1 = this.cx + this.r * Math.cos(-this.currentAngle * this.rad);
|
||||
this.x2 = this.cx + this.r * Math.cos(-this.endAngle * this.rad);
|
||||
this.y1 = this.cy + this.r * Math.sin(-this.currentAngle * this.rad);
|
||||
this.y2 = this.cy + this.r * Math.sin(-this.endAngle * this.rad);
|
||||
}
|
||||
|
||||
PieSegment.prototype.render = function() {
|
||||
var _this = this;
|
||||
this.segment = this.paper.path(["M", this.cx, this.cy, "L", this.x1, this.y1, "A", this.r, this.r, 0, +(this.endAngle - this.currentAngle > 180), 0, this.x2, this.y2, "z"]).attr({
|
||||
fill: this.color,
|
||||
stroke: "#FFFFFF",
|
||||
"stroke-width": 2
|
||||
}).hover(function() {
|
||||
return _this.fire('hover', _this);
|
||||
});
|
||||
this.label = this.paper.text(this.cx + (this.r + this.distanceFromEdge) * Math.cos(-this.labelAngle * this.rad), this.cy + (this.r + this.distanceFromEdge) * Math.sin(-this.labelAngle * this.rad), this.labelAndValue.label).attr({
|
||||
fill: "#000000",
|
||||
"font-weight": "bold",
|
||||
stroke: "none",
|
||||
opacity: 1,
|
||||
"font-size": 12
|
||||
});
|
||||
return this.value = this.paper.text(this.cx + (this.r + this.distanceFromEdge) * Math.cos(-this.labelAngle * this.rad), this.cy + (this.r + this.distanceFromEdge) * Math.sin(-this.labelAngle * this.rad) + 14, this.labelAndValue.value).attr({
|
||||
fill: this.color,
|
||||
stroke: "none",
|
||||
opacity: 1,
|
||||
"font-size": 12
|
||||
});
|
||||
};
|
||||
|
||||
PieSegment.prototype.select = function() {
|
||||
if (!this.selected) {
|
||||
this.segment.stop().animate({
|
||||
transform: "s1.1 1.1 " + this.cx + " " + this.cy
|
||||
}, 150, "<>");
|
||||
return this.selected = true;
|
||||
}
|
||||
};
|
||||
|
||||
PieSegment.prototype.deselect = function() {
|
||||
if (this.selected) {
|
||||
this.segment.stop().animate({
|
||||
transform: ""
|
||||
}, 150, "<>");
|
||||
return this.selected = false;
|
||||
}
|
||||
};
|
||||
|
||||
return PieSegment;
|
||||
|
||||
})(Morris.EventEmitter);
|
||||
|
||||
}).call(this);
|
||||
|
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue