# Display layers with d3js without rewriting the whole map?

**URL:** https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518
**Category:** Help
**Created:** [January 13, 2023, 3:35pm UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518 "2023-01-13T15:35:49Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![neocarto](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/neocarto/32/6554_2.png) [@neocarto](https://talk.observablehq.com/u/neocarto)
#### Post date: [January 13, 2023, 3:35pm UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/1 "2023-01-13T15:35:49Z")

</div>

Small question about d3.js… I made a small example of a notebook that allows you to display a map and to choose the layers to display.

> **[Display layers with d3js ?](https://observablehq.com/d/1668ebf08bd6f36e)**
>
> Params Data

But by doing so, I rewrite the entire map each time. What would be a good way to display/hide layers without redrawing the whole map each time?

---

<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: [January 13, 2023, 5:26pm UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/2 "2023-01-13T17:26:04Z")

</div>

The general idea is to attach an update function to the SVG and then add a cell that calls that update function in response to a change in the input. That reaction cell refers to the button but the map does not. As a bonus, it’s not now easy to fade the layers in and out using a transition.

Here’s your map using this approach:

https://observablehq.com/embed/fa857a4a762bb6a7@130?cells=viewof+layers%2Cmap%2Creact

---

<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: [January 14, 2023, 12:39am UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/3 "2023-01-14T00:39:42Z")

</div>

If you want to avoid using side effect cells, you can instead invert control by listening for input events from within your chart. Here is an adaptation of Mark’s example. Place this code at the end of your `map` cell.

```javascript
  // ...
  function fade(group, opacity, duration = 500) {
    group.transition().duration(duration).attr("opacity", opacity);
  }
  
  for await(const layers of Generators.input(viewof layers)) {
    for(const name of ["aus", "ports", "roads"]) {
      const group = svg.select(`g.${name}`).interrupt();
      const opacity = group.attr("opacity");
      const selected = layers.includes(name);
      if(selected && opacity < 1) fade(group, 1);
      else if(!selected && opacity > 0) fade(group, 0);
    }
    yield svg.node();
  }
}

```

---

<div class="post-metadata">

### Author: ![stardisblue](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/stardisblue/32/4456_2.png) [@stardisblue](https://talk.observablehq.com/u/stardisblue)
#### Post date: [January 21, 2023, 8:21pm UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/4 "2023-01-21T20:21:39Z")

</div>

A little bit late but I usually reuse the cell’s `this` object to avoid having side effect cells. I find mootari’s solution more “the observable way”. but here is an example of what i’m talking about (solution 4):

> **[How to display and hide layers with Observable & d3js?](https://observablehq.com/d/93e3e38c954a5878)**
>
> With Observable, we have the advantage of working in a fully responsive environment. Let's see how it is possible to simply show and hide the layers of a map. 1. Basic solution The first solution is to draw a map with the \`d3.js\` library. Then, using...

---

<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: [January 22, 2023, 12:04am UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/5 "2023-01-22T00:04:36Z")

</div>

@stardisblue It’s pretty cool the way that you’ve gathered several of these approaches into one notebook! I’ve just sent you a suggestion that includes yet another approach, which might seem natural to anyone who started with D3 nearly 10 years ago.

---

<div class="post-metadata">

### Author: ![stardisblue](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/stardisblue/32/4456_2.png) [@stardisblue](https://talk.observablehq.com/u/stardisblue)
#### Post date: [January 23, 2023, 2:19pm UTC](https://talk.observablehq.com/t/display-layers-with-d3js-without-rewriting-the-whole-map/7518/6 "2023-01-23T14:19:50Z")

</div>

You give me too much credit, I simply forked the notebook 😃.  
I still merged your contribution for completness.
