Public
Edited
May 2, 2023
Insert cell
Insert cell
<div>
<svg width="500" height="500">
<g id="layer1">
<rect x="20" y="20" width="150" height="50" style="fill:red;"></rect>
<text x="25" y="40">Layer 1, red box</text>
</g>
<g id="layer2">
<circle cx="400" cy="150" r="100" style="fill: blue;"></circle>
<text x="400" y="160" text-anchor="middle" style="fill: white;">Layer 2, blue circle</text>
</g>
<g id="layer3">
<path d="M125,250 L250,400 350,300 450,375" style="fill: #ddd; stroke: green; stroke-width: 10px"></path>
<text transform="translate(180,270) rotate(21)">Layer 3, green path</text>
</g>
</svg>

<div id="controls">
<h2>Clever title</h2>
<div>
Turn layers on or off:<br />
<button id="btn-one-on">1 On</button><button id="btn-one-off">1 Off</button> - <button id="btn-one-only">1 Only</button><br />
<button id="btn-two-on">2 On</button><button id="btn-two-off">2 Off</button> - <button id="btn-two-only">2 Only</button><br />
<button id="btn-three-on">3 On</button><button id="btn-three-off">3 Off</button> - <button id="btn-three-only">3 Only</button><br />
<br />
<button id="btn-allOn">All On</button>
<button id="btn-allOff">All Off</button>
<br /><br />
Toggle on/off:<br />
<button id="btn-one-toggle">Layer 1</button><br />
<button id="btn-two-toggle">Layer 2</button><br />
<button id="btn-three-toggle">Layer 3</button><br />
<br /><br />
with a slider: <input id="slider" name="slider" type="range" min="1" max="3" step="1" />
</div>
</div>

<style>
/* and the buttons and slider can be styled to whatever we want, including CSS :hover styles */
#controls {position: absolute; right: 250px; top: 20px; width: 300px; font-size: 12px; font-family: Helvetica,Arial,sans-serif;}
button {border: 1px solid #aaa; border-radius: 5px; background-color: #eee; font-size: 10px;}
button:hover {cursor: pointer; background-color: #ccc;}
input#slider {width: 100px;}
</style>
<!-- and now end the overall container -->
</div>
Insert cell
viz = d3.select(vizContainer)
Insert cell
{
// then we attach an .on("click", () => doSomething) to each of the buttons or control inputs above.
const btns = d3.select(vizContainer).select("#controls");

// register event listeners
btns.select("#btn-one-on").on("click", () => layerOn("layer1"));
btns.select("#btn-one-off").on("click", () => layerOff("layer1"));
btns.select("#btn-one-only").on("click", () => layerOnlyOn("layer1"));
btns.select("#btn-two-on").on("click", () => layerOn("layer2"));
btns.select("#btn-two-off").on("click", () => layerOff("layer2"));
btns.select("#btn-two-only").on("click", () => layerOnlyOn("layer2"));
btns.select("#btn-three-on").on("click", () => layerOn("layer3"));
btns.select("#btn-three-off").on("click", () => layerOff("layer3"));
btns.select("#btn-three-only").on("click", () => layerOnlyOn("layer3"));

btns.select("#btn-allOn").on("click", allOn);
btns.select("#btn-allOff").on("click", allOff);

btns.select("#btn-one-toggle").on("click", () => layerToggleOnOff("layer1"));
btns.select("#btn-two-toggle").on("click", () => layerToggleOnOff("layer2"));
btns.select("#btn-three-toggle").on("click", () => layerToggleOnOff("layer3"));

btns.select("#slider").on("input", (evt) => layerOnlyOn("layer" + evt.target.value));
}
Insert cell
layerOff = (id) => {
viz.select("#" + id).style("visibility","hidden")
}
Insert cell
layerOn = (id) => {
viz.select("#" + id).style("visibility","visible")
}
Insert cell
layerToggleOnOff = (id) => {
let layer = viz.select("#" + id);
if (layer.style("visibility") == "hidden") {
layer.style("visibility","visible");
} else {
layer.style("visibility","hidden");
}
}
Insert cell
allOn = () => {
viz.selectAll("g").style("visibility","visible")
}
Insert cell
allOff = () => {
viz.selectAll("g").style("visibility","hidden")
}
Insert cell
layerOnlyOn = (id) => {
allOff();
viz.select("#" + id).style("visibility","visible")
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more