d3 v.7



https://cdn.jsdelivr.net/npm/d3@7 - библиотека d3 v.7
подключить html
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
в битриксе
Bitrix\Main\Page\Asset::getInstance()->addJs(SITE_TEMPLATE_PATH . "/js/d3.v7.min.js");

Основные методы работы
выбрать svg
var svg = d3.select("svg");
выбрать div#familyTree и в нем создать svg
var svg = d3.select("#familyTree").append("svg");
установить атрибуты svg
svg.attr("width", 1000);
svg.attr("height", 300);
или можно сразу
var svg = d3.select("#familyTree").append("svg")
   .attr("width", 1000)
   .attr("height", 300);

Шкала X
//Создание шкалы для оси X
const xScale = d3.scaleLinear()
   .domain([0, 10])   //  минимальное и максимальное значение
   .range([0, 500]); // ширина графика 


// Создание оси X
const xAxis = d3.axisBottom(xScale);

// Добавление оси X
svg.append("g")
.attr("transform", "translate(30,0)") //чтобы текст от шкалы влазил
.call(xAxis);
Шкала Y
//Создание шкалы для оси Y
const yScale = d3.scaleLinear()
   .domain([0, 100]) //  минимальное и максимальное значение
   .range([300, 0]); // // ширина графика


// Создание оси Y
const yAxis = d3.axisLeft(yScale);

// Добавление оси Y
svg.append("g")
.attr("transform", "translate(30,0)")
.call(yAxis);
Создание линии
список кривых линий

var data = [22, 25, 28, 32, 30, 28, 27];
var line = d3.line()
   .x((d, i) => xScale(i*100))
   .y(d => yScale(d*10))
   .curve(d3.curveMonotoneX); //можно не указывать, будет ломаная линия


svg.append("path")
   .datum(data)
   .attr("fill", "none")
   .attr("stroke", "blue")
   .attr("stroke-width", 2)
   .attr("transform", "translate(30,0)")
   .attr("d", line);

Создание гистограммы

data = [20, 100, 60, 40, 70];
var barWidth = 20; // Ширина столбика гистограммы

svg.selectAll("rect")
  .data(data)
  .enter()     
  .append("rect")
  .attr("width", barWidth)
  .attr("height", d => d)  
  .attr("transform", "translate(30,0)")
  .attr("x", (d, i) => barWidth * i)

Рисуем круги
data = [10, 20, 30, 40, 50];

var circles = svg.selectAll("circle")
   .data(data)   
   .enter()   
   .append("circle")
   .style("fill", "steelblue")
   .attr("r", function(d) { return (d+5); })
   .attr("cx", function(d) { return Math.random() * 1000; })
   .attr("cy", d => d*2);


Примеры работы с d3.treemap
Пример 1


файл test.csv
name,parent,value
Origin,,
rect1,Origin,112
rect2,Origin,23
rect3,Origin,11
rect4,Origin,40
rect5,Origin,300 
rect6,Origin,25
//отступы
const margin = {top: 10, right: 10, bottom: 10, left: 10},
  width = 445 - margin.left - margin.right,
  height = 445 - margin.top - margin.bottom;

// добавляем svg
const svg = d3.select("#familyTree")
   .append("svg")
     .attr("width", width + margin.left + margin.right)
     .attr("height", height + margin.top + margin.bottom)
   .append("g")
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// читаем csv
d3.csv("<?=$this->GetFolder()?>/test.csv").then(function(data) { //$this->GetFolder() - битриксовский путь к папке
     /*console.log(data); выдаст
   0: {name: 'Origin', parent: '', value: ''}
   1: {name: 'rect1', parent: 'Origin', value: '112'}
   2: {name: 'rect2', parent: 'Origin', value: '23'}
   3: {name: 'rect3', parent: 'Origin', value: '11'}
   4: {name: 'rect4', parent: 'Origin', value: '40'}
   5: {name: 'rect5', parent: 'Origin', value: '300 '}
   6: {name: 'rect6', parent: 'Origin', value: '25'}
   columns: ['name', 'parent', 'value']
   */

  // переформатирование данных
  const root = d3.stratify()
    .id(function(d) { return d.name; })   // столбец name
    .parentId(function(d) { return d.parent; })   // столбец parent
    (data);
  
  root.sum(function(d) { return +d.value })   // сумма колонок value

  // d3.treemap вычисляет положение каждого элемента иерархии
  // Координаты добавляются к корневому объекту выше
  d3.treemap()
    .size([width, height])
    .padding(4)
    (root)

  //добавляем прямоугольники
  svg
    .selectAll("rect")
    .data(root.leaves())
    .join("rect")
    .attr('x', function (d) { return d.x0; })
    .attr('y', function (d) { return d.y0; })
    .attr('width', function (d) { return d.x1 - d.x0; })
    .attr('height', function (d) { return d.y1 - d.y0; })
    .style("stroke", "#371722") //обводка
    .style("fill", "#e5e0db"); //фон

  // добавляем текст label в прямоугольники
  svg
    .selectAll("text")
    .data(root.leaves())
    .join("text")
    .attr("x", function(d){ return d.x0+15}) //координата x   
    .attr("y", function(d){ return d.y0+25}) //координата y   
    .text(function(d){ return d.data.name}) //из столбца name
    .attr("font-size", "15px") //размер шрифта
    .attr("fill", "#371722") //цвет текста
});
Пример 2

const treeData = 
     {"name": "Петр",
     "value": 15,
     "type": "black",
     "level": "blue",
     "children": [
       {
         "name": "Василий",
         "value": 10,
         "type": "grey",
         "level": "blue"
       },
       {
         "name": "Екатерина",
         "value": 10,
         "type": "grey",
         "level": "red",
         "children": [
           {
             "name": "Дмитрий",
             "value": 7.5,
             "type": "grey",
             "level": "blue"
           },
           {
             "name": "Евгений",
             "value": 7.5,
             "type": "grey",
             "level": "blue"
           },
           {
             "name": "Арсений",
             "value": 7.5,
             "type": "grey",
             "level": "blue"
           },
           {
             "name": "Валерий",
             "value": 7.5,
             "type": "grey",
             "level": "blue"
           }

         ]
       },
       {
         "name": "Мария",
         "value": 10,
         "type": "grey",
         "level": "red"
       },
       {
         "name": "Ольга",
         "value": 10,
         "type": "grey",
         "level": "red",
         "children": [
           {
             "name": "Александр",
             "value": 7.5,
             "type": "grey",
             "level": "blue"
           }
         ]
       },
       {
         "name": "Вероника",
         "value": 10,
         "type": "grey",
         "level": "red"
       }
     ]};

// размеры и отступы
const margin = {top: 20, right: 90, bottom: 30, left: 90},
      width  = 660 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

// слой дерева
const treemap = d3.tree().size([height, width]);

//  конструируем иерархические данные из treeData
let nodes = d3.hierarchy(treeData);

// узлы дерева вставляем наше дерево
nodes = treemap(nodes);


const svg = d3.select("#familyTree").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

const g = svg.append("g")
        .attr("transform","translate(" + margin.left + "," + margin.top + ")");


// соединения между узлами
const link = g.selectAll(".link")
    .data( nodes.descendants().slice(1))
    .enter().append("path")
    .attr("class", "link")
    .style("stroke", d => d.data.level)
    .attr("d", d => {
       return "M" + d.y + "," + d.x
         + "C" + (d.y + d.parent.y) / 2 + "," + d.x
         + " " + (d.y + d.parent.y) / 2 + "," + d.parent.x
         + " " + d.parent.y + "," + d.parent.x;
       });

// узлы
const node = g.selectAll(".node")
    .data(nodes.descendants())
    .enter().append("g")
    .attr("class", d => "node" + (d.children ? " node--internal" : " node--leaf"))
    .attr("transform", d => "translate(" + d.y + "," + d.x + ")");

// кружки
node.append("circle")
  .attr("r", d => d.data.value)
  .style("stroke", d => d.data.type)
  .style("fill", d => d.data.level);
  
// текст-подписи
node.append("text")
  .attr("dy", ".35em")
  .attr("x", d => d.children ? (d.data.value + 5) * -1 : d.data.value + 5)
  .attr("y", d => d.children && d.depth !== 0 ? -(d.data.value + 5) : d.data.value)
  .style("text-anchor", d => d.children ? "end" : "start")
  .text(d => d.data.name);
Если блог был полезным, можете угостить меня "чашечкой кофе" :)

Сбер по номеру телефона +7 (953) 585-13-09 Вероника.
Спасибо!