parseChartOption.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /**
  2. * 将请求返回的图表展示数据解析为前台展示用的config
  3. */
  4. import moment from 'moment'
  5. import EllipsisTooltip from '../components/common/ellipsisTooltip/index'
  6. import STATISTICS_OPTION from '../components/chartDesigner/sections/statisticsOption.json'
  7. export default function(viewType, data, chartConfig) {
  8. if(!data) {
  9. return {};
  10. }
  11. try {
  12. let o;
  13. switch(viewType) {
  14. case 'bar': {
  15. o = barOption(data, chartConfig);
  16. break;
  17. }
  18. case 'pie': {
  19. o = pieOption(data, chartConfig);
  20. break;
  21. }
  22. case 'line': {
  23. o = lineOption(data, chartConfig);
  24. break;
  25. }
  26. case 'scatter': {
  27. o = scatterOption(data, chartConfig);
  28. break;
  29. }
  30. case 'aggregateTable': {
  31. o = aggregateTableOption(data, chartConfig);
  32. break;
  33. }case 'dataView' : {
  34. o = dataViewOption(data, chartConfig);
  35. break;
  36. }
  37. default:{
  38. o = {};
  39. break;
  40. }
  41. }
  42. return o;
  43. }catch(e) {
  44. console.error(e);
  45. }
  46. }
  47. function barOption(data, barConfig) {
  48. let xTitle = barConfig.xAxis?`${barConfig.xAxis.column.label}${barConfig.xAxis.granularity.value?'('+barConfig.xAxis.granularity.label+')':''}`:null
  49. let yTitle = barConfig.yAxis?`${barConfig.yAxis.column.label}${barConfig.yAxis.gauge.value?'('+barConfig.yAxis.gauge.label+')':''}`:null
  50. data.serieses = data.serieses || [];
  51. let option = {
  52. tooltip : {
  53. trigger: "axis",
  54. axisPointer: {
  55. type: "cross",
  56. label: {
  57. backgroundColor: "#6a7985"
  58. }
  59. }
  60. },
  61. legend: {
  62. show: data.serieses.length > 1
  63. },
  64. grid: {
  65. left: '10%',
  66. right: '10%',
  67. top: 60,
  68. bottom: 60,
  69. containLabel: true
  70. },
  71. xAxis: [{
  72. type: 'category',
  73. data: data.xAxis.map(d => {
  74. let gv= barConfig.xAxis.granularity.value;
  75. let xv = d || '空';
  76. if(gv === 'halfYear') {
  77. let arr = d.split('-H');
  78. xv = arr[0] + ['上半年', '下半年'][arr[1] - 1]
  79. }else if(gv === 'month') {
  80. xv = d.replace('-M', '-');
  81. }else if(gv === 'quarter') {
  82. let arr = d.split('-Q');
  83. xv = arr[0] + '-' + ['一', '二', '三', '四'][arr[1] - 1] + '季度'
  84. }else if(gv === 'week') {
  85. let arr = d.split('-W');
  86. xv = arr[0] + '-' + arr[1] + '周'
  87. }
  88. return xv;
  89. }),
  90. name: xTitle || '横轴',
  91. }],
  92. yAxis: [{
  93. name: yTitle || '纵轴',
  94. type: 'value'
  95. }],
  96. series: data.serieses.map(s => {
  97. return {
  98. name: barConfig.groupBy ? s.name : (barConfig.yAxis.column.label || s.name),
  99. type: 'bar',
  100. data: s.value,
  101. // stack: s.stack
  102. }
  103. })
  104. }
  105. return option;
  106. }
  107. function pieOption(data, pieConfig) {
  108. let columnName = pieConfig.xAxis.column.label + (pieConfig.xAxis.granularity.value ? '('+pieConfig.xAxis.granularity.label+')' : '');
  109. let option = {
  110. tooltip : {
  111. trigger: 'item',
  112. formatter: "{a} <br/>{b} : {c} ({d}%)"
  113. },
  114. legend: {
  115. data: (data.xAxis || []).map(d => d || '空')
  116. },
  117. grid: {
  118. left: '10%',
  119. right: '10%',
  120. top: 100,
  121. bottom: 60,
  122. containLabel: true
  123. },
  124. series : [
  125. {
  126. name: columnName,
  127. type: 'pie',
  128. // radius : '55%',
  129. // center: ['50%', '60%'],
  130. data: (data.serieses || [{ value: [] }])[0].value.map(v => ({ ...v, name: v.name || '空' })),
  131. itemStyle: {
  132. emphasis: {
  133. shadowBlur: 10,
  134. shadowOffsetX: 0,
  135. shadowColor: 'rgba(0, 0, 0, 0.5)'
  136. }
  137. }
  138. }
  139. ]
  140. };
  141. return option;
  142. }
  143. function lineOption(data, lineConfig) {
  144. let xTitle = lineConfig.xAxis?`${lineConfig.xAxis.column.label}${lineConfig.xAxis.granularity.value?'('+lineConfig.xAxis.granularity.label+')':''}`:null
  145. let yTitle = lineConfig.yAxis?`${lineConfig.yAxis.column.label}${lineConfig.yAxis.gauge.value?'('+lineConfig.yAxis.gauge.label+')':''}`:null
  146. data.serieses = data.serieses || [];
  147. let option = {
  148. tooltip: {
  149. trigger: 'axis',
  150. axisPointer: {
  151. type: 'cross'
  152. }
  153. },
  154. legend: {
  155. show: data.serieses.length > 1
  156. },
  157. xAxis: {
  158. name: xTitle || '横轴',
  159. type: 'time'
  160. },
  161. yAxis: {
  162. name: yTitle || '纵轴',
  163. type: 'value'
  164. },
  165. series: (data.serieses || []).map(s => {
  166. return {
  167. name: s.name,
  168. type: 'line',
  169. data: s.mdata.map(m => {
  170. return [m.date, m.value]
  171. })
  172. }
  173. })
  174. };
  175. return option;
  176. }
  177. function scatterOption(data, scatterConfig) {
  178. let xTitle = scatterConfig.xAxis?`${scatterConfig.xAxis.column.label}${scatterConfig.xAxis.granularity.value?'('+scatterConfig.xAxis.granularity.label+')':''}`:null
  179. let yTitle = scatterConfig.yAxis?`${scatterConfig.yAxis.column.label}${scatterConfig.yAxis.gauge.value?'('+scatterConfig.yAxis.gauge.label+')':''}`:null
  180. let option = {
  181. tooltip : {
  182. showDelay : 0,
  183. axisPointer:{
  184. show: true,
  185. type : 'cross',
  186. lineStyle: {
  187. type : 'dashed',
  188. width : 1
  189. }
  190. }
  191. },
  192. legend: {
  193. show: true
  194. },
  195. xAxis : [
  196. {
  197. type : 'value',
  198. name: xTitle || '横轴',
  199. scale:true,
  200. splitLine: {
  201. show: false
  202. }
  203. }
  204. ],
  205. yAxis : [
  206. {
  207. type : 'value',
  208. name: yTitle || '纵轴',
  209. scale:true,
  210. splitLine: {
  211. show: false
  212. }
  213. }
  214. ],
  215. series : (data.serieses || []).map(s => {
  216. return {
  217. name: s.name,
  218. type: 'scatter',
  219. data: s.mdata.map(m => {
  220. return [m.date, m.value]
  221. })
  222. }
  223. })
  224. };
  225. return option;
  226. }
  227. function aggregateTableOption( data, aggregateTableConfig) {
  228. const resData = data.valueList;
  229. const { targetColumn, statistics } = aggregateTableConfig;
  230. let stypes = STATISTICS_OPTION.filter(o => statistics.indexOf(o.value) !== -1);
  231. let column = {
  232. title: '分析目标',
  233. dataIndex: 'targetColumn'
  234. };
  235. let targetColumnData = { targetColumn: targetColumn.label };
  236. let columns = [column];
  237. let dataSource = [targetColumnData]
  238. if(aggregateTableConfig.groupBy && aggregateTableConfig.groupBy.length > 0) {
  239. columns = columns.concat(aggregateTableConfig.groupBy.map(g => {
  240. return {
  241. title: g.label,
  242. dataIndex: g.key
  243. }
  244. })).concat(stypes.map(st => {
  245. return {
  246. title: st.label,
  247. dataIndex: st.value
  248. }
  249. }));
  250. dataSource = resData.map(d => {
  251. let obj = {};
  252. stypes.map(st => obj[st.value] = d[st.value.toUpperCase()]);
  253. aggregateTableConfig.groupBy.map(g => obj[g.key] = d[g.key])
  254. return { ...targetColumnData, ...obj };
  255. });
  256. }else {
  257. columns = columns.concat(stypes.map(st => {
  258. dataSource = dataSource.map(d => {
  259. d[st.value] = resData[st.value.toUpperCase()]
  260. return d
  261. });
  262. return {
  263. title: st.label,
  264. dataIndex: st.value
  265. }
  266. }));
  267. }
  268. let option = {
  269. columns: columns.map(c => {
  270. let _c = {
  271. ...c, width: 200
  272. };
  273. if(_c.dataIndex === 'percent') {
  274. return { ..._c, render: (value, record, index) => {
  275. return ((+value*100).toFixed(2)) + '%'}
  276. };
  277. }else {
  278. return _c;
  279. }
  280. }),
  281. dataSource: dataSource.map((d, i) => {
  282. return { ...d, key: i}
  283. })
  284. };
  285. return option;
  286. }
  287. function dataViewOption(data, dataViewConfig) {
  288. const { list, pageNum, pageSize, pages, total } = data.valueList;
  289. let columns = dataViewConfig.viewColumns || [];
  290. let dataSource = list || [];
  291. let option = {
  292. columns: columns.map(c => {
  293. let obj = {
  294. title: c.label,
  295. dataIndex: c.name,
  296. }
  297. if(c.type === 'time') {
  298. obj.render = (v, r, i) => {
  299. let text = moment(v).isValid() ? moment(v).format('YYYY-MM-DD') : v
  300. return <EllipsisTooltip title={text}>{text}</EllipsisTooltip>
  301. }
  302. }else {
  303. obj.render = v => {
  304. let text = v === null ? '空' : v
  305. return <EllipsisTooltip title={text}>{text}</EllipsisTooltip>
  306. }
  307. }
  308. return obj;
  309. }),
  310. dataSource: dataSource.map((d, i) => {
  311. return { ...d, key: i}
  312. }),
  313. pageNum,
  314. pageSize,
  315. pages,
  316. total,
  317. };
  318. return option;
  319. }