You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by ph...@apache.org on 2010/06/09 17:26:25 UTC
svn commit: r953041 [3/6] - in /hadoop/zookeeper/trunk: ./
src/contrib/loggraph/ src/contrib/loggraph/bin/ src/contrib/loggraph/src/
src/contrib/loggraph/src/java/ src/contrib/loggraph/src/java/org/
src/contrib/loggraph/src/java/org/apache/ src/contrib...
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.line.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.line.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.line.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.line.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,230 @@
+/*
+ * g.Raphael 0.4 - Charting library, based on Raphaël
+ *
+ * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+Raphael.fn.g.linechart = function (x, y, width, height, valuesx, valuesy, opts) {
+ function shrink(values, dim) {
+ var k = values.length / dim,
+ j = 0,
+ l = k,
+ sum = 0,
+ res = [];
+ while (j < values.length) {
+ l--;
+ if (l < 0) {
+ sum += values[j] * (1 + l);
+ res.push(sum / k);
+ sum = values[j++] * -l;
+ l += k;
+ } else {
+ sum += values[j++];
+ }
+ }
+ return res;
+ }
+ opts = opts || {};
+ if (!this.raphael.is(valuesx[0], "array")) {
+ valuesx = [valuesx];
+ }
+ if (!this.raphael.is(valuesy[0], "array")) {
+ valuesy = [valuesy];
+ }
+ var allx = Array.prototype.concat.apply([], valuesx),
+ ally = Array.prototype.concat.apply([], valuesy),
+ xdim = this.g.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1),
+ minx = xdim.from,
+ maxx = xdim.to,
+ gutter = opts.gutter || 10,
+ kx = (width - gutter * 2) / (maxx - minx),
+ ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),
+ miny = ydim.from,
+ maxy = ydim.to,
+ ky = (height - gutter * 2) / (maxy - miny),
+ len = Math.max(valuesx[0].length, valuesy[0].length),
+ symbol = opts.symbol || "",
+ colors = opts.colors || Raphael.fn.g.colors,
+ that = this,
+ columns = null,
+ dots = null,
+ chart = this.set(),
+ path = [];
+
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ len = Math.max(len, valuesy[i].length);
+ }
+ var shades = this.set();
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ if (opts.shade) {
+ shades.push(this.path().attr({stroke: "none", fill: colors[i], opacity: opts.nostroke ? 1 : .3}));
+ }
+ if (valuesy[i].length > width - 2 * gutter) {
+ valuesy[i] = shrink(valuesy[i], width - 2 * gutter);
+ len = width - 2 * gutter;
+ }
+ if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {
+ valuesx[i] = shrink(valuesx[i], width - 2 * gutter);
+ }
+ }
+ var axis = this.set();
+ if (opts.axis) {
+ var ax = (opts.axis + "").split(/[,\s]+/);
+ +ax[0] && axis.push(this.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.northlabels));
+ +ax[1] && axis.push(this.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.eastlabels));
+ +ax[2] && axis.push(this.g.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.southlabels));
+ +ax[3] && axis.push(this.g.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.westlabels));
+ }
+ if (opts.northAxisLabel) {
+ this.g.text(x + gutter + width/2, gutter, opts.northAxisLabel);
+ }
+ if (opts.southAxisLabel) {
+ this.g.text(x + gutter + width/2, y + height + 20, opts.southAxisLabel);
+ }
+ if (opts.westAxisLabel) {
+ this.g.text(gutter, y + gutter + height/2, opts.westAxisLabel).attr({rotation: -90});
+ }
+ if (opts.eastAxisLabel) {
+ this.g.text(x + gutter + width + 20, y + gutter + height/2, opts.eastAxisLabel).attr({rotation: 90});
+ }
+
+ var lines = this.set(),
+ symbols = this.set(),
+ line;
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ if (!opts.nostroke) {
+ lines.push(line = this.path().attr({
+ stroke: colors[i],
+ "stroke-width": opts.width || 2,
+ "stroke-linejoin": "round",
+ "stroke-linecap": "round",
+ "stroke-dasharray": opts.dash || ""
+ }));
+ }
+ var sym = this.raphael.is(symbol, "array") ? symbol[i] : symbol,
+ symset = this.set();
+ path = [];
+ for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
+ var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx;
+ var Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
+ (Raphael.is(sym, "array") ? sym[j] : sym) && symset.push(this.g[Raphael.fn.g.markers[this.raphael.is(sym, "array") ? sym[j] : sym]](X, Y, (opts.width || 2) * 3).attr({fill: colors[i], stroke: "none"}));
+ path = path.concat([j ? "L" : "M", X, Y]);
+ }
+ symbols.push(symset);
+ if (opts.shade) {
+ shades[i].attr({path: path.concat(["L", X, y + height - gutter, "L", x + gutter + ((valuesx[i] || valuesx[0])[0] - minx) * kx, y + height - gutter, "z"]).join(",")});
+ }
+ !opts.nostroke && line.attr({path: path.join(",")});
+ }
+ function createColumns(f) {
+ // unite Xs together
+ var Xs = [];
+ for (var i = 0, ii = valuesx.length; i < ii; i++) {
+ Xs = Xs.concat(valuesx[i]);
+ }
+ Xs.sort();
+ // remove duplicates
+ var Xs2 = [],
+ xs = [];
+ for (var i = 0, ii = Xs.length; i < ii; i++) {
+ Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx);
+ }
+ Xs = Xs2;
+ ii = Xs.length;
+ var cvrs = f || that.set();
+ for (var i = 0; i < ii; i++) {
+ var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,
+ w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,
+ C;
+ f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({stroke: "none", fill: "#000", opacity: 0}));
+ C.values = [];
+ C.symbols = that.set();
+ C.y = [];
+ C.x = xs[i];
+ C.axis = Xs[i];
+ for (var j = 0, jj = valuesy.length; j < jj; j++) {
+ Xs2 = valuesx[j] || valuesx[0];
+ for (var k = 0, kk = Xs2.length; k < kk; k++) {
+ if (Xs2[k] == Xs[i]) {
+ C.values.push(valuesy[j][k]);
+ C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);
+ C.symbols.push(chart.symbols[j][k]);
+ }
+ }
+ }
+ f && f.call(C);
+ }
+ !f && (columns = cvrs);
+ }
+ function createDots(f) {
+ var cvrs = f || that.set(),
+ C;
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
+ var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
+ nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,
+ Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
+ f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({stroke: "none", fill: "#000", opacity: 0}));
+ C.x = X;
+ C.y = Y;
+ C.value = valuesy[i][j];
+ C.line = chart.lines[i];
+ C.shade = chart.shades[i];
+ C.symbol = chart.symbols[i][j];
+ C.symbols = chart.symbols[i];
+ C.axis = (valuesx[i] || valuesx[0])[j];
+ f && f.call(C);
+ }
+ }
+ !f && (dots = cvrs);
+ }
+ chart.push(lines, shades, symbols, axis, columns, dots);
+ chart.lines = lines;
+ chart.shades = shades;
+ chart.symbols = symbols;
+ chart.axis = axis;
+ chart.hoverColumn = function (fin, fout) {
+ !columns && createColumns();
+ columns.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.clickColumn = function (f) {
+ !columns && createColumns();
+ columns.click(f);
+ return this;
+ };
+ chart.hrefColumn = function (cols) {
+ var hrefs = that.raphael.is(arguments[0], "array") ? arguments[0] : arguments;
+ if (!(arguments.length - 1) && typeof cols == "object") {
+ for (var x in cols) {
+ for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {
+ columns[i].attr("href", cols[x]);
+ }
+ }
+ }
+ !columns && createColumns();
+ for (var i = 0, ii = hrefs.length; i < ii; i++) {
+ columns[i] && columns[i].attr("href", hrefs[i]);
+ }
+ return this;
+ };
+ chart.hover = function (fin, fout) {
+ !dots && createDots();
+ dots.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.click = function (f) {
+ !dots && createDots();
+ dots.click(f);
+ return this;
+ };
+ chart.each = function (f) {
+ createDots(f);
+ return this;
+ };
+ chart.eachColumn = function (f) {
+ createColumns(f);
+ return this;
+ };
+ return chart;
+};
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.pie.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.pie.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.pie.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.pie.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,205 @@
+/*
+ * g.Raphael 0.4 - Charting library, based on Raphaël
+ *
+ * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+Raphael.fn.g.piechart = function (cx, cy, r, values, opts) {
+ opts = opts || {};
+ var paper = this,
+ sectors = [],
+ covers = this.set(),
+ chart = this.set(),
+ series = this.set(),
+ order = [],
+ len = values.length,
+ angle = 0,
+ total = 0,
+ others = 0,
+ cut = 9,
+ defcut = true;
+ chart.covers = covers;
+ if (len == 1) {
+ series.push(this.circle(cx, cy, r).attr({fill: this.g.colors[0], stroke: opt.stroke || "#fff", "stroke-width": opts.strokewidth == null ? 1 : opts.strokewidth}));
+ covers.push(this.circle(cx, cy, r).attr(this.g.shim));
+ total = values[0];
+ values[0] = {value: values[0], order: 0, valueOf: function () { return this.value; }};
+ series[0].middle = {x: cx, y: cy};
+ series[0].mangle = 180;
+ } else {
+ function sector(cx, cy, r, startAngle, endAngle, fill) {
+ var rad = Math.PI / 180,
+ x1 = cx + r * Math.cos(-startAngle * rad),
+ x2 = cx + r * Math.cos(-endAngle * rad),
+ xm = cx + r / 2 * Math.cos(-(startAngle + (endAngle - startAngle) / 2) * rad),
+ y1 = cy + r * Math.sin(-startAngle * rad),
+ y2 = cy + r * Math.sin(-endAngle * rad),
+ ym = cy + r / 2 * Math.sin(-(startAngle + (endAngle - startAngle) / 2) * rad),
+ res = ["M", cx, cy, "L", x1, y1, "A", r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2, "z"];
+ res.middle = {x: xm, y: ym};
+ return res;
+ }
+ for (var i = 0; i < len; i++) {
+ total += values[i];
+ values[i] = {value: values[i], order: i, valueOf: function () { return this.value; }};
+ }
+ values.sort(function (a, b) {
+ return b.value - a.value;
+ });
+ for (var i = 0; i < len; i++) {
+ if (defcut && values[i] * 360 / total <= 1.5) {
+ cut = i;
+ defcut = false;
+ }
+ if (i > cut) {
+ defcut = false;
+ values[cut].value += values[i];
+ values[cut].others = true;
+ others = values[cut].value;
+ }
+ }
+ len = Math.min(cut + 1, values.length);
+ others && values.splice(len) && (values[cut].others = true);
+ for (var i = 0; i < len; i++) {
+ var mangle = angle - 360 * values[i] / total / 2;
+ if (!i) {
+ angle = 90 - mangle;
+ mangle = angle - 360 * values[i] / total / 2;
+ }
+ if (opts.init) {
+ var ipath = sector(cx, cy, 1, angle, angle - 360 * values[i] / total).join(",");
+ }
+ var path = sector(cx, cy, r, angle, angle -= 360 * values[i] / total);
+ var p = this.path(opts.init ? ipath : path).attr({fill: opts.colors && opts.colors[i] || this.g.colors[i] || "#666", stroke: opts.stroke || "#fff", "stroke-width": (opts.strokewidth == null ? 1 : opts.strokewidth), "stroke-linejoin": "round"});
+ p.value = values[i];
+ p.middle = path.middle;
+ p.mangle = mangle;
+ sectors.push(p);
+ series.push(p);
+ opts.init && p.animate({path: path.join(",")}, (+opts.init - 1) || 1000, ">");
+ }
+ for (var i = 0; i < len; i++) {
+ var p = paper.path(sectors[i].attr("path")).attr(this.g.shim);
+ opts.href && opts.href[i] && p.attr({href: opts.href[i]});
+ p.attr = function () {};
+ covers.push(p);
+ series.push(p);
+ }
+ }
+
+ chart.hover = function (fin, fout) {
+ fout = fout || function () {};
+ var that = this;
+ for (var i = 0; i < len; i++) {
+ (function (sector, cover, j) {
+ var o = {
+ sector: sector,
+ cover: cover,
+ cx: cx,
+ cy: cy,
+ mx: sector.middle.x,
+ my: sector.middle.y,
+ mangle: sector.mangle,
+ r: r,
+ value: values[j],
+ total: total,
+ label: that.labels && that.labels[j]
+ };
+ cover.mouseover(function () {
+ fin.call(o);
+ }).mouseout(function () {
+ fout.call(o);
+ });
+ })(series[i], covers[i], i);
+ }
+ return this;
+ };
+ // x: where label could be put
+ // y: where label could be put
+ // value: value to show
+ // total: total number to count %
+ chart.each = function (f) {
+ var that = this;
+ for (var i = 0; i < len; i++) {
+ (function (sector, cover, j) {
+ var o = {
+ sector: sector,
+ cover: cover,
+ cx: cx,
+ cy: cy,
+ x: sector.middle.x,
+ y: sector.middle.y,
+ mangle: sector.mangle,
+ r: r,
+ value: values[j],
+ total: total,
+ label: that.labels && that.labels[j]
+ };
+ f.call(o);
+ })(series[i], covers[i], i);
+ }
+ return this;
+ };
+ chart.click = function (f) {
+ var that = this;
+ for (var i = 0; i < len; i++) {
+ (function (sector, cover, j) {
+ var o = {
+ sector: sector,
+ cover: cover,
+ cx: cx,
+ cy: cy,
+ mx: sector.middle.x,
+ my: sector.middle.y,
+ mangle: sector.mangle,
+ r: r,
+ value: values[j],
+ total: total,
+ label: that.labels && that.labels[j]
+ };
+ cover.click(function () { f.call(o); });
+ })(series[i], covers[i], i);
+ }
+ return this;
+ };
+ chart.inject = function (element) {
+ element.insertBefore(covers[0]);
+ };
+ var legend = function (labels, otherslabel, mark, dir) {
+ var x = cx + r + r / 5,
+ y = cy,
+ h = y + 10;
+ labels = labels || [];
+ dir = (dir && dir.toLowerCase && dir.toLowerCase()) || "east";
+ mark = paper.g.markers[mark && mark.toLowerCase()] || "disc";
+ chart.labels = paper.set();
+ for (var i = 0; i < len; i++) {
+ var clr = series[i].attr("fill"),
+ j = values[i].order,
+ txt;
+ values[i].others && (labels[j] = otherslabel || "Others");
+ labels[j] = paper.g.labelise(labels[j], values[i], total);
+ chart.labels.push(paper.set());
+ chart.labels[i].push(paper.g[mark](x + 5, h, 5).attr({fill: clr, stroke: "none"}));
+ chart.labels[i].push(txt = paper.text(x + 20, h, labels[j] || values[j]).attr(paper.g.txtattr).attr({fill: opts.legendcolor || "#000", "text-anchor": "start"}));
+ covers[i].label = chart.labels[i];
+ h += txt.getBBox().height * 1.2;
+ }
+ var bb = chart.labels.getBBox(),
+ tr = {
+ east: [0, -bb.height / 2],
+ west: [-bb.width - 2 * r - 20, -bb.height / 2],
+ north: [-r - bb.width / 2, -r - bb.height - 10],
+ south: [-r - bb.width / 2, r + 10]
+ }[dir];
+ chart.labels.translate.apply(chart.labels, tr);
+ chart.push(chart.labels);
+ };
+ if (opts.legend) {
+ legend(opts.legend, opts.legendothers, opts.legendmark, opts.legendpos);
+ }
+ chart.push(series, covers);
+ chart.series = series;
+ chart.covers = covers;
+ return chart;
+};
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.raphael.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.raphael.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.raphael.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/g.raphael.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,481 @@
+/*
+ * g.Raphael 0.4 - Charting library, based on Raphaël
+ *
+ * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+
+
+(function () {
+ Raphael.fn.g = Raphael.fn.g || {};
+ Raphael.fn.g.markers = {
+ disc: "disc",
+ o: "disc",
+ flower: "flower",
+ f: "flower",
+ diamond: "diamond",
+ d: "diamond",
+ square: "square",
+ s: "square",
+ triangle: "triangle",
+ t: "triangle",
+ star: "star",
+ "*": "star",
+ cross: "cross",
+ x: "cross",
+ plus: "plus",
+ "+": "plus",
+ arrow: "arrow",
+ "->": "arrow"
+ };
+ Raphael.fn.g.shim = {stroke: "none", fill: "#000", "fill-opacity": 0};
+ Raphael.fn.g.txtattr = {font: "12px Arial, sans-serif"};
+ Raphael.fn.g.colors = [];
+ var hues = [.6, .2, .05, .1333, .75, 0];
+ for (var i = 0; i < 10; i++) {
+ if (i < hues.length) {
+ Raphael.fn.g.colors.push("hsb(" + hues[i] + ", .75, .75)");
+ } else {
+ Raphael.fn.g.colors.push("hsb(" + hues[i - hues.length] + ", 1, .5)");
+ }
+ }
+ Raphael.fn.g.text = function (x, y, text) {
+ return this.text(x, y, text).attr(this.g.txtattr);
+ };
+ Raphael.fn.g.labelise = function (label, val, total) {
+ if (label) {
+ return (label + "").replace(/(##+(?:\.#+)?)|(%%+(?:\.%+)?)/g, function (all, value, percent) {
+ if (value) {
+ return (+val).toFixed(value.replace(/^#+\.?/g, "").length);
+ }
+ if (percent) {
+ return (val * 100 / total).toFixed(percent.replace(/^%+\.?/g, "").length) + "%";
+ }
+ });
+ } else {
+ return (+val).toFixed(0);
+ }
+ };
+
+ Raphael.fn.g.finger = function (x, y, width, height, dir, ending, isPath) {
+ // dir 0 for horisontal and 1 for vertical
+ if ((dir && !height) || (!dir && !width)) {
+ return isPath ? "" : this.path();
+ }
+ ending = {square: "square", sharp: "sharp", soft: "soft"}[ending] || "round";
+ var path;
+ height = Math.round(height);
+ width = Math.round(width);
+ x = Math.round(x);
+ y = Math.round(y);
+ switch (ending) {
+ case "round":
+ if (!dir) {
+ var r = Math.floor(height / 2);
+ if (width < r) {
+ r = width;
+ path = ["M", x + .5, y + .5 - Math.floor(height / 2), "l", 0, 0, "a", r, Math.floor(height / 2), 0, 0, 1, 0, height, "l", 0, 0, "z"];
+ } else {
+ path = ["M", x + .5, y + .5 - r, "l", width - r, 0, "a", r, r, 0, 1, 1, 0, height, "l", r - width, 0, "z"];
+ }
+ } else {
+ var r = Math.floor(width / 2);
+ if (height < r) {
+ r = height;
+ path = ["M", x - Math.floor(width / 2), y, "l", 0, 0, "a", Math.floor(width / 2), r, 0, 0, 1, width, 0, "l", 0, 0, "z"];
+ } else {
+ path = ["M", x - r, y, "l", 0, r - height, "a", r, r, 0, 1, 1, width, 0, "l", 0, height - r, "z"];
+ }
+ }
+ break;
+ case "sharp":
+ if (!dir) {
+ var half = Math.floor(height / 2);
+ path = ["M", x, y + half, "l", 0, -height, Math.max(width - half, 0), 0, Math.min(half, width), half, -Math.min(half, width), half + (half * 2 < height), "z"];
+ } else {
+ var half = Math.floor(width / 2);
+ path = ["M", x + half, y, "l", -width, 0, 0, -Math.max(height - half, 0), half, -Math.min(half, height), half, Math.min(half, height), half, "z"];
+ }
+ break;
+ case "square":
+ if (!dir) {
+ path = ["M", x, y + Math.floor(height / 2), "l", 0, -height, width, 0, 0, height, "z"];
+ } else {
+ path = ["M", x + Math.floor(width / 2), y, "l", 1 - width, 0, 0, -height, width - 1, 0, "z"];
+ }
+ break;
+ case "soft":
+ var r;
+ if (!dir) {
+ r = Math.min(width, Math.round(height / 5));
+ path = ["M", x + .5, y + .5 - Math.floor(height / 2), "l", width - r, 0, "a", r, r, 0, 0, 1, r, r, "l", 0, height - r * 2, "a", r, r, 0, 0, 1, -r, r, "l", r - width, 0, "z"];
+ } else {
+ r = Math.min(Math.round(width / 5), height);
+ path = ["M", x - Math.floor(width / 2), y, "l", 0, r - height, "a", r, r, 0, 0, 1, r, -r, "l", width - 2 * r, 0, "a", r, r, 0, 0, 1, r, r, "l", 0, height - r, "z"];
+ }
+ }
+ if (isPath) {
+ return path.join(",");
+ } else {
+ return this.path(path);
+ }
+ };
+
+ // Symbols
+ Raphael.fn.g.disc = function (cx, cy, r) {
+ return this.circle(cx, cy, r);
+ };
+ Raphael.fn.g.line = function (cx, cy, r) {
+ return this.rect(cx - r, cy - r / 5, 2 * r, 2 * r / 5);
+ };
+ Raphael.fn.g.square = function (cx, cy, r) {
+ r = r * .7;
+ return this.rect(cx - r, cy - r, 2 * r, 2 * r);
+ };
+ Raphael.fn.g.triangle = function (cx, cy, r) {
+ r *= 1.75;
+ return this.path("M".concat(cx, ",", cy, "m0-", r * .58, "l", r * .5, ",", r * .87, "-", r, ",0z"));
+ };
+ Raphael.fn.g.diamond = function (cx, cy, r) {
+ return this.path(["M", cx, cy - r, "l", r, r, -r, r, -r, -r, r, -r, "z"]);
+ };
+ Raphael.fn.g.flower = function (cx, cy, r, n) {
+ r = r * 1.25;
+ var rout = r,
+ rin = rout * .5;
+ n = +n < 3 || !n ? 5 : n;
+ var points = ["M", cx, cy + rin, "Q"],
+ R;
+ for (var i = 1; i < n * 2 + 1; i++) {
+ R = i % 2 ? rout : rin;
+ points = points.concat([+(cx + R * Math.sin(i * Math.PI / n)).toFixed(3), +(cy + R * Math.cos(i * Math.PI / n)).toFixed(3)]);
+ }
+ points.push("z");
+ return this.path(points.join(","));
+ };
+ Raphael.fn.g.star = function (cx, cy, r, r2) {
+ r2 = r2 || r * .5;
+ var points = ["M", cx, cy + r2, "L"],
+ R;
+ for (var i = 1; i < 10; i++) {
+ R = i % 2 ? r : r2;
+ points = points.concat([(cx + R * Math.sin(i * Math.PI * .2)).toFixed(3), (cy + R * Math.cos(i * Math.PI * .2)).toFixed(3)]);
+ }
+ points.push("z");
+ return this.path(points.join(","));
+ };
+ Raphael.fn.g.cross = function (cx, cy, r) {
+ r = r / 2.5;
+ return this.path("M".concat(cx - r, ",", cy, "l", [-r, -r, r, -r, r, r, r, -r, r, r, -r, r, r, r, -r, r, -r, -r, -r, r, -r, -r, "z"]));
+ };
+ Raphael.fn.g.plus = function (cx, cy, r) {
+ r = r / 2;
+ return this.path("M".concat(cx - r / 2, ",", cy - r / 2, "l", [0, -r, r, 0, 0, r, r, 0, 0, r, -r, 0, 0, r, -r, 0, 0, -r, -r, 0, 0, -r, "z"]));
+ };
+ Raphael.fn.g.arrow = function (cx, cy, r) {
+ return this.path("M".concat(cx - r * .7, ",", cy - r * .4, "l", [r * .6, 0, 0, -r * .4, r, r * .8, -r, r * .8, 0, -r * .4, -r * .6, 0], "z"));
+ };
+
+ // Tooltips
+ Raphael.fn.g.tag = function (x, y, text, angle, r) {
+ angle = angle || 0;
+ r = r == null ? 5 : r;
+ text = text == null ? "$9.99" : text;
+ var R = .5522 * r,
+ res = this.set(),
+ d = 3;
+ res.push(this.path().attr({fill: "#000", stroke: "none"}));
+ res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff"}));
+ res.update = function () {
+ this.rotate(0, x, y);
+ var bb = this[1].getBBox();
+ if (bb.height >= r * 2) {
+ this[0].attr({path: ["M", x, y + r, "a", r, r, 0, 1, 1, 0, -r * 2, r, r, 0, 1, 1, 0, r * 2, "m", 0, -r * 2 -d, "a", r + d, r + d, 0, 1, 0, 0, (r + d) * 2, "L", x + r + d, y + bb.height / 2 + d, "l", bb.width + 2 * d, 0, 0, -bb.height - 2 * d, -bb.width - 2 * d, 0, "L", x, y - r - d].join(",")});
+ } else {
+ var dx = Math.sqrt(Math.pow(r + d, 2) - Math.pow(bb.height / 2 + d, 2));
+ // ["c", -R, 0, -r, R - r, -r, -r, 0, -R, r - R, -r, r, -r, R, 0, r, r - R, r, r, 0, R, R - r, r, -r, r]
+ // "a", r, r, 0, 1, 1, 0, -r * 2, r, r, 0, 1, 1, 0, r * 2,
+ this[0].attr({path: ["M", x, y + r, "c", -R, 0, -r, R - r, -r, -r, 0, -R, r - R, -r, r, -r, R, 0, r, r - R, r, r, 0, R, R - r, r, -r, r, "M", x + dx, y - bb.height / 2 - d, "a", r + d, r + d, 0, 1, 0, 0, bb.height + 2 * d, "l", r + d - dx + bb.width + 2 * d, 0, 0, -bb.height - 2 * d, "L", x + dx, y - bb.height / 2 - d].join(",")});
+ }
+ this[1].attr({x: x + r + d + bb.width / 2, y: y});
+ angle = (360 - angle) % 360;
+ this.rotate(angle, x, y);
+ angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});
+ return this;
+ };
+ res.update();
+ return res;
+ };
+ Raphael.fn.g.popupit = function (x, y, set, dir, size) {
+ dir = dir == null ? 2 : dir;
+ size = size || 5;
+ x = Math.round(x) + .5;
+ y = Math.round(y) + .5;
+ var bb = set.getBBox(),
+ w = Math.round(bb.width / 2),
+ h = Math.round(bb.height / 2),
+ dx = [0, w + size * 2, 0, -w - size * 2],
+ dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
+ p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -Math.max(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
+ "l", 0, -Math.max(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -Math.max(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
+ "l", Math.max(w - size, 0), 0, size, !dir * -size, size, !dir * size, Math.max(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
+ "l", 0, Math.max(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, Math.max(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
+ "l", -Math.max(w - size, 0), 0, "z"].join(","),
+ xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];
+ set.translate(xy.x - w - bb.x, xy.y - h - bb.y);
+ return this.path(p).attr({fill: "#000", stroke: "none"}).insertBefore(set.node ? set : set[0]);
+ };
+ Raphael.fn.g.popup = function (x, y, text, dir, size) {
+ dir = dir == null ? 2 : dir;
+ size = size || 5;
+ text = text || "$9.99";
+ var res = this.set(),
+ d = 3;
+ res.push(this.path().attr({fill: "#000", stroke: "none"}));
+ res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff"}));
+ res.update = function (X, Y, withAnimation) {
+ X = X || x;
+ Y = Y || y;
+ var bb = this[1].getBBox(),
+ w = bb.width / 2,
+ h = bb.height / 2,
+ dx = [0, w + size * 2, 0, -w - size * 2],
+ dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
+ p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size, -Math.max(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
+ "l", 0, -Math.max(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -Math.max(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
+ "l", Math.max(w - size, 0), 0, size, !dir * -size, size, !dir * size, Math.max(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
+ "l", 0, Math.max(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, Math.max(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
+ "l", -Math.max(w - size, 0), 0, "z"].join(","),
+ xy = [{x: X, y: Y + size * 2 + h}, {x: X - size * 2 - w, y: Y}, {x: X, y: Y - size * 2 - h}, {x: X + size * 2 + w, y: Y}][dir];
+ if (withAnimation) {
+ this[0].animate({path: p}, 500, ">");
+ this[1].animate(xy, 500, ">");
+ } else {
+ this[0].attr({path: p});
+ this[1].attr(xy);
+ }
+ return this;
+ };
+ return res.update(x, y);
+ };
+ Raphael.fn.g.flag = function (x, y, text, angle) {
+ angle = angle || 0;
+ text = text || "$9.99";
+ var res = this.set(),
+ d = 3;
+ res.push(this.path().attr({fill: "#000", stroke: "none"}));
+ res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff"}));
+ res.update = function (x, y) {
+ this.rotate(0, x, y);
+ var bb = this[1].getBBox(),
+ h = bb.height / 2;
+ this[0].attr({path: ["M", x, y, "l", h + d, -h - d, bb.width + 2 * d, 0, 0, bb.height + 2 * d, -bb.width - 2 * d, 0, "z"].join(",")});
+ this[1].attr({x: x + h + d + bb.width / 2, y: y});
+ angle = 360 - angle;
+ this.rotate(angle, x, y);
+ angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});
+ return this;
+ };
+ return res.update(x, y);
+ };
+ Raphael.fn.g.label = function (x, y, text) {
+ var res = this.set();
+ res.push(this.rect(x, y, 10, 10).attr({stroke: "none", fill: "#000"}));
+ res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff"}));
+ res.update = function () {
+ var bb = this[1].getBBox(),
+ r = Math.min(bb.width + 10, bb.height + 10) / 2;
+ this[0].attr({x: bb.x - r / 2, y: bb.y - r / 2, width: bb.width + r, height: bb.height + r, r: r});
+ };
+ res.update();
+ return res;
+ };
+ Raphael.fn.g.labelit = function (set) {
+ var bb = set.getBBox(),
+ r = Math.min(20, bb.width + 10, bb.height + 10) / 2;
+ return this.rect(bb.x - r / 2, bb.y - r / 2, bb.width + r, bb.height + r, r).attr({stroke: "none", fill: "#000"}).insertBefore(set[0]);
+ };
+ Raphael.fn.g.drop = function (x, y, text, size, angle) {
+ size = size || 30;
+ angle = angle || 0;
+ var res = this.set();
+ res.push(this.path(["M", x, y, "l", size, 0, "A", size * .4, size * .4, 0, 1, 0, x + size * .7, y - size * .7, "z"]).attr({fill: "#000", stroke: "none", rotation: [22.5 - angle, x, y]}));
+ angle = (angle + 90) * Math.PI / 180;
+ res.push(this.text(x + size * Math.sin(angle), y + size * Math.cos(angle), text).attr(this.g.txtattr).attr({"font-size": size * 12 / 30, fill: "#fff"}));
+ res.drop = res[0];
+ res.text = res[1];
+ return res;
+ };
+ Raphael.fn.g.blob = function (x, y, text, angle, size) {
+ angle = (+angle + 1 ? angle : 45) + 90;
+ size = size || 12;
+ var rad = Math.PI / 180,
+ fontSize = size * 12 / 12;
+ var res = this.set();
+ res.push(this.path().attr({fill: "#000", stroke: "none"}));
+ res.push(this.text(x + size * Math.sin((angle) * rad), y + size * Math.cos((angle) * rad) - fontSize / 2, text).attr(this.g.txtattr).attr({"font-size": fontSize, fill: "#fff"}));
+ res.update = function (X, Y, withAnimation) {
+ X = X || x;
+ Y = Y || y;
+ var bb = this[1].getBBox(),
+ w = Math.max(bb.width + fontSize, size * 25 / 12),
+ h = Math.max(bb.height + fontSize, size * 25 / 12),
+ x2 = X + size * Math.sin((angle - 22.5) * rad),
+ y2 = Y + size * Math.cos((angle - 22.5) * rad),
+ x1 = X + size * Math.sin((angle + 22.5) * rad),
+ y1 = Y + size * Math.cos((angle + 22.5) * rad),
+ dx = (x1 - x2) / 2,
+ dy = (y1 - y2) / 2,
+ rx = w / 2,
+ ry = h / 2,
+ k = -Math.sqrt(Math.abs(rx * rx * ry * ry - rx * rx * dy * dy - ry * ry * dx * dx) / (rx * rx * dy * dy + ry * ry * dx * dx)),
+ cx = k * rx * dy / ry + (x1 + x2) / 2,
+ cy = k * -ry * dx / rx + (y1 + y2) / 2;
+ if (withAnimation) {
+ this.animate({x: cx, y: cy, path: ["M", x, y, "L", x1, y1, "A", rx, ry, 0, 1, 1, x2, y2, "z"].join(",")}, 500, ">");
+ } else {
+ this.attr({x: cx, y: cy, path: ["M", x, y, "L", x1, y1, "A", rx, ry, 0, 1, 1, x2, y2, "z"].join(",")});
+ }
+ return this;
+ };
+ res.update(x, y);
+ return res;
+ };
+
+ Raphael.fn.g.colorValue = function (value, total, s, b) {
+ return "hsb(" + [Math.min((1 - value / total) * .4, 1), s || .75, b || .75] + ")";
+ };
+
+ Raphael.fn.g.snapEnds = function (from, to, steps) {
+ var f = from,
+ t = to;
+ if (f == t) {
+ return {from: f, to: t, power: 0};
+ }
+ function round(a) {
+ return Math.abs(a - .5) < .25 ? Math.floor(a) + .5 : Math.round(a);
+ }
+ var d = (t - f) / steps,
+ r = Math.floor(d),
+ R = r,
+ i = 0;
+ if (r) {
+ while (R) {
+ i--;
+ R = Math.floor(d * Math.pow(10, i)) / Math.pow(10, i);
+ }
+ i ++;
+ } else {
+ while (!r) {
+ i = i || 1;
+ r = Math.floor(d * Math.pow(10, i)) / Math.pow(10, i);
+ i++;
+ }
+ i && i--;
+ }
+ var t = round(to * Math.pow(10, i)) / Math.pow(10, i);
+ if (t < to) {
+ t = round((to + .5) * Math.pow(10, i)) / Math.pow(10, i);
+ }
+ var f = round((from - (i > 0 ? 0 : .5)) * Math.pow(10, i)) / Math.pow(10, i);
+ return {from: f, to: t, power: i};
+ };
+ Raphael.fn.g.axis = function (x, y, length, from, to, steps, orientation, labels, type, dashsize) {
+ dashsize = dashsize == null ? 3 : dashsize;
+ type = type || "t";
+ steps = steps || 10;
+ var path = type == "|" || type == " " ? ["M", x + .5, y, "l", 0, .001] : orientation == 1 || orientation == 3 ? ["M", x + .5, y, "l", 0, -length] : ["M", x, y + .5, "l", length, 0],
+ ends = this.g.snapEnds(from, to, steps),
+ f = ends.from,
+ t = ends.to,
+ i = ends.power,
+ j = 0,
+ text = this.set();
+ d = (t - f) / steps;
+ var label = f,
+ rnd = i > 0 ? i : 0;
+ dx = length / steps;
+ if (+orientation == 1 || +orientation == 3) {
+ var Y = y,
+ addon = (orientation - 1 ? 1 : -1) * (dashsize + 3 + !!(orientation - 1));
+ while (Y >= y - length) {
+ type != "-" && type != " " && (path = path.concat(["M", x - (type == "+" || type == "|" ? dashsize : !(orientation - 1) * dashsize * 2), Y + .5, "l", dashsize * 2 + 1, 0]));
+ text.push(this.text(x + addon, Y, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({"text-anchor": orientation - 1 ? "start" : "end"}));
+ label += d;
+ Y -= dx;
+ }
+ if (Math.round(Y + dx - (y - length))) {
+ type != "-" && type != " " && (path = path.concat(["M", x - (type == "+" || type == "|" ? dashsize : !(orientation - 1) * dashsize * 2), y - length + .5, "l", dashsize * 2 + 1, 0]));
+ text.push(this.text(x + addon, y - length, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({"text-anchor": orientation - 1 ? "start" : "end"}));
+ }
+ } else {
+ var X = x,
+ label = f,
+ rnd = i > 0 ? i : 0,
+ addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation),
+ dx = length / steps,
+ txt = 0,
+ prev = 0;
+ while (X <= x + length) {
+
+ text.push(txt = this.text(X, y + addon, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));
+ var bb = txt.getBBox();
+ var ds = dashsize;
+ if (prev >= bb.x - 5) {
+ text.pop(text.length - 1).remove();
+ ds = 1;
+ } else {
+ prev = bb.x + bb.width;
+ }
+
+ type != "-" && type != " " && (path = path.concat(["M", X + .5, y - (type == "+" ? ds : !!orientation * ds * 2), "l", 0, ds * 2 + 1]));
+
+ label += d;
+ X += dx;
+ }
+ if (Math.round(X - dx - x - length)) {
+ type != "-" && type != " " && (path = path.concat(["M", x + length + .5, y - (type == "+" ? dashsize : !!orientation * dashsize * 2), "l", 0, dashsize * 2 + 1]));
+ text.push(this.text(x + length, y + addon, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));
+ }
+ }
+ var res = this.path(path);
+ res.text = text;
+ res.all = this.set([res, text]);
+ res.remove = function () {
+ this.text.remove();
+ this.constructor.prototype.remove.call(this);
+ };
+ return res;
+ };
+
+ Raphael.el.lighter = function (times) {
+ times = times || 2;
+ var fs = [this.attrs.fill, this.attrs.stroke];
+ this.fs = this.fs || [fs[0], fs[1]];
+ fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);
+ fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);
+ fs[0].b = Math.min(fs[0].b * times, 1);
+ fs[0].s = fs[0].s / times;
+ fs[1].b = Math.min(fs[1].b * times, 1);
+ fs[1].s = fs[1].s / times;
+ this.attr({fill: "hsb(" + [fs[0].h, fs[0].s, fs[0].b] + ")", stroke: "hsb(" + [fs[1].h, fs[1].s, fs[1].b] + ")"});
+ };
+ Raphael.el.darker = function (times) {
+ times = times || 2;
+ var fs = [this.attrs.fill, this.attrs.stroke];
+ this.fs = this.fs || [fs[0], fs[1]];
+ fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);
+ fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);
+ fs[0].s = Math.min(fs[0].s * times, 1);
+ fs[0].b = fs[0].b / times;
+ fs[1].s = Math.min(fs[1].s * times, 1);
+ fs[1].b = fs[1].b / times;
+ this.attr({fill: "hsb(" + [fs[0].h, fs[0].s, fs[0].b] + ")", stroke: "hsb(" + [fs[1].h, fs[1].s, fs[1].b] + ")"});
+ };
+ Raphael.el.original = function () {
+ if (this.fs) {
+ this.attr({fill: this.fs[0], stroke: this.fs[1]});
+ delete this.fs;
+ }
+ };
+})();
\ No newline at end of file
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load-big.gif
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load-big.gif?rev=953041&view=auto
==============================================================================
Binary file - no diff available.
Propchange: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load-big.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load.gif
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load.gif?rev=953041&view=auto
==============================================================================
Binary file - no diff available.
Propchange: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/load.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.css
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.css?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.css (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.css Wed Jun 9 15:26:22 2010
@@ -0,0 +1,54 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+body { font-family: sans-serif; }
+
+div.fileSelector { border: solid 3px black; position: absolute; background: white;
+ -moz-border-radius: 10px; border-radius: 10px;
+ padding: 5px; font-family: sans-serif;
+ right: 10px; top: 10px;
+ }
+div.fileSelector a { cursor: pointer; }
+.fileSelector li.selectedFile { background: lightgreen; }
+
+div.selector { border: solid 3px black; position: absolute; background: white;
+ -moz-border-radius: 10px; border-radius: 10px;
+ padding: 5px;
+ right: 10px; top: 10px; background: #aaaaaa; opacity: 0.7;
+ }
+div.selector a { cursor: pointer; }
+.fileSelector li.selectedFile { background: lightgreen; }
+
+#fileLoader { -moz-border-radius: 10px; border-radius: 10px; background: #aaaaaa; opacity: 0.7; position: absolute; left: 20px; top: 20px; }
+#loadingScreen { position: absolute; top: 100px; margin-left: 40%; margin-right: 40%; width: 500px; background: #aaaaaa; opacity: 0.7; -moz-border-radius: 10px; border-radius: 10px; text-align: center }
+#filterinput { width: 500px; height: 100px; }
+/* main interface */
+#actions { float: right; }
+#views { float: left; }
+
+.closebutton { position: absolute; right: 5px; float: right; display: block; cursor: pointer; }
+
+.actionbutton { color: blue; text-decoration: none; padding: 3px; cursor: pointer; }
+span:hover.actionbutton { background: lightblue; }
+
+#status { text-align: center; }
+
+#canvas { width: 100%; height: 1000px; }
+
+#logtable { width: 100%; }
+.popUp { border: 3px solid black; -moz-border-radius: 10px; border-radius: 10px; position: absolute; background: white; padding: 10px; min-width: 300px; }
+
+.errorpage { position: absolute; top: 100px; margin-left: 40%; margin-right: 40%; width: 500px; background: #aaaaaa; opacity: 0.7; -moz-border-radius: 10px; border-radius: 10px; padding: 10px; }
\ No newline at end of file
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,262 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+LogGraph = function(canvas, status) {
+ this.canvas = document.getElementById(canvas);
+ this.status = document.getElementById(status);
+ this.starttime = 0;
+ this.endtime = 0;
+ this.period = 0;
+ this.numEntries = 0;
+ this.currentRender = 0;
+ this.filter = "";
+
+ this.saveFilters = function () {
+ localStorage.starttime = this.starttime;
+ localStorage.endtime = this.endtime;
+ localStorage.period = this.period;
+ localStorage.filter = this.filter;
+
+ };
+ this.loadFilters = function () {
+ if (localStorage.starttime) { this.starttime = parseInt(localStorage.starttime); }
+ if (localStorage.endtime) { this.endtime = parseInt(localStorage.endtime); }
+ if (localStorage.period) { this.period = parseInt(localStorage.period); }
+ if (localStorage.filter) { this.filter = localStorage.filter; }
+ };
+ this.loadFilters();
+ var self = this;
+
+ var updateStatus = function (starttime, period, filter, numEntries) {
+ self.starttime = starttime;
+ self.endtime = starttime + period;
+ self.period = period;
+ self.filter = filter;
+ self.saveFilters();
+
+ self.status.innerHTML = dateFormat(starttime, "HH:MM:ss,l") + " ⇒ " + dateFormat(self.endtime, "HH:MM:ss,l") + " | " + numEntries + " entries | " + (filter ? filter : "No filter");
+
+ if (self.currentRender) {
+ self.currentRender();
+ }
+ };
+
+ YUI().use("io-base", function(Y) {
+ var uri = "/info";
+ if (self.starttime) {
+ var uri = "/info?start=" + self.starttime + "&period=" + self.period + "&filter=" + self.filter;
+ }
+
+ function complete(id, o, args) {
+ var data = eval("(" + o.responseText + ")"); // Response data.
+ var period = data.endTime - data.startTime;
+ updateStatus(data.startTime, period, self.filter, data.numEntries);
+ };
+
+ Y.on('io:complete', complete, Y, []);
+ var request = Y.io(uri);
+ });
+
+ this.addLogs = function() {
+ new LogGraph.fileSelector(function (files) { new LogGraph.fileLoader(files); });
+ };
+
+ this.editFilters = function() {
+ new LogGraph.filterSelector(this.starttime, this.period, this.filter, updateStatus);
+ };
+
+ this.getCleanCanvas = function () {
+ this.canvas.innerHTML = "";
+ return this.canvas;
+ };
+
+ this.showLoadingScreen = function () {
+ this.loadingScreen = document.createElement("div");
+ this.loadingScreen.id = "loadingScreen";
+ this.loadingScreen.innerHTML = "<img src=\"load-big.gif\" /> <p>Loading...</p>";
+ document.body.appendChild(this.loadingScreen);
+ };
+
+ this.hideLoadingScreen = function () {
+ document.body.removeChild(this.loadingScreen);
+ this.loadingScreen.style.visibility = "hidden";
+ };
+
+
+ /***
+ * TODO: refactor these to load the data first, before handing to a draw funciton.
+ * We shouldn't pass the async q into the drawing function
+ */
+ this.showLogs = function() {
+ var self= this;
+ YUI().use('async-queue', function(Y) {
+ var q = new Y.AsyncQueue(self.showLoadingScreen,
+ // The second callback will pause the Queue and send an XHR for data
+ function () {
+ q.pause();
+ var loggraph = new LogGraph.LogTable(q, self.getCleanCanvas(), self.starttime, self.endtime, self.filter);
+ self.currentRender = self.showLogs;
+ },
+ self.hideLoadingScreen);
+ q.run();
+ }
+ );
+ };
+
+ this.serverGraph = function() {
+ var self= this;
+ YUI().use('async-queue', function(Y) {
+ var q = new Y.AsyncQueue(self.showLoadingScreen,
+ // The second callback will pause the Queue and send an XHR for data
+ function () {
+ q.pause();
+ var servergraph = new LogGraph.ServerGraph(q, self.getCleanCanvas(), self.starttime, self.endtime, self.filter);
+ self.currentRender = self.showLogs;
+ },
+ self.hideLoadingScreen);
+ q.run();
+ }
+ );
+ };
+
+ this.sessionGraph = function() {
+ var self= this;
+ YUI().use('async-queue', function(Y) {
+ var q = new Y.AsyncQueue(self.showLoadingScreen,
+ // The second callback will pause the Queue and send an XHR for data
+ function () {
+ q.pause();
+ var sessiongraph = new LogGraph.SessionGraph(q, self.getCleanCanvas(), self.starttime, self.endtime, self.filter);
+ self.currentRender = self.sessionGraph;
+ },
+ self.hideLoadingScreen);
+ q.run();
+ }
+ );
+ };
+
+ this.showStats = function() {
+ var self= this;
+ YUI().use('async-queue', function(Y) {
+ var q = new Y.AsyncQueue(self.showLoadingScreen,
+ // The second callback will pause the Queue and send an XHR for data
+ function () {
+ q.pause();
+ var statgraph = new LogGraph.StatsGraph(q, self.getCleanCanvas(), self.starttime, self.endtime, self.filter);
+ self.currentRender = self.showStats;
+ },
+ self.hideLoadingScreen);
+ q.run();
+ }
+ );
+ };
+};
+
+LogGraph.error = function(description) {
+ var errorPage = document.createElement("div");
+ errorPage.className = "errorpage";
+ var p = document.createElement("p");
+ p.innerHTML = description;
+ errorPage.appendChild(p);
+
+ var span = document.createElement("span");
+ p = document.createElement("p");
+ span.className = "actionButton";
+ span.innerHTML = "OK";
+ span.onclick = function (evt) {
+ document.body.removeChild(errorPage);
+ delete errorPage;
+ }
+ p.appendChild(span);
+ errorPage.appendChild(p);
+
+ document.body.appendChild(errorPage);
+};
+
+LogGraph.ticker =function(allow_dups) {
+ this.ticks = new Array();
+ this.current_tick = 0;
+ this.allow_dups = allow_dups;;
+
+ this.tick = function(time) {
+ if (time == this.ticks[this.ticks.length - 1] && this.allow_dups == true)
+ return this.current_tick;
+
+ this.ticks.push(time);
+ return this.current_tick++;
+ };
+
+ this.current = function() {
+ return this.current_tick;
+ };
+
+ this.reset = function() {
+ while (this.ticks.length) {
+ this.ticks.pop();
+ }
+ this.current_tick = 0;
+ };
+};
+
+
+LogGraph.timescale = function(starttime, endtime) {
+ this.starttime = starttime;
+ this.endtime = endtime;
+ this.millis = endtime - starttime;
+
+ this.draw = function(paper) {
+ var scale = paper.set();
+ scale.push(paper.path("M0 0 L" + paper.width + " 0"));
+
+ for (var i = 0; i < paper.width; i += 100) {
+ scale.push(paper.path("M" + i + " 0 L" + i + " 5"));
+ // var time = dateFormat((this.starttime + (i*ms_per_pixel)), "h:MM:ss,l");
+ // paper.text(i + 5, 10, time);
+ }
+
+ scale.attr({"stroke-width": 2});
+ };
+};
+
+/*
+ Fetch data from an uri and process it, the process data func returns true if any of the data is useful
+*/
+LogGraph.loadData = function (asyncq, uri, processdata) {
+ YUI().use("io-base", function(Y) {
+ function success(id, o, args) {
+ var data = eval("(" + o.responseText + ")"); // Response data.
+ if (data.error) {
+ LogGraph.error(data.error);
+ } else {
+ if (!processdata(data)) {
+ LogGraph.error("No data. Perhaps you should loosen your filter criteria.");
+ }
+ }
+ asyncq.run();
+ };
+ function failure(id, o, args) {
+ LogGraph.error("Error contacting server: (" + o.status + ") " + o.statusText);
+ asyncq.run();
+ };
+
+ Y.on('io:success', success, Y, []);
+ Y.on('io:failure', failure, Y, []);
+
+ var request = Y.io(uri);
+ });
+}
\ No newline at end of file
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.log.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.log.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.log.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.log.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+LogGraph.LogTable = function (asyncq, canvas, starttime, endtime, filter) {
+ this.starttime = starttime;
+ this.endtime = endtime;
+ this.filter = filter;
+
+ var table = document.createElement("table");
+ table.id = "logtable";
+ canvas.appendChild(table);
+
+ this.addLogLine = function(time, text) {
+ var tr = document.createElement("tr");
+ table.appendChild(tr);
+
+ var td = document.createElement("td");
+ td.innerHTML = dateFormat(time, "h:MM:ss,l");
+ tr.appendChild(td);
+
+ td = document.createElement("td");
+ td.innerHTML = text;
+ tr.appendChild(td);
+ }
+
+ var self = this;
+ var processdata = function(data) {
+ var events = data["events"];
+ var count = 0;
+ for (var i in events) {
+ var e = events[i];
+ if (e.type == "text") {
+ self.addLogLine(e.time, e.text);
+ count++;
+ }
+ }
+ return count != 0;
+ };
+
+ var uri = "/data?start=" + self.starttime + "&end=" + self.endtime + "&filter=" + self.filter;
+ LogGraph.loadData(asyncq, uri, processdata);
+};
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.server.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.server.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.server.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.server.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,329 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+LogGraph.ServerGraph = function(asyncq, canvas, starttime, endtime, filter) {
+ this.starttime = starttime;
+ this.endtime = endtime;
+ this.millis = endtime - starttime;
+ this.nextserverid = 0;
+ this.serveroffset = 100;
+ this.filter = filter;
+
+ this.pixels_per_tick = 20;
+ this.ticker = new LogGraph.ticker();
+
+
+ var paper = Raphael(canvas, 1, 1);
+
+ var self = this;
+
+ this.timescale = new LogGraph.timescale(starttime, endtime);
+ this.objects = new Array();
+
+ this.add = function(obj) {
+ this.objects.push(obj);
+ }
+
+ this.tick_to_x = function (timestamp) {
+ var x = timestamp * this.pixels_per_tick;
+ return x;
+ };
+
+ this._drawTime = function(paper, x, time) {
+ var p = paper.path("M" + x + " 0 L" + x + " " + paper.height);
+ var t = paper.text(x, 10, dateFormat(time, "h:MM:ss,l"));
+
+ t.hide();
+ p.mouseover(function(evt) {
+ t.show();
+ p.attr({stroke: "red"});
+ });
+ p.mouseout(function(evt) {
+ t.hide();
+ p.attr({stroke: "lightgray"});
+ });
+
+ return p;
+ };
+
+ this.draw = function(paper) {
+ var grid = paper.set();
+ for (var i = 0; i < paper.height; i += 20) {
+ grid.push(paper.path("M0 " + i + " L" + paper.width + " " + i));
+ }
+ var lasttick = this.starttime;
+ var scale = 500; // 500 ms
+
+ var y = 0;
+
+ for (var t = 0, len = this.ticker.ticks.length; t < len; t++) {
+ var basex = t * this.pixels_per_tick;
+ var thistick = this.ticker.ticks[t];
+ var nexttick = t + 1 == this.ticker.ticks.length ? this.endtime : this.ticker.ticks[t+1];
+ if (nexttick == thistick) {
+ continue;
+ }
+ var time = thistick - lasttick;
+ var first = scale - (lasttick % scale);
+
+ /* for (var i = 0; (first+scale*i) < time; i++) {
+
+ var toffset = first+scale*i;
+ var x = basex + LogGraph._pixels_per_tick * toffset/time;
+ grid.push(this._drawTime(paper, x, lasttick + toffset, grid));
+
+ }*/
+
+
+ //grid.push(paper.path("M" + i + " 0 L" + i + " " + paper.height));
+ lasttick = thistick;
+ }
+ grid.attr({stroke: "lightgray"});
+ this.timescale.draw(paper);
+
+ for (o in this.objects) {
+ this.objects[o].draw(paper);
+ }
+ };
+
+
+ var processdata = function(data) {
+ var servermap = {};
+ var servers = data.servers;
+ var count = 0;
+ for (s in servers) {
+ var server = new LogGraph.ServerGraph.server(self, "Server " + servers[s]);
+ servermap[servers[s]] = server;
+ self.add(server);
+ count++;
+ }
+
+ var messages = {};
+ var events = data.events;
+ for (var i in events) {
+ var e = events[i];
+ var t = e.time;
+ if (e.type == "stateChange") {
+ servermap[e.server].addState(e.state, self.ticker.tick(e.time));
+ }
+ if (e.type == "postmessage") {
+ src = servermap[e.src];
+ dst = servermap[e.dst];
+ var key = "key:s" + e.src + ",d" + e.dst + ",z" + e.zxid;
+
+ var m = new LogGraph.ServerGraph.message(self, src, self.ticker.tick(e.time), dst, e.zxid);
+ messages[key] = m;
+ }
+ if (e.type == "delivermessage") {
+ var key = "key:s" + e.src + ",d" + e.dst + ",z" + e.zxid;
+
+ var m = messages[key];
+ if (m) {
+ m.dsttime = self.ticker.tick(e.time);
+ m.name = "Propose";
+ self.add(m);
+ delete messages[key];
+ }
+ }
+ if (e.type == "exception") {
+ servermap[e.server].addException(self.ticker.tick(e.time), e.text, e.time);
+ }
+ count++;
+ }
+
+ for (var i in messages) {
+ var m = messages[i];
+ m.markIncomplete();
+ self.add(m);
+ count++;
+ }
+
+ if (count != 0) {
+ paper.setSize(self.tick_to_x(self.ticker.current()), 1000);
+
+ var line = paper.path("M0 0 L0 1000");
+ line.attr({"stroke": "red", "stroke-dasharray": "- "});
+ var base = canvas.offsetLeft;// + ((canvas.offsetWidth - paper.width)/2);
+ canvas.onmousemove = function (evt) {
+ var x = evt.screenX - base;
+
+ line.attr({"path": "M" + x + " 0 L"+ x +" 1000"});
+
+ };
+
+ self.draw(paper);
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ var uri = "/data?start=" + self.starttime + "&end=" + self.endtime + "&filter=" + filter;
+
+ LogGraph.loadData(asyncq, uri, processdata);
+};
+
+LogGraph.ServerGraph.server = function (graph, name) {
+ this.graph = graph;
+ this.serverid = graph.nextserverid++;
+ this.name = name;
+ this.y = (this.serverid * 300 + graph.serveroffset);
+ this.states = new Array();
+ this.exception = new Array();
+
+ this.addState = function(state, time) {
+ this.states.push([state, time]);
+ }
+
+ this.addException = function(tick, exception, time) {
+ this.exception.push(new LogGraph.ServerGraph.exception(this.graph, tick, exception, time));
+ }
+
+ this.draw = function(paper) {
+ var st = paper.set();
+ st.push(paper.path("M0 " + this.y + " L" + paper.width + " " + this.y));
+ st.push(paper.text(20, this.y - 10, this.name));
+ st.attr({stroke: "gray"});
+
+ var numstates = this.states.length;
+
+ for (s = 0; s < numstates; s++) {
+ var style = {};
+ switch (this.states[s][0]) {
+ case "INIT": style = {stroke: "yellow", "stroke-width":3}; break;
+ case "FOLLOWING": style = {stroke: "lightgreen", "stroke-width":7}; break;
+ case "LEADING": style = {stroke: "green", "stroke-width":10}; break;
+ case "LOOKING": style = {stroke: "orange", "stroke-width":5}; break;
+ }
+ var startx = this.graph.tick_to_x(this.states[s][1]);
+ var endx = s + 1 < numstates ? this.graph.tick_to_x(this.states[(s+1)][1]) : paper.width;
+ var p = paper.path("M" + startx + " " + this.y + " L" + endx + " " + this.y);
+ p.attr(style);
+ }
+
+ for (e in this.exception) {
+ this.exception[e].draw(paper, this);
+ }
+ }
+};
+
+LogGraph.ServerGraph.message = function(graph, src, srctime, dst, zxid) {
+ this.graph = graph;
+ this.src = src;
+ this.srctime = srctime;
+ this.dst = dst;
+ this.dsttime = 0; //dsttime;
+ this.name = "Unknown";
+ this.zxid = zxid;
+ this.moreinfo = "No extra information";
+ this.incomplete = false;
+
+ this.markIncomplete = function() {
+ this.incomplete = true;
+ this.dsttime = this.srctime;
+ }
+
+ this.draw = function(paper) {
+ var srcx = this.graph.tick_to_x(this.srctime);
+ var dstx = this.graph.tick_to_x(this.dsttime);
+
+ var arrow = paper.set();
+ var p = paper.path("M" + srcx + " " + this.src.y + " L" + dstx + " " + this.dst.y);
+ arrow.push(p);
+
+ var tx = (srcx + dstx)/2;
+ var ty = (this.src.y + this.dst.y)/2;
+ var t = paper.text(tx, ty, this.name);
+
+ var gradiant = (this.dst.y - this.src.y)/(dstx - srcx);
+ var angle = Math.atan(gradiant) * 57.2958;
+ t.rotate(angle, true);
+
+ var arrowl = paper.path("M" + dstx + " " + this.dst.y + " L" + (dstx - 10) +" " + this.dst.y);
+ arrowl.rotate(angle + 20, dstx, this.dst.y);
+ arrow.push(arrowl);
+ var arrowr = paper.path("M" + dstx + " " + this.dst.y + " L" + (dstx - 10) +" " + this.dst.y);
+ arrowr.rotate(angle - 20, dstx, this.dst.y);
+ arrow.push(arrowr);
+
+ arrow.attr({"stroke-width": 2, stroke: "gray"});
+ if (this.incomplete) {
+ arrow.attr({"stroke-dasharray": "- .", stroke: "pink", "stroke-width": 2});
+ }
+ arrow.mouseover(function(evt) {
+ t.attr({"font-size": 20});
+ arrow.attr({stroke: "red", "stroke-width": 3});
+ });
+ arrow.mouseout(function(evt) {
+ t.attr({"font-size": 10});
+
+ if (this.incomplete) {
+ arrow.attr({stroke: "pink", "stroke-width": 2});
+ } else {
+ arrow.attr({stroke: "gray", "stroke-width": 2});
+ }
+ });
+
+
+
+ arrow.click(function(evt) {
+ var popup = document.createElement("div");
+ popup.className = "popUp";
+ popup.innerHTML = "zxid: " + parseInt(this.zxid).toString(16);
+
+ popup.style.top = evt.clientY;
+ popup.style.left = evt.clientX;
+ document.body.appendChild(popup);
+
+ popup.onclick = function(evt) {
+ document.body.removeChild(popup);
+ };
+ });
+ }
+};
+
+LogGraph.ServerGraph.exception = function(graph, tick, exceptiontext, time) {
+ this.graph = graph;
+ this.time = time;
+ this.text = exceptiontext;
+ this.tick = tick;
+
+ var self = this;
+
+ this.draw = function(paper, server) {
+ var center = this.graph.tick_to_x(this.tick);
+ var p = paper.circle(center, server.y, 5);
+ p.attr({stroke: "orange", fill: "red"});
+
+ p.mouseover(function(evt) {
+ p.popup = document.createElement("div");
+ p.popup.className = "popUp";
+ p.popup.innerHTML = self.text.replace("\n", "<br/>");;
+ p.popup.style.top = server.y + 50;
+ p.popup.style.left = center + 25;
+ document.body.appendChild(p.popup);
+
+ p.animate({r: 10}, 500, "elastic");
+ });
+ p.mouseout(function(evt) {
+ document.body.removeChild(p.popup);
+ p.animate({r: 5}, 100);
+ });
+ }
+};
+
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.session.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.session.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.session.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.session.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,202 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+LogGraph.SessionGraph = function (asyncq, canvas, starttime, endtime, filter) {
+ this.sessions = new Array();
+ this.counter = 0;
+ this.exceptions = new Array();
+
+ this.pix_per_ticks = 4;
+ this.pix_per_session = 7;
+
+ var paper = Raphael(canvas, 1, 1);
+ this.ticker = new LogGraph.ticker();
+ var self = this;
+
+ this.starttime = starttime;
+ this.endtime = endtime;
+ this.filter = filter;
+
+ this.findOrCreateSession = function(id) {
+ if (this.sessions[id] == undefined) {
+ this.sessions[id] = new LogGraph.SessionGraph.session(this, ++this.counter, id);
+ }
+ return this.sessions[id];
+ }
+
+ this.height = function () { return this.counter * this.pix_per_session + 10; };
+ this.width = function () { return (self.ticker.current() * this.pix_per_ticks); };
+
+ this.draw = function(paper) {
+
+
+ var line = paper.path("M0 0 L0 " + this.height());
+ line.attr({"stroke": "red", "stroke-dasharray": "- "});
+ var base = canvas.offsetLeft;
+ var width = this.width();
+ canvas.onmousemove = function (evt) {
+ var x = evt.clientX - base;
+
+ line.attr({"path": "M" + x + " 0 L" + x + " " + self.height() });
+ };
+
+ for (var i in this.sessions) {
+ var s = this.sessions[i];
+ s.draw(paper);
+ }
+ };
+
+ var processdata = function(data) {
+ var count = 0;
+ for (var i in data.events) {
+ var e = data.events[i];
+ if (e.type == "transaction") {
+ e.tick = self.ticker.tick(e.time, true);
+ var session = self.findOrCreateSession(e.client);
+ session.addEvent(e);
+ count++;
+ }
+ }
+ paper.setSize(self.width(), self.height());
+
+ if (count != 0) {
+ self.draw(paper);
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ var uri = "/data?start=" + self.starttime + "&end=" + self.endtime + "&filter=" + filter;
+
+ LogGraph.loadData(asyncq, uri, processdata);
+};
+
+LogGraph.SessionGraph.sessionevent = function () {
+ this.time = time;
+ this.type = type;
+ this.client = client;
+ this.cxid = cxid;
+ this.zxid = zxid;
+ this.op = op;
+ this.extra = extra;
+};
+
+LogGraph.SessionGraph.sessionEventPopup = function (obj, e, x, y) {
+ obj.click(function(evt) {
+ var popup = document.createElement("div");
+ popup.className = "popUp";
+
+ var closebutton = document.createElement("div");
+ closebutton.className = "closebutton";
+ closebutton.title = "Close popup";
+ closebutton.innerHTML = "×";
+ popup.appendChild(closebutton);
+ closebutton.onclick= function(evt) { popup.style.visibility = "hidden"; document.body.removeChild(popup) };
+ var txt = document.createElement("span");
+ txt.innerHTML = "session: " + e.client + "<br/>op: " + e.op + "<br/>zxid: " + e.zxid + "<br/>time: " + e.time + "<br/>extra: " + e.extra;
+ popup.appendChild(txt);
+
+ popup.style.top = y;
+ popup.style.left = x;
+ document.body.appendChild(popup);
+
+ YUI().use('dd-drag', function(Y) {
+ //Selector of the node to make draggable
+ var dd = new Y.DD.Drag({
+ node: popup
+ });
+ });
+ });
+};
+
+LogGraph.SessionGraph.session = function (graph, index, id) {
+ this.index = index;
+ this.id = id;
+ this.graph = graph;
+
+ this.events = new Array();
+ this.starttick = 0;
+ this.endtick = undefined;
+
+ this.addEvent = function(e) {
+ this.events.push(e);
+
+ if (e.op == "createSession") {
+ // document.write("createSession for " + id.toString(16));
+ this.starttick = e.tick;
+ } else if (e.op == "closeSession") {
+ this.endtick = e.tick;
+ }
+ },
+
+ this._attach_action = function (sess, label) {
+ sess.mouseover(function(evt) {
+ label.show();
+ sess.attr({stroke: "gray"});
+ });
+
+ sess.mouseout(function(evt) {
+ label.hide();
+ sess.attr({stroke: "black"});
+ });
+ },
+
+ this.drawEvent = function (paper, y, e) {
+ var x = e.tick * this.graph.pix_per_ticks;;
+ var s = paper.path("M" + x + " " + (y - 3) + " L" + x + " " + (y + 3));
+ s.attr({"stroke-width": 2});
+ if (e.op == "error") {
+ s.attr({"stroke": "red"});
+ }
+ s.mouseover(function(evt) {
+ s.attr({"stroke-width": 5});
+ });
+
+ s.mouseout(function(evt) {
+ s.attr({"stroke-width": 2});
+ });
+
+ LogGraph.SessionGraph.sessionEventPopup(s, e, x, y);
+ },
+
+ this.draw = function(paper) {
+ var y = this.index*this.graph.pix_per_session;;
+ var start = this.starttick * this.graph.pix_per_ticks;
+ var end = this.endtick * this.graph.pix_per_ticks;
+
+ var sess = paper.set();
+
+ if (this.endtick == undefined) {
+ end = this.graph.width();
+ }
+
+ sess.push(paper.path("M" + start + " " + y + " L" + end + " " + y));
+ for (var i in this.events) {
+ var e = this.events[i];
+ this.drawEvent(paper, y, e);
+ }
+
+ //sess.attr({"stroke-width": 3});
+ label = paper.text(start + 100, y, this.id);
+ label.attr({"font-size": "14px"});
+ label.hide();
+ this._attach_action(sess, label);
+ }
+};
+
Added: hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.stats.js
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.stats.js?rev=953041&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.stats.js (added)
+++ hadoop/zookeeper/trunk/src/contrib/loggraph/web/org/apache/zookeeper/graph/resources/loggraph.stats.js Wed Jun 9 15:26:22 2010
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+LogGraph.StatsGraph = function (asyncq, canvas, starttime, endtime, filter) {
+ var processdata = function(data) {
+ var r = Raphael(canvas);
+ var x = data.map(function (x) { return x.time; });
+ var y = data.map(function (x) { return x.count; });
+ var xlabels = data.map(function (x) { return dateFormat(x.time, "HH:MM:ss,l"); } );
+ var h1 = function () {
+ this.tags = r.set();
+ for (var i = 0, ii = this.y.length; i < ii; i++) {
+ this.tags.push(r.g.tag(this.x, this.y[i], this.values[i], 160, 10).insertBefore(this).attr([{fill: "#fff"}, {fill: this.symbols[i].attr("fill")}]));
+ }
+ };
+ var h2 = function () {
+ this.tags && this.tags.remove();
+ };
+ r.g.linechart(40, 40, 1000, 500, x, y, {shade: true, axis: "0 0 1 1", symbol: "x", southlabels: xlabels, axisxstep: xlabels.length - 1 , westAxisLabel: "Write requests", southAxisLabel: "Time (min)"}).hoverColumn(h1, h2);
+
+ return true;
+ //r.g.barchart(0, 0, 1000, 100, y, {shade: true, symbol: "x"}).hoverColumn(h1, h2);
+ };
+
+ var uri = "/throughput?scale=minutes";
+ LogGraph.loadData(asyncq, uri, processdata);
+};
+
+