Adjusting the location of circles generated by d3 using a time interval

As a newbie to d3 and JavaScript, I'm facing an error that is beyond my current knowledge. I have successfully generated 6 circles using a 2D array and implemented a function to increment their x and y positions by 1 in each call of a timer. However, instead of updating the positions of the initial 6 circles, the timer keeps creating an infinite loop of "NaN" circles. Below is the code snippet I am using:

<body>
    <div id="svgDiv"></div>

    <script src="~/scripts/d3/d3.min.js"></script>
    <script src="~/scripts/App/test.js"></script>

</body>

and the JavaScript part:

var windowWidth = window.innerWidth;
var windowLength = window.innerHeight;

var pos =
    [[50, 40],
    [100, 80],
    [150, 120],
    [200, 160],
    [250, 200],
    [300, 240]];

var base = d3.select("#svgDiv").append("svg")
  .attr("width", windowWidth)
  .attr("height", windowLength);

function initSetup() {

    windowWidth = window.innerWidth;
    windowLength = window.innerHeight;

    base.attr("width", windowWidth)
        .attr("height", windowLength);

    document.body.style.overflow = 'hidden';
}
window.onload = initSetup;

function windowResize() {

    windowWidth = window.innerWidth;
    windowLength = window.innerHeight;
    base.attr("width", windowWidth)
       .attr("height", windowLength);

};
window.addEventListener("resize", windowResize);

function svgDivClick() {

    base.selectAll("circle")
        .data(pos) 
        .enter()
        .append("circle")
        .attr("cx", function (d, i) {
            return pos[i][0];
        })
        .attr("cy", function (d, i) {
            return pos[i][1];
        })
        .attr("r", 0)
        .style("fill", "00ACCD")
        .transition()
        .attr("r", 20)
        .style("fill", "00ACCD")
        .duration(500);

    base.exit().transition()
        .attr("r", 0)
        .remove();

    console.log("click works");
    d3.timer(animate);
};
document.getElementById("svgDiv").addEventListener("click", svgDivClick);

function animate() {

    base.selectAll("circle")
        .data("circle", function (d) { return d; })
        .enter()
        .append("circle")
        .attr("cx", function (d, i) {
            return d.cx + 1;
        })
        .attr("cy", function (d, i) {
            return d.cy + 1;
        });

    base.exit().transition()
        .attr("r", 0)
        .remove();
};

My ultimate aim is to make the circles move randomly, but currently, I'm focusing on managing their positions. Note: The error occurs in the animate function.

I'd appreciate any insights or guidance on this issue. Thank you in advance!

Answer №1

You seem to be facing some issues here. The primary problem is that you are continuously binding the same data to the DOM elements at a rate of 60 times per second, which doesn't seem necessary. Another issue is that you are not actually incrementing the positions, but rather resetting them. Additionally, the data does not contain any cx or cy properties. Lastly, you have not declared your circles' selection.

I have created a straightforward demonstration to illustrate the usage of a d3.timer. Take note of how the position is retrieved and modified. Also, keep in mind that I have removed all transitions in this example as mixing transitions with timers can be complex and often unnecessary.

Below is the demo:

var windowWidth = 500;
var windowHeight = 300;

var positions = [
  [50, 40],
  [100, 80],
  [150, 120],
  [200, 160],
  [250, 200],
  [300, 240]
];

var svgContainer = d3.select("body").append("svg")
  .attr("width", windowWidth)
  .attr("height", windowHeight);

var circles = svgContainer.selectAll("circle")
  .data(positions)
  .enter()
  .append("circle")
  .attr("cx", function(d, i) {
    return positions[i][0];
  })
  .attr("cy", function(d, i) {
    return positions[i][1];
  })
  .attr("r", 20)
  .style("fill", "#00ACCD");

var timer = d3.timer(animate);

function animate() {

  circles.attr("cx", function() {
    if (+d3.select(this).attr("cx") > 500) {
      timer.stop()
    }
    return +d3.select(this).attr("cx") + 1
  });
};
<script src="https://d3js.org/d3.v4.min.js"></script>

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

javascript monitoring numerous socket channels for echoes

Currently, I am in the process of developing a chat application. On the server side, I am utilizing: php, laravel 5.4, and pusher. On the client side, I have incorporated vue.js along with laravel-echo. Initially, I successfully created a "public chat roo ...

Update the webpage post a database entry without relying on the setTimeout() function in Javascript

Is there a method to automatically refresh the page after a new entry in the database without relying on Javascript's setTimeout or setInterval functions? Could an AJAX function or a MySQL function accomplish this task instead? Must we continuously ...

What causes the content of my container to disappear following a setInterval div swap in Internet Explorer?

