$.extend(Pizza, { line : function (legend) { var settings = legend.data('settings'), svg = this.svg(legend, settings), container = $(this.identifier(legend)), width = container.outerWidth(), height = container.outerHeight(), data = legend.data('graph-data'), max_x = max_y = min_x = min_y = total_x = total_y = 0, i = data.length, points = ''; for (var i = 0; i < data.length; i++) { if (data[i].x > max_x) max_x = data[i].x; if (data[i].y > max_y) max_y = data[i].y; if (min_x > data[i].x) min_x = data[i].x; if (min_y > data[i].y) min_y = data[i].y; total_x += data[i].x; total_y += data[i].y; } var existing_group = $('g[data-id=line]', svg); if (existing_group.length > 0) { var line_g = $('g[data-id=line]', svg)[0], circle_g = $('g[data-id=points]', svg)[0], polyline = $('path[data-id=path]', line_g)[0]; } else { var polyline = this.svg_obj('path'), line_g = this.svg_obj('g'), circle_g = this.svg_obj('g'); line_g.setAttribute('data-id', 'line'); circle_g.setAttribute('data-id', 'points'); polyline.setAttribute('data-id', 'path'); } for (var i = 0; i < data.length; i++) { if (existing_group.length > 0) { var circle = $('circle[data-id=c' + i + ']', circle_g)[0]; } else { var circle = this.svg_obj('circle'); circle.setAttribute('data-id', 'c' + i); } var x = (data[i].x / max_x) * width, y = (data[i].y / max_y) * height; points += x + ',' + y + ' '; this.set_attr(circle, {cx: x, cy: y,r: 0,fill: data[i.color], 'data-value': data[i].x + ', ' + data[i].y, 'data-tooltip': '', 'title': data[i].x + ', ' + data[i].y, 'class': 'has-tip tip-top'}); Snap(circle).animate({ r: 4 }, 1500, mina[settings.animation_type]); this.animate(Snap(circle), x, y, settings, 2); if (existing_group.length < 1) { circle_g.appendChild(circle); } } this.flip(circle_g, height); this.flip(line_g, height); if (settings.show_grid) { this.assemble_grid_x(svg, min_x, max_x, width, height, settings); this.assemble_grid_y(svg, min_y, max_y, width, height, settings); } var v = this.points_to_path(points); this.set_attr(polyline, {d:v, fill: 'none', stroke: 'black', 'stroke-width': 2}); if (existing_group.length < 1) { line_g.appendChild(polyline); svg.appendChild(line_g); } if (existing_group.length < 1) { svg.appendChild(circle_g); } return [legend, svg]; }, assemble_grid_x : function (svg, min, max, width, height, settings) { var existing_group = $('g[data-id=gridx]', svg); if (existing_group.length > 0) { var line_g = existing_group[0], text_g = $('g[data-id=labelx]', svg)[0]; } else { var line_g = this.svg_obj('g'), text_g = this.svg_obj('g'); line_g.setAttribute('data-id', 'gridx'); text_g.setAttribute('data-id', 'labelx'); } var ticks = this.ticks(min, max, settings.bar_intervals).reverse(), ticks_length = i = ticks.length, total_tick_width = 0, interval = width/(ticks_length-1); while (i--) { if (existing_group.length > 0) { var line = $('line[data-id=l' + i + ']', line_g)[0], text = $('text[data-id=t' + i + ']', text_g)[0]; } else { var line = this.svg_obj('line'), text = this.svg_obj('text'); line.setAttribute('data-id', 'l' + i); text.setAttribute('data-id', 't' + i); } var line_width = total_tick_width + interval; this.set_attr(line, { x1 : line_width, x2 : line_width, y1 : 0, y2 : height, stroke : 'gray', 'stroke-width' : 1, 'stroke-dasharray' : '5,5' }) .set_attr(text, { y: height + 20, x: line_width - interval, 'text-anchor': 'middle' }); if (existing_group.length < 1) { text.innerHTML = ticks[i]; text_g.appendChild(text); line_g.appendChild(line); } total_tick_width = line_width; } line_g.setAttribute('transform', 'translate(-' + interval + ', 0)'); if (existing_group.length < 1) { svg.appendChild(line_g); svg.appendChild(text_g); } }, assemble_grid_y : function (svg, min, max, width, height, settings) { var existing_group = $('g[data-id=gridy]', svg); if (existing_group.length > 0) { var line_g = existing_group[0], text_g = $('g[data-id=labely]', svg)[0]; } else { var line_g = this.svg_obj('g'), text_g = this.svg_obj('g'); line_g.setAttribute('data-id', 'gridy'); text_g.setAttribute('data-id', 'labely'); } var ticks = this.ticks(min, max, settings.bar_intervals), ticks_length = i = ticks.length, total_tick_height = 0; while (i--) { if (existing_group.length > 0) { var line = $('line[data-id=l' + i + ']', line_g)[0], text = $('text[data-id=t' + i + ']', text_g)[0]; } else { var line = this.svg_obj('line'), text = this.svg_obj('text'); line.setAttribute('data-id', 'l' + i); text.setAttribute('data-id', 't' + i); } var line_height = total_tick_height + (height/(ticks_length-1)); this.set_attr(line, { x1 : 0, x2 : width, y1 : line_height, y2 : line_height, stroke : 'gray', 'stroke-width' : 1, 'stroke-dasharray' : '5,5' }) .set_attr(text, { x : -8, y : line_height + 5, 'text-anchor': 'end' }); if (existing_group.length < 1) { text_g.appendChild(text); line_g.appendChild(line); text.innerHTML = ticks[i]; } total_tick_height = line_height; } line_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')'); text_g.setAttribute('transform', 'translate(0, -' + total_tick_height / ticks_length + ')'); if (existing_group.length < 1) { svg.appendChild(line_g); svg.appendChild(text_g); } }, points_to_path : function (points) { var points = points.split(/\s+|,/); var x0=points.shift(), y0=points.shift(); var pathdata = 'M'+x0+','+y0+'L'+points.join(' '); return ['M'+x0+','+y0+'L'].concat(points).join(' '); }, line_events : function () { $(this.scope).on('mouseenter.pizza mouseleave.pizza touchstart.pizza', '[data-line-id] li', function (e) { var parent = $(this).parent(), path = $('#' + parent.data('line-id') + ' circle[data-id="c' + $(this).index() + '"]')[0], settings = $(this).parent().data('settings'); if (/start/i.test(e.type)) { $(path).siblings('circle').each(function () { if (this.nodeName) { Snap(path).animate({ transform: 's1 1 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy') }, settings.animation_speed, mina[settings.animation_type]); } }); } if (/enter|start/i.test(e.type)) { Snap(path).animate({ transform: 's2 2 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy') }, settings.animation_speed, mina[settings.animation_type]); $(path).trigger('mouseenter') } else { Snap(path).animate({ transform: 's1 1 ' + path.getAttribute('cx') + ' ' + path.getAttribute('cy') }, settings.animation_speed, mina[settings.animation_type]); $(path).trigger('mouseout') } }); } });