Как добавить заполненные разделы в круги SVG с помощью d3.js - PullRequest
5 голосов
/ 29 июня 2019

Я генерирую несколько SVG-кругов, используя d3.js. Я могу их сгенерировать, но не могу понять, как разделить их на 4 равных раздела и покрасить каждый раздел. Я использую версию 4 d3.js.

Вот фрагмент моего javascript из моей скрипки:

var nodes = [

  {"type":'family',"id":'f1',"name":'', "image":""},
  {"type":'person',"id":'p1',"name":'fred flintstone',"age": 39, "relationship": "father","sex":' '},
  {"type":'person',"id":'p2',"name":'wilma flintstone',"age": 36, "relationship": "mother","sex":'m'},
  {"type":'person',"id":'p3',"name":'pebbles flintstone',"age": 4 , "relationship": "daughter","sex":'mf'},
  {"type":'person',"id":'p4',"name":'dino',"age": 8 ,"relationship": "pet","sex":'m'},


  {"type":'family',"id":'f3',"name":'', "image":""},
  {"type":'person',"id":'p5',"name":'barney rubble',"age": 43, "relationship": "father","sex":'m'},
  {"type":'person',"id":'p6',"name":'betty rubble',"age": 41, "relationship": "mother","sex":'f'},
  {"type":'person',"id":'p7',"name":'bam bam rubble',"age": 4, "relationship": "son","sex":'m'},


]

//more code in my fiddle

  my.width = function(value) {
    if (!arguments.length) return width;
    width = value;
    return my;
  };

  my.nodes = function(value) {
    if (!arguments.length) return nodes;
    nodes = value;
    return my;
  };

  my.links = function(value) {
    if (!arguments.length) return links;
    links = value;
    return my;
  };

  my.height = function(value) {
    if (!arguments.length) return height;
    height = value;
    return my;
  };

  return my;
}

Большое спасибо заранее.

https://jsfiddle.net/pqk8y3mb/

1 Ответ

8 голосов
/ 02 июля 2019

Я бы рекомендовал вручную рисовать дуги с помощью path .

SVG

Во-первых, вот рабочий пример с дополнениями: https://jsfiddle.net/mztafs0w/


Пояснение:

SVG Path имеет такие команды, как M для M ove, A для A rc, L для отрисовки L in to:

  • Заглавные буквы - абсолютные движения пикселей
  • Строчные буквы - относительные перемещения пикселей

Чтобы создать заполненный круговой фрагмент с использованием SVG-пути, необходимо выполнить следующие действия:

How to draw an arc источник изображения


Допустим, ваш радиус равен 40, и вы хотите срез для верхнего правого квадранта. Вся команда для этого будет:

  • Переместить X (0) Y (-40) - перейти наверх
  • Дуга Радиус X (40) Радиус Y (40) XRot (0)> 180 градусов? (0) Размах (1) X (40) Y (0) - дуга направо
  • Линия X (0) Y (0) - возврат в центр

Сжатый в формат пути SVG, это выглядит как:

M 0 -40 A 40 40 0 0 1 40 0 L 0 0 (минимально M0,-40A40,40,0,0,1,40,0L0,0)

Выполнить это 4 раза, чтобы получить все 4 квадранта, достаточно просто, а замена радиуса на $ {r} позволяет легко настроить размер.

Окончательный код, добавленный к вашей скрипте JS:

var slices=[];
  slices[0] = node.append("path")
  .attr("d", function(d) {
    let r = d.type == "family" ? family_radius + 5 : 40;
    return `M 0 -${r} A ${r} ${r} 0 0 1 ${r} 0 L 0 0`; } )
  .attr("fill", "coral");
slices[1] = node.append("path")
    .attr("d", function(d) {
    let r = d.type == "family" ? family_radius + 5 : 40;
    return `M ${r} 0 A ${r} ${r} 0 0 1 0 ${r} L 0 0`; } )
  .attr("fill", "royalblue");
slices[2] = node.append("path")
  .attr("d", function(d) {
    let r = d.type == "family" ? family_radius + 5 : 40;
    return `M 0 ${r} A ${r} ${r} 0 0 1 -${r} 0 L 0 0`; } )
  .attr("fill", "olivedrab");
slices[3] = node.append("path")
  .attr("d", function(d) {
    let r = d.type == "family" ? family_radius + 5 : 40;
    return `M -${r} 0 A ${r} ${r} 0 0 1 0 -${r} L 0 0`; } )
  .attr("fill", "goldenrod");

Рекомендую удалить нерабочий раздел descriptionArc и сделать код более DRY . Вы можете выполнить больше вычислений, чтобы ломтики круга ломались в местах, отличных от 0/90/180/270. Дайте мне знать, если вам нужна помощь с любым из них, или вы можете проверить источник изображения для получения дополнительных советов.

Я также изменил family_radius на family_radius + 5, чтобы вы могли видеть дуги, нарисованные под белой заливкой этих меньших кругов. Если это нежелательно, вы можете либо удалить белую заливку на этих кружках (строка 165 if(d.type == "family"){return "white"}), либо просто вообще не рисовать эти кусочки для этих кружков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...