While developing a website on Chrome and Firefox, I was informed that it also needs to function properly in Internet Explorer. I managed to resolve the double padding issue in IE, but now I'm facing a new problem. The content of my "grid" disappears a ...

Tips for successfully retrieving a variable from a function triggered by onreadystatechange=function()

Combining the ajax technique with php, I'm looking to extract the return variable from the function called by onreadystatechange. A java function triggers a call to a php script upon submission, which then validates certain data in the database and r ...

Transferring data between functional components in ReactJS and dealing with the output of [object Object] or undefined

I'm struggling with passing a prop in functional components that are both located in the same .js file. I previously attempted to seek help for this issue, but unfortunately, it wasn't productive. My goal is to extract the member_id from the GET ...

"What is the best way to include additional fields within a popover in an AngularJS application

This is my code for implementing a popover using AngularJS. I am trying to figure out how to add custom styling to the popover HTML, but I am having trouble binding elements in that part of the code. <!DOCTYPE html> <html> <head> <l ...

Attempted to create registrations for two views using the identical name RCTScrollView

Having trouble running my React Native app on iOS, I keep getting an error while the Android version works perfectly fine. Does anyone have any insight on this issue? XCode 11.5, RN 0.61.5, Using React Native CLI I've searched multiple sites but hav ...

Turn off Node.js Caching for Good

My Node.js website seems to be stuck using a cached version even after updating the code and using the -w option. I need to figure out how to disable caching with Forever in Node.js and completely uninstall it. I found this answer that confirms it caches: ...

Refreshing the page allows Socket.io to establish multiple connections

I've been working on setting up a chatroom, but I've noticed that each time the page refreshes, more connections are being established. It's interesting because initially only one connection is created when I visit the chat room page. Howeve ...

Extensions for ASP.Net web application

Currently, I am working on a web application that is being developed in C# using the ASP.NET MVC framework. An important goal of mine is to provide clients with the ability to create their own plugins for this web application, with each client having its ...

Teach Google Bot how to recognize AJAX content

I'm facing a major issue while developing a website for someone else. The problem lies in the modals that are supposed to open when a user clicks on a product. My goal is to ensure that Google Bot recognizes these modals as individual pages. When a mo ...

Sending a file using Angular's $http service

I am facing an issue while trying to upload a form with an image file using the angular $http function and multer in the background for receiving. I have successfully uploaded the image via a direct form submission (without angular) as shown below: <fo ...

Modify the appearance of certain text within an input field

I need some help adding style to specific text within an input field. For example, if the user types in "Hello world" and the special text is "world" I want to achieve this result: https://i.sstatic.net/Ozd6n.png This is what my HTML code looks like: & ...

Vue.js: The chart's dataset has been refreshed

I am utilizing vue-chart.js to create a basic chart. import { Line } from 'vue-chartjs'; export default { extends: Line, mounted() { this.renderChart({ labels: [this.getChartLabels], datasets: [ { label: &a ...

"Is it possible to differentiate between a variable that is BehaviorSubject and one that is not

I am dealing with a variable that can be of type Date or BehaviorSubject<Date | null>. My concern is figuring out how to determine whether the variable is a BehaviorSubject or not. Can you help me with this? ...

Using buttons as spinners for input elements with identical styles but unique identifiers

Currently, I am in the process of developing a project that involves users. In order to display all users, I am executing a query on an SQL database. After styling the interface, I have added an input element beside each user, which initializes at zero. Ad ...

In the node.js application, the route for serving static images from the "/uploads/images" directory using express.static has been found to be dysfunctional

The following Route in my node.js server app API, deployed on the server for fetching images, is not functioning correctly app.use("/uploads/images", express.static(path.join("uploads", "images"))); However, the path below is working perfectly fine app.us ...

IE may not support the use of XMLHttpRequest with the POST method

When interacting with a server through an XMLHttpRequest to post data, the code typically follows this structure: var xhr = new XMLHttpRequest(); var url = 'http://myurl/post'; xhr.open("POST", url, true); xhr.setRequestHeader("Content-type", " ...

ASP.NET service with an added quotation mark in the JSON response!

I am trying to make a web service method call in JavaScript within an ASP.NET 3.5 environment. After inspecting the result using Firebug, I found the following: {"d":"[{\"TI\":\"www\"},{\"TI\":\"www1\"}]"} It seem ...

How to Send Javascript DOM Value to Inner HTML

I am trying to extract a value from a hidden element ID and set it as the inner HTML for another element ID. Below is my code: <script> function replaceText(){ var x=document.getElementById("mainTitle1").textContent; document.getElementById("mainTi ...