Я работаю с набором данных, в котором есть все точки, необходимые для построения круга. Мне нужно использовать набор данных для создания кругового элемента svg path (а не svg circle).
Я пробовал следующее, что не сработало. Какие команды пути я могу использовать, чтобы путь выглядел как полный круг.
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');<!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>Дайте определение «не сработало». Связка линий выглядит как круг только в том случае, если линий много, в противном случае она выглядит как многоугольник (или десятиугольник в данном случае). Вы можете использовать curve, но закрытие требует внимания.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать метод кривой D3 для создания плавного перехода между точками.
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');<!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>Форма не похожа на идеальный круг.
Отвечая на ваш конкретный вопрос, вы хотите изменить те команды «L», которые являются командами прямой линии, на команды «A», которые являются командами рисования дуги. Формат команд «A»: A|a]rx,ry, вращение по оси x, флаг большой дуги, флаг развертки, x,y.
Это дает вам следующее в вашем случае:
<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>Майкл, извини, что вмешиваюсь. @ smpa01 Я увидел этот ответ только перед тем, как опубликовать свой собственный. Пожалуйста, считайте, что это просто ответ на ваш вопрос «Как я могу программно сгенерировать эту часть». Что касается значения радиуса, без дополнительных знаний о том, как передаются ваши данные, на это невозможно ответить.
Не беспокойтесь @ccprog. ОП может найти центр круга по трем точкам на нем. Смотрите этот вопрос: math.stackexchange.com/questions/213658/…. Тогда расстояние между любой точкой и центром даст вам радиус.
d3 не очень полезен, когда дело доходит до написания команды дуги SVG. И path.arc , и path.arcTo используют параметры, требующие повторного вычисления ваших данных, только для того, чтобы внутри вычисление можно было отменить. Проще просто написать строку атрибута напрямую.
Для этого необходимо заранее знать три значения:
radius вашего круга,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>
вы можете попробовать заменить команду L на A96,96 1 0 0, где 96, 96 — радиус окружности.