# Combining Inputs.select and drill down chart

**URL:** <https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279>\
**Category:** Help\
**Created:** [February 23, 2022, 12:31pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279 "2022-02-23T12:31:45Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![FionaEBI](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fionaebi/32/6086_2.png) [@FionaEBI](https://talk.observablehq.com/u/FionaEBI)\
**Post date:** [February 23, 2022, 12:31pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/1 "2022-02-23T12:31:45Z")

</div>

Hello,  
I would welcome advice, please? How do I combine an ‘Inputs.select’ drop-down menu with a drill-down chart? Currently when I drill down to a second level of chart, and then change the ‘Inputs.select’ drop-down menu, then the chart resets to the upper (default) chart.

A example is provided here: [Test2 drill down-drill up plot with dropdown input / fionaebi / Observable](https://observablehq.com/d/be881c11b52b29ee)

For example, I would like to drill down from the ‘rectangles’ chart to the ‘circles’ chart, and then change the drop-down menu from e.g. ‘ClinChem’ to ‘Hematology’ and stay with the ‘circles’ chart for the updated ‘Hematology’ data. Currently, the chart resets to show the upper level ‘rectangles’ chart for the updated ‘Hematology’ data.

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [February 24, 2022, 9:30am UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/2 "2022-02-24T09:30:22Z")

</div>

I got a bit overwhelmed trying to fix your chart directly (sorry, maybe I’m sleepy!) but I put together a stripped-down example that might help: [Combining Inputs with internal interactivity in a chart / Toph Tucker / Observable](https://observablehq.com/@tophtucker/combining-inputs-with-internal-interactivity-in-a-chart)

The core idea is that, if a cell references another cell, the cell re-runs entirely when the cell it depends on changes. So, if your chart depends on an Input, the _whole chart_ gets destroyed and recreated every time the Input changes.

The trick is that a chart is a DOM node, and a DOM node is a JavaScript object, and you can stick functions onto that object and call them. So we stick an `update` method onto the chart and return it with the chart. Then, a _different_ cell refers to the Input (so it’ll re-run whenever the Input changes) and calls the update method each time with the value of the Input.

That way, you can run _only_ the code in `update`, and it can change the existing chart without destroying it.

---

<div class="post-metadata">

**Author:** ![mcmcclur](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mcmcclur/32/2364_2.png) [@mcmcclur](https://talk.observablehq.com/u/mcmcclur)\
**Post date:** [February 24, 2022, 12:14pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/3 "2022-02-24T12:14:26Z")

</div>

> [@tophtucker](#):
>
> I got a bit overwhelmed trying to fix your chart directly

I had the same issue; a lot of subtle interdependencies in the original notebook.

FYI: Your notebook doesn’t seem to work in Firefox on my Mac.

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [February 24, 2022, 8:59pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/4 "2022-02-24T20:59:54Z")

</div>

> [@mcmcclur](#):
>
> FYI: Your notebook doesn’t seem to work in Firefox on my Mac.

Oh interesting, it works for me in Firefox for Mac, v97. What do you see broken?

---

<div class="post-metadata">

**Author:** ![mcmcclur](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mcmcclur/32/2364_2.png) [@mcmcclur](https://talk.observablehq.com/u/mcmcclur)\
**Post date:** [February 25, 2022, 10:12am UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/5 "2022-02-25T10:12:40Z")

</div>

> [@tophtucker](#):
>
> What do you see broken?

The problem, evidently, is that I don’t know how to use Firefox. 😕  
Sorry for the confusion!

---

<div class="post-metadata">

**Author:** ![FionaEBI](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fionaebi/32/6086_2.png) [@FionaEBI](https://talk.observablehq.com/u/FionaEBI)\
**Post date:** [February 25, 2022, 12:26pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/6 "2022-02-25T12:26:09Z")

</div>

Dear tophtucker,  
Many thanks for your prompt and helpful simplified code example and explanation about the ‘update’ method. I’ve reworked my approach to apply these suggestions, and have now got a version up and running, which is great.  
I completely understand that my original posted example was a bit too complicated 🙂  
Much appreciated!

---

<div class="post-metadata">

**Author:** ![FionaEBI](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fionaebi/32/6086_2.png) [@FionaEBI](https://talk.observablehq.com/u/FionaEBI)\
**Post date:** [February 25, 2022, 12:36pm UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/7 "2022-02-25T12:36:09Z")

</div>

BTW The only thing that I don’t understand about your solution code is why the line “// Call render once initially // render();” is required. The code seems to work with or without this line included?  
Thanks

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [March 1, 2022, 1:26am UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/8 "2022-03-01T01:26:37Z")

</div>

Glad it helped, and good question! You don’t need that initial `render` call if you _know_ that `chart.update(color)` is gonna run and call `render` inside `update`. In this case, we do know that. But if you didn’t have the update cell — e.g., if you wanted to reuse this chart somewhere as a static thing without controls — then it wouldn’t. So I guess it just felt like a good practice here to have the update code also run on initialization.

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [March 1, 2022, 1:27am UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/9 "2022-03-01T01:27:16Z")

</div>

(Another weird thing (added to the end of the notebook) is that if you want to import the chart into another notebook, you also have to import and run the update cell!)

---

<div class="post-metadata">

**Author:** ![mootari](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mootari/32/581_2.png) [@mootari](https://talk.observablehq.com/u/mootari)\
**Post date:** [March 1, 2022, 11:06am UTC](https://talk.observablehq.com/t/combining-inputs-select-and-drill-down-chart/6279/10 "2022-03-01T11:06:21Z")

</div>

> [@tophtucker](#):
>
> Another weird thing (added to the end of the notebook) is that if you want to import the chart into another notebook, you also have to import and run the update cell!)

The alternative would be to not use a cell that has side effects, but instead reference the select (or color in Toph’s case) input via its `viewof` prefix. That way the `chart` cell won’t be invalidated when the value changes:

```javascript
viewof myInput = Inputs.select(/* ... */)

```

```javascript
chart = {
  const sel = d3.select(/* ... */);
  const input = viewof myInput;

  // Draw the chart for the first time.
  updateChart(input.value);

  // Redraw the chart whenever the selection changes.
  input.addEventListener('input', updateChart);
  // Remove event handler when this cell is invalidated.
  invalidation.then(() => input.removeEventListener('input', updateChart));

  return sel.node();

  function updateChart() {
    const value = input.value;
    // do update stuff
  }
}

```
