Xaxis.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import React from 'react'
  2. import * as echarts from 'echarts/lib/echarts'
  3. import { IMetricAxisConfig } from './Pivot'
  4. import { IWidgetMetric, DimetionType, IChartStyles } from '../Widget'
  5. import { IChartLine, IChartUnit } from './Chart'
  6. import { metricAxisLabelFormatter, getXaxisLabel, decodeMetricName } from '../util'
  7. import { PIVOT_DEFAULT_AXIS_LINE_COLOR, PIVOT_XAXIS_ROTATE_LIMIT } from 'app/globalConstants'
  8. const styles = require('./Pivot.less')
  9. interface IXaxisProps {
  10. width: number
  11. metrics: IWidgetMetric[]
  12. data: any[]
  13. metricAxisConfig?: IMetricAxisConfig
  14. dimetionAxis: DimetionType
  15. chartStyles: IChartStyles
  16. elementSize: number
  17. }
  18. export class Xaxis extends React.PureComponent<IXaxisProps, {}> {
  19. private container: HTMLDivElement = null
  20. public componentDidMount () {
  21. this.renderAxis()
  22. }
  23. public componentDidUpdate () {
  24. this.renderAxis()
  25. }
  26. private renderAxis = () => {
  27. const { metrics, data, metricAxisConfig, dimetionAxis, chartStyles, elementSize } = this.props
  28. const {
  29. showLine,
  30. lineStyle,
  31. lineSize,
  32. lineColor,
  33. showLabel,
  34. labelFontFamily,
  35. labelFontSize,
  36. labelColor,
  37. showTitleAndUnit,
  38. titleFontFamily,
  39. titleFontSize,
  40. titleColor
  41. } = dimetionAxis === 'col' ? chartStyles.xAxis : chartStyles.yAxis
  42. const doms = this.container.children as HTMLCollectionOf<HTMLDivElement>
  43. data.forEach((block, i) => {
  44. let instance = echarts.getInstanceByDom(doms[i])
  45. if (!instance) {
  46. instance = echarts.init(doms[i], 'default')
  47. } else {
  48. instance.clear()
  49. }
  50. const grid = []
  51. const xAxis = []
  52. const yAxis = []
  53. let xSum = 0
  54. let ySum = 0
  55. let index = 0
  56. block.data.forEach((line: IChartLine) => {
  57. const { data: lineData } = line
  58. lineData.forEach((unit: IChartUnit) => {
  59. const { width, records } = unit
  60. metrics.forEach((m, l) => {
  61. const metricAxisStyle = m.chart.coordinate === 'polar'
  62. ? {
  63. axisLabel: {
  64. show: false
  65. },
  66. axisLine: {
  67. lineStyle: {
  68. color: PIVOT_DEFAULT_AXIS_LINE_COLOR
  69. }
  70. },
  71. axisTick: {
  72. show: false
  73. }
  74. }
  75. : {
  76. axisLabel: {
  77. show: showLabel,
  78. color: labelColor,
  79. fontFamily: labelFontFamily,
  80. fontSize: labelFontSize,
  81. showMinLabel: false,
  82. showMaxLabel: false,
  83. formatter: metricAxisLabelFormatter
  84. },
  85. axisLine: {
  86. show: showLine,
  87. lineStyle: {
  88. color: lineColor,
  89. width: lineSize,
  90. type: lineStyle
  91. }
  92. },
  93. axisTick: {
  94. show: showLine,
  95. lineStyle: {
  96. color: lineColor
  97. }
  98. }
  99. }
  100. const axisTitle = showTitleAndUnit && {
  101. name: decodeMetricName(m.name),
  102. nameLocation: 'center',
  103. nameGap: 28,
  104. nameTextStyle: {
  105. color: titleColor,
  106. fontFamily: titleFontFamily,
  107. fontSize: titleFontSize
  108. }
  109. }
  110. grid.push({
  111. top: dimetionAxis === 'col' ? xSum : ySum,
  112. left: dimetionAxis === 'col' ? ySum - 1 : (xSum - 1 + l * width), // 隐藏yaxisline
  113. width
  114. })
  115. if (dimetionAxis === 'col') {
  116. xAxis.push({
  117. gridIndex: index,
  118. type: 'category',
  119. data: records.map((r) => r.key),
  120. interval: 0,
  121. axisLabel: {
  122. show: showLabel,
  123. color: labelColor,
  124. fontFamily: labelFontFamily,
  125. fontSize: labelFontSize,
  126. interval: 0,
  127. rotate: elementSize <= PIVOT_XAXIS_ROTATE_LIMIT ? -90 : 0,
  128. formatter: getXaxisLabel(elementSize * .8)
  129. },
  130. axisLine: {
  131. show: showLine,
  132. lineStyle: {
  133. color: lineColor,
  134. width: lineSize,
  135. type: lineStyle
  136. }
  137. },
  138. axisTick: {
  139. show: showLine,
  140. lineStyle: {
  141. color: lineColor
  142. }
  143. }
  144. })
  145. yAxis.push({
  146. gridIndex: index,
  147. show: false,
  148. type: 'value'
  149. })
  150. } else {
  151. xAxis.push({
  152. gridIndex: index,
  153. type: 'value',
  154. ...axisTitle,
  155. ...metricAxisStyle,
  156. ...metricAxisConfig[m.name].yAxis
  157. })
  158. yAxis.push({
  159. gridIndex: index,
  160. show: false,
  161. type: 'category'
  162. })
  163. }
  164. index += 1
  165. })
  166. if (dimetionAxis === 'col') {
  167. ySum += width
  168. } else {
  169. xSum += width * metrics.length
  170. }
  171. })
  172. if (dimetionAxis === 'col') {
  173. ySum = 0
  174. } else {
  175. xSum = 0
  176. }
  177. })
  178. instance.setOption({
  179. grid,
  180. xAxis,
  181. yAxis
  182. })
  183. instance.resize()
  184. })
  185. }
  186. public render () {
  187. const { width, data } = this.props
  188. const blocks = data.map((block) => (
  189. <div key={block.key} style={{width: block.length}} />
  190. ))
  191. return (
  192. <div
  193. className={styles.xAxis}
  194. style={{width}}
  195. ref={(f) => this.container = f}
  196. >
  197. {blocks}
  198. </div>
  199. )
  200. }
  201. }
  202. export default Xaxis