Variable Scope in D3 JavaScript

variable scope in d3 javascript

Because d3 requests (like d3.json) are asynchronous, it's best practice to wrap all of the code dependent on your external request within the request callback, ensuring that this code has access to the data before executing. From the D3 docs: "When loading data asynchronously, code that depends on the loaded data should generally exist within the callback function."

So one option is to put all of your code within the callback function. If you'd like to separate the code into parts, you can also pass the response from your request to a separate function, something like this:

function myFunc(data) {
console.log(data);
}

d3.json('file.json', function (data) {
var json = data;
myFunc(json);
});

javascript and d3.js variable scope: variable resets outside of function call

This is due to the asynchronous nature of javascript. The blocks of code you write do not get evaluated "in order" as you might expect. Basically, anything that uses the d3.csv call HAS to be within that block:

d3.csv("epochStats.csv", function(d) {
console.log(d.length);
maxEpochs = d.length;
console.log(maxEpochs);
// anything else that uses the value of maxEpochs, or reads the file data, etc....
});
console.log(maxEpochs); <-- This could be evaluated before the above csv block.

How to share scope between functions in d3.js?

If you declare the variables outside your functions and then assign to them (without using the var keyword in the function) then your functions will be closures, granted access to set and get values from those variables.

var x,y;
function foo(){
x = d3.scale.ordinal();
d3.select("...").on("click",onclick);
}
function bar(){
y = d3.scale.linear();
d3.select("...").on("click",onclick);
}
function onclick(){
// has access to both x and y here
}

Alternatively, if that's too dirty feeling, then create a closure around the local variable during event registration, passing the value to your shared function:

function foo(){
var x = d3.scale.ordinal();
d3.select("...").on("click",function(evt){
onclick.call(this,evt,x);
});
}
function foo(){
var y = d3.scale.linear();
d3.select("...").on("click",function(evt){
onclick.call(this,evt,y);
});
}
function onclick(evt,scale){
// Use 'scale' passed in
}

Note that in this case you cannot unregister onclick later because that was not the function that was registered with the handler.

variables scope in javascript D3

here is what i did after I took Dogbert's comment in consideration:

 var eSVG, originMouse;

svg.on("mousedown", function() {
eSVG= this, // svg element
originMouse = d3.mouse(eSVG), // mouse origing
rect = svg.append("rect").attr("class", "zoom");
originMouse[0] = Math.max(0, Math.min(width, originMouse[0]));
originMouse[1] = Math.max(0, Math.min(height, originMouse[1]));

svg.on("mousemove", function() {
console.log(eSVG); **// defined **
var m = d3.mouse(eSVG);
console.log(originMouse); **// defined **
m[0] = Math.max(0, Math.min(width, m[0]));
m[1] = Math.max(0, Math.min(height, m[1]));
rect.attr("x", Math.min(originMouse[0], m[0])-130)
.attr("y", Math.min(originMouse[1], m[1])-80)
.attr("width", Math.abs(m[0] - originMouse[0]))
.attr("height", Math.abs(m[1] - originMouse[1]));
})
d3.event.stopPropagation();
})

How to bring variables into the scope of the .each method in d3

You don't need to list "d" in the formal parameters for that anonymous function.

mainSVG.selectAll(".points")
.each(function(){
if(d[D.x] >= e[0][0]){

Variables declared in outer scopes are always available in inner scopes unless they're "shadowed" by a more-inner declaration of the same identifier. That's what's happening in your code.

You don't need "D" at all; just reference "d". Now, if the d3 code passes something useful to the function used as the .each() iterator, then declare it, but give it a name different from "d":

mainSVG.selectAll(".points")
.each(function(not_d){
if(not_d[d.x] >= e[0][0]){


Related Topics



Leave a reply



Submit