Skip to content

Commit cf93f74

Browse files
committed
revert path interpolation
1 parent 5e128a4 commit cf93f74

1 file changed

Lines changed: 58 additions & 29 deletions

File tree

  • packages/vuetify/src/components/VSparkline/util
Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,72 @@
1-
// Types
2-
import type { Point } from '../VTrendline'
1+
// @ts-nocheck
2+
/* eslint-disable */
3+
4+
import { Point } from '../VSparkline'
5+
// import { checkCollinear, getDistance, moveTo } from './math'
36

47
/**
5-
* Catmull-Rom spline converted to cubic Bezier.
6-
* Unlike the previous corner-rounding approach, this passes through every
7-
* data point, so markers placed at point positions are always on the line.
8-
*
9-
* `smooth` controls tension: 0 = straight lines, 8 (default true) = full curve.
8+
* From https://github.com/unsplash/react-trend/blob/master/src/helpers/DOM.helpers.js#L18
109
*/
11-
export function genPath (points: Point[], smooth: number, fill = false, height = 75) {
10+
export function genPath (points: Point[], radius: number, fill = false, height = 75) {
1211
if (points.length === 0) return ''
13-
14-
const start = points[0]
12+
const start = points.shift()!
1513
const end = points[points.length - 1]
1614

17-
const prefix = fill
18-
? `M${start.x} ${height - start.x + 2} L${start.x} ${start.y}`
19-
: `M${start.x} ${start.y}`
15+
return (
16+
(fill ? `M${start.x} ${height - start.x + 2} L${start.x} ${start.y}` : `M${start.x} ${start.y}`) +
17+
points
18+
.map((point, index) => {
19+
const next = points[index + 1]
20+
const prev = points[index - 1] || start
21+
const isCollinear = next && checkCollinear(next, point, prev)
2022

21-
const suffix = fill ? `L${end.x} ${height - start.x + 2} Z` : ''
23+
if (!next || isCollinear) {
24+
return `L${point.x} ${point.y}`
25+
}
2226

23-
if (smooth === 0 || points.length < 3) {
24-
return prefix + points.slice(1).map(point => `L${point.x} ${point.y}`).join('') + suffix
25-
}
27+
const threshold = Math.min(
28+
getDistance(prev, point),
29+
getDistance(next, point)
30+
)
31+
const isTooCloseForRadius = threshold / 2 < radius
32+
const radiusForPoint = isTooCloseForRadius ? threshold / 2 : radius
33+
34+
const before = moveTo(prev, point, radiusForPoint)
35+
const after = moveTo(next, point, radiusForPoint)
36+
37+
return `L${before.x} ${before.y}S${point.x} ${point.y} ${after.x} ${after.y}`
38+
})
39+
.join('') +
40+
(fill ? `L${end.x} ${height - start.x + 2} Z` : '')
41+
)
42+
}
2643

27-
const tension = Math.min(smooth / 8, 1)
44+
function int (value: string | number): number {
45+
return parseInt(value, 10)
46+
}
2847

29-
const curves = points.slice(1).map((curr, index) => {
30-
const prev = points[index]
31-
const prevPrev = points[Math.max(0, index - 1)]
32-
const next = points[Math.min(points.length - 1, index + 2)]
48+
/**
49+
* https://en.wikipedia.org/wiki/Collinearity
50+
* x=(x1+x2)/2
51+
* y=(y1+y2)/2
52+
*/
53+
export function checkCollinear (p0: Point, p1: Point, p2: Point): boolean {
54+
return int(p0.x + p2.x) === int(2 * p1.x) && int(p0.y + p2.y) === int(2 * p1.y)
55+
}
3356

34-
const controlPoint1X = prev.x + (curr.x - prevPrev.x) * tension / 6
35-
const controlPoint1Y = prev.y + (curr.y - prevPrev.y) * tension / 6
36-
const controlPoint2X = curr.x - (next.x - prev.x) * tension / 6
37-
const controlPoint2Y = curr.y - (next.y - prev.y) * tension / 6
57+
export function getDistance (p1: Point, p2: Point): number {
58+
return Math.sqrt(
59+
Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)
60+
)
61+
}
3862

39-
return `C${controlPoint1X} ${controlPoint1Y} ${controlPoint2X} ${controlPoint2Y} ${curr.x} ${curr.y}`
40-
})
63+
export function moveTo (to: Point, from: Point, radius: number) {
64+
const vector = { x: to.x - from.x, y: to.y - from.y }
65+
const length = Math.sqrt((vector.x * vector.x) + (vector.y * vector.y))
66+
const unitVector = { x: vector.x / length, y: vector.y / length }
4167

42-
return prefix + curves.join('') + suffix
68+
return {
69+
x: from.x + unitVector.x * radius,
70+
y: from.y + unitVector.y * radius,
71+
}
4372
}

0 commit comments

Comments
 (0)