Utilize d3.behavior.zoom to target and zoom in on a particular group ID, while also retrieving the bounding box

I'm currently working on creating an interactive pan/zoom SVG floorplan/map by utilizing the d3.behavior.zoom() feature. My code is inspired by the concept of Zoom to Bounding Box II.

My approach involves asynchronously loading an SVG using $.get() and then employing a button.on('click') function to retrieve the bounding box (.getBBox()) of a specific <g> element with the ID #g-1101 (depicted as a red circle in the SVG). I aim to center the viewport of the SVG on the midpoint of the bounding box of #g-1101.

In my initial attempts, I tried to shift the top-level svg > g element by using the

.getBBox().x && .getBBox().y
values of g#1101. However, it appears there might be an error in my calculations.

Furthermore, I experimented with formulas like

(svg.node().getBBox().width / 2) - scale * g.getBBox().x)
to align the center of the bounding box with the viewport, but the translation seems to be way off.

Code

(function(){

 var svg, g; $.get('http://layersofcomplexity.com/__fp.svg', function(svg){
   $('body').append($(svg));
   init();
  },'text');

  function init() {

    console.log('init');

   svg = d3.select('svg');
   g = d3.select('svg > g');

    var zoom = d3.behavior.zoom()
    .translate([0, 0])
    .scale(1)
    .scaleExtent([1, 8])
    .on("zoom", zoomed);

    svg
    .call(zoom)
    .call(zoom.event);

    $('.pan').on('click', function(){
//       var id = '#g-1011';
      var scale = 4;
      var bbox = $('#g-1101')[0].getBBox(); 
//       d3.select(id).node().getBBox();
      var x = bbox.x;
      var y = bbox.y;
      // var scale = .9 / Math.max(dx / width, dy / height),
      // var translate = [width / 2 - scale * x, height / 2 - scale * y];
      var width = svg.node().getBBox().width;
      var height = svg.node().getBBox().height;
      var translate = [-scale*x,-scale*y];
      g.transition().duration(750) .call(zoom.translate(translate).scale(scale).event);
    });

  }

  function zoomed() {
    g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

})();

-- EDIT JSBin was broken --

Could you help me figure out what I might be overlooking? JSBin.

Answer №1

To align the highlighted element in red g#g-1101, simply make a small adjustment in your code:

  var bbox = $('#g-1101')[0].getBBox(); 


  var x = bbox.x-((bbox.width));
  var y = bbox.y-((bbox.height));
  //adjust the scale by 1
  var translate = [-(x*(scale-1)),-(y*(scale-1))];

Find the working code here

I hope this solution proves helpful

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

Parsing JSON in an Express application

I have developed a small application to test a larger one that I am currently working on. The small application reads data from a CSV file and then attempts to send this data to my API endpoint using POST requests. This is necessary as I need to send a lar ...

Unlocking protection: Confirming password strength and security with password indicator and regular expressions for special characters in angular through directive

I have developed an app for password validation using an AngularJS directive. The requirements for the password include at least one special character, one capital letter, one number, and a minimum length of 8 characters. Additionally, I have included a pa ...

Link up each query with every php echo

Suppose I have the following PHP code: $logger = $_SESSION['logger']; $postquery = $con->query("SELECT * FROM posts ORDER BY id DESC LIMIT 5"); while($row = $postquery->fetch_object()){ $posts[] = $row; } And then, this section of ...

Using react-hook-form for form submission and managing state in React

I want a button that toggles between displaying "Edit" for entering Edit mode and "Save" for submitting the form. However, the issue is that when I press the button while it shows "Edit," it submits the form. Link to codesandbox with the code provided be ...

Guide on organizing users into groups and filtering them using Firestore's reference field type

I currently manage a small group of employees with plans to expand in the future. To streamline operations, I am looking to implement a grouping feature that allows users to sort employees based on their assigned groups. Although I thought about using the ...

Exploring the assortment of reactions post-awaitReaction in node.js

The current code runs smoothly, but I encounter an issue when attempting to send messages after selecting either the X or check option. Instead of the expected outcome, I receive Despite my understanding that this collection is a map, all attempts to acce ...

Using Vue to Bring in External JavaScript Files

If I have 2 JavaScript files located in the 'resources/assets/js' directory, named 'app.js' and 'ext_app.js', what could be the issue? Within 'ext_app.js' file, there is a function defined like this: function testF ...

Retrieve information stored within an object's properties

Possible Duplicate: Accessing a JavaScript Object Literal's Value within the Same Object Let's take a closer look at this JavaScript object var settings = { user:"someuser", password:"password", country:"Country", birthplace:countr ...

Issue Detected at a Precise Line Number - Android Studio

Despite my numerous attempts to modify the specific line in question, including leaving it empty, turning it into a comment, or removing it entirely, the error message persists. I even went as far as deleting the class and creating a new one, but the same ...

Protected Bootstrap Environment

Bootstrap is an amazing tool, but it tends to enforce too many opinions. The selectors used in its rules are quite broad, such as input or label. Is there a method to isolate Bootstrap's CSS so that it only impacts elements within a container with a ...

Removing the year data and converting the month in JavaScript

Currently, I am utilizing the following code snippet to parse XML in Javascript: $this(find).text() When this code runs within an HTML environment, the output for the date from the XML data appears as: 2014-04-07T19:48:00 My objective is to format it l ...

Error: The request does not have the 'Access-Control-Allow-Origin' header

As a beginner in post requests, I've been encountering an error when attempting to make a post request. Despite searching for solutions, the answers are too complex for me to grasp how to adjust my code to resolve it. var url = 'http://unturnedb ...

Tips for positioning a box on top of a map in a floating manner

I am trying to figure out how to position the div with class box on top of the map in this jsbin. Can someone help me achieve this? Below is the CSS code I have for styling the box and body. body { font-family: "Helvetica Neue", Helvetica, sans-serif; ...

Updating choices within a div in real-time by changing the select box dynamically

I need to swap out the select box that is nested inside this div <div class="models"> <select disabled="disable"> <option>Model Name</option> </select> </div> I am attempting to target the div and manipul ...

Setting the second tab as the primary active tab

I am currently working on a script that is well-known, and everything is functioning perfectly. However, I want to change it so that when the page is first opened, it displays the second tab instead of the first one (the first tab being a mail compose tab ...

Unable to retrieve user attributes (provided as res.locals.user) in express and hbs view

Here is a snippet of code I use to verify user tokens and store the user information in req.locals: exports.isLoggedIn = async (req, res, next) => { if (req.cookies.jwt) { try { const decoded = await promisify(jwt.verify)( ...

A dynamic 3-column layout featuring a fluid design, with the middle div expanding based on the

Sorry for the vague title, I'm struggling to explain my issue clearly, so let me elaborate. I am using flexbox to create a 3-column layout and want the middle column to expand when either or both of the side panels are collapsed. Here is a screenshot ...

Improving the efficiency of ajax/javascript is necessary as the delay in data retrieval is too significant. There must be a more effective approach to this

Utilizing ajax requests to populate modal popup windows with user-filled data has been my current method. These popup windows, designed as div layouts, are controlled by jquery for showing and hiding. However, there seems to be a noticeable delay in this p ...

Manipulating data with Angular's array object

I am having an issue with posting an object array. I anticipate the post to be in JSON format like this: {"campaign":"ben", "slots":[ { "base_image": "base64 code here" } ] } However, when I attempt to post ...

Caution: Refs cannot be assigned to function components

I'm currently using the latest version of Next.js to create my blog website, but I keep encountering an error when trying to implement a form. The error message reads as follows: Warning: Function components cannot be given refs. Attempts to access t ...