632 lines
16 KiB
JavaScript
632 lines
16 KiB
JavaScript
(function (b) {
|
|
function c(D) {
|
|
var h = null;
|
|
var L = null;
|
|
var n = null;
|
|
var B = null;
|
|
var p = null;
|
|
var M = 0;
|
|
var F = true;
|
|
var o = 10;
|
|
var w = 0.95;
|
|
var A = 0;
|
|
var d = false;
|
|
var z = false;
|
|
var j = [];
|
|
D.hooks.processOptions.push(g);
|
|
D.hooks.bindEvents.push(e);
|
|
|
|
function g(O, N) {
|
|
if (N.series.pie.show) {
|
|
N.grid.show = false;
|
|
if (N.series.pie.label.show == "auto") {
|
|
if (N.legend.show) {
|
|
N.series.pie.label.show = false;
|
|
} else {
|
|
N.series.pie.label.show = true;
|
|
}
|
|
}
|
|
if (N.series.pie.radius == "auto") {
|
|
if (N.series.pie.label.show) {
|
|
N.series.pie.radius = 3 / 4;
|
|
} else {
|
|
N.series.pie.radius = 1;
|
|
}
|
|
}
|
|
if (N.series.pie.tilt > 1) {
|
|
N.series.pie.tilt = 1;
|
|
}
|
|
if (N.series.pie.tilt < 0) {
|
|
N.series.pie.tilt = 0;
|
|
}
|
|
O.hooks.processDatapoints.push(E);
|
|
O.hooks.drawOverlay.push(H);
|
|
O.hooks.draw.push(r);
|
|
}
|
|
}
|
|
|
|
function e(P, N) {
|
|
var O = P.getOptions();
|
|
if (O.series.pie.show && O.grid.hoverable) {
|
|
N.unbind("mousemove").mousemove(t);
|
|
}
|
|
if (O.series.pie.show && O.grid.clickable) {
|
|
N.unbind("click").click(l);
|
|
}
|
|
}
|
|
|
|
function G(O) {
|
|
var P = "";
|
|
|
|
function N(S, T) {
|
|
if (!T) {
|
|
T = 0;
|
|
}
|
|
for (var R = 0; R < S.length; ++R) {
|
|
for (var Q = 0; Q < T; Q++) {
|
|
P += "\t";
|
|
}
|
|
if (typeof S[R] == "object") {
|
|
P += "" + R + ":\n";
|
|
N(S[R], T + 1);
|
|
} else {
|
|
P += "" + R + ": " + S[R] + "\n";
|
|
}
|
|
}
|
|
}
|
|
N(O);
|
|
alert(P);
|
|
}
|
|
|
|
function q(P) {
|
|
for (var N = 0; N < P.length; ++N) {
|
|
var O = parseFloat(P[N].data[0][1]);
|
|
if (O) {
|
|
M += O;
|
|
}
|
|
}
|
|
}
|
|
|
|
function E(Q, N, O, P) {
|
|
if (!d) {
|
|
d = true;
|
|
h = Q.getCanvas();
|
|
L = b(h).parent();
|
|
a = Q.getOptions();
|
|
Q.setData(K(Q.getData()));
|
|
}
|
|
}
|
|
|
|
function I() {
|
|
A = L.children().filter(".legend").children().width();
|
|
n = Math.min(h.width, h.height / a.series.pie.tilt) / 2;
|
|
p = h.height / 2 + a.series.pie.offset.top;
|
|
B = h.width / 2;
|
|
if (a.series.pie.offset.left == "auto") {
|
|
if (a.legend.position.match("w")) {
|
|
B += A / 2;
|
|
} else {
|
|
B -= A / 2;
|
|
}
|
|
} else {
|
|
B += a.series.pie.offset.left;
|
|
}
|
|
if (B < n) {
|
|
B = n;
|
|
} else {
|
|
if (B > h.width - n) {
|
|
B = h.width - n;
|
|
}
|
|
}
|
|
}
|
|
|
|
function v(O) {
|
|
for (var N = 0; N < O.length; ++N) {
|
|
if (typeof O[N].data == "number") {
|
|
O[N].data = [[1, O[N].data]];
|
|
} else {
|
|
if (
|
|
typeof O[N].data == "undefined" ||
|
|
typeof O[N].data[0] == "undefined"
|
|
) {
|
|
if (
|
|
typeof O[N].data != "undefined" &&
|
|
typeof O[N].data.label != "undefined"
|
|
) {
|
|
O[N].label = O[N].data.label;
|
|
}
|
|
O[N].data = [[1, 0]];
|
|
}
|
|
}
|
|
}
|
|
return O;
|
|
}
|
|
|
|
function K(Q) {
|
|
Q = v(Q);
|
|
q(Q);
|
|
var P = 0;
|
|
var S = 0;
|
|
var N = a.series.pie.combine.color;
|
|
var R = [];
|
|
for (var O = 0; O < Q.length; ++O) {
|
|
Q[O].data[0][1] = parseFloat(Q[O].data[0][1]);
|
|
if (!Q[O].data[0][1]) {
|
|
Q[O].data[0][1] = 0;
|
|
}
|
|
if (Q[O].data[0][1] / M <= a.series.pie.combine.threshold) {
|
|
P += Q[O].data[0][1];
|
|
S++;
|
|
if (!N) {
|
|
N = Q[O].color;
|
|
}
|
|
} else {
|
|
R.push({
|
|
data: [[1, Q[O].data[0][1]]],
|
|
color: Q[O].color,
|
|
label: Q[O].label,
|
|
angle: (Q[O].data[0][1] * (Math.PI * 2)) / M,
|
|
percent: (Q[O].data[0][1] / M) * 100,
|
|
});
|
|
}
|
|
}
|
|
if (S > 0) {
|
|
R.push({
|
|
data: [[1, P]],
|
|
color: N,
|
|
label: a.series.pie.combine.label,
|
|
angle: (P * (Math.PI * 2)) / M,
|
|
percent: (P / M) * 100,
|
|
});
|
|
}
|
|
return R;
|
|
}
|
|
|
|
function r(S, Q) {
|
|
if (!L) {
|
|
return;
|
|
}
|
|
ctx = Q;
|
|
I();
|
|
var T = S.getData();
|
|
var P = 0;
|
|
while (F && P < o) {
|
|
F = false;
|
|
if (P > 0) {
|
|
n *= w;
|
|
}
|
|
P += 1;
|
|
N();
|
|
if (a.series.pie.tilt <= 0.8) {
|
|
O();
|
|
}
|
|
R();
|
|
}
|
|
if (P >= o) {
|
|
N();
|
|
L.prepend(
|
|
'<div class="error">Could not draw pie with labels contained inside canvas</div>'
|
|
);
|
|
}
|
|
if (S.setSeries && S.insertLegend) {
|
|
S.setSeries(T);
|
|
S.insertLegend();
|
|
}
|
|
|
|
function N() {
|
|
ctx.clearRect(0, 0, h.width, h.height);
|
|
L.children().filter(".pieLabel, .pieLabelBackground").remove();
|
|
}
|
|
|
|
function O() {
|
|
var Z = 5;
|
|
var Y = 15;
|
|
var W = 10;
|
|
var X = 0.02;
|
|
if (a.series.pie.radius > 1) {
|
|
var U = a.series.pie.radius;
|
|
} else {
|
|
var U = n * a.series.pie.radius;
|
|
}
|
|
if (
|
|
U >= h.width / 2 - Z ||
|
|
U * a.series.pie.tilt >= h.height / 2 - Y ||
|
|
U <= W
|
|
) {
|
|
return;
|
|
}
|
|
ctx.save();
|
|
ctx.translate(Z, Y);
|
|
ctx.globalAlpha = X;
|
|
ctx.fillStyle = "#000";
|
|
ctx.translate(B, p);
|
|
ctx.scale(1, a.series.pie.tilt);
|
|
for (var V = 1; V <= W; V++) {
|
|
ctx.beginPath();
|
|
ctx.arc(0, 0, U, 0, Math.PI * 2, false);
|
|
ctx.fill();
|
|
U -= V;
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function R() {
|
|
startAngle = Math.PI * a.series.pie.startAngle;
|
|
if (a.series.pie.radius > 1) {
|
|
var U = a.series.pie.radius;
|
|
} else {
|
|
var U = n * a.series.pie.radius;
|
|
}
|
|
ctx.save();
|
|
ctx.translate(B, p);
|
|
ctx.scale(1, a.series.pie.tilt);
|
|
ctx.save();
|
|
var Y = startAngle;
|
|
for (var W = 0; W < T.length; ++W) {
|
|
T[W].startAngle = Y;
|
|
X(T[W].angle, T[W].color, true);
|
|
}
|
|
ctx.restore();
|
|
ctx.save();
|
|
ctx.lineWidth = a.series.pie.stroke.width;
|
|
Y = startAngle;
|
|
for (var W = 0; W < T.length; ++W) {
|
|
X(T[W].angle, a.series.pie.stroke.color, false);
|
|
}
|
|
ctx.restore();
|
|
J(ctx);
|
|
if (a.series.pie.label.show) {
|
|
V();
|
|
}
|
|
ctx.restore();
|
|
|
|
function X(ab, Z, aa) {
|
|
if (ab <= 0) {
|
|
return;
|
|
}
|
|
if (aa) {
|
|
ctx.fillStyle = Z;
|
|
} else {
|
|
ctx.strokeStyle = Z;
|
|
ctx.lineJoin = "round";
|
|
}
|
|
ctx.beginPath();
|
|
if (Math.abs(ab - Math.PI * 2) > 1e-9) {
|
|
ctx.moveTo(0, 0);
|
|
} else {
|
|
if (b.browser.msie) {
|
|
ab -= 0.0001;
|
|
}
|
|
}
|
|
ctx.arc(0, 0, U, Y, Y + ab, false);
|
|
ctx.closePath();
|
|
Y += ab;
|
|
if (aa) {
|
|
ctx.fill();
|
|
} else {
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
|
|
function V() {
|
|
var ac = startAngle;
|
|
if (a.series.pie.label.radius > 1) {
|
|
var Z = a.series.pie.label.radius;
|
|
} else {
|
|
var Z = n * a.series.pie.label.radius;
|
|
}
|
|
for (var ab = 0; ab < T.length; ++ab) {
|
|
if (T[ab].percent >= a.series.pie.label.threshold * 100) {
|
|
aa(T[ab], ac, ab);
|
|
}
|
|
ac += T[ab].angle;
|
|
}
|
|
|
|
function aa(ap, ai, ag) {
|
|
if (ap.data[0][1] == 0) {
|
|
return;
|
|
}
|
|
var ar = a.legend.labelFormatter,
|
|
aq,
|
|
ae = a.series.pie.label.formatter;
|
|
if (ar) {
|
|
aq = ar(ap.label, ap);
|
|
} else {
|
|
aq = ap.label;
|
|
}
|
|
if (ae) {
|
|
aq = ae(aq, ap);
|
|
}
|
|
var aj = (ai + ap.angle + ai) / 2;
|
|
var ao = B + Math.round(Math.cos(aj) * Z);
|
|
var am = p + Math.round(Math.sin(aj) * Z) * a.series.pie.tilt;
|
|
var af =
|
|
'<span class="pieLabel" id="pieLabel' +
|
|
ag +
|
|
'" style="position:absolute;top:' +
|
|
am +
|
|
"px;left:" +
|
|
ao +
|
|
'px;">' +
|
|
aq +
|
|
"</span>";
|
|
L.append(af);
|
|
var an = L.children("#pieLabel" + ag);
|
|
var ad = am - an.height() / 2;
|
|
var ah = ao - an.width() / 2;
|
|
an.css("top", ad);
|
|
an.css("left", ah);
|
|
if (
|
|
0 - ad > 0 ||
|
|
0 - ah > 0 ||
|
|
h.height - (ad + an.height()) < 0 ||
|
|
h.width - (ah + an.width()) < 0
|
|
) {
|
|
F = true;
|
|
}
|
|
if (a.series.pie.label.background.opacity != 0) {
|
|
var ak = a.series.pie.label.background.color;
|
|
if (ak == null) {
|
|
ak = ap.color;
|
|
}
|
|
var al = "top:" + ad + "px;left:" + ah + "px;";
|
|
b(
|
|
'<div class="pieLabelBackground" style="position:absolute;width:' +
|
|
an.width() +
|
|
"px;height:" +
|
|
an.height() +
|
|
"px;" +
|
|
al +
|
|
"background-color:" +
|
|
ak +
|
|
';"> </div>'
|
|
)
|
|
.insertBefore(an)
|
|
.css("opacity", a.series.pie.label.background.opacity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function J(N) {
|
|
if (a.series.pie.innerRadius > 0) {
|
|
N.save();
|
|
innerRadius =
|
|
a.series.pie.innerRadius > 1
|
|
? a.series.pie.innerRadius
|
|
: n * a.series.pie.innerRadius;
|
|
N.globalCompositeOperation = "destination-out";
|
|
N.beginPath();
|
|
N.fillStyle = a.series.pie.stroke.color;
|
|
N.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
|
|
N.fill();
|
|
N.closePath();
|
|
N.restore();
|
|
N.save();
|
|
N.beginPath();
|
|
N.strokeStyle = a.series.pie.stroke.color;
|
|
N.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
|
|
N.stroke();
|
|
N.closePath();
|
|
N.restore();
|
|
}
|
|
}
|
|
|
|
function s(Q, R) {
|
|
for (var S = false, P = -1, N = Q.length, O = N - 1; ++P < N; O = P) {
|
|
((Q[P][1] <= R[1] && R[1] < Q[O][1]) ||
|
|
(Q[O][1] <= R[1] && R[1] < Q[P][1])) &&
|
|
R[0] <
|
|
((Q[O][0] - Q[P][0]) * (R[1] - Q[P][1])) / (Q[O][1] - Q[P][1]) +
|
|
Q[P][0] &&
|
|
(S = !S);
|
|
}
|
|
return S;
|
|
}
|
|
|
|
function u(R, P) {
|
|
var T = D.getData(),
|
|
O = D.getOptions(),
|
|
N =
|
|
O.series.pie.radius > 1
|
|
? O.series.pie.radius
|
|
: n * O.series.pie.radius;
|
|
for (var Q = 0; Q < T.length; ++Q) {
|
|
var S = T[Q];
|
|
if (S.pie.show) {
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, 0);
|
|
ctx.arc(0, 0, N, S.startAngle, S.startAngle + S.angle, false);
|
|
ctx.closePath();
|
|
x = R - B;
|
|
y = P - p;
|
|
if (ctx.isPointInPath) {
|
|
if (ctx.isPointInPath(R - B, P - p)) {
|
|
ctx.restore();
|
|
return {
|
|
datapoint: [S.percent, S.data],
|
|
dataIndex: 0,
|
|
series: S,
|
|
seriesIndex: Q,
|
|
};
|
|
}
|
|
} else {
|
|
p1X = N * Math.cos(S.startAngle);
|
|
p1Y = N * Math.sin(S.startAngle);
|
|
p2X = N * Math.cos(S.startAngle + S.angle / 4);
|
|
p2Y = N * Math.sin(S.startAngle + S.angle / 4);
|
|
p3X = N * Math.cos(S.startAngle + S.angle / 2);
|
|
p3Y = N * Math.sin(S.startAngle + S.angle / 2);
|
|
p4X = N * Math.cos(S.startAngle + S.angle / 1.5);
|
|
p4Y = N * Math.sin(S.startAngle + S.angle / 1.5);
|
|
p5X = N * Math.cos(S.startAngle + S.angle);
|
|
p5Y = N * Math.sin(S.startAngle + S.angle);
|
|
arrPoly = [
|
|
[0, 0],
|
|
[p1X, p1Y],
|
|
[p2X, p2Y],
|
|
[p3X, p3Y],
|
|
[p4X, p4Y],
|
|
[p5X, p5Y],
|
|
];
|
|
arrPoint = [x, y];
|
|
if (s(arrPoly, arrPoint)) {
|
|
ctx.restore();
|
|
return {
|
|
datapoint: [S.percent, S.data],
|
|
dataIndex: 0,
|
|
series: S,
|
|
seriesIndex: Q,
|
|
};
|
|
}
|
|
}
|
|
ctx.restore();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function t(N) {
|
|
m("plothover", N);
|
|
}
|
|
|
|
function l(N) {
|
|
m("plotclick", N);
|
|
}
|
|
|
|
function m(N, T) {
|
|
var O = D.offset(),
|
|
R = parseInt(T.pageX - O.left),
|
|
P = parseInt(T.pageY - O.top),
|
|
V = u(R, P);
|
|
if (a.grid.autoHighlight) {
|
|
for (var Q = 0; Q < j.length; ++Q) {
|
|
var S = j[Q];
|
|
if (S.auto == N && !(V && S.series == V.series)) {
|
|
f(S.series);
|
|
}
|
|
}
|
|
}
|
|
if (V) {
|
|
k(V.series, N);
|
|
}
|
|
var U = { pageX: T.pageX, pageY: T.pageY };
|
|
L.trigger(N, [U, V]);
|
|
}
|
|
|
|
function k(O, P) {
|
|
if (typeof O == "number") {
|
|
O = series[O];
|
|
}
|
|
var N = C(O);
|
|
if (N == -1) {
|
|
j.push({ series: O, auto: P });
|
|
D.triggerRedrawOverlay();
|
|
} else {
|
|
if (!P) {
|
|
j[N].auto = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
function f(O) {
|
|
if (O == null) {
|
|
j = [];
|
|
D.triggerRedrawOverlay();
|
|
}
|
|
if (typeof O == "number") {
|
|
O = series[O];
|
|
}
|
|
var N = C(O);
|
|
if (N != -1) {
|
|
j.splice(N, 1);
|
|
D.triggerRedrawOverlay();
|
|
}
|
|
}
|
|
|
|
function C(P) {
|
|
for (var N = 0; N < j.length; ++N) {
|
|
var O = j[N];
|
|
if (O.series == P) {
|
|
return N;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
function H(Q, R) {
|
|
var P = Q.getOptions();
|
|
var N =
|
|
P.series.pie.radius > 1 ? P.series.pie.radius : n * P.series.pie.radius;
|
|
R.save();
|
|
R.translate(B, p);
|
|
R.scale(1, P.series.pie.tilt);
|
|
for (i = 0; i < j.length; ++i) {
|
|
O(j[i].series);
|
|
}
|
|
J(R);
|
|
R.restore();
|
|
|
|
function O(S) {
|
|
if (S.angle < 0) {
|
|
return;
|
|
}
|
|
R.fillStyle =
|
|
"rgba(255, 255, 255, " + P.series.pie.highlight.opacity + ")";
|
|
R.beginPath();
|
|
if (Math.abs(S.angle - Math.PI * 2) > 1e-9) {
|
|
R.moveTo(0, 0);
|
|
}
|
|
R.arc(0, 0, N, S.startAngle, S.startAngle + S.angle, false);
|
|
R.closePath();
|
|
R.fill();
|
|
}
|
|
}
|
|
}
|
|
var a = {
|
|
series: {
|
|
pie: {
|
|
show: false,
|
|
radius: "auto",
|
|
innerRadius: 0,
|
|
startAngle: 3 / 2,
|
|
tilt: 1,
|
|
offset: { top: 0, left: "auto" },
|
|
stroke: { color: "#FFF", width: 1 },
|
|
label: {
|
|
show: "auto",
|
|
formatter: function (d, e) {
|
|
return (
|
|
'<div style="font-size:x-small;text-align:center;padding:2px;color:' +
|
|
e.color +
|
|
';">' +
|
|
d +
|
|
"<br/>" +
|
|
Math.round(e.percent) +
|
|
"%</div>"
|
|
);
|
|
},
|
|
radius: 1,
|
|
background: { color: null, opacity: 0 },
|
|
threshold: 0,
|
|
},
|
|
combine: { threshold: -1, color: null, label: "Other" },
|
|
highlight: { opacity: 0.5 },
|
|
},
|
|
},
|
|
};
|
|
b.plot.plugins.push({ init: c, options: a, name: "pie", version: "1.0" });
|
|
})(jQuery);
|
|
|
|
jQuery.browser = {};
|
|
(function () {
|
|
jQuery.browser.msie = false;
|
|
jQuery.browser.version = 0;
|
|
if (navigator.userAgent.match(/MSIE ([0-9]+)\./)) {
|
|
jQuery.browser.msie = true;
|
|
jQuery.browser.version = RegExp.$1;
|
|
}
|
|
})();
|