From 756f430c444f273cfcb3264eab26483bc811cfd7 Mon Sep 17 00:00:00 2001 From: Phyks Date: Fri, 28 Mar 2014 15:00:01 +0100 Subject: [PATCH] Rounded curve --- timeline.js | 106 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/timeline.js b/timeline.js index 4d8d845..1bc6188 100644 --- a/timeline.js +++ b/timeline.js @@ -155,19 +155,77 @@ SVG.addPoints = function (data) { } } +SVG.getControlPoints = function (data) { + // http://www.particleincell.com/wp-content/uploads/2012/06/bezier-spline.js + p1 = new Array(); + p2 = new Array(); + n = data.length - 1; + + /*rhs vector*/ + a = new Array(); + b = new Array(); + c = new Array(); + r = new Array(); + + /*left most segment*/ + a[0] = 0; + b[0] = 2; + c[0] = 1; + r[0] = data[0] + 2*data[1]; + + /*internal segments*/ + for (i = 1; i < n - 1; i++) { + a[i] = 1; + b[i] = 4; + c[i] = 1; + r[i] = 4 * data[i] + 2 * data[i+1]; + } + + /*right segment*/ + a[n-1] = 2; + b[n-1] = 7; + c[n-1] = 0; + r[n-1] = 8*data[n-1] + data[n]; + + /*solves Ax=b with the Thomas algorithm (from Wikipedia)*/ + for (i = 1; i < n; i++) { + m = a[i]/b[i-1]; + b[i] = b[i] - m * c[i - 1]; + r[i] = r[i] - m*r[i-1]; + } + + p1[n-1] = r[n-1]/b[n-1]; + for (i = n - 2; i >= 0; --i) { + p1[i] = (r[i] - c[i] * p1[i+1]) / b[i]; + } + + /*we have p1, now compute p2*/ + for (i=0;i 0) { - last_point = points[points.length - 1]; - - line = document.createElementNS(SVG.ns, 'line'); - line.setAttribute('class', 'line'); - line.setAttribute('x1', last_point[0]); - line.setAttribute('x2', x); - line.setAttribute('y1', last_point[1]); - line.setAttribute('y2', y); - line.setAttribute('stroke', '#3f72bf'); - line.setAttribute('stroke-width', 2); - SVG.g.appendChild(line); - } - points.push([x, y]); } + var px = SVG.getControlPoints(x); + var py = SVG.getControlPoints(y); + var path = ''; + for(point = 0; point < SVG.raw_points.length - 1; point++) { + path += 'C '+px.p1[point]+' '+py.p1[point]+' '+px.p2[point]+' '+py.p2[point]+' '+x[point+1]+' '+y[point+1]+' '; + } + line = document.createElementNS(SVG.ns, 'path'); + line.setAttribute('class', 'graph'); + line.setAttribute('fill', '#3f72bf'); + line.setAttribute('opacity', '0.25'); + line.setAttribute('stroke', 'none'); + line.setAttribute('d', 'M '+SVG.marginLeft+' '+SVG.marginBottom+' L '+x[0]+' '+y[0]+' '+ path + ' M '+SVG.marginLeft+' '+SVG.marginBottom+' Z'); + SVG.g.insertBefore(line, SVG.g.querySelectorAll('.point')[0]); + + line = document.createElementNS(SVG.ns, 'path'); + line.setAttribute('class', 'line'); + line.setAttribute('stroke', '#3f72bf'); + line.setAttribute('stroke-width', 2); + line.setAttribute('fill', 'none'); + line.setAttribute('d', 'M '+x[0]+' '+y[0]+' '+path); + SVG.g.appendChild(line); } var old = window.onresize || function() {}; @@ -200,7 +264,7 @@ window.onresize = function() { if(SVG.g !== false) { SVG.g.setAttribute('transform', 'translate(0, ' + SVG.holder.parentElement.offsetHeight + ') scale(1, -1)'); SVG.axis.setAttribute('x2', holder.offsetWidth - 13 - SVG.marginRight); - [].forEach.call(SVG.holder.querySelectorAll('.point, .line'), function(el) { + [].forEach.call(SVG.holder.querySelectorAll('.point, .line, .graph'), function(el) { el.parentElement.removeChild(el); }); SVG.draw();