indicatorView.jsx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * 指标板
  3. */
  4. import React from 'react';
  5. import EmptyContent from '../../common/emptyContent/index';
  6. import './indicatorView.less';
  7. class IndicatorView extends React.Component {
  8. constructor(props) {
  9. super(props);
  10. this.state = {}
  11. }
  12. componentDidMount() {
  13. this.autoLayout();
  14. window.addEventListener('resize', this.addAutoLayoutEvent);
  15. }
  16. componentWillUnmount() {
  17. window.removeEventListener('resize', this.addAutoLayoutEvent);
  18. }
  19. addAutoLayoutEvent = () => {
  20. window.clearTimeout(this.resizeKey);
  21. this.resizeKey = window.setTimeout(() => {
  22. this.autoLayout()
  23. }, 300);
  24. }
  25. autoLayout = () => {
  26. const { chartOption } = this.props;
  27. const { data } = chartOption;
  28. if(!data || data.length === 0) {
  29. return;
  30. }
  31. let extraRowCount = data[0].others.length;
  32. let cardMinHeight = extraRowCount === 0 ? 100 : (100 + 10 + (extraRowCount-1) * 21);
  33. let container = this.containerRef;
  34. if(!container) return;
  35. let body = container.getElementsByClassName('indicator-body')[0];
  36. let cards = body.getElementsByClassName('indicator-box');
  37. let cardCount = cards.length;
  38. let bodyBox = body.getBoundingClientRect();
  39. let maxColNum = cardCount > 4 ? 4 : cardCount; // 列数
  40. let maxRowNum = Math.ceil(cardCount / maxColNum); // 行数
  41. let cardHeight = bodyBox.height / maxRowNum - 8;
  42. cardHeight = cardHeight < cardMinHeight ? cardMinHeight : cardHeight;
  43. let inScroll = maxRowNum * (8 + cardHeight) > bodyBox.height;
  44. let cardWidth = (bodyBox.width - (inScroll ? 12 : 2)) / maxColNum - 8;
  45. while(cardWidth < 180 && maxColNum > 1) {
  46. maxColNum--;
  47. maxRowNum = Math.ceil(cardCount / maxColNum);
  48. cardHeight = bodyBox.height / maxRowNum - 8;
  49. cardHeight = cardHeight < cardMinHeight ? cardMinHeight : cardHeight;
  50. inScroll = maxRowNum * (8 + cardHeight) > bodyBox.height;
  51. cardWidth = (bodyBox.width - (inScroll ? 12 : 2)) / maxColNum - 8;
  52. }
  53. while(cardWidth > 300 && maxColNum < cardCount) {
  54. maxColNum++;
  55. maxRowNum = Math.ceil(cardCount / maxColNum);
  56. cardHeight = bodyBox.height / maxRowNum - 8;
  57. cardHeight = cardHeight < cardMinHeight ? cardMinHeight : cardHeight;
  58. inScroll = maxRowNum * (8 + cardHeight) > bodyBox.height;
  59. cardWidth = (bodyBox.width - (inScroll ? 12 : 2)) / maxColNum - 8;
  60. }
  61. body.style.overflow = inScroll ? 'auto' : 'visible';
  62. if(cardCount === 1) {
  63. cards[0].style.border = 'none';
  64. }
  65. let fun = function(els, width) {
  66. for(let j = 0; j < els.length; j++) {
  67. let wrap = els[j].getElementsByClassName('over-wrapper')[0];
  68. wrap.style.width = width + 'px';
  69. }
  70. };
  71. for(let i = 0; i < cards.length; i++) {
  72. cards[i].style.width = cardWidth + 'px';
  73. cards[i].style.height = cardHeight + 'px';
  74. let cells = cards[i].getElementsByClassName('cell');
  75. let w = cardWidth - 9 * 2;
  76. fun(cells, w);
  77. }
  78. }
  79. generateExtra = (data) => {
  80. return data.map((d, i) => (
  81. <div className='row indicator-extra' key={i}>
  82. <div className='cell c-extra'>
  83. <div className='over-wrapper'>
  84. <span className='til' title={d.name}>{d.name === null ? '空' : d.name}</span>
  85. <span className='val' title={d.value}>{d.value === null ? '--' : d.value}</span>
  86. </div>
  87. </div>
  88. </div>
  89. ));
  90. }
  91. render() {
  92. const { chartOption } = this.props;
  93. const { data, themeConfig } = chartOption;
  94. const { name: themeName } = themeConfig || {};
  95. if(!data || data.length === 0) {
  96. return <div className='indicator-container empty' ref={ node => this.containerRef = node }>
  97. <div className='indicator-body'>
  98. <EmptyContent />
  99. </div>
  100. </div>
  101. }
  102. return <div className={`indicator-container ${themeName}`} ref={ node => this.containerRef = node }>
  103. <div className='indicator-body'>
  104. {
  105. data.map((d, i) => (
  106. <div className={`indicator-box`} key={i}>
  107. {d.name !== undefined && <div className='row indicator-name'>
  108. <div className='cell c-name'>
  109. <div className='over-wrapper' title={d.name}>{d.name === null ? '空' : d.name}</div>
  110. </div>
  111. </div>}
  112. {d.name !== undefined && <div className='row indicator-key'>
  113. <div className='cell c-key'>
  114. <div className='over-wrapper' title={d.key}>{d.key === null ? '空': d.key}</div>
  115. </div>
  116. </div>}
  117. {d.name === undefined && <div className='row indicator-name'>
  118. <div className='cell c-name'>
  119. <div className='over-wrapper' title={d.key}>{d.key === null ? '空' : d.key}</div>
  120. </div>
  121. </div>}
  122. <div className='row indicator-value'>
  123. <div className='cell c-value'>
  124. <div className='over-wrapper' title={d.value}>{d.value === null ? '--' : d.value}</div>
  125. </div>
  126. </div>
  127. {d.others && d.others.length > 0 && this.generateExtra(d.others)}
  128. </div>
  129. ))
  130. }
  131. </div>
  132. </div>
  133. }
  134. }
  135. export default IndicatorView