Lately I have been using D3 for visualizing data for a React project and it got my attention for a while. I was especially interested as to the scope of this very powerful tool that has a great problem solving ability range related to any kind of data visualization. It gives you a feeling that you can do . Okay, lets talk about it. __ANYTHING__ What is D3.js ? D3.js is a javascript library used for visualizing data. It is very powerful with the combination of (Support Vector Graphics) and . __SVG__ __HTML__ Now it depends on the creativity of the developer using it to actually visualize it in the most beautiful way. Since this is data driven , d3.js works on your pure data and transforms it in a graphical way. While applying d3.js, you will doing lot of CSS, at the same time solving some Mathematical Coordinate Geometry problems. For instance, applying Pythagorean theorem, calculating the distance between two coordinates ` ` and ` ` on a graph etc. (x1, y1) (x2, y2) This article focuses on creating a complex node of a graph that is a node having lot of elements or information attached to it, instead of just an empty circle. You will find so many example snippets and gists especially on , or for creating graphs or trees with version but not many on the latest version. bl.ocks.org stackoverflow observablehq v3 v5 Pre-requisite Html, CSS , Javascript, Coordinate Geometry. Let's Start We will be writing a simple working script for creating a complex SVG node. You need to include the following inside your html for using d3 library. <script> <body> v5 < > body < = > script src "https://d3js.org/d3.v5.min.js" </ > script </ > body Canvas and data container element Specify some and for the canvas where all your SVG elements will reside. We then call on element, appending to it, and specifying properties like and We currently have our json data as with some params that we may need to visualize. width height d3.select() body svg width height nodes < > script width = , height = ; nodes = [ { id: , name: , description: , connection_count: } ]; svg = d3 .select( ) .append( ) .attr( , width) .attr( , height); var 500 400 const 0 "ServiceGroup" "Port : 80" 3 const "body" "svg" "width" "height" </ > script Lets append new element into variable (canvas) and insert node data into it, indexing with . g svg id circle = svg .append( ) .selectAll( ) .data(nodes, d => d.id); g = circle.enter(); let "svg:g" "g" const Rectangular node Now we append element into our with coordinates as . rect svg (x,y) (0,0) rectangularNode = g .append( ) .attr( , ) .attr( , d => { ; }) .attr( , d => { ; }); const "svg:rect" "class" "node" "x" return 0 "y" return 0 Now here it gets tricky for deciding the positions of elements to be placed inside the rectangular node. We have our basic node ready and will place inner elements with reference to the rectangular node and not the canvas. One of the ways for doing that is to get the coordinates element using . rect getBBox() outerNodebbox = rectangularNode.node().getBBox(); var Image element Since we have placement coordinates of this box, we can place the things inside. Say I want to place below logo. It's simple images = g .append( ) .attr( , ) .attr( , { X = outerNodebbox.x; X + ; }) .attr( , { Y = outerNodebbox.y; HEIGHT = outerNodebbox.height; Y + HEIGHT / ; }); const "svg:image" "xlink:href" "https://img.icons8.com/ios-glyphs/30/000000/superman.png" "x" ( ) function d let return 10 "y" ( ) function d let let return 3 As you can see we have tweaked variables and a little bit for inner positions. I wanted the image to be in middle, tabbed ( ) from the left. X Y 10 Text element Similarly to add a text, we use the node data using keys and append to like below: text svg label = g .append( ) .attr( , ) .attr( , { outerNodebbox.width / ; }) .attr( , { outerNodebbox.height / ; }) .attr( , ) .text( { d[ ]; }); const "svg:text" "class" "name" "dx" ( ) function d return 3 "dy" ( ) function d return 3 "dominant-baseline" "central" => d return "name" Another example to add text description = g .append( ) .attr( , ) .attr( , { outerNodebbox.width / ; }) .attr( , { ( * outerNodebbox.height) / ; }) .attr( , ) .text( { d[ ]; }); const "svg:text" "class" "description" "dx" ( ) function d return 3 "dy" ( ) function d return 2 3 "dominant-baseline" "central" => d return "description" Circular counter element Now what if I want to insert a circle inside the rectangular node and maintain a text inside it. We do it as follows: count_circle = g .append( ) .attr( , ) .style( , ) .attr( , ) .attr( , { X = outerNodebbox.x; WIDTH = outerNodebbox.width; X + ( * WIDTH) / ; }) .attr( , { Y = outerNodebbox.y; HEIGHT = outerNodebbox.height; Y + ( * HEIGHT) / ; }); const "svg:circle" "class" "countCircle" "visibility" "unset" "r" 10 "cx" ( ) function d let let return 2.5 3 "cy" ( ) function d let let return 2 3 and text count_text = g .append( ) .attr( , ) .attr( , ) .attr( , { X = outerNodebbox.x; WIDTH = outerNodebbox.width; X + ( * WIDTH) / ; }) .attr( , { Y = outerNodebbox.y; HEIGHT = outerNodebbox.height; Y + ( * HEIGHT) / ; }) .attr( , ) .text( { d[ ]; }); const "svg:text" "class" "countText" "r" 10 "dx" ( ) function d let let return 2.5 3 "dy" ( ) function d let let return 2 3 "dominant-baseline" "central" => d return "connection_count" At last simply merge all the elements into one. circle = g.merge(circle); If you wonder how does it look like while browser inspecting, see for yourself. Cool right!! You can find the entire code here Happy learning!!! Previously published at https://medium.com/@afrinchakure12/a-composite-node-of-a-graph-using-d3-js-v5-146a0e0a0473