chartDesigner.js 32 KB

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