opened
saulshanabrook
username_0
I have a discrete field and I am able to map different colors to it's different values. However, I would like to have a final color map to all the other colors which I didn't set up a mapping for.

This might be possible already and I was just unable to find it.

The motiviation is reproducing MapD's example of plotting dots for each tweet colored by country: https://www.omnisci.com/docs/latest/6_vegaTutorials.html#getting-more-from-your-data-1

In their custom Vega they have a way of specifying a default value:

```json
"scales:" [
     .
     .
     .
  {
    "name": "color",
    "type": "ordinal",
    "domain": ["en",  "es", "fr"],
    "range": ["#27aeef", "#87bc45", "#ef9b20"],
    "default": "gray",
    "nullValue": "#cacaca"
  }
]
```
Allow setting default in ordinal range for color
issue
created
domoritz
username_1
Moved
comment
created
saulshanabrook
username_0
I believe so or in LLVM. Since it is executed against their in memory database on the GPU. I don't know if that code is open source.
comment
created
kanitw
username_2
In any case, one quick solution is to do the following:

```
{
    "name": "color",
    "type": "ordinal",
    "domain": ["en",  "es", "fr", "other"], 
    "range": ["#27aeef", "#87bc45", "#ef9b20", "gray"],
    "nullValue": "#cacaca"
  }
```

then derive a new field based on this formula `{"en": "en", "es": "es", "fr": "fr"}[datum.old_field] || "other"`.  Then basically you get a new field with four possible values.
comment
created
saulshanabrook
username_0
Ah nice, thanks for that snippet.
comment
created
kanitw
username_2
I think it is actually still useful from a theming perspective.  Users may want to consistently color null/undefined/invalid value as grey.  

That said, I agree that D3 might be the right level to support this kind of things.
comment
created
roying
username_3
In Vega 4.3.0, this signal expression works in assigning a "default" or "else" scale value:

```
"scales": [
  {
      "name": "color",
      "type": "ordinal",
      "domain": {
        "data": "table",
        "field": "category"
      },
      "range": ["red", "blue", "green", "yellow"]
    }
...

	"fill": {"signal": "indexof(domain('color'), datum.category) <  length(range('color')) ? scale('color', datum.category) : 'grey' "}
```
comment
created
jheer
username_4
An even simpler (and more efficient) expression would be:

`scale('color', datum.category) || 'grey'`

This will work so long as the scale domain is defined and `domainImplicit` is not set to `true`.

Also: Under the hood, D3 does support setting an `unknown` value on ordinal scales, however, this will  return a default value for **any** value not included in the domain, not just null or missing data. One option for Vega could be to leverage that functionality, so long as those semantics are acceptable.
comment
created
domoritz
username_1
```ts
scale('color', datum.category) || 'grey'
```

Is simple enough that we could consider generating this expression in Vega-Lite. This way we could support a `default` value.
comment
created
kanitw
username_2
I think this semantic is okay for handling the "default/unknown/else" case.  It would only be useful when users know a few values that they care about like `["en",  "es", "fr"]`.  But for data-driven domain (default in VL), the unknown case wouldn't happen.  

`scale('color', datum.category) || 'grey'` still doesn't work for handling null value in Vega-Lite though, since Vega-Lite uses data-driven domain. Thus, if the data includes null (or undefined), they will still be included as one of the domain values. 

We can sort of get around this using a conditional rule. However, `null` wouldn't then be included in the legend.

If we want to include null in the legend, then we still need to do something more. 

a) If there is a way to combine range, then we can do something like: 

```
"domain": {"fields": [[null],{"data": "source_0", "field": "Major_Genre", "sort": true}]},
"range": // some syntax to concatenate grey with scheme 
```

but it won't work for undefined.   

b) Another solution would be simply adding a legend without title with only null value and just its color. (This probably also works for null/invalid value of quantitative/sequential color scale.)  The trick part is then showing this legend only when the data field contains null.
comment