Arjun
Arjun

Reputation: 823

Ellipse drawing By using arc in d3

I want to draw a ellipse by using arc. I did it for circle but i could not make it for ellipse. Please help me for ellipse

Code For Circle

var π = Math.PI,
    τ = 2 * π,
    n = 500;

var width = 300,
    height = 200,
    outerRadius = width / 2 - 20,
    innerRadius = outerRadius - 20;

d3.select("svg").append("g")
    .attr("transform", "translate(" + width / 2 + "," + 200	 + ")")
  .selectAll("path")
    .data(d3.range(0, τ, τ / n))
  .enter().append("path")
    .attr("d", d3.svg.arc()
        .outerRadius(outerRadius)
        .innerRadius(innerRadius)
        .startAngle(function(d) { return d; })
        .endAngle(function(d) { return d + τ / n * 1.1; }))
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="960" height="960"></svg>

Upvotes: 1

Views: 1742

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101800

The D3 arc() function only generates a circular arc segment. It actually generates the outline of a solid shape based on the inner and outer radii you provide.

The only way you can transform that circular arc into an elliptical one is to scale the horizontal and vertical dimensions differently. See below.

var π = Math.PI,
    τ = 2 * π,
    n = 500;

var width = 300,
    height = 200,
    outerRadius = 1,
    innerRadius = 0.85,
    cx = 200,
    cy = 150;

d3.select("svg").append("g")
    .attr("transform", "translate(" + cx + "," + cy + ") scale(" + (width/2) + "," + (height/2) + ")")
  .selectAll("path")
    .data(d3.range(0, τ, τ / n))
  .enter().append("path")
    .attr("d", d3.svg.arc()
        .outerRadius(outerRadius)
        .innerRadius(innerRadius)
        .startAngle(function(d) { return d; })
        .endAngle(function(d) { return d + τ / n * 1.1; }))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="960" height="960"></svg>

The drawback of course is that the uneven scaling messes with the thickness of the arc. Maybe that's okay for you. If not, you should maybe expand your question with further details of what you actually are trying to achieve.

Upvotes: 2

Related Questions