Repository: h2oai/wave
File: ui/src/plot.tsx (TypeScript)

Code before:
    stack,
    dodge, dodge_field,
    curve,
    fill_color, fill_opacity, stroke_color, stroke_opacity, stroke_dash, stroke_size,
    label_field, label_format, label_offset, label_offset_x, label_offset_y, label_rotation, label_position, label_overlap,
    label_fill_color, label_fill_opacity, label_stroke_color, label_stroke_opacity, label_stroke_size,
    label_font_size, label_font_weight, label_line_height, label_align,
  }: MarkExt): GeometryOption => {
    const o: GeometryOption = {}
    if (isS(type)) o.type = type

    const adjust: AdjustOption[] = []
    // TODO set marginRatio=1 polar coords
    if (isS(dodge_field)) {
      adjust.push({ type: 'dodge', marginRatio: 0, dodgeBy: dodge_field })
    } else if (dodge === 'auto') {
      adjust.push({ type: 'dodge', marginRatio: 0 })
    }
    if (stack === 'auto') adjust.push({ type: 'stack' })
    if (adjust.length) o.adjust = adjust
    if (isS(x_field) && isS(y_field)) o.position = { fields: [x_field, y_field] }
    if (isS(color_field)) {
      const values = isS(color_range) ? split(color_range) : cat10
      o.color = { fields: [color_field], values }
      if (color_domain?.length && color_domain.length == values.length) {
        o.color.callback = (x: any) => values[color_domain.indexOf(x)]
      }
    } else {
      o.color = isS(color) ? color : theme.colors.gray
    }
    if (isS(shape_field)) {
      if (isS(shape_range)) {
        o.shape = { fields: [shape_field], values: split(shape_range) }
      } else {
        o.shape = { fields: [shape_field] }
      }
    } else if (isS(shape)) {
      o.shape = shape
    }
    if (isS(size_field)) {
      if (isS(size_range)) {
        o.size = { fields: [size_field], values: parseInts(size_range) }
      } else {
        o.size = { fields: [size_field] }
      }
    } else if (isF(size)) {
      o.size = size
    }
    if (isS(label_field)) {
      const styles = makeTextStyle(
        label_fill_color, label_fill_opacity, label_stroke_color, label_stroke_opacity, label_stroke_size,

Review comment (suggestion):
```suggestion
        o.color.callback = (x: S) => values[color_domain.indexOf(x)]
```

Code after:
    stack,
    dodge, dodge_field,
    curve,
    fill_color, fill_opacity, stroke_color, stroke_opacity, stroke_dash, stroke_size,
    label_field, label_format, label_offset, label_offset_x, label_offset_y, label_rotation, label_position, label_overlap,
    label_fill_color, label_fill_opacity, label_stroke_color, label_stroke_opacity, label_stroke_size,
    label_font_size, label_font_weight, label_line_height, label_align,
  }: MarkExt): GeometryOption => {
    const o: GeometryOption = {}
    if (isS(type)) o.type = type

    const adjust: AdjustOption[] = []
    // TODO set marginRatio=1 polar coords
    if (isS(dodge_field)) {
      adjust.push({ type: 'dodge', marginRatio: 0, dodgeBy: dodge_field })
    } else if (dodge === 'auto') {
      adjust.push({ type: 'dodge', marginRatio: 0 })
    }
    if (stack === 'auto') adjust.push({ type: 'stack' })
    if (adjust.length) o.adjust = adjust
    if (isS(x_field) && isS(y_field)) o.position = { fields: [x_field, y_field] }
    if (isS(color_field)) {
      const colors = isS(color_range) ? split(color_range) : cat10
      o.color = { fields: [color_field], values: colors }
      if (color_domain && color_domain.length == colors.length) {
        const domain_colors = color_domain.reduce((acc, value, i) => {
          acc[value] = colors[i]
          return acc
        }, {} as Dict<S>)
        o.color.callback = (x: S) => domain_colors[x]
      }
    } else {
      o.color = isS(color) ? color : theme.colors.gray
    }
    if (isS(shape_field)) {
      if (isS(shape_range)) {
        o.shape = { fields: [shape_field], values: split(shape_range) }
      } else {
        o.shape = { fields: [shape_field] }
      }
    } else if (isS(shape)) {
      o.shape = shape
    }
    if (isS(size_field)) {
      if (isS(size_range)) {
        o.size = { fields: [size_field], values: parseInts(size_range) }
      } else {
        o.size = { fields: [size_field] }
      }
    } else if (isF(size)) {
      o.size = size