diff --git a/src/apps/canvas/assembly-symmetry.ts b/src/apps/canvas/assembly-symmetry.ts index 0fe6a734730dd50f51c2a8af3ba15af36d5c0517..f4cdb2888466a56c6f9babcc311ea010249714db 100644 --- a/src/apps/canvas/assembly-symmetry.ts +++ b/src/apps/canvas/assembly-symmetry.ts @@ -66,10 +66,10 @@ export function getClusterColorTheme(symmetryId: number, assemblySymmetry: Assem const DefaultColor = Color(0xCCCCCC) const s = assemblySymmetry.db.rcsb_assembly_symmetry const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId) - if (!symmetry) return { granularity: 'uniform', color: () => DefaultColor } + if (!symmetry) return { features: {}, granularity: 'uniform', color: () => DefaultColor } const clusters = assemblySymmetry.getClusters(symmetryId) - if (!clusters._rowCount) return { granularity: 'uniform', color: () => DefaultColor } + if (!clusters._rowCount) return { features: {}, granularity: 'uniform', color: () => DefaultColor } const clusterByMember = new Map<string, number>() for (let i = 0, il = clusters._rowCount; i < il; ++i) { @@ -83,6 +83,7 @@ export function getClusterColorTheme(symmetryId: number, assemblySymmetry: Assem const scale = ColorScale.create({ domain: [ 0, clusters._rowCount - 1 ] }) return { + features: {}, granularity: 'instance', color: (location: Location): Color => { if (StructureElement.isLocation(location)) { diff --git a/src/apps/canvas/index.ts b/src/apps/canvas/index.ts index cbc1a3a568a9c81c31a702134dce10a4c80471d7..dd72f8aaa98406272ed4a2d583781a38dc97743e 100644 --- a/src/apps/canvas/index.ts +++ b/src/apps/canvas/index.ts @@ -25,8 +25,8 @@ if (pdbId) app.loadPdbIdOrMmcifUrl(pdbId, { assemblyId }) // app.loadPdbIdOrMmcifUrl('http://localhost:8091/ngl/data/1crn.cif') -app.loadPdbIdOrMmcifUrl('3pqr') -app.loadCcp4Url('http://localhost:8091/ngl/data/3pqr-mode0.ccp4') +// app.loadPdbIdOrMmcifUrl('3pqr') +// app.loadCcp4Url('http://localhost:8091/ngl/data/3pqr-mode0.ccp4') // app.loadPdbIdOrMmcifUrl('1lee') // app.loadCcp4Url('http://localhost:8091/ngl/data/1lee.ccp4') diff --git a/src/mol-geo/geometry/color-data.ts b/src/mol-geo/geometry/color-data.ts index cc66f80c9edd161b5a518d38acab4be1f9faedc1..59c2a16686bd0a4a97ee1e3877f51995965482c4 100644 --- a/src/mol-geo/geometry/color-data.ts +++ b/src/mol-geo/geometry/color-data.ts @@ -6,11 +6,11 @@ import { ValueCell } from 'mol-util'; import { TextureImage, createTextureImage } from 'mol-gl/renderable/util'; -import { Color } from 'mol-util/color'; +import { Color, ColorMap } from 'mol-util/color'; import { Vec2, Vec3 } from 'mol-math/linear-algebra'; import { LocationIterator } from '../util/location-iterator'; import { NullLocation } from 'mol-model/location'; -import { LocationColor, ColorThemeProps, ColorTheme, ColorThemeName, ScaleLegend, TableLegend } from 'mol-theme/color'; +import { LocationColor, ColorThemeProps, ColorTheme, ColorThemeName, ScaleLegend, TableLegend, ColorScaleName, getColorScaleFromName } from 'mol-theme/color'; import { RuntimeContext } from 'mol-task'; import { getGranularity } from './geometry'; import { Structure } from 'mol-model/structure'; @@ -27,6 +27,8 @@ export type ColorData = { export interface ColorProps { colorTheme: ColorThemeName + colorList?: Color[] | ColorScaleName + colorMap?: ColorMap<any> colorDomain?: [number, number] colorValue?: Color colorFunction?: LocationColor, @@ -41,6 +43,10 @@ export function getColorThemeProps(props: ColorProps): ColorThemeProps { name: props.colorTheme } if (props.colorDomain !== undefined) p.domain = props.colorDomain + if (props.colorList !== undefined) { + p.list = typeof props.colorList === 'string' ? getColorScaleFromName(props.colorList) : props.colorList + } + if (props.colorMap !== undefined) p.map = props.colorMap if (props.colorValue !== undefined) p.value = props.colorValue if (props.structure !== undefined) p.structure = props.structure if (props.colorFunction !== undefined) p.color = props.colorFunction diff --git a/src/mol-geo/geometry/direct-volume/transfer-function.ts b/src/mol-geo/geometry/direct-volume/transfer-function.ts index 98f496f143517cebdb1345d5a7a48168ecb9b94b..1679daa27fe7867c4e128141509e5bdd362f4a41 100644 --- a/src/mol-geo/geometry/direct-volume/transfer-function.ts +++ b/src/mol-geo/geometry/direct-volume/transfer-function.ts @@ -29,7 +29,7 @@ export function createTransferFunctionTexture(controlPoints: ControlPoint[], tex ] const scale = ColorScale.create({ domain: [0, 1], - colors: ColorMatplotlib.viridis + list: ColorMatplotlib.viridis }) const n = 256 diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index 42cef994a0120f6b5f47dc7fab7912a1c2c0aaf7..57df5ab488d3f3c0d6f006ca8a4cf15223d8de6a 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -10,7 +10,7 @@ import { RenderableState } from 'mol-gl/renderable'; import { ValueCell } from 'mol-util'; import { BaseValues } from 'mol-gl/renderable/schema'; import { Color } from 'mol-util/color'; -import { ColorThemeOptions, ColorThemeName } from 'mol-theme/color'; +import { ColorThemeOptions, ColorThemeName, ColorScaleOptions, ColorScaleName } from 'mol-theme/color'; import { LocationIterator } from '../util/location-iterator'; import { ColorType } from './color-data'; import { SizeType } from './size-data'; @@ -65,6 +65,7 @@ export namespace Geometry { useFog: BooleanParam('Use Fog', '', false), quality: SelectParam<VisualQuality>('Quality', '', 'auto', VisualQualityOptions), colorTheme: SelectParam<ColorThemeName>('Color Theme', '', 'uniform', ColorThemeOptions), + colorList: SelectParam<ColorScaleName>('Color Scale', '', 'default', ColorScaleOptions), colorValue: ColorParam('Color Value', '', Color(0xCCCCCC)), } export const DefaultProps = paramDefaultValues(Params) diff --git a/src/mol-repr/index.ts b/src/mol-repr/index.ts index 7ae464d9501497a8a2e1bd2fff2a7d47136d6a0b..a293cf595c352db3bd053bf82228a0e3080f8be6 100644 --- a/src/mol-repr/index.ts +++ b/src/mol-repr/index.ts @@ -11,6 +11,7 @@ import { Loci, isEmptyLoci, EmptyLoci } from 'mol-model/loci'; import { MarkerAction } from '../mol-geo/geometry/marker-data'; import { Params, MultiSelectParam } from 'mol-util/parameter'; import { WebGLContext } from 'mol-gl/webgl/context'; +// import { ColorTheme } from 'mol-theme/color'; // export interface RepresentationProps { // visuals?: string[] @@ -106,7 +107,9 @@ export namespace Representation { // export interface VisualContext extends RepresentationContext { - runtime: RuntimeContext + runtime: RuntimeContext, + // TODO + // colorTheme: ColorTheme, } export interface Visual<D, P extends RepresentationProps> { diff --git a/src/mol-repr/util.ts b/src/mol-repr/util.ts index 792e9ff05be9e3331d77b8323948daba894e4916..0b71cd247d96592ae3dc676a30a4fd54b88cb27b 100644 --- a/src/mol-repr/util.ts +++ b/src/mol-repr/util.ts @@ -44,7 +44,10 @@ export function sizeChanged(oldProps: SizeProps, newProps: SizeProps) { export function colorChanged(oldProps: ColorProps, newProps: ColorProps) { return ( oldProps.colorTheme !== newProps.colorTheme || - oldProps.colorValue !== newProps.colorValue + oldProps.colorValue !== newProps.colorValue || + oldProps.colorDomain !== newProps.colorDomain || + oldProps.colorList !== newProps.colorList || + oldProps.colorMap !== newProps.colorMap ) } diff --git a/src/mol-theme/color.ts b/src/mol-theme/color.ts index c11848731cdae4a30529c7d2e62a9ed272b8cc26..d087e249c80cbd17e3e30f49102a5bdde537f012 100644 --- a/src/mol-theme/color.ts +++ b/src/mol-theme/color.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Color } from 'mol-util/color'; +import { Color, ColorMap } from 'mol-util/color'; import { Structure } from 'mol-model/structure'; import { Location } from 'mol-model/location'; import { ColorType } from 'mol-geo/geometry/color-data'; @@ -23,6 +23,7 @@ import { SequenceIdColorTheme } from './color/sequence-id'; import { SecondaryStructureColorTheme } from './color/secondary-structure'; import { MoleculeTypeColorTheme } from './color/molecule-type'; import { PolymerIndexColorTheme } from './color/polymer-index'; +import { ColorMatplotlib, ColorBrewer, ColorOther } from 'mol-util/color/tables'; export type LocationColor = (location: Location, isSecondary: boolean) => Color @@ -36,6 +37,29 @@ export function ScaleLegend(minLabel: string, maxLabel: string, colors: Color[]) return { kind: 'scale-legend', minLabel, maxLabel, colors } } +export type ColorScaleName = ( + 'default' | + keyof typeof ColorBrewer | keyof typeof ColorMatplotlib | keyof typeof ColorOther +) +export const ColorScaleNames = [ + 'default', + ...Object.keys(ColorBrewer), ...Object.keys(ColorMatplotlib), ...Object.keys(ColorOther) +] +export const ColorScaleOptions = ColorScaleNames.map(n => [n, n] as [ColorScaleName, string]) + +export function getColorScaleFromName(name: string) { + if (name === 'default') { + return + } else if (name in ColorBrewer) { + return ColorBrewer[name as keyof typeof ColorBrewer] + } else if (name in ColorMatplotlib) { + return ColorMatplotlib[name as keyof typeof ColorMatplotlib] + } else if (name in ColorOther) { + return ColorOther[name as keyof typeof ColorOther] + } + console.warn(`unknwon color list named '${name}'`) +} + export interface TableLegend { kind: 'table-legend' table: [ string, Color ][] @@ -44,7 +68,23 @@ export function TableLegend(table: [ string, Color ][]): TableLegend { return { kind: 'table-legend', table } } +export interface ColorThemeFeatures { + /** Does allow providing a structure object */ + structure?: boolean + /** Does allow providing a volume object */ + volume?: boolean + /** Does allow providing a list of colors (for creating a scale) */ + list?: boolean + /** Does allow providing a map of colors */ + map?: boolean + /** Does allow providing the boundaries for the scale */ + domain?: boolean + /** Does allow providing a single/special color value */ + value?: boolean +} + export interface ColorTheme { + features: ColorThemeFeatures granularity: ColorType color: LocationColor description?: string @@ -74,6 +114,8 @@ export interface ColorThemeProps { name: ColorThemeName domain?: [number, number] value?: Color + list?: Color[] + map?: ColorMap<any> structure?: Structure color?: LocationColor granularity?: ColorType, diff --git a/src/mol-theme/color/carbohydrate-symbol.ts b/src/mol-theme/color/carbohydrate-symbol.ts index c777c91d538684085041c23698ee19657fb18de7..a21853d87f941f899f7071ff3260b55b9d346541 100644 --- a/src/mol-theme/color/carbohydrate-symbol.ts +++ b/src/mol-theme/color/carbohydrate-symbol.ts @@ -47,6 +47,7 @@ export function CarbohydrateSymbolColorTheme(props: ColorThemeProps): ColorTheme } return { + features: {}, granularity: 'group', color: color, description: Description, diff --git a/src/mol-theme/color/chain-id.ts b/src/mol-theme/color/chain-id.ts index e281dc9a20dc39fd36c3f937ec8920bb87e1f9b3..0fd9e3955a12238e72496d5e527a8a7e71741944 100644 --- a/src/mol-theme/color/chain-id.ts +++ b/src/mol-theme/color/chain-id.ts @@ -63,6 +63,7 @@ export function ChainIdColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: {}, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/cross-link.ts b/src/mol-theme/color/cross-link.ts index 6f8ab371e6ff957f71fd081850f25acc55b23ac0..bb3cf176c4f5a5c8fdbc330b63e7c69e5436c089 100644 --- a/src/mol-theme/color/cross-link.ts +++ b/src/mol-theme/color/cross-link.ts @@ -6,10 +6,12 @@ import { Link } from 'mol-model/structure'; -import { Color, ColorScale, ColorBrewer } from 'mol-util/color'; +import { Color, ColorScale } from 'mol-util/color'; import { Location } from 'mol-model/location'; import { ColorThemeProps, ColorTheme, LocationColor } from '../color'; import { Vec3 } from 'mol-math/linear-algebra'; +import { ColorBrewer } from 'mol-util/color/tables'; +import { defaults } from 'mol-util'; const DefaultColor = Color(0xCCCCCC) const Description = 'Colors cross-links by the deviation of the observed distance versus the modeled distance (e.g. `ihm_cross_link_restraint.distance_threshold`).' @@ -27,7 +29,10 @@ export function CrossLinkColorTheme(props: ColorThemeProps): ColorTheme { if (props.structure) { const crosslinks = props.structure.crossLinkRestraints - scale = ColorScale.create({ domain: [ -10, 10 ], colors: ColorBrewer.RdYlBu }) + scale = ColorScale.create({ + domain: defaults(props.domain, [ -10, 10 ]), + list: defaults(props.list, ColorBrewer.RdYlBu) + }) const scaleColor = scale.color color = (location: Location): Color => { @@ -44,6 +49,7 @@ export function CrossLinkColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: { list: true, domain: true }, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/custom.ts b/src/mol-theme/color/custom.ts index 4901ac06f6860660a7cfb1edb9a1505d9e052c17..4eb5a10ea4497ba5c419607e1467245b4758dc0e 100644 --- a/src/mol-theme/color/custom.ts +++ b/src/mol-theme/color/custom.ts @@ -13,6 +13,7 @@ const DefaultColor = Color(0xCCCCCC) export function CustomColorTheme(props: ColorThemeProps): ColorTheme { const value = defaults(props.value, DefaultColor) return { + features: {}, granularity: defaults(props.granularity, 'uniform'), color: defaults(props.color, () => value), description: props.description, diff --git a/src/mol-theme/color/element-index.ts b/src/mol-theme/color/element-index.ts index 8ca2d273a0c5c30c2d16c323adefd77ed043295d..ecce0a1c1bc0804043f2c9ee4c5f8aaabbc69882 100644 --- a/src/mol-theme/color/element-index.ts +++ b/src/mol-theme/color/element-index.ts @@ -29,7 +29,7 @@ export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme { elementCount += units[i].elements.length unitIdIndex.set(units[i].id, i) } - scale = ColorScale.create({ domain: [ 0, elementCount - 1 ] }) + scale = ColorScale.create({ domain: [ 0, elementCount - 1 ], list: props.list }) const scaleColor = scale.color color = (location: Location): Color => { @@ -48,6 +48,7 @@ export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: { list: true }, granularity: 'groupInstance', color, description: Description, diff --git a/src/mol-theme/color/element-symbol.ts b/src/mol-theme/color/element-symbol.ts index e382f14d87f48d496faaa8eb2c0e794bbc04aa5c..8d7f87b21d0d99e686fea90c4011a3df572d7b2d 100644 --- a/src/mol-theme/color/element-symbol.ts +++ b/src/mol-theme/color/element-symbol.ts @@ -40,6 +40,7 @@ export function ElementSymbolColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: {}, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/molecule-type.ts b/src/mol-theme/color/molecule-type.ts index f2be520fe8c9791b3d4920d8634aa7da709d9662..9bdc21d39a52dae10358d5f0d3c61feda2cabd44 100644 --- a/src/mol-theme/color/molecule-type.ts +++ b/src/mol-theme/color/molecule-type.ts @@ -49,6 +49,7 @@ export function MoleculeTypeColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: {}, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/polymer-index.ts b/src/mol-theme/color/polymer-index.ts index 891b17300f72f94ab19e1c1883e19c303f9d0659..b32fa80cbaa1649bbdf2b0aed8d2ace1f6f9b3e8 100644 --- a/src/mol-theme/color/polymer-index.ts +++ b/src/mol-theme/color/polymer-index.ts @@ -22,7 +22,7 @@ export function PolymerIndexColorTheme(props: ColorThemeProps): ColorTheme { for (let i = 0, il = units.length; i <il; ++i) { if (units[i].polymerElements.length > 0) ++polymerCount } - scale = ColorScale.create({ domain: [ 0, polymerCount - 1 ] }) + scale = ColorScale.create({ list: props.list, domain: [ 0, polymerCount - 1 ] }) const unitIdColor = new Map<number, Color>() for (let i = 0, j = 0, il = units.length; i <il; ++i) { if (units[i].polymerElements.length > 0) { @@ -45,6 +45,7 @@ export function PolymerIndexColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: { structure: true, list: true }, granularity: 'instance', color, description: Description, diff --git a/src/mol-theme/color/residue-name.ts b/src/mol-theme/color/residue-name.ts index 02f2425fbc446cc9ca174ae743073b9b047c2501..756ef8c482458704ceaca1f097cfbe8f9fa9216a 100644 --- a/src/mol-theme/color/residue-name.ts +++ b/src/mol-theme/color/residue-name.ts @@ -105,6 +105,7 @@ export function ResidueNameColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: {}, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/secondary-structure.ts b/src/mol-theme/color/secondary-structure.ts index 55e76a3da44858ad6703322fc7956abfc38f3434..d9a6fd7b6e15518dd354c721417e7e1c73ca75b6 100644 --- a/src/mol-theme/color/secondary-structure.ts +++ b/src/mol-theme/color/secondary-structure.ts @@ -72,6 +72,7 @@ export function SecondaryStructureColorTheme(props: ColorThemeProps): ColorTheme } return { + features: {}, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/sequence-id.ts b/src/mol-theme/color/sequence-id.ts index 7f68bf57e787716054a599e67c789c1214e5814e..808e4ace55c17a952ee46d6dd8fc14f8c68dd8e5 100644 --- a/src/mol-theme/color/sequence-id.ts +++ b/src/mol-theme/color/sequence-id.ts @@ -10,6 +10,7 @@ import { ColorScale, Color } from 'mol-util/color'; import { Location } from 'mol-model/location'; import { ColorThemeProps, ColorTheme } from '../color'; import { ColorOther } from 'mol-util/color/tables'; +import { defaults } from 'mol-util'; const DefaultColor = Color(0xCCCCCC) const Description = 'Gives every polymer residue a color based on its `seq_id` value.' @@ -57,7 +58,7 @@ function getSequenceLength(unit: Unit, element: ElementIndex) { export function SequenceIdColorTheme(props: ColorThemeProps): ColorTheme { const p = { ...props, - colors: ColorOther.rainbow, + list: defaults(props.list, ColorOther.rainbow), minLabel: 'Start', maxLabel: 'End', } @@ -83,6 +84,7 @@ export function SequenceIdColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: { list: true }, granularity: 'group', color, description: Description, diff --git a/src/mol-theme/color/shape-group.ts b/src/mol-theme/color/shape-group.ts index 6743791a3c58d823359eab0f6f8052c1bb8b55aa..0d74a08c77afa0c23f265036e0279daf2c1d76b5 100644 --- a/src/mol-theme/color/shape-group.ts +++ b/src/mol-theme/color/shape-group.ts @@ -13,6 +13,7 @@ const DefaultColor = Color(0xCCCCCC) export function ShapeGroupColorTheme(props: ColorThemeProps): ColorTheme { return { + features: {}, granularity: 'group', color: (location: Location): Color => { if (Shape.isLocation(location)) { diff --git a/src/mol-theme/color/uniform.ts b/src/mol-theme/color/uniform.ts index d9ab15c4db1cae6a21d6dd7b3376d3cd87817ce1..f7fb57769ecbdcfbdbe6a9ba6bda5507eedbd45f 100644 --- a/src/mol-theme/color/uniform.ts +++ b/src/mol-theme/color/uniform.ts @@ -14,6 +14,7 @@ export function UniformColorTheme(props: ColorThemeProps): ColorTheme { const color = props.value || DefaultColor return { + features: {}, granularity: 'uniform', color: () => color, description: Description, diff --git a/src/mol-theme/color/unit-index.ts b/src/mol-theme/color/unit-index.ts index 3e4fed18b986e43f85fa9c076d9d765695f73494..f41b29199a01f064b84b4c3155fd64b06da9c4cd 100644 --- a/src/mol-theme/color/unit-index.ts +++ b/src/mol-theme/color/unit-index.ts @@ -37,6 +37,7 @@ export function UnitIndexColorTheme(props: ColorThemeProps): ColorTheme { } return { + features: {}, granularity: 'instance', color, description: Description, diff --git a/src/mol-util/color/color.ts b/src/mol-util/color/color.ts index 1668282d9125336756abbd5b20296924472b2552..426c639b538118909cfc392688197f6db691020a 100644 --- a/src/mol-util/color/color.ts +++ b/src/mol-util/color/color.ts @@ -65,8 +65,8 @@ export namespace Color { } } -type ColorTable<T extends { [k: string]: number[] }> = { [k in keyof T]: Color[] } +export type ColorTable<T extends { [k: string]: number[] }> = { [k in keyof T]: Color[] } export function ColorTable<T extends { [k: string]: number[] }>(o: T) { return o as ColorTable<T> } -type ColorMap<T extends { [k: string]: number }> = { [k in keyof T]: Color } +export type ColorMap<T extends { [k: string]: number }> = { [k in keyof T]: Color } export function ColorMap<T extends { [k: string]: number }>(o: T) { return o as ColorMap<T> } \ No newline at end of file diff --git a/src/mol-util/color/index.ts b/src/mol-util/color/index.ts index 2332d4a24ec9502444a54e46e15a1b546b412f49..33691a4115e086ca31cd68ca87f5ee7fdb129885 100644 --- a/src/mol-util/color/index.ts +++ b/src/mol-util/color/index.ts @@ -4,6 +4,5 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -export { Color, ColorMap, ColorTable } from './color' -export { ColorScale } from './scale'; -export { ColorBrewer, ColorNames } from './tables' \ No newline at end of file +export { Color, ColorMap, ColorTable } from './color'; +export { ColorScale } from './scale'; \ No newline at end of file diff --git a/src/mol-util/color/scale.ts b/src/mol-util/color/scale.ts index e4bc9bb02e0efa3bd0f34b34dc4c6bf8b069d29d..c7cf7980c114e7b5363ede0cc7b80a1b176c0f5e 100644 --- a/src/mol-util/color/scale.ts +++ b/src/mol-util/color/scale.ts @@ -25,7 +25,7 @@ export interface ColorScale { export const DefaultColorScale = { domain: [0, 1], reverse: false, - colors: ColorBrewer.RdYlBu, + list: ColorBrewer.RdYlBu, minLabel: '' as string | undefined, maxLabel: '' as string | undefined, } @@ -33,8 +33,10 @@ export type ColorScaleProps = Partial<typeof DefaultColorScale> export namespace ColorScale { export function create(props: ColorScaleProps): ColorScale { - const { domain, reverse, colors: _colors } = { ...DefaultColorScale, ...props } - const colors = reverse ? _colors.slice().reverse() : _colors + // ensure that no undefined .list property exists so that the default assignment works + if (props.list === undefined) delete props.list + const { domain, reverse, list } = { ...DefaultColorScale, ...props } + const colors = reverse ? list.slice().reverse() : list const count1 = colors.length - 1 let diff = 0, min = 0, max = 0