Canovice
Canovice

Reputation: 10481

Draw a zig-zagging circle with d3 / svg

I would like to create a circle in d3 that draws a zig-zaggy circle. This isn't a great explanation, so I drew this picture in a drawing app.

It would be great if i could control the size / number of zags (there should be more than i drew in this picture, maybe 50 - 100 instead of 15 - 20).

enter image description here Thanks in advance on this!

Upvotes: 2

Views: 409

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102218

For that task I'd use d3.lineRadial, which:

Constructs a new radial line generator with the default settings. A radial line generator is equivalent to the standard Cartesian line generator, except the x and y accessors are replaced with angle and radius accessors

This is how the generator would look like (for the data structure used in the demo below, made of an array of arrays):

const generator = d3.lineRadial()
    .angle(d => d[0])
    .radius(d => d[1])

Which given the demo data can be even simpler, just:

const generator = d3.lineRadial();

And here is a demo:

const svg = d3.select("svg")
  .append("g")
  .attr("transform", "translate(100,50)");
const data = d3.range(51).map(d => [(Math.PI * 2) / (50 / d), d % 2 ? 40 : 50]);
const generator = d3.lineRadial()
const path = svg.append("path")
  .attr("d", d3.lineRadial()(data))
path {
  fill: none;
  stroke: black;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>

In this demo, the number of zigzags and the size of the circle is controlled by the data. For instance, less zigzags and a bigger distance between the inner and outer radiuses:

const svg = d3.select("svg")
  .append("g")
  .attr("transform", "translate(100,70)");
const data = d3.range(27).map(d => [(Math.PI * 2) / (26 / d), d % 2 ? 30 : 70]);
const generator = d3.lineRadial()
const path = svg.append("path")
  .attr("d", d3.lineRadial()(data))
path {
  fill: none;
  stroke: black;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>

PS: this does not create a <circle> element, which obviously would never have zigzags, but a <path> element instead.

Upvotes: 2

Related Questions