scale.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Color } from './color'
  7. import { ColorBrewer } from './tables'
  8. import { ScaleLegend } from 'mol-theme/color';
  9. import { defaults } from 'mol-util';
  10. export interface ColorScale {
  11. /** Returns hex color for given value */
  12. color: (value: number) => Color
  13. /** Copies color to rgb int8 array */
  14. colorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void
  15. /** Copies normalized (0 to 1) hex color to rgb array */
  16. normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => void
  17. /** */
  18. setDomain: (min: number, max: number) => void
  19. /** Legend */
  20. readonly legend: ScaleLegend
  21. }
  22. export const DefaultColorScale = {
  23. domain: [0, 1],
  24. reverse: false,
  25. colors: ColorBrewer.RdYlBu,
  26. minLabel: '' as string | undefined,
  27. maxLabel: '' as string | undefined,
  28. }
  29. export type ColorScaleProps = Partial<typeof DefaultColorScale>
  30. export namespace ColorScale {
  31. export function create(props: ColorScaleProps): ColorScale {
  32. const { domain, reverse, colors: _colors } = { ...DefaultColorScale, ...props }
  33. const colors = reverse ? _colors.slice().reverse() : _colors
  34. const count1 = colors.length - 1
  35. let diff = 0, min = 0, max = 0
  36. function setDomain(_min: number, _max: number) {
  37. min = _min
  38. max = _max
  39. diff = (max - min) || 1
  40. }
  41. setDomain(domain[0], domain[1])
  42. const minLabel = defaults(props.minLabel, min.toString())
  43. const maxLabel = defaults(props.maxLabel, max.toString())
  44. function color(value: number) {
  45. const t = Math.min(colors.length - 1, Math.max(0, ((value - min) / diff) * count1))
  46. const tf = Math.floor(t)
  47. const c1 = colors[tf]
  48. const c2 = colors[Math.ceil(t)]
  49. return Color.interpolate(c1, c2, t - tf)
  50. }
  51. return {
  52. color,
  53. colorToArray: (value: number, array: Helpers.NumberArray, offset: number) => {
  54. Color.toArray(color(value), array, offset)
  55. },
  56. normalizedColorToArray: (value: number, array: Helpers.NumberArray, offset: number) => {
  57. Color.toArrayNormalized(color(value), array, offset)
  58. },
  59. setDomain,
  60. get legend() { return ScaleLegend(minLabel, maxLabel, colors) }
  61. }
  62. }
  63. }