On my journey to learn d3, I often have difficulties passing from vanilla JS (standard js right?) to observable code and vice versa. Problems rise when I have external data or when I need to update the chart (zoom, pan ect…)
So my question is:
Is there a well defined methodology to port code from let’s say https://bl.ocks.org/ to observable and vice versa ?
I don’t know of a “well-defined” methodology, but I did put some tips at the end of the above notebook. For me the most important thing was to understand how the code that I’m porting works inside and out before trying to adapt it to Observable’s runtime.
Thank you very much Bryan. You are of great help. Seen a correction after trying several hours is useful. I continued with your solution. Rephrasing and clarifying the code. I now understand that the cell should return a DOM element that will be inserted in the div attached to the cell. But I’m left with what looks like subtleties to the beginner that I am.
For example, why the following 2 selects are not returning the exact same DOM element ?
foo = html<button id="fooId">Change data</button>
Same for : DOM.svg(width, height) and html<svg width=width, height=height></svg>
Also in your correction you wrote const div = html'<div>;
With just with one div as in the html doc example where it’s written : html<h1>Hello, world!
with just one h1.
Is that just a short cut to html<div></div> ?
Here’s my (possibly inaccurate) understanding. When select is given a string, it searches the current DOM tree using the string as a CSS selector. foo hasn’t yet been appended to the DOM tree so you get the null selection. Hopefully someone will jump in and correct me if this is way off.
In the second one you probably mean:
html`<svg width="width" height="height"></svg>`
These will create slightly different svg elements, check the Observable stdlib docs. DOM.svg also specifies a viewBox in the svg element it creates.
Yep, the html function conveniently closes all HTML tags in the string.
Great, your explanation for the foo makes a lot of sens if the three lignes are in the same cell but if each is in a different cell then foo may be rendered when select search the DOM tree.
But in the latter case there is still a difference with the _parents
If a cell references a variable bouton2, the referencing cell will wait until the cell that defines bouton2 runs (and adds the button to the DOM) before running. Thus the referencing cell will see the bouton2 as an HTMLButtonElement that has been added to the DOM. In addition, the referencing cell will re-run automatically whenever the defining cell runs, for example if you change the definition or if the definition depends on some other changing value.
On the other hand, if a cell says
it might run before the bouton2 cell runs, or it might not, meaning it’s uncertain whether it will find a matching element. Additionally, such a cell would not re-run automatically when the bouton2 definition changes, because Observable can’t see the dependency between the two cells.
This is likely just a coincidence. The order is not guaranteed. And equally important, cells are re-evaluated only if a cell they reference changes (other than running them explicitly). Dependencies should be explicit.