structure-representation.tsx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 * as React from 'react'
  7. import { StructureRepresentation, StructureProps } from 'mol-geo/representation/structure';
  8. import Viewer from 'mol-view/viewer';
  9. import { VisualQuality, VisualQualityNames } from 'mol-geo/representation/util';
  10. import { ColorThemeProps, ColorThemeName, ColorThemeNames, ColorTheme } from 'mol-view/theme/color';
  11. import { Color } from 'mol-util/color';
  12. export interface StructureRepresentationComponentProps {
  13. viewer: Viewer
  14. representation: StructureRepresentation<StructureProps>
  15. }
  16. export interface StructureRepresentationComponentState {
  17. label: string
  18. visible: boolean
  19. alpha: number
  20. quality: VisualQuality
  21. colorTheme: ColorThemeProps
  22. }
  23. export class StructureRepresentationComponent extends React.Component<StructureRepresentationComponentProps, StructureRepresentationComponentState> {
  24. state = {
  25. label: this.props.representation.label,
  26. visible: this.props.representation.props.visible,
  27. alpha: this.props.representation.props.alpha,
  28. quality: this.props.representation.props.quality,
  29. colorTheme: this.props.representation.props.colorTheme,
  30. }
  31. componentWillMount() {
  32. const repr = this.props.representation
  33. this.setState({
  34. ...this.state,
  35. label: repr.label,
  36. visible: repr.props.visible,
  37. alpha: repr.props.alpha,
  38. quality: repr.props.quality,
  39. colorTheme: repr.props.colorTheme,
  40. })
  41. }
  42. async update(state: Partial<StructureRepresentationComponentState>) {
  43. const repr = this.props.representation
  44. const props: Partial<StructureProps> = {}
  45. if (state.visible !== undefined) props.visible = state.visible
  46. if (state.quality !== undefined) props.quality = state.quality
  47. if (state.alpha !== undefined) props.alpha = state.alpha
  48. if (state.colorTheme !== undefined) props.colorTheme = state.colorTheme
  49. await repr.createOrUpdate(props).run()
  50. this.props.viewer.add(repr)
  51. this.props.viewer.requestDraw(true)
  52. console.log(this.props.viewer.stats)
  53. const newState = {
  54. ...this.state,
  55. visible: repr.props.visible,
  56. quality: repr.props.quality,
  57. alpha: repr.props.alpha,
  58. colorTheme: repr.props.colorTheme,
  59. }
  60. this.setState(newState)
  61. }
  62. render() {
  63. const { label, visible, quality, alpha, colorTheme } = this.state
  64. const ct = ColorTheme(colorTheme)
  65. if (ct.legend && ct.legend.kind === 'scale-legend') {
  66. // console.log(`linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`)
  67. }
  68. return <div>
  69. <div>
  70. <h4>{label}</h4>
  71. </div>
  72. <div>
  73. <div>
  74. <span>Visible </span>
  75. <button onClick={(e) => this.update({ visible: !visible }) }>
  76. {visible ? 'Hide' : 'Show'}
  77. </button>
  78. </div>
  79. <div>
  80. <span>Quality </span>
  81. <select value={quality} onChange={(e) => this.update({ quality: e.target.value as VisualQuality }) }>
  82. {VisualQualityNames.map(name => <option key={name} value={name}>{name}</option>)}
  83. </select>
  84. </div>
  85. <div>
  86. <span>Opacity </span>
  87. <input type='range'
  88. defaultValue={alpha.toString()}
  89. min='0'
  90. max='1'
  91. step='0.05'
  92. onInput={(e) => this.update({ alpha: parseFloat(e.currentTarget.value) })}
  93. >
  94. </input>
  95. </div>
  96. <div>
  97. <span>Color Theme </span>
  98. <select value={colorTheme.name} onChange={(e) => this.update({ colorTheme: { name: e.target.value as ColorThemeName } }) }>
  99. {ColorThemeNames.map(name => <option key={name} value={name}>{name}</option>)}
  100. </select>
  101. {ct.description ? <div><i>{ct.description}</i></div> : ''}
  102. {
  103. ct.legend && ct.legend.kind === 'scale-legend'
  104. ? <div
  105. style={{
  106. width: '100%',
  107. height: '30px',
  108. background: `linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`
  109. }}
  110. >
  111. <span style={{float: 'left', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.min}</span>
  112. <span style={{float: 'right', padding: '6px', color: 'white', fontWeight: 'bold', backgroundColor: 'rgba(0, 0, 0, 0.2)'}}>{ct.legend.max}</span>
  113. </div>
  114. : ct.legend && ct.legend.kind === 'table-legend'
  115. ? <div>
  116. {ct.legend.table.map((value, i) => {
  117. const [name, color] = value
  118. return <div key={i} style={{minWidth: '60px', marginRight: '5px', display: 'inline-block'}}>
  119. <div style={{width: '30px', height: '20px', backgroundColor: Color.toStyle(color), display: 'inline-block'}}></div>
  120. {name}
  121. </div>
  122. })}
  123. </div>
  124. : ''
  125. }
  126. </div>
  127. </div>
  128. </div>;
  129. }
  130. }