Skip to content

Commit

Permalink
chore: code clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisburnell committed Feb 18, 2024
1 parent 11edb18 commit 2af1ba7
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.github
demo.html
29 changes: 1 addition & 28 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Demo of svg-sparkline Web Component" />
<title>svg-sparkline Web Component Demo</title>

<style>
@media (prefers-color-scheme: dark) {
:root {
Expand Down Expand Up @@ -82,7 +81,7 @@ <h2>Defined width and height</h2>
</p>
<h2>Server-rendered and hydrated</h2>
<p>
<svg-sparkline values="8,3,2,7,9,1,5,6,4,10,3,8,2,7,1,9" start-label="Start" end-label="End" animate="true">
<svg-sparkline values="8,3,2,7,9,1,5,6,4,10,3,8,2,7,1,9" start-label="Start" end-label="End">
<span>Start</span>
<svg width="200px" height="36px" viewBox="0 0 15 12" preserveAspectRatio="none" role="img">
<title>Sparkline ranging from 1 to 10.</title>
Expand Down Expand Up @@ -123,32 +122,6 @@ <h2>Server-rendered and hydrated</h2>
text-align: end;
}
}
@media (prefers-reduced-motion: no-preference) {
svg-sparkline[animate]:not(:defined) {
--duration: var(--svg-sparkline-animation-duration, var(--animation-duration, 1s));
--first-delay: var(--svg-sparkline-animation-first-delay, var(--svg-sparkline-animation-delay, var(--animation-delay, 1s)));
--second-delay: var(--svg-sparkline-animation-second-delay, calc(var(--duration) + var(--first-delay)));
svg:first-of-type {
clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
animation: swipe var(--duration) linear var(--first-delay) forwards;
}
svg:last-of-type,
span {
opacity: 0;
animation: fadein var(--duration) linear var(--second-delay) forwards;
}
}
}
@keyframes swipe {
to {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
}
@keyframes fadein {
to {
opacity: 1;
}
}
</style>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@chrisburnell/svg-sparkline",
"version": "1.0.5",
"version": "1.0.6",
"description": "A Web Component that builds an SVG Sparkline.",
"main": "svg-sparkline.js",
"scripts": {
Expand Down
66 changes: 35 additions & 31 deletions svg-sparkline.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class SVGSparkline extends HTMLElement {
</linearGradient>
</defs>
<path
d="${this.getPath(this.values, this.curve ? this.bezierCommand : this.lineCommand)} L ${this.getFinalX(this.values)} ${this.getAdjustedMaxY(this.values)} L 0 ${this.getAdjustedMaxY(this.values)} Z"
d="${this.getPath(this.values, this.curve)} L ${this.getFinalX(this.values)} ${this.getAdjustedMaxY(this.values)} L 0 ${this.getAdjustedMaxY(this.values)} Z"
fill="${this.fill ? gradientColor : `url('#svg-sparkline-gradient-${gradientID}')`}"
stroke="transparent"
/>
Expand All @@ -131,7 +131,7 @@ class SVGSparkline extends HTMLElement {

content.push(`
<path
d="${this.getPath(this.values, this.curve ? this.bezierCommand : this.lineCommand)}"
d="${this.getPath(this.values, this.curve)}"
stroke="${color}"
stroke-width="${this.lineWidth}"
stroke-linecap="round"
Expand Down Expand Up @@ -209,12 +209,15 @@ class SVGSparkline extends HTMLElement {
const threshold = Math.min(Math.max(Number(this.getAttribute("threshold") || 0.333), 0), 1)

if (this.hasAttribute("animate")) {
const observer = new IntersectionObserver((entries, observer) => {
if (entries[0].intersectionRatio > threshold) {
this.setAttribute("visible", true)
observer.unobserve(this)
}
}, { threshold: threshold })
const observer = new IntersectionObserver(
(entries, observer) => {
if (entries[0].intersectionRatio > threshold) {
this.setAttribute("visible", true)
observer.unobserve(this)
}
},
{ threshold: threshold }
)
observer.observe(this)
}
}
Expand All @@ -228,42 +231,41 @@ class SVGSparkline extends HTMLElement {
this.setCSS()
}

static maxDecimals(value, decimals = 2) {
maxDecimals(value, decimals = 2) {
return +value.toFixed(decimals)
}

getViewBox(values) {
return `0 0 ${values.length - 1} ${Math.max(...values) + 2}`
return `0 0 ${values.length - 1} ${this.getAdjustedMaxY(values)}`
}

lineCommand(point, i) {
return `L ${i},${point}`
}

static line(ax, ay, bx, by) {
line(ax, ay, bx, by) {
const lengthX = bx - ax
const lengthY = by - ay

return {
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
angle: Math.atan2(lengthY, lengthX)
angle: Math.atan2(lengthY, lengthX),
}
}

static controlPoint(cx, cy, px, py, nx, ny, reverse) {
// When the current is the first or last point of the array, previous and
// next don't exist. Replace with current.
controlPoint(cx, cy, px, py, nx, ny, reverse) {
// When the current X,Y are the first or last point of the array,
// previous or next X,Y don't exist. Replace with current X,Y.
px = px || cx
py = py || cy
nx = nx || cx
ny = ny || cy

const smoothing = 0.2

const o = SVGSparkline.line(px, py, nx, ny)
const line = this.line(px, py, nx, ny)

const angle = o.angle + (reverse ? Math.PI : 0)
const length = o.length * smoothing
const smoothing = 0.2
const angle = line.angle + (reverse ? Math.PI : 0)
const length = line.length * smoothing

const x = cx + Math.cos(angle) * length
const y = cy + Math.sin(angle) * length
Expand All @@ -272,20 +274,22 @@ class SVGSparkline extends HTMLElement {
}

bezierCommand(point, i, a) {
const [csx, csy] = SVGSparkline.controlPoint(i-1, a[i-1], i-2, a[i-2], i, point)
const [cex, cey] = SVGSparkline.controlPoint(i, point, i-1, a[i-1], i+1, a[i+1], true)
const [csx, csy] = this.controlPoint(i - 1, a[i - 1], i - 2, a[i - 2], i, point)
const [cex, cey] = this.controlPoint(i, point, i - 1, a[i - 1], i + 1, a[i + 1], true)

return `C ${SVGSparkline.maxDecimals(csx)},${SVGSparkline.maxDecimals(csy)} ${SVGSparkline.maxDecimals(cex)},${SVGSparkline.maxDecimals(cey)} ${i},${point}`
return `C ${this.maxDecimals(csx)},${this.maxDecimals(csy)} ${this.maxDecimals(cex)},${this.maxDecimals(cey)} ${i},${point}`
}

getPath(values, command = this.lineCommand) {
return values
// flips each point in the vertical range
.map((point) => Math.max(...values) - point + 1)
// generate a string
.reduce((acc, point, i, a) => {
return i < 1 ? `M 0,${point}` : `${acc} ${command(point, i, a)}`
}, "")
getPath(values, curve) {
return (
values
// flips each point in the vertical range
.map((point) => Math.max(...values) - point + 1)
// generate a string
.reduce((acc, point, i, a) => {
return i < 1 ? `M 0,${point}` : `${acc} ${curve ? this.bezierCommand(point, i, a) : this.lineCommand(point, i)}`
}, "")
)
}

getFinalX(values) {
Expand Down

0 comments on commit 2af1ba7

Please sign in to comment.