Cell.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import React from 'react'
  2. import { IWidgetMetric, IChartStyles } from '../Widget'
  3. import { ILegend } from './Pivot'
  4. import { IDataParamProperty } from '../Workbench/OperatingPanel'
  5. import { DEFAULT_SPLITER } from 'app/globalConstants'
  6. import { decodeMetricName } from 'containers/Widget/components/util'
  7. import { getFormattedValue } from '../Config/Format';
  8. const styles = require('./Pivot.less')
  9. interface ICellProps {
  10. colKey?: string
  11. rowKey?: string
  12. width: number
  13. height?: number
  14. interacting?: boolean
  15. metrics: IWidgetMetric[]
  16. chartStyles: IChartStyles
  17. color: IDataParamProperty
  18. legend: ILegend
  19. data: any[]
  20. ifSelectedTdToDrill: (obj: any) => any
  21. isDrilling?: boolean
  22. }
  23. interface ICellState {
  24. isSelected?: boolean
  25. }
  26. export class Cell extends React.PureComponent <ICellProps, ICellState> {
  27. constructor (props) {
  28. super(props)
  29. this.state = {
  30. isSelected: false
  31. }
  32. }
  33. public componentWillReceiveProps (nextProps) {
  34. if (nextProps.isDrilling === false) {
  35. this.setState({
  36. isSelected: false
  37. })
  38. }
  39. if (this.props.interacting !== nextProps.interacting && !nextProps.interacting) {
  40. this.setState({isSelected: false})
  41. }
  42. }
  43. private selectTd = (event) => {
  44. const pagex = event.pageX
  45. const pagey = event.pageY
  46. const {ifSelectedTdToDrill, data, isDrilling, colKey = '', rowKey = ''} = this.props
  47. this.setState({
  48. isSelected: !this.state.isSelected
  49. }, () => {
  50. const {isSelected} = this.state
  51. const key = [colKey, rowKey].join(String.fromCharCode(0))
  52. let obj = null
  53. if (ifSelectedTdToDrill && isSelected) {
  54. obj = {
  55. data: {[key]: data && data.length === 1 ? data[0] : data},
  56. range: [[pagex, pagex], [pagey, pagey]]
  57. }
  58. } else {
  59. obj = {
  60. data: {[key]: false}
  61. }
  62. }
  63. ifSelectedTdToDrill(obj)
  64. })
  65. }
  66. public render () {
  67. const { colKey = '', rowKey = '', width, height, data, chartStyles, color, legend } = this.props
  68. const { isSelected } = this.state
  69. const {
  70. color: fontColor,
  71. fontSize,
  72. fontFamily,
  73. lineColor,
  74. lineStyle
  75. } = chartStyles.pivot
  76. let metrics = this.props.metrics
  77. if (colKey.includes(DEFAULT_SPLITER) && rowKey.includes(DEFAULT_SPLITER)) {
  78. const metricColKey = getMetricKey(colKey)
  79. const metricRowKey = getMetricKey(rowKey)
  80. if (metricColKey === metricRowKey) {
  81. const [name, id] = metricColKey.split(DEFAULT_SPLITER)
  82. metrics = metrics.filter((m) => m.name === `${name}${DEFAULT_SPLITER}${id}`)
  83. } else {
  84. metrics = []
  85. }
  86. } else if (colKey.includes(DEFAULT_SPLITER)) {
  87. const [name, id] = getMetricKey(colKey).split(DEFAULT_SPLITER)
  88. metrics = metrics.filter((m) => m.name === `${name}${DEFAULT_SPLITER}${id}`)
  89. } else if (rowKey.includes(DEFAULT_SPLITER)) {
  90. const [name, id] = getMetricKey(rowKey).split(DEFAULT_SPLITER)
  91. metrics = metrics.filter((m) => m.name === `${name}${DEFAULT_SPLITER}${id}`)
  92. }
  93. const content = metrics.map((m) => {
  94. const decodedMetricName = decodeMetricName(m.name)
  95. const currentColorItem = color.items.find((i) => i.config.actOn === m.name) || color.items.find((i) => i.config.actOn === 'all')
  96. return data && data.map((d, index) => {
  97. let styleColor
  98. if (currentColorItem) {
  99. const legendSelectedItem = legend[currentColorItem.name]
  100. if (!(legendSelectedItem && legendSelectedItem.includes(d[currentColorItem.name]))) {
  101. styleColor = {
  102. color: currentColorItem.config.values[d[currentColorItem.name]]
  103. }
  104. }
  105. }
  106. return (
  107. <p
  108. key={`${m.name}${index}`}
  109. className={styles.cellContent}
  110. style={{...styleColor}}
  111. >
  112. {getFormattedValue(d[`${m.agg}(${decodedMetricName})`], m.format)}
  113. </p>
  114. )
  115. })
  116. })
  117. const cellStyles = {
  118. width,
  119. ...(height && { height }),
  120. color: fontColor,
  121. fontSize: Number(fontSize),
  122. fontFamily,
  123. borderColor: lineColor,
  124. borderStyle: lineStyle,
  125. backgroundColor: isSelected ? '#d2eafb' : '#fff'
  126. }
  127. return (
  128. <td style={cellStyles} onClick={this.selectTd}>
  129. {content}
  130. </td>
  131. )
  132. }
  133. }
  134. export default Cell
  135. function getMetricKey (key) {
  136. return key.split(String.fromCharCode(0))
  137. .filter((k) => k.includes(DEFAULT_SPLITER))[0]
  138. }