Published
Edited
Sep 30, 2019
Insert cell
md`# Smooth Random Splines`
Insert cell
start = {
const svg = d3
.select(DOM.svg(w, h))
.style('background', c.bg)
.style('width', w)
.style('height', h)
.on('click', (d, i) => {
})
const circleGroup = svg.append('g')
.attr('fill-opacity', 1)
.attr('stroke-width', 0)
const pathGroup = svg.append('g')
.attr('stroke', c.secondary)
.attr('stroke-width', 1)
.attr('fill', 'none')
const splineGroup = svg.append('g')
.attr('stroke', c.primary)
.attr('stroke-width', 2)
.attr('fill', 'none')
let points = d3.range(p)
.map(() => randomPoint())
points = points.map(({x, y}, i) => {
if (i > 0 && i < points.length - 1) {
const degrees = []
const A = points[i - 1]
const B = points[i]
const C = points[i + 1]

degrees[0] = {
p: B,
d: degree(A, B, C)
}

for (let j = 1; j < s; j++) {
const p = randomPoint()

degrees[j] = {
p,
d: degree(A, p, C)
}
}

const maxDegree = degrees.reduce((p, v) => {
return ( p.d > v.d ? p : v )
})
const text = `${Math.floor(maxDegree.d)}°`

x = maxDegree.p.x
y = maxDegree.p.y

circleGroup
.append('text')
.attr('fill', c.secondary)
.attr('x', x)
.attr('y', y)
.attr('dx', r * 1.6)
.text(text)
}

circleGroup.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('r', r)
.attr('fill', i > 0 && i < points.length -1 ? c.secondary : c.primary)


return { x, y }
})

const paths = pathGroup
.append('path')
.attr('d', d3.line()
.x(p => p.x)
.y(p => p.y)(points)
)
const splines = splineGroup
.append('path')
.attr('d', d3.line()
.x(p => p.x)
.y(p => p.y)
.curve(d3.curveBasis)(points)
)

return svg.node()
}
Insert cell
md`## Helpers`
Insert cell
Insert cell
Insert cell
md`## Parameters`
Insert cell
Insert cell
w = width
Insert cell
h = w / 16 * 9
Insert cell
b = 20
Insert cell
r = h * 0.01
Insert cell
p = 3
Insert cell
// Minimum degree
m = 60
Insert cell
// Maximum steps
s = 10
Insert cell
md`## Imports`
Insert cell
d3 = require('d3@5')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more