RowHeader.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import React from 'react'
  2. import classnames from 'classnames'
  3. import Yaxis from './Yaxis'
  4. import { IDrawingData, IMetricAxisConfig } from './Pivot'
  5. import {
  6. IWidgetMetric,
  7. DimetionType,
  8. IChartStyles,
  9. IWidgetDimension
  10. } from '../Widget'
  11. import {
  12. spanSize,
  13. getPivotCellWidth,
  14. getPivotCellHeight,
  15. getAxisData,
  16. decodeMetricName,
  17. getAggregatorLocale,
  18. getPivot,
  19. getStyleConfig
  20. } from '../util'
  21. import { PIVOT_LINE_HEIGHT, DEFAULT_SPLITER } from 'app/globalConstants'
  22. const styles = require('./Pivot.less')
  23. interface IRowHeaderProps {
  24. rows: IWidgetDimension[]
  25. rowKeys: string[][]
  26. colKeys: string[][]
  27. rowWidths: number[]
  28. rowTree: object
  29. colTree: object
  30. tree: object
  31. chartStyles: IChartStyles
  32. drawingData: IDrawingData
  33. dimetionAxis: DimetionType
  34. metrics: IWidgetMetric[]
  35. metricAxisConfig: IMetricAxisConfig
  36. hasMetricNameDimetion: boolean
  37. }
  38. export class RowHeader extends React.Component<IRowHeaderProps, {}> {
  39. private emitFilters = (rowField, rowType, rowValue, rowData) => () => {
  40. // console.log(rowField)
  41. // console.log(rowType)
  42. // console.log(rowValue)
  43. // console.log(rowData)
  44. }
  45. public render() {
  46. const {
  47. rows,
  48. rowKeys,
  49. colKeys,
  50. rowWidths,
  51. rowTree,
  52. colTree,
  53. tree,
  54. chartStyles,
  55. drawingData,
  56. dimetionAxis,
  57. metrics,
  58. metricAxisConfig,
  59. hasMetricNameDimetion
  60. } = this.props
  61. const { elementSize, unitMetricHeight } = drawingData
  62. const {
  63. color: fontColor,
  64. fontSize,
  65. fontFamily,
  66. lineColor,
  67. lineStyle,
  68. headerBackgroundColor
  69. } = getStyleConfig(chartStyles).pivot
  70. const headers = []
  71. if (rows.length) {
  72. let elementCount = 0
  73. let x = -1
  74. let hasAuxiliaryLine = false
  75. rowKeys.forEach((rk, i) => {
  76. const flatRowKey = rk.join(String.fromCharCode(0))
  77. const header = []
  78. const { height, records } = rowTree[flatRowKey]
  79. const maxElementCount = tree[flatRowKey]
  80. ? Math.max(
  81. ...Object.values(tree[flatRowKey]).map((r: any[]) =>
  82. r ? r.length : 0
  83. )
  84. )
  85. : records.length
  86. let cellHeight = 0
  87. rk.forEach((txt, j) => {
  88. const rowValue = txt
  89. const { name: rowField, type: rowType } = rows[j]
  90. const rowData = records[j]
  91. if (dimetionAxis === 'row') {
  92. if (j === rk.length - 1) {
  93. x = -1
  94. } else if (j === rk.length - 2) {
  95. const lastRk = rowKeys[i + 1] || []
  96. elementCount += 1
  97. if (rk[j] === lastRk[j]) {
  98. return
  99. } else {
  100. cellHeight = elementCount * elementSize
  101. x = 1
  102. elementCount = 0
  103. hasAuxiliaryLine = true
  104. }
  105. } else {
  106. x = spanSize(rowKeys, i, j)
  107. }
  108. } else {
  109. if (j === rk.length - 1) {
  110. cellHeight =
  111. dimetionAxis === 'col'
  112. ? unitMetricHeight * metrics.length
  113. : maxElementCount === 1
  114. ? getPivotCellHeight(height)
  115. : getPivotCellHeight(
  116. maxElementCount *
  117. (hasMetricNameDimetion ? 1 : metrics.length) *
  118. PIVOT_LINE_HEIGHT
  119. )
  120. hasAuxiliaryLine = dimetionAxis === 'col'
  121. }
  122. x = spanSize(rowKeys, i, j)
  123. }
  124. const columnClass = classnames({
  125. [styles.topBorder]: true,
  126. [styles.bottomBorder]: true
  127. })
  128. const contentClass = classnames({
  129. [styles.hasAuxiliaryLine]: hasAuxiliaryLine
  130. })
  131. if (x !== -1) {
  132. let colContent
  133. if (txt.includes(DEFAULT_SPLITER)) {
  134. const [name, id, agg] = txt.split(DEFAULT_SPLITER)
  135. colContent = `[${getAggregatorLocale(agg)}]${name}`
  136. } else {
  137. colContent = txt
  138. }
  139. header.push(
  140. <th
  141. key={`${txt}${j}`}
  142. rowSpan={x}
  143. colSpan={1}
  144. className={columnClass}
  145. onClick={this.emitFilters(rowField, rowType, rowValue, rowData)}
  146. style={{
  147. width: getPivotCellWidth(rowWidths[j]),
  148. ...(!!cellHeight && { height: cellHeight }),
  149. ...(!dimetionAxis && {
  150. backgroundColor: headerBackgroundColor
  151. }),
  152. color: fontColor,
  153. fontSize: Number(fontSize),
  154. fontFamily,
  155. borderColor: lineColor,
  156. borderStyle: lineStyle
  157. }}
  158. >
  159. <p
  160. className={contentClass}
  161. {...(!!cellHeight && {
  162. style: {
  163. height: cellHeight - 1,
  164. lineHeight: `${cellHeight - 1}px`
  165. }
  166. })}
  167. >
  168. {colContent}
  169. {hasAuxiliaryLine && (
  170. <span
  171. className={styles.line}
  172. style={{
  173. borderColor: lineColor,
  174. borderStyle: lineStyle
  175. }}
  176. />
  177. )}
  178. </p>
  179. </th>
  180. )
  181. }
  182. })
  183. headers.push(<tr key={flatRowKey}>{header}</tr>)
  184. })
  185. }
  186. let yAxis
  187. if (
  188. dimetionAxis &&
  189. !(dimetionAxis === 'row' && !colKeys.length && !rowKeys.length)
  190. ) {
  191. const { data, length } = getAxisData(
  192. 'y',
  193. rowKeys,
  194. colKeys,
  195. rowTree,
  196. colTree,
  197. tree,
  198. metrics,
  199. drawingData,
  200. dimetionAxis
  201. )
  202. yAxis = (
  203. <Yaxis
  204. height={length}
  205. metrics={metrics}
  206. data={data}
  207. chartStyles={chartStyles}
  208. dimetionAxis={dimetionAxis}
  209. metricAxisConfig={metricAxisConfig}
  210. />
  211. )
  212. }
  213. const containerClass = classnames({
  214. [styles.rowBody]: true,
  215. [styles.raw]: !dimetionAxis
  216. })
  217. return (
  218. <div className={containerClass}>
  219. <table className={styles.pivot}>
  220. <thead>{headers}</thead>
  221. </table>
  222. {yAxis}
  223. </div>
  224. )
  225. }
  226. }
  227. export default RowHeader