Skip to content

Commit

Permalink
Fixed an issue with spline tension
Browse files Browse the repository at this point in the history
  • Loading branch information
js1300 committed Jul 21, 2021
1 parent d77f618 commit cf09c90
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/bargraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ class GrapheneBargraph {
points.push(offsetIndex + i + 0.5);
points.push(dataset[this.axisMinX + i] * scale);
}
this.grapheneHelper.drawLines('lines', this.backgroundContext, points);
this.grapheneHelper.drawLines('lines', this.backgroundContext, points, this.axisMaxY);

this.backgroundContext.restore();
this.backgroundContext.stroke();
Expand Down
26 changes: 19 additions & 7 deletions src/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class GrapheneHelper {
context.fill();
}

drawLines(type, context, points) {
drawLines(type, context, points, maxY) {
if (type == 'lines') {
for (var i = 0; i < points.length; i += 2) {
context.lineTo(points[i], points[i + 1]);
Expand All @@ -106,25 +106,37 @@ class GrapheneHelper {
context.quadraticCurveTo(controlPointX2, y1, x1, y1);
}
} else if (type == 'splines') {
this.drawSpline(context, points, 0.33);
this.drawSpline(context, points, 0.33, maxY);
}
}

//http://scaledinnovation.com/analytics/splines/aboutSplines.html
getControlPoints(x0, y0, x1, y1, x2, y2, t) {
getControlPoints(x0, y0, x1, y1, x2, y2, t, maxY) {
// x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
// x2,y2 is the next knot -- not connected here but needed to calculate p2
// p1 is the control point calculated here, from x1 back toward x0.
// p2 is the next control point, calculated here and returned to become the
// next segment's p1.
// t is the 'tension' which controls how far the control points spread.
// at is adjusted tension

var at = t;
if (y1 == 0) {
if (maxY >= 100) {
at = t;
} else if (maxY <= 3) {
at = 0.01;
} else {
at = (maxY / 100) * t;
}
}

// Scaling factors: distances from this knot to the previous and following knots.
var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
var d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

var fa = t * d01 / (d01 + d12);
var fb = t - fa;
var fa = at * d01 / (d01 + d12);
var fb = at - fa;

var p1x = x1 + fa * (x0 - x2);
var p1y = y1 + fa * (y0 - y2);
Expand All @@ -136,13 +148,13 @@ class GrapheneHelper {
}

//http://scaledinnovation.com/analytics/splines/aboutSplines.html
drawSpline(ctx, pts, t) {
drawSpline(ctx, pts, t, maxY) {
var cp = []; // array of control points, as x0,y0,x1,y1,...
var n = pts.length;

// Draw an open curve, not connected at the ends
for (var i = 0; i < n - 4; i += 2) {
cp = cp.concat(this.getControlPoints(pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], t));
cp = cp.concat(this.getControlPoints(pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], t, maxY));
}

// For open curves the first and last arcs are simple quadratics.
Expand Down
4 changes: 2 additions & 2 deletions src/linegraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ class GrapheneLinegraph {
points.push(i);
points.push(dataset[this.axisMinX + i] * scale);
}
this.grapheneHelper.drawLines(this.graphDrawingMethod, this.backgroundContext, points);
this.grapheneHelper.drawLines(this.graphDrawingMethod, this.backgroundContext, points, this.axisMaxY);
this.backgroundContext.lineTo(axisRangeX, this.axisMinY);

this.backgroundContext.restore();
Expand All @@ -711,7 +711,7 @@ class GrapheneLinegraph {
points.push(i);
points.push(dataset[this.axisMinX + i] * scale);
}
this.grapheneHelper.drawLines(this.graphDrawingMethod, this.backgroundContext, points);
this.grapheneHelper.drawLines(this.graphDrawingMethod, this.backgroundContext, points, this.axisMaxY);

this.backgroundContext.restore();
this.backgroundContext.stroke();
Expand Down

0 comments on commit cf09c90

Please sign in to comment.