Mastering the Art of Page Scrolling with d3

I would like to implement a scrolling effect for my d3 that allows the entire page to scroll while panning, similar to the effect on challonge (http://challonge.com/tournaments/bracket_generator?ref=OQS06q7I5u). However, I only want the scrolling to occur along the y-axis.

Here is my current attempt at achieving this:

pan.call(d3.drag().on("drag", function dragged() {
        // x axis
        thisPosX += d3.event.dx;
        g.attr("transform", "translate(" + thisPosX + ", 0)");
        g1.attr("transform", "translate(" + thisPosX + ", 0)");
        position.x = thisPosX;
        // y axis.
        var tmp = d3.event.dy;
        if (tmp != -lastTmp) {
            $window.scrollTo(0, $window.scrollY - tmp);
            lastTmp = tmp;
        }
}));

However, this code seems to cause lag and some spikes during the panning process. Are there any alternative methods or better ways to achieve this effect? By the way, I am using Angular.

Answer №1

I don't think you need to rely on d3 for what you're attempting to accomplish. While it is possible to bind events using d3, the drag behavior in question is specifically designed for dragging elements within a static container such as a canvas or SVG.

Fortunately, I came across this Codepen example that might serve your needs.

To achieve this, my suggestion would be to wrap your SVG inside a div element that possesses the necessary drag behavior. This approach was taken by Challonge, and you can reference their source code shown below: https://i.stack.imgur.com/DiuGO.png

Next, implement a scroll on drag behavior. To achieve this, I've adapted the previous Codepen example to utilize d3:

var curYPos = 0;
var curDown = false;

var scrollable = d3.select('#scrollable');
scrollable.on('mousemove', function () {
  // Scroll only if mouse button is down
  if (curDown === true){
    // Scroll only along the Y-axis
    // d3.mouse(this) represents the cursor position inside your scrollable element (this)
    window.scrollTo(0, document.body.scrollTop + (curYPos - d3.mouse(this)[1]));
  }
});

scrollable.on('mousedown', function () {
  curDown = true;
  curYPos = d3.mouse(this)[1];
});
scrollable.on('mouseup mouseleave', function () {
  curDown = false;
});

To see a live demonstration of this scroll on drag behavior, you can check out the following Demo.

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

Accessing a precise div element in a webpage

Currently, I am utilizing Vue.js and Nuxt for my web development. One issue I am facing is related to anchors. Specifically, when I navigate to mysite.com/page1#section1, I want the page to scroll to section1. In my code, I have the following snippet: < ...

Utilizing Azure SDK to send an email

In my Node.js project, I am currently utilizing azure-graph: const MsRest = require('ms-rest-azure'); const credentials = await MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId, { tokenAudience: 'graph' } ...

Sending data using Ajax to the server-side code in ASP.NET

Struggling to successfully pass a series of values through Ajax to a code-behind method in order to insert the data into a database table. However, encountering issues where string variables are being received as empty strings and int variables as 0. The ...

Loading large amounts of data efficiently with Angular and Firebase

Currently, I am utilizing AngularJS in conjunction with Firebase. Objective: My aim is to showcase all the information stored within my Firebase database (which consists of a fixed number of approximately 1600 items). Challenge: The issue at hand is that ...

How to use AJAX script to call a non-static page method in ASP.NET

Is it possible to achieve this task without utilizing the UpdatePanel feature? ...

Looking for assistance with jqGrid

Is there a method to confirm if the grid has finished loading using a separate function? My goal is to automatically click on the first row and move that row to the second grid once this action occurs. jQuery("#search_grid").jqGrid('setGridParam&apo ...

elevate the div with a floating effect

My goal is to create a chat feature for users that will only be visible for a limited time period. I was thinking of using PHP and timestamp to achieve this functionality, but I also want to make the chat visually disappear by having the message div float ...

How to Handle Empty Input Data in JQuery Serialization

Having an issue with a form that triggers a modal window containing another form when a button is clicked. The second form includes an input field and send/cancel buttons. The goal is to serialize the data from the modal form and send it to a server using ...

In pursuit of increased speed

When using $routeProvider in Angular, I have noticed that every time I navigate to a specific route, I see the following logs in the console: XHR finished loading: "http://localhost:8080/root/partials/view1.html". XHR finished loading: "http://localhost:8 ...

Comparing Two Arrays in AngularJS and Disabling on Identical Cases

I currently have two tables: "Available subject" and "Added subject" which are populated by ng-repeat with two separate lists of objects. My objective is to accomplish three things: 1 - When the user clicks on the plus sign, a row with identical content s ...

The process of creating a React build varies greatly from the initial development phase

Thank you for offering to help me! After building my React web app, it looks very different from development mode. I use serve -s build to monitor the app build. However, even on my online DigitalOcean server, it doesn't appear the same as in develop ...

What events precede and follow a keydown action in a Textarea field?

I need to prevent users from pressing function keys (F1, F2, etc.), the tab key, and any other characters from being added. The code below is supposed to achieve this on my website but it's not working. document.getElementById("code").addEventList ...

CanvasJS showcasing a variety of pie charts

I need to generate multiple pie charts for a website, but I'm struggling with the idea of dynamically rendering them based on the required quantity. I know that I will have to create a maximum of 28 pie charts at once. My initial approach involves man ...

Guide on how to gather values into a variable from the DOM using jQuery

Trying to make this function: The current issue I'm facing is that when changing a digit (by clicking on a hexagon), I want to save the selected number as the value of a hidden input field next to the digit in the DOM. Any ideas on how to achieve th ...

Obtain the date in ISO format without subtracting the timezone offset

I need to obtain a Date string without the timezone being added or subtracted. Currently, when I set my OS timezone to GMT +13 and create a new Date() object, the toISOString() method subtracts one day. For example, today is 11/02. If I adjust my OS time ...

What is the best approach to tackle this design?

As a newcomer to React, I'm facing challenges in positioning components. The layout I envision is consistent across all pages, with certain elements remaining the same. Should I utilize a grid system for this design? How should I approach achieving th ...

What strategies can I use to ensure that I can successfully send 3,000 requests to the Google Drive API using node.js without surpassing

I'm currently assisting a friend with a unique project he has in mind. He is looking to create 3000 folders on Google Drive, each paired with a QR code linking to its URL. The plan is to populate each folder with photos taken by event attendees, who ...

Loading images dynamically in ReactJS allows for a seamless and customized user experience

I've been trying to dynamically fetch images from my images folder based on data retrieved from the database. Despite searching through numerous resources, I'm still struggling to crack this issue. Check out my code snippet below: import sword fr ...

Using Angular.js version 1.6.9, you can dynamically apply a class based on a condition by utilizing the

I am attempting to use ng-class in order to implement conditional styling within an ng-repeat. The condition is supposed to be based on the evaluation of a string within an object data. I am working to apply bold formatting to the 3rd item using this code ...

It seems that there is a null value being returned in the midst of the

I have developed a model using express. While setting this in one function, it returns null in another function, forcing me to use return. What is the proper method to handle this situation? const Seat = function(seat) { this.seat = seat.seat; this. ...