can functions be values of radio buttons

I have a couple a functions
they’re in an array
I can make a radio switch using values 0,1… toward function number in the array and use the function by array[valuechoosen]()…and this works
I was wondering wether the function (names) could be passed straightfully as value in the radio switch, but then the viewof my radio select turns into string of the function…

ways=[d3.scaleLinear,d3.scaleLog]
viewof whichf = radio({
  options: [
    { label: 'linear', value: 0 },
    { label: 'log', value: 1},
    ],
  value: 0
})
fx={
return ways[whichf]()
  .domain([0.001, 10])
    .range([0,100])
}

fx(5) works…

But I would like to do something like :

viewof whichf = radio({
  options: [
    { label: 'linear', value: d3.scaleLinear },
    { label: 'log', value: d3.scaleLog},
    ],
  value: d3.scaleLinear
})

afterthat whichf contains the text of the function…
and is of type string…

I don’t think that’s supported by Jeremy’s radio input, but you can certainly do it yourself. Here’s an example with a select input, but you could adapt the code to use radio buttons instead.

Here’s the source for the input:

viewof tile = {
  const options = [
    {name: "d3.treemapBinary", value: d3.treemapBinary},
    {name: "d3.treemapDice", value: d3.treemapDice},
    {name: "d3.treemapSlice", value: d3.treemapSlice},
    {name: "d3.treemapSliceDice", value: d3.treemapSliceDice},
    {name: "d3.treemapSquarify", value: d3.treemapSquarify, selected: true}
  ];
  const form = html`<form style="display: flex; align-items: center; min-height: 33px;"><select name=i>${options.map(o => Object.assign(html`<option>`, {textContent: o.name, selected: o.selected}))}`;
  form.i.onchange = () => form.dispatchEvent(new CustomEvent("input"));
  form.oninput = () => form.value = options[form.i.selectedIndex].value;
  form.oninput();
  return form;
}

The key part is the form.value assignment, which pulls from the options array.

1 Like

ok thanks I was suspecting the radio import nature…
thanks for reformatting my post also… I’m new to this :slight_smile:

I’ll have a test without importing and using raw materials.
Thanks a lot !

Just for the record, you can still use string references:

viewof whichf = radio({
  options: [
    { label: 'linear', value: 'scaleLinear' },
    { label: 'log', value: 'scaleLog'},
    ],
  value: 'scaleLinear'
})
d3[whichf]()(123)

… or even wrap everything:

viewof whichf = Object.defineProperty(
  html`<div>${radio({
    options: [
      { label: 'linear', value: 'scaleLinear' },
      { label: 'log', value: 'scaleLog'},
      ],
    value: 'scaleLinear'
  })}`,
  'value',
  {get() { return d3[this.firstChild.value] } }
) 
whichf()(123)
3 Likes

wowie zowie, that’s the winner, didn’t think could access the functions in library that way…
I prefer really this solution to my array of function indexed values

Big Big thanks :slight_smile:

1 Like

You can expand that technique further to generate the available options. E.g., to create entries for every scale* function, except scaleDiverging* and scaleSequential*, use:

const options = Object.keys(d3)
  .filter(k => k.match(/^scale(?!Diverging|Sequential)/))
  .map(k => ({
    // strip "scale" prefix and convert first character to lowercase
    label: k.slice(5, 6).toLowerCase() + k.slice(6),   
    value: k
  }));
3 Likes