manymanymore
manymanymore

Reputation: 3109

Can not draw a rounded rect in svg using d3.js

Here is my code:

var svg = d3.select("#drawRegion")
                .append("svg");

svg
	.attr("width", "100%")
  .attr("height", "100%")
  .attr("viewBox", "0 0 400 100");
  

var roundedPath = svg
								.append("path");

var path = "M0 100 L0 0 L300 0 A100 100 0 0 0 0 300 100 Z"

roundedPath
				.attr("d", path)
        .attr("fill", "none")
        .attr("stroke-width", "2px")
        .attr("stroke", "#000");
#drawRegion {
    width: 400px;
    height: 100px;
    display: inline-block;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    position: relative;
}
<div id="drawRegion">

</div>
<script src="https://d3js.org/d3.v5.min.js"></script>

I did everything according to the documentation and I am expecting to get the rectangle which has the right lower corner rounded. But what I am getting is some strange shape.

According to this the solution might have been to change large-arc-flag, sweep-flag values, I tried all 4 possible combinations of 0 and 1, but still some strange shapes appear.

What am I doing wrong here?

Upvotes: 0

Views: 1641

Answers (3)

Paul LeBeau
Paul LeBeau

Reputation: 101820

There are a few things wrong:

  1. You had too many values in your Arc (A) command.
  2. Your arc end coordinates were wrong. You need to sweep around from 300,0 to 200,100 (not 300,100).
  3. Your sweep flag was wrong. It needed to be "1" (clockwise).

var svg = d3.select("#drawRegion")
                .append("svg");

svg
  .attr("width", "100%")
  .attr("height", "100%")
  .attr("viewBox", "0 0 400 100");
  

var roundedPath = svg
                    .append("path");

var path = "M0 100 L0 0 L300 0 A100 100 0 0 1 200 100 Z"

roundedPath
        .attr("d", path)
        .attr("fill", "none")
        .attr("stroke-width", "2px")
        .attr("stroke", "#000");
#drawRegion {
    width: 400px;
    height: 100px;
    display: inline-block;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    position: relative;
}
<div id="drawRegion">

</div>
<script src="https://d3js.org/d3.v5.min.js"></script>

Upvotes: 3

Mark
Mark

Reputation: 108517

If you inspect the debug console, you'll see the following error:

Error: attribute d: Expected number, "…0 0 0 0 300 100 Z"

Essentially this is telling your your d attribute is mal-formed. The A (arc) has too many parameters (you have an extra 0). Fixing that you'll still see your shape is a bit wonky. It should be:

var svg = d3.select("#drawRegion")
                .append("svg");

svg
	.attr("width", "100%")
  .attr("height", "100%")
  .attr("viewBox", "0 0 400 100");
  

var roundedPath = svg
								.append("path");

var path = "M0 100 L0 0 L300 0 A100 100 0 0 1 300 100 Z"

roundedPath
				.attr("d", path)
        .attr("fill", "none")
        .attr("stroke-width", "2px")
        .attr("stroke", "#000");
 
#drawRegion {
    width: 400px;
    height: 100px;
    display: inline-block;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    position: relative;
}
<div id="drawRegion">

</div>
<script src="https://d3js.org/d3.v5.min.js"></script>

Upvotes: 2

Vikas Kumar
Vikas Kumar

Reputation: 11

use this link

https://bl.ocks.org/mbostock/3468167

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  margin: auto;
  width: 960px;
}

path {
  fill: #ccc;
  stroke: #000;
  stroke-width: 1.5px;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500)
  .append("g")
    .attr("transform", "translate(480,250)");

var rect = svg.append("path")
    .attr("d", rightRoundedRect(-240, -120, 480, 240, 20));

// Returns path data for a rectangle with rounded right corners.
// Note: it’s probably easier to use a <rect> element with rx and ry attributes!
// The top-left corner is ⟨x,y⟩.
function rightRoundedRect(x, y, width, height, radius) {
  return "M" + x + "," + y
       + "h" + (width - radius)
       + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
       + "v" + (height - 2 * radius)
       + "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
       + "h" + (radius - width)
       + "z";
}

</script>

Upvotes: -2

Related Questions