Как нарисовать такую фигуру на D3?

161
29 января 2020, 08:00

Подскажите, как её нарисовать не используя две фигуры. Так же известен радиус, высота и расстояние между верхней точкой окружности и верхним ребром прямоугольника.

Моя реализация:

this.svg.append("circle")      
    .attr("cx", 45)           
    .attr("cy", 299)           
    .attr("r", 35)
    .style("stroke", "green")
    .attr('fill', 'none')
    .attr('stroke-width', 3);
this.svg.append('rect')
    .attr('x', 10) 
    .attr('y', 300) 
    .attr('width',70) 
    .attr('height', 70)
    .attr('stroke', 'green')
    .attr('fill', 'white')
    .style("stroke", "green")
    .attr('stroke-width', 3);

Answer 1

D3 тут весьма сбоку и пригодится только доля DOM манипуляций.

Все что необходимо, это составить примерно вот такой path

<path d="M200,100v100h-100v-100A50,50,0,0,1,200,100">.

Перечислю все команды в порядке их использования в пути:

M100,100 идем в точку 200 100

v100 чертим вертикальную линию на 100 вниз от текущей точки

h-100 чертим горизонтальную линию на 100 влево от текущей точки

v-100 чертим вертикальную линию на 100 вверх от текущей точки

A50,50,0,0,1,200,100 чертим дугу радиусом по x и по y равным 50 и с окончанием в точке 200 100

Аргументы команды arc: rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y

Вот иллюстрация как работают 3 флага в аргументах дуги (x-axis-rotation, large-arc-flag, sweep-flag)

shape(35, 100, 30, 60);     
shape(125, 100, 30, 90);   
shape(235, 100, 50, 60); 
shape(325, 100, 10, 60);  
shape(375, 100, 10, 160);  
shape(475, 100, 35, 110);  
 
// x центра, y центра, радиус, общая высота 
function shape(cx, cy, r, h) { 
   
  let dy = cy + r/2 - h/2; 
   
  let d = ` 
    M${cx+r},${dy} 
    v${h} h${-r*2} v${-h} 
    a${r},${r},0,0,1,${r*2},0  
  `; 
 
  svg = d3.select('svg'); 
 
  svg.append("path")       
      .attr("stroke", "green") 
      .attr('fill', 'none') 
      .attr('stroke-width', 3) 
      .attr('d', d); 
   
  // все ниже нужно только для подсказок 
  svg.append('path') 
     .attr("stroke", "red") 
     .attr('fill', 'none') 
     .attr('marker-start','url(#triangle2r)') 
     .attr('marker-end','url(#triangle1r)') 
     .attr('d', `M${cx},${dy},v${h}`) 
   
  svg.append('path') 
     .attr("stroke", "blue") 
     .attr('fill', 'none') 
     .attr('marker-end','url(#triangle1b)') 
     .attr('marker-start','url(#triangle2b)') 
     .attr('d', `M${cx},${dy},l${Math.cos(1)*r},-${Math.sin(1)*r}`) 
   
  svg.append('circle') 
     .attr('cx', cx) 
     .attr('cy', cy) 
     .attr('r', 2) 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 
<svg viewBox="0 0 600 200" height="90vh"> 
   <defs> 
    <marker id="triangle1r" viewBox="0 0 10 10" refX="9" refY="5"  
          markerWidth="5" markerHeight="5" orient="auto"> 
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#f00"/> 
    </marker> 
    <marker id="triangle2r" viewBox="0 0 10 10" refX="1" refY="5"  
          markerWidth="5" markerHeight="5" orient="auto"> 
      <path d="M 10 0 L 0 5 L 10 10 z" fill="#f00"/> 
    </marker> 
    <marker id="triangle1b" viewBox="0 0 10 10" refX="9" refY="5"  
          markerWidth="5" markerHeight="5" orient="auto"> 
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#00f"/> 
    </marker> 
    <marker id="triangle2b" viewBox="0 0 10 10" refX="1" refY="5"  
          markerWidth="5" markerHeight="5" orient="auto"> 
      <path d="M 10 0 L 0 5 L 10 10 z" fill="#00f"/> 
    </marker> 
</defs>  
</svg>

Вспомогательные маркеры:

Синяя линия - r, красная - h, точка - центр фигуры

READ ALSO
Выравнивание window.open() окна по центру монитора

Выравнивание window.open() окна по центру монитора

Открываю на сайте всплывающее окно, токо оно открывается в левом верхнем углуwindow

194
Как преобразовать объект массива

Как преобразовать объект массива

Необходимо изменить структуру из такой:

144
Ошибка при подключении к MySQL 8.0.15-a2

Ошибка при подключении к MySQL 8.0.15-a2

У меня возникла проблема с MySQL я недавно ее поставил настроил и вот тут уже проблема с коннектором Внимание Phpmyadmin работает без проблем а коннект...

158
Mysql выборка иерархии

Mysql выборка иерархии

не могли бы вы помочь написать рекурсивный запрос на выбор данных из одной единственной таблицы ? (Без использования PHP)

184