summaryrefslogtreecommitdiff
path: root/test/g.raphael
diff options
context:
space:
mode:
Diffstat (limited to 'test/g.raphael')
-rw-r--r--test/g.raphael/README.md17
-rw-r--r--test/g.raphael/docs/bar.markdown104
-rw-r--r--test/g.raphael/docs/dot.markdown135
-rw-r--r--test/g.raphael/docs/g.markdown7
-rw-r--r--test/g.raphael/docs/line.markdown159
-rw-r--r--test/g.raphael/docs/pie.markdown150
-rw-r--r--test/g.raphael/examples/barchart/barchart_basic.html20
-rw-r--r--test/g.raphael/examples/barchart/barchart_custom_axis.html23
-rw-r--r--test/g.raphael/examples/barchart/barchart_custom_spacing.html21
-rw-r--r--test/g.raphael/examples/barchart/barchart_horizontal.html20
-rw-r--r--test/g.raphael/examples/barchart/barchart_hover.html27
-rw-r--r--test/g.raphael/examples/barchart/barchart_hoverCol.html29
-rw-r--r--test/g.raphael/examples/barchart/barchart_stacked.html28
-rw-r--r--test/g.raphael/examples/barchart/barchart_text_axis.html25
-rw-r--r--test/g.raphael/examples/dot/dotchart_basic.html22
-rw-r--r--test/g.raphael/examples/dot/dotchart_href.html28
-rw-r--r--test/g.raphael/examples/dot/dotchart_labels.html23
-rw-r--r--test/g.raphael/examples/dot/dotchart_symbols.html22
-rw-r--r--test/g.raphael/examples/linechart/linechart_basic.html21
-rw-r--r--test/g.raphael/examples/linechart/linechart_interactive.html27
-rw-r--r--test/g.raphael/examples/linechart/linechart_opts.html22
-rw-r--r--test/g.raphael/examples/linechart/linechart_shading.html28
-rw-r--r--test/g.raphael/examples/piechart/piechart_basic.html24
-rw-r--r--test/g.raphael/examples/piechart/piechart_each.html28
-rw-r--r--test/g.raphael/examples/piechart/piechart_hover.html28
-rw-r--r--test/g.raphael/examples/piechart/piechart_hover_adv.html41
-rw-r--r--test/g.raphael/examples/piechart/piechart_rotate.html28
-rw-r--r--test/g.raphael/examples/piechart/piechart_with_legend.html20
-rw-r--r--test/g.raphael/examples/raphael-min.js116
-rw-r--r--test/g.raphael/g.bar-min.js7
-rw-r--r--test/g.raphael/g.bar.js386
-rw-r--r--test/g.raphael/g.dot-min.js7
-rw-r--r--test/g.raphael/g.dot.js110
-rw-r--r--test/g.raphael/g.line-min.js7
-rw-r--r--test/g.raphael/g.line.js254
-rw-r--r--test/g.raphael/g.pie-min.js1
-rw-r--r--test/g.raphael/g.pie.js205
-rw-r--r--test/g.raphael/g.raphael-min.js7
-rw-r--r--test/g.raphael/g.raphael.js475
-rw-r--r--test/g.raphael/test.html58
-rw-r--r--test/g.raphael/test2.html55
41 files changed, 2815 insertions, 0 deletions
diff --git a/test/g.raphael/README.md b/test/g.raphael/README.md
new file mode 100644
index 0000000..34092b9
--- /dev/null
+++ b/test/g.raphael/README.md
@@ -0,0 +1,17 @@
+# unofficial documentation fork of g.raphael #
+
+I started this fork while learning about g.raphael and decided to record down what I know from my noobish studying of the source code. This is *NOT* an official documentation, you should keep a lookout on the [official gRaphael website](http://example.net/) for the real deal.
+
+In the meantime, I hope this continue to serve as a easy to understand resource.
+
+## docs folder ##
+
+contains the various breakdown of the different g.raphael charts written in markdown.
+
+## examples folder ##
+
+contains examples. Often I get emails or Twitter messages asking me how to do X in gRaphael and I prefer to just make an example and post it here for other people to reference.
+
+## I could be wrong ##
+
+If you spot any mistake or wish to expound on the current stuff here, please let me know. \ No newline at end of file
diff --git a/test/g.raphael/docs/bar.markdown b/test/g.raphael/docs/bar.markdown
new file mode 100644
index 0000000..150e7dc
--- /dev/null
+++ b/test/g.raphael/docs/bar.markdown
@@ -0,0 +1,104 @@
+# g.bar.js #
+
+## Requirements ##
+
+ + raphael.js
+ + g.raphael.js
+ + g.bar.js
+
+## Overview ##
+
+Creates a bar chart.
+
+## Parameters ##
+
+**1. x** number **X coordinate of the centre**
+
+**2. y** number **Y coordinate of the centre**
+
+**3. width** number **width**
+
+**4. height** number **height**
+
+**5. values** array of numbers **Values for your bars.**
+
+**5. opts** object **Options (more info soon.)**
+
+_opts_
+
+**type**
+
+Values are,
+
+ + "round"
+ + "sharp"
+ + "soft"
+ + "square"
+
+Defaults to "square" if type is not specified.
+
+**stacked**
+
+Values are,
+
+ + true
+ + false
+
+Defaults to false. Use this to stack your bars instead of displaying them side by side.
+
+**gutter**
+
+Values given as a string, denoting %. E.g. "40%"
+
+Defaults to "20%". For horizontal barcharts, this is calculated as,
+
+ bargutter = Math.floor(barheight * gutter / 100)
+
+e.g. if my height was 220, and I had 4 bars, then my barheight is calculated as,
+
+ Math.floor(height / (len * (100 + gutter) + gutter) * 100); // where len is 4 and height is 220, and if not specified, gutter is 20
+
+then according to the above, my bargutter = 8px.
+
+
+## Methods ##
+
+**1. .hover(fin, fout)** - fin/fout: **callbacks to trigger when mouse hovers in and out respectively over the bars.**
+
+## Usage ##
+
+Create a bar chart,
+
+
+ // bare bones
+ var barchart = r.g.barchart(_params);
+ // example
+ var barchart = r.g.barchart(10, 10, 300, 220, [[30, 20, 10]]);
+ // horizontal barchart
+ var hbarchart = r.g.hbarchart(10, 10, 300, 220, [[30, 20, 10]]);
+
+
+Create a stacked bar chart,
+
+
+ // example
+ var barchart = r.g.barchart(10, 10, 300, 220, [[30, 20, 10], [44, 66, 88]], {stacked:true});
+
+
+Attach hover event to piechart,
+
+
+ // example
+ r.g.barchart.hover(function() {
+ this.bar.attr({fill: "#333"});
+ }, function() {
+ this.bar.attr({fill: "#666"});
+ });
+
+## Others ##
+
+N/A
+
+## Written by ##
+
+Kenny Shen, www.northpole.sg. \ No newline at end of file
diff --git a/test/g.raphael/docs/dot.markdown b/test/g.raphael/docs/dot.markdown
new file mode 100644
index 0000000..03fa76f
--- /dev/null
+++ b/test/g.raphael/docs/dot.markdown
@@ -0,0 +1,135 @@
+# g.dot.js #
+
+## Requirements ##
+
+ + raphael.js
+ + g.raphael.js
+ + g.dot.js
+
+## Overview ##
+
+Creates a dot chart.
+
+## Parameters ##
+
+**1. x** number **X coordinate of the centre**
+
+**2. y** number **Y coordinate of the centre**
+
+**3. width** number **width**
+
+**4. height** number **height**
+
+**5. valuesx** array of numbers **Values for x-axis.**
+
+**6. valuesy** array of numbers **Values for y-axis.**
+
+**7. size** array of numbers **Values for dot data.**
+
+**8. opts** object **Options (more info soon.)**
+
+_opts_
+
+**symbol**
+
+Values are,
+
+_(shorthand: full name)_
+
+ + o: "disc"
+ + f: "flower"
+ + d: "diamond"
+ + s: "square"
+ + t: "triangle"
+ + *: "star"
+ + x: "cross"
+ + +: "plus"
+ + ->: "arrow"
+
+If omitted, an empty "" is assigned to indicate no symbols.
+
+**max**
+
+Value - number. If omitted, this defaults to 100. This sets the max radius for the maximum value of your dot.
+
+**href**
+
+Value - array of links(string). This is positional and will be mapped from left to right. For example, if you supply 'href:["http://www.google.com","http://www.yahoo.com"]' and you have 4 dots, the links will be applied to the first two.
+
+**axis**
+
+Value - "_top_ _right_ _bottom_ _left_". If omitted, no axis will be rendered for the line chart. For example, if you wanted axis rendered for the left and bottom, (as in a typical x-y chart), you'll add 'axis:"0 0 1 1"' to opts. The axis is created using g.axis (for more information, see the g documentation).
+
+**axisxlabels**
+
+Value - array of labels.
+
+**axisylabels**
+
+Value - array of labels(string).
+
+**axisxstep**
+
+Value - number. Sets the stepping for the x-axis.
+
+**axisystep**
+
+Value - number. Sets the stepping for the y-axis.
+
+**heat**
+
+Value - boolean. If omitted, defaults to false. Sets a spectrum of color based on your values evenly across the dots.
+
+## Methods ##
+
+**1. .hover(fin, fout)** - fin/fout: **callbacks to trigger when mouse hovers in and out respectively over the dots.**
+
+**2. .click(f)** - f: **callback to trigger on click event.**
+
+**3. .each(f)** - f: **callback applied to each iteration.**
+
+## Usage ##
+
+Create a Raphael instance,
+
+
+ // bare bones
+ var r = Raphael();
+ // create at top left corner of #element
+ var r = Raphael('dot-chart');
+
+
+Create a dot chart,
+
+
+ // bare bones
+ var dotchart = r.g.dotchart(_params);
+ // example
+ var dotchart = r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10});
+
+
+Create labels,
+
+
+ // example
+ var axisx = ["dot1","dot2","dot3","dot4","dot5"]
+ r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10, axis: "0 0 1 0", axisxlabels: axisx, axisxstep: 4, heat: true});
+
+
+Attach click event to dotchart,
+
+
+ // example
+ var dots = r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10, href: ["http://www.google.com","http://www.yahoo.com",,,"http://www.raphaeljs.com"]});
+ dots.each(function() {
+ this.click(function() {
+ // alerts href, if defined
+ alert(this.attrs.href);
+ });
+ });
+
+## Others ##
+
+## Written by ##
+
+Kenny Shen, www.northpole.sg. \ No newline at end of file
diff --git a/test/g.raphael/docs/g.markdown b/test/g.raphael/docs/g.markdown
new file mode 100644
index 0000000..10faea2
--- /dev/null
+++ b/test/g.raphael/docs/g.markdown
@@ -0,0 +1,7 @@
+# g.raphael.js #
+
+_in progress_
+
+## Written by ##
+
+Kenny Shen, www.northpole.sg. \ No newline at end of file
diff --git a/test/g.raphael/docs/line.markdown b/test/g.raphael/docs/line.markdown
new file mode 100644
index 0000000..9ee4c96
--- /dev/null
+++ b/test/g.raphael/docs/line.markdown
@@ -0,0 +1,159 @@
+# g.line.js #
+
+## Requirements ##
+
+ + raphael.js
+ + g.raphael.js
+ + g.line.js
+
+## Overview ##
+
+Creates a line chart.
+
+## Parameters ##
+
+**1. x** number **X coordinate of the centre**
+
+**2. y** number **Y coordinate of the centre**
+
+**3. width** number **width**
+
+**4. height** number **height**
+
+**5. valuesx** array of numbers **Values for x-axis.**
+
+**6. valuesy** array of numbers **Values for y-axis.**
+
+**7. opts** object **Options (more info soon.)**
+
+_opts_
+
+**colors**
+
+Value - an array of color values, such as ["#444","#666"...]. If omitted, random colors will be used. (actually, Raphael.fn.g.colors. More info on this in the g.raphael.js documentation) For more information, refer to the [supported color formats](http://raphaeljs.com/reference.html#colour) section of the Raphaeljs documention.
+
+**symbol**
+
+Values are,
+
+_(shorthand: full name)_
+
+ + o: "disc"
+ + f: "flower"
+ + d: "diamond"
+ + s: "square"
+ + t: "triangle"
+ + *: "star"
+ + x: "cross"
+ + +: "plus"
+ + ->: "arrow"
+
+If omitted, an empty "" is assigned to indicate no symbols.
+
+**shade**
+
+Value - boolean. If omitted, false is assumed. If true, the area underneath the line will be shaded with the same color as the line, with opacity set to .3. You can affect this by setting nostroke (see below) option to true.
+
+**nostroke**
+
+Value - boolean. If omitted, false is assumed.
+
+**axis**
+
+Value - "_top_ _right_ _bottom_ _left_". If omitted, no axis will be rendered for the line chart. For example, if you wanted axis rendered for the left and bottom, (as in a typical x-y chart), you'll add 'axis:"0 0 1 1"' to opts. The axis is created using g.axis (for more information, see the g documentation).
+
+**smooth**
+
+Value - boolean. If omitted, false is assumed. If true, smoothing/rounding is applied to the path between data points.
+
+**gutter**
+
+Value - number. If omitted, value of '10' is assigned. Think of this as a general padding value between the chart and the bounding box/container.
+
+
+## Methods ##
+
+**1. .hover(fin, fout)** - fin/fout: **callbacks to trigger when mouse hovers in and out respectively over the data points.**
+
+**2. .click(f)** - f: **callback to trigger on click event.**
+
+**3. .each(f)** - f: **callback applied to each iteration.**
+
+.each(f) works by iterating through each of the data points and returning each as a 'dot' object to the callback f(). Within the callback, you can access the object returned on each iteration in the context of 'this', for example
+
+
+ var f = function() {
+
+ console.log(this.symbol); // the symbol used to represent the data point on the line chart
+
+ }
+
+**4. .hoverColumn(fin, fout)** - fin/fout: **callbacks to trigger when mouse hovers in and out respectively over the data columns.**
+
+**5. .clickColumn(f)** - f: **callback to trigger on click event.**
+
+**6. .hrefColumn(cols)** - _coming soon_
+
+**7. .eachColumn(f)** - f: **callback applied to each iteration.**
+
+
+## Usage ##
+
+Create a Raphael instance,
+
+
+ // bare bones
+ var r = Raphael();
+ // create at top left corner of #element
+ var r = Raphael('line-chart');
+
+
+Create a line chart,
+
+
+ // bare bones
+ var linechart = r.g.linechart(_params);
+ // example
+ var linechart = r.g.linechart(10,10,300,220,[1,2,3,4,5],[10,20,15,35,30], {"colors":["#444"], "symbol":"s", axis:"0 0 1 1"});
+
+
+Attach hover event to linechart,
+
+
+ // example
+ r.g.linechart.hover(function() {
+ this.symbol.attr({'fill':'#CCC'});
+ }, function() {
+ this.symbol.attr({'fill':'#444'});
+ });
+
+
+Attach click event to linechart,
+
+
+ // example
+ r.g.linechart.click(function() {
+ alert("You clicked on the line chart!");
+ });
+
+
+## Others ##
+
+There's two important internal methods that are used to create and return the objects for interaction with a gRaphael line chart, based on what methods you call.
+
+.hover(), .click(), .each() create and return representations ('dots') of the data points used to plot the line. The dots have the following properties when they're returned in the context of 'this' to the methods you call,
+
+ + x
+ + y
+ + value
+ + line
+ + shade
+ + symbol
+ + symbols
+ + axis
+
+.hoverColumn(), .clickColumn(), .eachColumn() create and return groupings of data 'dots'. Columns have similar properties to their atomic counterparts but are usually array of values.
+
+## Written by ##
+
+Kenny Shen, www.northpole.sg. \ No newline at end of file
diff --git a/test/g.raphael/docs/pie.markdown b/test/g.raphael/docs/pie.markdown
new file mode 100644
index 0000000..3dbc6d3
--- /dev/null
+++ b/test/g.raphael/docs/pie.markdown
@@ -0,0 +1,150 @@
+# g.pie.js #
+
+## Requirements ##
+
+ + raphael.js
+ + g.raphael.js
+ + g.pie.js
+
+## Overview ##
+
+Creates a pie chart.
+
+## Parameters ##
+
+**1. x** number **X coordinate of the centre**
+
+**2. y** number **Y coordinate of the centre**
+
+**3. r** number **radius**
+
+**4. values** array of numbers **Values for your slices.**
+
+**5. opts** object **Options (more info soon.)**
+
+_opts_
+
+**legend**
+
+Values are,
+
+ + legend - e.g. ["apples", "oranges"]
+ + legendothers
+ + legendmark
+ + legendpos - e.g. "west"
+
+legend is required. If legendpos is omitted, 'east' is assumed. If legendmark is omitted, 'disc' is assumed. The current possible options for legendmark and legendpos are,
+
+**legendmark**
+
+Values are,
+
+_(shorthand: full name)_
+
+ + o: "disc"
+ + f: "flower"
+ + d: "diamond"
+ + s: "square"
+ + t: "triangle"
+ + *: "star"
+ + x: "cross"
+ + +: "plus"
+ + ->: "arrow"
+
+**legendpos**
+
+Values are,
+
+ + "north"
+ + "south"
+ + "east"
+ + "west"
+
+## Methods ##
+
+**1. .hover(fin, fout)** - fin/fout: **callbacks to trigger when mouse hovers in and out respectively over the pie sectors.**
+
+**2. .click(f)** - f: **callback to trigger on click event.**
+
+**3. .each(f)** - f: **callback applied to each iteration.**
+
+.each(f) works by iterating through each of the slices and returning each as an object to the callback f(). Within the callback, you can access the object returned on each iteration in the context of 'this', for example
+
+
+ var f = function() {
+
+ console.log(this.r); // the radius of the slice
+
+ }
+
+## Usage ##
+
+Create a Raphael instance,
+
+
+ // bare bones
+ var r = Raphael();
+ // create at top left corner of #element
+ var r = Raphael('pie-chart');
+
+
+Create a pie chart,
+
+
+ // bare bones
+ var pie = r.g.piechart(_params);
+ // example
+ var pie = r.g.piechart(10, 10, 90, [10,20,30]);
+
+
+Create legends,
+
+
+ // example
+ r.g.piechart(320, 240, 100, [10,20,30,40], {legend:['%% apples', '%% bananas', '%% cherries', '%% durians'], legendmark:"*", legendpos: "south"});
+
+Attach hover event to piechart,
+
+
+ // example
+ r.g.piechart(10, 10, 90, [10,20,30]).hover(function() {
+ // when mouse hovers over slice, change color
+ this.sector.attr({fill:"#FAA"});
+ }, function() {
+ // when mouse hovers out, restore color
+ this.sector.attr({fill:"#666"});
+ });
+
+Attach click event to piechart,
+
+
+ // example
+ r.g.piechart.click(function() {
+ alert("You clicked on the pie chart!");
+ });
+
+## Others ##
+
+Each pie chart in g.raphael.js is composed of a 'series', or a collection of slices/sectors. Each slice has its own 'sector' property which carries information like the value, the color and other attributes, as well as its own 'cover' which can be thought of as a layer (really set to opacity 0) to which you attach events like click or hover.
+
+When you iterate through each slice of the pie chart using .each(), the returned slice has the following properties:
+
+ + sector
+ + cover
+ + cx
+ + cy
+ + x (middle x coordinate of the sector)
+ + y (middle y coordinate of the sector)
+ + mangle
+ + r (radius)
+ + value
+ + total
+ + label
+
+When you attach a hover event for example, using .hover(), g.raphael.js is essentially iterating through each slice, as it does in .each(), and passing the returned slice to the callbacks to be called, and setting the events to happen by binding mouseover and mouseout events to the covers.
+
+All of this is container within the 'chart' object, which is initialized and returned to you when you first call g.piechart.
+
+## Written by ##
+
+Kenny Shen, www.northpole.sg. \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_basic.html b/test/g.raphael/examples/barchart/barchart_basic.html
new file mode 100644
index 0000000..8956e9f
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_basic.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a simple barchart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series barchart at 10, 10
+ // width 300, height 220, data: [55, 20, 13, 32, 5, 1, 2, 10]
+ r.g.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_custom_axis.html b/test/g.raphael/examples/barchart/barchart_custom_axis.html
new file mode 100644
index 0000000..5cf8e74
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_custom_axis.html
@@ -0,0 +1,23 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a barchart with customised axis</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series barchart at 10, 10
+ // width 300, height 220, data: [55, 20, 13, 32, 5, 1, 2, 10]
+ var max_val = 50
+ r.g.barchart(40, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]);
+ axis = r.g.axis(40,230,300,0,400,10,2);
+ axis.text.attr({font:"9px Arial", fill:"#888", "font-weight": "regular", "color": "#ff0000", "fill": "#ff0000"});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_custom_spacing.html b/test/g.raphael/examples/barchart/barchart_custom_spacing.html
new file mode 100644
index 0000000..f7a51e7
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_custom_spacing.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a horizontal barchart with gutters</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series horizontal barchart at 10, 10
+ // width 300, height 220, data: [10,20,30,40]
+ r.g.hbarchart(10, 10, 300, 220, [[10,20,30,40]], {"gutter":"40%"});
+ // My bar sizes will be 36px high and gutter(space between) 14px. (for more on how this is calculated, refer to bar.markdown)
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_horizontal.html b/test/g.raphael/examples/barchart/barchart_horizontal.html
new file mode 100644
index 0000000..87f422f
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_horizontal.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a simple barchart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series horizontal barchart at 10, 10
+ // width 300, height 220, data: [55, 20, 13, 32, 5, 1, 2, 10]
+ r.g.hbarchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_hover.html b/test/g.raphael/examples/barchart/barchart_hover.html
new file mode 100644
index 0000000..4366857
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_hover.html
@@ -0,0 +1,27 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a .hover() example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series barchart at 10, 10
+ // width 300, height 220, data: [55, 20, 13, 32, 5, 1, 2, 10]
+ var barchart = r.g.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]).attr({fill: "#666"});
+
+ // Add a hover event to the barchart
+ barchart.hover(function() {
+ this.bar.attr({fill: "#333"});
+ }, function() {
+ this.bar.attr({fill: "#666"});
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_hoverCol.html b/test/g.raphael/examples/barchart/barchart_hoverCol.html
new file mode 100644
index 0000000..0c61574
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_hoverCol.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a .hoverColumn() example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a stacked series barchart at 10, 10
+ // width 300, height 220, data: [55, 20, 13],[16,11,5]
+ r.g.barchart(10, 10, 300, 220, [[55, 20, 13],[16,11,5]], {stacked:true}).hoverColumn(function() {
+ var y = [], res = [];
+ for (var i = this.bars.length; i--;) {
+ y.push(this.bars[i].y);
+ res.push(this.bars[i].value || "0");
+ }
+ this.flag = r.g.popup(this.bars[0].x, Math.min.apply(Math, y), res.join(", ")).insertBefore(this);
+ }, function() {
+ this.flag.animate({opacity: 0}, 3000, ">", function () {this.remove();});
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/test/g.raphael/examples/barchart/barchart_stacked.html b/test/g.raphael/examples/barchart/barchart_stacked.html
new file mode 100644
index 0000000..6bfd9de
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_stacked.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a stacked vs unstacked barchart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 480 x 640 at 10, 50
+ var r = Raphael(10, 50, 480, 640);
+
+ var data1 = [10, 55, 33];
+ var data2 = [16, 44, 123];
+ var data3 = [4, 66, 58];
+
+ // Creates a stacked barchart at 10, 10
+ // width 300, height 220, data sets: data1, data2, data3
+ r.g.barchart(10, 10, 300, 220, [data1, data2, data3], {stacked:true});
+
+ // Creates a barchart at 10, 320
+ // width 300, height 220, data sets: data1, data2, data3
+ r.g.barchart(10, 320, 300, 220, [data1, data2, data3]);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/barchart/barchart_text_axis.html b/test/g.raphael/examples/barchart/barchart_text_axis.html
new file mode 100644
index 0000000..e3036f7
--- /dev/null
+++ b/test/g.raphael/examples/barchart/barchart_text_axis.html
@@ -0,0 +1,25 @@
+<html>
+ <head>
+ <title>gRaphaël Bar Chart - a barchart with text x-axis</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.bar-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a single series barchart at 10, 10
+ // width 300, height 220, data: [10,20,30,40]
+ var max_val = 50
+ r.g.barchart(40, 10, 320, 220, [[10,20,30,40]]);
+ axis = r.g.axis(85,230,310,null,null,4,2,["Today", "Yesterday", "Tomorrow", "Future"], "|", 0);
+ axis.text.attr({font:"12px Arial", "font-weight": "regular", "fill": "#333333"});
+ // show y-axis by setting orientation to 1
+ axis2 = r.g.axis(40,230,300,0,400,10,1);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/dot/dotchart_basic.html b/test/g.raphael/examples/dot/dotchart_basic.html
new file mode 100644
index 0000000..3cb74ed
--- /dev/null
+++ b/test/g.raphael/examples/dot/dotchart_basic.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - a simple dot chart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.dot-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple dot chart at 10, 10
+ // width 300, height 220
+ // x-values: [5,10,15,20,25], y-values: [220,220,220,220,220]
+ // size: [1,2,3,4,5]
+ r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/dot/dotchart_href.html b/test/g.raphael/examples/dot/dotchart_href.html
new file mode 100644
index 0000000..575d8ab
--- /dev/null
+++ b/test/g.raphael/examples/dot/dotchart_href.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - a simple dot chart example with hyperlinks</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.dot-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple dot chart at 10, 10
+ // width 300, height 220
+ // x-values: [5,10,15,20,25], y-values: [220,220,220,220,220]
+ // size: [1,2,3,4,5]
+ // attach links to the first 2 dots, and the last dot.
+ var dots = r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10, href: ["http://www.google.com","http://www.yahoo.com",,,"http://www.raphaeljs.com"]});
+ dots.each(function() {
+ this.click(function() {
+ alert(this.attrs.href);
+ });
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/dot/dotchart_labels.html b/test/g.raphael/examples/dot/dotchart_labels.html
new file mode 100644
index 0000000..3d61097
--- /dev/null
+++ b/test/g.raphael/examples/dot/dotchart_labels.html
@@ -0,0 +1,23 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - a labelled dot chart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.dot-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple dot chart at 10, 10
+ // width 300, height 220
+ // x-values: [5,10,15,20,25], y-values: [220,220,220,220,220]
+ // size: [1,2,3,4,5]
+ var axisx = ["dot1","dot2","dot3","dot4","dot5"]
+ r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10, axis: "0 0 1 0", axisxlabels: axisx, axisxstep: 4, heat: true});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/dot/dotchart_symbols.html b/test/g.raphael/examples/dot/dotchart_symbols.html
new file mode 100644
index 0000000..60a6f21
--- /dev/null
+++ b/test/g.raphael/examples/dot/dotchart_symbols.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - customised symbol dot chart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.dot-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple dot chart at 10, 10
+ // width 300, height 220
+ // x-values: [5,10,15,20,25], y-values: [220,220,220,220,220]
+ // size: [1,2,3,4,5]
+ r.g.dotchart(10,10,300,220,[5,10,15,20,25],[220,220,220,220,220],[1,2,3,4,5], {max:10, symbol:'*'});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/linechart/linechart_basic.html b/test/g.raphael/examples/linechart/linechart_basic.html
new file mode 100644
index 0000000..4527f12
--- /dev/null
+++ b/test/g.raphael/examples/linechart/linechart_basic.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - a simple line chart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.line-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple line chart at 10, 10
+ // width 300, height 220
+ // x-values: [1,2,3,4,5], y-values: [10,20,15,35,30]
+ r.g.linechart(10,10,300,220,[1,2,3,4,5],[10,20,15,35,30]);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/linechart/linechart_interactive.html b/test/g.raphael/examples/linechart/linechart_interactive.html
new file mode 100644
index 0000000..824d969
--- /dev/null
+++ b/test/g.raphael/examples/linechart/linechart_interactive.html
@@ -0,0 +1,27 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - line chart interaction example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.line-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 320 × 300 at 10, 50
+ var r = Raphael('holder');
+
+ // Creates a simple line chart at 10, 10
+ // width 300, height 220
+ // x-values: [1,2,3,4,5], y-values: [10,20,15,35,30]
+ var linec = r.g.linechart(10,10,300,220,[1,2,3,4,5],[10,20,15,35,30], {"colors":["#444"], "symbol":"s", axis:"0 0 1 1"});
+ linec.hover(function() {
+ this.symbol.attr({'fill':'#CCC'});
+ }, function() {
+ this.symbol.attr({'fill':'#444'});
+ });
+ }
+ </script>
+ </head>
+ <body>
+ <div id="holder" style="width:320px;height:300px;border:1px dashed #CCC;">
+ </body>
+</html>
diff --git a/test/g.raphael/examples/linechart/linechart_opts.html b/test/g.raphael/examples/linechart/linechart_opts.html
new file mode 100644
index 0000000..ac14e24
--- /dev/null
+++ b/test/g.raphael/examples/linechart/linechart_opts.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - line chart interaction example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.line-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 320 × 300 at 10, 50
+ var r = Raphael('holder');
+
+ // Creates a simple line chart at 10, 10
+ // width 300, height 220
+ // x-values: [1,2,3,4,5], y-values: [10,20,15,35,30]
+ r.g.linechart(10,10,300,220,[1,2,3,4,5],[10,20,15,35,30], {"colors":["#444"], "symbol":"s", axis:"0 0 0 1", smooth: true, gutter:35});
+ }
+ </script>
+ </head>
+ <body>
+ <div id="holder" style="width:320px;height:300px;border:1px dashed #CCC;">
+ </body>
+</html>
diff --git a/test/g.raphael/examples/linechart/linechart_shading.html b/test/g.raphael/examples/linechart/linechart_shading.html
new file mode 100644
index 0000000..c429d8c
--- /dev/null
+++ b/test/g.raphael/examples/linechart/linechart_shading.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Line Chart - a line chart with shading example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.line-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+
+ // Creates a simple line chart at 10, 10
+ // width 300, height 220
+ // x-values: [1,2,3,4,5], y-values: [10,20,15,35,30]
+ // shade is set to true (fill color opacity will be .3)
+ r.g.linechart(10,10,300,220,[1,2,3,4,5],[10,20,15,35,30], {shade:true, "colors":["#F44"]});
+
+ // Creates a simple line chart at 10, 10
+ // width 300, height 220
+ // x-values: [1,2,3,4,5], y-values: [5,10,5,15,20]
+ // shade is set to true, nostroke is set to true (fill color opacity will be 1)
+ r.g.linechart(10,10,300,220,[1,2,3,4,5],[5,10,5,15,20], {shade:true, "colors":["#44F"], nostroke:true});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/piechart/piechart_basic.html b/test/g.raphael/examples/piechart/piechart_basic.html
new file mode 100644
index 0000000..54cc4bb
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_basic.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - a simple piechart example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 200,
+ // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
+ var pie = r.g.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);
+
+ // add a click event to the pie chart
+ pie.click(function() {
+ alert("You clicked on the pie chart!");
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/piechart/piechart_each.html b/test/g.raphael/examples/piechart/piechart_each.html
new file mode 100644
index 0000000..e66be8d
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_each.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - iterating through sectors using .each()</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 200,
+ // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
+ var pie = r.g.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);
+
+ // revealing the value of each sector by iterating through the piechart with .each
+
+ // simple callback that logs each sector received
+ var callback = function() {
+ console.log(this.sector);
+ };
+
+ pie.each(callback);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/test/g.raphael/examples/piechart/piechart_hover.html b/test/g.raphael/examples/piechart/piechart_hover.html
new file mode 100644
index 0000000..f3a62a8
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_hover.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - a .hover() example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 200,
+ // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
+ var pie = r.g.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]).attr({fill:"#666"});
+
+ // add a hover event to the pie chart
+ pie.hover(function() {
+ // when mouse hovers over sector
+ this.sector.attr({fill:"#FAA"});
+ }, function() {
+ // when mouse hovers out
+ this.sector.attr({fill:"#666"});
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/piechart/piechart_hover_adv.html b/test/g.raphael/examples/piechart/piechart_hover_adv.html
new file mode 100644
index 0000000..ce41d3a
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_hover_adv.html
@@ -0,0 +1,41 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - a more complex .hover() example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 200,
+ // radius 100 and data: [55, 20, 13, 32]
+ var pie = r.g.piechart(320, 240, 100, [55, 20, 13, 32]).attr({"fill":"#666"});
+
+ var tooltip;
+ // add a hover event to the pie chart
+ pie.hover(function() {
+ // we store the sector that's being hovered
+ var that = this.sector;
+ // loop through the pie and highlight the hovered sector while dimming the rest
+ // also show the value of the hovered sector
+ pie.each(function() {
+ if(this.sector.id === that.id) {
+ this.sector.attr({fill:"#666"});
+ tooltip = r.g.text(this.x, this.y, this.sector.value.value).attr({"font-size": 15, "fill":"#FFF"});
+
+ } else {
+ this.sector.animate({"opacity":0.25}, 1000);
+ }
+ });
+ }, function() {
+ // when mouse hovers out, restore pie to original color
+ tooltip.remove();
+ pie.animate({"opacity":1, "fill":"#666"}, 1000);
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/piechart/piechart_rotate.html b/test/g.raphael/examples/piechart/piechart_rotate.html
new file mode 100644
index 0000000..1ee3a24
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_rotate.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - rotate your piechart</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 240,
+ // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
+ var pie = r.g.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2]);
+ var orientation = r.g.line(100, 50, 20).attr({"fill":"#333"});
+ // add a click event to the pie chart and rotate pie
+ // note: after click event is triggered, the pie no longer seems clickable?
+ pie.click(function() {
+ pie.each(function(){
+ this.sector.animate({"opacity": 0,"rotation": "180 320 240"}, 2000, ">");
+ });
+ orientation.animate({"stroke-opacity":0.25, "opacity":0.5, "rotation": "180 100 50"}, 2000, ">");
+ });
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/piechart/piechart_with_legend.html b/test/g.raphael/examples/piechart/piechart_with_legend.html
new file mode 100644
index 0000000..721656a
--- /dev/null
+++ b/test/g.raphael/examples/piechart/piechart_with_legend.html
@@ -0,0 +1,20 @@
+<html>
+ <head>
+ <title>gRaphaël Pie Chart - a piechart with legend example</title>
+ <script type="text/javascript" src="../raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.raphael-min.js"></script>
+ <script type="text/javascript" src="../../g.pie-min.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ // Creates canvas 640 × 480 at 10, 50
+ var r = Raphael(10, 50, 640, 480);
+ // Creates pie chart at with center at 320, 200,
+ // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
+ // Add legend to piechart.
+ var pie = r.g.piechart(320, 240, 100, [10,20,30,40], {legend:['%% apples', '%% bananas', '%% cherries', '%% durians'], legendmark:"*", legendpos: "south"});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html> \ No newline at end of file
diff --git a/test/g.raphael/examples/raphael-min.js b/test/g.raphael/examples/raphael-min.js
new file mode 100644
index 0000000..33e620e
--- /dev/null
+++ b/test/g.raphael/examples/raphael-min.js
@@ -0,0 +1,116 @@
+/*
+ * Raphael 1.4.7 - JavaScript Vector Library
+ *
+ * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+Raphael=function(){function l(){if(l.is(arguments[0],U)){for(var a=arguments[0],b=Ca[K](l,a.splice(0,3+l.is(a[0],P))),c=b.set(),d=0,f=a[o];d<f;d++){var e=a[d]||{};sb.test(e.type)&&c[F](b[e.type]().attr(e))}return c}return Ca[K](l,arguments)}l.version="1.4.7";var V=/[, ]+/,sb=/^(circle|rect|path|ellipse|text|image)$/,p="prototype",z="hasOwnProperty",C=document,aa=window,Qa={was:Object[p][z].call(aa,"Raphael"),is:aa.Raphael};function H(){}var x="appendChild",K="apply",M="concat",Da="createTouch"in C,
+A="",N=" ",D=String,G="split",Ra="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[G](N),Ea={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},R="join",o="length",fa=String[p].toLowerCase,v=Math,Y=v.max,ba=v.min,P="number",ga="string",U="array",O="toString",ca="fill",tb=Object[p][O],E=v.pow,F="push",ja=/^(?=[\da-f]$)/,Sa=/^url\(['"]?([^\)]+?)['"]?\)$/i,ub=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+(?:\s*,\s*[\d\.]+)?)\s*\)|rgba?\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%(?:\s*,\s*[\d\.]+%)?)\s*\)|hsb\(\s*([\d\.]+(?:deg|\xb0)?\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hsb\(\s*([\d\.]+(?:deg|\xb0|%)\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hsl\(\s*([\d\.]+(?:deg|\xb0)?\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hsl\(\s*([\d\.]+(?:deg|\xb0|%)\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i,
+Q=v.round,W="setAttribute",y=parseFloat,ha=parseInt,Fa=" progid:DXImageTransform.Microsoft",sa=String[p].toUpperCase,ta={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt",
+"stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},Ga={along:"along",blur:P,"clip-rect":"csv",cx:P,cy:P,fill:"colour","fill-opacity":P,"font-size":P,height:P,opacity:P,path:"path",r:P,rotation:"csv",rx:P,ry:P,scale:"csv",stroke:"colour","stroke-opacity":P,"stroke-width":P,translation:"csv",width:P,x:P,y:P},I="replace";l.type=aa.SVGAngle||C.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure",
+"1.1")?"SVG":"VML";if(l.type=="VML"){var da=C.createElement("div");da.innerHTML='<v:shape adj="1"/>';da=da.firstChild;da.style.behavior="url(#default#VML)";if(!(da&&typeof da.adj=="object"))return l.type=null;da=null}l.svg=!(l.vml=l.type=="VML");H[p]=l[p];l._id=0;l._oid=0;l.fn={};l.is=function(a,b){b=fa.call(b);return b=="object"&&a===Object(a)||b=="undefined"&&typeof a==b||b=="null"&&a==null||b=="array"&&Array.isArray&&Array.isArray(a)||fa.call(tb.call(a).slice(8,-1))==b};l.setWindow=function(a){aa=
+a;C=aa.document};function ua(a){if(l.vml){var b=/^\s+|\s+$/g;ua=Z(function(d){var f;d=D(d)[I](b,A);try{var e=new aa.ActiveXObject("htmlfile");e.write("<body>");e.close();f=e.body}catch(g){f=aa.createPopup().document.body}e=f.createTextRange();try{f.style.color=d;var h=e.queryCommandValue("ForeColor");h=(h&255)<<16|h&65280|(h&16711680)>>>16;return"#"+("000000"+h[O](16)).slice(-6)}catch(i){return"none"}})}else{var c=C.createElement("i");c.title="Rapha\u00ebl Colour Picker";c.style.display="none";C.body[x](c);
+ua=Z(function(d){c.style.color=d;return C.defaultView.getComputedStyle(c,A).getPropertyValue("color")})}return ua(a)}function Ta(){return"hsb("+[this.h,this.s,this.b]+")"}function vb(){return"hsl("+[this.h,this.s,this.l]+")"}function wb(){return this.hex}l.hsb2rgb=function(a,b,c){if(l.is(a,"object")&&"h"in a&&"s"in a&&"b"in a){c=a.b;b=a.s;a=a.h}return l.hsl2rgb(a,b,c/2)};l.hsl2rgb=function(a,b,c){if(l.is(a,"object")&&"h"in a&&"s"in a&&"l"in a){c=a.l;b=a.s;a=a.h}if(a>1||b>1||c>1){a/=255;b/=255;c/=
+255}var d={},f=["r","g","b"],e;if(b){b=c<0.5?c*(1+b):c+b-c*b;c=2*c-b;for(var g=0,h=f.length;g<h;g++){e=a+1/3*-(g-1);e<0&&e++;e>1&&e--;d[f[g]]=e*6<1?c+(b-c)*6*e:e*2<1?b:e*3<2?c+(b-c)*(2/3-e)*6:c}}else d={r:c,g:c,b:c};d.r*=255;d.g*=255;d.b*=255;a=(~~d.r)[O](16);f=(~~d.g)[O](16);b=(~~d.b)[O](16);a=a[I](ja,"0");f=f[I](ja,"0");b=b[I](ja,"0");d.hex="#"+a+f+b;d.toString=wb;return d};l.rgb2hsb=function(a,b,c){if(b==null&&l.is(a,"object")&&"r"in a&&"g"in a&&"b"in a){c=a.b;b=a.g;a=a.r}if(b==null&&l.is(a,ga)){var d=
+l.getRGB(a);a=d.r;b=d.g;c=d.b}if(a>1||b>1||c>1){a/=255;b/=255;c/=255}var f=Y(a,b,c),e=ba(a,b,c);d=f;if(e==f)return{h:0,s:0,b:f,toString:Ta};else{var g=f-e;e=g/f;a=a==f?(b-c)/g:b==f?2+(c-a)/g:4+(a-b)/g;a/=6;a<0&&a++;a>1&&a--}return{h:a,s:e,b:d,toString:Ta}};l.rgb2hsl=function(a,b,c){if(b==null&&l.is(a,"object")&&"r"in a&&"g"in a&&"b"in a){c=a.b;b=a.g;a=a.r}if(b==null&&l.is(a,ga)){var d=l.getRGB(a);a=d.r;b=d.g;c=d.b}if(a>1||b>1||c>1){a/=255;b/=255;c/=255}var f=Y(a,b,c),e=ba(a,b,c);d=(f+e)/2;if(e==f)a=
+{h:0,s:0,l:d};else{var g=f-e;e=d<0.5?g/(f+e):g/(2-f-e);a=a==f?(b-c)/g:b==f?2+(c-a)/g:4+(a-b)/g;a/=6;a<0&&a++;a>1&&a--;a={h:a,s:e,l:d}}a.toString=vb;return a};var xb=/,?([achlmqrstvxz]),?/gi,ka=/\s*,\s*/,yb={hs:1,rg:1};l._path2string=function(){return this.join(",")[I](xb,"$1")};function Z(a,b,c){function d(){var f=Array[p].slice.call(arguments,0),e=f[R]("\u25ba"),g=d.cache=d.cache||{},h=d.count=d.count||[];if(g[z](e))return c?c(g[e]):g[e];h[o]>=1000&&delete g[h.shift()];h[F](e);g[e]=a[K](b,f);return c?
+c(g[e]):g[e]}return d}l.getRGB=Z(function(a){if(!a||(a=D(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1};if(a=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(yb[z](a.substring(0,2))||a.charAt()=="#")&&(a=ua(a));var b,c,d,f,e;if(a=a.match(ub)){if(a[2]){d=ha(a[2].substring(5),16);c=ha(a[2].substring(3,5),16);b=ha(a[2].substring(1,3),16)}if(a[3]){d=ha((e=a[3].charAt(3))+e,16);c=ha((e=a[3].charAt(2))+e,16);b=ha((e=a[3].charAt(1))+e,16)}if(a[4]){a=a[4][G](ka);b=y(a[0]);c=y(a[1]);d=y(a[2]);f=y(a[3])}if(a[5]){a=
+a[5][G](ka);b=y(a[0])*2.55;c=y(a[1])*2.55;d=y(a[2])*2.55;f=y(a[3])}if(a[6]){a=a[6][G](ka);b=y(a[0]);c=y(a[1]);d=y(a[2]);(a[0].slice(-3)=="deg"||a[0].slice(-1)=="\u00b0")&&(b/=360);return l.hsb2rgb(b,c,d)}if(a[7]){a=a[7][G](ka);b=y(a[0])*2.55;c=y(a[1])*2.55;d=y(a[2])*2.55;(a[0].slice(-3)=="deg"||a[0].slice(-1)=="\u00b0")&&(b/=360*2.55);return l.hsb2rgb(b,c,d)}if(a[8]){a=a[8][G](ka);b=y(a[0]);c=y(a[1]);d=y(a[2]);(a[0].slice(-3)=="deg"||a[0].slice(-1)=="\u00b0")&&(b/=360);return l.hsl2rgb(b,c,d)}if(a[9]){a=
+a[9][G](ka);b=y(a[0])*2.55;c=y(a[1])*2.55;d=y(a[2])*2.55;(a[0].slice(-3)=="deg"||a[0].slice(-1)=="\u00b0")&&(b/=360*2.55);return l.hsl2rgb(b,c,d)}a={r:b,g:c,b:d};b=(~~b)[O](16);c=(~~c)[O](16);d=(~~d)[O](16);b=b[I](ja,"0");c=c[I](ja,"0");d=d[I](ja,"0");a.hex="#"+b+c+d;isFinite(y(f))&&(a.o=f);return a}return{r:-1,g:-1,b:-1,hex:"none",error:1}},l);l.getColor=function(a){a=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75};var b=this.hsb2rgb(a.h,a.s,a.b);a.h+=0.075;if(a.h>1){a.h=0;a.s-=0.2;
+a.s<=0&&(this.getColor.start={h:0,s:1,b:a.b})}return b.hex};l.getColor.reset=function(){delete this.start};var zb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,Ab=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig;l.parsePathString=Z(function(a){if(!a)return null;var b={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},c=[];if(l.is(a,U)&&l.is(a[0],U))c=va(a);c[o]||D(a)[I](zb,function(d,f,e){var g=[];d=fa.call(f);e[I](Ab,function(h,i){i&&g[F](+i)});if(d=="m"&&g[o]>2){c[F]([f][M](g.splice(0,2)));d="l";
+f=f=="m"?"l":"L"}for(;g[o]>=b[d];){c[F]([f][M](g.splice(0,b[d])));if(!b[d])break}});c[O]=l._path2string;return c});l.findDotsAtSegment=function(a,b,c,d,f,e,g,h,i){var j=1-i,m=E(j,3)*a+E(j,2)*3*i*c+j*3*i*i*f+E(i,3)*g;j=E(j,3)*b+E(j,2)*3*i*d+j*3*i*i*e+E(i,3)*h;var n=a+2*i*(c-a)+i*i*(f-2*c+a),r=b+2*i*(d-b)+i*i*(e-2*d+b),q=c+2*i*(f-c)+i*i*(g-2*f+c),k=d+2*i*(e-d)+i*i*(h-2*e+d);a=(1-i)*a+i*c;b=(1-i)*b+i*d;f=(1-i)*f+i*g;e=(1-i)*e+i*h;h=90-v.atan((n-q)/(r-k))*180/v.PI;(n>q||r<k)&&(h+=180);return{x:m,y:j,
+m:{x:n,y:r},n:{x:q,y:k},start:{x:a,y:b},end:{x:f,y:e},alpha:h}};var xa=Z(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=wa(a);for(var b=0,c=0,d=[],f=[],e,g=0,h=a[o];g<h;g++){e=a[g];if(e[0]=="M"){b=e[1];c=e[2];d[F](b);f[F](c)}else{b=Bb(b,c,e[1],e[2],e[3],e[4],e[5],e[6]);d=d[M](b.min.x,b.max.x);f=f[M](b.min.y,b.max.y);b=e[5];c=e[6]}}a=ba[K](0,d);e=ba[K](0,f);return{x:a,y:e,width:Y[K](0,d)-a,height:Y[K](0,f)-e}});function va(a){var b=[];if(!l.is(a,U)||!l.is(a&&a[0],U))a=l.parsePathString(a);for(var c=
+0,d=a[o];c<d;c++){b[c]=[];for(var f=0,e=a[c][o];f<e;f++)b[c][f]=a[c][f]}b[O]=l._path2string;return b}var Ha=Z(function(a){if(!l.is(a,U)||!l.is(a&&a[0],U))a=l.parsePathString(a);var b=[],c=0,d=0,f=0,e=0,g=0;if(a[0][0]=="M"){c=a[0][1];d=a[0][2];f=c;e=d;g++;b[F](["M",c,d])}g=g;for(var h=a[o];g<h;g++){var i=b[g]=[],j=a[g];if(j[0]!=fa.call(j[0])){i[0]=fa.call(j[0]);switch(i[0]){case "a":i[1]=j[1];i[2]=j[2];i[3]=j[3];i[4]=j[4];i[5]=j[5];i[6]=+(j[6]-c).toFixed(3);i[7]=+(j[7]-d).toFixed(3);break;case "v":i[1]=
++(j[1]-d).toFixed(3);break;case "m":f=j[1];e=j[2];default:for(var m=1,n=j[o];m<n;m++)i[m]=+(j[m]-(m%2?c:d)).toFixed(3)}}else{b[g]=[];if(j[0]=="m"){f=j[1]+c;e=j[2]+d}i=0;for(m=j[o];i<m;i++)b[g][i]=j[i]}j=b[g][o];switch(b[g][0]){case "z":c=f;d=e;break;case "h":c+=+b[g][j-1];break;case "v":d+=+b[g][j-1];break;default:c+=+b[g][j-2];d+=+b[g][j-1]}}b[O]=l._path2string;return b},0,va),oa=Z(function(a){if(!l.is(a,U)||!l.is(a&&a[0],U))a=l.parsePathString(a);var b=[],c=0,d=0,f=0,e=0,g=0;if(a[0][0]=="M"){c=
++a[0][1];d=+a[0][2];f=c;e=d;g++;b[0]=["M",c,d]}g=g;for(var h=a[o];g<h;g++){var i=b[g]=[],j=a[g];if(j[0]!=sa.call(j[0])){i[0]=sa.call(j[0]);switch(i[0]){case "A":i[1]=j[1];i[2]=j[2];i[3]=j[3];i[4]=j[4];i[5]=j[5];i[6]=+(j[6]+c);i[7]=+(j[7]+d);break;case "V":i[1]=+j[1]+d;break;case "H":i[1]=+j[1]+c;break;case "M":f=+j[1]+c;e=+j[2]+d;default:for(var m=1,n=j[o];m<n;m++)i[m]=+j[m]+(m%2?c:d)}}else{m=0;for(n=j[o];m<n;m++)b[g][m]=j[m]}switch(i[0]){case "Z":c=f;d=e;break;case "H":c=i[1];break;case "V":d=i[1];
+break;case "M":f=b[g][b[g][o]-2];e=b[g][b[g][o]-1];default:c=b[g][b[g][o]-2];d=b[g][b[g][o]-1]}}b[O]=l._path2string;return b},null,va);function ya(a,b,c,d){return[a,b,c,d,c,d]}function Ua(a,b,c,d,f,e){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*f+h*c,g*e+h*d,f,e]}function Va(a,b,c,d,f,e,g,h,i,j){var m=v.PI,n=m*120/180,r=m/180*(+f||0),q=[],k,t=Z(function(J,ia,za){var Cb=J*v.cos(za)-ia*v.sin(za);J=J*v.sin(za)+ia*v.cos(za);return{x:Cb,y:J}});if(j){w=j[0];k=j[1];e=j[2];B=j[3]}else{k=t(a,b,-r);a=k.x;b=k.y;
+k=t(h,i,-r);h=k.x;i=k.y;v.cos(m/180*f);v.sin(m/180*f);k=(a-h)/2;w=(b-i)/2;B=k*k/(c*c)+w*w/(d*d);if(B>1){B=v.sqrt(B);c=B*c;d=B*d}B=c*c;var L=d*d;B=(e==g?-1:1)*v.sqrt(v.abs((B*L-B*w*w-L*k*k)/(B*w*w+L*k*k)));e=B*c*w/d+(a+h)/2;var B=B*-d*k/c+(b+i)/2,w=v.asin(((b-B)/d).toFixed(7));k=v.asin(((i-B)/d).toFixed(7));w=a<e?m-w:w;k=h<e?m-k:k;w<0&&(w=m*2+w);k<0&&(k=m*2+k);if(g&&w>k)w-=m*2;if(!g&&k>w)k-=m*2}m=k-w;if(v.abs(m)>n){q=k;m=h;L=i;k=w+n*(g&&k>w?1:-1);h=e+c*v.cos(k);i=B+d*v.sin(k);q=Va(h,i,c,d,f,0,g,m,
+L,[k,q,e,B])}m=k-w;f=v.cos(w);e=v.sin(w);g=v.cos(k);k=v.sin(k);m=v.tan(m/4);c=4/3*c*m;m=4/3*d*m;d=[a,b];a=[a+c*e,b-m*f];b=[h+c*k,i-m*g];h=[h,i];a[0]=2*d[0]-a[0];a[1]=2*d[1]-a[1];if(j)return[a,b,h][M](q);else{q=[a,b,h][M](q)[R]()[G](",");j=[];h=0;for(i=q[o];h<i;h++)j[h]=h%2?t(q[h-1],q[h],r).y:t(q[h],q[h+1],r).x;return j}}function la(a,b,c,d,f,e,g,h,i){var j=1-i;return{x:E(j,3)*a+E(j,2)*3*i*c+j*3*i*i*f+E(i,3)*g,y:E(j,3)*b+E(j,2)*3*i*d+j*3*i*i*e+E(i,3)*h}}var Bb=Z(function(a,b,c,d,f,e,g,h){var i=f-2*
+c+a-(g-2*f+c),j=2*(c-a)-2*(f-c),m=a-c,n=(-j+v.sqrt(j*j-4*i*m))/2/i;i=(-j-v.sqrt(j*j-4*i*m))/2/i;var r=[b,h],q=[a,g];v.abs(n)>1000000000000&&(n=0.5);v.abs(i)>1000000000000&&(i=0.5);if(n>0&&n<1){n=la(a,b,c,d,f,e,g,h,n);q[F](n.x);r[F](n.y)}if(i>0&&i<1){n=la(a,b,c,d,f,e,g,h,i);q[F](n.x);r[F](n.y)}i=e-2*d+b-(h-2*e+d);j=2*(d-b)-2*(e-d);m=b-d;n=(-j+v.sqrt(j*j-4*i*m))/2/i;i=(-j-v.sqrt(j*j-4*i*m))/2/i;v.abs(n)>1000000000000&&(n=0.5);v.abs(i)>1000000000000&&(i=0.5);if(n>0&&n<1){n=la(a,b,c,d,f,e,g,h,n);q[F](n.x);
+r[F](n.y)}if(i>0&&i<1){n=la(a,b,c,d,f,e,g,h,i);q[F](n.x);r[F](n.y)}return{min:{x:ba[K](0,q),y:ba[K](0,r)},max:{x:Y[K](0,q),y:Y[K](0,r)}}}),wa=Z(function(a,b){var c=oa(a),d=b&&oa(b);a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null};b={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null};function f(q,k){var t;if(!q)return["C",k.x,k.y,k.x,k.y,k.x,k.y];!(q[0]in{T:1,Q:1})&&(k.qx=k.qy=null);switch(q[0]){case "M":k.X=q[1];k.Y=q[2];break;case "A":q=["C"][M](Va[K](0,[k.x,k.y][M](q.slice(1))));break;case "S":t=k.x+(k.x-
+(k.bx||k.x));k=k.y+(k.y-(k.by||k.y));q=["C",t,k][M](q.slice(1));break;case "T":k.qx=k.x+(k.x-(k.qx||k.x));k.qy=k.y+(k.y-(k.qy||k.y));q=["C"][M](Ua(k.x,k.y,k.qx,k.qy,q[1],q[2]));break;case "Q":k.qx=q[1];k.qy=q[2];q=["C"][M](Ua(k.x,k.y,q[1],q[2],q[3],q[4]));break;case "L":q=["C"][M](ya(k.x,k.y,q[1],q[2]));break;case "H":q=["C"][M](ya(k.x,k.y,q[1],k.y));break;case "V":q=["C"][M](ya(k.x,k.y,k.x,q[1]));break;case "Z":q=["C"][M](ya(k.x,k.y,k.X,k.Y));break}return q}function e(q,k){if(q[k][o]>7){q[k].shift();
+for(var t=q[k];t[o];)q.splice(k++,0,["C"][M](t.splice(0,6)));q.splice(k,1);i=Y(c[o],d&&d[o]||0)}}function g(q,k,t,L,B){if(q&&k&&q[B][0]=="M"&&k[B][0]!="M"){k.splice(B,0,["M",L.x,L.y]);t.bx=0;t.by=0;t.x=q[B][1];t.y=q[B][2];i=Y(c[o],d&&d[o]||0)}}for(var h=0,i=Y(c[o],d&&d[o]||0);h<i;h++){c[h]=f(c[h],a);e(c,h);d&&(d[h]=f(d[h],b));d&&e(d,h);g(c,d,a,b,h);g(d,c,b,a,h);var j=c[h],m=d&&d[h],n=j[o],r=d&&m[o];a.x=j[n-2];a.y=j[n-1];a.bx=y(j[n-4])||a.x;a.by=y(j[n-3])||a.y;b.bx=d&&(y(m[r-4])||b.x);b.by=d&&(y(m[r-
+3])||b.y);b.x=d&&m[r-2];b.y=d&&m[r-1]}return d?[c,d]:c},null,va),Wa=Z(function(a){for(var b=[],c=0,d=a[o];c<d;c++){var f={},e=a[c].match(/^([^:]*):?([\d\.]*)/);f.color=l.getRGB(e[1]);if(f.color.error)return null;f.color=f.color.hex;e[2]&&(f.offset=e[2]+"%");b[F](f)}c=1;for(d=b[o]-1;c<d;c++)if(!b[c].offset){a=y(b[c-1].offset||0);e=0;for(f=c+1;f<d;f++)if(b[f].offset){e=b[f].offset;break}if(!e){e=100;f=d}e=y(e);for(e=(e-a)/(f-c+1);c<f;c++){a+=e;b[c].offset=a+"%"}}return b});function Xa(a,b,c,d){if(l.is(a,
+ga)||l.is(a,"object")){a=l.is(a,ga)?C.getElementById(a):a;if(a.tagName)return b==null?{container:a,width:a.style.pixelWidth||a.offsetWidth,height:a.style.pixelHeight||a.offsetHeight}:{container:a,width:b,height:c}}else return{container:1,x:a,y:b,width:c,height:d}}function Ia(a,b){var c=this;for(var d in b)if(b[z](d)&&!(d in a))switch(typeof b[d]){case "function":(function(f){a[d]=a===c?f:function(){return f[K](c,arguments)}})(b[d]);break;case "object":a[d]=a[d]||{};Ia.call(this,a[d],b[d]);break;default:a[d]=
+b[d];break}}function ma(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)}function Ya(a,b){if(b.top!==a){ma(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a}}function Za(a,b){if(b.bottom!==a){ma(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a}}function $a(a,b,c){ma(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a}function ab(a,b,c){ma(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=
+a);a.prev=b.prev;b.prev=a;a.next=b}function bb(a){return function(){throw new Error("Rapha\u00ebl: you are calling to method \u201c"+a+"\u201d of removed object");}}var cb=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;l.pathToRelative=Ha;if(l.svg){H[p].svgns="http://www.w3.org/2000/svg";H[p].xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~~a===a)*0.5};var u=function(a,b){if(b)for(var c in b)b[z](c)&&a[W](c,D(b[c]));else{a=C.createElementNS(H[p].svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";
+return a}};l[O]=function(){return"Your browser supports SVG.\nYou are running Rapha\u00ebl "+this.version};var db=function(a,b){var c=u("path");b.canvas&&b.canvas[x](c);b=new s(c,b);b.type="path";ea(b,{fill:"none",stroke:"#000",path:a});return b},pa=function(a,b,c){var d="linear",f=0.5,e=0.5,g=a.style;b=D(b)[I](cb,function(m,n,r){d="radial";if(n&&r){f=y(n);e=y(r);m=(e>0.5)*2-1;E(f-0.5,2)+E(e-0.5,2)>0.25&&(e=v.sqrt(0.25-E(f-0.5,2))*m+0.5)&&e!=0.5&&(e=e.toFixed(5)-1.0E-5*m)}return A});b=b[G](/\s*\-\s*/);
+if(d=="linear"){var h=b.shift();h=-y(h);if(isNaN(h))return null;h=[0,0,v.cos(h*v.PI/180),v.sin(h*v.PI/180)];var i=1/(Y(v.abs(h[2]),v.abs(h[3]))||1);h[2]*=i;h[3]*=i;if(h[2]<0){h[0]=-h[2];h[2]=0}if(h[3]<0){h[1]=-h[3];h[3]=0}}b=Wa(b);if(!b)return null;i=a.getAttribute(ca);(i=i.match(/^url\(#(.*)\)$/))&&c.defs.removeChild(C.getElementById(i[1]));i=u(d+"Gradient");i.id="r"+(l._id++)[O](36);u(i,d=="radial"?{fx:f,fy:e}:{x1:h[0],y1:h[1],x2:h[2],y2:h[3]});c.defs[x](i);c=0;for(h=b[o];c<h;c++){var j=u("stop");
+u(j,{offset:b[c].offset?b[c].offset:!c?"0%":"100%","stop-color":b[c].color||"#fff"});i[x](j)}u(a,{fill:"url(#"+i.id+")",opacity:1,"fill-opacity":1});g.fill=A;g.opacity=1;return g.fillOpacity=1},Ja=function(a){var b=a.getBBox();u(a.pattern,{patternTransform:l.format("translate({0},{1})",b.x,b.y)})},ea=function(a,b){var c={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},d=a.node,f=a.attrs,e=
+a.rotate();function g(k,t){if(t=c[fa.call(t)]){var L=k.attrs["stroke-width"]||"1";k={round:L,square:L,butt:0}[k.attrs["stroke-linecap"]||b["stroke-linecap"]]||0;for(var B=[],w=t[o];w--;)B[w]=t[w]*L+(w%2?1:-1)*k;u(d,{"stroke-dasharray":B[R](",")})}}b[z]("rotation")&&(e=b.rotation);var h=D(e)[G](V);if(h.length-1){h[1]=+h[1];h[2]=+h[2]}else h=null;y(e)&&a.rotate(0,true);for(var i in b)if(b[z](i))if(ta[z](i)){var j=b[i];f[i]=j;switch(i){case "blur":a.blur(j);break;case "rotation":a.rotate(j,true);break;
+case "href":case "title":case "target":var m=d.parentNode;if(fa.call(m.tagName)!="a"){var n=u("a");m.insertBefore(n,d);n[x](d);m=n}m.setAttributeNS(a.paper.xlink,i,j);break;case "cursor":d.style.cursor=j;break;case "clip-rect":m=D(j)[G](V);if(m[o]==4){a.clip&&a.clip.parentNode.parentNode.removeChild(a.clip.parentNode);var r=u("clipPath");n=u("rect");r.id="r"+(l._id++)[O](36);u(n,{x:m[0],y:m[1],width:m[2],height:m[3]});r[x](n);a.paper.defs[x](r);u(d,{"clip-path":"url(#"+r.id+")"});a.clip=n}if(!j){(j=
+C.getElementById(d.getAttribute("clip-path")[I](/(^url\(#|\)$)/g,A)))&&j.parentNode.removeChild(j);u(d,{"clip-path":A});delete a.clip}break;case "path":if(a.type=="path")u(d,{d:j?(f.path=oa(j)):"M0,0"});break;case "width":d[W](i,j);if(f.fx){i="x";j=f.x}else break;case "x":if(f.fx)j=-f.x-(f.width||0);case "rx":if(i=="rx"&&a.type=="rect")break;case "cx":h&&(i=="x"||i=="cx")&&(h[1]+=j-f[i]);d[W](i,j);a.pattern&&Ja(a);break;case "height":d[W](i,j);if(f.fy){i="y";j=f.y}else break;case "y":if(f.fy)j=-f.y-
+(f.height||0);case "ry":if(i=="ry"&&a.type=="rect")break;case "cy":h&&(i=="y"||i=="cy")&&(h[2]+=j-f[i]);d[W](i,j);a.pattern&&Ja(a);break;case "r":a.type=="rect"?u(d,{rx:j,ry:j}):d[W](i,j);break;case "src":a.type=="image"&&d.setAttributeNS(a.paper.xlink,"href",j);break;case "stroke-width":d.style.strokeWidth=j;d[W](i,j);f["stroke-dasharray"]&&g(a,f["stroke-dasharray"]);break;case "stroke-dasharray":g(a,j);break;case "translation":j=D(j)[G](V);j[0]=+j[0]||0;j[1]=+j[1]||0;if(h){h[1]+=j[0];h[2]+=j[1]}Aa.call(a,
+j[0],j[1]);break;case "scale":j=D(j)[G](V);a.scale(+j[0]||1,+j[1]||+j[0]||1,isNaN(y(j[2]))?null:+j[2],isNaN(y(j[3]))?null:+j[3]);break;case ca:if(m=D(j).match(Sa)){r=u("pattern");var q=u("image");r.id="r"+(l._id++)[O](36);u(r,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});u(q,{x:0,y:0});q.setAttributeNS(a.paper.xlink,"href",m[1]);r[x](q);j=C.createElement("img");j.style.cssText="position:absolute;left:-9999em;top-9999em";j.onload=function(){u(r,{width:this.offsetWidth,height:this.offsetHeight});
+u(q,{width:this.offsetWidth,height:this.offsetHeight});C.body.removeChild(this);a.paper.safari()};C.body[x](j);j.src=m[1];a.paper.defs[x](r);d.style.fill="url(#"+r.id+")";u(d,{fill:"url(#"+r.id+")"});a.pattern=r;a.pattern&&Ja(a);break}m=l.getRGB(j);if(m.error){if(({circle:1,ellipse:1}[z](a.type)||D(j).charAt()!="r")&&pa(d,j,a.paper)){f.gradient=j;f.fill="none";break}}else{delete b.gradient;delete f.gradient;!l.is(f.opacity,"undefined")&&l.is(b.opacity,"undefined")&&u(d,{opacity:f.opacity});!l.is(f["fill-opacity"],
+"undefined")&&l.is(b["fill-opacity"],"undefined")&&u(d,{"fill-opacity":f["fill-opacity"]})}m[z]("o")&&u(d,{"fill-opacity":m.o>1?m.o/100:m.o});case "stroke":m=l.getRGB(j);d[W](i,m.hex);i=="stroke"&&m[z]("o")&&u(d,{"stroke-opacity":m.o>1?m.o/100:m.o});break;case "gradient":(({circle:1,ellipse:1})[z](a.type)||D(j).charAt()!="r")&&pa(d,j,a.paper);break;case "opacity":case "fill-opacity":if(f.gradient){if(m=C.getElementById(d.getAttribute(ca)[I](/^url\(#|\)$/g,A))){m=m.getElementsByTagName("stop");m[m[o]-
+1][W]("stop-opacity",j)}break}default:i=="font-size"&&(j=ha(j,10)+"px");m=i[I](/(\-.)/g,function(k){return sa.call(k.substring(1))});d.style[m]=j;d[W](i,j);break}}Db(a,b);if(h)a.rotate(h.join(N));else y(e)&&a.rotate(e,true)},eb=1.2,Db=function(a,b){if(!(a.type!="text"||!(b[z]("text")||b[z]("font")||b[z]("font-size")||b[z]("x")||b[z]("y")))){var c=a.attrs,d=a.node,f=d.firstChild?ha(C.defaultView.getComputedStyle(d.firstChild,A).getPropertyValue("font-size"),10):10;if(b[z]("text")){for(c.text=b.text;d.firstChild;)d.removeChild(d.firstChild);
+b=D(b.text)[G]("\n");for(var e=0,g=b[o];e<g;e++)if(b[e]){var h=u("tspan");e&&u(h,{dy:f*eb,x:c.x});h[x](C.createTextNode(b[e]));d[x](h)}}else{b=d.getElementsByTagName("tspan");e=0;for(g=b[o];e<g;e++)e&&u(b[e],{dy:f*eb,x:c.x})}u(d,{y:c.y});a=a.getBBox();(a=c.y-(a.y+a.height/2))&&isFinite(a)&&u(d,{y:c.y+a})}},s=function(a,b){this[0]=a;this.id=l._oid++;this.node=a;a.raphael=this;this.paper=b;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!b.bottom&&
+(b.bottom=this);(this.prev=b.top)&&(b.top.next=this);b.top=this;this.next=null};s[p].rotate=function(a,b,c){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][R](N);return this._.rt.deg}var d=this.getBBox();a=D(a)[G](V);if(a[o]-1){b=y(a[1]);c=y(a[2])}a=y(a[0]);if(b!=null)this._.rt.deg=a;else this._.rt.deg+=a;c==null&&(b=null);this._.rt.cx=b;this._.rt.cy=c;b=b==null?d.x+d.width/2:b;c=c==null?d.y+d.height/2:c;if(this._.rt.deg){this.transformations[0]=
+l.format("rotate({0} {1} {2})",this._.rt.deg,b,c);this.clip&&u(this.clip,{transform:l.format("rotate({0} {1} {2})",-this._.rt.deg,b,c)})}else{this.transformations[0]=A;this.clip&&u(this.clip,{transform:A})}u(this.node,{transform:this.transformations[R](N)});return this};s[p].hide=function(){!this.removed&&(this.node.style.display="none");return this};s[p].show=function(){!this.removed&&(this.node.style.display="");return this};s[p].remove=function(){if(!this.removed){ma(this,this.paper);this.node.parentNode.removeChild(this.node);
+for(var a in this)delete this[a];this.removed=true}};s[p].getBBox=function(){if(this.removed)return this;if(this.type=="path")return xa(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var d=0,f=this.node.getNumberOfChars();d<f;d++){var e=this.node.getExtentOfChar(d);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-
+b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};s[p].attr=function(a,b){if(this.removed)return this;if(a==null){a={};for(var c in this.attrs)if(this.attrs[z](c))a[c]=this.attrs[c];this._.rt.deg&&(a.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(a.scale=this.scale());a.gradient&&a.fill=="none"&&(a.fill=a.gradient)&&delete a.gradient;return a}if(b==null&&l.is(a,ga)){if(a=="translation")return Aa.call(this);if(a=="rotation")return this.rotate();if(a=="scale")return this.scale();
+if(a==ca&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[a]}if(b==null&&l.is(a,U)){b={};c=0;for(var d=a.length;c<d;c++)b[a[c]]=this.attr(a[c]);return b}if(b!=null){c={};c[a]=b;ea(this,c)}else a!=null&&l.is(a,"object")&&ea(this,a);return this};s[p].toFront=function(){if(this.removed)return this;this.node.parentNode[x](this.node);var a=this.paper;a.top!=this&&Ya(this,a);return this};s[p].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=
+this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);Za(this,this.paper)}return this};s[p].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[x](this.node);$a(this,a,this.paper);return this};s[p].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);ab(this,a,this.paper);return this};s[p].blur=
+function(a){var b=this;if(+a!==0){var c=u("filter"),d=u("feGaussianBlur");b.attrs.blur=a;c.id="r"+(l._id++)[O](36);u(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;u(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var fb=function(a,b,c,d){var f=u("circle");a.canvas&&a.canvas[x](f);a=new s(f,a);a.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};a.type="circle";
+u(f,a.attrs);return a},gb=function(a,b,c,d,f,e){var g=u("rect");a.canvas&&a.canvas[x](g);a=new s(g,a);a.attrs={x:b,y:c,width:d,height:f,r:e||0,rx:e||0,ry:e||0,fill:"none",stroke:"#000"};a.type="rect";u(g,a.attrs);return a},hb=function(a,b,c,d,f){var e=u("ellipse");a.canvas&&a.canvas[x](e);a=new s(e,a);a.attrs={cx:b,cy:c,rx:d,ry:f,fill:"none",stroke:"#000"};a.type="ellipse";u(e,a.attrs);return a},ib=function(a,b,c,d,f,e){var g=u("image");u(g,{x:c,y:d,width:f,height:e,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,
+"href",b);a.canvas&&a.canvas[x](g);a=new s(g,a);a.attrs={x:c,y:d,width:f,height:e,src:b};a.type="image";return a},jb=function(a,b,c,d){var f=u("text");u(f,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[x](f);a=new s(f,a);a.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:ta.font,stroke:"none",fill:"#000"};a.type="text";ea(a,a.attrs);return a},kb=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[W]("width",this.width);this.canvas[W]("height",this.height);return this},
+Ca=function(){var a=Xa[K](0,arguments),b=a&&a.container,c=a.x,d=a.y,f=a.width;a=a.height;if(!b)throw new Error("SVG container not found.");var e=u("svg");c=c||0;d=d||0;f=f||512;a=a||342;u(e,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:a});if(b==1){e.style.cssText="position:absolute;left:"+c+"px;top:"+d+"px";C.body[x](e)}else b.firstChild?b.insertBefore(e,b.firstChild):b[x](e);b=new H;b.width=f;b.height=a;b.canvas=e;Ia.call(b,b,l.fn);b.clear();return b};H[p].clear=function(){for(var a=
+this.canvas;a.firstChild;)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=u("desc"))[x](C.createTextNode("Created with Rapha\u00ebl"));a[x](this.desc);a[x](this.defs=u("defs"))};H[p].remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bb(a)}}if(l.vml){var lb={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},Eb=/([clmz]),?([^clmz]*)/gi,Fb=/-?[^,\s-]+/g,qa=1000+N+1000,na=10,ra={path:1,rect:1},Gb=function(a){var b=/[ahqstv]/ig,
+c=oa;D(a).match(b)&&(c=wa);b=/[clmz]/g;if(c==oa&&!D(a).match(b))return a=D(a)[I](Eb,function(i,j,m){var n=[],r=fa.call(j)=="m",q=lb[j];m[I](Fb,function(k){if(r&&n[o]==2){q+=n+lb[j=="m"?"l":"L"];n=[]}n[F](Q(k*na))});return q+n});b=c(a);var d;a=[];for(var f=0,e=b[o];f<e;f++){c=b[f];d=fa.call(b[f][0]);d=="z"&&(d="x");for(var g=1,h=c[o];g<h;g++)d+=Q(c[g]*na)+(g!=h-1?",":A);a[F](d)}return a[R](N)};l[O]=function(){return"Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\u00ebl "+
+this.version};db=function(a,b){var c=S("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=S("shape"),f=d.style;f.width=b.width+"px";f.height=b.height+"px";d.coordsize=qa;d.coordorigin=b.coordorigin;c[x](d);d=new s(d,c,b);f={fill:"none",stroke:"#000"};a&&(f.path=a);d.isAbsolute=true;d.type="path";d.path=[];d.Path=A;ea(d,f);b.canvas[x](c);return d};ea=function(a,b){a.attrs=a.attrs||{};var c=a.node,
+d=a.attrs,f=c.style,e;e=(b.x!=d.x||b.y!=d.y||b.width!=d.width||b.height!=d.height||b.r!=d.r)&&a.type=="rect";var g=a;for(var h in b)if(b[z](h))d[h]=b[h];if(e){d.path=mb(d.x,d.y,d.width,d.height,d.r);a.X=d.x;a.Y=d.y;a.W=d.width;a.H=d.height}b.href&&(c.href=b.href);b.title&&(c.title=b.title);b.target&&(c.target=b.target);b.cursor&&(f.cursor=b.cursor);"blur"in b&&a.blur(b.blur);if(b.path&&a.type=="path"||e)c.path=Gb(d.path);b.rotation!=null&&a.rotate(b.rotation,true);if(b.translation){e=D(b.translation)[G](V);
+Aa.call(a,e[0],e[1]);if(a._.rt.cx!=null){a._.rt.cx+=+e[0];a._.rt.cy+=+e[1];a.setBox(a.attrs,e[0],e[1])}}if(b.scale){e=D(b.scale)[G](V);a.scale(+e[0]||1,+e[1]||+e[0]||1,+e[2]||null,+e[3]||null)}if("clip-rect"in b){e=D(b["clip-rect"])[G](V);if(e[o]==4){e[2]=+e[2]+ +e[0];e[3]=+e[3]+ +e[1];h=c.clipRect||C.createElement("div");var i=h.style,j=c.parentNode;i.clip=l.format("rect({1}px {2}px {3}px {0}px)",e);if(!c.clipRect){i.position="absolute";i.top=0;i.left=0;i.width=a.paper.width+"px";i.height=a.paper.height+
+"px";j.parentNode.insertBefore(h,j);h[x](j);c.clipRect=h}}if(!b["clip-rect"])c.clipRect&&(c.clipRect.style.clip=A)}if(a.type=="image"&&b.src)c.src=b.src;if(a.type=="image"&&b.opacity){c.filterOpacity=Fa+".Alpha(opacity="+b.opacity*100+")";f.filter=(c.filterMatrix||A)+(c.filterOpacity||A)}b.font&&(f.font=b.font);b["font-family"]&&(f.fontFamily='"'+b["font-family"][G](",")[0][I](/^['"]+|['"]+$/g,A)+'"');b["font-size"]&&(f.fontSize=b["font-size"]);b["font-weight"]&&(f.fontWeight=b["font-weight"]);b["font-style"]&&
+(f.fontStyle=b["font-style"]);if(b.opacity!=null||b["stroke-width"]!=null||b.fill!=null||b.stroke!=null||b["stroke-width"]!=null||b["stroke-opacity"]!=null||b["fill-opacity"]!=null||b["stroke-dasharray"]!=null||b["stroke-miterlimit"]!=null||b["stroke-linejoin"]!=null||b["stroke-linecap"]!=null){c=a.shape||c;f=c.getElementsByTagName(ca)&&c.getElementsByTagName(ca)[0];e=false;!f&&(e=f=S(ca));if("fill-opacity"in b||"opacity"in b){a=((+d["fill-opacity"]+1||2)-1)*((+d.opacity+1||2)-1)*((+l.getRGB(b.fill).o+
+1||2)-1);a<0&&(a=0);a>1&&(a=1);f.opacity=a}b.fill&&(f.on=true);if(f.on==null||b.fill=="none")f.on=false;if(f.on&&b.fill)if(a=b.fill.match(Sa)){f.src=a[1];f.type="tile"}else{f.color=l.getRGB(b.fill).hex;f.src=A;f.type="solid";if(l.getRGB(b.fill).error&&(g.type in{circle:1,ellipse:1}||D(b.fill).charAt()!="r")&&pa(g,b.fill)){d.fill="none";d.gradient=b.fill}}e&&c[x](f);f=c.getElementsByTagName("stroke")&&c.getElementsByTagName("stroke")[0];e=false;!f&&(e=f=S("stroke"));if(b.stroke&&b.stroke!="none"||
+b["stroke-width"]||b["stroke-opacity"]!=null||b["stroke-dasharray"]||b["stroke-miterlimit"]||b["stroke-linejoin"]||b["stroke-linecap"])f.on=true;(b.stroke=="none"||f.on==null||b.stroke==0||b["stroke-width"]==0)&&(f.on=false);a=l.getRGB(b.stroke);f.on&&b.stroke&&(f.color=a.hex);a=((+d["stroke-opacity"]+1||2)-1)*((+d.opacity+1||2)-1)*((+a.o+1||2)-1);h=(y(b["stroke-width"])||1)*0.75;a<0&&(a=0);a>1&&(a=1);b["stroke-width"]==null&&(h=d["stroke-width"]);b["stroke-width"]&&(f.weight=h);h&&h<1&&(a*=h)&&(f.weight=
+1);f.opacity=a;b["stroke-linejoin"]&&(f.joinstyle=b["stroke-linejoin"]||"miter");f.miterlimit=b["stroke-miterlimit"]||8;b["stroke-linecap"]&&(f.endcap=b["stroke-linecap"]=="butt"?"flat":b["stroke-linecap"]=="square"?"square":"round");if(b["stroke-dasharray"]){a={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};f.dashstyle=a[z](b["stroke-dasharray"])?a[b["stroke-dasharray"]]:
+A}e&&c[x](f)}if(g.type=="text"){f=g.paper.span.style;d.font&&(f.font=d.font);d["font-family"]&&(f.fontFamily=d["font-family"]);d["font-size"]&&(f.fontSize=d["font-size"]);d["font-weight"]&&(f.fontWeight=d["font-weight"]);d["font-style"]&&(f.fontStyle=d["font-style"]);g.node.string&&(g.paper.span.innerHTML=D(g.node.string)[I](/</g,"&#60;")[I](/&/g,"&#38;")[I](/\n/g,"<br>"));g.W=d.w=g.paper.span.offsetWidth;g.H=d.h=g.paper.span.offsetHeight;g.X=d.x;g.Y=d.y+Q(g.H/2);switch(d["text-anchor"]){case "start":g.node.style["v-text-align"]=
+"left";g.bbx=Q(g.W/2);break;case "end":g.node.style["v-text-align"]="right";g.bbx=-Q(g.W/2);break;default:g.node.style["v-text-align"]="center";break}}};pa=function(a,b){a.attrs=a.attrs||{};var c="linear",d=".5 .5";a.attrs.gradient=b;b=D(b)[I](cb,function(i,j,m){c="radial";if(j&&m){j=y(j);m=y(m);E(j-0.5,2)+E(m-0.5,2)>0.25&&(m=v.sqrt(0.25-E(j-0.5,2))*((m>0.5)*2-1)+0.5);d=j+N+m}return A});b=b[G](/\s*\-\s*/);if(c=="linear"){var f=b.shift();f=-y(f);if(isNaN(f))return null}var e=Wa(b);if(!e)return null;
+a=a.shape||a.node;b=a.getElementsByTagName(ca)[0]||S(ca);!b.parentNode&&a.appendChild(b);if(e[o]){b.on=true;b.method="none";b.color=e[0].color;b.color2=e[e[o]-1].color;a=[];for(var g=0,h=e[o];g<h;g++)e[g].offset&&a[F](e[g].offset+N+e[g].color);b.colors&&(b.colors.value=a[o]?a[R]():"0% "+b.color);if(c=="radial"){b.type="gradientradial";b.focus="100%";b.focussize=d;b.focusposition=d}else{b.type="gradient";b.angle=(270-f)%360}}return 1};s=function(a,b,c){this[0]=a;this.id=l._oid++;this.node=a;a.raphael=
+this;this.Y=this.X=0;this.attrs={};this.Group=b;this.paper=c;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);(this.prev=c.top)&&(c.top.next=this);c.top=this;this.next=null};s[p].rotate=function(a,b,c){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][R](N);return this._.rt.deg}a=D(a)[G](V);if(a[o]-1){b=y(a[1]);c=y(a[2])}a=y(a[0]);if(b!=null)this._.rt.deg=a;else this._.rt.deg+=a;c==null&&(b=null);this._.rt.cx=b;this._.rt.cy=c;
+this.setBox(this.attrs,b,c);this.Group.style.rotation=this._.rt.deg;return this};s[p].setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,f=this.shape&&this.shape.style||this.node.style;a=a||{};for(var e in a)if(a[z](e))this.attrs[e]=a[e];b=b||this._.rt.cx;c=c||this._.rt.cy;var g=this.attrs,h;switch(this.type){case "circle":a=g.cx-g.r;e=g.cy-g.r;h=g=g.r*2;break;case "ellipse":a=g.cx-g.rx;e=g.cy-g.ry;h=g.rx*2;g=g.ry*2;break;case "image":a=+g.x;e=+g.y;h=g.width||0;g=g.height||
+0;break;case "text":this.textpath.v=["m",Q(g.x),", ",Q(g.y-2),"l",Q(g.x)+1,", ",Q(g.y-2)][R](A);a=g.x-Q(this.W/2);e=g.y-this.H/2;h=this.W;g=this.H;break;case "rect":case "path":if(this.attrs.path){g=xa(this.attrs.path);a=g.x;e=g.y;h=g.width;g=g.height}else{e=a=0;h=this.paper.width;g=this.paper.height}break;default:e=a=0;h=this.paper.width;g=this.paper.height;break}b=b==null?a+h/2:b;c=c==null?e+g/2:c;b=b-this.paper.width/2;c=c-this.paper.height/2;var i;d.left!=(i=b+"px")&&(d.left=i);d.top!=(i=c+"px")&&
+(d.top=i);this.X=ra[z](this.type)?-b:a;this.Y=ra[z](this.type)?-c:e;this.W=h;this.H=g;if(ra[z](this.type)){f.left!=(i=-b*na+"px")&&(f.left=i);f.top!=(i=-c*na+"px")&&(f.top=i)}else if(this.type=="text"){f.left!=(i=-b+"px")&&(f.left=i);f.top!=(i=-c+"px")&&(f.top=i)}else{d.width!=(i=this.paper.width+"px")&&(d.width=i);d.height!=(i=this.paper.height+"px")&&(d.height=i);f.left!=(i=a-b+"px")&&(f.left=i);f.top!=(i=e-c+"px")&&(f.top=i);f.width!=(i=h+"px")&&(f.width=i);f.height!=(i=g+"px")&&(f.height=i)}};
+s[p].hide=function(){!this.removed&&(this.Group.style.display="none");return this};s[p].show=function(){!this.removed&&(this.Group.style.display="block");return this};s[p].getBBox=function(){if(this.removed)return this;if(ra[z](this.type))return xa(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};s[p].remove=function(){if(!this.removed){ma(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);
+for(var a in this)delete this[a];this.removed=true}};s[p].attr=function(a,b){if(this.removed)return this;if(a==null){a={};for(var c in this.attrs)if(this.attrs[z](c))a[c]=this.attrs[c];this._.rt.deg&&(a.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(a.scale=this.scale());a.gradient&&a.fill=="none"&&(a.fill=a.gradient)&&delete a.gradient;return a}if(b==null&&l.is(a,ga)){if(a=="translation")return Aa.call(this);if(a=="rotation")return this.rotate();if(a=="scale")return this.scale();if(a==ca&&
+this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[a]}if(this.attrs&&b==null&&l.is(a,U)){var d={};c=0;for(b=a[o];c<b;c++)d[a[c]]=this.attr(a[c]);return d}if(b!=null){d={};d[a]=b}b==null&&l.is(a,"object")&&(d=a);if(d){if(d.text&&this.type=="text")this.node.string=d.text;ea(this,d);if(d.gradient&&({circle:1,ellipse:1}[z](this.type)||D(d.gradient).charAt()!="r"))pa(this,d.gradient);(!ra[z](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};s[p].toFront=
+function(){!this.removed&&this.Group.parentNode[x](this.Group);this.paper.top!=this&&Ya(this,this.paper);return this};s[p].toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);Za(this,this.paper)}return this};s[p].insertAfter=function(a){if(this.removed)return this;if(a.constructor==X)a=a[a.length];a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):
+a.Group.parentNode[x](this.Group);$a(this,a,this.paper);return this};s[p].insertBefore=function(a){if(this.removed)return this;if(a.constructor==X)a=a[0];a.Group.parentNode.insertBefore(this.Group,a.Group);ab(this,a,this.paper);return this};var Hb=/ progid:\S+Blur\([^\)]+\)/g;s[p].blur=function(a){var b=this.node.runtimeStyle,c=b.filter;c=c.replace(Hb,A);if(+a!==0){this.attrs.blur=a;b.filter=c+N+Fa+".Blur(pixelradius="+(+a||1.5)+")";b.margin=l.format("-{0}px 0 0 -{0}px",Q(+a||1.5))}else{b.filter=
+c;b.margin=0;delete this.attrs.blur}};fb=function(a,b,c,d){var f=S("group"),e=S("oval");f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=qa;f.coordorigin=a.coordorigin;f[x](e);e=new s(e,f,a);e.type="circle";ea(e,{stroke:"#000",fill:"none"});e.attrs.cx=b;e.attrs.cy=c;e.attrs.r=d;e.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[x](f);return e};function mb(a,b,c,d,f){return f?l.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",
+a+f,b,c-f*2,f,-f,d-f*2,f*2-c,f*2-d):l.format("M{0},{1}l{2},0,0,{3},{4},0z",a,b,c,d,-c)}gb=function(a,b,c,d,f,e){var g=mb(b,c,d,f,e);a=a.path(g);var h=a.attrs;a.X=h.x=b;a.Y=h.y=c;a.W=h.width=d;a.H=h.height=f;h.r=e;h.path=g;a.type="rect";return a};hb=function(a,b,c,d,f){var e=S("group"),g=S("oval");e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=qa;e.coordorigin=a.coordorigin;e[x](g);g=new s(g,e,a);g.type="ellipse";ea(g,{stroke:"#000"});g.attrs.cx=
+b;g.attrs.cy=c;g.attrs.rx=d;g.attrs.ry=f;g.setBox({x:b-d,y:c-f,width:d*2,height:f*2});a.canvas[x](e);return g};ib=function(a,b,c,d,f,e){var g=S("group"),h=S("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=qa;g.coordorigin=a.coordorigin;h.src=b;g[x](h);h=new s(h,g,a);h.type="image";h.attrs.src=b;h.attrs.x=c;h.attrs.y=d;h.attrs.w=f;h.attrs.h=e;h.setBox({x:c,y:d,width:f,height:e});a.canvas[x](g);return h};jb=function(a,b,c,d){var f=S("group"),
+e=S("shape"),g=e.style,h=S("path"),i=S("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=qa;f.coordorigin=a.coordorigin;h.v=l.format("m{0},{1}l{2},{1}",Q(b*10),Q(c*10),Q(b*10)+1);h.textpathok=true;g.width=a.width;g.height=a.height;i.string=D(d);i.on=true;e[x](i);e[x](h);f[x](e);g=new s(i,f,a);g.shape=e;g.textpath=h;g.type="text";g.attrs.text=d;g.attrs.x=b;g.attrs.y=c;g.attrs.w=1;g.attrs.h=1;ea(g,{font:ta.font,stroke:"none",fill:"#000"});
+g.setBox();a.canvas[x](f);return g};kb=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var S;C.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!C.namespaces.rvml&&C.namespaces.add("rvml","urn:schemas-microsoft-com:vml");S=function(a){return C.createElement("<rvml:"+a+' class="rvml">')}}catch(Pb){S=function(a){return C.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}Ca=
+function(){var a=Xa[K](0,arguments),b=a.container,c=a.height,d=a.width,f=a.x;a=a.y;if(!b)throw new Error("VML container not found.");var e=new H,g=e.canvas=C.createElement("div"),h=g.style;f=f||0;a=a||0;d=d||512;c=c||342;d==+d&&(d+="px");c==+c&&(c+="px");e.width=1000;e.height=1000;e.coordsize=na*1000+N+na*1000;e.coordorigin="0 0";e.span=C.createElement("span");e.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";g[x](e.span);h.cssText=
+l.format("width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",d,c);if(b==1){C.body[x](g);h.left=f+"px";h.top=a+"px";h.position="absolute"}else b.firstChild?b.insertBefore(g,b.firstChild):b[x](g);Ia.call(e,e,l.fn);return e};H[p].clear=function(){this.canvas.innerHTML=A;this.span=C.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[x](this.span);this.bottom=
+this.top=null};H[p].remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bb(a);return true}}H[p].safari=navigator.vendor=="Apple Computer, Inc."&&(navigator.userAgent.match(/Version\/(.*?)\s/)[1]<4||aa.navigator.platform.slice(0,2)=="iP")?function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});aa.setTimeout(function(){a.remove()})}:function(){};function Ib(){this.returnValue=false}function Jb(){return this.originalEvent.preventDefault()}
+function Kb(){this.cancelBubble=true}function Lb(){return this.originalEvent.stopPropagation()}var Mb=function(){if(C.addEventListener)return function(a,b,c,d){var f=Da&&Ea[b]?Ea[b]:b;function e(g){if(Da&&Ea[z](b))for(var h=0,i=g.targetTouches&&g.targetTouches.length;h<i;h++)if(g.targetTouches[h].target==a){i=g;g=g.targetTouches[h];g.originalEvent=i;g.preventDefault=Jb;g.stopPropagation=Lb;break}return c.call(d,g)}a.addEventListener(f,e,false);return function(){a.removeEventListener(f,e,false);return true}};
+else if(C.attachEvent)return function(a,b,c,d){function f(g){g=g||aa.event;g.preventDefault=g.preventDefault||Ib;g.stopPropagation=g.stopPropagation||Kb;return c.call(d,g)}a.attachEvent("on"+b,f);function e(){a.detachEvent("on"+b,f);return true}return e}}(),$=[];function Ka(a){for(var b=a.clientX,c=a.clientY,d,f=$.length;f--;){d=$[f];if(Da)for(var e=a.touches.length,g;e--;){g=a.touches[e];if(g.identifier==d.el._drag.id){b=g.clientX;c=g.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();
+break}}else a.preventDefault();d.move&&d.move.call(d.el,b-d.el._drag.x,c-d.el._drag.y,b,c)}}function La(){l.unmousemove(Ka).unmouseup(La);for(var a=$.length,b;a--;){b=$[a];b.el._drag={};b.end&&b.end.call(b.el)}$=[]}for(da=Ra[o];da--;)(function(a){l[a]=s[p][a]=function(b){if(l.is(b,"function")){this.events=this.events||[];this.events.push({name:a,f:b,unbind:Mb(this.shape||this.node||C,a,b,this)})}return this};l["un"+a]=s[p]["un"+a]=function(b){for(var c=this.events,d=c[o];d--;)if(c[d].name==a&&c[d].f==
+b){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(Ra[da]);s[p].hover=function(a,b){return this.mouseover(a).mouseout(b)};s[p].unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};s[p].drag=function(a,b,c){this._drag={};this.mousedown(function(d){(d.originalEvent||d).preventDefault();this._drag.x=d.clientX;this._drag.y=d.clientY;this._drag.id=d.identifier;b&&b.call(this,d.clientX,d.clientY);!$.length&&l.mousemove(Ka).mouseup(La);$.push({el:this,move:a,
+end:c})});return this};s[p].undrag=function(a,b,c){for(b=$.length;b--;){$[b].el==this&&$[b].move==a&&$[b].end==c&&$.splice(b,1);!$.length&&l.unmousemove(Ka).unmouseup(La)}};H[p].circle=function(a,b,c){return fb(this,a||0,b||0,c||0)};H[p].rect=function(a,b,c,d,f){return gb(this,a||0,b||0,c||0,d||0,f||0)};H[p].ellipse=function(a,b,c,d){return hb(this,a||0,b||0,c||0,d||0)};H[p].path=function(a){a&&!l.is(a,ga)&&!l.is(a[0],U)&&(a+=A);return db(l.format[K](l,arguments),this)};H[p].image=function(a,b,c,
+d,f){return ib(this,a||"about:blank",b||0,c||0,d||0,f||0)};H[p].text=function(a,b,c){return jb(this,a||0,b||0,c||A)};H[p].set=function(a){arguments[o]>1&&(a=Array[p].splice.call(arguments,0,arguments[o]));return new X(a)};H[p].setSize=kb;H[p].top=H[p].bottom=null;H[p].raphael=l;function nb(){return this.x+N+this.y}s[p].resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};s[p].scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,
+y:this._.sy,toString:nb};b=b||a;!+b&&(b=a);var f,e,g=this.attrs;if(a!=0){var h=this.getBBox(),i=h.x+h.width/2,j=h.y+h.height/2;f=a/this._.sx;e=b/this._.sy;c=+c||c==0?c:i;d=+d||d==0?d:j;h=~~(a/v.abs(a));var m=~~(b/v.abs(b)),n=this.node.style,r=c+(i-c)*f;j=d+(j-d)*e;switch(this.type){case "rect":case "image":var q=g.width*h*f,k=g.height*m*e;this.attr({height:k,r:g.r*ba(h*f,m*e),width:q,x:r-q/2,y:j-k/2});break;case "circle":case "ellipse":this.attr({rx:g.rx*h*f,ry:g.ry*m*e,r:g.r*ba(h*f,m*e),cx:r,cy:j});
+break;case "text":this.attr({x:r,y:j});break;case "path":i=Ha(g.path);for(var t=true,L=0,B=i[o];L<B;L++){var w=i[L],J=sa.call(w[0]);if(!(J=="M"&&t)){t=false;if(J=="A"){w[i[L][o]-2]*=f;w[i[L][o]-1]*=e;w[1]*=h*f;w[2]*=m*e;w[5]=+!(h+m?!+w[5]:+w[5])}else if(J=="H"){J=1;for(var ia=w[o];J<ia;J++)w[J]*=f}else if(J=="V"){J=1;for(ia=w[o];J<ia;J++)w[J]*=e}else{J=1;for(ia=w[o];J<ia;J++)w[J]*=J%2?f:e}}}e=xa(i);f=r-e.x-e.width/2;e=j-e.y-e.height/2;i[0][1]+=f;i[0][2]+=e;this.attr({path:i});break}if(this.type in
+{text:1,image:1}&&(h!=1||m!=1))if(this.transformations){this.transformations[2]="scale("[M](h,",",m,")");this.node[W]("transform",this.transformations[R](N));f=h==-1?-g.x-(q||0):g.x;e=m==-1?-g.y-(k||0):g.y;this.attr({x:f,y:e});g.fx=h-1;g.fy=m-1}else{this.node.filterMatrix=Fa+".Matrix(M11="[M](h,", M12=0, M21=0, M22=",m,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");n.filter=(this.node.filterMatrix||A)+(this.node.filterOpacity||A)}else if(this.transformations){this.transformations[2]=
+A;this.node[W]("transform",this.transformations[R](N));g.fx=0;g.fy=0}else{this.node.filterMatrix=A;n.filter=(this.node.filterMatrix||A)+(this.node.filterOpacity||A)}g.scale=[a,b,c,d][R](N);this._.sx=a;this._.sy=b}return this};s[p].clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var ob=Z(function(a,b,c,d,f,e,g,h,i){for(var j=0,m,n=0;n<1.01;n+=0.01){var r=la(a,b,c,d,f,e,g,h,n);n&&(j+=E(E(m.x-r.x,2)+E(m.y-r.y,
+2),0.5));if(j>=i)return r;m=r}});function Ma(a,b){return function(c,d,f){c=wa(c);for(var e,g,h,i,j="",m={},n=0,r=0,q=c.length;r<q;r++){h=c[r];if(h[0]=="M"){e=+h[1];g=+h[2]}else{i=Nb(e,g,h[1],h[2],h[3],h[4],h[5],h[6]);if(n+i>d){if(b&&!m.start){e=ob(e,g,h[1],h[2],h[3],h[4],h[5],h[6],d-n);j+=["C",e.start.x,e.start.y,e.m.x,e.m.y,e.x,e.y];if(f)return j;m.start=j;j=["M",e.x,e.y+"C",e.n.x,e.n.y,e.end.x,e.end.y,h[5],h[6]][R]();n+=i;e=+h[5];g=+h[6];continue}if(!a&&!b){e=ob(e,g,h[1],h[2],h[3],h[4],h[5],h[6],
+d-n);return{x:e.x,y:e.y,alpha:e.alpha}}}n+=i;e=+h[5];g=+h[6]}j+=h}m.end=j;e=a?n:b?m:l.findDotsAtSegment(e,g,h[1],h[2],h[3],h[4],h[5],h[6],1);e.alpha&&(e={x:e.x,y:e.y,alpha:e.alpha});return e}}var Nb=Z(function(a,b,c,d,f,e,g,h){for(var i={x:0,y:0},j=0,m=0;m<1.01;m+=0.01){var n=la(a,b,c,d,f,e,g,h,m);m&&(j+=E(E(i.x-n.x,2)+E(i.y-n.y,2),0.5));i=n}return j}),pb=Ma(1),Ba=Ma(),Na=Ma(0,1);s[p].getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return pb(this.attrs.path)}};
+s[p].getPointAtLength=function(a){if(this.type=="path"){if(this.node.getPointAtLength)return this.node.getPointAtLength(a);return Ba(this.attrs.path,a)}};s[p].getSubpath=function(a,b){if(this.type=="path"){if(v.abs(this.getTotalLength()-b)<1.0E-6)return Na(this.attrs.path,a).end;b=Na(this.attrs.path,b,1);return a?Na(b,a).end:b}};l.easing_formulas={linear:function(a){return a},"<":function(a){return E(a,3)},">":function(a){return E(a-1,3)+1},"<>":function(a){a*=2;if(a<1)return E(a,3)/2;a-=2;return(E(a,
+3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return E(2,-10*a)*v.sin((a-c)*2*v.PI/b)+1},bounce:function(a){var b=7.5625,c=2.75;if(a<1/c)a=b*a*a;else if(a<2/c){a-=1.5/c;a=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;a=b*a*a+0.9375}else{a-=2.625/c;a=b*a*a+0.984375}return a}};var T={length:0};function qb(){var a=+new Date;for(var b in T)if(b!="length"&&T[z](b)){var c=
+T[b];if(c.stop||c.el.removed){delete T[b];T[o]--}else{var d=a-c.start,f=c.ms,e=c.easing,g=c.from,h=c.diff,i=c.to,j=c.t,m=c.prev||0,n=c.el,r=c.callback,q={},k;if(d<f){r=l.easing_formulas[e]?l.easing_formulas[e](d/f):d/f;for(var t in g)if(g[z](t)){switch(Ga[t]){case "along":k=r*f*h[t];i.back&&(k=i.len-k);e=Ba(i[t],k);n.translate(h.sx-h.x||0,h.sy-h.y||0);h.x=e.x;h.y=e.y;n.translate(e.x-h.sx,e.y-h.sy);i.rot&&n.rotate(h.r+e.alpha,e.x,e.y);break;case P:k=+g[t]+r*f*h[t];break;case "colour":k="rgb("+[Oa(Q(g[t].r+
+r*f*h[t].r)),Oa(Q(g[t].g+r*f*h[t].g)),Oa(Q(g[t].b+r*f*h[t].b))][R](",")+")";break;case "path":k=[];e=0;for(var L=g[t][o];e<L;e++){k[e]=[g[t][e][0]];for(var B=1,w=g[t][e][o];B<w;B++)k[e][B]=+g[t][e][B]+r*f*h[t][e][B];k[e]=k[e][R](N)}k=k[R](N);break;case "csv":switch(t){case "translation":k=h[t][0]*(d-m);e=h[t][1]*(d-m);j.x+=k;j.y+=e;k=k+N+e;break;case "rotation":k=+g[t][0]+r*f*h[t][0];g[t][1]&&(k+=","+g[t][1]+","+g[t][2]);break;case "scale":k=[+g[t][0]+r*f*h[t][0],+g[t][1]+r*f*h[t][1],2 in i[t]?i[t][2]:
+A,3 in i[t]?i[t][3]:A][R](N);break;case "clip-rect":k=[];for(e=4;e--;)k[e]=+g[t][e]+r*f*h[t][e];break}break}q[t]=k}n.attr(q);n._run&&n._run.call(n)}else{if(i.along){e=Ba(i.along,i.len*!i.back);n.translate(h.sx-(h.x||0)+e.x-h.sx,h.sy-(h.y||0)+e.y-h.sy);i.rot&&n.rotate(h.r+e.alpha,e.x,e.y)}(j.x||j.y)&&n.translate(-j.x,-j.y);i.scale&&(i.scale+=A);n.attr(i);delete T[b];T[o]--;n.in_animation=null;l.is(r,"function")&&r.call(n)}c.prev=d}}l.svg&&n&&n.paper&&n.paper.safari();T[o]&&aa.setTimeout(qb)}function Oa(a){return Y(ba(a,
+255),0)}function Aa(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:nb};this._.tx+=+a;this._.ty+=+b;switch(this.type){case "circle":case "ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case "rect":case "image":case "text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case "path":var c=Ha(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this}s[p].animateWith=function(a,b,c,d,f){T[a.id]&&(b.start=T[a.id].start);return this.animate(b,c,d,
+f)};s[p].animateAlong=rb();s[p].animateAlongBack=rb(1);function rb(a){return function(b,c,d,f){var e={back:a};l.is(d,"function")?(f=d):(e.rot=d);b&&b.constructor==s&&(b=b.attrs.path);b&&(e.along=b);return this.animate(e,c,f)}}s[p].onAnimation=function(a){this._run=a||0;return this};s[p].animate=function(a,b,c,d){if(l.is(c,"function")||!c)d=c||null;var f={},e={},g={};for(var h in a)if(a[z](h))if(Ga[z](h)){f[h]=this.attr(h);f[h]==null&&(f[h]=ta[h]);e[h]=a[h];switch(Ga[h]){case "along":var i=pb(a[h]),
+j=Ba(a[h],i*!!a.back),m=this.getBBox();g[h]=i/b;g.tx=m.x;g.ty=m.y;g.sx=j.x;g.sy=j.y;e.rot=a.rot;e.back=a.back;e.len=i;a.rot&&(g.r=y(this.rotate())||0);break;case P:g[h]=(e[h]-f[h])/b;break;case "colour":f[h]=l.getRGB(f[h]);i=l.getRGB(e[h]);g[h]={r:(i.r-f[h].r)/b,g:(i.g-f[h].g)/b,b:(i.b-f[h].b)/b};break;case "path":i=wa(f[h],e[h]);f[h]=i[0];j=i[1];g[h]=[];i=0;for(m=f[h][o];i<m;i++){g[h][i]=[0];for(var n=1,r=f[h][i][o];n<r;n++)g[h][i][n]=(j[i][n]-f[h][i][n])/b}break;case "csv":j=D(a[h])[G](V);i=D(f[h])[G](V);
+switch(h){case "translation":f[h]=[0,0];g[h]=[j[0]/b,j[1]/b];break;case "rotation":f[h]=i[1]==j[1]&&i[2]==j[2]?i:[0,j[1],j[2]];g[h]=[(j[0]-f[h][0])/b,0,0];break;case "scale":a[h]=j;f[h]=D(f[h])[G](V);g[h]=[(j[0]-f[h][0])/b,(j[1]-f[h][1])/b,0,0];break;case "clip-rect":f[h]=D(f[h])[G](V);g[h]=[];for(i=4;i--;)g[h][i]=(j[i]-f[h][i])/b;break}e[h]=j}}this.stop();this.in_animation=1;T[this.id]={start:a.start||+new Date,ms:b,easing:c,from:f,diff:g,to:e,el:this,callback:d,t:{x:0,y:0}};++T[o]==1&&qb();return this};
+s[p].stop=function(){T[this.id]&&T[o]--;delete T[this.id];return this};s[p].translate=function(a,b){return this.attr({translation:a+" "+b})};s[p][O]=function(){return"Rapha\u00ebl\u2019s object"};l.ae=T;function X(a){this.items=[];this[o]=0;this.type="set";if(a)for(var b=0,c=a[o];b<c;b++)if(a[b]&&(a[b].constructor==s||a[b].constructor==X)){this[this.items[o]]=this.items[this.items[o]]=a[b];this[o]++}}X[p][F]=function(){for(var a,b,c=0,d=arguments[o];c<d;c++)if((a=arguments[c])&&(a.constructor==s||
+a.constructor==X)){b=this.items[o];this[b]=this.items[b]=a;this[o]++}return this};X[p].pop=function(){delete this[this[o]--];return this.items.pop()};for(var Pa in s[p])if(s[p][z](Pa))X[p][Pa]=function(a){return function(){for(var b=0,c=this.items[o];b<c;b++)this.items[b][a][K](this.items[b],arguments);return this}}(Pa);X[p].attr=function(a,b){if(a&&l.is(a,U)&&l.is(a[0],"object")){b=0;for(var c=a[o];b<c;b++)this.items[b].attr(a[b])}else{c=0;for(var d=this.items[o];c<d;c++)this.items[c].attr(a,b)}return this};
+X[p].animate=function(a,b,c,d){(l.is(c,"function")||!c)&&(d=c||null);var f=this.items[o],e=f,g,h=this,i;d&&(i=function(){!--f&&d.call(h)});c=l.is(c,ga)?c:i;for(g=this.items[--e].animate(a,b,c,i);e--;)this.items[e].animateWith(g,a,b,c,i);return this};X[p].insertAfter=function(a){for(var b=this.items[o];b--;)this.items[b].insertAfter(a);return this};X[p].getBBox=function(){for(var a=[],b=[],c=[],d=[],f=this.items[o];f--;){var e=this.items[f].getBBox();a[F](e.x);b[F](e.y);c[F](e.x+e.width);d[F](e.y+
+e.height)}a=ba[K](0,a);b=ba[K](0,b);return{x:a,y:b,width:Y[K](0,c)-a,height:Y[K](0,d)-b}};X[p].clone=function(a){a=new X;for(var b=0,c=this.items[o];b<c;b++)a[F](this.items[b].clone());return a};l.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)if(a.face[z](d))b.face[d]=a.face[d];if(this.fonts[c])this.fonts[c][F](b);else this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=ha(a.face["units-per-em"],10);
+for(var f in a.glyphs)if(a.glyphs[z](f)){c=a.glyphs[f];b.glyphs[f]={w:c.w,k:{},d:c.d&&"M"+c.d[I](/[mlcxtrv]/g,function(g){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[g]||"M"})+"z"};if(c.k)for(var e in c.k)if(c[z](e))b.glyphs[f].k[e]=c.k[e]}}return a};H[p].getFont=function(a,b,c,d){d=d||"normal";c=c||"normal";b=+b||{normal:400,bold:700,lighter:300,bolder:800}[b]||400;if(l.fonts){var f=l.fonts[a];if(!f){a=new RegExp("(^|\\s)"+a[I](/[^\w\d\s+!~.:_-]/g,A)+"(\\s|$)","i");for(var e in l.fonts)if(l.fonts[z](e))if(a.test(e)){f=
+l.fonts[e];break}}var g;if(f){e=0;for(a=f[o];e<a;e++){g=f[e];if(g.face["font-weight"]==b&&(g.face["font-style"]==c||!g.face["font-style"])&&g.face["font-stretch"]==d)break}}return g}};H[p].print=function(a,b,c,d,f,e){e=e||"middle";var g=this.set(),h=D(c)[G](A),i=0;l.is(d,c)&&(d=this.getFont(d));if(d){c=(f||16)/d.face["units-per-em"];var j=d.face.bbox.split(V);f=+j[0];e=+j[1]+(e=="baseline"?j[3]-j[1]+ +d.face.descent:(j[3]-j[1])/2);j=0;for(var m=h[o];j<m;j++){var n=j&&d.glyphs[h[j-1]]||{},r=d.glyphs[h[j]];
+i+=j?(n.w||d.w)+(n.k&&n.k[h[j]]||0):0;r&&r.d&&g[F](this.path(r.d).attr({fill:"#000",stroke:"none",translation:[i,0]}))}g.scale(c,c,f,e).translate(a-f,b-e)}return g};var Ob=/\{(\d+)\}/g;l.format=function(a,b){var c=l.is(b,U)?[0][M](b):arguments;a&&l.is(a,ga)&&c[o]-1&&(a=a[I](Ob,function(d,f){return c[++f]==null?A:c[f]}));return a||A};l.ninja=function(){Qa.was?(Raphael=Qa.is):delete Raphael;return l};l.el=s[p];return l}();
diff --git a/test/g.raphael/g.bar-min.js b/test/g.raphael/g.bar-min.js
new file mode 100644
index 0000000..3556bd0
--- /dev/null
+++ b/test/g.raphael/g.bar-min.js
@@ -0,0 +1,7 @@
+/*
+ * 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].length<q){for(var J=q;J--;){O[K].push(0);}}}w=Math.max.apply(Math,u.stacked?N:w);}w=(u.to)||w;var D=a/(q*(100+n)+n)*100,b=D*n/100,g=u.vgutter==null?20:u.vgutter,t=[],k=C+b,f=(d-2*g)/w;if(!u.stretch){b=Math.round(b);D=Math.floor(D);}!u.stacked&&(D/=B||1);for(var K=0;K<q;K++){t=[];for(var J=0;J<(B||1);J++){var L=Math.round((B?O[J][K]:O[K])*f),m=A+d-g-L,H=this.g.finger(Math.round(k+D/2),m+L,D,L,true,P).attr({stroke:"none",fill:F[B?J:K]});if(B){v[J].push(H);}else{v.push(H);}H.y=m;H.x=Math.round(k+D/2);H.w=D;H.h=L;H.value=B?O[J][K]:O[K];if(!u.stacked){k+=D;}else{t.push(H);}}if(u.stacked){var I;r.push(I=this.rect(t[0].x-t[0].w/2,A,D,d).attr(this.g.shim));I.bars=this.set();var o=0;for(var E=t.length;E--;){t[E].toFront();}for(var E=0,p=t.length;E<p;E++){var H=t[E],z,L=(o+H.value)*f,G=this.g.finger(H.x,A+d-g-!!o*0.5,D,L,true,P,1);I.bars.push(H);o&&H.attr({path:G});H.h=L;H.y=A+d-g-!!o*0.5-L;e.push(z=this.rect(H.x-H.w/2,H.y,D,H.value*f).attr(this.g.shim));z.bar=H;z.value=H.value;o+=H.value;}k+=D;}k+=b;}r.toFront();k=C+b;if(!u.stacked){for(var K=0;K<q;K++){for(var J=0;J<(B||1);J++){var z;e.push(z=this.rect(Math.round(k),A+g,D,d-g).attr(this.g.shim));z.bar=B?v[J][K]:v[K];z.value=z.bar.value;k+=D;}k+=b;}}M.label=function(y,S){y=y||[];this.labels=c.set();var T,h=-Infinity;if(u.stacked){for(var x=0;x<q;x++){var Q=0;for(var s=0;s<(B||1);s++){Q+=B?O[s][x]:O[x];if(s==B-1){var U=c.g.labelise(y[x],Q,w);T=c.g.text(v[x*(B||1)+s].x,A+d-g/2,U).insertBefore(e[x*(B||1)+s]);var R=T.getBBox();if(R.x-7<h){T.remove();}else{this.labels.push(T);h=R.x+R.width;}}}}}else{for(var x=0;x<q;x++){for(var s=0;s<(B||1);s++){var U=c.g.labelise(B?y[s]&&y[s][x]:y[x],B?O[s][x]:O[x],w);T=c.g.text(v[x*(B||1)+s].x,S?A+d-g/2:v[x*(B||1)+s].y-10,U).insertBefore(e[x*(B||1)+s]);var R=T.getBBox();if(R.x-7<h){T.remove();}else{this.labels.push(T);h=R.x+R.width;}}}}return this;};M.hover=function(i,h){r.hide();e.show();e.mouseover(i).mouseout(h);return this;};M.hoverColumn=function(i,h){e.hide();r.show();h=h||function(){};r.mouseover(i).mouseout(h);return this;};M.click=function(h){r.hide();e.show();e.click(h);return this;};M.each=function(j){if(!Raphael.is(j,"function")){return this;}for(var h=e.length;h--;){j.call(e[h]);}return this;};M.eachColumn=function(j){if(!Raphael.is(j,"function")){return this;}for(var h=r.length;h--;){j.call(r[h]);}return this;};M.clickColumn=function(h){e.hide();r.show();r.click(h);return this;};M.push(v,e,r);M.bars=v;M.covers=e;return M;};Raphael.fn.g.hbarchart=function(n,l,B,w,c,r){r=r||{};var e={round:"round",sharp:"sharp",soft:"soft"}[r.type]||"square",f=parseFloat(r.gutter||"20%"),u=this.set(),A=this.set(),h=this.set(),E=this.set(),M=Math.max.apply(Math,c),a=[],o=this,C=0,m=r.colors||this.g.colors,H=c.length;if(this.raphael.is(c[0],"array")){M=[];C=H;H=0;for(var G=c.length;G--;){A.push(this.set());M.push(Math.max.apply(Math,c[G]));H=Math.max(H,c[G].length);}if(r.stacked){for(var G=H;G--;){var p=0;for(var F=c.length;F--;){p+=+c[F][G]||0;}a.push(p);}}for(var G=c.length;G--;){if(c[G].length<H){for(var F=H;F--;){c[G].push(0);}}}M=Math.max.apply(Math,r.stacked?a:M);}M=(r.to)||M;var J=Math.floor(w/(H*(100+f)+f)*100),k=Math.floor(J*f/100),g=[],b=l+k,d=(B-1)/M;!r.stacked&&(J/=C||1);for(var G=0;G<H;G++){g=[];for(var F=0;F<(C||1);F++){var L=C?c[F][G]:c[G],I=this.g.finger(n,b+J/2,Math.round(L*d),J-1,false,e).attr({stroke:"none",fill:m[C?F:G]});if(C){A[F].push(I);}else{A.push(I);}I.x=n+Math.round(L*d);I.y=b+J/2;I.w=Math.round(L*d);I.h=J;I.value=+L;if(!r.stacked){b+=J;}else{g.push(I);}}if(r.stacked){var q=this.rect(n,g[0].y-g[0].h/2,B,J).attr(this.g.shim);E.push(q);q.bars=this.set();var v=0;for(var t=g.length;t--;){g[t].toFront();}for(var t=0,D=g.length;t<D;t++){var I=g[t],K,L=Math.round((v+I.value)*d),z=this.g.finger(n,I.y,L,J-1,false,e,1);q.bars.push(I);v&&I.attr({path:z});I.w=L;I.x=n+L;h.push(K=this.rect(n+v*d,I.y-I.h/2,I.value*d,J).attr(this.g.shim));K.bar=I;v+=I.value;}b+=J;}b+=k;}E.toFront();b=l+k;if(!r.stacked){for(var G=0;G<H;G++){for(var F=0;F<(C||1);F++){var K=this.rect(n,b,B,J).attr(this.g.shim);h.push(K);K.bar=C?A[F][G]:A[G];K.value=K.bar.value;b+=J;}b+=k;}}u.label=function(R,P){R=R||[];this.labels=o.set();for(var O=0;O<H;O++){for(var N=0;N<C;N++){var y=o.g.labelise(C?R[N]&&R[N][O]:R[O],C?c[N][O]:c[O],M);var Q=P?A[O*(C||1)+N].x-J/2+3:n+5,x=P?"end":"start",s;this.labels.push(s=o.g.text(Q,A[O*(C||1)+N].y,y).attr({"text-anchor":x}).insertBefore(h[0]));if(s.getBBox().x<n+5){s.attr({x:n+5,"text-anchor":"start"});}else{A[O*(C||1)+N].label=s;}}}return this;};u.hover=function(j,i){E.hide();h.show();i=i||function(){};h.mouseover(j).mouseout(i);return this;};u.hoverColumn=function(j,i){h.hide();E.show();i=i||function(){};E.mouseover(j).mouseout(i);return this;};u.each=function(s){if(!Raphael.is(s,"function")){return this;}for(var j=h.length;j--;){s.call(h[j]);}return this;};u.eachColumn=function(s){if(!Raphael.is(s,"function")){return this;}for(var j=E.length;j--;){s.call(E[j]);}return this;};u.click=function(i){E.hide();h.show();h.click(i);return this;};u.clickColumn=function(i){h.hide();E.show();E.click(i);return this;};u.push(A,h,E);u.bars=A;u.covers=h;return u;}; \ No newline at end of file
diff --git a/test/g.raphael/g.bar.js b/test/g.raphael/g.bar.js
new file mode 100644
index 0000000..9ff5e5b
--- /dev/null
+++ b/test/g.raphael/g.bar.js
@@ -0,0 +1,386 @@
+/*!
+ * 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 (x, y, width, height, values, opts) {
+ opts = opts || {};
+ var type = {round: "round", sharp: "sharp", soft: "soft"}[opts.type] || "square",
+ gutter = parseFloat(opts.gutter || "20%"),
+ chart = this.set(),
+ bars = this.set(),
+ covers = this.set(),
+ covers2 = this.set(),
+ total = Math.max.apply(Math, values),
+ stacktotal = [],
+ paper = this,
+ multi = 0,
+ colors = opts.colors || this.g.colors,
+ len = values.length;
+ if (this.raphael.is(values[0], "array")) {
+ total = [];
+ multi = len;
+ len = 0;
+ for (var i = values.length; i--;) {
+ bars.push(this.set());
+ total.push(Math.max.apply(Math, values[i]));
+ len = Math.max(len, values[i].length);
+ }
+ if (opts.stacked) {
+ for (var i = len; i--;) {
+ var tot = 0;
+ for (var j = values.length; j--;) {
+ tot +=+ values[j][i] || 0;
+ }
+ stacktotal.push(tot);
+ }
+ }
+ for (var i = values.length; i--;) {
+ if (values[i].length < len) {
+ for (var j = len; j--;) {
+ values[i].push(0);
+ }
+ }
+ }
+ total = Math.max.apply(Math, opts.stacked ? stacktotal : total);
+ }
+
+ total = (opts.to) || total;
+ var barwidth = width / (len * (100 + gutter) + gutter) * 100,
+ barhgutter = barwidth * gutter / 100,
+ barvgutter = opts.vgutter == null ? 20 : opts.vgutter,
+ stack = [],
+ X = x + barhgutter,
+ Y = (height - 2 * barvgutter) / total;
+ if (!opts.stretch) {
+ barhgutter = Math.round(barhgutter);
+ barwidth = Math.floor(barwidth);
+ }
+ !opts.stacked && (barwidth /= multi || 1);
+ for (var i = 0; i < len; i++) {
+ stack = [];
+ for (var j = 0; j < (multi || 1); j++) {
+ var h = Math.round((multi ? values[j][i] : values[i]) * Y),
+ top = y + height - barvgutter - h,
+ bar = this.g.finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type).attr({stroke: "none", fill: colors[multi ? j : i]});
+ if (multi) {
+ bars[j].push(bar);
+ } else {
+ bars.push(bar);
+ }
+ bar.y = top;
+ bar.x = Math.round(X + barwidth / 2);
+ bar.w = barwidth;
+ bar.h = h;
+ bar.value = multi ? values[j][i] : values[i];
+ if (!opts.stacked) {
+ X += barwidth;
+ } else {
+ stack.push(bar);
+ }
+ }
+ if (opts.stacked) {
+ var cvr;
+ covers2.push(cvr = this.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(this.g.shim));
+ cvr.bars = this.set();
+ var size = 0;
+ for (var s = stack.length; s--;) {
+ stack[s].toFront();
+ }
+ for (var s = 0, ss = stack.length; s < ss; s++) {
+ var bar = stack[s],
+ cover,
+ h = (size + bar.value) * Y,
+ path = this.g.finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1);
+ cvr.bars.push(bar);
+ size && bar.attr({path: path});
+ bar.h = h;
+ bar.y = y + height - barvgutter - !!size * .5 - h;
+ covers.push(cover = this.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(this.g.shim));
+ cover.bar = bar;
+ cover.value = bar.value;
+ size += bar.value;
+ }
+ X += barwidth;
+ }
+ X += barhgutter;
+ }
+ covers2.toFront();
+ X = x + barhgutter;
+ if (!opts.stacked) {
+ for (var i = 0; i < len; i++) {
+ for (var j = 0; j < (multi || 1); j++) {
+ var cover;
+ covers.push(cover = this.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(this.g.shim));
+ cover.bar = multi ? bars[j][i] : bars[i];
+ cover.value = cover.bar.value;
+ X += barwidth;
+ }
+ X += barhgutter;
+ }
+ }
+ chart.label = function (labels, isBottom) {
+ labels = labels || [];
+ this.labels = paper.set();
+ var L, l = -Infinity;
+ if (opts.stacked) {
+ for (var i = 0; i < len; i++) {
+ var tot = 0;
+ for (var j = 0; j < (multi || 1); j++) {
+ tot += multi ? values[j][i] : values[i];
+ if (j == multi - 1) {
+ var label = paper.g.labelise(labels[i], tot, total);
+ L = paper.g.text(bars[i * (multi || 1) + j].x, y + height - barvgutter / 2, label).insertBefore(covers[i * (multi || 1) + j]);
+ var bb = L.getBBox();
+ if (bb.x - 7 < l) {
+ L.remove();
+ } else {
+ this.labels.push(L);
+ l = bb.x + bb.width;
+ }
+ }
+ }
+ }
+ } else {
+ for (var i = 0; i < len; i++) {
+ for (var j = 0; j < (multi || 1); j++) {
+ var label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);
+ L = paper.g.text(bars[i * (multi || 1) + j].x, isBottom ? y + height - barvgutter / 2 : bars[i * (multi || 1) + j].y - 10, label).insertBefore(covers[i * (multi || 1) + j]);
+ var bb = L.getBBox();
+ if (bb.x - 7 < l) {
+ L.remove();
+ } else {
+ this.labels.push(L);
+ l = bb.x + bb.width;
+ }
+ }
+ }
+ }
+ return this;
+ };
+ chart.hover = function (fin, fout) {
+ covers2.hide();
+ covers.show();
+ covers.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.hoverColumn = function (fin, fout) {
+ covers.hide();
+ covers2.show();
+ fout = fout || function () {};
+ covers2.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.click = function (f) {
+ covers2.hide();
+ covers.show();
+ covers.click(f);
+ return this;
+ };
+ chart.each = function (f) {
+ if (!Raphael.is(f, "function")) {
+ return this;
+ }
+ for (var i = covers.length; i--;) {
+ f.call(covers[i]);
+ }
+ return this;
+ };
+ chart.eachColumn = function (f) {
+ if (!Raphael.is(f, "function")) {
+ return this;
+ }
+ for (var i = covers2.length; i--;) {
+ f.call(covers2[i]);
+ }
+ return this;
+ };
+ chart.clickColumn = function (f) {
+ covers.hide();
+ covers2.show();
+ covers2.click(f);
+ return this;
+ };
+ chart.push(bars, covers, covers2);
+ chart.bars = bars;
+ chart.covers = covers;
+ return chart;
+};
+Raphael.fn.g.hbarchart = function (x, y, width, height, values, opts) {
+ opts = opts || {};
+ var type = {round: "round", sharp: "sharp", soft: "soft"}[opts.type] || "square",
+ gutter = parseFloat(opts.gutter || "20%"),
+ chart = this.set(),
+ bars = this.set(),
+ covers = this.set(),
+ covers2 = this.set(),
+ total = Math.max.apply(Math, values),
+ stacktotal = [],
+ paper = this,
+ multi = 0,
+ colors = opts.colors || this.g.colors,
+ len = values.length;
+ if (this.raphael.is(values[0], "array")) {
+ total = [];
+ multi = len;
+ len = 0;
+ for (var i = values.length; i--;) {
+ bars.push(this.set());
+ total.push(Math.max.apply(Math, values[i]));
+ len = Math.max(len, values[i].length);
+ }
+ if (opts.stacked) {
+ for (var i = len; i--;) {
+ var tot = 0;
+ for (var j = values.length; j--;) {
+ tot +=+ values[j][i] || 0;
+ }
+ stacktotal.push(tot);
+ }
+ }
+ for (var i = values.length; i--;) {
+ if (values[i].length < len) {
+ for (var j = len; j--;) {
+ values[i].push(0);
+ }
+ }
+ }
+ total = Math.max.apply(Math, opts.stacked ? stacktotal : total);
+ }
+
+ total = (opts.to) || total;
+ var barheight = Math.floor(height / (len * (100 + gutter) + gutter) * 100),
+ bargutter = Math.floor(barheight * gutter / 100),
+ stack = [],
+ Y = y + bargutter,
+ X = (width - 1) / total;
+ !opts.stacked && (barheight /= multi || 1);
+ for (var i = 0; i < len; i++) {
+ stack = [];
+ for (var j = 0; j < (multi || 1); j++) {
+ var val = multi ? values[j][i] : values[i],
+ bar = this.g.finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type).attr({stroke: "none", fill: colors[multi ? j : i]});
+ if (multi) {
+ bars[j].push(bar);
+ } else {
+ bars.push(bar);
+ }
+ bar.x = x + Math.round(val * X);
+ bar.y = Y + barheight / 2;
+ bar.w = Math.round(val * X);
+ bar.h = barheight;
+ bar.value = +val;
+ if (!opts.stacked) {
+ Y += barheight;
+ } else {
+ stack.push(bar);
+ }
+ }
+ if (opts.stacked) {
+ var cvr = this.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(this.g.shim);
+ covers2.push(cvr);
+ cvr.bars = this.set();
+ var size = 0;
+ for (var s = stack.length; s--;) {
+ stack[s].toFront();
+ }
+ for (var s = 0, ss = stack.length; s < ss; s++) {
+ var bar = stack[s],
+ cover,
+ val = Math.round((size + bar.value) * X),
+ path = this.g.finger(x, bar.y, val, barheight - 1, false, type, 1);
+ cvr.bars.push(bar);
+ size && bar.attr({path: path});
+ bar.w = val;
+ bar.x = x + val;
+ covers.push(cover = this.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(this.g.shim));
+ cover.bar = bar;
+ size += bar.value;
+ }
+ Y += barheight;
+ }
+ Y += bargutter;
+ }
+ covers2.toFront();
+ Y = y + bargutter;
+ if (!opts.stacked) {
+ for (var i = 0; i < len; i++) {
+ for (var j = 0; j < (multi || 1); j++) {
+ var cover = this.rect(x, Y, width, barheight).attr(this.g.shim);
+ covers.push(cover);
+ cover.bar = multi ? bars[j][i] : bars[i];
+ cover.value = cover.bar.value;
+ Y += barheight;
+ }
+ Y += bargutter;
+ }
+ }
+ chart.label = function (labels, isRight) {
+ labels = labels || [];
+ this.labels = paper.set();
+ for (var i = 0; i < len; i++) {
+ for (var j = 0; j < multi; j++) {
+ var label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);
+ var X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5,
+ A = isRight ? "end" : "start",
+ L;
+ this.labels.push(L = paper.g.text(X, bars[i * (multi || 1) + j].y, label).attr({"text-anchor": A}).insertBefore(covers[0]));
+ if (L.getBBox().x < x + 5) {
+ L.attr({x: x + 5, "text-anchor": "start"});
+ } else {
+ bars[i * (multi || 1) + j].label = L;
+ }
+ }
+ }
+ return this;
+ };
+ chart.hover = function (fin, fout) {
+ covers2.hide();
+ covers.show();
+ fout = fout || function () {};
+ covers.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.hoverColumn = function (fin, fout) {
+ covers.hide();
+ covers2.show();
+ fout = fout || function () {};
+ covers2.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ chart.each = function (f) {
+ if (!Raphael.is(f, "function")) {
+ return this;
+ }
+ for (var i = covers.length; i--;) {
+ f.call(covers[i]);
+ }
+ return this;
+ };
+ chart.eachColumn = function (f) {
+ if (!Raphael.is(f, "function")) {
+ return this;
+ }
+ for (var i = covers2.length; i--;) {
+ f.call(covers2[i]);
+ }
+ return this;
+ };
+ chart.click = function (f) {
+ covers2.hide();
+ covers.show();
+ covers.click(f);
+ return this;
+ };
+ chart.clickColumn = function (f) {
+ covers.hide();
+ covers2.show();
+ covers2.click(f);
+ return this;
+ };
+ chart.push(bars, covers, covers2);
+ chart.bars = bars;
+ chart.covers = covers;
+ return chart;
+};
diff --git a/test/g.raphael/g.dot-min.js b/test/g.raphael/g.dot-min.js
new file mode 100644
index 0000000..0488465
--- /dev/null
+++ b/test/g.raphael/g.dot-min.js
@@ -0,0 +1,7 @@
+/*
+ * 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.dotchart=function(K,J,a,f,w,v,r,F){function Q(b){+b[0]&&(b[0]=c.g.axis(K+q,J+q,a-2*q,B,n,F.axisxstep||Math.floor((a-2*q)/20),2,F.axisxlabels||null,F.axisxtype||"t"));+b[1]&&(b[1]=c.g.axis(K+a-q,J+f-q,f-2*q,A,m,F.axisystep||Math.floor((f-2*q)/20),3,F.axisylabels||null,F.axisytype||"t"));+b[2]&&(b[2]=c.g.axis(K+q,J+f-q+E,a-2*q,B,n,F.axisxstep||Math.floor((a-2*q)/20),0,F.axisxlabels||null,F.axisxtype||"t"));+b[3]&&(b[3]=c.g.axis(K+q-E,J+f-q,f-2*q,A,m,F.axisystep||Math.floor((f-2*q)/20),1,F.axisylabels||null,F.axisytype||"t"));}F=F||{};var u=this.g.snapEnds(Math.min.apply(Math,w),Math.max.apply(Math,w),w.length-1),B=u.from,n=u.to,q=F.gutter||10,I=this.g.snapEnds(Math.min.apply(Math,v),Math.max.apply(Math,v),v.length-1),A=I.from,m=I.to,z=Math.max(w.length,v.length,r.length),t=this.g.markers[F.symbol]||"disc",G=this.set(),s=this.set(),D=F.max||100,p=Math.max.apply(Math,r),o=[],c=this,N=Math.sqrt(p/Math.PI)*2/D;for(var O=0;O<z;O++){o[O]=Math.min(Math.sqrt(r[O]/Math.PI)*2/N,D);}q=Math.max.apply(Math,o.concat(q));var C=this.set(),E=Math.max.apply(Math,o);if(F.axis){var l=(F.axis+"").split(/[,\s]+/);Q(l);var P=[],S=[];for(var O=0,H=l.length;O<H;O++){var T=l[O].all?l[O].all.getBBox()[["height","width"][O%2]]:0;P[O]=T+q;S[O]=T;}q=Math.max.apply(Math,P.concat(q));for(var O=0,H=l.length;O<H;O++){if(l[O].all){l[O].remove();l[O]=1;}}Q(l);for(var O=0,H=l.length;O<H;O++){if(l[O].all){C.push(l[O].all);}}G.axis=C;}var M=(a-q*2)/((n-B)||1),L=(f-q*2)/((m-A)||1);for(var O=0,H=v.length;O<H;O++){var e=this.raphael.is(t,"array")?t[O]:t,j=K+q+(w[O]-B)*M,h=J+f-q-(v[O]-A)*L;e&&o[O]&&s.push(this.g[e](j,h,o[O]).attr({fill:F.heat?this.g.colorValue(o[O],E):Raphael.fn.g.colors[0],"fill-opacity":F.opacity?o[O]/D:1,stroke:"none"}));}var d=this.set();for(var O=0,H=v.length;O<H;O++){var j=K+q+(w[O]-B)*M,h=J+f-q-(v[O]-A)*L;d.push(this.circle(j,h,E).attr(this.g.shim));F.href&&F.href[O]&&d[O].attr({href:F.href[O]});d[O].r=+o[O].toFixed(3);d[O].x=+j.toFixed(3);d[O].y=+h.toFixed(3);d[O].X=w[O];d[O].Y=v[O];d[O].value=r[O]||0;d[O].dot=s[O];}G.covers=d;G.series=s;G.push(s,C,d);G.hover=function(g,b){d.mouseover(g).mouseout(b);return this;};G.click=function(b){d.click(b);return this;};G.each=function(g){if(!Raphael.is(g,"function")){return this;}for(var b=d.length;b--;){g.call(d[b]);}return this;};G.href=function(k){var g;for(var b=d.length;b--;){g=d[b];if(g.X==k.x&&g.Y==k.y&&g.value==k.value){g.attr({href:k.href});}}};return G;}; \ No newline at end of file
diff --git a/test/g.raphael/g.dot.js b/test/g.raphael/g.dot.js
new file mode 100644
index 0000000..ecffea2
--- /dev/null
+++ b/test/g.raphael/g.dot.js
@@ -0,0 +1,110 @@
+/*!
+ * 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.dotchart = function (x, y, width, height, valuesx, valuesy, size, opts) {
+ function drawAxis(ax) {
+ +ax[0] && (ax[0] = paper.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || "t"));
+ +ax[1] && (ax[1] = paper.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || "t"));
+ +ax[2] && (ax[2] = paper.g.axis(x + gutter, y + height - gutter + maxR, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || "t"));
+ +ax[3] && (ax[3] = paper.g.axis(x + gutter - maxR, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || "t"));
+ }
+ opts = opts || {};
+ var xdim = this.g.snapEnds(Math.min.apply(Math, valuesx), Math.max.apply(Math, valuesx), valuesx.length - 1),
+ minx = xdim.from,
+ maxx = xdim.to,
+ gutter = opts.gutter || 10,
+ ydim = this.g.snapEnds(Math.min.apply(Math, valuesy), Math.max.apply(Math, valuesy), valuesy.length - 1),
+ miny = ydim.from,
+ maxy = ydim.to,
+ len = Math.max(valuesx.length, valuesy.length, size.length),
+ symbol = this.g.markers[opts.symbol] || "disc",
+ res = this.set(),
+ series = this.set(),
+ max = opts.max || 100,
+ top = Math.max.apply(Math, size),
+ R = [],
+ paper = this,
+ k = Math.sqrt(top / Math.PI) * 2 / max;
+
+ for (var i = 0; i < len; i++) {
+ R[i] = Math.min(Math.sqrt(size[i] / Math.PI) * 2 / k, max);
+ }
+ gutter = Math.max.apply(Math, R.concat(gutter));
+ var axis = this.set(),
+ maxR = Math.max.apply(Math, R);
+ if (opts.axis) {
+ var ax = (opts.axis + "").split(/[,\s]+/);
+ drawAxis(ax);
+ var g = [], b = [];
+ for (var i = 0, ii = ax.length; i < ii; i++) {
+ var bb = ax[i].all ? ax[i].all.getBBox()[["height", "width"][i % 2]] : 0;
+ g[i] = bb + gutter;
+ b[i] = bb;
+ }
+ gutter = Math.max.apply(Math, g.concat(gutter));
+ for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {
+ ax[i].remove();
+ ax[i] = 1;
+ }
+ drawAxis(ax);
+ for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {
+ axis.push(ax[i].all);
+ }
+ res.axis = axis;
+ }
+ var kx = (width - gutter * 2) / ((maxx - minx) || 1),
+ ky = (height - gutter * 2) / ((maxy - miny) || 1);
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ var sym = this.raphael.is(symbol, "array") ? symbol[i] : symbol,
+ X = x + gutter + (valuesx[i] - minx) * kx,
+ Y = y + height - gutter - (valuesy[i] - miny) * ky;
+ sym && R[i] && series.push(this.g[sym](X, Y, R[i]).attr({fill: opts.heat ? this.g.colorValue(R[i], maxR) : Raphael.fn.g.colors[0], "fill-opacity": opts.opacity ? R[i] / max : 1, stroke: "none"}));
+ }
+ var covers = this.set();
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ var X = x + gutter + (valuesx[i] - minx) * kx,
+ Y = y + height - gutter - (valuesy[i] - miny) * ky;
+ covers.push(this.circle(X, Y, maxR).attr(this.g.shim));
+ opts.href && opts.href[i] && covers[i].attr({href: opts.href[i]});
+ covers[i].r = +R[i].toFixed(3);
+ covers[i].x = +X.toFixed(3);
+ covers[i].y = +Y.toFixed(3);
+ covers[i].X = valuesx[i];
+ covers[i].Y = valuesy[i];
+ covers[i].value = size[i] || 0;
+ covers[i].dot = series[i];
+ }
+ res.covers = covers;
+ res.series = series;
+ res.push(series, axis, covers);
+ res.hover = function (fin, fout) {
+ covers.mouseover(fin).mouseout(fout);
+ return this;
+ };
+ res.click = function (f) {
+ covers.click(f);
+ return this;
+ };
+ res.each = function (f) {
+ if (!Raphael.is(f, "function")) {
+ return this;
+ }
+ for (var i = covers.length; i--;) {
+ f.call(covers[i]);
+ }
+ return this;
+ };
+ res.href = function (map) {
+ var cover;
+ for (var i = covers.length; i--;) {
+ cover = covers[i];
+ if (cover.X == map.x && cover.Y == map.y && cover.value == map.value) {
+ cover.attr({href: map.href});
+ }
+ }
+ };
+ return res;
+};
diff --git a/test/g.raphael/g.line-min.js b/test/g.raphael/g.line-min.js
new file mode 100644
index 0000000..137adb2
--- /dev/null
+++ b/test/g.raphael/g.line-min.js
@@ -0,0 +1,7 @@
+/*
+ * 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(M,L,b,d,t,s,F){function E(x,ae){var i=x.length/ae,y=0,a=i,Y=0,X=[];while(y<x.length){a--;if(a<0){Y+=x[y]*(1+a);X.push(Y/i);Y=x[y++]*-a;a+=i}else{Y+=x[y++]}}return X}function P(j,i,aj,ah,ae,Y){var y=(aj-j)/2,x=(ae-aj)/2,ak=Math.atan((aj-j)/Math.abs(ah-i)),ai=Math.atan((ae-aj)/Math.abs(ah-Y));ak=i<ah?Math.PI-ak:ak;ai=Y<ah?Math.PI-ai:ai;var X=Math.PI/2-((ak+ai)%(Math.PI*2))/2,am=y*Math.sin(X+ak),ag=y*Math.cos(X+ak),al=x*Math.sin(X+ai),af=x*Math.cos(X+ai);return{x1:aj-am,y1:ah+ag,x2:aj+al,y2:ah+af}}F=F||{};if(!this.raphael.is(t[0],"array")){t=[t]}if(!this.raphael.is(s[0],"array")){s=[s]}var m=F.gutter||10,u=Math.max(t[0].length,s[0].length),o=F.symbol||"",Q=F.colors||Raphael.fn.g.colors,K=this,q=null,l=null,ab=this.set(),R=[];for(var aa=0,H=s.length;aa<H;aa++){u=Math.max(u,s[aa].length)}var ac=this.set();for(aa=0,H=s.length;aa<H;aa++){if(F.shade){ac.push(this.path().attr({stroke:"none",fill:Q[aa],opacity:F.nostroke?1:0.3}))}if(s[aa].length>b-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<H;aa++){if(!F.nostroke){I.push(n=this.path().attr({stroke:Q[aa],"stroke-width":F.width||2,"stroke-linejoin":"round","stroke-linecap":"round","stroke-dasharray":F.dash||""}))}var c=this.raphael.is(o,"array")?o[aa]:o,C=this.set();R=[];for(var Z=0,r=s[aa].length;Z<r;Z++){var f=M+m+((t[aa]||t[0])[Z]-z)*V,e=L+d-m-(s[aa][Z]-v)*T;(Raphael.is(c,"array")?c[Z]:c)&&C.push(this.g[Raphael.fn.g.markers[this.raphael.is(c,"array")?c[Z]:c]](f,e,(F.width||2)*3).attr({fill:Q[aa],stroke:"none"}));if(F.smooth){if(Z&&Z!=r-1){var O=M+m+((t[aa]||t[0])[Z-1]-z)*V,A=L+d-m-(s[aa][Z-1]-v)*T,N=M+m+((t[aa]||t[0])[Z+1]-z)*V,w=L+d-m-(s[aa][Z+1]-v)*T;var ad=P(O,A,f,e,N,w);R=R.concat([ad.x1,ad.y1,f,e,ad.x2,ad.y2])}if(!Z){R=["M",f,e,"C",f,e]}}else{R=R.concat([Z?"L":"M",f,e])}}if(F.smooth){R=R.concat([f,e,f,e])}W.push(C);if(F.shade){ac[aa].attr({path:R.concat(["L",f,L+d-m,"L",M+m+((t[aa]||t[0])[0]-z)*V,L+d-m,"z"]).join(",")})}!F.nostroke&&n.attr({path:R.join(",")})}function G(ak){var ah=[];for(var ai=0,am=t.length;ai<am;ai++){ah=ah.concat(t[ai])}ah.sort();var an=[],ae=[];for(ai=0,am=ah.length;ai<am;ai++){ah[ai]!=ah[ai-1]&&an.push(ah[ai])&&ae.push(M+m+(ah[ai]-z)*V)}ah=an;am=ah.length;var Y=ak||K.set();for(ai=0;ai<am;ai++){var y=ae[ai]-(ae[ai]-(ae[ai-1]||M))/2,al=((ae[ai+1]||M+b)-ae[ai])/2+(ae[ai]-(ae[ai-1]||M))/2,a;ak?(a={}):Y.push(a=K.rect(y-1,L,Math.max(al+1,1),d).attr({stroke:"none",fill:"#000",opacity:0}));a.values=[];a.symbols=K.set();a.y=[];a.x=ae[ai];a.axis=ah[ai];for(var ag=0,aj=s.length;ag<aj;ag++){an=t[ag]||t[0];for(var af=0,x=an.length;af<x;af++){if(an[af]==ah[ai]){a.values.push(s[ag][af]);a.y.push(L+d-m-(s[ag][af]-v)*T);a.symbols.push(ab.symbols[ag][af])}}}ak&&ak.call(a)}!ak&&(q=Y)}function D(ai){var ae=ai||K.set(),a;for(var ag=0,ak=s.length;ag<ak;ag++){for(var af=0,ah=s[ag].length;af<ah;af++){var y=M+m+((t[ag]||t[0])[af]-z)*V,aj=M+m+((t[ag]||t[0])[af?af-1:1]-z)*V,x=L+d-m-(s[ag][af]-v)*T;ai?(a={}):ae.push(a=K.circle(y,x,Math.abs(aj-y)/2).attr({stroke:"none",fill:"#000",opacity:0}));a.x=y;a.y=x;a.value=s[ag][af];a.line=ab.lines[ag];a.shade=ab.shades[ag];a.symbol=ab.symbols[ag][af];a.symbols=ab.symbols[ag];a.axis=(t[ag]||t[0])[af];ai&&ai.call(a)}}!ai&&(l=ae)}ab.push(I,ac,W,B,q,l);ab.lines=I;ab.shades=ac;ab.symbols=W;ab.axis=B;ab.hoverColumn=function(i,a){!q&&G();q.mouseover(i).mouseout(a);return this};ab.clickColumn=function(a){!q&&G();q.click(a);return this};ab.hrefColumn=function(X){var Y=K.raphael.is(arguments[0],"array")?arguments[0]:arguments;if(!(arguments.length-1)&&typeof X=="object"){for(var a in X){for(var j=0,y=q.length;j<y;j++){if(q[j].axis==a){q[j].attr("href",X[a])}}}}!q&&G();for(j=0,y=Y.length;j<y;j++){q[j]&&q[j].attr("href",Y[j])}return this};ab.hover=function(i,a){!l&&D();l.mouseover(i).mouseout(a);return this};ab.click=function(a){!l&&D();l.click(a);return this};ab.each=function(a){D(a);return this};ab.eachColumn=function(a){G(a);return this};return ab}; \ No newline at end of file
diff --git a/test/g.raphael/g.line.js b/test/g.raphael/g.line.js
new file mode 100644
index 0000000..2267ac2
--- /dev/null
+++ b/test/g.raphael/g.line.js
@@ -0,0 +1,254 @@
+/*!
+ * 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 (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;
+ }
+ function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) {
+ var l1 = (p2x - p1x) / 2,
+ l2 = (p3x - p2x) / 2,
+ a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
+ b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));
+ a = p1y < p2y ? Math.PI - a : a;
+ b = p3y < p2y ? Math.PI - b : b;
+ var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,
+ dx1 = l1 * Math.sin(alpha + a),
+ dy1 = l1 * Math.cos(alpha + a),
+ dx2 = l2 * Math.sin(alpha + b),
+ dy2 = l2 * Math.cos(alpha + b);
+ return {
+ x1: p2x - dx1,
+ y1: p2y + dy1,
+ x2: p2x + dx2,
+ y2: p2y + dy2
+ };
+ }
+ opts = opts || {};
+ if (!this.raphael.is(valuesx[0], "array")) {
+ valuesx = [valuesx];
+ }
+ if (!this.raphael.is(valuesy[0], "array")) {
+ valuesy = [valuesy];
+ }
+ var gutter = opts.gutter || 10,
+ 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 (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 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,
+ ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),
+ miny = ydim.from,
+ maxy = ydim.to,
+ kx = (width - gutter * 2) / ((maxx - minx) || 1),
+ ky = (height - gutter * 2) / ((maxy - miny) || 1);
+
+ 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));
+ +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));
+ +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));
+ +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));
+ }
+ var lines = this.set(),
+ symbols = this.set(),
+ line;
+ for (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,
+ 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"}));
+ if (opts.smooth) {
+ if (j && j != jj - 1) {
+ var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,
+ Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,
+ X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,
+ Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky;
+ var a = getAnchors(X0, Y0, X, Y, X2, Y2);
+ path = path.concat([a.x1, a.y1, X, Y, a.x2, a.y2]);
+ }
+ if (!j) {
+ path = ["M", X, Y, "C", X, Y];
+ }
+ } else {
+ path = path.concat([j ? "L" : "M", X, Y]);
+ }
+ }
+ if (opts.smooth) {
+ path = path.concat([X, Y, 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 (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 (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 (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;
+};
diff --git a/test/g.raphael/g.pie-min.js b/test/g.raphael/g.pie-min.js
new file mode 100644
index 0000000..55eafc0
--- /dev/null
+++ b/test/g.raphael/g.pie-min.js
@@ -0,0 +1 @@
+Raphael.fn.g.piechart=function(e,d,o,b,l){l=l||{};var k=this,m=[],g=this.set(),n=this.set(),j=this.set(),u=[],w=b.length,x=0,A=0,z=0,c=9,y=true;n.covers=g;if(w==1){j.push(this.circle(e,d,o).attr({fill:this.g.colors[0],stroke:l.stroke||"#fff","stroke-width":l.strokewidth==null?1:l.strokewidth}));g.push(this.circle(e,d,o).attr(this.g.shim));A=b[0];b[0]={value:b[0],order:0,valueOf:function(){return this.value;}};j[0].middle={x:e,y:d};j[0].mangle=180;}else{function t(F,E,i,H,D,M){var J=Math.PI/180,B=F+i*Math.cos(-H*J),p=F+i*Math.cos(-D*J),G=F+i/2*Math.cos(-(H+(D-H)/2)*J),L=E+i*Math.sin(-H*J),K=E+i*Math.sin(-D*J),C=E+i/2*Math.sin(-(H+(D-H)/2)*J),I=["M",F,E,"L",B,L,"A",i,i,0,+(Math.abs(D-H)>180),1,p,K,"z"];I.middle={x:G,y:C};return I;}for(var v=0;v<w;v++){A+=b[v];b[v]={value:b[v],order:v,valueOf:function(){return this.value;}};}b.sort(function(p,i){return i.value-p.value;});for(v=0;v<w;v++){if(y&&b[v]*360/A<=1.5){c=v;y=false;}if(v>c){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<w;v++){var f=x-360*b[v]/A/2;if(!v){x=90-f;f=x-360*b[v]/A/2;}if(l.init){var h=t(e,d,1,x,x-360*b[v]/A).join(",");}var s=t(e,d,o,x,x-=360*b[v]/A);var q=this.path(l.init?h:s).attr({fill:l.colors&&l.colors[v]||this.g.colors[v]||"#666",stroke:l.stroke||"#fff","stroke-width":(l.strokewidth==null?1:l.strokewidth),"stroke-linejoin":"round"});q.value=b[v];q.middle=s.middle;q.mangle=f;m.push(q);j.push(q);l.init&&q.animate({path:s.join(",")},(+l.init-1)||1000,">");}for(v=0;v<w;v++){q=k.path(m[v].attr("path")).attr(this.g.shim);l.href&&l.href[v]&&q.attr({href:l.href[v]});q.attr=function(){};g.push(q);j.push(q);}}n.hover=function(C,r){r=r||function(){};var B=this;for(var p=0;p<w;p++){(function(D,E,i){var F={sector:D,cover:E,cx:e,cy:d,mx:D.middle.x,my:D.middle.y,mangle:D.mangle,r:o,value:b[i],total:A,label:B.labels&&B.labels[i]};E.mouseover(function(){C.call(F);}).mouseout(function(){r.call(F);});})(j[p],g[p],p);}return this;};n.each=function(B){var r=this;for(var p=0;p<w;p++){(function(C,D,i){var E={sector:C,cover:D,cx:e,cy:d,x:C.middle.x,y:C.middle.y,mangle:C.mangle,r:o,value:b[i],total:A,label:r.labels&&r.labels[i]};B.call(E);})(j[p],g[p],p);}return this;};n.click=function(B){var r=this;for(var p=0;p<w;p++){(function(C,D,i){var E={sector:C,cover:D,cx:e,cy:d,mx:C.middle.x,my:C.middle.y,mangle:C.mangle,r:o,value:b[i],total:A,label:r.labels&&r.labels[i]};D.click(function(){B.call(E);});})(j[p],g[p],p);}return this;};n.inject=function(i){i.insertBefore(g[0]);};var a=function(G,B,r,p){var K=e+o+o/5,J=d,F=J+10;G=G||[];p=(p&&p.toLowerCase&&p.toLowerCase())||"east";r=k.g.markers[r&&r.toLowerCase()]||"disc";n.labels=k.set();for(var E=0;E<w;E++){var L=j[E].attr("fill"),C=b[E].order,D;b[E].others&&(G[C]=B||"Others");G[C]=k.g.labelise(G[C],b[E],A);n.labels.push(k.set());n.labels[E].push(k.g[r](K+5,F,5).attr({fill:L,stroke:"none"}));n.labels[E].push(D=k.text(K+20,F,G[C]||b[C]).attr(k.g.txtattr).attr({fill:l.legendcolor||"#000","text-anchor":"start"}));g[E].label=n.labels[E];F+=D.getBBox().height*1.2;}var H=n.labels.getBBox(),I={east:[0,-H.height/2],west:[-H.width-2*o-20,-H.height/2],north:[-o-H.width/2,-o-H.height-10],south:[-o-H.width/2,o+10]}[p];n.labels.translate.apply(n.labels,I);n.push(n.labels);};if(l.legend){a(l.legend,l.legendothers,l.legendmark,l.legendpos);}n.push(j,g);n.series=j;n.covers=g;return n;}; \ No newline at end of file
diff --git a/test/g.raphael/g.pie.js b/test/g.raphael/g.pie.js
new file mode 100644
index 0000000..f055d5c
--- /dev/null
+++ b/test/g.raphael/g.pie.js
@@ -0,0 +1,205 @@
+/*
+ * 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.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: opts.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 (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 (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 (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);
+ 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;
+};
diff --git a/test/g.raphael/g.raphael-min.js b/test/g.raphael/g.raphael-min.js
new file mode 100644
index 0000000..1dba168
--- /dev/null
+++ b/test/g.raphael/g.raphael-min.js
@@ -0,0 +1,7 @@
+/*
+ * 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(){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<e.length){Raphael.fn.g.colors.push("hsb("+e[b]+", .75, .75)");}else{Raphael.fn.g.colors.push("hsb("+e[b-e.length]+", 1, .5)");}}Raphael.fn.g.text=function(f,h,g){return this.text(f,h,g).attr(this.g.txtattr);};Raphael.fn.g.labelise=function(f,h,g){if(f){return(f+"").replace(/(##+(?:\.#+)?)|(%%+(?:\.%+)?)/g,function(i,k,j){if(k){return(+h).toFixed(k.replace(/^#+\.?/g,"").length);}if(j){return(h*100/g).toFixed(j.replace(/^%+\.?/g,"").length)+"%";}});}else{return(+h).toFixed(0);}};Raphael.fn.g.finger=function(l,k,g,m,h,i,j){if((h&&!m)||(!h&&!g)){return j?"":this.path();}i={square:"square",sharp:"sharp",soft:"soft"}[i]||"round";var o;m=Math.round(m);g=Math.round(g);l=Math.round(l);k=Math.round(k);switch(i){case"round":if(!h){var f=~~(m/2);if(g<f){f=g;o=["M",l+0.5,k+0.5-~~(m/2),"l",0,0,"a",f,~~(m/2),0,0,1,0,m,"l",0,0,"z"];}else{o=["M",l+0.5,k+0.5-f,"l",g-f,0,"a",f,f,0,1,1,0,m,"l",f-g,0,"z"];}}else{f=~~(g/2);if(m<f){f=m;o=["M",l-~~(g/2),k,"l",0,0,"a",~~(g/2),f,0,0,1,g,0,"l",0,0,"z"];}else{o=["M",l-f,k,"l",0,f-m,"a",f,f,0,1,1,g,0,"l",0,m-f,"z"];}}break;case"sharp":if(!h){var n=~~(m/2);o=["M",l,k+n,"l",0,-m,a(g-n,0),0,c(n,g),n,-c(n,g),n+(n*2<m),"z"];}else{n=~~(g/2);o=["M",l+n,k,"l",-g,0,0,-a(m-n,0),n,-c(n,m),n,c(n,m),n,"z"];}break;case"square":if(!h){o=["M",l,k+~~(m/2),"l",0,-m,g,0,0,m,"z"];}else{o=["M",l+~~(g/2),k,"l",1-g,0,0,-m,g-1,0,"z"];}break;case"soft":if(!h){f=c(g,Math.round(m/5));o=["M",l+0.5,k+0.5-~~(m/2),"l",g-f,0,"a",f,f,0,0,1,f,f,"l",0,m-f*2,"a",f,f,0,0,1,-f,f,"l",f-g,0,"z"];}else{f=c(Math.round(g/5),m);o=["M",l-~~(g/2),k,"l",0,f-m,"a",f,f,0,0,1,f,-f,"l",g-2*f,0,"a",f,f,0,0,1,f,f,"l",0,m-f,"z"];}}if(j){return o.join(",");}else{return this.path(o);}};Raphael.fn.g.disc=function(f,h,g){return this.circle(f,h,g);};Raphael.fn.g.line=function(f,h,g){return this.rect(f-g,h-g/5,2*g,2*g/5);};Raphael.fn.g.square=function(f,h,g){g=g*0.7;return this.rect(f-g,h-g,2*g,2*g);};Raphael.fn.g.triangle=function(f,h,g){g*=1.75;return this.path("M".concat(f,",",h,"m0-",g*0.58,"l",g*0.5,",",g*0.87,"-",g,",0z"));};Raphael.fn.g.diamond=function(f,h,g){return this.path(["M",f,h-g,"l",g,g,-g,g,-g,-g,g,-g,"z"]);};Raphael.fn.g.flower=function(j,h,f,g){f=f*1.25;var o=f,m=o*0.5;g=+g<3||!g?5:g;var p=["M",j,h+m,"Q"],l;for(var k=1;k<g*2+1;k++){l=k%2?o:m;p=p.concat([+(j+l*Math.sin(k*Math.PI/g)).toFixed(3),+(h+l*Math.cos(k*Math.PI/g)).toFixed(3)]);}p.push("z");return this.path(p.join(","));};Raphael.fn.g.star=function(f,n,m,h,g){h=h||m*0.382;g=g||5;var l=["M",f,n+h,"L"],k;for(var j=1;j<g*2;j++){k=j%2?m:h;l=l.concat([(f+k*Math.sin(j*Math.PI/g)),(n+k*Math.cos(j*Math.PI/g))]);}l.push("z");return this.path(l.join(","));};Raphael.fn.g.cross=function(f,h,g){g=g/2.5;return this.path("M".concat(f-g,",",h,"l",[-g,-g,g,-g,g,g,g,-g,g,g,-g,g,g,g,-g,g,-g,-g,-g,g,-g,-g,"z"]));};Raphael.fn.g.plus=function(f,h,g){g=g/2;return this.path("M".concat(f-g/2,",",h-g/2,"l",[0,-g,g,0,0,g,g,0,0,g,-g,0,0,g,-g,0,0,-g,-g,0,0,-g,"z"]));};Raphael.fn.g.arrow=function(f,h,g){return this.path("M".concat(f-g*0.7,",",h-g*0.4,"l",[g*0.6,0,0,-g*0.4,g,g*0.8,-g,g*0.8,0,-g*0.4,-g*0.6,0],"z"));};Raphael.fn.g.tag=function(f,m,l,k,i){k=k||0;i=i==null?5:i;l=l==null?"$9.99":l;var h=0.5522*i,g=this.set(),j=3;g.push(this.path().attr({fill:"#000",stroke:"#000"}));g.push(this.text(f,m,l).attr(this.g.txtattr).attr({fill:"#fff","font-family":"Helvetica, Arial"}));g.update=function(){this.rotate(0,f,m);var o=this[1].getBBox();if(o.height>=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(p<o){p=q((o+0.5)*Math.pow(10,h))/Math.pow(10,h);}k=q((n-(h>0?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/test/g.raphael/g.raphael.js b/test/g.raphael/g.raphael.js
new file mode 100644
index 0000000..e9c74cd
--- /dev/null
+++ b/test/g.raphael/g.raphael.js
@@ -0,0 +1,475 @@
+/*!
+ * 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 () {
+ var mmax = Math.max,
+ mmin = 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 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 = ~~(height / 2);
+ if (width < r) {
+ r = width;
+ 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 {
+ r = ~~(width / 2);
+ if (height < r) {
+ r = height;
+ 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"];
+ }
+ }
+ break;
+ case "sharp":
+ if (!dir) {
+ 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 {
+ 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 + ~~(height / 2), "l", 0, -height, width, 0, 0, height, "z"];
+ } else {
+ path = ["M", x + ~~(width / 2), y, "l", 1 - width, 0, 0, -height, width - 1, 0, "z"];
+ }
+ break;
+ case "soft":
+ if (!dir) {
+ 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 = 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) {
+ 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, rays) {
+ r2 = r2 || r * .382;
+ rays = rays || 5;
+ var points = ["M", cx, cy + r2, "L"],
+ R;
+ for (var i = 1; i < rays * 2; i++) {
+ R = i % 2 ? r : r2;
+ 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(","));
+ };
+ 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: "#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();
+ 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));
+ 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);
+ 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, -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 > 3 ? 3 : dir;
+ size = size || 5;
+ text = text || "$9.99";
+ var res = this.set(),
+ d = 3;
+ 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;
+ 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, -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.animate(xy, 500, ">");
+ } else {
+ this.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: "#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(),
+ 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 = 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();
+ return res;
+ };
+ Raphael.fn.g.labelit = function (set) {
+ var bb = set.getBBox(),
+ 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;
+ 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 = 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),
+ 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(" + [mmin((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 ? ~~(a) + .5 : Math.round(a);
+ }
+ var d = (t - f) / steps,
+ r = ~~(d),
+ R = r,
+ i = 0;
+ if (r) {
+ while (R) {
+ i--;
+ R = ~~(d * Math.pow(10, i)) / Math.pow(10, i);
+ }
+ i ++;
+ } else {
+ while (!r) {
+ i = i || 1;
+ r = ~~(d * Math.pow(10, i)) / Math.pow(10, i);
+ i++;
+ }
+ i && 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);
+ }
+ 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 ? 2 : 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 {
+ label = f;
+ rnd = (i > 0) * i;
+ addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation);
+ var X = x,
+ dx = length / steps,
+ txt = 0,
+ prev = 0;
+ while (X <= x + length) {
+ type != "-" && type != " " && (path = path.concat(["M", X + .5, y - (type == "+" ? dashsize : !!orientation * dashsize * 2), "l", 0, dashsize * 2 + 1]));
+ 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();
+ if (prev >= bb.x - 5) {
+ text.pop(text.length - 1).remove();
+ } else {
+ prev = bb.x + bb.width;
+ }
+ 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 = mmin(fs[0].b * times, 1);
+ fs[0].s = fs[0].s / times;
+ 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] + ")"});
+ };
+ 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 = mmin(fs[0].s * times, 1);
+ fs[0].b = fs[0].b / times;
+ 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] + ")"});
+ };
+ 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/test/g.raphael/test.html b/test/g.raphael/test.html
new file mode 100644
index 0000000..01e8d85
--- /dev/null
+++ b/test/g.raphael/test.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <title>gRaphaël Dynamic Bar Chart</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="author" content="Dmitry Baranovskiy">
+ <meta name="description" content="Charting JavaScript Library">
+ <link rel="stylesheet" href="demo.css" type="text/css" media="screen" charset="utf-8">
+ <link rel="stylesheet" href="demo-print.css" type="text/css" media="print" charset="utf-8">
+ <script src="../raphael.js" type="text/javascript" charset="utf-8"></script>
+ <script src="g.raphael.js" type="text/javascript" charset="utf-8"></script>
+ <script src="g.bar.js" type="text/javascript" charset="utf-8"></script>
+ <script type="text/javascript" charset="utf-8">
+ window.onload = function () {
+ var r = Raphael("holder"),
+ fin = function () {
+ console.log(this);
+ this.flag = r.g.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
+ },
+ fout = function () {
+ this.flag.animate({opacity: 0}, 300, function () {this.remove();});
+ },
+ fin2 = function () {
+ var y = [], res = [];
+ for (var i = this.bars.length; i--;) {
+ y.push(this.bars[i].y);
+ res.push(this.bars[i].value || "0");
+ }
+ this.flag = r.g.popup(this.bars[0].x, Math.min.apply(Math, y), res.join(", ")).insertBefore(this);
+ },
+ fout2 = function () {
+ this.flag.animate({opacity: 0}, 300, function () {this.remove();});
+ };
+ r.g.txtattr.font = "12px 'Fontin Sans', Fontin-Sans, sans-serif";
+
+ r.g.text(160, 10, "Single Series Chart");
+ r.g.text(480, 10, "Multiline Series Stacked Chart");
+ r.g.text(160, 250, "Multiple Series Chart");
+ r.g.text(480, 250, "Multiline Series Stacked Chart\nColumn Hover");
+
+ r.g.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]).hover(fin, fout);
+ r.g.hbarchart(330, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]], {stacked: true}).hover(fin, fout);
+ r.g.hbarchart(10, 250, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]]).hover(fin, fout);
+ var c = r.g.barchart(330, 250, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]], {stacked: true, type: "soft"}).hoverColumn(fin2, fout2).eachColumn(function () {
+ this.bars[1].attr({stroke: "#000"});
+ });
+ // c.bars[1].attr({stroke: "#fff"});
+ };
+ </script>
+ </head>
+ <body class="raphael" id="g.raphael.dmitry.baranovskiy.com">
+ <div id="holder"></div>
+ <p>
+ Demo of <a href="http://g.raphaeljs.com/">gRaphaël</a> JavaScript library.
+ </p>
+ </body>
+</html>
diff --git a/test/g.raphael/test2.html b/test/g.raphael/test2.html
new file mode 100644
index 0000000..f5ded7b
--- /dev/null
+++ b/test/g.raphael/test2.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <title>gRaphaël Static Line Charts</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="author" content="Dmitry Baranovskiy">
+ <meta name="description" content="Charting JavaScript Library">
+ <link rel="stylesheet" href="demo.css" type="text/css" media="screen" charset="utf-8">
+ <link rel="stylesheet" href="demo-print.css" type="text/css" media="print" charset="utf-8">
+ <script src="../raphael.js" type="text/javascript" charset="utf-8"></script>
+ <script src="g.raphael.js" type="text/javascript" charset="utf-8"></script>
+ <script src="g.line.js" type="text/javascript" charset="utf-8"></script>
+ <script type="text/javascript" charset="utf-8">
+ window.onload = function () {
+ var r = Raphael("holder");
+ r.g.txtattr.font = "12px 'Fontin Sans', Fontin-Sans, sans-serif";
+
+ var x = [], y = [], y2 = [], y3 = [];
+ for (var i = 0; i < 500; i++) {
+ x[i] = i * 10;
+ y[i] = (y[i - 1] || 0) + (Math.random() * 7) - 3;
+ y2[i] = (y2[i - 1] || 150) + (Math.random() * 7) - 3.5;
+ y3[i] = (y3[i - 1] || 300) + (Math.random() * 7) - 4;
+ }
+
+ r.g.text(160, 10, "Simple Line Chart");
+ r.g.text(480, 10, "shade = true");
+ r.g.text(160, 250, "shade = true & nostroke = true");
+ r.g.text(480, 250, "Symbols, axis and hover effect");
+
+ r.g.linechart(10, 10, 300, 220, x, [y, y2, y3]);
+ r.g.linechart(330, 10, 300, 220, x, [y, y2, y3], {shade: true});
+ r.g.linechart(10, 250, 300, 220, x, [y, y2, y3], {nostroke: true, shade: true});
+ var lines = r.g.linechart(330, 250, 300, 220, [[1, 2, 3, 4, 5, 6, 7],[3.5, 4.5, 5.5, 6.5, 7, 8]], [[12, 32, 23, 15, 17, 27, 22], [10, 20, 30, 25, 15, 28]], {nostroke: false, axis: "0 0 1 1", symbol: "o"}).hoverColumn(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")}]));
+ }
+ }, function () {
+ this.tags && this.tags.remove();
+ });
+ // lines.lines[0].animate({"stroke-width": 6}, 1000);
+ // lines.symbols[0].attr({stroke: "#fff"});
+ // lines.symbols[0][1].animate({fill: "#f00"}, 1000);
+ };
+ </script>
+ </head>
+ <body class="raphael" id="g.raphael.dmitry.baranovskiy.com">
+ <div id="holder"></div>
+ <p>
+ Demo of <a href="http://g.raphaeljs.com/">gRaphaël</a> JavaScript library.
+ </p>
+ </body>
+</html>