https://cdn.jsdelivr.net/npm/d3@7 - библиотека d3 v.7 |
<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"); |
var svg = d3.select("#familyTree").append("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 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
![](https://nikaverro.ru/upload/medialibrary/ec0/ubtnn5ymfy6oe7upfo2ngxa2pw14cyy8.png)
файл 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") //цвет текста }); |
![](https://nikaverro.ru/upload/medialibrary/cf6/29we237c6u1s8qj9zerch010dsfm5dwv.png)
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); |