Exploring R object characteristics with JavaScript - Continued!

Previously, I shared a question with similarities (Retrieving R object attributes in JavaScript). Unfortunately, the answer received did not directly address my real problem due to an oversimplified example. Here, I am exploring the need to retrieve R object attributes in JavaScript and looking for alternative approaches.

My dataset consists of 5 variables and 100 observations. Using hexagon binning, I created a scatterplot matrix with each plot containing 12-18 hexagons. To retain the rows of observations grouped within these hexagon bins across all plots, I utilized the base::attr function in R as shown in the code below:

attr(hexdf, "cID") <- h@cID

The objective is to build an interactive R Plotly object representing the hexagon binning. When a user clicks on any hexagon bin (from any scatterplot), they should obtain the associated 100 observation rows. While progress has been made towards this, there's still work to be done. Below is a minimal working example of my current setup:

Library(plotly)
...
myLength = length(ggPS[["x"]][["data"]])
...

ggPS %>% onRender("
          function(el, x, data) {
          ...
          cN = e.points[0].curveNumber
            split1 = (x.data[cN].text).split(' ')
            hexID = (x.data[cN].text).split(' ')[2]
            counts = split1[1].split('<')[0]

            console.log(myX)
            console.log(myY)
            console.log(hexID)
            console.log(counts)
          })}
           ", data = pS[5,2]$data)

Upon execution, an image like the one shown here is generated: https://i.sstatic.net/jskyp.png

If I click on a particular hexagon, I can identify its position in the subplot ("myX" and "myY"), the clicked ID ("hexID"), and the number of data points binned ("counts"). For instance, clicking on a specific hexagon may reveal that myX=5, myY=2, hexID=39, and counts=1, indicating the coordinates of the bin where one data point resides.

To fetch the row corresponding to the clicked hexagon, running the following code in R yields the desired output:

myX <- 5
myY <- 2
hexID <- 39
obsns <- which(attr(pS[myX,myY]$data, "cID")==hexID)
dat <- bindata[obsns,]

This retrieves the row from the data frame containing the single data observation residing in the selected hexagon:

> dat
     ID        A         B        C          D        E
95 ID95 1.586833 -1.208083 1.778429 -0.1101588 3.810277

The challenge lies in integrating the base::attr() function within the onRender() function to access the "obsns" object. Any insights or alternate strategies to resolve this issue would be greatly appreciated. Thank you for your suggestions!

Answer №1

It may not be possible to directly retrieve the hex IDs from the plotly library, so one approach could involve passing all necessary data to the onRender function for your specific purpose.

To achieve this, consider enhancing your bindata dataframe by including a column named mX-mY for each hex plot. This new column would indicate the corresponding hexbin for every observation in that plot:

for(i in 2:5) {
  for(j in 1:4) {
    bindata[[paste(i,j,sep="-")]] <- attr(pS[i,j]$data, "cID")
  }
}

After updating the bindata dataframe, you can then utilize it within the onRender function. Whenever you interact with a hexagon on any plot, the function will search through the appropriate column in bindata to identify which observations correspond to that specific hexbin:

ggPS %>% onRender("
              function(el, x, data) {

              myLength = Math.sqrt(document.getElementsByClassName('cartesianlayer')[0].childNodes.length);


              el.on('plotly_click', function(e) {
              xVar = (e.points[0].xaxis._id).replace(/[^0-9]/g,'')
              if (xVar.length == 0) xVar = 1
              yVar = (e.points[0].yaxis._id).replace(/[^0-9]/g,'')
              if (yVar.length == 0) yVar = 1
              myX = myLength + 1 - (yVar - myLength * (xVar - 1))
              myY = xVar

              cN = e.points[0].curveNumber
              split1 = (x.data[cN].text).split(' ')
              hexID = (x.data[cN].text).split(' ')[2]
              counts = split1[1].split('<')[0]

              var selected_rows = [];

              data.forEach(function(row){
                if(row[myX+'-'+myY]==hexID) selected_rows.push(row);
              });
              console.log(selected_rows);

              })}
              ", data = bindata)

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

Tips for adjusting the height of a div using the slideToggle function for expanding and collapsing content

Is there a way to modify my code in order to adjust the height of a <div> using slideToggle()? The current implementation works almost correctly, with one minor issue. When I click on one "read_more" and then click on another, it does not behave as e ...

Is there a way to inform the List component when the height of its row items has been altered in order to trigger a rerender

In my project, I am using a react-virtualized List where each item in the rows has an expand button. When this button is clicked, the row's height changes to reveal more information. The problem I am facing is that after clicking the button, the inne ...

"X-Requested-With" header not being included in XMLHttpRequest request

After successfully using jQuery.ajax() to make an ajax call to an MVC action, I decided to switch to using the XMLHttpRequest along with the HTML5 File API due to some forms containing file controls. However, since making this change, the MVC action no lon ...

Tips for implementing dropdown control validation using AngularJS validators

I am currently facing an issue with angular js dropdown validation. I have been trying to implement dropdown validation using the code from this website: https://github.com/turinggroup/angular-validator However, upon checking the demo provided in this lin ...

Are certain browsers unable to play dynamically generated HTML5 audio files?

While working on my project, I encountered an issue with creating and controlling an audio element in JavaScript. The element works perfectly fine in Firefox, Chrome, and Opera; however, it fails to function properly in IE and Safari. In these browsers, ...

Using Javascript to enable a button to perform multiple actions on an element

In my current setup, there are buttons that can adjust the height, color, and opacity of a box. For example- document.getelementbyID("growbutton").addEventlistener("click", function growFunction() { document.getelementbyID("box&q ...

Getting AJAX to function on a local server with either XAMPP or node.js

I am completely stumped and in need of some assistance. My current challenge involves trying to implement AJAX on a local server, but I am feeling lost when it comes to even the most basic coding. I have installed node.js and XAMPP to my system and have b ...

Encountering a mixed content error in Internet Explorer 8 due to the Nivo slider jQuery?

I am encountering an issue with the Nivo jQuery slider on my HTTPS website, as it appears to be generating a mixed content error in Internet Explorer 8. Despite posting on the Dev7 Studios forum and conducting extensive research on the IE 8 mixed content ...

JavaScript loop not functioning properly to show modals when button is clicked

I successfully created a Javascript function to display a modal on button click, but I realized that I would have to manually repeat the code 56 times. Instead, I attempted to write a loop to automate this process, but unfortunately, the new function is no ...

Add an asterisk before each line of comment when working in a TypeScript file using the VS Code IDE

Within my VS Code workspace, I am using the Typescript language and would like to format my comments across multiple lines with a specific style (look out for the star character) /** *@desc any text * any text */ However, when I attempt to write a comm ...

Possible scope problem causing AngularJS image preview not showing up in ng-repeat loop

I came across this question and made some modifications. It works well when used outside of the ng-repeat. However, I'm facing issues when trying to use it within my repeat loop; the image.src does not update. I believe this is more related to the sc ...

Creating a fresh array in JavaScript

Attempting to create a new array with specified values. Scenario 1: var x = new Array(3).map(()=>1); At this point, x equals [undefined * 3] Scenario 2: var x = [...new Array(3)].map(()=>1); Now x is [1,1,1] Can anyone provide assistance on wh ...

Dynamic views loaded from ui-router can cause compatibility issues with running Javascript

Currently, I am facing an issue while attempting to load a template into a UI-View using UI-Router. Although the JavaScript is loaded, it does not run on the loaded views. The situation unfolds as follows: I have developed a template in HTML containing all ...

Every time I attempt to insert a background image into a div using jQuery, I am consistently faced with a 404 error message

When I hit enter in my search bar, a new div is created each time. However, I am struggling to assign a background image to the created div as I keep receiving a 404 error in the console. Below is the code snippet I'm working with: function appendToD ...

Invoke a component and initiate a click event from within the App.vue component

Within my template, there is a click event: <span v-on:click="showGalery()"> This event is linked to the following method: export default { name: 'osaka', data: function () { return { galery: false, } }, methods: { ...

Troubleshooting jQuery masonry problem related to initial display and height settings

Within a div, there is a masonry container with the inline style property display:none. With several divs on the page, clicking their respective buttons during load causes them to switch like a slideshow. This disrupts masonry's ability to calculate t ...

Using placeholders for multi-statement queries in Node.js with MySQL

I've reached the final stages of my project. The only thing left to do is to write the final query to the database. I want to use placeholders for this, but I'm not sure how to do it correctly in a multi-statement query. This is the query I have ...

Testing the screen size automatically using Javascript

Hello everyone, I've implemented a JavaScript code that triggers an image to slowly appear and darken the background when a link is clicked. However, on an iPad, the background doesn't completely turn black as intended. The CSS specifies that the ...

Why does my chart.js disappear every time I perform a new render?

Hey there, I'm facing an issue with my code. Let me paste what I have... import React, { memo, useEffect } from 'react'; import Chart from "chart.js"; /* redux-hook */ import { useSelector } from 'react-redux' const lineChart = m ...

Transform the API response into a map in Angular version 16

When I receive a JSON response from a Java server, the structure looks like this: { "summary": { }, "runs": { "key_1": { "object_1": { }, "object_2": { ...