构建圆形SVG路径

huangapple go评论68阅读模式
英文:

Building circular svg path

问题

I am working with a dataset that has all the points required to build a circle. I need to utilize the dataset to build an svg path (and not svg circle) element that is circular.

我正在处理一个包含构建圆所需的所有点的数据集。我需要利用这个数据集来构建一个svg **path**元素(而不是svg circle),使其呈现为圆形。

I tried as following which did not work.
我尝试了以下方法,但没有成功。

What path commands can I use to make the path appear like a full circle.
我可以使用哪些路径命令使路径看起来像一个完整的圆。

英文:

I am working with a dataset that has all the points required to build a circle. I need to utilize the dataset to build a svg path (and not svg circle) element that is circular.

I tried as following which did not work.
What path commands can I use to make the path appear like a full circle.

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const svgns = &#39;http://www.w3.org/2000/svg&#39;;
const data = [{
	&quot;x&quot;: 384,
	&quot;y&quot;: 552
}, {
	&quot;x&quot;: 440.4273842,
	&quot;y&quot;: 533.6656315
}, {
	&quot;x&quot;: 475.3014256,
	&quot;y&quot;: 485.6656315
}, {
	&quot;x&quot;: 475.3014256,
	&quot;y&quot;: 426.3343685
}, {
	&quot;x&quot;: 440.4273842,
	&quot;y&quot;: 378.3343685
}, {
	&quot;x&quot;: 384,
	&quot;y&quot;: 360
}, {
	&quot;x&quot;: 327.5726158,
	&quot;y&quot;: 378.3343685
}, {
	&quot;x&quot;: 292.6985744,
	&quot;y&quot;: 426.3343685
}, {
	&quot;x&quot;: 292.6985744,
	&quot;y&quot;: 485.6656315
}, {
	&quot;x&quot;: 327.5726158,
	&quot;y&quot;: 533.6656315
}, {
	&quot;x&quot;: 384,
	&quot;y&quot;: 552
}];

const svg = d3.select(&#39;#viz&#39;)
	.append(&#39;svg&#39;)
	.attr(&#39;xmlns&#39;, svgns)
	.attr(&#39;viewBox&#39;, &#39;0 0 600, 600&#39;);

svg.append(&#39;path&#39;)
	.attr(&#39;d&#39;, () =&gt; {
		return d3.line().x(d =&gt; d.x).y(d =&gt; d.y)(data)
	})
	.attr(&#39;fill&#39;, &#39;none&#39;)
	.attr(&#39;stroke&#39;, &#39;red&#39;);

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;
&lt;body&gt;   
    &lt;div id=&quot;viz&quot;&gt;&lt;/div&gt;   
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

答案1

得分: 3

d3在编写SVG弧线命令时并不是特别有帮助。path.arcpath.arcTo都使用需要重新计算数据的参数,只是内部计算可以被逆转。更容易的方法是直接编写属性字符串。

这需要预先知道三个值:

  • 您的圆的半径
  • largeArc标志:弧小于半圆为0,弧长于半圆为1
  • sweep标志:逆时针弧为0,顺时针弧为1。
const svgns = 'http://www.w3.org/2000/svg';
const data = [{
    "x": 384,
    "y": 552
}, {
    "x": 440.4273842,
    "y": 533.6656315
}, {
    "x": 475.3014256,
    "y": 485.6656315
}, {
    "x": 475.3014256,
    "y": 426.3343685
}, {
    "x": 440.4273842,
    "y": 378.3343685
}, {
    "x": 384,
    "y": 360
}, {
    "x": 327.5726158,
    "y": 378.3343685
}, {
    "x": 292.6985744,
    "y": 426.3343685
}, {
    "x": 292.6985744,
    "y": 485.6656315
}, {
    "x": 327.5726158,
    "y": 533.6656315
}, {
    "x": 384,
    "y": 552
}];

const r = 96;
const largeArc = 0;
const sweep = 0;

const svg = d3.select('#viz')
    .append('svg')
    .attr('xmlns', svgns)
    .attr('viewBox', '0 0 600, 600');

svg.append('path')
    .attr('d', () => {
        return data.reduce((path, d, i) => {
            if (i) {
                path += `A${r} ${r} 0 ${largeArc}${sweep}${d.x},${d.y}`;
            } else {
                path += `M${d.x},${d.y}`;
            }
            return path;
        }, "");
    })
    .attr('fill', 'none')
    .attr('stroke', 'red');
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>

<body>
    <div id="viz"></div>
</body>

</html>

请注意,上述代码是一段JavaScript和HTML代码,用于创建SVG路径并将其添加到HTML文档中。

英文:

d3 is not really helpfull when it comes to writing the SVG arc command. Both path.arc and path.arcTo use parameters that demand recomputing your data, only so that internally the computation can be reversed. It is easier just to write the attribute string directly.

This requires the knowledge of three values in advance:

  • the radius of your circle,
  • the largeArc flag: 0 for arcs less than half a circle, 1 for arcs that are longer
  • the sweep flag: 0 for counterclockwise arcs, 1 for clockwise arcs.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const svgns = &#39;http://www.w3.org/2000/svg&#39;;
const data = [{
&quot;x&quot;: 384,
&quot;y&quot;: 552
}, {
&quot;x&quot;: 440.4273842,
&quot;y&quot;: 533.6656315
}, {
&quot;x&quot;: 475.3014256,
&quot;y&quot;: 485.6656315
}, {
&quot;x&quot;: 475.3014256,
&quot;y&quot;: 426.3343685
}, {
&quot;x&quot;: 440.4273842,
&quot;y&quot;: 378.3343685
}, {
&quot;x&quot;: 384,
&quot;y&quot;: 360
}, {
&quot;x&quot;: 327.5726158,
&quot;y&quot;: 378.3343685
}, {
&quot;x&quot;: 292.6985744,
&quot;y&quot;: 426.3343685
}, {
&quot;x&quot;: 292.6985744,
&quot;y&quot;: 485.6656315
}, {
&quot;x&quot;: 327.5726158,
&quot;y&quot;: 533.6656315
}, {
&quot;x&quot;: 384,
&quot;y&quot;: 552
}];
const r = 96;
const largeArc = 0;
const sweep = 0;
const svg = d3.select(&#39;#viz&#39;)
.append(&#39;svg&#39;)
.attr(&#39;xmlns&#39;, svgns)
.attr(&#39;viewBox&#39;, &#39;0 0 600, 600&#39;);
svg.append(&#39;path&#39;)
.attr(&#39;d&#39;, () =&gt; {
return data.reduce((path, d, i) =&gt; {
if (i) {
path += `A${r} ${r} 0 ${largeArc}${sweep}${d.x},${d.y}`;
} else {
path += `M${d.x},${d.y}`;
}
return path;
}, &quot;&quot;);
})
.attr(&#39;fill&#39;, &#39;none&#39;)
.attr(&#39;stroke&#39;, &#39;red&#39;);

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;
&lt;body&gt;   
    &lt;div id=&quot;viz&quot;&gt;&lt;/div&gt;   
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

答案2

得分: 2

Answering your specific question - you want to change those "L" commands which are straight line commands, to "A" commands which are arc draw commands. The format of "A" commands is: A|a]rx,ry, x-axis-rotation, large-arc-flag, sweep-flag, x,y

That gives you the following in your case:

<svg width="600px" height="400px" viewBox="0 200 1200 800">
  
    <path d="M384,552
        A 100,100,0, 0, 0, 440.427,533.666 
        A 100,100,0, 0, 0, 475.301,485.666 
        A 100,100,0, 0, 0, 475.301,426.334 
        A 100,100,0, 0, 0, 440.427,378.334 
        A 100,100,0, 0, 0, 384,360
        A 100,100,0, 0, 0, 327.573,378.334
        A 100,100,0, 0, 0, 292.699,426.334 
        A 100,100,0, 0, 0, 292.699,485.666
        A 100,100,0, 0, 0, 327.573,533.666
        A 100,100,0, 0, 0, 384,552  "/>
</svg>
英文:

Answering your specific question - you want to change those "L" commands which are straight line commands, to "A" commands which are arc draw commands. The format of "A" commands is: A|a]rx,ry, x-axis-rotation, large-arc-flag, sweep-flag, x,y

That gives you the following in your case:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;svg width=&quot;600px&quot; height=&quot;400px&quot; viewBox=&quot;0 200 1200 800&quot;&gt;
&lt;path d=&quot;M384,552
A 100,100,0, 0, 0, 440.427,533.666 
A 100,100,0, 0, 0, 475.301,485.666 
A 100,100,0, 0, 0, 475.301,426.334 
A 100,100,0, 0, 0, 440.427,378.334 
A 100,100,0, 0, 0, 384,360
A 100,100,0, 0, 0, 327.573,378.334
A 100,100,0, 0, 0, 292.699,426.334 
A 100,100,0, 0, 0, 292.699,485.666
A 100,100,0, 0, 0, 327.573,533.666
A 100,100,0, 0, 0, 384,552  &quot;/&gt;
&lt;/svg&gt;

<!-- end snippet -->

答案3

得分: 0

You can use the D3 curve method to create a smooth transition between points.

const svgns = 'http://www.w3.org/2000/svg';
const data = [
  { x: 384, y: 552 },
  { x: 440.4273842, y: 533.6656315 },
  { x: 475.3014256, y: 485.6656315 },
  { x: 475.3014256, y: 426.3343685 },
  { x: 440.4273842, y: 378.3343685 },
  { x: 384, y: 360 },
  { x: 327.5726158, y: 378.3343685 },
  { x: 292.6985744, y: 426.3343685 },
  { x: 292.6985744, y: 485.6656315 },
  { x: 327.5726158, y: 533.6656315 },
  { x: 384, y: 552 }
];

const svg = d3.select('#viz')
  .append('svg')
  .attr('xmlns', svgns)
  .attr('viewBox', '0 0 600, 600');

const curve = d3.line().curve(d3.curveNatural);
const points = data.map(Object.values);

svg.append('path')
  .attr('d', curve(points))
  .attr('fill', 'none')
  .attr('stroke', 'red');
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
    <div id="viz"></div>
</body>
</html>
英文:

You can use the D3 curve method to create a smooth transition between points.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const svgns = &#39;http://www.w3.org/2000/svg&#39;;
const data=[{x:384,y:552},{x:440.4273842,y:533.6656315},{x:475.3014256,y:485.6656315},{x:475.3014256,y:426.3343685},{x:440.4273842,y:378.3343685},{x:384,y:360},{x:327.5726158,y:378.3343685},{x:292.6985744,y:426.3343685},{x:292.6985744,y:485.6656315},{x:327.5726158,y:533.6656315},{x:384,y:552}];
const svg = d3.select(&#39;#viz&#39;)
.append(&#39;svg&#39;)
.attr(&#39;xmlns&#39;, svgns)
.attr(&#39;viewBox&#39;, &#39;0 0 600, 600&#39;);
const curve = d3.line().curve(d3.curveNatural);
const points = data.map(Object.values); // [[384, 552], [440.4273842, 533.6656315] ...]
svg.append(&#39;path&#39;)
.attr(&#39;d&#39;, curve(points))
.attr(&#39;fill&#39;, &#39;none&#39;)
.attr(&#39;stroke&#39;, &#39;red&#39;);

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;
&lt;body&gt;   
    &lt;div id=&quot;viz&quot;&gt;&lt;/div&gt;   
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月29日 21:58:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定