[Pkg-javascript-commits] [libjs-graphael] 01/07: Imported Upstream version 0.5

Praveen Arimbrathodiyil praveen at moszumanska.debian.org
Mon Dec 14 14:50:18 UTC 2015


This is an automated email from the git hooks/post-receive script.

praveen pushed a commit to branch master
in repository libjs-graphael.

commit 3ae995830c5bc55fe9fa00baf6929ff743f64052
Author: Praveen Arimbrathodiyil <praveen at debian.org>
Date:   Mon Dec 14 20:13:36 2015 +0530

    Imported Upstream version 0.5
---
 README.markdown         |  21 ++
 docs/blueprint-min.png  | Bin 0 -> 6705 bytes
 docs/dr-print.css       | 218 ++++++++++++
 docs/dr.css             | 404 ++++++++++++++++++++++
 docs/reference.html     | 350 +++++++++++++++++++
 docs/reference.js       |  35 ++
 g.bar.js                | 621 +++++++++++++++++++++++++++++++++
 g.dot.js                | 156 +++++++++
 g.line.js               | 329 ++++++++++++++++++
 g.pie.js                | 255 ++++++++++++++
 g.raphael.js            | 887 ++++++++++++++++++++++++++++++++++++++++++++++++
 g.raphael.json          |   9 +
 min/g.bar-min.js        |   7 +
 min/g.dot-min.js        |   7 +
 min/g.line-min.js       |   7 +
 min/g.pie-min.js        |   1 +
 min/g.raphael-min.js    |   7 +
 raphael-min.js          |   8 +
 test/barchart.html      |  37 ++
 test/barchart2.html     |  51 +++
 test/brightness.html    |  47 +++
 test/css/demo-print.css |  17 +
 test/css/demo.css       |  21 ++
 test/dotchart.html      |  35 ++
 test/images/bg.png      | Bin 0 -> 3383 bytes
 test/images/bgbg.png    | Bin 0 -> 2436 bytes
 test/linechart.html     |  66 ++++
 test/piechart.html      |  26 ++
 test/piechart2.html     |  46 +++
 test/tooltips.html      |  85 +++++
 30 files changed, 3753 insertions(+)

diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..f09da30
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,21 @@
+g.Raphaël - Official charting plugin for Raphaël
+=========
+
+For more information, see: http://g.raphaeljs.com/
+
+Changelog
+---------
+
+**v0.5**
+
+ * Refactored codebase and API to work with Raphaël 2.0
+ * `g` is no longer a namespace, but instead a prototype object that all charts inherit. See documentation for all configurable options on the `g` prototype.
+ * `g.markers` has been removed. The marker parameter strings now just try and resolve functions on the Paper prototype.
+ * All primitive shapes have been removed. They are now part of Raphaël core in `plugins/`
+ * The companion function `original` to the brightness functions `lighter` and `darker` has been renamed to `resetBrightness` to account for the `g` namespace removal
+ * Tooltips have been modified/enhanced in the following ways:
+   * All tooltips can now be called on any Element or Set instance, as well as from the paper object.
+   * All tooltip `update` functions have been removed. Tooltip functions now return their path element. It is up to the caller to manage both the Element or set that is used as the context and the path element that was drawn by the tooltip function.
+   * All tooltip `dir` options have been changed from `0`, `1`, `2`, `3`, to `'down'`, `'left'`, `'up'`, `'right'` repectively.
+   * `blob` and `drop` tooltips no longer accept `size` parameters. Instead, the bounding box of the Element/Set being used as content is used to automatically determine the size.
+   * `popupit` and `labelit` have been removed. Their functionality is now the default behavior of all tooltips
diff --git a/docs/blueprint-min.png b/docs/blueprint-min.png
new file mode 100644
index 0000000..f9c4302
Binary files /dev/null and b/docs/blueprint-min.png differ
diff --git a/docs/dr-print.css b/docs/dr-print.css
new file mode 100644
index 0000000..91b4137
--- /dev/null
+++ b/docs/dr-print.css
@@ -0,0 +1,218 @@
+html, body {
+    background: #fff;
+    margin: 2cm 1cm;
+    padding: 0;
+}
+.dr-doc {
+    font: 300 16px/1.4 "Myriad Pro", "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif;
+}
+.dr-toc {
+    display: none;
+}
+::-moz-selection {
+    background: #c00;
+    color: #fff;
+}
+::selection {
+    background: #c00;
+    color: #fff;
+}
+.dr-doc code,
+.dr-type em,
+.dr-returns em,
+.dr-property em {
+    font-family: Menlo, Consolas, Monaco, "Lucida Console", monospace;
+}
+pre.code {
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+    border: dotted 1px #666;
+    padding: .5em;
+}
+pre.code code {
+    color: #000;
+}
+code b {
+    color: #63f;
+    font-weight: normal;
+}
+code i,
+code i *,
+code i .d {
+    color: #363;
+    font-style: normal;
+}
+code .s {
+    color: #e7be61;
+}
+code .d {
+    color: #cf6a4c;
+}
+code .c,
+code .c * {
+    color: #999;
+    font-style: italic;
+}
+em.amp {
+    font-family: Baskerville, "Goudy Old Style", Palatino, "Book Antiqua", serif;
+    font-style: italic;
+}
+dl.dr-parameters {
+    margin: 8px 0;
+}
+dt.dr-param {
+    color: #666;
+    font-weight: 400;
+    float: left;
+    margin-right: 16px;
+    min-width: 160px;
+}
+dd.dr-type {
+    margin: 0;
+}
+dd.dr-description {
+    display: table;
+    min-height: 24px;
+    border: solid 1px #fff;
+}
+.dr-type {
+    float: left;
+}
+.extra {
+    display: none;
+}
+.dr-type em,
+.dr-returns em,
+.dr-property em {
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    background: #ccc;
+    border-radius: 5px;
+    float: left;
+    font-size: .75em;
+    font-style: normal;
+    font-weight: 700;
+    margin: 0 8px 0 0;
+    min-width: 80px;
+    padding: 2px 5px;
+    text-align: center;
+}
+.dr-type em.amp,
+.dr-returns em.amp,
+.dr-property em.amp {
+    float: none;
+    background: none;
+    font-size: 1em;
+    font-weight: 400;
+    font-style: italic;
+    margin: 0;
+    padding: 0;
+    min-width: 0;
+}
+.dr-property em.dr-type {
+    margin: 4px 16px 0 0;
+}
+em.dr-type-string {
+    background: #e1edb1;
+    color: #3d4c00;
+}
+em.dr-type-object {
+    background: #edb1b1;
+    color: #4c0000;
+}
+em.dr-type-function {
+    background: #cfb1ed;
+    color: #26004c;
+}
+em.dr-type-number {
+    background: #b1c9ed;
+    color: #001e4c;
+}
+em.dr-type-boolean {
+    background: #b1edc9;
+    color: #004c1e;
+}
+em.dr-type-array {
+    background: #edd5b1;
+    color: #4c2d00;
+}
+dd.dr-optional {
+    display: none;
+}
+ol.dr-json {
+    list-style: none;
+    margin: 0 -30px;
+    padding: 16px 30px;
+}
+ol.dr-json .dr-json-key {
+    float: left;
+    min-width: 50px;
+    margin-right: 16px;
+}
+ol.dr-json .dr-json-description {
+    display: table;
+}
+ol.dr-json ol.dr-json  {
+    margin: 0;
+    padding: 0 0 0 50px;
+}
+h1 {
+    font-weight: 400;
+    font-size: 2.6em;
+    margin: 0;
+}
+h2, h3, h4, h5 {
+    margin: 1em 0 .5em 0;
+    padding: 6px 0 0;
+    font-weight: 600;
+    position: relative;
+    clear: left;
+}
+h5 {
+    font-size: 18px;
+}
+h4 {
+    font-size: 20px;
+}
+h3 {
+    font-size: 28px;
+}
+h2 {
+    font-size: 38px;
+}
+h2.dr-method,
+h3.dr-method,
+h4.dr-method,
+h5.dr-method {
+    color: #900;
+}
+h2.dr-property,
+h3.dr-property,
+h4.dr-property,
+h5.dr-property {
+    color: #009;
+}
+i.dr-trixie {
+    display: none;
+}
+p.header {
+    font-size: 19px;
+    font-weight: 600;
+    margin: 1em 0 .3em;
+}
+.dr-returns {
+    margin-top: 16px;
+}
+.dr-returns .dr-title {
+    float: left;
+    margin-right: 16px;
+    width: 160px;
+}
+a.dr-hash,
+a.dr-link,
+a.dr-sourceline {
+    display: none;
+}
+p {
+    margin: 0 0 .5em;
+}
\ No newline at end of file
diff --git a/docs/dr.css b/docs/dr.css
new file mode 100644
index 0000000..6d999ca
--- /dev/null
+++ b/docs/dr.css
@@ -0,0 +1,404 @@
+html, body {
+    height: 100%;
+    margin: 0;
+    padding: 0;
+}
+#dr-js {
+    background: #999;
+    margin: 0;
+    padding: 0;
+    overflow-y: hidden;
+}
+#src-dr-js {
+    background: #000;
+    margin: 1em;
+    padding: 0;
+}
+.dr-doc {
+    background: #eee;
+    border-right: solid #eee 3px;
+    float: right;
+    font: 300 16px/1.4 "Myriad Pro", "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif;
+    height: 100%;
+    margin: 0;
+    overflow: auto;
+    padding: 0 30px;
+    width: 800px;
+}
+.dr-toc {
+    background: #ddd;
+    background: -moz-linear-gradient(left, #ddd 0%, #eee 100%); /* firefox */
+    background: -webkit-gradient(linear, left top, right top, color-stop(0%, #ddd), color-stop(100%, #eee)); /* webkit */
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ddd', endColorstr='#eee',GradientType=1); /* ie */
+    border-right: solid #ddd 3px;
+    float: right;
+    font-family: Menlo, Consolas, Monaco, "Lucida Console", monospace;
+    height: 100%;
+    list-style: none;
+    margin: 0;
+    overflow: auto;
+    padding: 0 16px;
+    width: 240px;
+}
+#dr {
+    margin: 0 auto;
+    width: 1152px;
+    height: 100%;
+}
+::-moz-selection {
+    background: #c00;
+    color: #fff;
+}
+::selection {
+    background: #c00;
+    color: #fff;
+}
+.dr-doc code,
+.dr-type em,
+.dr-returns em,
+.dr-property em {
+    font-family: Menlo, Consolas, Monaco, "Lucida Console", monospace;
+}
+.extra {
+    display: none;
+}
+pre.code code {
+    color: #fff;
+}
+pre.code {
+    background: #333;
+    color: #fff;
+    overflow-x: auto;
+    padding: 16px 30px;
+    margin: 0 -30px;
+}
+code b {
+    color: #e9df8f;
+    font-weight: normal;
+}
+code i,
+code i *,
+code i .d {
+    color: #8b9967;
+    font-style: normal;
+}
+code .s {
+    color: #e7be61;
+}
+code .d {
+    color: #cf6a4c;
+}
+code .c,
+code .c * {
+    color: #999;
+    font-style: italic;
+}
+em.amp {
+    font-family: Baskerville, "Goudy Old Style", Palatino, "Book Antiqua", serif;
+    font-style: italic;
+}
+dl.dr-parameters {
+    margin: 8px 0;
+}
+dt.dr-param {
+    color: #666;
+    font-weight: 400;
+    float: left;
+    margin-right: 16px;
+    min-width: 160px;
+}
+dd.dr-type {
+    margin: 0;
+}
+dd.dr-description {
+    display: table;
+    min-height: 24px;
+    border: solid 1px #eee;
+}
+.dr-type {
+    float: left;
+}
+.dr-type em,
+.dr-returns em,
+.dr-property em {
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    background: #ccc;
+    border-radius: 5px;
+    float: left;
+    font-size: .75em;
+    font-style: normal;
+    font-weight: 700;
+    margin: 0 8px 0 0;
+    min-width: 80px;
+    padding: 2px 5px;
+    text-align: center;
+}
+.dr-type em.amp,
+.dr-returns em.amp,
+.dr-property em.amp {
+    float: none;
+    background: none;
+    font-size: 1em;
+    font-weight: 400;
+    font-style: italic;
+    margin: 0;
+    padding: 0;
+    min-width: 0;
+}
+.dr-property em.dr-type {
+    margin: 4px 16px 0 0;
+}
+em.dr-type-string {
+    background: #e1edb1;
+    color: #3d4c00;
+}
+em.dr-type-object {
+    background: #edb1b1;
+    color: #4c0000;
+}
+em.dr-type-function {
+    background: #cfb1ed;
+    color: #26004c;
+}
+em.dr-type-number {
+    background: #b1c9ed;
+    color: #001e4c;
+}
+em.dr-type-boolean {
+    background: #b1edc9;
+    color: #004c1e;
+}
+em.dr-type-array {
+    background: #edd5b1;
+    color: #4c2d00;
+}
+dd.dr-optional {
+    display: none;
+}
+ol.dr-json {
+    background: #ddd;
+    list-style: none;
+    margin: 0 -30px;
+    padding: 16px 30px;
+}
+ol.dr-json .dr-json-key {
+    float: left;
+    min-width: 50px;
+    margin-right: 16px;
+}
+ol.dr-json .dr-json-description {
+    display: table;
+}
+ol.dr-json ol.dr-json  {
+    margin: 0;
+    padding: 0 0 0 50px;
+}
+h1 {
+    font-weight: 400;
+    font-size: 2.6em;
+    margin: 0;
+}
+h2, h3, h4, h5 {
+    margin: 1em 0 .5em 0;
+    padding: 6px 0 0;
+    font-weight: 600;
+    position: relative;
+}
+h5 {
+    font-size: 18px;
+}
+h4 {
+    font-size: 20px;
+}
+h3 {
+    font-size: 28px;
+}
+h2 {
+    font-size: 38px;
+}
+h2.dr-method,
+h3.dr-method,
+h4.dr-method,
+h5.dr-method {
+    color: #900;
+}
+h2.dr-property,
+h3.dr-property,
+h4.dr-property,
+h5.dr-property {
+    color: #009;
+}
+i.dr-trixie {
+    border: solid 10px #eee;
+    border-left-color: #999;
+    height: 0;
+    margin-left: -30px;
+    margin-top: -10px;
+    overflow: hidden;
+    position: absolute;
+    top: 50%;
+    width: 0;
+}
+p.header {
+    font-size: 19px;
+    font-weight: 600;
+    margin: 1em 0 .3em;
+}
+.dr-returns {
+    margin-top: 16px;
+}
+.dr-returns .dr-title {
+    float: left;
+    margin-right: 16px;
+    width: 160px;
+}
+.dr-toc a {
+    display: block;
+    text-decoration: none;
+    color: #333;
+    padding-top: 8px;
+    position: relative;
+    z-index: 1000;
+}
+.dr-toc li.dr-lvl1 a {
+    padding-left: 1em;
+}
+.dr-toc li.dr-lvl2 a {
+    padding-left: 2em;
+}
+.dr-toc li.dr-lvl3 a {
+    padding-left: 3em;
+}
+.dr-toc li.dr-lvl4 a {
+    padding-left: 4em;
+}
+.dr-toc li.dr-lvl5 a {
+    padding-left: 5em;
+}
+.dr-toc li.dr-lvl6 a {
+    padding-left: 6em;
+}
+.dr-toc a.dr-property {
+    color: #339;
+}
+.dr-toc a.dr-method {
+    color: #933;
+}
+.dr-toc a:hover {
+    text-shadow: 0 0 2px #333;
+}
+.dr-toc a.dr-property:hover {
+    text-shadow: 0 0 2px #66c;
+}
+.dr-toc a.dr-method:hover {
+    text-shadow: 0 0 2px #c66;
+}
+a.dr-hash,
+a.dr-sourceline {
+    -webkit-transition: opacity 0.2s linear;
+    color: #333;
+    font-family: Menlo, "Arial Unicode MS", sans-serif;
+    margin: 0 0 0 .3em;
+    opacity: 0;
+    text-decoration: none;
+}
+a.dr-link {
+    position: relative;
+    color: #3875c0;
+}
+a.dr-link:hover {
+    text-shadow: 0 1px 2px #999;
+    bottom: 1px;
+    padding-bottom: 1px;
+}
+a.dr-link:visited {
+    color: #7051bc;
+}
+h2:hover a.dr-hash,
+h3:hover a.dr-hash,
+h4:hover a.dr-hash,
+h5:hover a.dr-hash,
+h2:hover a.dr-sourceline,
+h3:hover a.dr-sourceline,
+h4:hover a.dr-sourceline,
+h5:hover a.dr-sourceline {
+    opacity: 1;
+}
+p {
+    margin: 0 0 .5em;
+}
+
+.dr-source-line {
+    margin: 0;
+}
+.dr-source-line a {
+    -webkit-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    -moz-border-radius: 5px;
+    -moz-border-radius: 5px;
+    border-radius: 5px;
+    border-radius: 5px;
+    color: #000;
+    background: #999;
+    font-weight: 400;
+    font-size: .75em;
+    text-decoration: none;
+    padding: 5px;
+}
+#src-dr-js code {
+    background: #000;
+    display: block;
+    color: #fff;
+    font-family: Menlo, Consolas, Monaco, "Lucida Console", monospace;
+    white-space: pre;
+    padding-left: 100px;
+    position: relative;
+    line-height: 1.2;
+}
+#src-dr-js code:hover {
+    background: #333;
+}
+#src-dr-js code:hover .ln {
+    color: #fff;
+}
+#src-dr-js code .ln {
+    position: absolute;
+    left: 0;
+    color: #333;
+    width: 70px;
+    text-align: right;
+}
+
+/*Scrollbar*/
+.dr-doc::-webkit-scrollbar,
+.dr-toc::-webkit-scrollbar {
+    width: 7px;
+    height: 9px;
+}
+.dr-doc::-webkit-scrollbar-button:start:decrement, 
+.dr-doc::-webkit-scrollbar-button:end:increment,
+.dr-toc::-webkit-scrollbar-button:start:decrement, 
+.dr-toc::-webkit-scrollbar-button:end:increment {
+    display: block;
+    height: 0;
+    background-color: transparent;
+}
+.dr-doc::-webkit-scrollbar-track-piece,
+.dr-toc::-webkit-scrollbar-track-piece {
+    -webkit-border-radius: 0;
+    -webkit-border-bottom-right-radius: 4px;
+    -webkit-border-bottom-left-radius: 4px;
+}
+.dr-doc::-webkit-scrollbar-thumb:vertical,
+.dr-toc::-webkit-scrollbar-thumb:vertical {
+    height: 50px;
+    background-color: rgba(0, 0, 0, 0.2);
+    -webkit-border-radius: 4px;
+}
+.dr-doc::-webkit-scrollbar-thumb:horizontal,
+.dr-toc::-webkit-scrollbar-thumb:horizontal {
+    width: 50px;
+    background-color: rgba(0, 0, 0, 0.2);
+    -webkit-border-radius: 4px;
+}
\ No newline at end of file
diff --git a/docs/reference.html b/docs/reference.html
new file mode 100644
index 0000000..ef3eec9
--- /dev/null
+++ b/docs/reference.html
@@ -0,0 +1,350 @@
+<!DOCTYPE html>
+<!-- Generated with Dr.js -->
+<html lang="en"><head><meta charset="utf-8"><title>g.Raphaël Reference</title><link rel="stylesheet" href="dr.css" media="screen"><link rel="stylesheet" href="dr-print.css" media="print"></head><body id="dr-js"><div id="dr"><ol class="dr-toc" id="dr-toc"><li class="dr-lvl0"><a href="#Element" class="{clas}"><span>Element</span></a></li><li class="dr-lvl1"><a href="#Element.blob" class="dr-method"><span>Element.blob()</span></a></li><li class="dr-lvl1"><a href="#Element.darker" class="dr- [...]
+<div class="extra" id="Element-extra"></div></div><div class="Element-blob-section"><h3 id="Element.blob" class="dr-method"><i class="dr-trixie"> </i>Element.blob(angle, x, y)<a href="#Element.blob" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 375 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L375">&#x27ad;</a></h3>
+<div class="extra" id="Element.blob-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'blob' tooltip. Can also be used on sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+<dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the blob's tail [default: Element's <code>x</code> or <code>cx</code>]</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the blob's tail [default: Element's <code>x</code> or <code>cx</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the blob</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">8</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).blob(<span class="d">60</span>);
+</code></pre>
+</div><div class="Element-darker-section"><h3 id="Element.darker" class="dr-method"><i class="dr-trixie"> </i>Element.darker(times)<a href="#Element.darker" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 633 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L633">&#x27ad;</a></h3>
+<div class="extra" id="Element.darker-extra"></div></div><div class="dr-method"><p>Makes the context element darker by decreasing the brightness and increasing the saturation by a given factor. Can be called on Sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">times</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">adjustment factor [default: <code>2</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">Element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">20</span>).attr({
+    fill: <i>"#ff0000"</i>,
+    stroke: <i>"#fff"</i>,
+    <i>"stroke-width"</i>: <span class="d">2</span>
+}).darker(<span class="d">6</span>);
+</code></pre>
+</div><div class="Element-drop-section"><h3 id="Element.drop" class="dr-method"><i class="dr-trixie"> </i>Element.drop(angle, x, y)<a href="#Element.drop" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 225 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L225">&#x27ad;</a></h3>
+<div class="extra" id="Element.drop-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'drop' tooltip. Can also be used on sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+<dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the drop's point [default: Element's <code>x</code> or <code>cx</code>]</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the drop's point [default: Element's <code>x</code> or <code>cx</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the drop</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">8</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).drop(<span class="d">60</span>);
+</code></pre>
+</div><div class="Element-flag-section"><h3 id="Element.flag" class="dr-method"><i class="dr-trixie"> </i>Element.flag(angle, x, y)<a href="#Element.flag" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 281 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L281">&#x27ad;</a></h3>
+<div class="extra" id="Element.flag-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'flag' tooltip. Can also be used on sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+<dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the flag's point [default: Element's <code>x</code> or <code>cx</code>]</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the flag's point [default: Element's <code>x</code> or <code>cx</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the flag</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">10</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).flag(<span class="d">60</span>);
+</code></pre>
+</div><div class="Element-label-section"><h3 id="Element.label" class="dr-method"><i class="dr-trixie"> </i>Element.label()<a href="#Element.label" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 346 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L346">&#x27ad;</a></h3>
+<div class="extra" id="Element.label-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'label' tooltip. Can also be used on sets.
+</p>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the label.</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">10</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).label();
+</code></pre>
+</div><div class="Element-lighter-section"><h3 id="Element.lighter" class="dr-method"><i class="dr-trixie"> </i>Element.lighter(times)<a href="#Element.lighter" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 597 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L597">&#x27ad;</a></h3>
+<div class="extra" id="Element.lighter-extra"></div></div><div class="dr-method"><p>Makes the context element lighter by increasing the brightness and reducing the saturation by a given factor. Can be called on Sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">times</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">adjustment factor [default: <code>2</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">Element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">20</span>).attr({
+    fill: <i>"#ff0000"</i>,
+    stroke: <i>"#fff"</i>,
+    <i>"stroke-width"</i>: <span class="d">2</span>
+}).lighter(<span class="d">6</span>);
+</code></pre>
+</div><div class="Element-popup-section"><h3 id="Element.popup" class="dr-method"><i class="dr-trixie"> </i>Element.popup(dir, size, x, y)<a href="#Element.popup" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 24 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L24">&#x27ad;</a></h3>
+<div class="extra" id="Element.popup-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'popup' tooltip. Can also be used on sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">dir</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">location of Element relative to the tail: <code>'down'</code>, <code>'left'</code>, <code>'up'</code> [default], or <code>'right'</code>.</dd>
+<dt class="dr-param">size</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">amount of bevel/padding around the Element, as well as half the width and height of the tail [default: <code>5</code>]</dd>
+<dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the popup's tail [default: Element's <code>x</code> or <code>cx</code>]</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the popup's tail [default: Element's <code>y</code> or <code>cy</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the popup</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">5</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).popup();
+</code></pre>
+</div><div class="Element-resetBrightness-section"><h3 id="Element.resetBrightness" class="dr-method"><i class="dr-trixie"> </i>Element.resetBrightness()<a href="#Element.resetBrightness" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 665 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L665">&#x27ad;</a></h3>
+<div class="extra" id="Element.resetBrightness-extra"></div></div><div class="dr-method"><p>Resets brightness and saturation levels to their original values. See <a href="#Element.lighter" class="dr-link">Element.lighter</a> and <a href="#Element.darker" class="dr-link">Element.darker</a>. Can be called on Sets.
+</p>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">Element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">20</span>).attr({
+    fill: <i>"#ff0000"</i>,
+    stroke: <i>"#fff"</i>,
+    <i>"stroke-width"</i>: <span class="d">2</span>
+}).lighter(<span class="d">6</span>).resetBrightness();
+</code></pre>
+</div><div class="Element-tag-section"><h3 id="Element.tag" class="dr-method"><i class="dr-trixie"> </i>Element.tag(angle, r, x, y)<a href="#Element.tag" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 135 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L135">&#x27ad;</a></h3>
+<div class="extra" id="Element.tag-extra"></div></div><div class="dr-method"><p>Puts the context Element in a 'tag' tooltip. Can also be used on sets.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+<dt class="dr-param">r</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">radius of the loop [default: <code>5</code>]</dd>
+<dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the center of the tag loop [default: Element's <code>x</code> or <code>cx</code>]</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the center of the tag loop [default: Element's <code>x</code> or <code>cx</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">path element of the tag</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.circle(<span class="d">50</span>, <span class="d">50</span>, <span class="d">15</span>).attr({
+    stroke: <i>"#fff"</i>,
+    fill: <i>"<span class="d">0</span>-#c9de96-#8ab66b:<span class="d">44</span>-#<span class="d">398235</span>"</i>
+}).tag(<span class="d">60</span>);
+</code></pre>
+</div><div class="Paper-section"><h2 id="Paper" class="undefined"><i class="dr-trixie"> </i>Paper<a href="#Paper" title="Link to this section" class="dr-hash">&#x2693;</a></h2>
+<div class="extra" id="Paper-extra"></div></div><div class="Paper-blob-section"><h3 id="Paper.blob" class="dr-method"><i class="dr-trixie"> </i>Paper.blob(x, y, text, angle)<a href="#Paper.blob" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 569 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L569">&#x27ad;</a></h3>
+<div class="extra" id="Paper.blob-extra"></div></div><div class="dr-method"><p>Puts the given text into a 'blob' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.blob" class="dr-link">Element.blob</a>
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the blob's tail</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the blob's tail</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the blob</dd>
+<dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the blob path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.blob(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>, <span class="d">60</span>);
+</code></pre>
+</div><div class="Paper-drop-section"><h3 id="Paper.drop" class="dr-method"><i class="dr-trixie"> </i>Paper.drop(x, y, text, angle)<a href="#Paper.drop" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 545 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L545">&#x27ad;</a></h3>
+<div class="extra" id="Paper.drop-extra"></div></div><div class="dr-method"><p>Puts the given text into a 'drop' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.drop" class="dr-link">Element.drop</a>
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the drop's point</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the drop's point</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the drop</dd>
+<dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the drop path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.drop(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>, <span class="d">60</span>);
+</code></pre>
+</div><div class="Paper-flag-section"><h3 id="Paper.flag" class="dr-method"><i class="dr-trixie"> </i>Paper.flag(x, y, text, angle)<a href="#Paper.flag" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 521 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L521">&#x27ad;</a></h3>
+<div class="extra" id="Paper.flag-extra"></div></div><div class="dr-method"><p>Puts the given <code>text</code> into a 'flag' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.flag" class="dr-link">Element.flag</a>
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the flag's point</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the flag's point</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the flag</dd>
+<dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the flag path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.flag(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>, <span class="d">60</span>);
+</code></pre>
+</div><div class="Paper-label-section"><h3 id="Paper.label" class="dr-method"><i class="dr-trixie"> </i>Paper.label(x, y, text)<a href="#Paper.label" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 445 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L445">&#x27ad;</a></h3>
+<div class="extra" id="Paper.label-extra"></div></div><div class="dr-method"><p>Puts the given <code>text</code> into a 'label' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.label" class="dr-link">Element.label</a>
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the center of the label</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the center of the label</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the label</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the label path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.label(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>);
+</code></pre>
+</div><div class="Paper-popup-section"><h3 id="Paper.popup" class="dr-method"><i class="dr-trixie"> </i>Paper.popup(x, y, text, dir, size)<a href="#Paper.popup" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 472 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L472">&#x27ad;</a></h3>
+<div class="extra" id="Paper.popup-extra"></div></div><div class="dr-method"><p>Puts the given <code>text</code> into a 'popup' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.popup" class="dr-link">Element.popup</a>
+</p>
+<p>Note: The <code>dir</code> parameter has changed from g.Raphael 0.4.1 to 0.5. The options <code>0</code>, <code>1</code>, <code>2</code>, and <code>3</code> has been changed to <code>'down'</code>, <code>'left'</code>, <code>'up'</code>, and <code>'right'</code> respectively.
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the popup's tail</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the popup's tail</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the popup</dd>
+<dt class="dr-param">dir</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">location of the text relative to the tail: <code>'down'</code>, <code>'left'</code>, <code>'up'</code> [default], or <code>'right'</code>.</dd>
+<dt class="dr-param">size</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">amount of padding around the Element [default: <code>5</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the popup path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.popup(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>, <i>'down'</i>);
+</code></pre>
+</div><div class="Paper-tag-section"><h3 id="Paper.tag" class="dr-method"><i class="dr-trixie"> </i>Paper.tag(x, y, text, angle, r)<a href="#Paper.tag" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 497 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L497">&#x27ad;</a></h3>
+<div class="extra" id="Paper.tag-extra"></div></div><div class="dr-method"><p>Puts the given text into a 'tag' tooltip. The text is given a default style according to <a href="#g.txtattr" class="dr-link">g.txtattr</a>. See <a href="#Element.tag" class="dr-link">Element.tag</a>
+</p>
+<p class="header">Parameters
+</p>
+<dl class="dr-parameters"><dt class="dr-param">x</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">x coordinate of the center of the tag loop</dd>
+<dt class="dr-param">y</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">y coordinate of the center of the tag loop</dd>
+<dt class="dr-param">text</dt>
+<dd class="dr-type"><em class="dr-type-string">string</em></dd>
+<dd class="dr-description">text to place inside the tag</dd>
+<dt class="dr-param">angle</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">angle of orientation in degrees [default: <code>0</code>]</dd>
+<dt class="dr-param">r</dt>
+<dd class="dr-type"><em class="dr-type-number">number</em></dd>
+<dd class="dr-description">radius of the loop [default: <code>5</code>]</dd>
+</dl>
+<p class="dr-returns"><strong class="dr-title">Returns:</strong> <em class="dr-type-object">object</em> <span class="dr-description">set containing the tag path and the text element</span></p>
+<p class="header">Usage
+</p>
+<pre class="javascript code"><code>paper.tag(<span class="d">50</span>, <span class="d">50</span>, <i>"$<span class="d">9.99</span>"</i>, <span class="d">60</span>);
+</code></pre>
+</div><div class="g-section"><h2 id="g" class="undefined"><i class="dr-trixie"> </i>g<a href="#g" title="Link to this section" class="dr-hash">&#x2693;</a></h2>
+<div class="extra" id="g-extra"></div></div><div class="g-colors-section"><h3 id="g.colors" class="dr-array"><i class="dr-trixie"> </i>g.colors<a href="#g.colors" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 726 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L726">&#x27ad;</a></h3>
+<div class="extra" id="g.colors-extra"></div></div><div class="dr-array"><p>An array of color values that charts will iterate through when drawing chart data values.
+</p>
+</div><div class="g-shim-section"><h3 id="g.shim" class="dr-object"><i class="dr-trixie"> </i>g.shim<a href="#g.shim" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 706 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L706">&#x27ad;</a></h3>
+<div class="extra" id="g.shim-extra"></div></div><div class="dr-object"><p>An attribute object that charts will set on all generated shims (shims being the invisible objects that mouse events are bound to)
+</p>
+<p class="header">Default value
+</p>
+<pre class="javascript code"><code>{ stroke: <i>'none'</i>, fill: <i>'#<span class="d">000</span>'</i>, <i>'fill-opacity'</i>: <span class="d">0</span> }
+</code></pre>
+</div><div class="g-txtattr-section"><h3 id="g.txtattr" class="dr-object"><i class="dr-trixie"> </i>g.txtattr<a href="#g.txtattr" title="Link to this section" class="dr-hash">&#x2693;</a><a class="dr-sourceline" title="Go to line 717 in the source" href="https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js#L717">&#x27ad;</a></h3>
+<div class="extra" id="g.txtattr-extra"></div></div><div class="dr-object"><p>An attribute object that charts and tooltips will set on any generated text
+</p>
+<p class="header">Default value
+</p>
+<pre class="javascript code"><code>{ font: <i>'12px Arial, sans-serif'</i>, fill: <i>'#fff'</i> }
+</code></pre>
+</div></div></div>
+<script src="../raphael-min.js"></script>
+<script src="../g.raphael.js"></script>
+<script src="reference.js"></script>
+</body></html>
\ No newline at end of file
diff --git a/docs/reference.js b/docs/reference.js
new file mode 100644
index 0000000..6280f4e
--- /dev/null
+++ b/docs/reference.js
@@ -0,0 +1,35 @@
+Raphael(function () {
+    var grad = {
+            stroke: "#fff",
+            fill: "0-#c9de96-#8ab66b:44-#398235"
+        },
+        fill = {
+            stroke: "#fff",
+            fill: "#ff0000",
+            "stroke-width": 2
+        };
+
+    function prepare(id) {
+        var div = document.getElementById(id);
+        div.style.cssText = "display:block;float:right;padding:10px;width:99px;height:99px;background:#2C53B0 url(./blueprint-min.png) no-repeat";
+        return Raphael(div, 99, 99);
+    }
+    
+    prepare("Element.popup-extra").circle(50, 50, 5).attr(grad).popup();
+    prepare("Element.tag-extra").circle(50, 50, 15).attr(grad).tag(60);
+    prepare("Element.drop-extra").circle(50, 50, 8).attr(grad).drop(60);
+    prepare("Element.flag-extra").circle(50, 50, 10).attr(grad).flag(60);
+    prepare("Element.label-extra").circle(50, 50, 10).attr(grad).label();
+    prepare("Element.blob-extra").circle(50, 50, 8).attr(grad).blob(60);
+
+    prepare("Paper.popup-extra").popup(50, 50, "Hello", 'down');
+    prepare("Paper.tag-extra").tag(50, 50, "$9.99", 60);
+    prepare("Paper.drop-extra").drop(50, 50, "$10", 60);
+    prepare("Paper.flag-extra").flag(50, 50, "$9.99", 60);
+    prepare("Paper.label-extra").label(50, 50, "$9.99");
+    prepare("Paper.blob-extra").blob(50, 50, "Hello", 60);
+
+    prepare("Element.lighter-extra").circle(50, 50, 20).attr(fill).lighter(6);
+    prepare("Element.darker-extra").circle(50, 50, 20).attr(fill).darker(6);
+    prepare("Element.resetBrightness-extra").circle(50, 50, 20).attr(fill).lighter(6).resetBrightness();
+});
diff --git a/g.bar.js b/g.bar.js
new file mode 100644
index 0000000..b0834b7
--- /dev/null
+++ b/g.bar.js
@@ -0,0 +1,621 @@
+/*!
+ * g.Raphael 0.5 - 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 mmin = Math.min,
+        mmax = Math.max;
+
+    function finger(x, y, width, height, dir, ending, isPath, paper) {
+        var path,
+            ends = { round: 'round', sharp: 'sharp', soft: 'soft', square: 'square' };
+
+        // dir 0 for horizontal and 1 for vertical
+        if ((dir && !height) || (!dir && !width)) {
+            return isPath ? "" : paper.path();
+        }
+
+        ending = ends[ending] || "square";
+        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 paper.path(path);
+        }
+    }
+
+    /*
+     * Vertical Barchart
+     */
+    function VBarchart(paper, x, y, width, height, values, opts) {
+        opts = opts || {};
+
+        var chartinst = this,
+            type = opts.type || "square",
+            gutter = parseFloat(opts.gutter || "20%"),
+            chart = paper.set(),
+            bars = paper.set(),
+            covers = paper.set(),
+            covers2 = paper.set(),
+            total = Math.max.apply(Math, values),
+            stacktotal = [],
+            multi = 0,
+            colors = opts.colors || chartinst.colors,
+            len = values.length;
+
+        if (Raphael.is(values[0], "array")) {
+            total = [];
+            multi = len;
+            len = 0;
+
+            for (var i = values.length; i--;) {
+                bars.push(paper.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 = finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type, null, paper).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 = paper.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(chartinst.shim));
+                cvr.bars = paper.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 = finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1, paper);
+
+                    cvr.bars.push(bar);
+                    size && bar.attr({path: path});
+                    bar.h = h;
+                    bar.y = y + height - barvgutter - !!size * .5 - h;
+                    covers.push(cover = paper.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(chartinst.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 = paper.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(chartinst.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.labelise(labels[i], tot, total);
+
+                            L = paper.text(bars[i * (multi || 1) + j].x, y + height - barvgutter / 2, label).attr(txtattr).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.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);
+
+                        L = paper.text(bars[i * (multi || 1) + j].x, isBottom ? y + height - barvgutter / 2 : bars[i * (multi || 1) + j].y - 10, label).attr(txtattr).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;
+    };
+
+    /**
+     * Horizontal Barchart
+     */
+    function HBarchart(paper, x, y, width, height, values, opts) {
+        opts = opts || {};
+
+        var chartinst = this,
+            type = opts.type || "square",
+            gutter = parseFloat(opts.gutter || "20%"),
+            chart = paper.set(),
+            bars = paper.set(),
+            covers = paper.set(),
+            covers2 = paper.set(),
+            total = Math.max.apply(Math, values),
+            stacktotal = [],
+            multi = 0,
+            colors = opts.colors || chartinst.colors,
+            len = values.length;
+
+        if (Raphael.is(values[0], "array")) {
+            total = [];
+            multi = len;
+            len = 0;
+
+            for (var i = values.length; i--;) {
+                bars.push(paper.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 = finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type, null, paper).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 = paper.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(chartinst.shim);
+
+                covers2.push(cvr);
+                cvr.bars = paper.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 = finger(x, bar.y, val, barheight - 1, false, type, 1, paper);
+
+                    cvr.bars.push(bar);
+                    size && bar.attr({ path: path });
+                    bar.w = val;
+                    bar.x = x + val;
+                    covers.push(cover = paper.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(chartinst.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 = paper.rect(x, Y, width, barheight).attr(chartinst.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.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total),
+                        X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5,
+                        A = isRight ? "end" : "start",
+                        L;
+
+                    this.labels.push(L = paper.text(X, bars[i * (multi || 1) + j].y, label).attr(txtattr).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;
+    };
+    
+    //inheritance
+    var F = function() {};
+    F.prototype = Raphael.g;
+    HBarchart.prototype = VBarchart.prototype = new F;
+    
+    Raphael.fn.hbarchart = function(x, y, width, height, values, opts) {
+        return new HBarchart(this, x, y, width, height, values, opts);
+    };
+    
+    Raphael.fn.barchart = function(x, y, width, height, values, opts) {
+        return new VBarchart(this, x, y, width, height, values, opts);
+    };
+})();
diff --git a/g.dot.js b/g.dot.js
new file mode 100644
index 0000000..17f4c96
--- /dev/null
+++ b/g.dot.js
@@ -0,0 +1,156 @@
+/*!
+ * g.Raphael 0.5 - 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 colorValue = function (value, total, s, b) {
+            return 'hsb(' + [Math.min((1 - value / total) * .4, 1), s || .75, b || .75] + ')';
+        };
+
+    function Dotchart(paper, x, y, width, height, valuesx, valuesy, size, opts) {
+        
+        var chartinst = this;
+        
+        function drawAxis(ax) {
+            +ax[0] && (ax[0] = chartinst.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", null, paper));
+            +ax[1] && (ax[1] = chartinst.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", null, paper));
+            +ax[2] && (ax[2] = chartinst.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", null, paper));
+            +ax[3] && (ax[3] = chartinst.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", null, paper));
+        }
+
+        opts = opts || {};
+        var xdim = chartinst.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 = chartinst.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 = paper[opts.symbol] || "circle",
+            res = paper.set(),
+            series = paper.set(),
+            max = opts.max || 100,
+            top = Math.max.apply(Math, size),
+            R = [],
+            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 = paper.set(),
+            maxR = Math.max.apply(Math, R);
+
+        if (opts.axis) {
+            var ax = (opts.axis + "").split(/[,\s]+/);
+
+            drawAxis.call(chartinst, 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.call(chartinst, 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 = paper.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(paper[sym](X, Y, R[i]).attr({ fill: opts.heat ? colorValue(R[i], maxR) : chartinst.colors[0], "fill-opacity": opts.opacity ? R[i] / max : 1, stroke: "none" }));
+        }
+
+        var covers = paper.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(paper.circle(X, Y, maxR).attr(chartinst.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 (!paper.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;
+    };
+    
+    //inheritance
+    var F = function() {};
+    F.prototype = Raphael.g
+    Dotchart.prototype = new F;
+    
+    //public
+    Raphael.fn.dotchart = function(x, y, width, height, valuesx, valuesy, size, opts) {
+        return new Dotchart(this, x, y, width, height, valuesx, valuesy, size, opts);
+    }
+})();
diff --git a/g.line.js b/g.line.js
new file mode 100644
index 0000000..1d0c255
--- /dev/null
+++ b/g.line.js
@@ -0,0 +1,329 @@
+/*!
+ * g.Raphael 0.5 - 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 () {
+
+    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
+        };
+    }
+
+    function Linechart(paper, x, y, width, height, valuesx, valuesy, opts) {
+        
+        var chartinst = this;
+        
+        opts = opts || {};
+
+        if (!paper.raphael.is(valuesx[0], "array")) {
+            valuesx = [valuesx];
+        }
+
+        if (!paper.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 || chartinst.colors,
+            columns = null,
+            dots = null,
+            chart = paper.set(),
+            path = [];
+
+        for (var i = 0, ii = valuesy.length; i < ii; i++) {
+            len = Math.max(len, valuesy[i].length);
+        }
+
+        var shades = paper.set();
+
+        for (i = 0, ii = valuesy.length; i < ii; i++) {
+            if (opts.shade) {
+                shades.push(paper.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 = chartinst.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1),
+            minx = xdim.from,
+            maxx = xdim.to,
+            ydim = chartinst.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 = paper.set();
+
+        if (opts.axis) {
+            var ax = (opts.axis + "").split(/[,\s]+/);
+            +ax[0] && axis.push(chartinst.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, paper));
+            +ax[1] && axis.push(chartinst.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, paper));
+            +ax[2] && axis.push(chartinst.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, paper));
+            +ax[3] && axis.push(chartinst.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, paper));
+        }
+
+        var lines = paper.set(),
+            symbols = paper.set(),
+            line;
+
+        for (i = 0, ii = valuesy.length; i < ii; i++) {
+            if (!opts.nostroke) {
+                lines.push(line = paper.path().attr({
+                    stroke: colors[i],
+                    "stroke-width": opts.width || 2,
+                    "stroke-linejoin": "round",
+                    "stroke-linecap": "round",
+                    "stroke-dasharray": opts.dash || ""
+                }));
+            }
+
+            var sym = Raphael.is(symbol, "array") ? symbol[i] : symbol,
+                symset = paper.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(paper[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,
+                            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 || paper.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 = paper.rect(X - 1, y, Math.max(w + 1, 1), height).attr({ stroke: "none", fill: "#000", opacity: 0 }));
+                C.values = [];
+                C.symbols = paper.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 || paper.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 = paper.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 = paper.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;
+    };
+    
+    //inheritance
+    var F = function() {};
+    F.prototype = Raphael.g;
+    Linechart.prototype = new F;
+    
+    //public
+    Raphael.fn.linechart = function(x, y, width, height, valuesx, valuesy, opts) {
+        return new Linechart(this, x, y, width, height, valuesx, valuesy, opts);
+    }
+    
+})();
diff --git a/g.pie.js b/g.pie.js
new file mode 100644
index 0000000..df2afb3
--- /dev/null
+++ b/g.pie.js
@@ -0,0 +1,255 @@
+/*
+ * g.Raphael 0.5 - 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 () {
+
+    function Piechart(paper, cx, cy, r, values, opts) {
+        opts = opts || {};
+
+        var chartinst = this,
+            sectors = [],
+            covers = paper.set(),
+            chart = paper.set(),
+            series = paper.set(),
+            order = [],
+            len = values.length,
+            angle = 0,
+            total = 0,
+            others = 0,
+            cut = 9,
+            defcut = true;
+
+        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;
+        }
+
+        chart.covers = covers;
+
+        if (len == 1) {
+            series.push(paper.circle(cx, cy, r).attr({ fill: chartinst.colors[0], stroke: opts.stroke || "#fff", "stroke-width": opts.strokewidth == null ? 1 : opts.strokewidth }));
+            covers.push(paper.circle(cx, cy, r).attr(chartinst.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 {
+            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 = paper.path(opts.init ? ipath : path).attr({ fill: opts.colors && opts.colors[i] || chartinst.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(chartinst.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[mark && mark.toLowerCase()] || "circle";
+            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] = chartinst.labelise(labels[j], values[i], total);
+                chart.labels.push(paper.set());
+                chart.labels[i].push(paper[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(chartinst.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;
+    };
+    
+    //inheritance
+    var F = function() {};
+    F.prototype = Raphael.g;
+    Piechart.prototype = new F;
+    
+    //public
+    Raphael.fn.piechart = function(cx, cy, r, values, opts) {
+        return new Piechart(this, cx, cy, r, values, opts);
+    }
+    
+})();
diff --git a/g.raphael.js b/g.raphael.js
new file mode 100644
index 0000000..f49ffb5
--- /dev/null
+++ b/g.raphael.js
@@ -0,0 +1,887 @@
+/*!
+ * g.Raphael 0.5 - 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.
+ */
+
+/*
+ * Tooltips on Element prototype
+ */
+/*\
+ * Element.popup
+ [ method ]
+ **
+ * Puts the context Element in a 'popup' tooltip. Can also be used on sets.
+ **
+ > Parameters
+ **
+ - dir (string) location of Element relative to the tail: `'down'`, `'left'`, `'up'` [default], or `'right'`.
+ - size (number) amount of bevel/padding around the Element, as well as half the width and height of the tail [default: `5`]
+ - x (number) x coordinate of the popup's tail [default: Element's `x` or `cx`]
+ - y (number) y coordinate of the popup's tail [default: Element's `y` or `cy`]
+ **
+ = (object) path element of the popup
+ > Usage
+ | paper.circle(50, 50, 5).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).popup();
+ \*/
+Raphael.el.popup = function (dir, size, x, y) {
+    var paper = this.paper || this[0].paper,
+        bb, xy, center, cw, ch;
+
+    if (!paper) return;
+
+    switch (this.type) {
+        case 'text':
+        case 'circle':
+        case 'ellipse': center = true; break;
+        default: center = false;
+    }
+
+    dir = dir == null ? 'up' : dir;
+    size = size || 5;
+    bb = this.getBBox();
+
+    x = typeof x == 'number' ? x : (center ? bb.x + bb.width / 2 : bb.x);
+    y = typeof y == 'number' ? y : (center ? bb.y + bb.height / 2 : bb.y);
+    cw = Math.max(bb.width / 2 - size, 0);
+    ch = Math.max(bb.height / 2 - size, 0);
+
+    this.translate(x - bb.x - (center ? bb.width / 2 : 0), y - bb.y - (center ? bb.height / 2 : 0));
+    bb = this.getBBox();
+
+    var paths = {
+        up: [
+            'M', x, y,
+            'l', -size, -size, -cw, 0,
+            'a', size, size, 0, 0, 1, -size, -size,
+            'l', 0, -bb.height,
+            'a', size, size, 0, 0, 1, size, -size,
+            'l', size * 2 + cw * 2, 0,
+            'a', size, size, 0, 0, 1, size, size,
+            'l', 0, bb.height,
+            'a', size, size, 0, 0, 1, -size, size,
+            'l', -cw, 0,
+            'z'
+        ].join(','),
+        down: [
+            'M', x, y,
+            'l', size, size, cw, 0,
+            'a', size, size, 0, 0, 1, size, size,
+            'l', 0, bb.height,
+            'a', size, size, 0, 0, 1, -size, size,
+            'l', -(size * 2 + cw * 2), 0,
+            'a', size, size, 0, 0, 1, -size, -size,
+            'l', 0, -bb.height,
+            'a', size, size, 0, 0, 1, size, -size,
+            'l', cw, 0,
+            'z'
+        ].join(','),
+        left: [
+            'M', x, y,
+            'l', -size, size, 0, ch,
+            'a', size, size, 0, 0, 1, -size, size,
+            'l', -bb.width, 0,
+            'a', size, size, 0, 0, 1, -size, -size,
+            'l', 0, -(size * 2 + ch * 2),
+            'a', size, size, 0, 0, 1, size, -size,
+            'l', bb.width, 0,
+            'a', size, size, 0, 0, 1, size, size,
+            'l', 0, ch,
+            'z'
+        ].join(','),
+        right: [
+            'M', x, y,
+            'l', size, -size, 0, -ch,
+            'a', size, size, 0, 0, 1, size, -size,
+            'l', bb.width, 0,
+            'a', size, size, 0, 0, 1, size, size,
+            'l', 0, size * 2 + ch * 2,
+            'a', size, size, 0, 0, 1, -size, size,
+            'l', -bb.width, 0,
+            'a', size, size, 0, 0, 1, -size, -size,
+            'l', 0, -ch,
+            'z'
+        ].join(',')
+    };
+
+    xy = {
+        up: { x: -!center * (bb.width / 2), y: -size * 2 - (center ? bb.height / 2 : bb.height) },
+        down: { x: -!center * (bb.width / 2), y: size * 2 + (center ? bb.height / 2 : bb.height) },
+        left: { x: -size * 2 - (center ? bb.width / 2 : bb.width), y: -!center * (bb.height / 2) },
+        right: { x: size * 2 + (center ? bb.width / 2 : bb.width), y: -!center * (bb.height / 2) }
+    }[dir];
+
+    this.translate(xy.x, xy.y);
+    return paper.path(paths[dir]).attr({ fill: "#000", stroke: "none" }).insertBefore(this.node ? this : this[0]);
+};
+
+/*\
+ * Element.tag
+ [ method ]
+ **
+ * Puts the context Element in a 'tag' tooltip. Can also be used on sets.
+ **
+ > Parameters
+ **
+ - angle (number) angle of orientation in degrees [default: `0`]
+ - r (number) radius of the loop [default: `5`]
+ - x (number) x coordinate of the center of the tag loop [default: Element's `x` or `cx`]
+ - y (number) y coordinate of the center of the tag loop [default: Element's `x` or `cx`]
+ **
+ = (object) path element of the tag
+ > Usage
+ | paper.circle(50, 50, 15).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).tag(60);
+ \*/
+Raphael.el.tag = function (angle, r, x, y) {
+    var d = 3,
+        paper = this.paper || this[0].paper;
+
+    if (!paper) return;
+
+    var p = paper.path().attr({ fill: '#000', stroke: '#000' }),
+        bb = this.getBBox(),
+        dx, R, center, tmp;
+
+    switch (this.type) {
+        case 'text':
+        case 'circle':
+        case 'ellipse': center = true; break;
+        default: center = false;
+    }
+
+    angle = angle || 0;
+    x = typeof x == 'number' ? x : (center ? bb.x + bb.width / 2 : bb.x);
+    y = typeof y == 'number' ? y : (center ? bb.y + bb.height / 2 : bb.y);
+    r = r == null ? 5 : r;
+    R = .5522 * r;
+
+    if (bb.height >= r * 2) {
+        p.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 {
+        dx = Math.sqrt(Math.pow(r + d, 2) - Math.pow(bb.height / 2 + d, 2));
+        p.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(",")
+        });
+    }
+
+    angle = 360 - angle;
+    p.rotate(angle, x, y);
+
+    if (this.attrs) {
+        //elements
+        this.attr(this.attrs.x ? 'x' : 'cx', x + r + d + (!center ? this.type == 'text' ? bb.width : 0 : bb.width / 2)).attr('y', center ? y : y - bb.height / 2);
+        this.rotate(angle, x, y);
+        angle > 90 && angle < 270 && this.attr(this.attrs.x ? 'x' : 'cx', x - r - d - (!center ? bb.width : bb.width / 2)).rotate(180, x, y);
+    } else {
+        //sets
+        if (angle > 90 && angle < 270) {
+            this.translate(x - bb.x - bb.width - r - d, y - bb.y - bb.height / 2);
+            this.rotate(angle - 180, bb.x + bb.width + r + d, bb.y + bb.height / 2);
+        } else {
+            this.translate(x - bb.x + r + d, y - bb.y - bb.height / 2);
+            this.rotate(angle, bb.x - r - d, bb.y + bb.height / 2); 
+        }
+    }
+
+    return p.insertBefore(this.node ? this : this[0]);
+};
+
+/*\
+ * Element.drop
+ [ method ]
+ **
+ * Puts the context Element in a 'drop' tooltip. Can also be used on sets.
+ **
+ > Parameters
+ **
+ - angle (number) angle of orientation in degrees [default: `0`]
+ - x (number) x coordinate of the drop's point [default: Element's `x` or `cx`]
+ - y (number) y coordinate of the drop's point [default: Element's `x` or `cx`]
+ **
+ = (object) path element of the drop
+ > Usage
+ | paper.circle(50, 50, 8).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).drop(60);
+ \*/
+Raphael.el.drop = function (angle, x, y) {
+    var bb = this.getBBox(),
+        paper = this.paper || this[0].paper,
+        center, size, p, dx, dy;
+
+    if (!paper) return;
+
+    switch (this.type) {
+        case 'text':
+        case 'circle':
+        case 'ellipse': center = true; break;
+        default: center = false;
+    }
+
+    angle = angle || 0;
+
+    x = typeof x == 'number' ? x : (center ? bb.x + bb.width / 2 : bb.x);
+    y = typeof y == 'number' ? y : (center ? bb.y + bb.height / 2 : bb.y);
+    size = Math.max(bb.width, bb.height) + Math.min(bb.width, bb.height);
+    p = paper.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"}).rotate(22.5 - angle, x, y);
+
+    angle = (angle + 90) * Math.PI / 180;
+    dx = (x + size * Math.sin(angle)) - (center ? 0 : bb.width / 2);
+    dy = (y + size * Math.cos(angle)) - (center ? 0 : bb.height / 2);
+
+    this.attrs ?
+        this.attr(this.attrs.x ? 'x' : 'cx', dx).attr(this.attrs.y ? 'y' : 'cy', dy) :
+        this.translate(dx - bb.x, dy - bb.y);
+
+    return p.insertBefore(this.node ? this : this[0]);
+};
+
+/*\
+ * Element.flag
+ [ method ]
+ **
+ * Puts the context Element in a 'flag' tooltip. Can also be used on sets.
+ **
+ > Parameters
+ **
+ - angle (number) angle of orientation in degrees [default: `0`]
+ - x (number) x coordinate of the flag's point [default: Element's `x` or `cx`]
+ - y (number) y coordinate of the flag's point [default: Element's `x` or `cx`]
+ **
+ = (object) path element of the flag
+ > Usage
+ | paper.circle(50, 50, 10).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).flag(60);
+ \*/
+Raphael.el.flag = function (angle, x, y) {
+    var d = 3,
+        paper = this.paper || this[0].paper;
+
+    if (!paper) return;
+
+    var p = paper.path().attr({ fill: '#000', stroke: '#000' }),
+        bb = this.getBBox(),
+        h = bb.height / 2,
+        center;
+
+    switch (this.type) {
+        case 'text':
+        case 'circle':
+        case 'ellipse': center = true; break;
+        default: center = false;
+    }
+
+    angle = angle || 0;
+    x = typeof x == 'number' ? x : (center ? bb.x + bb.width / 2 : bb.x);
+    y = typeof y == 'number' ? y : (center ? bb.y + bb.height / 2: bb.y);
+
+    p.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(",")
+    });
+
+    angle = 360 - angle;
+    p.rotate(angle, x, y);
+
+    if (this.attrs) {
+        //elements
+        this.attr(this.attrs.x ? 'x' : 'cx', x + h + d + (!center ? this.type == 'text' ? bb.width : 0 : bb.width / 2)).attr('y', center ? y : y - bb.height / 2);
+        this.rotate(angle, x, y);
+        angle > 90 && angle < 270 && this.attr(this.attrs.x ? 'x' : 'cx', x - h - d - (!center ? bb.width : bb.width / 2)).rotate(180, x, y);
+    } else {
+        //sets
+        if (angle > 90 && angle < 270) {
+            this.translate(x - bb.x - bb.width - h - d, y - bb.y - bb.height / 2);
+            this.rotate(angle - 180, bb.x + bb.width + h + d, bb.y + bb.height / 2);
+        } else {
+            this.translate(x - bb.x + h + d, y - bb.y - bb.height / 2);
+            this.rotate(angle, bb.x - h - d, bb.y + bb.height / 2);
+        }
+    }
+
+    return p.insertBefore(this.node ? this : this[0]);
+};
+
+/*\
+ * Element.label
+ [ method ]
+ **
+ * Puts the context Element in a 'label' tooltip. Can also be used on sets.
+ **
+ = (object) path element of the label.
+ > Usage
+ | paper.circle(50, 50, 10).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).label();
+ \*/
+Raphael.el.label = function () {
+    var bb = this.getBBox(),
+        paper = this.paper || this[0].paper,
+        r = Math.min(20, bb.width + 10, bb.height + 10) / 2;
+
+    if (!paper) return;
+
+    return paper.rect(bb.x - r / 2, bb.y - r / 2, bb.width + r, bb.height + r, r).attr({ stroke: 'none', fill: '#000' }).insertBefore(this.node ? this : this[0]);
+};
+
+/*\
+ * Element.blob
+ [ method ]
+ **
+ * Puts the context Element in a 'blob' tooltip. Can also be used on sets.
+ **
+ > Parameters
+ **
+ - angle (number) angle of orientation in degrees [default: `0`]
+ - x (number) x coordinate of the blob's tail [default: Element's `x` or `cx`]
+ - y (number) y coordinate of the blob's tail [default: Element's `x` or `cx`]
+ **
+ = (object) path element of the blob
+ > Usage
+ | paper.circle(50, 50, 8).attr({
+ |     stroke: "#fff",
+ |     fill: "0-#c9de96-#8ab66b:44-#398235"
+ | }).blob(60);
+ \*/
+Raphael.el.blob = function (angle, x, y) {
+    var bb = this.getBBox(),
+        rad = Math.PI / 180,
+        paper = this.paper || this[0].paper,
+        p, center, size;
+
+    if (!paper) return;
+
+    switch (this.type) {
+        case 'text':
+        case 'circle':
+        case 'ellipse': center = true; break;
+        default: center = false;
+    }
+
+    p = paper.path().attr({ fill: "#000", stroke: "none" });
+    angle = (+angle + 1 ? angle : 45) + 90;
+    size = Math.min(bb.height, bb.width);
+    x = typeof x == 'number' ? x : (center ? bb.x + bb.width / 2 : bb.x);
+    y = typeof y == 'number' ? y : (center ? bb.y + bb.height / 2 : bb.y);
+
+    var w = Math.max(bb.width + size, size * 25 / 12),
+        h = Math.max(bb.height + size, 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;
+
+    p.attr({
+        x: cx,
+        y: cy,
+        path: [
+            "M", x, y,
+            "L", x1, y1,
+            "A", rx, ry, 0, 1, 1, x2, y2,
+            "z"
+        ].join(",")
+    });
+
+    this.translate(cx - bb.x - bb.width / 2, cy - bb.y - bb.height / 2);
+
+    return p.insertBefore(this.node ? this : this[0]);
+};
+
+/*
+ * Tooltips on Paper prototype
+ */
+/*\
+ * Paper.label
+ [ method ]
+ **
+ * Puts the given `text` into a 'label' tooltip. The text is given a default style according to @g.txtattr. See @Element.label
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the center of the label
+ - y (number) y coordinate of the center of the label
+ - text (string) text to place inside the label
+ **
+ = (object) set containing the label path and the text element
+ > Usage
+ | paper.label(50, 50, "$9.99");
+ \*/
+Raphael.fn.label = function (x, y, text) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.label(), text);
+};
+
+/*\
+ * Paper.popup
+ [ method ]
+ **
+ * Puts the given `text` into a 'popup' tooltip. The text is given a default style according to @g.txtattr. See @Element.popup
+ *
+ * Note: The `dir` parameter has changed from g.Raphael 0.4.1 to 0.5. The options `0`, `1`, `2`, and `3` has been changed to `'down'`, `'left'`, `'up'`, and `'right'` respectively.
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the popup's tail
+ - y (number) y coordinate of the popup's tail
+ - text (string) text to place inside the popup
+ - dir (string) location of the text relative to the tail: `'down'`, `'left'`, `'up'` [default], or `'right'`.
+ - size (number) amount of padding around the Element [default: `5`]
+ **
+ = (object) set containing the popup path and the text element
+ > Usage
+ | paper.popup(50, 50, "$9.99", 'down');
+ \*/
+Raphael.fn.popup = function (x, y, text, dir, size) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.popup(dir, size), text);
+};
+
+/*\
+ * Paper.tag
+ [ method ]
+ **
+ * Puts the given text into a 'tag' tooltip. The text is given a default style according to @g.txtattr. See @Element.tag
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the center of the tag loop
+ - y (number) y coordinate of the center of the tag loop
+ - text (string) text to place inside the tag
+ - angle (number) angle of orientation in degrees [default: `0`]
+ - r (number) radius of the loop [default: `5`]
+ **
+ = (object) set containing the tag path and the text element
+ > Usage
+ | paper.tag(50, 50, "$9.99", 60);
+ \*/
+Raphael.fn.tag = function (x, y, text, angle, r) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.tag(angle, r), text);
+};
+
+/*\
+ * Paper.flag
+ [ method ]
+ **
+ * Puts the given `text` into a 'flag' tooltip. The text is given a default style according to @g.txtattr. See @Element.flag
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the flag's point
+ - y (number) y coordinate of the flag's point
+ - text (string) text to place inside the flag
+ - angle (number) angle of orientation in degrees [default: `0`]
+ **
+ = (object) set containing the flag path and the text element
+ > Usage
+ | paper.flag(50, 50, "$9.99", 60);
+ \*/
+Raphael.fn.flag = function (x, y, text, angle) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.flag(angle), text);
+};
+
+/*\
+ * Paper.drop
+ [ method ]
+ **
+ * Puts the given text into a 'drop' tooltip. The text is given a default style according to @g.txtattr. See @Element.drop
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the drop's point
+ - y (number) y coordinate of the drop's point
+ - text (string) text to place inside the drop
+ - angle (number) angle of orientation in degrees [default: `0`]
+ **
+ = (object) set containing the drop path and the text element
+ > Usage
+ | paper.drop(50, 50, "$9.99", 60);
+ \*/
+Raphael.fn.drop = function (x, y, text, angle) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.drop(angle), text);
+};
+
+/*\
+ * Paper.blob
+ [ method ]
+ **
+ * Puts the given text into a 'blob' tooltip. The text is given a default style according to @g.txtattr. See @Element.blob
+ **
+ > Parameters
+ **
+ - x (number) x coordinate of the blob's tail
+ - y (number) y coordinate of the blob's tail
+ - text (string) text to place inside the blob
+ - angle (number) angle of orientation in degrees [default: `0`]
+ **
+ = (object) set containing the blob path and the text element
+ > Usage
+ | paper.blob(50, 50, "$9.99", 60);
+ \*/
+Raphael.fn.blob = function (x, y, text, angle) {
+    var set = this.set();
+
+    text = this.text(x, y, text).attr(Raphael.g.txtattr);
+    return set.push(text.blob(angle), text);
+};
+
+/**
+ * Brightness functions on the Element prototype
+ */
+/*\
+ * Element.lighter
+ [ method ]
+ **
+ * Makes the context element lighter by increasing the brightness and reducing the saturation by a given factor. Can be called on Sets.
+ **
+ > Parameters
+ **
+ - times (number) adjustment factor [default: `2`]
+ **
+ = (object) Element
+ > Usage
+ | paper.circle(50, 50, 20).attr({
+ |     fill: "#ff0000",
+ |     stroke: "#fff",
+ |     "stroke-width": 2
+ | }).lighter(6);
+ \*/
+Raphael.el.lighter = function (times) {
+    times = times || 2;
+
+    var fs = [this.attrs.fill, this.attrs.stroke];
+
+    this.fs = this.fs || [fs[0], fs[1]];
+
+    fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);
+    fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);
+    fs[0].b = Math.min(fs[0].b * times, 1);
+    fs[0].s = fs[0].s / times;
+    fs[1].b = Math.min(fs[1].b * times, 1);
+    fs[1].s = fs[1].s / times;
+
+    this.attr({fill: "hsb(" + [fs[0].h, fs[0].s, fs[0].b] + ")", stroke: "hsb(" + [fs[1].h, fs[1].s, fs[1].b] + ")"});
+    return this;
+};
+
+/*\
+ * Element.darker
+ [ method ]
+ **
+ * Makes the context element darker by decreasing the brightness and increasing the saturation by a given factor. Can be called on Sets.
+ **
+ > Parameters
+ **
+ - times (number) adjustment factor [default: `2`]
+ **
+ = (object) Element
+ > Usage
+ | paper.circle(50, 50, 20).attr({
+ |     fill: "#ff0000",
+ |     stroke: "#fff",
+ |     "stroke-width": 2
+ | }).darker(6);
+ \*/
+Raphael.el.darker = function (times) {
+    times = times || 2;
+
+    var fs = [this.attrs.fill, this.attrs.stroke];
+
+    this.fs = this.fs || [fs[0], fs[1]];
+
+    fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);
+    fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);
+    fs[0].s = Math.min(fs[0].s * times, 1);
+    fs[0].b = fs[0].b / times;
+    fs[1].s = Math.min(fs[1].s * times, 1);
+    fs[1].b = fs[1].b / times;
+
+    this.attr({fill: "hsb(" + [fs[0].h, fs[0].s, fs[0].b] + ")", stroke: "hsb(" + [fs[1].h, fs[1].s, fs[1].b] + ")"});
+    return this;
+};
+
+/*\
+ * Element.resetBrightness
+ [ method ]
+ **
+ * Resets brightness and saturation levels to their original values. See @Element.lighter and @Element.darker. Can be called on Sets.
+ **
+ = (object) Element
+ > Usage
+ | paper.circle(50, 50, 20).attr({
+ |     fill: "#ff0000",
+ |     stroke: "#fff",
+ |     "stroke-width": 2
+ | }).lighter(6).resetBrightness();
+ \*/
+Raphael.el.resetBrightness = function () {
+    if (this.fs) {
+        this.attr({ fill: this.fs[0], stroke: this.fs[1] });
+        delete this.fs;
+    }
+    return this;
+};
+
+//alias to set prototype
+(function () {
+    var brightness = ['lighter', 'darker', 'resetBrightness'],
+        tooltips = ['popup', 'tag', 'flag', 'label', 'drop', 'blob'];
+
+    for (var f in tooltips) (function (name) {
+        Raphael.st[name] = function () {
+            return Raphael.el[name].apply(this, arguments);
+        };
+    })(tooltips[f]);
+
+    for (var f in brightness) (function (name) {
+        Raphael.st[name] = function () {
+            for (var i = 0; i < this.length; i++) {
+                this[i][name].apply(this[i], arguments);
+            }
+
+            return this;
+        };
+    })(brightness[f]);
+})();
+
+//chart prototype for storing common functions
+Raphael.g = {
+    /*\
+     * g.shim
+     [ object ]
+     **
+     * An attribute object that charts will set on all generated shims (shims being the invisible objects that mouse events are bound to)
+     **
+     > Default value
+     | { stroke: 'none', fill: '#000', 'fill-opacity': 0 }
+     \*/
+    shim: { stroke: 'none', fill: '#000', 'fill-opacity': 0 },
+
+    /*\
+     * g.txtattr
+     [ object ]
+     **
+     * An attribute object that charts and tooltips will set on any generated text
+     **
+     > Default value
+     | { font: '12px Arial, sans-serif', fill: '#fff' }
+     \*/  
+    txtattr: { font: '12px Arial, sans-serif', fill: '#fff' },
+
+    /*\
+     * g.colors
+     [ array ]
+     **
+     * An array of color values that charts will iterate through when drawing chart data values.
+     **
+     \*/
+    colors: (function () {
+            var hues = [.6, .2, .05, .1333, .75, 0],
+                colors = [];
+
+            for (var i = 0; i < 10; i++) {
+                if (i < hues.length) {
+                    colors.push('hsb(' + hues[i] + ',.75, .75)');
+                } else {
+                    colors.push('hsb(' + hues[i - hues.length] + ', 1, .5)');
+                }
+            }
+
+            return colors;
+    })(),
+    
+    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 };
+    },
+
+    axis: function (x, y, length, from, to, steps, orientation, labels, type, dashsize, paper) {
+        dashsize = dashsize == null ? 2 : dashsize;
+        type = type || "t";
+        steps = steps || 10;
+        paper = arguments[arguments.length-1] //paper is always last argument
+
+        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.snapEnds(from, to, steps),
+            f = ends.from,
+            t = ends.to,
+            i = ends.power,
+            j = 0,
+            txtattr = { font: "11px 'Fontin Sans', Fontin-Sans, sans-serif" },
+            text = paper.set(),
+            d;
+
+        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(paper.text(x + addon, Y, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(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(paper.text(x + addon, y - length, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(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 = paper.text(X, y + addon, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(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(paper.text(x + length, y + addon, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(txtattr));
+            }
+        }
+
+        var res = paper.path(path);
+
+        res.text = text;
+        res.all = paper.set([res, text]);
+        res.remove = function () {
+            this.text.remove();
+            this.constructor.prototype.remove.call(this);
+        };
+
+        return res;
+    },
+    
+    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);
+        }
+    }
+}
diff --git a/g.raphael.json b/g.raphael.json
new file mode 100644
index 0000000..d680b1f
--- /dev/null
+++ b/g.raphael.json
@@ -0,0 +1,9 @@
+{
+    "title": "g.Raphaël",
+    "output": "../g.raphael/docs/reference.html",
+    "scripts": ["../raphael-min.js", "../g.raphael.js", "reference.js"],
+    "files": [{
+        "url": "../g.raphael/g.raphael.js",
+        "link": "https://github.com/DmitryBaranovskiy/g.raphael/blob/master/g.raphael.js"
+    }]
+}
diff --git a/min/g.bar-min.js b/min/g.bar-min.js
new file mode 100644
index 0000000..f9f77d3
--- /dev/null
+++ b/min/g.bar-min.js
@@ -0,0 +1,7 @@
+/*!
+ * g.Raphael 0.5 - 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 f=Math.min,a=Math.max;function e(o,m,h,p,j,k,l,i){var s,n={round:"round",sharp:"sharp",soft:"soft",square:"square"};if((j&&!p)||(!j&&!h)){return l?"":i.path()}k=n[k]||"square";p=Math.round(p);h=Math.round(h);o=Math.round(o);m=Math.round(m);switch(k){case"round":if(!j){var g=~~(p/2);if(h<g){g=h;s=["M",o+0.5,m+0.5-~~(p/2),"l",0,0,"a",g,~~(p/2),0,0,1,0,p,"l",0,0,"z"]}else{s=["M",o+0.5,m+0.5-g,"l",h-g,0,"a",g,g,0,1,1,0,p,"l",g-h,0,"z"]}}else{g=~~(h/2);if(p<g){g=p;s=["M",o-~~( [...]
\ No newline at end of file
diff --git a/min/g.dot-min.js b/min/g.dot-min.js
new file mode 100644
index 0000000..4ba3af6
--- /dev/null
+++ b/min/g.dot-min.js
@@ -0,0 +1,7 @@
+/*!
+ * g.Raphael 0.5 - 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 b=function(g,f,e,d){return"hsb("+[Math.min((1-g/f)*0.4,1),e||0.75,d||0.75]+")"};function a(e,N,M,d,j,B,A,t,I){var v=this;function U(g){+g[0]&&(g[0]=v.axis(N+s,M+s,d-2*s,E,p,I.axisxstep||Math.floor((d-2*s)/20),2,I.axisxlabels||null,I.axisxtype||"t",null,e));+g[1]&&(g[1]=v.axis(N+d-s,M+j-s,j-2*s,D,o,I.axisystep||Math.floor((j-2*s)/20),3,I.axisylabels||null,I.axisytype||"t",null,e));+g[2]&&(g[2]=v.axis(N+s,M+j-s+H,d-2*s,E,p,I.axisxstep||Math.floor((d-2*s)/20),0,I.axisxlabels [...]
\ No newline at end of file
diff --git a/min/g.line-min.js b/min/g.line-min.js
new file mode 100644
index 0000000..39b4682
--- /dev/null
+++ b/min/g.line-min.js
@@ -0,0 +1,7 @@
+/*!
+ * g.Raphael 0.5 - 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(){function a(g,n){var f=g.length/n,h=0,e=f,m=0,i=[];while(h<g.length){e--;if(e<0){m+=g[h]*(1+e);i.push(m/f);m=g[h++]*-e;e+=f}else{m+=g[h++]}}return i}function d(f,e,p,n,k,j){var h=(p-f)/2,g=(k-p)/2,q=Math.atan((p-f)/Math.abs(n-e)),o=Math.atan((k-p)/Math.abs(n-j));q=e<n?Math.PI-q:q;o=j<n?Math.PI-o:o;var i=Math.PI/2-((q+o)%(Math.PI*2))/2,s=h*Math.sin(i+q),m=h*Math.cos(i+q),r=g*Math.sin(i+o),l=g*Math.cos(i+o);return{x1:p-s,y1:n+m,x2:p+r,y2:n+l}}function b(f,P,O,e,h,A,z,J){var s=th [...]
\ No newline at end of file
diff --git a/min/g.pie-min.js b/min/g.pie-min.js
new file mode 100644
index 0000000..624adeb
--- /dev/null
+++ b/min/g.pie-min.js
@@ -0,0 +1 @@
+(function(){function b(n,h,g,t,e,o){o=o||{};var c=this,q=[],k=n.set(),s=n.set(),m=n.set(),x=[],z=e.length,A=0,D=0,C=0,f=9,B=true;function w(I,H,i,K,G,P){var M=Math.PI/180,E=I+i*Math.cos(-K*M),p=I+i*Math.cos(-G*M),J=I+i/2*Math.cos(-(K+(G-K)/2)*M),O=H+i*Math.sin(-K*M),N=H+i*Math.sin(-G*M),F=H+i/2*Math.sin(-(K+(G-K)/2)*M),L=["M",I,H,"L",E,O,"A",i,i,0,+(Math.abs(G-K)>180),1,p,N,"z"];L.middle={x:J,y:F};return L}s.covers=k;if(z==1){m.push(n.circle(h,g,t).attr({fill:c.colors[0],stroke:o.stroke| [...]
\ No newline at end of file
diff --git a/min/g.raphael-min.js b/min/g.raphael-min.js
new file mode 100644
index 0000000..ec0ce1f
--- /dev/null
+++ b/min/g.raphael-min.js
@@ -0,0 +1,7 @@
+/*!
+ * g.Raphael 0.5 - 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.el.popup=function(d,k,h,g){var c=this.paper||this[0].paper,f,j,b,e,a;if(!c){return}switch(this.type){case"text":case"circle":case"ellipse":b=true;break;default:b=false}d=d==null?"up":d;k=k||5;f=this.getBBox();h=typeof h=="number"?h:(b?f.x+f.width/2:f.x);g=typeof g=="number"?g:(b?f.y+f.height/2:f.y);e=Math.max(f.width/2-k,0);a=Math.max(f.height/2-k,0);this.translate(h-f.x-(b?f.width/2:0),g-f.y-(b?f.height/2:0));f=this.getBBox();var i={up:["M",h,g,"l",-k,-k,-e,0,"a",k,k,0,0,1,-k,-k [...]
\ No newline at end of file
diff --git a/raphael-min.js b/raphael-min.js
new file mode 100644
index 0000000..e69ea16
--- /dev/null
+++ b/raphael-min.js
@@ -0,0 +1,8 @@
+// ┌─────────────────────────────────────────────────────────────────────┐ \\
+// │ Raphaël 2.0 - JavaScript Vector Library                             │ \\
+// ├─────────────────────────────────────────────────────────────────────┤ \\
+// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com)   │ \\
+// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com)             │ \\
+// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
+// └─────────────────────────────────────────────────────────────────────┘ \\
+(function(a){var b="0.3.2",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=[];h=a,i=0;for(var s=0,t=f.length;s<t;s++)"zIndex"in f[s]&&(o.push(f[s].zIndex),f[s].zIndex<0&&(p[f[s].zIndex]=f[s]));o.sort(g);while(o[l]<0){n=p[o[l++]],q.push(n.apply(b,e));if(i){i=d;return q}}for(s=0;s<t;s++){n=f[s];if("zIndex"in n)if(n.zIndex==o[l]){q.pu [...]
\ No newline at end of file
diff --git a/test/barchart.html b/test/barchart.html
new file mode 100644
index 0000000..055a534
--- /dev/null
+++ b/test/barchart.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>g·Raphaël Static Bar Charts</title>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.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"),
+                    data1 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    data2 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    data3 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+                    txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
+                
+                r.text(160, 10, "Single Series Chart").attr(txtattr);
+                r.text(480, 10, "Multiline Series Chart").attr(txtattr);
+                r.text(160, 250, "Multiple Series Stacked Chart").attr(txtattr);
+                r.text(480, 250, 'Multiline Series Stacked Vertical Chart. Type "round"').attr(txtattr);
+                
+                r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]], 0, {type: "sharp"});
+                r.barchart(330, 10, 300, 220, data1);
+                r.barchart(10, 250, 300, 220, data2, {stacked: true});
+                r.barchart(330, 250, 300, 220, data3, {stacked: true, type: "round"});
+            };
+        </script>
+    </head>
+    <body class="raphael" id="g.raphael.dmitry.baranovskiy.com">
+        <div id="holder"></div>
+        <p>
+            Demo of <a href="http://g.raphaeljs.com/">g·Raphaël</a> JavaScript library.
+        </p>
+    </body>
+</html>
diff --git a/test/barchart2.html b/test/barchart2.html
new file mode 100644
index 0000000..833d1d8
--- /dev/null
+++ b/test/barchart2.html
@@ -0,0 +1,51 @@
+<!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>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.raphael.js" type="text/javascript"></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 () {
+                        this.flag = r.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.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();});
+                    },
+                    txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
+                
+                r.text(160, 10, "Single Series Chart").attr(txtattr);
+                r.text(480, 10, "Multiline Series Stacked Chart").attr(txtattr);
+                r.text(160, 250, "Multiple Series Chart").attr(txtattr);
+                r.text(480, 250, "Multiline Series Stacked Chart\nColumn Hover").attr(txtattr);
+                
+                r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]]).hover(fin, fout);
+                r.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.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.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);
+            };
+        </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/brightness.html b/test/brightness.html
new file mode 100644
index 0000000..0fa6083
--- /dev/null
+++ b/test/brightness.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Raphael Tooltips</title>
+        <script src="../raphael-min.js" type="text/javascript"></script>
+        <script src="../g.raphael.js" type="text/javascript"></script>
+        <style type="text/css">
+            body {
+                background-color: #222;
+            }
+        </style>
+        <script type="text/javascript">
+            window.onload = function () {
+                var r = Raphael("holder", 1200, 800);
+
+                r.circle(200, 200, 150).attr({ fill: '#ff0000' }).lighter(6);
+                r.circle(550, 200, 150).attr({ fill: '#ff0000' }).lighter(6).resetBrightness();
+                r.circle(900, 200, 150).attr({ fill: '#ff0000' }).darker(6);
+
+                var s = r.set();
+
+                s.push(
+                    r.circle(200, 500, 75).attr({fill: '#ff0000' }),
+                    r.circle(200, 700, 75).attr({fill: '#00ff00' })
+                ).lighter(6);
+
+                var t = r.set();
+
+                t.push(
+                    r.circle(550, 500, 75).attr({fill: '#ff0000' }),
+                    r.circle(550, 700, 75).attr({fill: '#00ff00' })
+                ).lighter(6).resetBrightness();
+
+                var u = r.set();
+
+                u.push(
+                    r.circle(900, 500, 75).attr({fill: '#ff0000'}),
+                    r.circle(900, 700, 75).attr({fill: '#00ff00'})
+                ).darker(6);
+            };
+        </script>
+    </head>
+    <body class="raphael">
+        <div id="holder"></div>
+    </body>
+</html>
diff --git a/test/css/demo-print.css b/test/css/demo-print.css
new file mode 100644
index 0000000..7ebd11c
--- /dev/null
+++ b/test/css/demo-print.css
@@ -0,0 +1,17 @@
+body {
+    background: #fff;
+    font: 100.01% "Fontin Sans", Fontin-Sans, "Myriad Pro", "Lucida Grande", "Lucida Sans Unicode", Lucida, Verdana, Helvetica, sans-serif;
+    color: #000;
+    margin: 10px 0 0 0;
+    padding: 0;
+    text-align: center;
+}
+#holder {
+    margin: 0 auto;
+    width: 640px;
+    height: 480px;
+}
+p {
+    text-align: left;
+    margin: .5em 2em;
+}
diff --git a/test/css/demo.css b/test/css/demo.css
new file mode 100644
index 0000000..9ab945f
--- /dev/null
+++ b/test/css/demo.css
@@ -0,0 +1,21 @@
+body {
+    background: #999 url(../images/bgbg.png);
+    font: 100.01% "Fontin Sans", Fontin-Sans, "Myriad Pro", "Lucida Grande", "Lucida Sans Unicode", Lucida, Verdana, Helvetica, sans-serif;
+    color: #000;
+    margin: 10px 0 0 0;
+    padding: 0;
+    text-align: center;
+}
+#holder {
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+    -webkit-box-shadow: 0 1px 3px #666;
+    background: #ddd url(../images/bg.png);
+    margin: 0 auto;
+    width: 640px;
+    height: 480px;
+}
+p {
+    text-align: left;
+    margin: .5em 2em;
+}
diff --git a/test/dotchart.html b/test/dotchart.html
new file mode 100644
index 0000000..8a69c96
--- /dev/null
+++ b/test/dotchart.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>gRaphaël Dot Chart</title>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.raphael.js" type="text/javascript"></script>
+        <script src="../g.dot.js" type="text/javascript" charset="utf-8"></script>
+        <script type="text/javascript" charset="utf-8">
+            window.onload = function () {
+                var r = Raphael("holder"),
+                    xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 [...]
+                    ys = [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 [...]
+                    data = [294, 300, 204, 255, 348, 383, 334, 217, 114, 33, 44, 26, 41, 39, 52, 17, 13, 2, 0, 2, 5, 6, 64, 153, 294, 313, 195, 280, 365, 392, 340, 184, 87, 35, 43, 55, 53, 79, 49, 19, 6, 1, 0, 1, 1, 10, 50, 181, 246, 246, 220, 249, 355, 373, 332, 233, 85, 54, 28, 33, 45, 72, 54, 28, 5, 5, 0, 1, 2, 3, 58, 167, 206, 245, 194, 207, 334, 290, 261, 160, 61, 28, 11, 26, 33, 46, 36, 5, 6, 0, 0, 0, 0, 0, 0, 9, 9, 10, 7, 10, 14, 3, 3, 7, 0, 3, 4, 4, 6, 28, 24, 3, 5, 0, 0, 0, 0, 0 [...]
+                    axisy = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+                    axisx = ["12am", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12pm", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"];
+
+                r.dotchart(10, 10, 620, 260, xs, ys, data, {symbol: "o", max: 10, heat: true, axis: "0 0 1 1", axisxstep: 23, axisystep: 6, axisxlabels: axisx, axisxtype: " ", axisytype: " ", axisylabels: axisy}).hover(function () {
+                    this.marker = this.marker || r.tag(this.x, this.y, this.value, 0, this.r + 2).insertBefore(this);
+                    this.marker.show();
+                }, function () {
+                    this.marker && this.marker.hide();
+                });
+            };
+        </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/images/bg.png b/test/images/bg.png
new file mode 100644
index 0000000..42c4a82
Binary files /dev/null and b/test/images/bg.png differ
diff --git a/test/images/bgbg.png b/test/images/bgbg.png
new file mode 100644
index 0000000..771e425
Binary files /dev/null and b/test/images/bgbg.png differ
diff --git a/test/linechart.html b/test/linechart.html
new file mode 100644
index 0000000..e2967ed
--- /dev/null
+++ b/test/linechart.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>gRaphaël Line Charts</title>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.raphael.js" type="text/javascript"></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"),
+                    txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
+                
+                var x = [], y = [], y2 = [], y3 = [];
+
+                for (var i = 0; i < 1e6; 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.text(160, 10, "Simple Line Chart (1000 points)").attr(txtattr);
+                r.text(480, 10, "shade = true (10,000 points)").attr(txtattr);;
+                r.text(160, 250, "shade = true & nostroke = true (1,000,000 points)").attr(txtattr);
+                r.text(480, 250, "Symbols, axis and hover effect").attr(txtattr);
+
+                r.linechart(10, 10, 300, 220, x, [y.slice(0, 1e3), y2.slice(0, 1e3), y3.slice(0, 1e3)]).hoverColumn(function () {
+                    this.set = r.set(
+                        r.circle(this.x, this.y[0]),
+                        r.circle(this.x, this.y[1]),
+                        r.circle(this.x, this.y[2])
+                    );
+                }, function () {
+                    this.set.remove();
+                });
+
+                r.linechart(330, 10, 300, 220, x, [y.slice(0, 1e4), y2.slice(0, 1e4), y3.slice(0, 1e4)], { shade: true });
+                r.linechart(10, 250, 300, 220, x, [y, y2, y3], { nostroke: true, shade: true });
+
+                var lines = r.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: "circle", smooth: true }).hoverColumn(function () {
+                    this.tags = r.set();
+
+                    for (var i = 0, ii = this.y.length; i < ii; i++) {
+                        this.tags.push(r.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.symbols.attr({ r: 6 });
+                // 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>
diff --git a/test/piechart.html b/test/piechart.html
new file mode 100644
index 0000000..78358f4
--- /dev/null
+++ b/test/piechart.html
@@ -0,0 +1,26 @@
+<!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 Pie Chart</title>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.raphael.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.pie.js" type="text/javascript" charset="utf-8"></script>
+        <script type="text/javascript" charset="utf-8">
+            window.onload = function () {
+                var r = Raphael("holder");
+
+                r.text(320, 70, "Static Pie Chart").attr({ font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" });
+                r.piechart(320, 240, 150, [55, 20, 13, 32, 5, 1, 2, 10]);
+            };
+        </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/piechart2.html b/test/piechart2.html
new file mode 100644
index 0000000..70baab3
--- /dev/null
+++ b/test/piechart2.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>g·Raphaël Dynamic Pie Chart</title>
+        <link rel="stylesheet" href="css/demo.css" type="text/css" media="screen" charset="utf-8">
+        <link rel="stylesheet" href="css/demo-print.css" type="text/css" media="print" charset="utf-8">
+        <script src="../raphael-min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.raphael.js" type="text/javascript" charset="utf-8"></script>
+        <script src="../g.pie.js" type="text/javascript" charset="utf-8"></script>
+        <script type="text/javascript" charset="utf-8">
+            window.onload = function () {
+                var r = Raphael("holder"),
+                    pie = r.piechart(320, 240, 100, [55, 20, 13, 32, 5, 1, 2, 10], { legend: ["%%.%% - Enterprise Users", "IE Users"], legendpos: "west", href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]});
+
+                r.text(320, 100, "Interactive Pie Chart").attr({ font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" });
+                pie.hover(function () {
+                    this.sector.stop();
+                    this.sector.scale(1.1, 1.1, this.cx, this.cy);
+
+                    if (this.label) {
+                        this.label[0].stop();
+                        this.label[0].attr({ r: 7.5 });
+                        this.label[1].attr({ "font-weight": 800 });
+                    }
+                }, function () {
+                    this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
+
+                    if (this.label) {
+                        this.label[0].animate({ r: 5 }, 500, "bounce");
+                        this.label[1].attr({ "font-weight": 400 });
+                    }
+                });
+            };
+        </script>
+    </head>
+    <body class="raphael" id="g.raphael.dmitry.baranovskiy.com">
+        <div id="holder"></div>
+        <p>
+            Pie chart with legend, hyperlinks on two first sectors and hover effect.
+        </p>
+        <p>
+            Demo of <a href="http://g.raphaeljs.com/">g·Raphaël</a> JavaScript library.
+        </p>
+    </body>
+</html>
diff --git a/test/tooltips.html b/test/tooltips.html
new file mode 100644
index 0000000..95cf8e3
--- /dev/null
+++ b/test/tooltips.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+    <head>
+        <title>Raphael Tooltips</title>
+        <script src="../raphael-min.js" type="text/javascript"></script>
+        <script src="../g.raphael.js" type="text/javascript"></script>
+        <script type="text/javascript">
+            window.onload = function () {
+                var r = Raphael("holder", 2000, 2000),
+                    s = r.set(),
+                    t = r.set(),
+                    u = r.set(),
+                    v = r.set();
+
+                function ref(count, y) {
+                    var def = ["M30,", y, "l", 50 * count, ",0"],
+                        end = "," + (y - 20) + "l0,40";
+
+                    for (var i = 1; i <= count; i++) {
+                        def.push("M", 50 * i, end);
+                    }
+
+                    r.path(def.join('')).attr({ stroke: '#c00', translation: [150.5, 100.5] }).insertBefore(s[0]);
+                }
+
+                s.push(
+                    r.tag(50, 150, "$9.99", 130),
+                    r.tag(100, 150, "$9.99", 310),
+                    r.label(150, 150, "$9.99"),
+                    r.flag(200, 150, "$9.99", 60),
+                    r.flag(250, 150, "$9.99", 240),
+                    r.popup(300, 150, "$9.99", 'down', 20),
+                    r.popup(350, 150, "$9.99", 'right'),
+                    r.drop(400, 150, "$10", 60),
+                    r.rect(450, 150, 15, 15).attr({fill:'90-#fff-#000'}).drop(),
+                    r.blob(500, 150, "$9.99", 60),
+                    r.blob(550, 150, "$9.99", 270),
+                    r.circle(600, 150, 10).attr({fill:'#ff0000'}).label(),
+                    r.circle(650, 150, 10).attr({fill:'#ff0000'}).popup(),
+                    r.circle(700, 150, 10).attr({fill:'#ff0000'}).popup('down'),
+                    r.circle(800, 150, 10).attr({fill:'#ff0000'}).tag(130, null, 750),
+                    r.circle(800, 150, 10).attr({fill:'#ff0000'}).tag(),
+                    r.circle(900, 150, 10).attr({fill:'#ff0000'}).blob(),
+                    r.circle(800, 150, 10).attr({fill:'#ff0000'}).blob(270, 850)
+                );
+
+                for (var i = 0; i < 30; i++) {
+                    //t.push(r.text(800, 350, "$9.99").attr({fill:'#ff0000'}).tag(360 / 30 * i, 50 * (i + 1)));
+                    //t.push(r.circle(800, 350, 10).attr({fill:'90-#fff-#000'}).tag(360 / 30 * i, 5, 50 * (i + 1)));
+                    t.push(r.rect(800, 350, 20, 20).attr({fill:'90-#ff0000-#0000ff'}).flag(360 / 30 * i, 50 * (i + 1)));
+                }
+
+                ref(t.length, 350);
+
+                //test on sets
+                u.push(
+                    r.circle(100, 850, 10).attr({fill: '#00ff00'}),
+                    r.circle(110, 800, 10).attr({fill: '#0000ff'})
+                ).flag(130);
+
+                var a = r.set();
+                a.push(
+                    r.circle(200, 850, 10).attr({fill: '#00ff00'}),
+                    r.circle(210, 800, 10).attr({fill: '#0000ff'})
+                ).flag(30);
+                ref(s.length, 150);
+
+
+                var v = r.set();
+
+                for (var i = 0; i < 30; i++) {
+                    //v.push(r.circle(0, 0, 10).attr({fill:'90-#fff-#000'}).blob(360 / 30 * i, 50 * (i + 1), 550));
+                    v.push(r.rect(0, 0, 20, 20).attr({fill:'90-#fff-#000'}).blob(360 / 30 * i, 50 * (i + 1), 550));
+                    //v.push(r.text(0, 0, 'Hello').attr({fill:'90-#fff-#000'}).blob(360 / 30 * i, 50 * (i + 1), 550));
+                }
+
+                ref(v.length, 550);
+            };
+        </script>
+    </head>
+    <body class="raphael">
+        <div id="holder"></div>
+    </body>
+</html>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/libjs-graphael.git



More information about the Pkg-javascript-commits mailing list