Exploring the creation of a dynamic graph with d3.js

I'm new to d3 and attempting to create a graph layout.

        var w = 1000;
        var h = 500;
        var dataset = {
            nodes: [{
                name: 'Alice'
            }, {
                name: 'David'
            }, {
                name: 'Eve'
            }],
            edges: [{
                source: 0,
                target: 1
            }, {
                source: 1,
                target: 2
            }]
        };
        var svg = d3.select("body")
            .append("svg")
            .attr("height", h)
            .attr("width", w);

        var force = d3.layout.force()
            .nodes(dataset.nodes)
            .links(dataset.edges)
            .size([w, h])
            .linkDistance([50])
            .start();

        var nodes = svg.selectAll("circle")
            .data(dataset.nodes)
            .enter()
            .append("circle")
            .attr("r", 10)
            .style("fill", "blue")
            .call(force.drag);

        var edges = svg.selectAll("line")
            .data(dataset.edges)
            .enter()
            .append("line")
            .style("stroke", "#999")
            .style("stroke-width", 2);

You can view my fiddle here: http://jsfiddle.net/username/example/

I'm having trouble getting the graph to display correctly. Any advice or suggestions would be greatly appreciated.

Answer №1

1. Ensure that the cx and cy of the circle are set in order to position it correctly. 2. Set x1, y1, x2, and y2 of the line to properly position the line.

3. To activate the layout, listen for the tick event of the force layout.

            
var w = 300;
var h = 300; 
var dataset = {
    nodes: [{
        name: 'Aden'
    }, {
        name: 'Bob'
    }, {
        name: 'Sue'
    }],
    edges: [{
        source: 0,
        target: 1
    }, {
        source: 1,
        target: 2
    }]
};
var svg = d3.select("body")
    .append("svg")
    .attr("height", h)
    .attr("width", w);

var force = d3.layout.force()
    .nodes(dataset.nodes)
    .links(dataset.edges)
    .size([w, h])
    .on("tick", tick) 
    .linkDistance([50])
    .start();

var nodes = svg.selectAll("circle")
    .data(dataset.nodes)
    .enter()
    .append("circle")
    .attr("r", 10)
    .attr("cx", function (d) {return d.x; })
    .attr("cy", function (d) { return d.y; })
    .style("fill", "red")
    .call(force.drag);

var edges = svg.selectAll("line")
    .data(dataset.edges)
    .enter()
    .append("line")
    .attr("x1", function (d) {
        return d.source.x;
    })
    .attr("y1", function (d) {
        return d.source.y;
    })
    .attr("x2", function (d) {
        return d.target.x;
    })
    .attr("y2", function (d){
        return d.target.y;
    })
    .style("stroke", "#ccc")
    .style("stroke-width", 1);

