chartDesigner.js 31 KB

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