chartDesigner.js 34 KB

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