Can you specify the third argument sent to the listener?

Recently I delved into exploring the capabilities of the d3 framework. One thing that caught my attention was the presence of a third parameter in the event listener for v3. Despite always being 0, I couldn't find any explanation on its intended purpose.

According to the documentation:

The specified listener is invoked in the same manner as other operator functions, being passed the current datum d and index i, with the this context as the current DOM element.

This leaves me questioning the significance of this mysterious third parameter.


In the code snippet below, you'll notice that when clicking on any of the rectangles, three parameters are passed to the function f:

var svg = d3.select("body").append("svg")

function f(d, idx, whoami) {
    console.log('I am the data:\t' + d);
    console.log('I am the index:\t' + idx);
    console.log('But who am i?\t' + whoami);
    console.log('Length:' + arguments.length);
    console.log(arguments);
}

var data = ['A', 'B', 'C'];

svg.selectAll('rect')
  .data(data)
    .enter()
    .append('rect')
    .attr("x", 0)
    .attr("y", function(el, i) {return i * 40;})
    .attr("width", 100)
    .attr("height", 40)
    .on("click", f);
rect {
  fill: #333;
  opacity: 0.3;
  stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

Answer №1

There is a hidden feature that remains undocumented. If you explore the code implementation of selection.on() in version 3.5.17, you will discover that it utilizes selection.each() internally to connect the listener to each node within the selected group.

return this.each(d3_selection_on(type, listener, capture));

Furthermore, the internal function d3_selection_on leads to onAdd for adding listeners, and this reference is passed as the callback to .each(). Therefore, .each() executes onAdd for every individual node in the current selection. Meanwhile, onAdd encapsulates the arguments from the .each() call by storing them in the listener's context:

function d3_selection_on(type, listener, capture) {

  /* ... */

  function onAdd() {
    var l = wrap(listener, d3_array(arguments));  // wrap points to d3_selection_onListener
    /* ... */
  }

  /* ... */

function d3_selection_onListener(listener, argumentz) {
  return function(e) {
    /* ... */
    argumentz[0] = this.__data__;                 // Set the latest datum as the first argument
    try {
      listener.apply(this, argumentz);            // Pass arguments from closure to the listener
    } finally {
      d3.event = o;
    }
  };
}

Upon examining the implementation of selection.each(), it becomes evident that not only two arguments—mentioned in the official documentation—are provided to the callback but rather three arguments:

if (node = group[i]) callback(node, i, j);

The third argument j represents the index of the group. In cases where grouping is absent, this argument always holds the value 0.

By modifying your demonstration, it's possible to showcase how establishing a grouped selection impacts the value assigned to this third argument. The following snippet replicates your three rectangles while organizing them into separate <g> elements with their own data binding to establish a form of grouping.

var svg = d3.select("body").append("svg")

function f(d, idx, whoami) {
    console.log('I am the data:\t' + d);
    console.log('I am the index:\t' + idx);
    console.log('But who am i?\t' + whoami);
    console.log('Length:' + arguments.length);
    console.log(arguments);
}

var data = [['A', 'B', 'C'], ['a', 'b', 'c']];

svg.selectAll('g')
  .data(data)
  .enter().append('g')
  .selectAll('rect')
  .data(d => d)
  .enter().append('rect')
    .attr("x", function(el, i, j) {return j * 110;})
    .attr("y", function(el, i) {return i * 40;})
    .attr("width", 100)
    .attr("height", 40)
    .on("click", f, true);
rect {
  fill: #333;
  opacity: 0.3;
  stroke: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>

This aspect remains entirely unmentioned in the official documentation for both .each() and .on().

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

The issue of Datatables child row not refreshing when using AJAX

I'm attempting to retrieve child row data in Datatables using AJAX: $('#myTable tbody').on('click', 'td', function () { var tr = $(this).closest('tr'); var row = myTable.row( tr ); if ( row.child.isS ...

jQuery blueimp File Uploader: Transferring multiple files to the server on Internet Explorer

After customizing the demo for my Rails application, I encountered an issue with the plugin in Internet Explorer. While it works smoothly on Chrome and Firefox, in IE (all versions) it fails to upload all but one file when multiple files are selected, and ...

Different ways to analyze elements from 2 arrays to hone in on specific values

I'm really struggling to solve this issue. I have two arrays - one for cars and the other for active filters. The cars array consists of HTML li tags with attributes like car type, number of seats, price, etc. On the other hand, the active_filters arr ...

Troubleshooting: jQuery $.post not functioning as expected in certain circumstances

I'm currently experimenting with inserting data into a MySQL database using AJAX and jQuery's $.post method. To test this functionality, I have created the following setup: In my index.html file (which already includes jQuery for various other f ...

Ways to make JavaScript cycle through a set of images

I'm having trouble trying to set up a code that will rotate multiple images in a cycle for an image gallery I'm working on. So far, I've only been able to get one image to cycle through successfully. Any help or suggestions would be greatly ...

Is it possible to incorporate two ng-repeat directives within a single td element in a table?

The results so far Expected outcome Please advise me on how to incorporate two ng-repeats within one td. When I use a span tag afterwards, the expected result is not achieved. I have used one ng-repeat in the td and the other in a span tag, which is why t ...

Informing the parent window of the child window's activities in order to adjust the timer for the user timeout feature

Within my Jquery function, I have implemented a feature that darkens the screen after a period of user inactivity. This triggers a pop-up window giving the user the option to stay logged in by clicking a button. If there is no response within the set time ...

Is there a way to use ng-click to switch the ng-src of one image with that of another?

*I made updates to the plunkr and code to reflect my localhost version more accurately. It turned out that the AngularJS version was not the issue even after fixing the previous plunkr.* Let me start by saying that I am facing some challenges with Angular ...

What is the process for adding parameters to a Fetch GET request?

I have developed a basic Flask jsonify function that returns a JSON Object, although I am not certain if it qualifies as an API. @app.route('/searchData/<int:id>',methods=["GET"]) def searchData(id): return jsonify(searchData(id)) Curr ...

Can anyone tell me the location of the modalColor with the background set to 'greenYellow' in the popup window?

Take a look at the sample in jQuery.bPopup.js called Example 2b I am trying to design a popup window with customized text and background style, using the Example 2b, custom settings: Simple jQuery popup with custom settings (Jamaican popup, relax man) $ ...

The cause of Interface A improperly extending Interface B errors in Typescript

Why does extending an interface by adding more properties make it non-assignable to a function accepting the base interface type? Shouldn't the overriding interface always have the properties that the function expects from the Base interface type? Th ...

Quick Validator. Establishing a schema that relies on specific values

I have a situation where I need to differentiate between two types of users - teacher and student. The schema for a teacher looks like this: { username : string; firstName : string; lastName : string; type : 1; // 1 = teacher schoolId : o ...

This error message 'React Native _this2.refs.myinput.focus is not a function' indicates that

When working with React-Native, I encountered a specific issue involving a custom component that extends from TextInput. The code snippet below demonstrates the relevant components: TextBox.js ... render() { return ( <TextInput {...this.props} ...

Guide on creating a menu that remains open continuously through mouse hovering until the user chooses an option from the menu

I have a unique scenario where I am working with two images. When the mouse hovers over each image, two corresponding menu bars appear. However, the issue is that when the mouse moves away from the images, the menu disappears. Any suggestions on how to im ...

Sending data to API using AngularJS Http Post

Upon clicking "Add new User", a modal pop-up will appear with a form containing a text field and a checkbox. However, upon clicking the create button, the data is not being posted to the API and the modal pop-up remains open without closing. I would like ...

Is there a way to store div content in a PHP Session?

Just starting to learn php & ajax, so be patient with me. I have a clickable map. When the user clicks on a point, the value is displayed in a div. Once they select a point, they should be able to proceed to the next step. Now I want to save the content ...

VS code is showing the directory listing instead of serving the HTML file

Recently, I attempted to use nodejs to serve the Disp.html file by following a code snippet from a tutorial I found on YouTube. const http = require("http"); const fs = require("fs"); const fileContent = fs.readFileSync("Disp.html& ...

When it comes to utilizing jQuery for the mobile view, how many jQuery libraries are recommended for optimal performance?

I'm currently constructing a website using ROR, and for the mobile view, I've implemented the mobile_fu gem. The designer provided me with a design for the mobile view that includes various jQuery sliders, players, image sliders, drop-down menus ...

What factors influence Redux in determining when to update the user interface?

As per the design, when the state updates, the UI should also update accordingly. However, if I return a completely new object, it seems to have no effect on the UI. case 'clearArticleForm': let newState1 = {}; return newState1; } E ...

Angular, JavaScript, and PHP are three powerful programming languages that

This file contains HTML code <ul class="list"> <li id="numword" data-score="{{item.score}}" class="" ng-repeat="item in words track by $index"> {{item.word}} {{item.score}} </li> </ul> Here is the visual representa ...