* Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
-Raphael.fn.g.linechart = function (x, y, width, height, valuesx, valuesy, opts) {
+(function () {
+ var defcolors = (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;
+ })();
+
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);
}
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,
y2: p2y + dy2
};
}
- opts = opts || {};
- if (!this.raphael.is(valuesx[0], "array")) {
- valuesx = [valuesx];
- }
- if (!this.raphael.is(valuesy[0], "array")) {
- valuesy = [valuesy];
- }
- var gutter = opts.gutter || 10,
- len = Math.max(valuesx[0].length, valuesy[0].length),
- symbol = opts.symbol || "",
- colors = opts.colors || Raphael.fn.g.colors,
- that = this,
- columns = null,
- dots = null,
- chart = this.set(),
- path = [];
-
- for (var i = 0, ii = valuesy.length; i < ii; i++) {
- len = Math.max(len, valuesy[i].length);
- }
- var shades = this.set();
- for (i = 0, ii = valuesy.length; i < ii; i++) {
- if (opts.shade) {
- shades.push(this.path().attr({stroke: "none", fill: colors[i], opacity: opts.nostroke ? 1 : .3}));
- }
- if (valuesy[i].length > width - 2 * gutter) {
- valuesy[i] = shrink(valuesy[i], width - 2 * gutter);
- len = width - 2 * gutter;
+ Raphael.fn.linechart = function (x, y, width, height, valuesx, valuesy, opts) {
+
+ opts = opts || {};
+
+ if (!Raphael.is(valuesx[0], "array")) {
+ valuesx = [valuesx];
}
- if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {
- valuesx[i] = shrink(valuesx[i], width - 2 * gutter);
+
+ if (!Raphael.is(valuesy[0], "array")) {
+ valuesy = [valuesy];
}
- }
- var allx = Array.prototype.concat.apply([], valuesx),
- ally = Array.prototype.concat.apply([], valuesy),
- xdim = this.g.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1),
- minx = xdim.from,
- maxx = xdim.to,
- ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),
- miny = ydim.from,
- maxy = ydim.to,
- kx = (width - gutter * 2) / ((maxx - minx) || 1),
- ky = (height - gutter * 2) / ((maxy - miny) || 1);
-
- var axis = this.set();
- if (opts.axis) {
- var ax = (opts.axis + "").split(/[,\s]+/);
- +ax[0] && axis.push(this.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2));
- +ax[1] && axis.push(this.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3));
- +ax[2] && axis.push(this.g.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0));
- +ax[3] && axis.push(this.g.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1));
- }
- var lines = this.set(),
- symbols = this.set(),
- line;
- for (i = 0, ii = valuesy.length; i < ii; i++) {
- if (!opts.nostroke) {
- lines.push(line = this.path().attr({
- stroke: colors[i],
- "stroke-width": opts.width || 2,
- "stroke-linejoin": "round",
- "stroke-linecap": "round",
- "stroke-dasharray": opts.dash || ""
- }));
+
+ var gutter = opts.gutter || 10,
+ len = Math.max(valuesx[0].length, valuesy[0].length),
+ symbol = opts.symbol || "",
+ colors = opts.colors || defcolors,
+ that = this,
+ columns = null,
+ dots = null,
+ chart = this.set(),
+ path = [];
+
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ len = Math.max(len, valuesy[i].length);
}
- var sym = this.raphael.is(symbol, "array") ? symbol[i] : symbol,
- symset = this.set();
- path = [];
- for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
- var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
- Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
- (Raphael.is(sym, "array") ? sym[j] : sym) && symset.push(this.g[Raphael.fn.g.markers[this.raphael.is(sym, "array") ? sym[j] : sym]](X, Y, (opts.width || 2) * 3).attr({fill: colors[i], stroke: "none"}));
- if (opts.smooth) {
- if (j && j != jj - 1) {
- var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,
- Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,
- X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,
- Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky;
- var a = getAnchors(X0, Y0, X, Y, X2, Y2);
- path = path.concat([a.x1, a.y1, X, Y, a.x2, a.y2]);
- }
- if (!j) {
- path = ["M", X, Y, "C", X, Y];
- }
- } else {
- path = path.concat([j ? "L" : "M", X, Y]);
+
+ var shades = this.set();
+
+ for (i = 0, ii = valuesy.length; i < ii; i++) {
+ if (opts.shade) {
+ shades.push(this.path().attr({ stroke: "none", fill: colors[i], opacity: opts.nostroke ? 1 : .3 }));
+ }
+
+ if (valuesy[i].length > width - 2 * gutter) {
+ valuesy[i] = shrink(valuesy[i], width - 2 * gutter);
+ len = width - 2 * gutter;
+ }
+
+ if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {
+ valuesx[i] = shrink(valuesx[i], width - 2 * gutter);
}
}
- 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);
+
+ var allx = Array.prototype.concat.apply([], valuesx),
+ ally = Array.prototype.concat.apply([], valuesy),
+ xdim = this.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1),
+ minx = xdim.from,
+ maxx = xdim.to,
+ ydim = this.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),
+ miny = ydim.from,
+ maxy = ydim.to,
+ kx = (width - gutter * 2) / ((maxx - minx) || 1),
+ ky = (height - gutter * 2) / ((maxy - miny) || 1);
+
+ var axis = this.set();
+
+ if (opts.axis) {
+ var ax = (opts.axis + "").split(/[,\s]+/);
+ +ax[0] && axis.push(this.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2));
+ +ax[1] && axis.push(this.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3));
+ +ax[2] && axis.push(this.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0));
+ +ax[3] && axis.push(this.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1));
}
- Xs = Xs2;
- ii = Xs.length;
- var cvrs = f || that.set();
- for (i = 0; i < ii; i++) {
- var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,
- w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,
- C;
- f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({stroke: "none", fill: "#000", opacity: 0}));
- C.values = [];
- C.symbols = that.set();
- C.y = [];
- C.x = xs[i];
- C.axis = Xs[i];
- for (var j = 0, jj = valuesy.length; j < jj; j++) {
- Xs2 = valuesx[j] || valuesx[0];
- for (var k = 0, kk = Xs2.length; k < kk; k++) {
- if (Xs2[k] == Xs[i]) {
- C.values.push(valuesy[j][k]);
- C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);
- C.symbols.push(chart.symbols[j][k]);
- }
- }
+
+ var lines = this.set(),
+ symbols = this.set(),
+ line;
+
+ for (i = 0, ii = valuesy.length; i < ii; i++) {
+ if (!opts.nostroke) {
+ lines.push(line = this.path().attr({
+ stroke: colors[i],
+ "stroke-width": opts.width || 2,
+ "stroke-linejoin": "round",
+ "stroke-linecap": "round",
+ "stroke-dasharray": opts.dash || ""
+ }));
}
- f && f.call(C);
- }
- !f && (columns = cvrs);
- }
- function createDots(f) {
- var cvrs = f || that.set(),
- C;
- for (var i = 0, ii = valuesy.length; i < ii; i++) {
+
+ var sym = Raphael.is(symbol, "array") ? symbol[i] : symbol,
+ symset = this.set();
+
+ path = [];
+
for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
- nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,
Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
- f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({stroke: "none", fill: "#000", opacity: 0}));
- C.x = X;
- C.y = Y;
- C.value = valuesy[i][j];
- C.line = chart.lines[i];
- C.shade = chart.shades[i];
- C.symbol = chart.symbols[i][j];
- C.symbols = chart.symbols[i];
- C.axis = (valuesx[i] || valuesx[0])[j];
- f && f.call(C);
+
+ (Raphael.is(sym, "array") ? sym[j] : sym) && symset.push(this[Raphael.is(sym, "array") ? sym[j] : sym](X, Y, (opts.width || 2) * 3).attr({ fill: colors[i], stroke: "none" }));
+
+ if (opts.smooth) {
+ if (j && j != jj - 1) {
+ var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,
+ Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,
+ X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,
+ Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky,
+ 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(",") });
}
- !f && (dots = cvrs);
- }
- chart.push(lines, shades, symbols, axis, columns, dots);
- chart.lines = lines;
- chart.shades = shades;
- chart.symbols = symbols;
- chart.axis = axis;
- chart.hoverColumn = function (fin, fout) {
- !columns && createColumns();
- columns.mouseover(fin).mouseout(fout);
- return this;
- };
- chart.clickColumn = function (f) {
- !columns && createColumns();
- columns.click(f);
- return this;
- };
- chart.hrefColumn = function (cols) {
- var hrefs = that.raphael.is(arguments[0], "array") ? arguments[0] : arguments;
- if (!(arguments.length - 1) && typeof cols == "object") {
- for (var x in cols) {
- for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {
- columns[i].attr("href", cols[x]);
+
+ function createColumns(f) {
+ // unite Xs together
+ var Xs = [];
+
+ for (var i = 0, ii = valuesx.length; i < ii; i++) {
+ Xs = Xs.concat(valuesx[i]);
+ }
+
+ Xs.sort();
+ // remove duplicates
+
+ var Xs2 = [],
+ xs = [];
+
+ for (i = 0, ii = Xs.length; i < ii; i++) {
+ Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx);
+ }
+
+ Xs = Xs2;
+ ii = Xs.length;
+
+ var cvrs = f || that.set();
+
+ for (i = 0; i < ii; i++) {
+ var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,
+ w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,
+ C;
+
+ f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({ stroke: "none", fill: "#000", opacity: 0 }));
+ C.values = [];
+ C.symbols = that.set();
+ C.y = [];
+ C.x = xs[i];
+ C.axis = Xs[i];
+
+ for (var j = 0, jj = valuesy.length; j < jj; j++) {
+ Xs2 = valuesx[j] || valuesx[0];
+
+ for (var k = 0, kk = Xs2.length; k < kk; k++) {
+ if (Xs2[k] == Xs[i]) {
+ C.values.push(valuesy[j][k]);
+ C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);
+ C.symbols.push(chart.symbols[j][k]);
+ }
+ }
}
+
+ f && f.call(C);
}
+
+ !f && (columns = cvrs);
}
- !columns && createColumns();
- for (i = 0, ii = hrefs.length; i < ii; i++) {
- columns[i] && columns[i].attr("href", hrefs[i]);
+
+ function createDots(f) {
+ var cvrs = f || that.set(),
+ C;
+
+ for (var i = 0, ii = valuesy.length; i < ii; i++) {
+ for (var j = 0, jj = valuesy[i].length; j < jj; j++) {
+ var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,
+ nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,
+ Y = y + height - gutter - (valuesy[i][j] - miny) * ky;
+
+ f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({ stroke: "none", fill: "#000", opacity: 0 }));
+ C.x = X;
+ C.y = Y;
+ C.value = valuesy[i][j];
+ C.line = chart.lines[i];
+ C.shade = chart.shades[i];
+ C.symbol = chart.symbols[i][j];
+ C.symbols = chart.symbols[i];
+ C.axis = (valuesx[i] || valuesx[0])[j];
+ f && f.call(C);
+ }
+ }
+
+ !f && (dots = cvrs);
}
- 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;
+
+ chart.push(lines, shades, symbols, axis, columns, dots);
+ chart.lines = lines;
+ chart.shades = shades;
+ chart.symbols = symbols;
+ chart.axis = axis;
+
+ chart.hoverColumn = function (fin, fout) {
+ !columns && createColumns();
+ columns.mouseover(fin).mouseout(fout);
+ return this;
+ };
+
+ chart.clickColumn = function (f) {
+ !columns && createColumns();
+ columns.click(f);
+ return this;
+ };
+
+ chart.hrefColumn = function (cols) {
+ var hrefs = that.raphael.is(arguments[0], "array") ? arguments[0] : arguments;
+
+ if (!(arguments.length - 1) && typeof cols == "object") {
+ for (var x in cols) {
+ for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {
+ columns[i].attr("href", cols[x]);
+ }
+ }
+ }
+
+ !columns && createColumns();
+
+ for (i = 0, ii = hrefs.length; i < ii; i++) {
+ columns[i] && columns[i].attr("href", hrefs[i]);
+ }
+
+ return this;
+ };
+
+ chart.hover = function (fin, fout) {
+ !dots && createDots();
+ dots.mouseover(fin).mouseout(fout);
+ return this;
+ };
+
+ chart.click = function (f) {
+ !dots && createDots();
+ dots.click(f);
+ return this;
+ };
+
+ chart.each = function (f) {
+ createDots(f);
+ return this;
+ };
+
+ chart.eachColumn = function (f) {
+ createColumns(f);
+ return this;
+ };
+
+ return chart;
};
- return chart;
-};
+})();
--- /dev/null
+<!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/raphael.js" type="text/javascript" charset="utf-8"></script>
+ <script src="../raphael/plugins/raphael.tooltips.js" type="text/javascript"></script>
+ <script src="../g.utils.js" type="text/javascript" charset="utf-8"></script>
+ <script src="../g.line.js" type="text/javascript" charset="utf-8"></script>
+ <script type="text/javascript" charset="utf-8">
+ window.onload = function () {
+ var r = Raphael("holder"),
+ 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>
+++ /dev/null
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-<html lang="en">
- <head>
- <title>gRaphaël Static Line Charts</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="author" content="Dmitry Baranovskiy">
- <meta name="description" content="Charting JavaScript Library">
- <link rel="stylesheet" href="demo.css" type="text/css" media="screen" charset="utf-8">
- <link rel="stylesheet" href="demo-print.css" type="text/css" media="print" charset="utf-8">
- <script src="../raphael.js" type="text/javascript" charset="utf-8"></script>
- <script src="g.raphael.js" type="text/javascript" charset="utf-8"></script>
- <script src="g.line.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript" charset="utf-8">
- window.onload = function () {
- var r = Raphael("holder");
- r.g.txtattr.font = "12px 'Fontin Sans', Fontin-Sans, sans-serif";
-
- var x = [], y = [], y2 = [], y3 = [];
- for (var i = 0; i < 500; i++) {
- x[i] = i * 10;
- y[i] = (y[i - 1] || 0) + (Math.random() * 7) - 3;
- y2[i] = (y2[i - 1] || 150) + (Math.random() * 7) - 3.5;
- y3[i] = (y3[i - 1] || 300) + (Math.random() * 7) - 4;
- }
-
- r.g.text(160, 10, "Simple Line Chart");
- r.g.text(480, 10, "shade = true");
- r.g.text(160, 250, "shade = true & nostroke = true");
- r.g.text(480, 250, "Symbols, axis and hover effect");
-
- r.g.linechart(10, 10, 300, 220, x, [y, y2, y3]);
- r.g.linechart(330, 10, 300, 220, x, [y, y2, y3], {shade: true});
- r.g.linechart(10, 250, 300, 220, x, [y, y2, y3], {nostroke: true, shade: true});
- var lines = r.g.linechart(330, 250, 300, 220, [[1, 2, 3, 4, 5, 6, 7],[3.5, 4.5, 5.5, 6.5, 7, 8]], [[12, 32, 23, 15, 17, 27, 22], [10, 20, 30, 25, 15, 28]], {nostroke: false, axis: "0 0 1 1", symbol: "o"}).hoverColumn(function () {
- this.tags = r.set();
- for (var i = 0, ii = this.y.length; i < ii; i++) {
- this.tags.push(r.g.tag(this.x, this.y[i], this.values[i], 160, 10).insertBefore(this).attr([{fill: "#fff"}, {fill: this.symbols[i].attr("fill")}]));
- }
- }, function () {
- this.tags && this.tags.remove();
- });
- // lines.lines[0].animate({"stroke-width": 6}, 1000);
- // lines.symbols[0].attr({stroke: "#fff"});
- // lines.symbols[0][1].animate({fill: "#f00"}, 1000);
- };
- </script>
- </head>
- <body class="raphael" id="g.raphael.dmitry.baranovskiy.com">
- <div id="holder"></div>
- <p>
- Demo of <a href="http://g.raphaeljs.com/">gRaphaël</a> JavaScript library.
- </p>
- </body>
-</html>