finishing touches on a range slider | d3-simple-slider

Searching for a range slider (not available at Jeremy’s input bazare) , I came across d3-simple-slider, which I almost have working:

The problem seems to be that the demo examples, as hosted on bl.ocks refers to both the d3-simple-slider module and d3 as d3. I give the module an explicit name (d3_slider) and it appears in my notebook, but it’s doesn’t work.

I tried linking d3 and the d3-simple-slider module as follows, but this doesn’t seem to ‘link’ both d3 and the module under the name d3:

d3 = {
  const d3 = await require('d3@5');
  await require('d3-simple-slider@1.4.1/build/d3-simple-slider.js');
  return d3;
}

Any ideas on what’s missing?

Thanks for your insights!

I haven’t tried to make your notebook work yet, but I think the solution to the require question is just to use multiple parameters in require (see the discussion here):

d3 = require('d3@5', 'd3-simple-slider@1.4.1/build/d3-simple-slider.js')
1 Like

Thanks Bryan! That method of requiring does get around the linking of d3 and the module. The notebook still doesn’t work with this fix though :frowning: not sure why.

Likely because d3-simple-slider accesses d3.event in a different scope than the one used by d3. As a result, when d3 sets d3.event, d3Selection.event inside the slider scope is still null.

2 Likes

Woah, @mootari - Perfect answer, and yet I’ll one I’ll have to research before I can pretend to understand :wink: Still - THANK YOU! I’ll see what I can do to figure out what this means… and why the behavior would differ in Observable vs. the HTML examples.

All you need to do is to alias d3-selection to d3:

d3 = require.alias({'d3-selection': 'd3'})('d3@5', 'd3-simple-slider@1.4.1')

and then access the slider via d3.sliderBottom.

With the aliased require d3-simple-slider will be fed the d3 module instead of d3-selection.

1 Like

Awesome! Thank you both @mootari & @bgchen !

You’re very welcome! And remember that the require function is actually d3-require (in case you want to look up the documentation).

As for debugging issues like these, my strategy usually involves opening the dev tools and enabling “Pause on exceptions”. This will give you the opportunity to inspect the scope in which the error occured, as well as the function calls leading up to the error.

2 Likes

… Too funny, but now that this is working, I still have to get past the hurdle of figuring out how to pass the values to another cell :sweat:

Nice tip!

I’d try this pattern (untested, and assuming that sliderBottom() returns a d3 selection):

viewof slider = {
  const slider = d3.sliderBottom();
  const view = slider.node();
  slider.on('onchange', val => {
    view.value = val;
    slider.dispatch('input');
 });
  return view;
}

You’ll also want to think about what kind of API you want to offer. That is, what arguments your slider factory function should receive.

1 Like

Thanks for the lead! I’ll play around and see what I can manage.