英文:
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 = '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');
svg.append('path')
.attr('d', () => {
return d3.line().x(d => d.x).y(d => d.y)(data)
})
.attr('fill', 'none')
.attr('stroke', 'red');
<!-- language: lang-html -->
<!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>
<!-- end snippet -->
答案1
得分: 3
d3在编写SVG弧线命令时并不是特别有帮助。path.arc和path.arcTo都使用需要重新计算数据的参数,只是内部计算可以被逆转。更容易的方法是直接编写属性字符串。
这需要预先知道三个值:
- 您的圆的
半径
, largeArc
标志:弧小于半圆为0,弧长于半圆为1sweep
标志:逆时针弧为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 = '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');
<!-- language: lang-html -->
<!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>
<!-- 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 -->
<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>
<!-- 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 = '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); // [[384, 552], [440.4273842, 533.6656315] ...]
svg.append('path')
.attr('d', curve(points))
.attr('fill', 'none')
.attr('stroke', 'red');
<!-- language: lang-html -->
<!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>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论