Public
Edited
May 1, 2023
Fork of d3 gears
1 fork
Insert cell
Insert cell
function svgradialpath(points) {
return svg`<svg width=300 height=300><path d="${d3.lineRadial()(
points
)}" stroke="silver" fill="#efefef" stroke-width="5" transform="translate(150,150)"></svg>`;
}
Insert cell
viewof innerRadius = Inputs.range([50, 95], {
value: 85,
step: 1,
label: "inner radius"
})
Insert cell
viewof outerRadius = Inputs.range([60, 100], {value: 100, step: 1, label: "outerradius"})
Insert cell
viewof degrees = Inputs.range([20, 90], {value: 40, step: 1, label: "degrees for gear"})
Insert cell


{
// generate a notched circle to make a gear
// based on configured degrees, first half of the degree range is inner radius, second half is outer
let circle = Array.from({length: 362}, (_, i) => [
(Math.PI/180) * i,
// doesn't allow for the nice slant on the gear teeth; should be possible to calculate boundary near the transition
(i % degrees) >= degrees/2 ? innerRadius : outerRadius
])

return svgradialpath(circle);
}
Insert cell
function svgpath(path) {
return svg`<svg width=300 height=300><path d="${path}" stroke="#8c8c8c" fill="#c6c6c6" stroke-width="5" transform="translate(150,150)" stroke-linecap="round"></svg>`
}
Insert cell
(360 / 3) / 2
Insert cell
{
let nteeth = 9;
let degrees = 360 / nteeth / 2;

let outerRadius = 100;
let innerRadius = 85;
let toothAngle = 4; // how many degrees for the angle from the edge of the tooth

let path = "";
let lineRadial = d3.lineRadial();

function toRadians(d) {
return (Math.PI / 180) * d;
}
let degreesRadian = toRadians(degrees);
let toothAngleRadian = toRadians(toothAngle);

for (let i = 0; i <= 360; i += degrees) {
let startAngle = toRadians(i);
let endAngle = startAngle + degreesRadian;

let arc = d3.arc()

let mode;
if ((i / degrees) % 2 == 0) {
// odd segment: draw the outer portion
arc.startAngle(startAngle).endAngle(endAngle)
.innerRadius(outerRadius).outerRadius(outerRadius);
path += arc();
} else {
// adjust start and end by tooth angle
let innerStartAngle = startAngle + toothAngleRadian;
let innerEndAngle = endAngle - toothAngleRadian;
// draw line from outer to inner, with angle adjusted for inner
path += lineRadial([[startAngle, outerRadius], [innerStartAngle, innerRadius]]);

// draw an arc for the inner portion
arc.startAngle(innerStartAngle).endAngle(innerEndAngle)
.innerRadius(innerRadius).outerRadius(innerRadius);
path += arc();

// draw line from inner toouter, with angle adjusted for inner
path += lineRadial([[innerEndAngle, innerRadius], [endAngle, outerRadius]]);
}
}

return svgpath(path);
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more