I would first try to approach this from a conceptual point of view. From what I can tell your Dark Mode toggle acts more like a preset, since I can change the affected sliders afterwards without the toggle getting deselected, in which case I would make it a button (and maybe even move it above the form).
If on the other hand it is in fact a modifier then I would recommend to not change the sliders, but apply the changes in your final calculations.
If you still need to include the button or toggle in your form, then I would recommend to use Inputs.form() with the template option instead for this particular scenario:
Thank you very much!, I have simplify the input by separating into two blocks as suggested.
Another thing that would be nice is to enable the input scroll Zoom (p.scrollZoom) when fullscreen is enable (I don’t want user to be stuck when scrolling down the page and the chart start zooming instead). I have tried the following function:
fullscreen = {
const button = html`<button> Go Full Screen`;
button.onclick = () => {
button.parentElement.nextElementSibling.requestFullscreen();
};
return button;
}
But it fails with a simple redefinition of the p.scrollZoom variable. I think that using input.dispatchEvent would be the way forward, but it is pretty obscure how this works.
From what I can tell d3-zoom offers no method to toggle zooming or ignore a zoom event - the internal transform will always get updated even if you choose to not apply it.
My recommendation would be to conditionally remove the event handlers on fullscreen change:
const zoom = d3.zoom().on("zoom", zoomed);
const toggleZoom = enabled => enabled
// Attach zoom handlers
? svg.call(zoom)
// Remove all *.zoom event handlers
: svg.on(".zoom", null);
// Initialize
toggleZoom();
svg.on("fullscreenchange", (e) => {
// Enable zooming if svg.node() is the fullscreen element
toggleZoom(e.target === document.fullscreenElement)
});
function zoomed({ transform }) {
svg.attr("transform", transform);
}
// --- alternative zoom from https://talk.observablehq.com/t/update-value-of-another-input-when-an-input-is-triggered-in-a-multi-input-single-object/8532/3 independant of toogle and allow zoom only on fullscreen --- //
document.addEventListener("fullscreenchange", function () {
console.log("fullscreenchange event fired!");
});
const zoom = d3.zoom().scaleExtent(0.1, 8).on("zoom", zoomed);
const toggleZoom = (enabled) =>
enabled
? // Attach zoom handlers
svgOrigin.call(zoom)
: // Remove all *.zoom event handlers
svgOrigin.on(".zoom", null);
// Initialize
toggleZoom();
document.addEventListener("fullscreenchange", (e) => {
// Enable zooming if svg.node() is the fullscreen element
console.log(e);
console.log(document.fullscreenElement);
console.log(e.target === document.fullscreenElement);
toggleZoom(e.target === document.fullscreenElement);
});
at the end of the code of the chart cell, with a few testing log and the log says it works and toggleZoom() is supposed to be ON, but there is no zoom or pan in fullscreen…
before you start testing with toggleZoom(). You’ll notice that zooming is already broken here, and if you log transform in zoomed you’ll see several NaN values because scaleExtent expects an array:
Very good ! you were right, I made a mistake in the argument of the function scaleExtent(). It all works nicely now. Thank you very much for your help.
If you have more patience, I have been trying to reset the position of the chart to (0,0) and scale 1 when exiting the full screen mode. I have tried using the translateExtent() function. It does the job but I wonder if there is a better solution (it is a bit complicated as there is a toggle p.scollZoom that allow to zoom and pan in no fullscreen mode) :
Anyway, thank you for your help, awesome. I wish there would be a template for basic chart display with options, fulscreen mode, dowload high resolution, etc.
Be sure to take a look at the d3-zoom docs. There you’ll find an example to reset a zoom transform, which you need to apply before you remove the handlers so that your SVG can still update: