Debugging a function in observable

I am struggling to find the error in my function and wonder what is the best way to do this:

In


I play with exploring different ways to visualize a chess game. I wanted to see how it looks like to add the moves as a text on a textpath.
The visualization returned from the function version5() works as expected and shows the moves along the path. There is obviously an overlap problem but also the orientation of the text is sometimes upside down.

I tried to fix the latter with version6().
It just differs form version5() by adding a .attr(“transform”, rotate) to flip the text. however the moves which are supposed to be flipped are disappearing (I suppose the translation before the rotation is wrong)

So the function which does something wrong is the function rotate which is defined as follows:

function rotate(d) {
  if (squareToPosition(d.to).x < squareToPosition(d.from).x) {
    const bbox = this.getBBox();
    const rx = bbox.x + bbox.width / 2;
    const ry = bbox.y + bbox.height / 2;
    return 'rotate(180 ' + rx + ' ' + ry + ')';
  }
  else {
    return 'rotate(0)';
  }
} 

There must be something wrong with is but I don’t know how to e.g. output the computed values of bbox to see what goes on and to fix the error.

For general notebook debugging, are you making use of your browser’s dev tools? I often use console.log to print out intermediate values in the dev console and debugger to set a breakpoint in the JavaScript debugger (which you can then use to step through execution). There’s some basic advice here.

In Firefox, there’s a strange error:

[Exception... "Failure"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: https://static.observableusercontent.com/worker/worker.54d38e47fc95010b5bef5208d55ffd52ae344c93b2e4f1ffdee38a96e153a0c4.js line 2 > eval :: rotate :: line 4"  data: no]

which is triggered by this line:

    const bbox = this.getBBox();

I guess because getBBox is failing. Maybe related to this post?

In Chrome bbox becomes an SVGRect {x: 0, y: 0, width: 0, height: 0}, which causes all rx and ry to be zero, and seems like it may not be what you want.

1 Like

Thanks for the great and quick answer!

Yes, I use Google Chromes dev tools - or Visual code studio and its debugging options.
WIth observable I don’t know how to find my source code in the browsers dev tool (so I can’t set a breakpoint) But the classic console.log helped!
As you mentioned, the reason for this behaviour is probably due to the explanation of Mike that the DOM is not build yet which you linked.
I wasn’t able to easily adopt this solution to my case - but found a way to compute the position without needing the access to this.getBBox().

In case someone is interested, my solution was:

function rotate(d) {
  const xFrom = squareToPosition(d.from).x;
  const xTo = squareToPosition(d.to).x;
  if (xTo < xFrom) {    
    // const bbox = this.getBBox();
    // const rx = bbox.x + bbox.width / 2;
    // const ry = bbox.y + bbox.height / 2;
    
    const rx = xTo + ((xFrom - xTo) / 2);
    const yFrom = squareToPosition(d.from).y;
    const yTo = squareToPosition(d.to).y;
    const ry = (yTo > yFrom) 
       ? yFrom + ((yTo - yFrom) / 2)
      : yTo + ((yFrom - yTo) / 2);
    return 'rotate(180 ' + rx + ' ' + ry + ')';
  }
  else {
    return 'rotate(0)';
  }
} 

and when I have more time, I want to import and adjust your @bchen observable so the user can also input a game by moving pieces with chessboard.js.
Thanks for the great help!

1 Like

Glad my post was helpful!

You can use the debugger statement to set a breakpoint using code. I actually learned about this from another post in this forum!

3 Likes

When I’m having a problem with something in Observable, and I’m using the online editor, I find I’m not using the browser debuggers as often anymore. I usually break the problem function and code down, line by line as needed into separate cells, starting with a copy of the original cell/function and using Alt-Enter to break up until I find a bad value or logic. If I need to peek into some code with svg or canvas elements, I’ll set the value property so I can inspect the internal variables or selections outside the cell if needed. i.e. svg.property(“value”, {xA, yA, svg, g_pnts}).

2 Likes