Is Passed Argument the Element or the Event? - events

In the script below, is eORe the element or the event?
$("#elementid").click(function(eORe) {
eORe.innerHTML += ' is the object of attention';
eORe.stopPropagation(); // don't bubble up
});
Note: One of the commands in the function must be wrong, based on the question.

Related

In Cypress how do we return array from method and pass the returned array value as parameter to another method

Let say I want to store the multiple elements and return the array to another method as a parameter.Currently I am using cucumber with cypress tool,In simple I want to return the array from step definition and make use of this array as parameter in another step definition,how to do with cypress tool?,Please someone guide me.
The main concept of sharing data in test is aliases
// when step
cy.wrap([1,2 3 4 5]).as('myElements')
// then step
cy.get('#myElements').then(elements => {
// pass it to command as parameter.
})
Moreover, you can setup your custom command as child and use 'prevSubject' to point out that it should receive result of previous command as argument:
// command:
Cypress.Commands.add('myCommand', {
prevSubject: true
}, (elements) => {})
// usage:
cy.get('#myElements').myCommand()

Apply mapping to attached data

I have a bunch of data attached to DOM elements, and I'd like to double each one. My naive approach was to select them all and call data with a function on the selection. I thought this would be sufficient since the data is stored on the elements rather than the selection itself.
However, this doesn't do what I want at all. Bizarrely it results in a selection with the data [undefined] rather than [2, 4, 6] and doesn't affect the data attached to the elements. Even stranger, if I call it with the identity function I get an exception: Cannot read property 'length' of undefined
What's going on here? Does D3 only allow data to be called with a function on an enter/exit selection?
// Create a bunch of elements with attached data.
const selection = d3.selectAll('p').data([1,2,3]).enter().append('p');
console.log(selection.data());
// This doesn't work, but seems like it should:
selection.data(d => d * 2);
console.log(selection.data());
// This throws an exception??
selection.data(d => d);
console.log(selection.data());
// Is this the simplest way that works?
selection.data(selection.data().map(d => d * 2));
console.log(selection.data());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
The first two examples you have are quite interesting.
While the first example might seem to be a workable solution:
selection.data(d => d * 2);
console.log(selection.data());
It won't work as expected. First, .data expects an array but it appears as though you are trying to pass each item individually. But also, d here is undefined, the function passed to .data() is called only once, not for each element in the selection. So there are no individual datums to work with in this example (you could have a datum to work with here in a nested selection (see docs)), I've only changed the above to log d and we can see it's undefined:
// Create a bunch of elements with attached data.
const selection = d3.selectAll('p').data([1,2,3]).enter().append('p');
// This doesn't work, but seems like it should:
selection.data(function(d) { console.log(d); return d * 2; })
console.log(selection.data());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
Why does the second example throw an error while the first doesn't? When multiplying undefined by 2 we get NaN, within the data method the method looks to determine the input data array's length, on NaN length is undefined, on undefined length is an error, I believe this is most likely why one produces and error and the other doesn't:
console.log(NaN.length);
console.log((undefined * 2).length);
console.log(undefined.length);
The non valid lengths also likely explain why no exit selection is created and the data isn't updated: the size of the exit selection is based on the size of the input data array. Data remains unchanged in the first example because within d3-selection the for loop to update the data never loops over the data as the for condition is never met:
for (var i = 0; i < dataLength; ++i) { // bind data
D3 is more designed to bind (new or updated) data to elements rather than to directly manipulate the data bound to those elements. But you can achieve the result you want, either as indicated in your third option, or from the get go with Xavier's comment, alternatively you could write a simple function and pass it to selection.each() (though there are many other solutions too):
// Create a bunch of elements with attached data.
const selection = d3.selectAll('p').data([1,2,3])
.enter()
.append('p')
.each(double);
function double() {
d3.select(this).datum(d => d*2);
}
console.log(selection.data());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>

How to use call function?

Lets say I have some g elements of class line. So I can write:
var lines = svg.selectAll('.line');
lines.exit().remove();
lines.transition().append('text')
lines.enter().append('g').attr('class', 'line');
And then append('text') is called for each g.line element. What if I want to call custom function f instead of append? I guess this should use call function, but:
lines.call(f) will call f only once (with all data, but I want to launch f separately for each element)
Luckily found that this is possible, not sure if there is smth better:
lines.transition().each(function(datum, index) {
renderDataLine(d3.select(this), data[index], ...);
});
You probably want to look at each, see here
I quote:
Invokes the specified function for each element in the current selection
I set up a fiddle (watch console) here

Returning other values from d3.call

Per the docs, "The call operator always returns the current selection, regardless of the return value of the specified function." I'd like to know if there is a variant of call or reasonable workaround for getting call-behavior that returns values other than the selection.
Motivation:
I've got a chart and a datebrush, each encapsulated in a function
function trends_datebrush() {
// Setup
function chart(_selection) {
_selection.each(function(_data) {
// Do things
...});
}
return chart;
};
(The chart follows a similar format but isn't called datebrush).
These are instantiated with:
d3.select("someDiv")
.datum("data")
.call(trends_datebrush());
// And then we call the chart
I'd like to return a subselection from brush to be used as the data variable in the chart call. As is I need to make them both aware of some higher order global state, which gets messy especially since I want other control functions to drill down on the data. If I could override call, then I could do something like
d3.select("someDiv")
.datum("data")
.call(trends_datebrush())
.call(trends_chart());
And then if I were to implement some new filter I could throw it into the chain with another call statement.
tl;DR: Looking for ways to get chain chart calls s.t. they can pass transformed data to each other. I want monadic D3 charts! Except I don't really know monads so I might be misusing the word.

How do I pass a cell argument from a spreadsheet to a custum function as a range?

I'm trying to get the following function to work by calling it from a spreadsheet cell:
=IsFormula(A1)
function IsFormula(aCell) {
return cell.getFormula().length != 0
}
What should I do?
Dror
Custom functions only have access to the cell's value, not the Range object itself. In your case, aCell would contain the value of the cell, which wouldn't work for your use case.

Resources