🏠 back to Observable

How do you get a referenced cell to always show its name, even when collapsed?

In the image below totals_donut, legend, and multiple referenced into the code displayed. Once they are referenced they don’t show their name in the cell list and so are difficult to find when collapsed.

  1. Should something show for those cells, even though they are being rendered elsewhere?
  2. In the short term, is there a way to get something to show by their cell/code?

A DOM element can only have one parent element. By including the elements in your top cell you simultaneously remove them from their original cell outputs.

If your elements aren’t dynamic, you can reference their outerHTML:

<div>${totals_donuts.outerHTML}</div>

However, I would recommend to instead wrap them in functions which return a fresh element on each call:

totals_donuts = function() {
  return html`<!-- ... your markup -->`;
}
<div>${totals_donuts()}</div>

The added benefit is that this pattern allows you to pass additional options into your factory functions, like e.g., color, width or even data.

1 Like

Thanks for that info. I’ll try to use that, but…

Would still like Observable to smart enough to show the name of the element in that situation.

It can’t. Each of your cells returns an HTML element, so Observable’s Inspector decides to render them as-is. But then, after the cell output was processed, you remove each element from its cell wrapper. There’s no sensible way for the inspector to handle this case.

If your cell would instead return an element which already has a parent element, e.g.:

foo = {
  const a = html`<div>`;
  const b = html`<div>${a}`;
  return a;
}

the cell would display as

foo = ▶ HTMLDivElement {}

If you want your cells to display some dynamic HTML, and be reusable, I would suggest using viewof plus the factory pattern:

viewof totals_donut = {
  const createElement = function() { /* return a DOM element */ };
  const view = createElement(); // This gets displayed as the cell output
  view.value = createElement; // this is the actual cell value
  return view;
}

Hmmm. Tried that. The cell the code is in displayed the viz but the cell it was included in displayed this.

I understand that you have a technical model you are following…

But…that solution means that either the user ends up with “unnamed” cells or has to learn somewhere to write the code you suggested above. Neither of those is a good solution for a beginning user and so is a bad user experience for a tool trying to encourage people to learn D3.

Because it’s a function, so you have to call it. Simply including it will only give you the function’s source code as a string.

“beginning user” is a very broad range, and an author’s level of experience is impossible to judge without looking at their code. For future posts I encourage you to include a notebook link that gives more context to the problem and allows other users to offer concrete suggestions.

And to avoid any misunderstandings, I don’t work for Observable, so someone from the team will have to comment on the other claims.

I too found the way HTML gets yanked out of one place to be included in another to be surprising behavior, and was pretty confused by it for a long time, even if it ultimately “makes sense” technically. It makes it hard to compose larger views out of smaller views while keeping both the pieces and the whole inspectable.

Like Fabian, I’ve moved toward wrapping the HTML in a function that returns an element as soon as I want them to be reusable. But I too wish there were a better way, since the function signature you get in the inspector is unsatisfying.

As for the cell names, Observable used to (c. 2018) always show them in the left gutter:

I think it was removed for the sake of smaller screens. And in other cases, the new way is cleaner. But the old way has certain advantages.

I made this notebook shows the problem based on @mootari’s feedback.

Try to guess where cells are, let alone ID’ing red, green or blue.

Seems that a technical philosophy is impeding a good user experience. However, the left gutter names would solve this. Would be a good option to be able to turn on/off. On for debugging, Off for presentation.