content.jsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import React from 'react'
  2. import { Layout, Tabs, Switch, Button } from 'antd'
  3. import BaseConfigForm from './sections/baseConfigForm'
  4. import AggregateTableConfigForm from './sections/aggregateTableConfigForm'
  5. import DataViewConfigForm from './sections/dataViewConfigForm'
  6. import BarConfigForm from './sections/barConfigForm'
  7. import PieConfigForm from './sections/pieConfigForm'
  8. import LineConfigForm from './sections/lineConfigForm'
  9. import ScatterConfigForm from './sections/scatterConfigForm'
  10. import IndicatorConfigForm from './sections/indicatorConfigForm'
  11. import StyleConfigForm from './sections/style/index'
  12. import OtherConfigForm from './sections/otherConfigForm'
  13. import TableView from './charts/tableView'
  14. import EchartsView from './charts/echartsView'
  15. import AggregateTableView from './charts/aggregateTableView'
  16. import IndicatorView from './charts/indicatorView'
  17. import ToolBar from './sections/toolbar'
  18. import { connect } from 'dva'
  19. import EmptyContent from '../common/emptyContent/index'
  20. import Thumbnail from '../common/echarts/thumbnail'
  21. import { hashcode } from '../../utils/baseUtils'
  22. import themes from './sections/style/theme/index'
  23. import './content.less'
  24. const { Header, Sider, Content, Footer } = Layout
  25. const { TabPane } = Tabs
  26. class ChartDesignerContent extends React.Component {
  27. constructor(props) {
  28. super(props);
  29. this.state = {
  30. isOwner: false,
  31. autoRefresh: true,
  32. collapsed: false,
  33. }
  34. }
  35. static getDerivedStateFromProps(nextProps, nextState) {
  36. const { chartDesigner, main } = nextProps;
  37. const isOwner = chartDesigner.creatorCode === main.currentUser.code || main.currentUser.role === 'superAdmin';
  38. if(chartDesigner.code !== nextState.code) {
  39. return {
  40. code: chartDesigner.code,
  41. isOwner: isOwner,
  42. collapsed: !isOwner,
  43. };
  44. }else {
  45. return null;
  46. }
  47. }
  48. onCollapse = () => {
  49. this.setState({
  50. collapsed: !this.state.collapsed,
  51. }, () => {
  52. window.setTimeout(() => {
  53. var e = document.createEvent("Event");
  54. e.initEvent("resize", true, true);
  55. window.dispatchEvent(e);
  56. }, 500);
  57. })
  58. }
  59. render() {
  60. const { chartDesigner, dispatch } = this.props;
  61. const { isOwner, autoRefresh } = this.state;
  62. const { code, baseConfig, chartOption, theme: themeName, styleConfig } = chartDesigner;
  63. const { viewType } = baseConfig;
  64. let configForm, chartView;
  65. let t = themes.find(t => t.name === themeName);
  66. let theme = t ? t.config : themes[0].config;
  67. if(viewType === 'aggregateTable') {
  68. configForm = (<AggregateTableConfigForm autoRefresh={autoRefresh}/>);
  69. chartView = (<AggregateTableView key={hashcode(chartOption)} chartOption={chartOption}/>);
  70. }else if(viewType === 'dataView') {
  71. configForm = (<DataViewConfigForm autoRefresh={autoRefresh}/>);
  72. chartView = (<TableView
  73. key={hashcode(chartOption)}
  74. chartOption={chartOption}
  75. viewRef={`tableview-${code}`}
  76. columns={chartOption.columns}
  77. dataSource={chartOption.dataSource}
  78. themeConfig={chartOption.themeConfig}
  79. styleConfig={styleConfig.dataView}
  80. pagination={{
  81. simple: false,
  82. current: chartOption.page,
  83. pageSize: chartOption.pageSize || 25,
  84. total: chartOption.total,
  85. showTotal: (total, range) => {
  86. return `第${range[0]}到第${range[1]}条数据,共${total}条数据`;
  87. },
  88. onChange: (page, pageSize) => {
  89. dispatch({ type: 'chartDesigner/fetchDataViewData', page, pageSize });
  90. }
  91. }}
  92. />);
  93. }else if(viewType === 'line') {
  94. configForm = (<LineConfigForm autoRefresh={autoRefresh}/>);
  95. // optionConfig 可以用来放替换属性(已做深拷贝替换)
  96. chartView = (<EchartsView key={hashcode(chartOption)} chartOption={chartOption} />);
  97. }else if(viewType === 'bar') {
  98. configForm = (<BarConfigForm autoRefresh={autoRefresh}/>);
  99. chartView = (<EchartsView key={hashcode(chartOption)} chartOption={chartOption} />);
  100. }else if(viewType === 'pie') {
  101. configForm = (<PieConfigForm autoRefresh={autoRefresh}/>);
  102. chartView = (<EchartsView key={hashcode(chartOption)} chartOption={chartOption} />);
  103. }else if(viewType === 'scatter') {
  104. configForm = (<ScatterConfigForm autoRefresh={autoRefresh}/>);
  105. chartView = (<EchartsView key={hashcode(chartOption)} chartOption={chartOption} />);
  106. }else if(viewType === 'indicator') {
  107. configForm = (<IndicatorConfigForm autoRefresh={autoRefresh}/>);
  108. chartView = (<IndicatorView key={hashcode(chartOption)} chartOption={chartOption} />);
  109. }else {
  110. chartView = <EmptyContent />
  111. }
  112. return (
  113. <Layout className='chartdesigner'>
  114. <Sider className={`sider-left${this.state.collapsed ? ' sider-left-collapsed' : ''}`} width={isOwner ? 300 : 0} >
  115. <Button className='collapse-toggle' style={{ display: isOwner? 'block' : 'none' }} shape='circle' size='small' icon={`${this.state.collapsed?'right':'left'}`} onClick={this.onCollapse} />
  116. <Tabs className='sider-tabs'>
  117. <TabPane className='chartconfig' tab='图表设置' key='1'>
  118. <BaseConfigForm/>
  119. { configForm }
  120. </TabPane>
  121. <TabPane className='styleconfig' tab='样式设置' key='2'>
  122. <StyleConfigForm viewType={viewType}/>
  123. </TabPane>
  124. <TabPane className='otherconfig' tab='其他设置' key='3'>
  125. <OtherConfigForm/>
  126. </TabPane>
  127. </Tabs>
  128. {!this.state.collapsed && <Footer className='sider-footer'>
  129. <div className='fresh-bar'>
  130. <Switch defaultChecked={autoRefresh} checkedChildren='自动刷新' unCheckedChildren='手动刷新' onChange={(checked) => {
  131. // 自动刷新后立即请求一次数据
  132. if(checked) {
  133. let page = chartOption.page || 1;
  134. let pageSize = chartOption.pageSize || ~~((document.getElementsByClassName('content-body')[0].offsetHeight - 12 * 2 - 40 - 24 - 8 * 2)/38) + 1;
  135. dispatch({ type: 'chartDesigner/fetchChartData', page, pageSize });
  136. }
  137. this.setState({
  138. autoRefresh: checked
  139. });
  140. // dispatch({ type: 'chartDesigner/silentSetField', name: 'autoRefresh', value: checked })
  141. }}/>
  142. <Button style={{ display: autoRefresh ? 'none' : 'block' }} size='small' onClick={() => {
  143. let page = chartOption.page || 1;
  144. let pageSize = chartOption.pageSize || ~~((document.getElementsByClassName('content-body')[0].offsetHeight - 12 * 2 - 40 - 24 - 8 * 2)/38) + 1;
  145. dispatch({ type: 'chartDesigner/fetchChartData', page, pageSize})
  146. }}
  147. >立即刷新</Button>
  148. </div>
  149. </Footer> }
  150. </Sider>
  151. <Content className='view-content' >
  152. <Layout>
  153. <Header className='content-header'>
  154. <ToolBar className='header-toolbar' autoRefresh={autoRefresh} isOwner={isOwner}/>
  155. </Header>
  156. <Content className='content-body' style={{ backgroundColor: theme.base.backgroundColor }}>
  157. {/* 创建一个隐藏echarts容器用于截缩略图 */}
  158. <Thumbnail
  159. style={{ position: 'absolute', display: 'none', top: 0, left: 0 }}
  160. key={`thumbnail-${hashcode(chartOption)}`}
  161. option={chartOption}
  162. />
  163. { chartView }
  164. </Content>
  165. </Layout>
  166. </Content>
  167. </Layout>
  168. )
  169. }
  170. }
  171. export default connect(({ present:{ main, chartDesigner } }) => ({ main, chartDesigner }))(ChartDesignerContent);