So implementieren Sie ein Topologiediagramm mit D3.js
In diesem Artikel wird hauptsächlich die Verwendung von D3.js zum Implementieren von Topologiediagrammen vorgestellt. Er hat einen gewissen Referenzwert. Jetzt kann ich ihn mit allen teilen, die ihn benötigen.
Für aktuelle Schreibprojekte sind Zeichenanwendungen erforderlich Es dauert einige Zeit, das Netzwerktopologiediagramm der Programmaufrufkette selbst zu schreiben. Als Erstes fällt mir Echarts ein, aber die benutzerdefinierte Schreibmethode von Echarts ist sehr mühsam und alle Dokumente basieren auf der Konfiguration Für die benutzerdefinierte Entwicklung war es nicht sehr praktisch, also habe ich es nach dem Ausprobieren aufgegeben und bin zu D3.js gewechselt, das vollständig unter meiner Kontrolle steht.
Werfen wir zunächst einen Blick auf den Effekt
Ich werde den Code als Referenz für Studenten weitergeben, die wie ich neu in D3 sind. Wenn Sie feststellen, dass etwas nicht stimmt, freuen wir uns über eine Korrektur!
Vollständiger Code:
html:
nbsp;html> <meta> <title>Title</title> <script> </script> <style> body{ overflow: hidden; } #togo{ width: 800px; height:500px; border:1px solid #ccc; user-select: none; } #togo text{ font-size:10px;/*和js里保持一致*/ fill:#1A2C3F; text-anchor: middle; } #togo .node-other{ text-anchor: start; } #togo .health1{ stroke:#92E1A2; } #togo .health2{ stroke:orange; } #togo .health3{ stroke:red; } #togo #cloud,#togo #database{ fill:#ccc; } #togo .link{ stroke:#E4E8ED; } #togo .node-title{ font-size: 14px; } #togo .node-code circle{ fill:#3F86F5; } #togo .node-code text{ fill:#fff; } #togo .node-bg{ fill:#fff; } #togo .arrow{ fill:#E4E8ED; } </style> <script></script> <svg> </svg> <script></script> <script> </script> <script> let t=new Togo('#togo',__options); t.render(); </script>
JS:
const fontSize = 10; const symbolSize = 40; const padding = 10; /* * 调用 new Togo(svg,option).render(); * */ class Togo { /**/ constructor(svg, option) { this.data = option.data; this.edges = option.edges; this.svg = d3.select(svg); } //主渲染方法 render() { this.scale = 1; this.width = this.svg.attr('width'); this.height = this.svg.attr('height'); this.container = this.svg.append('g') .attr('transform', 'scale(' + this.scale + ')'); this.initPosition(); this.initDefineSymbol(); this.initLink(); this.initNode(); this.initZoom(); } //初始化节点位置 initPosition() { let origin = [this.width / 2, this.height / 2]; let points = this.getVertices(origin, Math.min(this.width, this.height) * 0.3, this.data.length); this.data.forEach((item, i) => { item.x = points[i].x; item.y = points[i].y; }) } //根据多边形获取定位点 getVertices(origin, r, n) { if (typeof n !== 'number') return; var ox = origin[0]; var oy = origin[1]; var angle = 360 / n; var i = 0; var points = []; var tempAngle = 0; while (i 'marker-' + i) .attr('markerUnits', 'userSpaceOnUse') .attr('viewBox', '0 -5 10 10') .attr('refX', symbolSize / 2 + padding) .attr('refY', 0) .attr('markerWidth', 14) .attr('markerHeight', 14) .attr('orient', 'auto') .attr('stroke-width', 2) .append('svg:path') .attr('d', 'M2,0 L0,-3 L9,0 L0,3 M2,0 L0,-3') .attr('class','arrow') //数据库 let database =defs.append('g') .attr('id','database') .attr('transform','scale(0.042)'); database.append('path') .attr('d','M512 800c-247.42 0-448-71.63-448-160v160c0 88.37 200.58 160 448 160s448-71.63 448-160V640c0 88.37-200.58 160-448 160z') database.append('path') .attr('d','M512 608c-247.42 0-448-71.63-448-160v160c0 88.37 200.58 160 448 160s448-71.63 448-160V448c0 88.37-200.58 160-448 160z') ; database.append('path') .attr('d','M512 416c-247.42 0-448-71.63-448-160v160c0 88.37 200.58 160 448 160s448-71.63 448-160V256c0 88.37-200.58 160-448 160z') ; database.append('path') .attr('d','M64 224a448 160 0 1 0 896 0 448 160 0 1 0-896 0Z'); //云 let cloud=defs.append('g') .attr('id','cloud') .attr('transform','scale(0.042)') .append('path') .attr('d','M709.3 285.8C668.3 202.7 583 145.4 484 145.4c-132.6 0-241 102.8-250.4 233-97.5 27.8-168.5 113-168.5 213.8 0 118.9 98.8 216.6 223.4 223.4h418.9c138.7 0 251.3-118.8 251.3-265.3 0-141.2-110.3-256.2-249.4-264.5z') } //初始化链接线 initLink() { this.drawLinkLine(); this.drawLinkText(); } //初始化节点 initNode() { var self = this; //节点容器 this.nodes = this.container.selectAll(".node") .data(this.data) .enter() .append("g") .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }) .call(d3.drag() .on("drag", function (d) { self.onDrag(this, d) }) ) .on('click', function () { alert() }) //节点背景默认覆盖层 this.nodes.append('circle') .attr('r', symbolSize / 2 + padding) .attr('class', 'node-bg'); //节点图标 this.drawNodeSymbol(); //节点标题 this.drawNodeTitle(); //节点其他说明 this.drawNodeOther(); this.drawNodeCode(); } //画节点语言标识 drawNodeCode() { this.nodeCodes = this.nodes.filter(item => item.type == 'app') .append('g') .attr('class','node-code') .attr('transform', 'translate(' + -symbolSize / 2 + ',' + symbolSize / 3 + ')') this.nodeCodes .append('circle') .attr('r', d => fontSize / 2 * d.code.length / 2 + 3) this.nodeCodes .append('text') .attr('dy', fontSize / 2) .text(item => item.code); } //画节点图标 drawNodeSymbol() { //绘制节点 this.nodes.filter(item=>item.type=='app') .append("circle") .attr("r", symbolSize / 2) .attr("fill", '#fff') .attr('class', function (d) { return 'health'+d.health; }) .attr('stroke-width', '5px') this.nodes.filter(item=>item.type=='database') .append('use') .attr('xlink:href','#database') .attr('x',function () { return -this.getBBox().width/2 }) .attr('y',function () { return -this.getBBox().height/2 }) this.nodes.filter(item=>item.type=='cloud') .append('use') .attr('xlink:href','#cloud') .attr('x',function () { return -this.getBBox().width/2 }) .attr('y',function () { return -this.getBBox().height/2 }) } //画节点右侧信息 drawNodeOther() { //如果是应用的时候 this.nodeOthers = this.nodes.filter(item => item.type == 'app') .append("text") .attr("x", symbolSize / 2 + padding) .attr("y", -5) .attr('class','node-other') this.nodeOthers.append('tspan') .text(d => d.time + 'ms'); this.nodeOthers.append('tspan') .text(d => d.rpm + 'rpm') .attr('x', symbolSize / 2 + padding) .attr('dy', '1em'); this.nodeOthers.append('tspan') .text(d => d.epm + 'epm') .attr('x', symbolSize / 2 + padding) .attr('dy', '1em') } //画节点标题 drawNodeTitle() { //节点标题 this.nodes.append("text") .attr('class','node-title') .text(function (d) { return d.name; }) .attr("dy", symbolSize) this.nodes.filter(item => item.type == 'app').append("text") .text(function (d) { return d.active + '/' + d.total; }) .attr('dy', fontSize / 2) .attr('class','node-call') } //画节点链接线 drawLinkLine() { let data = this.data; if (this.lineGroup) { this.lineGroup.selectAll('.link') .attr( 'd', link => genLinkPath(link), ) } else { this.lineGroup = this.container.append('g') this.lineGroup.selectAll('.link') .data(this.edges) .enter() .append('path') .attr('class', 'link') .attr( 'marker-end', (link, i) => 'url(#' + 'marker-' + i + ')' ).attr( 'd', link => genLinkPath(link), ).attr( 'id', (link, i) => 'link-' + i ) .on('click', () => { alert() }) } function genLinkPath(d) { let sx = data[d.source].x; let tx = data[d.target].x; let sy = data[d.source].y; let ty = data[d.target].y; return 'M' + sx + ',' + sy + ' L' + tx + ',' + ty; } } drawLinkText() { let data = this.data; let self = this; if (this.lineTextGroup) { this.lineTexts .attr('transform', getTransform) } else { this.lineTextGroup = this.container.append('g') this.lineTexts = this.lineTextGroup .selectAll('.linetext') .data(this.edges) .enter() .append('text') .attr('dy', -2) .attr('transform', getTransform) .on('click', () => { alert() }) this.lineTexts .append('tspan') .text((d, i) => this.data[d.source].lineTime + 'ms,' + this.data[d.source].lineRpm + 'rpm'); this.lineTexts .append('tspan') .text((d, i) => this.data[d.source].lineProtocol) .attr('dy', '1em') .attr('dx', function () { return -this.getBBox().width / 2 }) } function getTransform(link) { let s = data[link.source]; let t = data[link.target]; let p = self.getCenter(s.x, s.y, t.x, t.y); let angle = self.getAngle(s.x, s.y, t.x, t.y); if (s.x > t.x && s.y t.y) { angle = -angle } return 'translate(' + p[0] + ',' + p[1] + ') rotate(' + angle + ')' } } update(d) { this.drawLinkLine(); this.drawLinkText(); } //拖拽方法 onDrag(ele, d) { d.x = d3.event.x; d.y = d3.event.y; d3.select(ele) .attr('transform', "translate(" + d3.event.x + "," + d3.event.y + ")") this.update(d); } //缩放方法 onZoom(ele) { var transform = d3.zoomTransform(ele); this.scale = transform.k; this.container.attr('transform', "translate(" + transform.x + "," + transform.y + ")scale(" + transform.k + ")") } }
Daten:
let __options={ data:[{ type:'app', name: 'monitor-web-server', time: 30, rpm: 40, epm: 50, active: 3, total: 5, code: 'java', health: 1, lineProtocol: 'http', lineTime: 12, lineRpm: 34, }, { type:'database', name: 'Mysql', time: 30, rpm: 40, epm: 50, active: 3, total: 5, code: 'java', health: 2, lineProtocol: 'http', lineTime: 12, lineRpm: 34, }, { type:'app', name: 'Redis', time: 30, rpm: 40, epm: 50, active: 3, total: 5, code: 'java', health: 3, lineProtocol: 'http', lineTime: 12, lineRpm: 34, }, { type:'cloud', name: 'ES', time: 30, rpm: 40, epm: 50, active: 3, total: 5, code: 'java', health: 1, lineProtocol: 'http', lineTime: 12, lineRpm: 34, value: 100 } ], edges: [ { source: 0, target: 3, }, { source: 1, target: 2, } , { source: 1, target: 3, }, { source: 0, target: 1, }, { source: 0, target: 2, } // { // source: 3, // target: 2, // }, ] }
Das Obige ist der gesamte Inhalt davon Ich hoffe, dass der Artikel für das Lernen aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website!
Verwandte Empfehlungen:
js verschiebt jedes Element an eine bestimmte Position
Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein Topologiediagramm mit D3.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Anleitung zum Tabellenrahmen in HTML. Hier besprechen wir verschiedene Möglichkeiten zum Definieren von Tabellenrändern anhand von Beispielen für den Tabellenrand in HTML.

Anleitung zum HTML-Rand links. Hier besprechen wir einen kurzen Überblick über HTML margin-left und seine Beispiele sowie seine Code-Implementierung.

Dies ist eine Anleitung für verschachtelte Tabellen in HTML. Hier diskutieren wir anhand der entsprechenden Beispiele, wie man eine Tabelle innerhalb der Tabelle erstellt.

Leitfaden zum HTML-Tabellenlayout. Hier besprechen wir die Werte des HTML-Tabellenlayouts zusammen mit den Beispielen und Ausgaben im Detail.

Leitfaden für HTML-Eingabeplatzhalter. Hier besprechen wir die Beispiele für HTML-Eingabeplatzhalter zusammen mit den Codes und Ausgaben.

Leitfaden zur HTML-geordneten Liste. Hier besprechen wir auch die Einführung von HTML-geordneten Listen und Typen sowie deren Beispiele

Anleitung zum Verschieben von Text in HTML. Hier besprechen wir eine Einführung, wie Marquee-Tags funktionieren, mit Syntax und Beispielen für die Implementierung.

Anleitung zum HTML-OnClick-Button. Hier diskutieren wir deren Einführung, Funktionsweise, Beispiele und Onclick-Events in verschiedenen Veranstaltungen.