function tick(e) {
     edges.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  nodes.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

Demo Update: http://jsfiddle.net/MnX23/3/

Answer №2

When working with circles in SVG, it is important to specify the attributes cx and cy, as well as the line attributes x1,y1,x2,y2.

  • The x1 attribute determines the starting point of the line on the x-axis
  • The y1 attribute determines the starting point of the line on the y-axis
  • The x2 attribute determines the ending point of the line on the x-axis
  • The y2 attribute determines the ending point of the line on the y-axis

Feel free to test out this code:

DEMO

   var width = 1000;
        var height = 500;
        var data = {
            nodes: [{
                name: 'Aden'
            }, {
                name: 'Bob'
            }, {
                name: 'Sue'
            }],
            edges: [{
                source: 0,
                target: 1
            }, {
                source: 1,
                target: 2
            }]
        };
        var svgCanvas = d3.select("body")
            .append("svg")
            .attr("height", height)
            .attr("width", width);

        var simulation = d3.layout.force()
            .nodes(data.nodes)
            .links(data.edges)
            .size([width, height])
            .linkDistance([50])
            .start();

        var nodeElements = svgCanvas.selectAll("circle")
            .data(data.nodes)
            .enter()
            .append("circle")
            .attr("r", 10)
            .style("fill", "red")

            .call(simulation.drag);

        var edgeElements = svgCanvas.selectAll("line")
            .data(data.edges)
            .enter()
            .append("line")

            .style("stroke", "#ccc")
            .style("stroke-width", 1);

       simulation.on("tick", function() {
       edgeElements.attr("x1", function(d) { return d.source.x; })
                   .attr("y1", function(d) { return d.source.y; })
                   .attr("x2", function(d) { return d.target.x; })
                   .attr("y2", function(d) { return d.target.y; });

      nodeElements.attr("cx", function(d) { return d.x; })
                  .attr("cy", function(d) { return d.y; });
            });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to extract all image URLs from a website using JavaScript?

There are various methods to retrieve image src urls using JavaScript, such as utilizing document.images or by targeting all img elements and fetching their src attributes. However, I am currently unable to extract the image urls specified within CSS styl ...

Steps for adding custom text/symbols from a button on the textAngular toolbar

My goal is to include a button on the toolbar that allows users to insert © into the textangular editor (). However, I am struggling to grasp how to add functionality to my registered button. The examples provided by textangular for custom functionali ...

Circular arrangement using D3 Circle Pack Layout in a horizontal orientation

I'm currently experimenting with creating a wordcloud using the D3 pack layout in a horizontal format. Instead of restricting the width, I am limiting the height for my layout. The pack layout automatically arranges the circles with the largest one ...

When the user initiates a fetch request, they will be directed to the POST page as a standard

Whenever I utilize fetch for a post request, I encounter an issue where the user is not redirected to the Post page as they would be with a regular form submission. My goal is to be able to direct the user to a specific location on the server side at app ...

Connect main data to sub-component

Example Vue Structure: <Root> <App> <component> Main function in main.js: function() { axios.get('/app-api/call').then(function (resp, error) { _this.response = resp.data; }) ...

Can the parent document interact with Shadow DOM elements?

When it comes to user-created shadow DOM elements, this question focuses more on accessibility using the date input type: For instance, let's say there is a date input on a webpage. After some editing, the shadow DOM markup for this element (in Chrom ...

Inconsistencies in Height Among JQuery Elements

I am encountering an issue with my datatable.js, where I am attempting to limit its height based on a specific row number, such as 4.5 rows. However, I am facing a problem with the row height (tr height). For example, when using the following method with m ...

Unable to apply ready function in jquery .load

When the document is ready, the following code is executed: jQuery(document).ready(function(){ jQuery('#button').click(function() { jQuery('#contact_form').load("/Users/mge/Downloads/jquery-ajax-1/readme.txt"); ...

Load annotations from a JSON file with Annotator.js

Seeking assistance with incorporating annotations into my website using annotator.js. I have been encountering difficulties getting it up and running successfully. My goal is to display highlighted annotations upon page load, but I keep receiving a JavaSc ...

Remove the export statement after transpiling TypeScript to JavaScript

I am new to using TypeScript. I have a project with Knockout TS, and after compiling it (using the Intellij plugin to automatically compile ts to js), this is my sample.ts file: import * as ko from "knockout"; ko; class HelloViewModel { language: Kn ...

Clearly defined form field even with the inclusion of value=" "

I have a database that I am using to display data in an HTML form for user editing. <input type="text" id="name" placeholder="Name" required = "true" value = <?php if(isset($_SESSION['name'])) echo $_SESSION['name'] ;?>> ...

showcasing products from database with the help of Angular 12

Here are the files related to the item: Item file And here is the component file: Component file Lastly, this is the data service file: Data Service file However, issues arise when testing the code with console log statements as it indicates that the ...

What is the best way to troubleshoot substrings for accurately reading URLs from an object?

While a user inputs a URL, I am attempting to iterate through an object to avoid throwing an error message until a substring does not match the beginning of any of the URLs in my defined object. Object: export const urlStrings: { [key: string]: string } = ...

Guide on how to showcase the template by leveraging the roomList information with ngTemplateOutlet in Angular

TS roomList = [{ name: 'Room2' }] HTML <div class="Layout-body"> <ng-container *ngFor="let dt of roomList; index as i" [ngTemplateOutlet]="Room1" [ngTemplateOutletContext]="{ data: dt, i: i }&qu ...

Tabulator automatically inserted 'numrow' after retrieving the data

I have a table of undetermined information (consisting of various columns and rows). I am now at the point where I need to utilize the function table.updateData(), but this function specifically requires the column id to be present in the data structure. S ...

Can a variable declared in wdio.conf be accessed?

Within the wdio.conf file, I have implemented a function called onPrepare where I am storing all my feature files in an array. let listOfFiles = fs.readdirSync(process.cwd() + '/features'); var featureFiles = []; listOfFiles.map((file) => { ...

What is the best way to retrieve the value of a select tag in Vue JS?

Delving into Vue JS has presented me with a challenge. I'm aiming to retrieve the value of the selected option. But unfortunately, I'm stuck. Despite my efforts to scour Google for answers, I have come up empty-handed. Below is a snippet of m ...

NodeJS closes the previous server port before establishing a new server connection

During my development and testing process, whenever I make changes, I find myself having to exit the server, implement the updates, and then start a new server. The first time I run the command node server.js, everything works perfectly. However, when I m ...

Ways to set the base URL on the development server for a call to react-scripts start

I am facing an issue with configuring my primary PHP server to run the ReactJS dev server created using yarn start within a directory named /reactive on the PHP site (using nginx proxy_pass). The problem is that I cannot set the root of the node server to ...

Unsynchronized state of affairs in the context of Angular navigation

Within my Angular project, I am currently relying on an asynchronous function called foo(): Promise<boolean>. Depending on the result of this function, I need to decide whether to display component Foo or Bar. Considering my specific need, what woul ...