operator-name.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. * Copyright (c) 2019 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 '../../mol-util/color';
  7. import { StructureElement, Link, Structure } from '../../mol-model/structure';
  8. import { Location } from '../../mol-model/location';
  9. import { ColorTheme, LocationColor } from '../color';
  10. import { ParamDefinition as PD } from '../../mol-util/param-definition'
  11. import { ThemeDataContext } from '../theme';
  12. import { getPaletteParams, getPalette } from '../../mol-util/color/palette';
  13. import { ScaleLegend, TableLegend } from '../../mol-util/legend';
  14. const DefaultColor = Color(0xCCCCCC)
  15. const Description = `Assigns a color based on the operator name of a transformed chain.`
  16. export const OperatorNameColorThemeParams = {
  17. ...getPaletteParams({ type: 'set', setList: 'dark-2' }),
  18. }
  19. export type OperatorNameColorThemeParams = typeof OperatorNameColorThemeParams
  20. export function getOperatorNameColorThemeParams(ctx: ThemeDataContext) {
  21. const params = PD.clone(OperatorNameColorThemeParams)
  22. if (ctx.structure) {
  23. if (getOperatorNameSerialMap(ctx.structure.root).size > 12) {
  24. params.palette.defaultValue.name = 'scale'
  25. params.palette.defaultValue.params = {
  26. ...params.palette.defaultValue.params,
  27. list: 'red-yellow-blue'
  28. }
  29. }
  30. }
  31. return params
  32. }
  33. function getOperatorNameSerialMap(structure: Structure) {
  34. const map = new Map<string, number>()
  35. for (let i = 0, il = structure.units.length; i < il; ++i) {
  36. const name = structure.units[i].conformation.operator.name
  37. if (!map.has(name)) map.set(name, map.size)
  38. }
  39. return map
  40. }
  41. export function OperatorNameColorTheme(ctx: ThemeDataContext, props: PD.Values<OperatorNameColorThemeParams>): ColorTheme<OperatorNameColorThemeParams> {
  42. let color: LocationColor
  43. let legend: ScaleLegend | TableLegend | undefined
  44. if (ctx.structure) {
  45. const operatorNameSerialMap = getOperatorNameSerialMap(ctx.structure.root)
  46. const labelTable = Array.from(operatorNameSerialMap.keys())
  47. props.palette.params.valueLabel = (i: number) => labelTable[i]
  48. const palette = getPalette(operatorNameSerialMap.size, props)
  49. legend = palette.legend
  50. color = (location: Location): Color => {
  51. let serial: number | undefined = undefined
  52. if (StructureElement.Location.is(location)) {
  53. const name = location.unit.conformation.operator.name
  54. serial = operatorNameSerialMap.get(name)
  55. } else if (Link.isLocation(location)) {
  56. const name = location.aUnit.conformation.operator.name
  57. serial = operatorNameSerialMap.get(name)
  58. }
  59. return serial === undefined ? DefaultColor : palette.color(serial)
  60. }
  61. } else {
  62. color = () => DefaultColor
  63. }
  64. return {
  65. factory: OperatorNameColorTheme,
  66. granularity: 'instance',
  67. color,
  68. props,
  69. description: Description,
  70. legend
  71. }
  72. }
  73. export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams> = {
  74. label: 'Operator Name',
  75. factory: OperatorNameColorTheme,
  76. getParams: getOperatorNameColorThemeParams,
  77. defaultValues: PD.getDefaultValues(OperatorNameColorThemeParams),
  78. isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
  79. }