chartDesigner.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. import { message } from 'antd'
  2. import * as service from '../services/index'
  3. import URLS from '../constants/url'
  4. import parseChartOption from './parseChartOption'
  5. import moment from 'moment'
  6. function getBodyFilters(filters) {
  7. return filters.filter(f => f.using).map(f => {
  8. let { name, operator, type, value1, value2 } = f;
  9. let bodyFilter = {
  10. columnName: name,
  11. columnType: type,
  12. symbol: operator,
  13. value: value1
  14. };
  15. if(type === 'scale' && operator === 'between') {
  16. bodyFilter['value'] = value1 + ',' + value2;
  17. }else if(type === 'time') {
  18. let v1 = moment(value1).format('YYYY-MM-DD');
  19. let v2 = moment(value2).format('YYYY-MM-DD');
  20. if(operator === 'between') {
  21. bodyFilter['value'] = v1 + ',' + v2;
  22. }else {
  23. bodyFilter['value'] = v1;
  24. }
  25. }else if(type === 'categorical' && (operator === 'contain' || operator === 'notContain')) {
  26. bodyFilter['value'] = JSON.stringify(value1);
  27. }
  28. return bodyFilter;
  29. });
  30. }
  31. export default {
  32. namespace: 'chartDesigner',
  33. state: {
  34. originData: {
  35. code: null,
  36. creatorCode: null,
  37. creatorName: null,
  38. header: { label: '无标题' },
  39. columns: [],
  40. baseConfig: { dataSource: { code: '' }, viewType: '' },
  41. aggregateTableConfig: { targetColumn: {}, statistics: [], groupBy: [] },
  42. dataViewConfig: { viewColumns: [], sortColumn: {key: ''}, sortType: 'asc' },
  43. barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
  44. lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
  45. pieConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} } },
  46. scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
  47. styleConfig: { visibleIndex: true },
  48. otherConfig:{},
  49. description: '',
  50. filters: [],
  51. chartOption: {},
  52. dirty: false,
  53. fetchConfig: {}
  54. },
  55. },
  56. reducers: {
  57. /**
  58. * 更新model字段值
  59. * 1. 进入撤销重做历史
  60. */
  61. setField(state, action) {
  62. const { name, value } = action;
  63. let obj = {};
  64. obj[name] = value;
  65. let newState = Object.assign({}, state, obj);
  66. return Object.assign({}, newState, {dirty: true});
  67. },
  68. /**
  69. * 批量更新model字段值
  70. * 1. 进入撤销重做历史
  71. */
  72. setFields(state, action) {
  73. const { fields } = action;
  74. let obj = {};
  75. fields.map(f => (obj[f.name] = f.value));
  76. let newState = Object.assign({}, state, obj);
  77. return Object.assign({}, newState, {dirty: true});
  78. },
  79. /**
  80. * 更新model字段值
  81. * 1. 不进入撤销重做历史
  82. */
  83. silentSetField(state, action) {
  84. const { name, value } = action;
  85. let obj = {};
  86. obj[name] = value;
  87. let newState = Object.assign({}, state, obj);
  88. return newState;
  89. },
  90. /**
  91. * 批量更新model字段值
  92. * 1. 不进入撤销重做历史
  93. */
  94. silentSetFields(state, action) {
  95. const { fields } = action;
  96. let obj = {};
  97. fields.map(f => (obj[f.name] = f.value));
  98. let newState = Object.assign({}, state, obj);
  99. return newState;
  100. },
  101. reset(state, action) {
  102. let newState = Object.assign({}, state, state.originData);
  103. return Object.assign({}, newState);
  104. },
  105. setDirty(state, action) {
  106. const { dirty } = action;
  107. let newState = Object.assign({}, state, { dirty });
  108. return newState;
  109. }
  110. },
  111. effects: {
  112. /**
  113. * 初始化批量更新model字段值
  114. * 触发数据刷新、不进入撤销重做历史
  115. */
  116. *defaultChangeFields(action, { select, call, put }) {
  117. const { fields } = action;
  118. yield put({ type: 'silentSetFields', fields });
  119. const { autoRefresh } = action;
  120. if(autoRefresh === undefined ? true : autoRefresh) {
  121. yield put({ type: 'fetchChartData' });
  122. }
  123. },
  124. /**
  125. * 更新model字段值
  126. * 可能影响到数据刷新的model字段改变一般用该action
  127. */
  128. *changeField(action, { select, call, put }) {
  129. const { name, value } = action;
  130. yield put({ type: 'setField', name, value });
  131. const { autoRefresh } = action;
  132. if(autoRefresh === undefined ? true : autoRefresh) {
  133. yield put({ type: 'fetchChartData' });
  134. }
  135. },
  136. /**
  137. * 批量更新model字段值
  138. */
  139. *changeFields(action, { select, call, put }) {
  140. const { fields } = action;
  141. yield put({ type: 'setFields', fields });
  142. const { autoRefresh } = action;
  143. if(autoRefresh === undefined ? true : autoRefresh) {
  144. yield put({ type: 'fetchChartData' });
  145. }
  146. },
  147. *changeDataSource(action, { select, call, put }) {
  148. const { dataSource } = action;
  149. yield put({ type: 'remoteDataColumn', code: dataSource.code });
  150. },
  151. *remoteQucikAdd(action, { select, call, put }) {
  152. try{
  153. const { dataSource } = action;
  154. yield put({ type: 'silentSetFields', fields: [
  155. { name: 'baseConfig', value: { dataSource: dataSource.code, viewType: '' } }
  156. ] });
  157. let body = {
  158. chartName: dataSource.name + '_未命名',
  159. dataId: dataSource.code,
  160. describes: '',
  161. chartConfig: '{}',
  162. chartType: '',
  163. };
  164. console.log('快速新增图表', body);
  165. const res = yield call(service.fetch, {
  166. url: URLS.CHART_ADD,
  167. body: body
  168. })
  169. console.log('快速新增图表', body, res);
  170. if(!res.err && res.data.data > 0) {
  171. yield put({ type: 'chart/fetchList', mandatory: true });
  172. yield put({ type: 'main/redirect', path: '/chart/' + res.data.data });
  173. // yield put({ type: 'chart/remoteDetail', code: res.data.data });
  174. }else {
  175. message.error('新增失败: ' + (res.err || res.data.msg));
  176. }
  177. }catch(e) {
  178. console.error(e);
  179. message.error('新增失败: ' + e);
  180. }
  181. },
  182. /**
  183. * 复制新增
  184. */
  185. *remoteCopyAdd(action, { select, call, put }) {
  186. try{
  187. yield put({ type: 'chart/remoteModify' });
  188. const { newHeaderLabel } = action;
  189. const chartDesigner = yield select(state => state.present.chartDesigner);
  190. const { filters, baseConfig, pieConfig, lineConfig, aggregateTableConfig, dataViewConfig,
  191. barConfig, scatterConfig, otherConfig, description, group, chartOption, fetchConfig, styleConfig } = chartDesigner;
  192. let body = {
  193. filters: JSON.stringify(filters),
  194. chartName: newHeaderLabel,
  195. dataId: baseConfig.dataSource.code,
  196. describes: description || '',
  197. style: JSON.stringify(styleConfig),
  198. otherConfig: JSON.stringify(otherConfig),
  199. chartsGroup: group+'' ? group : '-1',
  200. chartOption: JSON.stringify(chartOption),
  201. fetchConfig: JSON.stringify(fetchConfig),
  202. }; // 基本属性
  203. if(baseConfig.viewType === 'bar') {
  204. body.chartType = 'Histogram';
  205. body.chartConfig = JSON.stringify(barConfig);
  206. }else if(baseConfig.viewType === 'pie') {
  207. body.chartType = 'Pie';
  208. body.chartConfig = JSON.stringify(pieConfig);
  209. }else if(baseConfig.viewType === 'line') {
  210. body.chartType = 'Line';
  211. body.chartConfig = JSON.stringify(lineConfig);
  212. }else if(baseConfig.viewType === 'scatter') {
  213. body.chartType = 'scatter';
  214. body.chartConfig = JSON.stringify(scatterConfig);
  215. }else if(baseConfig.viewType === 'aggregateTable') {
  216. body.chartType = 'population';
  217. body.chartConfig = JSON.stringify(aggregateTableConfig);
  218. }else if(baseConfig.viewType === 'dataView') {
  219. body.chartType = 'individual';
  220. body.chartConfig = JSON.stringify(dataViewConfig);;
  221. }else {
  222. body.chartType = '';
  223. body.chartConfig = JSON.stringify({});
  224. }
  225. const res = yield call(service.fetch, {
  226. url: URLS.CHART_ADD,
  227. body: body
  228. })
  229. console.log('复制新增', body, res);
  230. if(!res.err && res.data.code > 0) {
  231. yield put({ type: 'chart/fetchList', mandatory: true });
  232. yield put({ type: 'main/redirect', path: '/chart/' + res.data.data , reload: true});
  233. }else {
  234. message.error('创建副本失败: ' + (res.err || res.data.msg));
  235. }
  236. }catch(e) {
  237. console.error(e);
  238. message.error('创建副本失败: ' + e);
  239. }
  240. },
  241. *remoteDataColumn(action, { select, call, put }) {
  242. const code = action.code;
  243. try {
  244. const res = yield call(service.fetch, {
  245. url: URLS.DATASOURCE_QUERY_DATACOLUMNS,
  246. body: code
  247. });
  248. console.log('获得图表关联数据源列数据', code, res);
  249. if(!res.err && res.data.code > 0) {
  250. let resData = res.data.data;
  251. let columns = resData.map((c, i) => {
  252. return {
  253. key: i,
  254. name: c.columnName,
  255. label: c.columnRaname,
  256. type: c.columnType,
  257. groupable: c.isGroup==='1'?true:false,
  258. filterable: c.isFilter==='1'?true:false,
  259. bucketizable: c.isSubsection==='1'?true:false,
  260. selection: []
  261. }
  262. })
  263. yield put({ type: 'silentSetField', name: 'columns', value: columns });
  264. }else {
  265. message.error('请求列数据失败:' + (res.err || res.data.msg));
  266. yield put({ type: 'silentSetField', name: 'columns', value: [] });
  267. }
  268. }catch(e) {
  269. message.error('请求列数据失败: ' + e);
  270. yield put({ type: 'silentSetField', name: 'columns', value: [] });
  271. }
  272. },
  273. *fetchChartData(action, { select, call, put }) {
  274. const chartDesigner = yield select(state => state.present.chartDesigner);
  275. const { baseConfig } = chartDesigner;
  276. const { viewType } = baseConfig;
  277. yield put({ type: 'silentSetField', name: 'fetchConfig', value: {} });
  278. if(viewType === 'bar') {
  279. const { barConfig } = chartDesigner;
  280. if(barConfig.xAxis.column.value && barConfig.yAxis.column.value) {
  281. yield put({ type: 'fetchBarData' });
  282. }else {
  283. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  284. }
  285. }else if(viewType === 'pie') {
  286. const { pieConfig } = chartDesigner;
  287. if(pieConfig.xAxis.column.value && pieConfig.yAxis.column.value) {
  288. yield put({ type: 'fetchPieData' });
  289. }else {
  290. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  291. }
  292. }else if(viewType === 'line') {
  293. const { lineConfig } = chartDesigner;
  294. if(lineConfig.xAxis.column.value && lineConfig.yAxis.column.value) {
  295. yield put({ type: 'fetchLineData' });
  296. }else {
  297. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  298. }
  299. }else if(viewType === 'scatter') {
  300. const { scatterConfig } = chartDesigner;
  301. if(scatterConfig.xAxis.column.value && scatterConfig.yAxis.column.value) {
  302. yield put({ type: 'fetchScatterData' });
  303. }else {
  304. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  305. }
  306. }else if(viewType === 'dataView') {
  307. const { dataViewConfig } = chartDesigner;
  308. if(dataViewConfig.viewColumns.length > 0 &&
  309. dataViewConfig.sortColumn.key &&
  310. dataViewConfig.sortType) {
  311. yield put({ type: 'fetchDataViewData' });
  312. }else {
  313. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  314. }
  315. }else if(viewType === 'aggregateTable') {
  316. const { aggregateTableConfig } = chartDesigner;
  317. if(aggregateTableConfig.targetColumn.name && aggregateTableConfig.statistics.length > 0) {
  318. yield put({ type: 'fetchAggregateTableData' });
  319. }else {
  320. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  321. }
  322. }else {
  323. console.log('no viewType......')
  324. }
  325. },
  326. *fetchBarData(action, { select, call, put }) {
  327. try {
  328. const chartDesigner = yield select(state => state.present.chartDesigner);
  329. const { code, barConfig, filters } = chartDesigner;
  330. const body = {
  331. id: code,
  332. groups: barConfig.groupBy && barConfig.groupBy.key ? [barConfig.groupBy.key] : [],
  333. xAxis: {
  334. columnRename: barConfig.xAxis.column.value,
  335. columnType: barConfig.xAxis.column.type,
  336. showDataType: barConfig.xAxis.granularity.value
  337. },
  338. yAxis: {
  339. columnRename: barConfig.yAxis.column.value,
  340. showDataType: barConfig.yAxis.gauge.value
  341. },
  342. filters: getBodyFilters(filters)
  343. };
  344. console.log('请求柱状图数据', body);
  345. let res = yield call(service.fetch, {
  346. url: URLS.CHART_BAR_OPTION,
  347. body: body,
  348. timeout: 30000
  349. });
  350. console.log('请求柱状图数据', body, res);
  351. if(!res.err && res.data.code > 0) {
  352. let option = parseChartOption('bar', res.data.data, barConfig);
  353. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  354. }else {
  355. message.error('请求柱状图数据失败: ' + (res.err || res.data.msg));
  356. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  357. }
  358. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  359. }catch(e) {
  360. console.error(e);
  361. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  362. message.error('请求柱状图数据失败: ' + e);
  363. }
  364. },
  365. *fetchPieData(action, { select, call, put }) {
  366. try {
  367. const chartDesigner = yield select(state => state.present.chartDesigner);
  368. const { code, pieConfig, filters } = chartDesigner;
  369. const body = {
  370. id: code,
  371. legendData: {
  372. columnRename: pieConfig.xAxis.column.value,
  373. columnType: pieConfig.xAxis.column.type,
  374. showDataType: pieConfig.xAxis.granularity.value
  375. },
  376. series: {
  377. columnRename: pieConfig.yAxis.column.value,
  378. columnName: pieConfig.yAxis.column.label,
  379. showDataType: pieConfig.yAxis.gauge.value
  380. },
  381. filters: getBodyFilters(filters)
  382. };
  383. console.log('请求饼图数据', body);
  384. let res = yield call(service.fetch, {
  385. url: URLS.CHART_PIE_OPTION,
  386. body: body,
  387. timeout: 30000
  388. });
  389. console.log('请求饼图数据', body, res);
  390. if(!res.err && res.data.code > 0) {
  391. let option = parseChartOption('pie', res.data.data, pieConfig);
  392. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  393. }else {
  394. message.error('请求饼图数据失败: ' + (res.err || res.data.msg));
  395. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  396. }
  397. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  398. }catch(e) {
  399. console.error(e);
  400. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  401. message.error('请求饼图数据失败: ' + e);
  402. }
  403. },
  404. *fetchLineData(action, { select, call, put }) {
  405. try {
  406. const chartDesigner = yield select(state => state.present.chartDesigner);
  407. const { code, lineConfig, filters } = chartDesigner;
  408. const body = {
  409. id: code,
  410. xAxis: {
  411. columnRename: lineConfig.xAxis.column.value,
  412. columnType: lineConfig.xAxis.column.type
  413. },
  414. yAxis: {
  415. columnRename: lineConfig.yAxis.column.value,
  416. showDataType: lineConfig.yAxis.gauge.value
  417. },
  418. groups: lineConfig.groupBy && lineConfig.groupBy.key ? [lineConfig.groupBy.key] : [],
  419. filters: getBodyFilters(filters)
  420. };
  421. console.log('请求折线图数据', body);
  422. let res = yield call(service.fetch, {
  423. url: URLS.CHART_LINE_OPTION,
  424. body: body,
  425. timeout: 30000
  426. });
  427. console.log('请求折线图数据', body, res);
  428. if(!res.err && res.data.code > 0) {
  429. let option = parseChartOption('line', res.data.data, lineConfig);
  430. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  431. }else {
  432. message.error('请求折线图数据失败: ' + (res.err || res.data.msg));
  433. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  434. }
  435. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  436. }catch(e) {
  437. console.error(e);
  438. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  439. message.error('请求折线图数据失败: ' + e);
  440. }
  441. },
  442. *fetchScatterData(action, { select, call, put }) {
  443. try {
  444. const chartDesigner = yield select(state => state.present.chartDesigner);
  445. const { code, scatterConfig, filters } = chartDesigner;
  446. const body = {
  447. id: code,
  448. xAxis: {
  449. columnRename: scatterConfig.xAxis.column.value,
  450. columnType: scatterConfig.xAxis.column.type
  451. },
  452. yAxis: {
  453. columnRename: scatterConfig.yAxis.column.value,
  454. showDataType: scatterConfig.yAxis.gauge.value
  455. },
  456. groups: scatterConfig.groupBy && scatterConfig.groupBy.key ? [scatterConfig.groupBy.key] : [],
  457. filters: getBodyFilters(filters)
  458. };
  459. console.log('请求散点图数据', body);
  460. let res = yield call(service.fetch, {
  461. url: URLS.CHART_SCATTER_OPTION,
  462. body: body,
  463. timeout: 30000
  464. });
  465. console.log('请求散点图数据', body, res);
  466. if(!res.err && res.data.code > 0) {
  467. let option = parseChartOption('scatter', res.data.data, scatterConfig);
  468. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  469. }else {
  470. message.error('请求散点图数据失败: ' + (res.err || res.data.msg));
  471. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  472. }
  473. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  474. }catch(e) {
  475. console.error(e);
  476. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  477. message.error('请求散点图数据失败: ' + e);
  478. }
  479. },
  480. *fetchDataViewData(action, { select, call, put }) {
  481. try {
  482. const chartDesigner = yield select(state => state.present.chartDesigner);
  483. const { code, dataViewConfig, filters } = chartDesigner;
  484. const { page, pageSize } = action;
  485. const body = {
  486. id: code,
  487. columnListName: dataViewConfig.viewColumns.map(c => c.name),
  488. sortColumn: dataViewConfig.sortColumn.key,
  489. sort: dataViewConfig.sortType,
  490. filters: getBodyFilters(filters),
  491. testPage: {
  492. pageNum: page || 1,
  493. pageSize: pageSize || 25,
  494. }
  495. };
  496. console.log('请求表格数据', body);
  497. let res = yield call(service.fetch, {
  498. url: URLS.CHART_DATAVIEW_OPTION,
  499. body: body,
  500. timeout: 30000
  501. });
  502. console.log('请求表格数据', body, res);
  503. if(!res.err && res.data.code > 0) {
  504. let option = parseChartOption('dataView', res.data.data, dataViewConfig);
  505. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  506. // 主动触发一次window的resize事件
  507. yield window.setTimeout(() => {
  508. var e = document.createEvent("Event");
  509. e.initEvent("resize", true, true);
  510. window.dispatchEvent(e);
  511. }, 200);
  512. }else {
  513. // message.error('请求列表数据失败: ' + (res.err || res.data.msg));
  514. // yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  515. }
  516. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  517. }catch(e) {
  518. console.error(e);
  519. // yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  520. // message.error('请求列表数据失败: ' + e);
  521. }
  522. },
  523. *fetchAggregateTableData(action, { select, call, put }) {
  524. try {
  525. const chartDesigner = yield select(state => state.present.chartDesigner);
  526. const { code, aggregateTableConfig, filters } = chartDesigner;
  527. const { targetColumn, statistics } = aggregateTableConfig;
  528. const body = {
  529. id: code,
  530. columnName: targetColumn.name,
  531. operatorList: statistics,
  532. groupByList: aggregateTableConfig.groupBy && aggregateTableConfig.groupBy.length > 0 ? aggregateTableConfig.groupBy.map(g => g.key) : [],
  533. filters: getBodyFilters(filters),
  534. testPage: {
  535. pageNum: 1,
  536. pageSize: 999,
  537. }
  538. };
  539. console.log('获得总体统计数据', body);
  540. let res = yield call(service.fetch, {
  541. url: URLS.CHART_AGGREGATETABLE_OPTION,
  542. body: body,
  543. timeout: 30000
  544. });
  545. console.log('获得总体统计数据', body, res);
  546. if(!res.err && res.data.code > 0) {
  547. let option = parseChartOption('aggregateTable', res.data.data, aggregateTableConfig);
  548. yield put({ type: 'silentSetField', name: 'chartOption', value: option });
  549. }else {
  550. message.error('请求统计数据失败: ' + (res.err || res.data.msg));
  551. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  552. }
  553. yield put({ type: 'silentSetField', name: 'fetchConfig', value: body });
  554. }catch(e) {
  555. console.error(e);
  556. yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  557. message.error('请求统计数据失败: ' + e);
  558. }
  559. },
  560. /**
  561. * 将图表数据以表格的方式作为预览
  562. */
  563. *remoteChartDataList(action, { select, call, put }) {
  564. try {
  565. const chartDesigner = yield select(state => state.present.chartDesigner);
  566. const { code, baseConfig, aggregateTableConfig, lineConfig, barConfig, pieConfig, scatterConfig, dataViewConfig, filters } = chartDesigner;
  567. const { viewType } = baseConfig;
  568. const { page, pageSize } = action;
  569. let columns = [];
  570. let columnListName = [];
  571. let sortColumn = null;
  572. if(viewType === 'aggregateTable') {
  573. const { groupBy, targetColumn } = aggregateTableConfig;
  574. groupBy.map(g => ({
  575. title: g.label,
  576. dataIndex: g.key,
  577. // render: g.columnType === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  578. })).concat({
  579. title: targetColumn.label,
  580. dataIndex: targetColumn.name,
  581. render: targetColumn.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  582. }).filter(x => !!x.dataIndex).forEach(x => {
  583. if(!columns.find(c => c.dataIndex === x.dataIndex)) {
  584. columns.push(x);
  585. }
  586. });;
  587. sortColumn = targetColumn.name;
  588. }else if(viewType === 'line') {
  589. const { groupBy, xAxis, yAxis } = lineConfig;
  590. [{
  591. title: groupBy ? groupBy.label : '',
  592. dataIndex: groupBy ?groupBy.key : '',
  593. // render: g.columnType === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  594. }, {
  595. title: xAxis.column.label,
  596. dataIndex: xAxis.column.value,
  597. render: xAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  598. }, {
  599. title: yAxis.column.label,
  600. dataIndex: yAxis.column.value,
  601. render: yAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  602. }].filter(x => !!x.dataIndex).forEach(x => {
  603. if(!columns.find(c => c.dataIndex === x.dataIndex)) {
  604. columns.push(x);
  605. }
  606. });;
  607. sortColumn = xAxis.column.value;
  608. }else if(viewType === 'bar') {
  609. const { groupBy, xAxis, yAxis } = barConfig;
  610. [{
  611. title: groupBy ? groupBy.label : '',
  612. dataIndex: groupBy ? groupBy.key : '',
  613. // render: g.columnType === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  614. }, {
  615. title: xAxis.column.label,
  616. dataIndex: xAxis.column.value,
  617. render: xAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  618. }, {
  619. title: yAxis.column.label,
  620. dataIndex: yAxis.column.value,
  621. render: yAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  622. }].filter(x => !!x.dataIndex).forEach(x => {
  623. if(!columns.find(c => c.dataIndex === x.dataIndex)) {
  624. columns.push(x);
  625. }
  626. });;
  627. sortColumn = xAxis.column.value;
  628. }else if(viewType === 'pie') {
  629. const { xAxis, yAxis } = pieConfig;
  630. [{
  631. title: xAxis.column.label,
  632. dataIndex: xAxis.column.value,
  633. render: xAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  634. }, {
  635. title: yAxis.column.label,
  636. dataIndex: yAxis.column.value,
  637. render: yAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  638. }].filter(x => !!x.dataIndex).forEach(x => {
  639. if(!columns.find(c => c.dataIndex === x.dataIndex)) {
  640. columns.push(x);
  641. }
  642. });;
  643. sortColumn = xAxis.column.value;
  644. }else if(viewType === 'scatter') {
  645. const { groupBy, xAxis, yAxis } = scatterConfig;
  646. [{
  647. title: groupBy ? groupBy.label : '',
  648. dataIndex: groupBy ? groupBy.key : '',
  649. // render: g.columnType === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  650. }, {
  651. title: xAxis.column.label,
  652. dataIndex: xAxis.column.value,
  653. render: xAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  654. }, {
  655. title: yAxis.column.label,
  656. dataIndex: yAxis.column.value,
  657. render: yAxis.column.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  658. }].filter(x => !!x.dataIndex).forEach(x => {
  659. if(!columns.find(c => c.dataIndex === x.dataIndex)) {
  660. columns.push(x);
  661. }
  662. });;
  663. sortColumn = xAxis.column.value;
  664. }else if(viewType === 'dataView') {
  665. columns = dataViewConfig.viewColumns.map(c => ({
  666. title: c.label,
  667. dataIndex: c.name,
  668. render: c.type === 'time' ? ((v, r, i) => moment(v).format('YYYY-MM-DD')) : v => v
  669. }));
  670. sortColumn = dataViewConfig.sortColumn.key;
  671. }
  672. columnListName = columns.map(c => c.dataIndex);
  673. const body = {
  674. id: code,
  675. columnListName: columnListName,
  676. sortColumn: sortColumn,
  677. sort: 'asc',
  678. filters: getBodyFilters(filters),
  679. testPage: {
  680. pageNum: page || 1,
  681. pageSize: pageSize || 25,
  682. }
  683. };
  684. yield put({ type: 'dataList/setField', name: 'loading', value: true });
  685. console.log('请求数据列表', body);
  686. let res = yield call(service.fetch, {
  687. url: URLS.CHART_DATAVIEW_OPTION,
  688. body: body,
  689. timeout: 30000
  690. });
  691. console.log('请求数据列表', body, res);
  692. if(!res.err && res.data.code > 0) {
  693. const { valueList } = res.data.data;
  694. const { list: dataSource, pageSize, total } = valueList;
  695. yield put({ type: 'dataList/setFields', fields: [
  696. { name: 'columns', value: columns },
  697. { name: 'dataSource', value: dataSource },
  698. { name: 'pageSize', value: pageSize },
  699. { name: 'total', value: total }
  700. ] });
  701. // 主动触发一次window的resize事件
  702. yield window.setTimeout(() => {
  703. var e = document.createEvent("Event");
  704. e.initEvent("resize", true, true);
  705. window.dispatchEvent(e);
  706. }, 20);
  707. }else {
  708. // message.error('请求列表数据失败: ' + (res.err || res.data.msg));
  709. // yield put({ type: 'silentSetField', name: 'chartOption', value: {} });
  710. }
  711. }catch(e) {
  712. console.error(e);
  713. message.error('请求数据列表失败: ' + e);
  714. }finally {
  715. yield put({ type: 'dataList/setField', name: 'loading', value: false });
  716. }
  717. },
  718. },
  719. subscriptions: {
  720. setup({ dispatch, history }) {
  721. dispatch({ type: 'reset' });
  722. },
  723. },
  724. };