Redefine a value for viewof ?

I’m trying to build dynamic display of input based on availability of data/metadata.

I defined a fallback values for computation/test on other cells :

viewof typeOfGrowth = undefined

Needed for test in others cells :

 growthSeriesFiltered = { 
      if (typeOfGrowth !== undefined )
      { return "blabla"
      else
      {
        return "bla"
      }
    }

But, i’m blocked by redefinition of the viewof, i try this without success :

    {
      if (myArray.length) {
      
      typeOfGrowth = checkbox({
      title: "Croissance",
      description: "Affichage de la croissance entre deux dates",
      options: metadata_opt(sources,typeOfGraph),
      submit: false
    })
      } 
      else { return undefined}
    }

return
SyntaxError: Assignment to constant variable typeOfGrowth

Hi @reyman, do you mind sharing your notebook to provide more context on what you want to achieve?

Observable uses dataflow, so cells aren’t allowed to change the value of other cells. Rather than assigning typeOfGrowth in another cell, you’d need to combine that into the definition of viewof typeOfGrowth.

viewof typeOfGrowth = {
  if (myArray.length) {    
    return checkbox({
      title: "Croissance",
      description: "Affichage de la croissance entre deux dates",
      options: metadata_opt(sources, ???),
      submit: false
   });
  }
}

(There are limited ways to assign cells from other cells with mutation, but there are usually cleaner ways to implement it, so I recommend exploring the cleaner ways first.)

I’d strongly recommend to think of your display as a component with its own API. I’ve put together a quick example here:

Edit: Added some manual controls to make it a bit clearer. Happy to extent the descriptions, just let me know which parts you find hard to understand.

1 Like

I’ve expanded the examples and features a bit:

Yes, my observable is here : https://observablehq.com/@reyman/covid

Sorry for the code quality, i’m discovering little by little all the power of d3/observable, but i have some difficulties with widget building.

I build a little api of my own to serve data and metadata about different sources of covid19 data, with some added statistics.

My idea was to use metadata answer to build the different option widget :

The return of metadata REST call

        return {
            'data':
                {"ecdc":{
                    "description" : "ECDC data",
                    "type" : [{
                        "name" : "cum",
                        "label" : "Données cumulées",
                        "options":[]
                              },{
                        "name": "daily",
                        "label": "Données journalières",
                        "options":[
                            {"label":"Moyenne mobile des décés sur 3 jours",
                             "value":"rolling_deaths"}]
                    }]}
                ,"etalab": {
                    "description": "Etalab french data consolidated",
                    "type": [{
                        "name": "cum",
                        "label": "Données cumulées",
                        "options": []
                }]}
            }}

As you could see, i have two type of covid19 data :

  • cumulated for : ECDC data
  • day by day for : ECDC data and Etalab institute data

In my published observable, user could switch between sources, type of data (cumulated or daily if exists) that regenerate an url, and corresponding data are fetch from server.

I also want to display wiget to choose options if they exists, this is the options array in metadata response.

For etalab, no options and only cumulated data :

Screenshot_2020-04-28 Covid Rey Observable(2)

For Ecdc data, cumulated data with no options :

Screenshot_2020-04-28 Covid Rey Observable(1)

For Ecdc data, daily data with one option :

Screenshot_2020-04-28 Covid Rey Observable

I probably add new option later for data.

So as you could see, i need to manage different combinaisons of widget possibilities using if/else.

viewof optionsCheckbox = checkbox(checkbox_data)
  • sources = ecdc or etalab
  • typeOfGraph = daily or cum
  • metadata_opt return options available if any
checkbox_data = {
  if (metadata_opt(sources,typeOfGraph).length) {
  return {
  title: "",
  description: "",
  options: metadata_opt(sources,typeOfGraph),
  submit: false
}
  }
  else { return undefined}
}

Using this code, my idea was to check if options exist or not in metadata data. If this option exist, i display the widget and collect the corresponding data, if not exist, do nothing.

optionSeries return data used by chart to display lines. If one serie, i have one line, if many series, i have multi-lines. Actually i also compute the growth of deaths and growth of cases for each dataset (i need to report that on metadata response on server as new options for cum and daily dataset … )

For daily data, if have three series of data available in optionSeries, so three lines (growth death, growth cases, rolling deaths ). For cumulated data, i only have two series available. (growth death and growth cases).

Idea was to filter these series based on checkbox options selected by user, perhaps displaying others widget/options if needed, like window size for rolling window mean computation…

optionSeriesFiltered = { 
  if (optionsCheckbox !== undefined )
  { return optionSeries.map(s => s.filter( d => optionsCheckbox.includes(d.name))).filter(e => e.length)}
  else
  {
    return "bla"
  }
} 

Problem was when optionCheckbox is undefined, this code FAILED, because :

  • 1 - viewof optionsCheckbox = TypeError: options is undefined
  • 2 - optionSeriesFiltered = RuntimeError: optionsCheckbox could not be resolved
  • 3 - finaly, chart = RuntimeError: optionSeriesFiltered could not be resolved

I need to rethink my workflow to better handle all of this.

Great, i answer to @mbostock and i take some times to look at your observable example now !

Hi @mootari, i’m interest to create a Dashboard like you propose on your example notebook.

Could you please add an example with input?, because, it’s not clear, how other cells in my program could access to the value of a select() / checkbox() / etc. from ( https://observablehq.com/@jashkenas/inputs#checkbox ) after they are injected into the dashboard using display() function ?

I describe my use case in the latest post, as you see, i have conditionnal input :

  • if data xa is available, display x1 and x2 input,
  • if data xb is available, display x1 only, etc.

@reyman I’ve put together an example here:

Let me know if you have any questions!

Note: I’m still in the process of discovering which design patterns can be used this way. E.g., in the above example the color will reset on every change of options, which isn’t ideal, but can be mitigated by moving the colorize option into a separate cell.

1 Like