2

I have created a javascript object as part of a visualization I am working on, and am funning into an issue with the object's instance variables. The relevant code is below:

function bubble() {
        //don't use these functions elsewhere--only modify them to change behavior
            this.color;
            this.bubbleCircles = chart.selectAll("circle");
                //.data(array,function(d){return d['date'];});

            this.bubbleCirclesEnter = function(selection){
                selection.enter().append("circle")
                    .style('stroke',this.color)
                    .style('fill',this.color)
                    .attr("cx", function (d, i) { return x(i); })
                    .attr("cy", function (d) { return y(d["measure"]) - 1.5*bubbleRadius; })
                    .attr("r", 0);
                    console.log(this.color);
                };

            this.bubbleCirclesEnterTransition = function(selection){
                return selection.transition()
                    .duration(400)
                    .delay(function(d,i){return i*segmentDuration;})
                    .ease('elastic')
                    .attr("r", bubbleRadius);
                };

            this.bubbleText = chart.selectAll('.label');
                //.data(array,function(d){return d['date'];});

            this.bubbleTextEnter = function(selection){
                selection
                    .enter().append("text")
                    .attr("x", function (d, i) { return x(i) - (13.0/16)*bubbleNumberSize; })
                    .attr("y", function (d, i) { return y(d['measure']) - 1.5*bubbleRadius + bubbleNumberSize*(5.0/16); })
                    .style("font-size", bubbleNumberSize.toString() + "px")
                    .style('fill',white)
                    .style('fill-opacity',1.0)
                    .style('stroke',white)
                    .style('stroke-opacity',1.0)
                    .text(function (d, i) { return d['measure'].toFixed(2); });
            };
        //actually use these ones

            this.enter = function() {
                this.bubbleCircles = this.bubbleCircles.call(this.bubbleCirclesEnter);
                this.bubbleText = this.bubbleText.call(this.bubbleTextEnter);
            };

            this.enterTransition = function() {
                this.bubbleCircles.call(this.bubbleCirclesEnterTransition);
            };

            this.draw = function() {
                this.enter();
                this.enterTransition();
            };

            this.setData = function(dataSet) {
                this.bubbleCircles = this.bubbleCircles.data(dataSet,function(d){ return d['date']; });
                this.bubbleText = this.bubbleText.data(dataSet,function(d){ return d['date']; });
            };

            this.setColor = function(bubblesColor) {
                this.color = bubblesColor;
            };
        };

The problem is with the this.color variable. It gets set when the 'setColor' method is called, but, later, when bubbleCirclesEnter is called (via this.draw and this.enter), a console.log of the variable shows that it is undefined.

If anyone could point out what I am doing wrong, I would really appreciate it!

1
  • What is this.bubbleCircles.call? What library are you using? Commented Jul 18, 2013 at 13:47

2 Answers 2

3

this changes scope throughout the object. When you enter any of your functions, the scope of this moves from a global scope to the local scope of the function. Generally what I've seen done is to set a new variable equal to this as another member. This article explains in better words than I can: http://ryanmorr.com/understanding-scope-and-context-in-javascript/

function bubble() {
    //don't use these functions elsewhere--only modify them to change behavior
        this.color;
        this.bubbleCircles = chart.selectAll("circle");
        var me = this;

. . .

this.bubbleCirclesEnter = function(selection){
            selection.enter().append("circle")
                .style('stroke',me.color)
                .style('fill',me.color)
                .attr("cx", function (d, i) { return x(i); })
                .attr("cy", function (d) { return y(d["measure"]) - 1.5*bubbleRadius; })
                .attr("r", 0);
                console.log(me.color);
            };
Sign up to request clarification or add additional context in comments.

6 Comments

"the scope of this becomes the function" is a littlebit inaccurate. Please clarify or link to some docs explaining it.
Seemed perfectly clear to me! I had a feeling it was some sort of scope issue like that -- thanks for the help!
Well actually the this keyword has nothing to do with the scope of a function. It's the calling context that is relevant for this. If you had used the variable scope (var color instead of a property) the problem would've gone away :)
I disagree with that. The OP obviously wants to access the color property from outside the object, so using a variable instead of a property wouldn't be an option.
We don't see the code that makes use of the bubbles so we can't be sure about that… He also has an explicit setter already which might indicate the use of a strict encapsulation :-)
|
-1

Just a idea:

Try to declare the color variable in your function:

function bubble() {
        //don't use these functions elsewhere--only modify them to change behavior
            var color = "";
   //rest of the code

2 Comments

Since you didn't declare your variable, it's undefined. You could use strict mode to avoid that. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Then no. OP does not have a variable, he has a property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.