Создание кругового пути svg

Я работаю с набором данных, в котором есть все точки, необходимые для построения круга. Мне нужно использовать набор данных для создания кругового элемента 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>

вы можете попробовать заменить команду L на A96,96 1 0 0, где 96, 96 — радиус окружности.

enxaneta 29.06.2023 16:21

Дайте определение «не сработало». Связка линий выглядит как круг только в том случае, если линий много, в противном случае она выглядит как многоугольник (или десятиугольник в данном случае). Вы можете использовать curve, но закрытие требует внимания.

Dave Newton 29.06.2023 16:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
61
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать метод кривой 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>

Форма не похожа на идеальный круг.

smpa01 29.06.2023 16:57

Отвечая на ваш конкретный вопрос, вы хотите изменить те команды «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 29.06.2023 18:29

Не беспокойтесь @ccprog. ОП может найти центр круга по трем точкам на нем. Смотрите этот вопрос: math.stackexchange.com/questions/213658/…. Тогда расстояние между любой точкой и центром даст вам радиус.

Michael Mullany 30.06.2023 13:17
Ответ принят как подходящий

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>

Другие вопросы по теме