From 9a4ae7d85f8330da7cca3fa438792edb491ac703 Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Thu, 10 Dec 2009 23:11:46 +0100 Subject: [PATCH 1/9] a radar graph for g.raphael with basic interaction --- g.radar.js | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 g.radar.js diff --git a/g.radar.js b/g.radar.js new file mode 100644 index 0000000..0bc5530 --- /dev/null +++ b/g.radar.js @@ -0,0 +1,216 @@ +/* + * Radar charts for g.Raphael + * + * Copyright (c) 2009 Silvan T. Golega + * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. + * + * Developed for: + * 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.radar = function (cx, cy, r, values, opts) { + opts = opts || {}; + var paper = this, + chart = this.set(), // the chart that will be constructed and returned + arms = [], // holds the values, their positions, paths, arms, discs + covers = this.set(), // holds the areas for event handling + middle_point, // raphael disc for background mesh + mesh = [], // the background mesh + total = 0, + max = 0, // the maximum of the values + len = values.length, // number of values + web = {pointarray: [], path: null}; // connecting lines between values + + //sectors = [], + //series = this.set(), + //order = [], + //angle = 0, + //others = 0, + //cut = 9, + //defcut = true; + chart.covers = covers; + + // overwrite default values for options with opts + var default_opts = { + meshwidth: 1, + strokewidth: 2, + stroke: "#f90", + meshcolor: "#999", + helplines: 5, + discradius: 5 + }; + for (var property in opts) + default_opts[property] = opts[property]; + opts = default_opts; + delete default_opts; + + // help function for drawing an arm + var arm = function (sx, sy, r, angle, m) { + var rad = Math.PI / 180, + cos = Math.cos(-angle * rad), + sin = Math.sin(-angle * rad), + x = sx + r * cos, + y = sy + r * sin, + ex = sx + m * cos, + ey = sy + m * sin, + res = { + x: x, + y: y, + //start: {x: sx, y: sy}, + //end: {x: ex, y: ey}, + path: ["M", cx, cy, "L", x, y].join(','), + rest: ["M", x, y, "L", ex, ey].join(','), + }; + return res; + } + + // determine the max value + for (var i = 0; i < len; i++) { + total += values[i]; + max = max>values[i] ? max : values[i]; + } + + // draw middle point and mesh circles + middle_point = this.g.disc(cx, cy, 5).attr({stroke: opts.meshcolor, fill: opts.meshcolor, "stroke-width": opts.meshwidth}); + if (opts.helplines){ + var helpradius = r / opts.helplines; + for (var i = 0; i < opts.helplines; i++) { + mesh[i] = this.circle(cx, cy, helpradius*(i+1)).attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); + } + } + + // draw the arms + for (var i = 0; i < len; i++) { + arms[i] = arm(cx, cy, r * values[i] / max, i * 360 / len, r); + arms[i].path = this.path(arms[i].path) + .attr({stroke: opts.stroke, "stroke-width": opts.strokewidth}); + arms[i].rest = this.path(arms[i].rest) + .attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); + } + + // draw a poligon through the value points + web.pointarray.push("M"); + for (var i = 0; i < len; i++) { + web.pointarray.push(arms[i].x, arms[i].y, "L"); + } + web.pointarray.push(arms[0].x, arms[0].y); + web.path = this.path(web.pointarray.join(',')).attr({stroke: opts.stroke, "stroke-width": opts.meshwidth, fill: opts.stroke, "fill-opacity": 0.4}); + + // draw the value points as latest to make sure they are the topmost + for (var i = 0; i < len; i++) { + arms[i].point = this.g.disc(arms[i].x, arms[i].y, opts.discradius) + .attr({stroke: opts.stroke, fill: opts.stroke }); + covers.push(arms[i].point); + } + + chart.hover = function (fin, fout) { + fout = fout || function () {}; + var that = this; + for (var i = 0; i < len; i++) { + (function (arm, cover, j) { + var o = { + arm: arm.point, + cover: cover, + cx: cx, + cy: cy, + mx: arm.x, + my: arm.y, + value: values[j], + max: max, + label: that.labels && that.labels[j] + }; + cover.mouseover(function () { + fin.call(o); + }).mouseout(function () { + fout.call(o); + }); + })(arms[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 (arm, cover, j) { + var o = { + arm: arm.point, + cover: cover, + cx: cx, + cy: cy, + x: arm.x, + y: arm.y, + value: values[j], + max: max, + label: that.labels && that.labels[j] + }; + f.call(o); + })(arms[i], covers[i], i); + } + return this; + }; + + chart.click = function (f) { + var that = this; + for (var i = 0; i < len; i++) { + (function (arm, cover, j) { + var o = { + arm: arm.point, + cover: cover, + cx: cx, + cy: cy, + mx: arm.x, + my: arm.y, + value: values[j], + max: max, + label: that.labels && that.labels[j] + }; + cover.click(function () { f.call(o); }); + })(arms[i], covers[i], i); + } + return this; + }; + + /* 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; +}; From 81d142f542dd47c96f1159bb5e8978ad75ca42d2 Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Thu, 10 Dec 2009 23:14:11 +0100 Subject: [PATCH 2/9] a simple sample for the radar graph --- test-radar.html | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 test-radar.html diff --git a/test-radar.html b/test-radar.html new file mode 100644 index 0000000..11c18e9 --- /dev/null +++ b/test-radar.html @@ -0,0 +1,54 @@ + + + + gRaphaël Static Radar Chart + + + + + + + +
+ + From a3a3f2b43a131bbf23e4b446d8c0b94f4c26f43c Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Mon, 14 Dec 2009 13:18:51 +0100 Subject: [PATCH 3/9] legend (labels) --- g.radar.js | 60 ++++++++++++++++++++++++++++--------------------- test-radar.html | 16 +++++++++++-- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/g.radar.js b/g.radar.js index 0bc5530..d71db16 100644 --- a/g.radar.js +++ b/g.radar.js @@ -13,24 +13,17 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { opts = opts || {}; var paper = this, - chart = this.set(), // the chart that will be constructed and returned arms = [], // holds the values, their positions, paths, arms, discs + chart = this.set(), // the chart that will be constructed and returned covers = this.set(), // holds the areas for event handling + series = this.set(), middle_point, // raphael disc for background mesh - mesh = [], // the background mesh + mesh = this.set(), // the background mesh total = 0, max = 0, // the maximum of the values len = values.length, // number of values web = {pointarray: [], path: null}; // connecting lines between values - //sectors = [], - //series = this.set(), - //order = [], - //angle = 0, - //others = 0, - //cut = 9, - //defcut = true; - chart.covers = covers; // overwrite default values for options with opts var default_opts = { @@ -77,19 +70,15 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { if (opts.helplines){ var helpradius = r / opts.helplines; for (var i = 0; i < opts.helplines; i++) { - mesh[i] = this.circle(cx, cy, helpradius*(i+1)).attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); + mesh.push(this.circle(cx, cy, helpradius*(i+1)).attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth})); } } - // draw the arms + // calculate the arms for (var i = 0; i < len; i++) { arms[i] = arm(cx, cy, r * values[i] / max, i * 360 / len, r); - arms[i].path = this.path(arms[i].path) - .attr({stroke: opts.stroke, "stroke-width": opts.strokewidth}); - arms[i].rest = this.path(arms[i].rest) - .attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); } - + // draw a poligon through the value points web.pointarray.push("M"); for (var i = 0; i < len; i++) { @@ -98,11 +87,18 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { web.pointarray.push(arms[0].x, arms[0].y); web.path = this.path(web.pointarray.join(',')).attr({stroke: opts.stroke, "stroke-width": opts.meshwidth, fill: opts.stroke, "fill-opacity": 0.4}); - // draw the value points as latest to make sure they are the topmost + // draw the value points (and arms) as latest to make sure they are the topmost for (var i = 0; i < len; i++) { + arms[i].path = this.path(arms[i].path) + .attr({stroke: opts.stroke, "stroke-width": opts.strokewidth}); + arms[i].rest = this.path(arms[i].rest) + .attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); arms[i].point = this.g.disc(arms[i].x, arms[i].y, opts.discradius) .attr({stroke: opts.stroke, fill: opts.stroke }); - covers.push(arms[i].point); + var cover = this.set(); + cover.push(arms[i].path, arms[i].rest, arms[i].point); + covers.push(cover); + series.push(arms[i].point); } chart.hover = function (fin, fout) { @@ -121,11 +117,18 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { max: max, label: that.labels && that.labels[j] }; - cover.mouseover(function () { + o.cover.mouseover(function () { fin.call(o); }).mouseout(function () { fout.call(o); }); + if (o.label){ + o.label.mouseover(function () { + fin.call(o); + }).mouseout(function () { + fout.call(o); + }); + } })(arms[i], covers[i], i); } return this; @@ -171,12 +174,17 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { label: that.labels && that.labels[j] }; cover.click(function () { f.call(o); }); + if (o.label){ + o.label.click(function () { + f.call(o); + }); + } })(arms[i], covers[i], i); } return this; }; - /* var legend = function (labels, otherslabel, mark, dir) { + var legend = function (labels, otherslabel, mark, dir) { var x = cx + r + r / 5, y = cy, h = y + 10; @@ -186,13 +194,13 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { chart.labels = paper.set(); for (var i = 0; i < len; i++) { var clr = series[i].attr("fill"), - j = values[i].order, + //j = values[i].order, txt; values[i].others && (labels[j] = otherslabel || "Others"); - labels[j] = paper.g.labelise(labels[j], values[i], total); + labels[i] = paper.g.labelise(labels[i], 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"})); + chart.labels[i].push(txt = paper.text(x + 20, h, labels[i] || values[i]).attr(paper.g.txtattr).attr({fill: opts.legendcolor || "#000", "text-anchor": "start"})); covers[i].label = chart.labels[i]; h += txt.getBBox().height * 1.2; } @@ -209,8 +217,8 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { if (opts.legend) { legend(opts.legend, opts.legendothers, opts.legendmark, opts.legendpos); } - chart.push(series, covers); + chart.push(series, covers, middle_point, mesh); chart.series = series; chart.covers = covers; -*/ return chart; + return chart; }; diff --git a/test-radar.html b/test-radar.html index 11c18e9..7c2c6d8 100644 --- a/test-radar.html +++ b/test-radar.html @@ -24,17 +24,29 @@ [35, 37, 16, 20, 40, 13, 32, 25, 42, 20 ], { stroke: "#09f", helplines: 4, - discradius: 6 + discradius: 6, + legend: ["Tolle Sache", "Spitze", "Weiß nicht "], + href: ["http://raphaeljs.com", "http://g.raphaeljs.com"] }); anim_radar.hover(function () { this.arm.stop(); this.arm.animate({scale: [3, 3, this.mx, this.my]}, 500); + //this.arm.scale(3); + if (this.label) { + this.label[0].stop(); + this.label[0].scale(2); + this.label[1].attr({"font-weight": 1200}); + } }, function () { anim_radar.each(function () { this.arm.stop(); this.arm.animate({scale: [1, 1, this.mx, this.my]}, 500); }); + if (this.label) { + this.label[0].animate({scale: 1}, 500, "bounce"); + this.label[1].attr({"font-weight": 400}); + } }); anim_radar.click(function () { @@ -49,6 +61,6 @@ -
+
From 1068b54d59bc681e734c4262e94e257619a8c6c5 Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Mon, 14 Dec 2009 13:28:58 +0100 Subject: [PATCH 4/9] naming issue --- g.radar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g.radar.js b/g.radar.js index d71db16..fb2ea20 100644 --- a/g.radar.js +++ b/g.radar.js @@ -146,8 +146,8 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { cover: cover, cx: cx, cy: cy, - x: arm.x, - y: arm.y, + mx: arm.x, + my: arm.y, value: values[j], max: max, label: that.labels && that.labels[j] From 861066734453787da57c8639bde1de611f8c939d Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Mon, 14 Dec 2009 13:30:37 +0100 Subject: [PATCH 5/9] naaming issue --- g.radar.js | 4 ++-- test-radar.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/g.radar.js b/g.radar.js index fb2ea20..d71db16 100644 --- a/g.radar.js +++ b/g.radar.js @@ -146,8 +146,8 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { cover: cover, cx: cx, cy: cy, - mx: arm.x, - my: arm.y, + x: arm.x, + y: arm.y, value: values[j], max: max, label: that.labels && that.labels[j] diff --git a/test-radar.html b/test-radar.html index 7c2c6d8..2db4261 100644 --- a/test-radar.html +++ b/test-radar.html @@ -41,7 +41,7 @@ }, function () { anim_radar.each(function () { this.arm.stop(); - this.arm.animate({scale: [1, 1, this.mx, this.my]}, 500); + this.arm.animate({scale: [1, 1, this.x, this.y]}, 500); }); if (this.label) { this.label[0].animate({scale: 1}, 500, "bounce"); From a5bf8497a42dda78fb48e5135941adb92d70eae8 Mon Sep 17 00:00:00 2001 From: "Silvan T. Golega" Date: Sat, 16 Jan 2010 16:25:34 +0100 Subject: [PATCH 6/9] The values are now numbered and can get titles in the legend --- g.radar.js | 29 +++++++++++++++++++++-------- test-radar.html | 25 +++++++++++++------------ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/g.radar.js b/g.radar.js index d71db16..ef7fb12 100644 --- a/g.radar.js +++ b/g.radar.js @@ -27,12 +27,14 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { // overwrite default values for options with opts var default_opts = { - meshwidth: 1, - strokewidth: 2, - stroke: "#f90", - meshcolor: "#999", - helplines: 5, - discradius: 5 + meshwidth: 1, + strokewidth: 2, + stroke: "#f90", + meshcolor: "#999", + helplines: 5, + discradius: 10, + numbers: true, + numberscolor: "#fff" }; for (var property in opts) default_opts[property] = opts[property]; @@ -95,11 +97,17 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { .attr({stroke: opts.meshcolor, "stroke-width": opts.meshwidth}); arms[i].point = this.g.disc(arms[i].x, arms[i].y, opts.discradius) .attr({stroke: opts.stroke, fill: opts.stroke }); + if(opts.numbers){ + arms[i].number = this.text(arms[i].x, arms[i].y+1, i+1).attr(this.g.txtattr).attr({fill: opts.numberscolor, "text-anchor": "middle"}); + } var cover = this.set(); cover.push(arms[i].path, arms[i].rest, arms[i].point); + if (arms[i].number) + cover.push(arms[i].number); covers.push(cover); series.push(arms[i].point); } + chart.hover = function (fin, fout) { fout = fout || function () {}; @@ -108,6 +116,7 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { (function (arm, cover, j) { var o = { arm: arm.point, + number: arm.number, cover: cover, cx: cx, cy: cy, @@ -143,6 +152,7 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { (function (arm, cover, j) { var o = { arm: arm.point, + number: arm.number, cover: cover, cx: cx, cy: cy, @@ -164,6 +174,7 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { (function (arm, cover, j) { var o = { arm: arm.point, + number: arm.number, cover: cover, cx: cx, cy: cy, @@ -194,13 +205,15 @@ Raphael.fn.g.radar = function (cx, cy, r, values, opts) { 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[i] = paper.g.labelise(labels[i], 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(paper.g[mark](x + 5, h, 8).attr({fill: clr, stroke: "none"})); chart.labels[i].push(txt = paper.text(x + 20, h, labels[i] || values[i]).attr(paper.g.txtattr).attr({fill: opts.legendcolor || "#000", "text-anchor": "start"})); + if(opts.numbers){ + chart.labels[i].push(paper.text(x+5, h+1, i+1).attr(paper.g.txtattr).attr({fill: opts.numberscolor, "text-anchor": "middle"})); + } covers[i].label = chart.labels[i]; h += txt.getBBox().height * 1.2; } diff --git a/test-radar.html b/test-radar.html index 2db4261..278df63 100644 --- a/test-radar.html +++ b/test-radar.html @@ -15,7 +15,8 @@ static_radar = r.g.radar( 320, 240, 200, - [35, 20, 13, 32, 25, 40, 37, 16, 42] + [35, 20, 13, 32, 25, 40, 37, 16, 42], + {discradius: 8, numbers: false} ); r.g.text(960, 20, "Animated Radar Chart").attr({"font-size": 20}); @@ -24,38 +25,38 @@ [35, 37, 16, 20, 40, 13, 32, 25, 42, 20 ], { stroke: "#09f", helplines: 4, - discradius: 6, - legend: ["Tolle Sache", "Spitze", "Weiß nicht "], + discradius: 10, + legend: ["Value number one", "A second value", "And a third one", + "Always give meaningful titles", "Don't you think?", "This legend rocks!"], href: ["http://raphaeljs.com", "http://g.raphaeljs.com"] }); anim_radar.hover(function () { this.arm.stop(); - this.arm.animate({scale: [3, 3, this.mx, this.my]}, 500); - //this.arm.scale(3); + this.arm.animate({scale: [2, 2, this.mx, this.my]}, 500); + this.number.animate({"font-size": 20}, 500); if (this.label) { this.label[0].stop(); this.label[0].scale(2); - this.label[1].attr({"font-weight": 1200}); + this.label[1].attr({"font-weight": "bold"}); + this.label[2].attr({"font-size": 20}); } }, function () { anim_radar.each(function () { this.arm.stop(); this.arm.animate({scale: [1, 1, this.x, this.y]}, 500); + this.number.animate({"font-size": 12}, 500); }); if (this.label) { this.label[0].animate({scale: 1}, 500, "bounce"); - this.label[1].attr({"font-weight": 400}); + this.label[1].attr({"font-weight": "normal"}); + this.label[2].attr({"font-size": 12}); } }); anim_radar.click(function () { - //this.arm.animate({scale: [5, 1, this.mx, this.my], cx: this.cx, cy: this.cy}, 500); this.arm.stop(); - anim_radar.each(function () { - this.arm.stop(); - this.arm.animate({scale: [this.value/5, this.value/5, this.mx, this.my]}, 500); - }); + window.location.href = ""; }); }; From 3c24968e0098c2163fcb034f84f38d69594e6b8a Mon Sep 17 00:00:00 2001 From: Dmitry Baranovskiy Date: Thu, 3 Jun 2010 06:16:01 +0800 Subject: [PATCH 7/9] 0.4.1 Bug fixes --- g.bar-min.js | 4 +- g.bar.js | 13 ++--- g.dot-min.js | 2 +- g.dot.js | 4 +- g.line-min.js | 2 +- g.line.js | 4 +- g.pie-min.js | 8 +-- g.pie.js | 12 ++--- g.raphael-min.js | 4 +- g.raphael.js | 129 +++++++++++++++++++++++------------------------ 10 files changed, 88 insertions(+), 94 deletions(-) diff --git a/g.bar-min.js b/g.bar-min.js index df821b4..3556bd0 100644 --- a/g.bar-min.js +++ b/g.bar-min.js @@ -1,7 +1,7 @@ /* - * g.Raphael 0.4 - Charting library, based on Raphaël + * g.Raphael 0.4.1 - 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.barchart=function(C,A,a,d,O,u){u=u||{};var P={round:"round",sharp:"sharp",soft:"soft"}[u.type]||"square",n=parseFloat(u.gutter||"20%"),M=this.set(),v=this.set(),e=this.set(),r=this.set(),w=Math.max.apply(Math,O),N=[],c=this,B=0,F=u.colors||this.g.colors,q=O.length;if(this.raphael.is(O[0],"array")){w=[];B=q;q=0;for(var K=O.length;K--;){v.push(this.set());w.push(Math.max.apply(Math,O[K]));q=Math.max(q,O[K].length);}if(u.stacked){for(var K=q;K--;){var l=0;for(var J=O.length;J--;){l+=+O[J][K]||0;}N.push(l);}}for(var K=O.length;K--;){if(O[K].length180),1,p,K,"z"];I.middle={x:G,y:C};return I;}for(var v=0;vc){y=false;b[c].value+=b[v];b[c].others=true;z=b[c].value;}}w=Math.min(c+1,b.length);z&&b.splice(w)&&(b[c].others=true);for(var v=0;v");}for(var v=0;v180),1,p,K,"z"];I.middle={x:G,y:C};return I;}for(var v=0;vc){y=false;b[c].value+=b[v];b[c].others=true;z=b[c].value;}}w=Math.min(c+1,b.length);z&&b.splice(w)&&(b[c].others=true);for(v=0;v");}for(v=0;v"); } - for (var i = 0; i < len; i++) { - var p = paper.path(sectors[i].attr("path")).attr(this.g.shim); + for (i = 0; i < len; i++) { + 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); diff --git a/g.raphael-min.js b/g.raphael-min.js index a9900b6..1dba168 100644 --- a/g.raphael-min.js +++ b/g.raphael-min.js @@ -1,7 +1,7 @@ /* - * g.Raphael 0.4 - Charting library, based on Raphaël + * g.Raphael 0.4.1 - 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 b=[0.6,0.2,0.05,0.1333,0.75,0];for(var a=0;a<10;a++){if(a=g*2){this[0].attr({path:["M",c,k+g,"a",g,g,0,1,1,0,-g*2,g,g,0,1,1,0,g*2,"m",0,-g*2-h,"a",g+h,g+h,0,1,0,0,(g+h)*2,"L",c+g+h,k+m.height/2+h,"l",m.width+2*h,0,0,-m.height-2*h,-m.width-2*h,0,"L",c,k-g-h].join(",")});}else{var l=Math.sqrt(Math.pow(g+h,2)-Math.pow(m.height/2+h,2));this[0].attr({path:["M",c,k+g,"c",-f,0,-g,f-g,-g,-g,0,-f,g-f,-g,g,-g,f,0,g,g-f,g,g,0,f,f-g,g,-g,g,"M",c+l,k-m.height/2-h,"a",g+h,g+h,0,1,0,0,m.height+2*h,"l",g+h-l+m.width+2*h,0,0,-m.height-2*h,"L",c+l,k-m.height/2-h].join(",")});}this[1].attr({x:c+g+h+m.width/2,y:k});i=(360-i)%360;this.rotate(i,c,k);i>90&&i<270&&this[1].attr({x:c-g-h-m.width/2,y:k,rotation:[180+i,c,k]});return this;};e.update();return e;};Raphael.fn.g.popupit=function(j,i,k,e,q){e=e==null?2:e;q=q||5;j=Math.round(j)+0.5;i=Math.round(i)+0.5;var g=k.getBBox(),l=Math.round(g.width/2),f=Math.round(g.height/2),o=[0,l+q*2,0,-l-q*2],m=[-f*2-q*3,-f-q,0,-f-q],c=["M",j-o[e],i-m[e],"l",-q,(e==2)*-q,-Math.max(l-q,0),0,"a",q,q,0,0,1,-q,-q,"l",0,-Math.max(f-q,0),(e==3)*-q,-q,(e==3)*q,-q,0,-Math.max(f-q,0),"a",q,q,0,0,1,q,-q,"l",Math.max(l-q,0),0,q,!e*-q,q,!e*q,Math.max(l-q,0),0,"a",q,q,0,0,1,q,q,"l",0,Math.max(f-q,0),(e==1)*q,q,(e==1)*-q,q,0,Math.max(f-q,0),"a",q,q,0,0,1,-q,q,"l",-Math.max(l-q,0),0,"z"].join(","),n=[{x:j,y:i+q*2+f},{x:j-q*2-l,y:i},{x:j,y:i-q*2-f},{x:j+q*2+l,y:i}][e];k.translate(n.x-l-g.x,n.y-f-g.y);return this.path(c).attr({fill:"#000",stroke:"none"}).insertBefore(k.node?k:k[0]);};Raphael.fn.g.popup=function(c,j,i,e,g){e=e==null?2:e;g=g||5;i=i||"$9.99";var f=this.set(),h=3;f.push(this.path().attr({fill:"#000",stroke:"none"}));f.push(this.text(c,j,i).attr(this.g.txtattr).attr({fill:"#fff"}));f.update=function(m,l,n){m=m||c;l=l||j;var q=this[1].getBBox(),s=q.width/2,o=q.height/2,v=[0,s+g*2,0,-s-g*2],t=[-o*2-g*3,-o-g,0,-o-g],k=["M",m-v[e],l-t[e],"l",-g,(e==2)*-g,-Math.max(s-g,0),0,"a",g,g,0,0,1,-g,-g,"l",0,-Math.max(o-g,0),(e==3)*-g,-g,(e==3)*g,-g,0,-Math.max(o-g,0),"a",g,g,0,0,1,g,-g,"l",Math.max(s-g,0),0,g,!e*-g,g,!e*g,Math.max(s-g,0),0,"a",g,g,0,0,1,g,g,"l",0,Math.max(o-g,0),(e==1)*g,g,(e==1)*-g,g,0,Math.max(o-g,0),"a",g,g,0,0,1,-g,g,"l",-Math.max(s-g,0),0,"z"].join(","),u=[{x:m,y:l+g*2+o},{x:m-g*2-s,y:l},{x:m,y:l-g*2-o},{x:m+g*2+s,y:l}][e];if(n){this[0].animate({path:k},500,">");this[1].animate(u,500,">");}else{this[0].attr({path:k});this[1].attr(u);}return this;};return f.update(c,j);};Raphael.fn.g.flag=function(c,i,h,g){g=g||0;h=h||"$9.99";var e=this.set(),f=3;e.push(this.path().attr({fill:"#000",stroke:"none"}));e.push(this.text(c,i,h).attr(this.g.txtattr).attr({fill:"#fff"}));e.update=function(j,m){this.rotate(0,j,m);var l=this[1].getBBox(),k=l.height/2;this[0].attr({path:["M",j,m,"l",k+f,-k-f,l.width+2*f,0,0,l.height+2*f,-l.width-2*f,0,"z"].join(",")});this[1].attr({x:j+k+f+l.width/2,y:m});g=360-g;this.rotate(g,j,m);g>90&&g<270&&this[1].attr({x:j-r-f-l.width/2,y:m,rotation:[180+g,j,m]});return this;};return e.update(c,i);};Raphael.fn.g.label=function(c,g,f){var e=this.set();e.push(this.rect(c,g,10,10).attr({stroke:"none",fill:"#000"}));e.push(this.text(c,g,f).attr(this.g.txtattr).attr({fill:"#fff"}));e.update=function(){var i=this[1].getBBox(),h=Math.min(i.width+10,i.height+10)/2;this[0].attr({x:i.x-h/2,y:i.y-h/2,width:i.width+h,height:i.height+h,r:h});};e.update();return e;};Raphael.fn.g.labelit=function(f){var e=f.getBBox(),c=Math.min(20,e.width+10,e.height+10)/2;return this.rect(e.x-c/2,e.y-c/2,e.width+c,e.height+c,c).attr({stroke:"none",fill:"#000"}).insertBefore(f[0]);};Raphael.fn.g.drop=function(c,i,h,f,g){f=f||30;g=g||0;var e=this.set();e.push(this.path(["M",c,i,"l",f,0,"A",f*0.4,f*0.4,0,1,0,c+f*0.7,i-f*0.7,"z"]).attr({fill:"#000",stroke:"none",rotation:[22.5-g,c,i]}));g=(g+90)*Math.PI/180;e.push(this.text(c+f*Math.sin(g),i+f*Math.cos(g),h).attr(this.g.txtattr).attr({"font-size":f*12/30,fill:"#fff"}));e.drop=e[0];e.text=e[1];return e;};Raphael.fn.g.blob=function(e,k,j,i,g){i=(+i+1?i:45)+90;g=g||12;var c=Math.PI/180,h=g*12/12;var f=this.set();f.push(this.path().attr({fill:"#000",stroke:"none"}));f.push(this.text(e+g*Math.sin((i)*c),k+g*Math.cos((i)*c)-h/2,j).attr(this.g.txtattr).attr({"font-size":h,fill:"#fff"}));f.update=function(q,p,v){q=q||e;p=p||k;var y=this[1].getBBox(),B=Math.max(y.width+h,g*25/12),x=Math.max(y.height+h,g*25/12),m=q+g*Math.sin((i-22.5)*c),z=p+g*Math.cos((i-22.5)*c),o=q+g*Math.sin((i+22.5)*c),A=p+g*Math.cos((i+22.5)*c),D=(o-m)/2,C=(A-z)/2,n=B/2,l=x/2,u=-Math.sqrt(Math.abs(n*n*l*l-n*n*C*C-l*l*D*D)/(n*n*C*C+l*l*D*D)),t=u*n*C/l+(o+m)/2,s=u*-l*D/n+(A+z)/2;if(v){this.animate({x:t,y:s,path:["M",e,k,"L",o,A,"A",n,l,0,1,1,m,z,"z"].join(",")},500,">");}else{this.attr({x:t,y:s,path:["M",e,k,"L",o,A,"A",n,l,0,1,1,m,z,"z"].join(",")});}return this;};f.update(e,k);return f;};Raphael.fn.g.colorValue=function(g,f,e,c){return"hsb("+[Math.min((1-g/f)*0.4,1),e||0.75,c||0.75]+")";};Raphael.fn.g.snapEnds=function(l,m,k){var h=l,n=m;if(h==n){return{from:h,to:n,power:0};}function o(f){return Math.abs(f-0.5)<0.25?Math.floor(f)+0.5:Math.round(f);}var j=(n-h)/k,c=Math.floor(j),g=c,e=0;if(c){while(g){e--;g=Math.floor(j*Math.pow(10,e))/Math.pow(10,e);}e++;}else{while(!c){e=e||1;c=Math.floor(j*Math.pow(10,e))/Math.pow(10,e);e++;}e&&e--;}var n=o(m*Math.pow(10,e))/Math.pow(10,e);if(n0?0:0.5))*Math.pow(10,e))/Math.pow(10,e);return{from:h,to:n,power:e};};Raphael.fn.g.axis=function(s,q,m,E,h,H,k,J,l,c){c=c==null?2:c;l=l||"t";H=H||10;var D=l=="|"||l==" "?["M",s+0.5,q,"l",0,0.001]:k==1||k==3?["M",s+0.5,q,"l",0,-m]:["M",s,q+0.5,"l",m,0],v=this.g.snapEnds(E,h,H),I=v.from,z=v.to,G=v.power,F=0,A=this.set();d=(z-I)/H;var p=I,o=G>0?G:0;u=m/H;if(+k==1||+k==3){var e=q,w=(k-1?1:-1)*(c+3+!!(k-1));while(e>=q-m){l!="-"&&l!=" "&&(D=D.concat(["M",s-(l=="+"||l=="|"?c:!(k-1)*c*2),e+0.5,"l",c*2+1,0]));A.push(this.text(s+w,e,(J&&J[F++])||(Math.round(p)==p?p:+p.toFixed(o))).attr(this.g.txtattr).attr({"text-anchor":k-1?"start":"end"}));p+=d;e-=u;}if(Math.round(e+u-(q-m))){l!="-"&&l!=" "&&(D=D.concat(["M",s-(l=="+"||l=="|"?c:!(k-1)*c*2),q-m+0.5,"l",c*2+1,0]));A.push(this.text(s+w,q-m,(J&&J[F])||(Math.round(p)==p?p:+p.toFixed(o))).attr(this.g.txtattr).attr({"text-anchor":k-1?"start":"end"}));}}else{var g=s,p=I,o=G>0?G:0,w=(k?-1:1)*(c+9+!k),u=m/H,B=0,C=0;while(g<=s+m){l!="-"&&l!=" "&&(D=D.concat(["M",g+0.5,q-(l=="+"?c:!!k*c*2),"l",0,c*2+1]));A.push(B=this.text(g,q+w,(J&&J[F++])||(Math.round(p)==p?p:+p.toFixed(o))).attr(this.g.txtattr));var n=B.getBBox();if(C>=n.x-5){A.pop(A.length-1).remove();}else{C=n.x+n.width;}p+=d;g+=u;}if(Math.round(g-u-s-m)){l!="-"&&l!=" "&&(D=D.concat(["M",s+m+0.5,q-(l=="+"?c:!!k*c*2),"l",0,c*2+1]));A.push(this.text(s+m,q+w,(J&&J[F])||(Math.round(p)==p?p:+p.toFixed(o))).attr(this.g.txtattr));}}var K=this.path(D);K.text=A;K.all=this.set([K,A]);K.remove=function(){this.text.remove();this.constructor.prototype.remove.call(this);};return K;};Raphael.el.lighter=function(e){e=e||2;var c=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[c[0],c[1]];c[0]=Raphael.rgb2hsb(Raphael.getRGB(c[0]).hex);c[1]=Raphael.rgb2hsb(Raphael.getRGB(c[1]).hex);c[0].b=Math.min(c[0].b*e,1);c[0].s=c[0].s/e;c[1].b=Math.min(c[1].b*e,1);c[1].s=c[1].s/e;this.attr({fill:"hsb("+[c[0].h,c[0].s,c[0].b]+")",stroke:"hsb("+[c[1].h,c[1].s,c[1].b]+")"});};Raphael.el.darker=function(e){e=e||2;var c=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[c[0],c[1]];c[0]=Raphael.rgb2hsb(Raphael.getRGB(c[0]).hex);c[1]=Raphael.rgb2hsb(Raphael.getRGB(c[1]).hex);c[0].s=Math.min(c[0].s*e,1);c[0].b=c[0].b/e;c[1].s=Math.min(c[1].s*e,1);c[1].b=c[1].b/e;this.attr({fill:"hsb("+[c[0].h,c[0].s,c[0].b]+")",stroke:"hsb("+[c[1].h,c[1].s,c[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 +(function(){var a=Math.max,c=Math.min;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 e=[0.6,0.2,0.05,0.1333,0.75,0];for(var b=0;b<10;b++){if(b=i*2){this[0].attr({path:["M",f,m+i,"a",i,i,0,1,1,0,-i*2,i,i,0,1,1,0,i*2,"m",0,-i*2-j,"a",i+j,i+j,0,1,0,0,(i+j)*2,"L",f+i+j,m+o.height/2+j,"l",o.width+2*j,0,0,-o.height-2*j,-o.width-2*j,0,"L",f,m-i-j].join(",")});}else{var n=Math.sqrt(Math.pow(i+j,2)-Math.pow(o.height/2+j,2));this[0].attr({path:["M",f,m+i,"c",-h,0,-i,h-i,-i,-i,0,-h,i-h,-i,i,-i,h,0,i,i-h,i,i,0,h,h-i,i,-i,i,"M",f+n,m-o.height/2-j,"a",i+j,i+j,0,1,0,0,o.height+2*j,"l",i+j-n+o.width+2*j,0,0,-o.height-2*j,"L",f+n,m-o.height/2-j].join(",")});}this[1].attr({x:f+i+j+o.width/2,y:m});k=(360-k)%360;this.rotate(k,f,m);k>90&&k<270&&this[1].attr({x:f-i-j-o.width/2,y:m,rotation:[180+k,f,m]});return this;};g.update();return g;};Raphael.fn.g.popupit=function(l,k,m,g,t){g=g==null?2:g;t=t||5;l=Math.round(l);k=Math.round(k);var j=m.getBBox(),n=Math.round(j.width/2),i=Math.round(j.height/2),s=[0,n+t*2,0,-n-t*2],o=[-i*2-t*3,-i-t,0,-i-t],f=["M",l-s[g],k-o[g],"l",-t,(g==2)*-t,-a(n-t,0),0,"a",t,t,0,0,1,-t,-t,"l",0,-a(i-t,0),(g==3)*-t,-t,(g==3)*t,-t,0,-a(i-t,0),"a",t,t,0,0,1,t,-t,"l",a(n-t,0),0,t,!g*-t,t,!g*t,a(n-t,0),0,"a",t,t,0,0,1,t,t,"l",0,a(i-t,0),(g==1)*t,t,(g==1)*-t,t,0,a(i-t,0),"a",t,t,0,0,1,-t,t,"l",-a(n-t,0),0,"z"].join(","),q=[{x:l,y:k+t*2+i},{x:l-t*2-n,y:k},{x:l,y:k-t*2-i},{x:l+t*2+n,y:k}][g];m.translate(q.x-n-j.x,q.y-i-j.y);return this.path(f).attr({fill:"#000",stroke:"none"}).insertBefore(m.node?m:m[0]);};Raphael.fn.g.popup=function(f,l,k,g,i){g=g==null?2:g>3?3:g;i=i||5;k=k||"$9.99";var h=this.set(),j=3;h.push(this.path().attr({fill:"#000",stroke:"#000"}));h.push(this.text(f,l,k).attr(this.g.txtattr).attr({fill:"#fff","font-family":"Helvetica, Arial"}));h.update=function(o,n,q){o=o||f;n=n||l;var t=this[1].getBBox(),u=t.width/2,s=t.height/2,y=[0,u+i*2,0,-u-i*2],v=[-s*2-i*3,-s-i,0,-s-i],m=["M",o-y[g],n-v[g],"l",-i,(g==2)*-i,-a(u-i,0),0,"a",i,i,0,0,1,-i,-i,"l",0,-a(s-i,0),(g==3)*-i,-i,(g==3)*i,-i,0,-a(s-i,0),"a",i,i,0,0,1,i,-i,"l",a(u-i,0),0,i,!g*-i,i,!g*i,a(u-i,0),0,"a",i,i,0,0,1,i,i,"l",0,a(s-i,0),(g==1)*i,i,(g==1)*-i,i,0,a(s-i,0),"a",i,i,0,0,1,-i,i,"l",-a(u-i,0),0,"z"].join(","),x=[{x:o,y:n+i*2+s},{x:o-i*2-u,y:n},{x:o,y:n-i*2-s},{x:o+i*2+u,y:n}][g];x.path=m;if(q){this.animate(x,500,">");}else{this.attr(x);}return this;};return h.update(f,l);};Raphael.fn.g.flag=function(f,k,j,i){i=i||0;j=j||"$9.99";var g=this.set(),h=3;g.push(this.path().attr({fill:"#000",stroke:"#000"}));g.push(this.text(f,k,j).attr(this.g.txtattr).attr({fill:"#fff","font-family":"Helvetica, Arial"}));g.update=function(l,o){this.rotate(0,l,o);var n=this[1].getBBox(),m=n.height/2;this[0].attr({path:["M",l,o,"l",m+h,-m-h,n.width+2*h,0,0,n.height+2*h,-n.width-2*h,0,"z"].join(",")});this[1].attr({x:l+m+h+n.width/2,y:o});i=360-i;this.rotate(i,l,o);i>90&&i<270&&this[1].attr({x:l-r-h-n.width/2,y:o,rotation:[180+i,l,o]});return this;};return g.update(f,k);};Raphael.fn.g.label=function(f,i,h){var g=this.set();g.push(this.rect(f,i,10,10).attr({stroke:"none",fill:"#000"}));g.push(this.text(f,i,h).attr(this.g.txtattr).attr({fill:"#fff"}));g.update=function(){var k=this[1].getBBox(),j=c(k.width+10,k.height+10)/2;this[0].attr({x:k.x-j/2,y:k.y-j/2,width:k.width+j,height:k.height+j,r:j});};g.update();return g;};Raphael.fn.g.labelit=function(h){var g=h.getBBox(),f=c(20,g.width+10,g.height+10)/2;return this.rect(g.x-f/2,g.y-f/2,g.width+f,g.height+f,f).attr({stroke:"none",fill:"#000"}).insertBefore(h.node?h:h[0]);};Raphael.fn.g.drop=function(f,k,j,h,i){h=h||30;i=i||0;var g=this.set();g.push(this.path(["M",f,k,"l",h,0,"A",h*0.4,h*0.4,0,1,0,f+h*0.7,k-h*0.7,"z"]).attr({fill:"#000",stroke:"none",rotation:[22.5-i,f,k]}));i=(i+90)*Math.PI/180;g.push(this.text(f+h*Math.sin(i),k+h*Math.cos(i),j).attr(this.g.txtattr).attr({"font-size":h*12/30,fill:"#fff"}));g.drop=g[0];g.text=g[1];return g;};Raphael.fn.g.blob=function(g,m,l,k,i){k=(+k+1?k:45)+90;i=i||12;var f=Math.PI/180,j=i*12/12;var h=this.set();h.push(this.path().attr({fill:"#000",stroke:"none"}));h.push(this.text(g+i*Math.sin((k)*f),m+i*Math.cos((k)*f)-j/2,l).attr(this.g.txtattr).attr({"font-size":j,fill:"#fff"}));h.update=function(t,s,y){t=t||g;s=s||m;var A=this[1].getBBox(),D=a(A.width+j,i*25/12),z=a(A.height+j,i*25/12),o=t+i*Math.sin((k-22.5)*f),B=s+i*Math.cos((k-22.5)*f),q=t+i*Math.sin((k+22.5)*f),C=s+i*Math.cos((k+22.5)*f),F=(q-o)/2,E=(C-B)/2,p=D/2,n=z/2,x=-Math.sqrt(Math.abs(p*p*n*n-p*p*E*E-n*n*F*F)/(p*p*E*E+n*n*F*F)),v=x*p*E/n+(q+o)/2,u=x*-n*F/p+(C+B)/2;if(y){this.animate({x:v,y:u,path:["M",g,m,"L",q,C,"A",p,n,0,1,1,o,B,"z"].join(",")},500,">");}else{this.attr({x:v,y:u,path:["M",g,m,"L",q,C,"A",p,n,0,1,1,o,B,"z"].join(",")});}return this;};h.update(g,m);return h;};Raphael.fn.g.colorValue=function(i,h,g,f){return"hsb("+[c((1-i/h)*0.4,1),g||0.75,f||0.75]+")";};Raphael.fn.g.snapEnds=function(n,o,m){var k=n,p=o;if(k==p){return{from:k,to:p,power:0};}function q(f){return Math.abs(f-0.5)<0.25?~~(f)+0.5:Math.round(f);}var l=(p-k)/m,g=~~(l),j=g,h=0;if(g){while(j){h--;j=~~(l*Math.pow(10,h))/Math.pow(10,h);}h++;}else{while(!g){h=h||1;g=~~(l*Math.pow(10,h))/Math.pow(10,h);h++;}h&&h--;}p=q(o*Math.pow(10,h))/Math.pow(10,h);if(p0?0:0.5))*Math.pow(10,h))/Math.pow(10,h);return{from:k,to:p,power:h};};Raphael.fn.g.axis=function(v,u,o,G,l,J,m,L,n,g){g=g==null?2:g;n=n||"t";J=J||10;var F=n=="|"||n==" "?["M",v+0.5,u,"l",0,0.001]:m==1||m==3?["M",v+0.5,u,"l",0,-o]:["M",v,u+0.5,"l",o,0],z=this.g.snapEnds(G,l,J),K=z.from,B=z.to,I=z.power,H=0,C=this.set();d=(B-K)/J;var s=K,q=I>0?I:0;w=o/J;if(+m==1||+m==3){var h=u,A=(m-1?1:-1)*(g+3+!!(m-1));while(h>=u-o){n!="-"&&n!=" "&&(F=F.concat(["M",v-(n=="+"||n=="|"?g:!(m-1)*g*2),h+0.5,"l",g*2+1,0]));C.push(this.text(v+A,h,(L&&L[H++])||(Math.round(s)==s?s:+s.toFixed(q))).attr(this.g.txtattr).attr({"text-anchor":m-1?"start":"end"}));s+=d;h-=w;}if(Math.round(h+w-(u-o))){n!="-"&&n!=" "&&(F=F.concat(["M",v-(n=="+"||n=="|"?g:!(m-1)*g*2),u-o+0.5,"l",g*2+1,0]));C.push(this.text(v+A,u-o,(L&&L[H])||(Math.round(s)==s?s:+s.toFixed(q))).attr(this.g.txtattr).attr({"text-anchor":m-1?"start":"end"}));}}else{s=K;q=(I>0)*I;A=(m?-1:1)*(g+9+!m);var k=v,w=o/J,D=0,E=0;while(k<=v+o){n!="-"&&n!=" "&&(F=F.concat(["M",k+0.5,u-(n=="+"?g:!!m*g*2),"l",0,g*2+1]));C.push(D=this.text(k,u+A,(L&&L[H++])||(Math.round(s)==s?s:+s.toFixed(q))).attr(this.g.txtattr));var p=D.getBBox();if(E>=p.x-5){C.pop(C.length-1).remove();}else{E=p.x+p.width;}s+=d;k+=w;}if(Math.round(k-w-v-o)){n!="-"&&n!=" "&&(F=F.concat(["M",v+o+0.5,u-(n=="+"?g:!!m*g*2),"l",0,g*2+1]));C.push(this.text(v+o,u+A,(L&&L[H])||(Math.round(s)==s?s:+s.toFixed(q))).attr(this.g.txtattr));}}var M=this.path(F);M.text=C;M.all=this.set([M,C]);M.remove=function(){this.text.remove();this.constructor.prototype.remove.call(this);};return M;};Raphael.el.lighter=function(g){g=g||2;var f=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[f[0],f[1]];f[0]=Raphael.rgb2hsb(Raphael.getRGB(f[0]).hex);f[1]=Raphael.rgb2hsb(Raphael.getRGB(f[1]).hex);f[0].b=c(f[0].b*g,1);f[0].s=f[0].s/g;f[1].b=c(f[1].b*g,1);f[1].s=f[1].s/g;this.attr({fill:"hsb("+[f[0].h,f[0].s,f[0].b]+")",stroke:"hsb("+[f[1].h,f[1].s,f[1].b]+")"});};Raphael.el.darker=function(g){g=g||2;var f=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[f[0],f[1]];f[0]=Raphael.rgb2hsb(Raphael.getRGB(f[0]).hex);f[1]=Raphael.rgb2hsb(Raphael.getRGB(f[1]).hex);f[0].s=c(f[0].s*g,1);f[0].b=f[0].b/g;f[1].s=c(f[1].s*g,1);f[1].b=f[1].b/g;this.attr({fill:"hsb("+[f[0].h,f[0].s,f[0].b]+")",stroke:"hsb("+[f[1].h,f[1].s,f[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 diff --git a/g.raphael.js b/g.raphael.js index 74c080f..e9c74cd 100644 --- a/g.raphael.js +++ b/g.raphael.js @@ -1,5 +1,5 @@ -/* - * g.Raphael 0.4 - Charting library, based on Raphaël +/*! + * g.Raphael 0.4.1 - 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. @@ -7,6 +7,8 @@ (function () { + var mmax = Math.max, + mmin = Math.min; Raphael.fn.g = Raphael.fn.g || {}; Raphael.fn.g.markers = { disc: "disc", @@ -71,18 +73,18 @@ switch (ending) { case "round": if (!dir) { - var r = Math.floor(height / 2); + var r = ~~(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"]; + path = ["M", x + .5, y + .5 - ~~(height / 2), "l", 0, 0, "a", r, ~~(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); + r = ~~(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"]; + path = ["M", x - ~~(width / 2), y, "l", 0, 0, "a", ~~(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"]; } @@ -90,28 +92,27 @@ 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"]; + var half = ~~(height / 2); + path = ["M", x, y + half, "l", 0, -height, mmax(width - half, 0), 0, mmin(half, width), half, -mmin(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"]; + half = ~~(width / 2); + path = ["M", x + half, y, "l", -width, 0, 0, -mmax(height - half, 0), half, -mmin(half, height), half, mmin(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"]; + path = ["M", x, y + ~~(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"]; + path = ["M", x + ~~(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"]; + r = mmin(width, Math.round(height / 5)); + path = ["M", x + .5, y + .5 - ~~(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"]; + r = mmin(Math.round(width / 5), height); + path = ["M", x - ~~(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) { @@ -153,13 +154,14 @@ points.push("z"); return this.path(points.join(",")); }; - Raphael.fn.g.star = function (cx, cy, r, r2) { - r2 = r2 || r * .5; + Raphael.fn.g.star = function (cx, cy, r, r2, rays) { + r2 = r2 || r * .382; + rays = rays || 5; var points = ["M", cx, cy + r2, "L"], R; - for (var i = 1; i < 10; i++) { + for (var i = 1; i < rays * 2; 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 = points.concat([(cx + R * Math.sin(i * Math.PI / rays)), (cy + R * Math.cos(i * Math.PI / rays))]); } points.push("z"); return this.path(points.join(",")); @@ -184,8 +186,8 @@ 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.push(this.path().attr({fill: "#000", stroke: "#000"})); + res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"})); res.update = function () { this.rotate(0, x, y); var bb = this[1].getBBox(); @@ -193,8 +195,6 @@ 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}); @@ -209,30 +209,30 @@ 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; + x = Math.round(x); + y = Math.round(y); 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(","), + p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size, + "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size, + "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size, + "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size, + "l", -mmax(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; + dir = dir == null ? 2 : dir > 3 ? 3 : 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.push(this.path().attr({fill: "#000", stroke: "#000"})); + res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"})); res.update = function (X, Y, withAnimation) { X = X || x; Y = Y || y; @@ -241,18 +241,17 @@ 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(","), + p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size, + "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size, + "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size, + "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size, + "l", -mmax(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]; + xy.path = p; if (withAnimation) { - this[0].animate({path: p}, 500, ">"); - this[1].animate(xy, 500, ">"); + this.animate(xy, 500, ">"); } else { - this[0].attr({path: p}); - this[1].attr(xy); + this.attr(xy); } return this; }; @@ -263,8 +262,8 @@ 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.push(this.path().attr({fill: "#000", stroke: "#000"})); + res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"})); res.update = function (x, y) { this.rotate(0, x, y); var bb = this[1].getBBox(), @@ -284,7 +283,7 @@ 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; + r = mmin(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(); @@ -292,8 +291,8 @@ }; 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]); + r = mmin(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.node ? set : set[0]); }; Raphael.fn.g.drop = function (x, y, text, size, angle) { size = size || 30; @@ -318,8 +317,8 @@ 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), + w = mmax(bb.width + fontSize, size * 25 / 12), + h = mmax(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), @@ -343,7 +342,7 @@ }; Raphael.fn.g.colorValue = function (value, total, s, b) { - return "hsb(" + [Math.min((1 - value / total) * .4, 1), s || .75, b || .75] + ")"; + return "hsb(" + [mmin((1 - value / total) * .4, 1), s || .75, b || .75] + ")"; }; Raphael.fn.g.snapEnds = function (from, to, steps) { @@ -353,31 +352,31 @@ return {from: f, to: t, power: 0}; } function round(a) { - return Math.abs(a - .5) < .25 ? Math.floor(a) + .5 : Math.round(a); + return Math.abs(a - .5) < .25 ? ~~(a) + .5 : Math.round(a); } var d = (t - f) / steps, - r = Math.floor(d), + r = ~~(d), R = r, i = 0; if (r) { while (R) { i--; - R = Math.floor(d * Math.pow(10, i)) / Math.pow(10, i); + R = ~~(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); + r = ~~(d * Math.pow(10, i)) / Math.pow(10, i); i++; } i && i--; } - var t = round(to * Math.pow(10, i)) / Math.pow(10, i); + 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); + 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) { @@ -409,10 +408,10 @@ 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 { + label = f; + rnd = (i > 0) * i; + addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation); var X = x, - label = f, - rnd = i > 0 ? i : 0, - addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation), dx = length / steps, txt = 0, prev = 0; @@ -449,9 +448,9 @@ 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].b = mmin(fs[0].b * times, 1); fs[0].s = fs[0].s / times; - fs[1].b = Math.min(fs[1].b * times, 1); + fs[1].b = mmin(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] + ")"}); }; @@ -461,9 +460,9 @@ 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].s = mmin(fs[0].s * times, 1); fs[0].b = fs[0].b / times; - fs[1].s = Math.min(fs[1].s * times, 1); + fs[1].s = mmin(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] + ")"}); }; From 36157ec6aa1732133386254b9792fc7647e4e038 Mon Sep 17 00:00:00 2001 From: Dmitry Baranovskiy Date: Thu, 8 Jul 2010 16:30:31 +0800 Subject: [PATCH 8/9] Fixed bug with recursion on large numbers. Added option smooth. --- g.line-min.js | 4 +-- g.line.js | 77 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/g.line-min.js b/g.line-min.js index f7138f3..603af8c 100644 --- a/g.line-min.js +++ b/g.line-min.js @@ -1,7 +1,7 @@ /* - * g.Raphael 0.4.1 - Charting library, based on Raphaël + * g.Raphael 0.4.2 - 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(J,I,a,c,s,r,C){function B(y,Y){var x=y.length/Y,V=0,i=x,X=0,W=[];while(Va-2*l){r[S]=B(r[S],a-2*l);t=a-2*l;}if(s[S]&&s[S].length>a-2*l){s[S]=B(s[S],a-2*l);}}var w=this.set();if(C.axis){var f=(C.axis+"").split(/[,\s]+/);+f[0]&&w.push(this.g.axis(J+l,I+l,a-2*l,v,h,C.axisxstep||Math.floor((a-2*l)/20),2));+f[1]&&w.push(this.g.axis(J+a-l,I+c-l,c-2*l,u,g,C.axisystep||Math.floor((c-2*l)/20),3));+f[2]&&w.push(this.g.axis(J+l,I+c-l,a-2*l,v,h,C.axisxstep||Math.floor((a-2*l)/20),0));+f[3]&&w.push(this.g.axis(J+l,I+c-l,c-2*l,u,g,C.axisystep||Math.floor((c-2*l)/20),1));}var F=this.set(),Q=this.set(),m;for(var S=0,E=r.length;Sb-2*m){s[aa]=E(s[aa],b-2*m);u=b-2*m}if(t[aa]&&t[aa].length>b-2*m){t[aa]=E(t[aa],b-2*m)}}var U=Array.prototype.concat.apply([],t),S=Array.prototype.concat.apply([],s),p=this.g.snapEnds(Math.min.apply(Math,U),Math.max.apply(Math,U),t[0].length-1),z=p.from,k=p.to,J=this.g.snapEnds(Math.min.apply(Math,S),Math.max.apply(Math,S),s[0].length-1),v=J.from,h=J.to,V=(b-m*2)/(k-z),T=(d-m*2)/(h-v);var B=this.set();if(F.axis){var g=(F.axis+"").split(/[,\s]+/);+g[0]&&B.push(this.g.axis(M+m,L+m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),2));+g[1]&&B.push(this.g.axis(M+b-m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),3));+g[2]&&B.push(this.g.axis(M+m,L+d-m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),0));+g[3]&&B.push(this.g.axis(M+m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),1))}var I=this.set(),W=this.set(),n;for(aa=0,H=s.length;aa Date: Thu, 8 Jul 2010 17:06:33 +0800 Subject: [PATCH 9/9] Fixed bug when all Y values are equal. --- g.line-min.js | 2 +- g.line.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/g.line-min.js b/g.line-min.js index 603af8c..137adb2 100644 --- a/g.line-min.js +++ b/g.line-min.js @@ -4,4 +4,4 @@ * 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(M,L,b,d,t,s,F){function E(x,ae){var i=x.length/ae,y=0,a=i,Y=0,X=[];while(yb-2*m){s[aa]=E(s[aa],b-2*m);u=b-2*m}if(t[aa]&&t[aa].length>b-2*m){t[aa]=E(t[aa],b-2*m)}}var U=Array.prototype.concat.apply([],t),S=Array.prototype.concat.apply([],s),p=this.g.snapEnds(Math.min.apply(Math,U),Math.max.apply(Math,U),t[0].length-1),z=p.from,k=p.to,J=this.g.snapEnds(Math.min.apply(Math,S),Math.max.apply(Math,S),s[0].length-1),v=J.from,h=J.to,V=(b-m*2)/(k-z),T=(d-m*2)/(h-v);var B=this.set();if(F.axis){var g=(F.axis+"").split(/[,\s]+/);+g[0]&&B.push(this.g.axis(M+m,L+m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),2));+g[1]&&B.push(this.g.axis(M+b-m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),3));+g[2]&&B.push(this.g.axis(M+m,L+d-m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),0));+g[3]&&B.push(this.g.axis(M+m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),1))}var I=this.set(),W=this.set(),n;for(aa=0,H=s.length;aab-2*m){s[aa]=E(s[aa],b-2*m);u=b-2*m}if(t[aa]&&t[aa].length>b-2*m){t[aa]=E(t[aa],b-2*m)}}var U=Array.prototype.concat.apply([],t),S=Array.prototype.concat.apply([],s),p=this.g.snapEnds(Math.min.apply(Math,U),Math.max.apply(Math,U),t[0].length-1),z=p.from,k=p.to,J=this.g.snapEnds(Math.min.apply(Math,S),Math.max.apply(Math,S),s[0].length-1),v=J.from,h=J.to,V=(b-m*2)/((k-z)||1),T=(d-m*2)/((h-v)||1);var B=this.set();if(F.axis){var g=(F.axis+"").split(/[,\s]+/);+g[0]&&B.push(this.g.axis(M+m,L+m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),2));+g[1]&&B.push(this.g.axis(M+b-m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),3));+g[2]&&B.push(this.g.axis(M+m,L+d-m,b-2*m,z,k,F.axisxstep||Math.floor((b-2*m)/20),0));+g[3]&&B.push(this.g.axis(M+m,L+d-m,d-2*m,v,h,F.axisystep||Math.floor((d-2*m)/20),1))}var I=this.set(),W=this.set(),n;for(aa=0,H=s.length;aa