Advertisement
Guest User

chart

a guest
Jun 13th, 2012
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Raphael Line Chart 1.2 - Raphael Line Charts plugin
  3.  *
  4.  * Copyright (c) 2011 Sagie Maoz (http://sagie.maoz.info)
  5.  * Dual-licensed under the GPL (http://www.opensource.org/licenses/gpl-3.0)
  6.  * and the MIT (http://www.opensource.org/licenses/mit-license) licenses.
  7.  */
  8. (function() {
  9.  
  10. // modified version of Raphael.fn.drawGrid() from the Raphael Analytics example
  11. Raphael.fn.drawGrid = function(x, y, width, height, x_step, x_size, y_count, y_size) {
  12.     var path,
  13.         rowHeight,
  14.         columnWidth;
  15.    
  16.     // frame border
  17.     path = ["M", Math.round(x) + 0.5, Math.round(y) + 0.5,
  18.             "L", Math.round(x + width) + 0.5, Math.round(y) + 0.5,
  19.             Math.round(x + width) + 0.5, Math.round(y + height) + 0.5,
  20.             Math.round(x) + 0.5, Math.round(y + height) + 0.5,
  21.             Math.round(x) + 0.5, Math.round(y) + 0.5];
  22.    
  23.     // horizontal lines
  24.     rowHeight = Math.ceil(height / y_count);
  25.     for (var i = 10; i < y_count; i++) {
  26.         path = path.concat(["M", Math.round(x) + 0.5, Math.round(y + i * rowHeight) + 0.5,
  27.                             "H", Math.round(x + width) + 0.5]);
  28.     }
  29.    
  30.     // vertical lines
  31.     if (!x_step) {
  32.         x_step = .5;
  33.         x_size = 10;
  34.     }
  35.     columnWidth = Math.ceil(width / x_size);
  36.     for (i = 0; i < x_size; i+= x_step) {
  37.         path = path.concat(["M", Math.round(x + i * (columnWidth + 1.1)) + 0.5, Math.round(y) + 0.5,
  38.                             "V", Math.round(y + height) + 0.5]);
  39.     }
  40.    
  41.     return this.path(path.join(","));
  42. };
  43.  
  44. Raphael.fn.popup = function(X, Y, set, position, ret) {
  45.     var pos = String(position || "top-middle").split("-"),
  46.         pos_x = pos[1] || "middle",
  47.         tokenRegex = /\{([^\}]+)\}/g,
  48.         objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,
  49.        
  50.         replacer = function(all, key, obj) {
  51.             var res = obj;
  52.             key.replace(objNotationRegex,
  53.             function(all, name, quote, quotedName, isFunc) {
  54.                 name = name || quotedName;
  55.                 if (res) {
  56.                     if (name in res) {
  57.                         res = res[name];
  58.                     }
  59.                     return (typeof res == "function") && isFunc && (res = res());
  60.                 }
  61.             });
  62.             res = (res === null || res == obj ? all: res) + "";
  63.             return res;
  64.         },
  65.        
  66.         fill = function(str, obj) {
  67.             return String(str).replace(tokenRegex,
  68.             function(all, key) {
  69.                 return replacer(all, key, obj);
  70.             });
  71.         },
  72.        
  73.         r = 5,
  74.         bb = set.getBBox(),
  75.         w = Math.round(bb.width),
  76.         h = Math.round(bb.height),
  77.         x = Math.round(bb.x) - r,
  78.         y = Math.round(bb.y) - r,
  79.         gap = Math.min(h / 2, w / 2, 10),
  80.         shapes = {
  81.             top: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
  82.             bottom: "M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z",
  83.             right: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z",
  84.             left: "M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z"
  85.         },
  86.         offset = {
  87.             hx0: X - (x + r + w - gap * 2),
  88.             hx1: X - (x + r + w / 2 - gap),
  89.             hx2: X - (x + r + gap),
  90.             vhy: Y - (y + r + h + r + gap),
  91.             "^hy": Y - (y - gap)
  92.         },
  93.         mask = [{
  94.             x: x + r,
  95.             y: y,
  96.             w: w,
  97.             w4: w / 4,
  98.             h4: h / 4,
  99.             right: 0,
  100.             left: w - gap * 2,
  101.             bottom: 0,
  102.             top: h - gap * 2,
  103.             r: r,
  104.             h: h,
  105.             gap: gap
  106.         },
  107.         {
  108.             x: x + r,
  109.             y: y,
  110.             w: w,
  111.             w4: w / 4,
  112.             h4: h / 4,
  113.             left: w / 2 - gap,
  114.             right: w / 2 - gap,
  115.             top: h / 2 - gap,
  116.             bottom: h / 2 - gap,
  117.             r: r,
  118.             h: h,
  119.             gap: gap
  120.         },
  121.         {
  122.             x: x + r,
  123.             y: y,
  124.             w: w,
  125.             w4: w / 4,
  126.             h4: h / 4,
  127.             left: 0,
  128.             right: w - gap * 2,
  129.             top: 0,
  130.             bottom: h - gap * 2,
  131.             r: r,
  132.             h: h,
  133.             gap: gap
  134.         }][pos_x == "middle" ? 1: (pos_x == "top" || pos_x == "left") * 2],
  135.         dx = 0,
  136.         dy = 0,
  137.         out = this.path(fill(shapes[pos[0]], mask)).insertBefore(set);
  138.        
  139.     switch (pos[0]) {
  140.         case "top":
  141.             dx = X - (x + r + mask.left + gap);
  142.             dy = Y - (y + r + h + r + gap);
  143.             break;
  144.         case "bottom":
  145.             dx = X - (x + r + mask.left + gap);
  146.             dy = Y - (y - gap);
  147.             break;
  148.         case "left":
  149.             dx = X - (x + r + w + r + gap);
  150.             dy = Y - (y + r + mask.top + gap);
  151.             break;
  152.         case "right":
  153.             dx = X - (x - gap);
  154.             dy = Y - (y + r + mask.top + gap);
  155.             break;
  156.     }
  157.     out.translate(dx, dy);
  158.     if (ret) {
  159.         ret = out.attr("path");
  160.         out.remove();
  161.         return {
  162.             path: ret,
  163.             dx: dx,
  164.             dy: dy
  165.         };
  166.     }
  167.     set.translate(dx, dy);
  168.     return out;
  169. };
  170.  
  171. Raphael.fn.lineChart = function(method) {
  172.    
  173.     // public methods
  174.     var methods = {
  175.        
  176.         init: function(options) {
  177.  
  178.             this.lineChart.settings = helpers.extend(true, {}, this.lineChart.defaults, options);
  179.             this.customAttributes.lineChart = {};
  180.            
  181.             // let's go
  182.             var element = this,
  183.                 o = this.customAttributes.lineChart,
  184.                 settings = this.lineChart.settings,
  185.                 gutter = settings.gutter,
  186.                 width = settings.width,
  187.                 height = settings.height,
  188.                
  189.                 table = helpers.loadTableData(settings.data_holder), //TODO allow passing data by array
  190.                 size = table.labels.length,
  191.                
  192.                 X = (width - gutter.left) / size,
  193.                 max = Math.max.apply(Math, table.data),
  194.                 Y = (height - gutter.bottom - gutter.top) / max,
  195.                
  196.                 blanket = element.set(),
  197.                 p,
  198.                 bgpp,
  199.                 x,
  200.                 y;
  201.            
  202.             o.size = size;
  203.             o.dots = [];
  204.             o.rects = [];
  205.             o.info = [];
  206.             //TODO allow customizing
  207.             o.path = element.path().attr({
  208.                 stroke: settings.colors.master,
  209.                 "stroke-width": 4,
  210.                 "stroke-linejoin": "round"
  211.             });
  212.             // chart area
  213.             //TODO allow customizing
  214.             if (settings.show_area) {
  215.                 o.bgp = element.path().attr({
  216.                     stroke: "none",
  217.                     opacity: 0.3,
  218.                     fill: "none"
  219.                 });
  220.             }
  221.             else {
  222.                 o.bgp = element.path().attr({
  223.                     stroke: "none",
  224.                     opacity: 0,
  225.                     fill: settings.colors.master
  226.                 }).hide();
  227.             }
  228.            
  229.             // draw background grid
  230.             if (!o.gridDrawn && settings.no_grid === false) {
  231.                 var grid = element.drawGrid(gutter.left + X * 0.5 + 0.5,
  232.                                 gutter.top + 0.5,
  233.                                 width - gutter.left - X,
  234.                                 height - gutter.top - gutter.bottom,
  235.                                 settings.x_labels_step,
  236.                                 size,
  237.                                 settings.y_labels_count,
  238.                                 max)
  239.                             .attr({ stroke: "#000" });
  240.  
  241.                 grid.toBack();
  242.             }
  243.             o.gridDrawn = true;
  244.            
  245.             // draw x axis labels
  246.             o.XLabels = [];
  247.             if (settings.x_labels_step) {
  248.                 helpers.drawXLabels(element, X, height - gutter.bottom + 18,
  249.                         settings.x_labels_step, table.labels,
  250.                         settings.text.axis_labels);
  251.             }
  252.            
  253.             // draw y axis labels
  254.             o.YLabels = [];
  255.             if (settings.y_labels_count) {
  256.                 helpers.drawYLabels(element, gutter.left, gutter.bottom,
  257.                             height, settings.y_labels_count,
  258.                             max, gutter.top, settings.text.axis_labels);
  259.             }
  260.  
  261.             // prepare popup
  262.             o.label = element.set();
  263.             //TODO ??
  264.             o.label.push(element.text(60, 12, "24 hits").attr(settings.text.popup_line1));
  265.             o.label.push(element.text(60, 27, "22 September 2008").attr(settings.text.popup_line2).attr({
  266.                 fill: settings.colors.master
  267.             }));
  268.             o.label.hide();
  269.  
  270.             //TODO allow customizing
  271.             o.frame = element.popup(100, 100, o.label, "right").attr({
  272.                 fill: "#ffffff",
  273.                 stroke: "#666",
  274.                 "stroke-width": 2,
  275.                 "fill-opacity": 0.8
  276.             }).hide();
  277.            
  278.             for (var i = 0, ii = size; i < ii; i++) {
  279.                 var dot, rect;
  280.  
  281.                 // calculate current x, y
  282.                 y = Math.round(height - gutter.bottom - Y * table.data[i]);
  283.                 x = Math.round(gutter.left + X * (i + 0.5));
  284.  
  285.                 if (!i) {
  286.                     p = ["M", x, y, "C", x, y];
  287.                     bgpp = ["M", gutter.left + X * 0.5, height - gutter.bottom, "L", x, y, "C", x, y];
  288.                 }
  289.                 else if (i < ii - 1) {
  290.                     var Y0 = Math.round(height - gutter.bottom - Y * table.data[i - 1]),
  291.                         X0 = Math.round(gutter.left + X * (i - 0.5)),
  292.                         Y2 = Math.round(height - gutter.bottom - Y * table.data[i + 1]),
  293.                         X2 = Math.round(gutter.left + X * (i + 1.5)),
  294.                         a = helpers.getAnchors(X0, Y0, x, y, X2, Y2);
  295.                     p = p.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
  296.                     bgpp = bgpp.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
  297.                 }
  298.  
  299.                 //TODO allow customizing all of these
  300.                 dot = element.circle(x, y, 4).attr({
  301.                     fill: "#ffffff",
  302.                     stroke: settings.colors.master,
  303.                     "stroke-width": 2
  304.                 });
  305.                 if (y === 0) {
  306.                     dot.attr({
  307.                         opacity: 0
  308.                     });
  309.                 }
  310.                
  311.                 o.dots.push(dot);
  312.                
  313.                 if (settings.mouse_coords == 'circle') {
  314.                     blanket.push(element.circle(x, y, 14).attr({
  315.                         stroke: "none",
  316.                         fill: "#fff",
  317.                         opacity: 0
  318.                     }));
  319.                 } else if (settings.mouse_coords == 'rect') {
  320.                     blanket.push(element.rect(gutter.left + X * i, 0, X, height - gutter.bottom).attr({
  321.                         stroke: "none",
  322.                         fill: "#fff",
  323.                         opacity: 0
  324.                     }));
  325.                 }
  326.                 rect = blanket[blanket.length - 1];
  327.                 o.rects.push(rect);
  328.                
  329.                 o.info.push({
  330.                     x: x,
  331.                     y: y,
  332.                     data: table.data[i],
  333.                     label: table.labels[i],
  334.                     line1: table.lines1[i],
  335.                     line2: table.lines2[i]
  336.                 });
  337.                 helpers.bindHoverEvent(this, i, dot, rect, o.frame, o.label);
  338.             }
  339.  
  340.             p = p.concat([x, y, x, y]);
  341.             bgpp = bgpp.concat([x, y, x, y, "L", x, height - gutter.bottom, "z"]);
  342.             o.path.attr({
  343.                 path: p
  344.             });
  345.             o.bgp.attr({
  346.                 path: bgpp
  347.             });
  348.             o.frame.toFront();
  349.             o.label[0].toFront();
  350.             o.label[1].toFront();
  351.             blanket.toFront();
  352.         },
  353.        
  354.         // Caution: this would only work for the same number of records
  355.         setDataHolder: function(id) {
  356.             var element = this,
  357.                 settings = this.lineChart.settings,
  358.                 o = this.customAttributes.lineChart,
  359.                 width = settings.width,
  360.                 height = settings.height,
  361.                 gutter = settings.gutter,
  362.                
  363.                 table = helpers.loadTableData(id),
  364.                
  365.                 X = (width - gutter.left) / table.labels.length,
  366.                 max = Math.max.apply(Math, table.data),
  367.                 Y = (height - gutter.bottom - gutter.top) / max,
  368.                
  369.                 p, bgpp;
  370.            
  371.             if (table.labels.length != o.size) {
  372.                 if (console && console.error) {
  373.                     console.error('Error: new data source has to be of same size');
  374.                     return false;
  375.                 }
  376.             }
  377.            
  378.             for (var i = 0, ii = table.labels.length; i < ii; i++) {
  379.                 var dot = o.dots[i],
  380.                     rect = o.rects[i];
  381.                
  382.                 // calculate current x, y
  383.                 y = Math.round(height - gutter.bottom - Y * table.data[i]);
  384.                 x = Math.round(gutter.left + X * (i + 0.5));
  385.                
  386.                 if (!i) {
  387.                     p = ["M", x, y, "C", x, y];
  388.                     bgpp = ["M", gutter.left + X * 0.5, height - gutter.bottom, "L", x, y, "C", x, y];
  389.                 }
  390.                 else if (i < ii - 1) {
  391.                     var Y0 = Math.round(height - gutter.bottom - Y * table.data[i - 1]),
  392.                         X0 = Math.round(gutter.left + X * (i - 0.5)),
  393.                         Y2 = Math.round(height - gutter.bottom - Y * table.data[i + 1]),
  394.                         X2 = Math.round(gutter.left + X * (i + 1.5)),
  395.                         a = helpers.getAnchors(X0, Y0, x, y, X2, Y2);
  396.                     p = p.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
  397.                     bgpp = bgpp.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
  398.                 }
  399.                
  400.                 dot.animate({cy: y},
  401.                     settings.animation.speed,
  402.                     settings.animation.easing);
  403.                
  404.                 // new popup data
  405.                 o.info[i] = {
  406.                     x: x,
  407.                     y: y,
  408.                     data: table.data[i],
  409.                     label: table.labels[i],
  410.                     line1: table.lines1[i],
  411.                     line2: table.lines2[i]
  412.                 };
  413.             }
  414.            
  415.             // animate paths
  416.             p = p.concat([x, y, x, y]);
  417.             bgpp = bgpp.concat([x, y, x, y, "L", x, height - gutter.bottom, "z"]);
  418.             o.path.animate({path: p},
  419.                     settings.animation.speed,
  420.                     settings.animation.easing);
  421.             o.bgp.animate({path: bgpp},
  422.                     settings.animation.speed,
  423.                     settings.animation.easing);
  424.            
  425.             // update x axis labels
  426.             if (settings.x_labels_step) {
  427.                 helpers.drawXLabels(element, X, height - gutter.bottom + 18,
  428.                         settings.x_labels_step, table.labels,
  429.                         settings.text.axis_labels);
  430.             }
  431.  
  432.             // draw y axis labels
  433.             if (settings.y_labels_count) {
  434.                 helpers.drawYLabels(element, gutter.left, gutter.bottom,
  435.                             height, settings.y_labels_count,
  436.                             max, gutter.top, settings.text.axis_labels);
  437.             }
  438.         }
  439.        
  440.     };
  441.    
  442.     // private methods
  443.     var helpers = {
  444.         extend: function () { // copied from jQuery source
  445.             // copy reference to target object
  446.             var target = arguments[0] || {},
  447.                 i = 1,
  448.                 length = arguments.length,
  449.                 deep = false,
  450.                 options, name, src, copy;
  451.  
  452.             // Handle a deep copy situation
  453.             if (typeof target === "boolean") {
  454.                 deep = target;
  455.                 target = arguments[1] || {};
  456.                 // skip the boolean and the target
  457.                 i = 2;
  458.             }
  459.  
  460.             // Handle case when target is a string or something (possible in deep copy)
  461.             if (typeof target !== "object" && typeof target !== "function") {
  462.                 target = {};
  463.             }
  464.  
  465.             // extend myself if only one argument is passed
  466.             if (length === i) {
  467.                 target = this;
  468.                 --i;
  469.             }
  470.  
  471.             for (; i < length; i++) {
  472.                 // Only deal with non-null/undefined values
  473.                 if ((options = arguments[i]) !== null) {
  474.                     // Extend the base object
  475.                     for (name in options) {
  476.                         if (options.hasOwnProperty(name))
  477.                         {
  478.                             src = target[name];
  479.                             copy = options[name];
  480.  
  481.                             // Prevent never-ending loop
  482.                             if (target === copy) {
  483.                                 continue;
  484.                             }
  485.  
  486.                             // Recurse if we're merging object literal values or arrays
  487.                             if (deep && copy && (copy.constructor == Object || copy.constructor == Array)) {
  488.                                 var clone = src && (src.constructor == Object || src.constructor == Array) ? src : copy.constructor == Array ? [] : {};
  489.  
  490.                                 // Never move original objects, clone them
  491.                                 target[name] = helpers.extend(deep, clone, copy);
  492.  
  493.                                 // Don't bring in undefined values
  494.                             } else if (copy !== undefined) {
  495.                                 target[name] = copy;
  496.                             }
  497.                         }
  498.                     }
  499.                 }
  500.             }
  501.  
  502.             // Return the modified object
  503.             return target;
  504.         },
  505.        
  506.         getAnchors: function(p1x, p1y, p2x, p2y, p3x, p3y) {
  507.             var l1 = (p2x - p1x) / 2,
  508.                 l2 = (p3x - p2x) / 2,
  509.                 a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
  510.                 b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y)),
  511.                 alpha, dx1, dy1, dx2, dy2;
  512.  
  513.             a = p1y < p2y ? Math.PI - a: a;
  514.             b = p3y < p2y ? Math.PI - b: b;
  515.             alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2;
  516.             dx1 = l1 * Math.sin(alpha + a);
  517.             dy1 = l1 * Math.cos(alpha + a);
  518.             dx2 = l2 * Math.sin(alpha + b);
  519.             dy2 = l2 * Math.cos(alpha + b);
  520.  
  521.             return {
  522.                 x1: p2x - dx1,
  523.                 y1: p2y + dy1,
  524.                 x2: p2x + dx2,
  525.                 y2: p2y + dy2
  526.             };
  527.         },
  528.        
  529.         loadTableData: function(table_id) {
  530.             var table = document.getElementById(table_id),
  531.                 res = {
  532.                     labels: [],
  533.                     data: [],
  534.                     lines1: [],
  535.                     lines2: []
  536.                 },
  537.                 labels, data, lines1, lines2, j;
  538.            
  539.             if (table) {
  540.                 labels = table.getElementsByTagName('tfoot')[0].getElementsByTagName('th');
  541.                 for (j=0; j < labels.length; j++) {
  542.                     res.labels.push(labels[j].innerHTML);
  543.                 }
  544.                 data = table.getElementsByClassName('data')[0].getElementsByTagName('td');
  545.                 for (j=0; j < data.length; j++) {
  546.                     res.data.push(data[j].innerHTML);
  547.                 }
  548.                 lines1 = table.getElementsByClassName('line1')[0].getElementsByTagName('td');
  549.                 for (j=0; j < lines1.length; j++) {
  550.                     res.lines1.push(lines1[j].innerHTML);
  551.                 }
  552.                 lines2 = table.getElementsByClassName('line2')[0].getElementsByTagName('td');
  553.                 for (j=0; j < lines2.length; j++) {
  554.                     res.lines2.push(lines2[j].innerHTML);
  555.                 }
  556.                 return res;
  557.             } else {
  558.                 return false;
  559.             }
  560.         },
  561.        
  562.         bindHoverEvent: function(elm, i, dot, rect, frame, label) {
  563.             var settings = elm.lineChart.settings,
  564.                 o = elm.customAttributes.lineChart,
  565.                 f_in = function() {
  566.                 var side = "right",
  567.                     info = o.info[i],
  568.                     x = info.x,
  569.                     y = info.y;
  570.                
  571.                 window.clearTimeout(elm.leave_timer);
  572.                 if (x + frame.getBBox().width > settings.width) {
  573.                     side = "left";
  574.                 }
  575.                 var ppp = elm.popup(x, y, label, side, 1);
  576.                 if (settings.mouse_coords == 'circle') {
  577.                     frame.attr({
  578.                         path: ppp.path,
  579.                         width: '200px'
  580.                     }).show();
  581.                     label[0].attr({
  582.                         text: info.line1,
  583.                         fill: settings.colors.line1,
  584.                         translation: [ppp.dx, ppp.dy]
  585.                     }).show();
  586.                     label[1].attr({
  587.                         text: info.line2,
  588.                         fill: settings.colors.line2,
  589.                         translation: [ppp.dx, ppp.dy]
  590.                     }).show();
  591.                 } else if (settings.mouse_coords == 'rect') {
  592.                     frame.show().stop().animate({
  593.                         path: ppp.path
  594.                     },
  595.                     200 * o.is_label_visible);
  596.                     label[0].attr({
  597.                         text: info.line1
  598.                     }).show().stop().animateWith(frame, {
  599.                         translation: [ppp.dx, ppp.dy]
  600.                     },
  601.                     200 * o.is_label_visible);
  602.                     label[1].attr({
  603.                         text: info.line2
  604.                     }).show().stop().animateWith(frame, {
  605.                         translation: [ppp.dx, ppp.dy]
  606.                     },
  607.                     200 * o.is_label_visible);
  608.                 }
  609.                 frame.toFront();
  610.                 label[0].toFront();
  611.                 label[1].toFront();
  612.                 this.toFront();
  613.                 dot.attr("r", 6);
  614.                 o.is_label_visible = true;
  615.         },
  616.         f_out = function() {
  617.             dot.attr("r", 4);
  618.        
  619.             elm.leave_timer = window.setTimeout(function() {
  620.                 frame.hide();
  621.                 label[0].hide();
  622.                 label[1].hide();
  623.                 o.is_label_visible = false;
  624.             },
  625.             1);
  626.         };
  627.            
  628.             rect.hover(f_in, f_out);
  629.         },
  630.        
  631.         drawXLabels: function(elm, x, y, step, labels, style) {
  632.             var settings = elm.lineChart.settings,
  633.                 o = elm.customAttributes.lineChart,
  634.                 i;
  635.            
  636.             // reset old labels
  637.             if (o.XLabels.length) {
  638.                 for (i = 0; i < o.XLabels.length; i++) {
  639.                     o.XLabels[i].remove();
  640.                 }
  641.             }
  642.    
  643.             o.XLabels = [];
  644.             for (i = 0; i < o.size; i++) {
  645.                 var label_x = Math.round(settings.gutter.left + x * (i + 0.5));
  646.                
  647.                 if (i % step === 0) {
  648.                     var l = elm.text(label_x, y, labels[i])
  649.                                 .attr(style).toBack();
  650.                     o.XLabels.push(l);
  651.                 }
  652.             }
  653.         },
  654.        
  655.         drawYLabels: function(elm, x, y, height, count, max, top, style) {
  656.             var settings = elm.lineChart.settings,
  657.                 o = elm.customAttributes.lineChart,
  658.                 step = Math.floor(max / count),
  659.                 labelHeight = (height - top - y) / count;
  660.            
  661.             // reset old labels
  662.             if (o.YLabels.length) {
  663.                 for (var i = 0; i < o.YLabels.length; i++) {
  664.                     o.YLabels[i].remove();
  665.                 }
  666.             }
  667.            
  668.             o.YLabels = [];
  669.             for (var j = 0; j <= count; j++) {
  670.                 var l = elm.text(x,
  671.                             height - y - (j * labelHeight),
  672.                             j * step).attr(style);
  673.                 o.YLabels.push(l);
  674.             }
  675.         }
  676.     };
  677.    
  678.     // go go go!
  679.     if (methods[method]) {
  680.         return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  681.     } else if (typeof method === 'object' || !method) {
  682.         return methods.init.apply(this, arguments);
  683.     } else {
  684.         if (console && console.error) {
  685.             console.error('lineChart: Method "' + method + '" not found.');
  686.         }
  687.     }
  688. };
  689.  
  690. Raphael.fn.lineChart.defaults = {
  691.     data_holder: null,      // table element holding the data to display
  692.     width: 500,             // chart width
  693.     height: 300,            // chart height
  694.     gutter: {               // gutter dimensions
  695.         top: 20,
  696.         right: 0,
  697.         bottom: 50,
  698.         left: 30
  699.     },
  700.     show_area: false,       // whether to fill the area below the line
  701.     mouse_coords: 'rect',   // way to capture mouse events
  702.     no_grid: false,         // whether to display background grid
  703.     x_labels_step: false,   // X axis: either false or a step integer
  704.     y_labels_count: false,  // Y axis: either false or a labels count
  705.     animation: {            // animation (on data source change) settings
  706.         speed: 600,
  707.         easing: "backOut"
  708.     },
  709.     colors: {               // color settings
  710.         master: '#01A8F0',
  711.         line1: '#000000',
  712.         line2: '#01A8F0',
  713.     },
  714.     text: {                 // text style settings
  715.         axis_labels: {
  716.             font: '10px Helvetica, Arial',
  717.             fill: "#000000"
  718.         },
  719.         popup_line1: {
  720.             font: 'bold 11px Helvetica, Arial',
  721.             fill: "#000000"
  722.         },
  723.         popup_line2: {
  724.             font: 'bold 10px Helvetica, Arial',
  725.             fill: "#000000"
  726.         }
  727.     }
  728. };
  729.  
  730. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement