How to use call function? - d3.js

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

Related

How we can slice elements fetched using cy.get() and then run tests on those specific elements only?

cy.get('li').slice(0,5)
The above line of code doesn't work as it Property 'slice' does not exist on type 'Chainable<JQuery>'
Is there a way to slice elements that we have fetched using cy.get()
Cypress's cy.get() yields a Chainable, which allows Cypress to easily pass elements (and other things) between Cypress commands. To use traditional JS functions, you'll just need to use .then().
cy.get('li').then(($els) => {
const $sliced = $els.slice(0, 5);
// whatever you need to do with $sliced.
// to easily iterate over these, do something like the following
cy.wrap($sliced) // add the $sliced variable into the Cypress chain
.each(($el) => {
// whatever needs to be tested on each element
});
});
As a small tweak to #agoff's answer, you can use the .invoke() command to use slice method on your jQuery array, where the first argument will be the method name and the following will be the method arguments.
cy.get('li')
.invoke('slice', '0', '5')
.should('have.length', 5)
Here is a working example.
There are a couple of other ways to do it,
add pseudo-selector :lt(5) to take first 5 items
cy.get('li:lt(5)')
apply a filter to the set
cy.get('li')
.filter((index,el) => index < 5)

Ti Nspire: Convert solve(...) output to a callable Function

in order to calculate the inverse function of f(x) I defined following function:
inv(fx):=exp▶list(solve(fx=y,x),x)
which output is:
inv(x^(2)) {piecewise(−√(y),y≥0),piecewise(√(y),y≥0)}
So that part works already, but how can I use this result as a callable function i(y)?
Thanks for your help
Outside of your program, you can turn the result into function i(y) with:
i(y):=piecewise(-√(y),y≥0,√(y),y≥0)
I do not have a CAS, so your results may differ, but, because the function can only return one value, it would only return (and display in the graph) the first value, in this case, -√(y). If you want to display on the graph or get the values of both, you would be better off creating two separate functions (-√(y), and √(y)). Hope this helps you "use the result as a callable function."

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.

make document.getElementById into a var

Is there any way you can make "document.getElementById" into a variable?
I want to be able to write
myVariable("id").innerHTML = (blabla);
instead of
document.getElementById("id").innerHTML = (blabla);
Pardon me if this has been answered. I've sought and found nil! newbie
You can wrap the output into another function
var shortID = function(id) {
return document.getElementById(id);
}
shortID('myID').innerHTML = "...";
To provide a simpler way to call common code, you can just define your own function like migvill suggests.
To answer the question directly though, you can point to the document.getElementById function (or any other function) using a variable. This is as obvious as you could imagine:
var myVariable = document.getElementById;
The problem with this is that the function itself (the object that myVariable now points to) is not intrinsically linked to the document object that it is designed to work with. When you write document.getElementById("id"), the document is automatically given to the function, but with myVariable you would need to specify it. This can be done using the call function:
myVariable.call(document, "id").innerHTML = "blabla";
And finally, the bind function can be used to create a new function that automatically links the given object (this has essentially the same effect as defining your own wrapper function):
var newFunc = myVariable.bind(document);
newFunc("id").innerHTML = "blabla";

Order $each by name

I am trying to figure why my ajax $each alters the way my list of names gets printed?
I have an json string like this:
[{"name":"Adam","len":1,"cid":2},{"name":"Bo","len":1,"cid":1},{"name":"Bob","len":1,"cid":3},{"name":"Chris","len":1,"cid":7},{"name":"James","len":1,"cid":5},{"name":"Michael","len":1,"cid":6},{"name":"Nick","len":1,"cid":4},{"name":"OJ","len":1,"cid":8}]
Here all the names are sorted in alphabetic order, but when getting them out they are sorted by "cid"? Why, and how can I change this?
Here is my jQuery:
var names = {};
$.getJSON('http://mypage.com/json/names.php', function(data){
$.each(data.courses, function (k, vali) {
names[vali.cid] = vali.name;
});
});
I guess its because "names[vali.cid]", but I need that part to stay that way. Can it still be done?
Hoping for help and thanks in advance :-.)
Ordering inside an object is not really defined or predictable when you iterate over it. I would suggest sorting the array based on an internal property:
var names = [];
$.getJSON('http://mypage.com/json/names.php', function(data){
$.each(data.courses, function (k, vali) {
names.push({name: vali.name, cid: vali.cid});
});
names.sort(function(a, b) {
return a.name.localeCompare(b.name);
});
});
Now you have an array that is ordered and you can iterate over it in a predictable order as well.
There is no "ajax $each" - you probably mean the jQuery function.
With "when getting them out" I presume you mean something like console.debug(names) after your $each call
Objects aren't ordered in javascript per definition, so there is no more order in your variable "names". Still, most javascript implementations today (and all the ones probably important to you - the ones used in the most used browsers) employ a stable order in objects which normally depends on the order you insert stuff.
All this said, there can probably be 3 reasons you're not getting what you're expecting:
Try console.debug(data) and see what you get - the order as you want it?
As you don't explicitly state how you debug your stuff, the problem could be in the way you output and not the data is stored. Here too try console.debug(names).
You're using a function which dereferences on expection, like console.*. This means if you console.debug() an object, the displayed values will depend on the moment you unfold the displayed tree in your browser, not when the line was called!

Resources