You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1169 lines
31 KiB

4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <template>
  2. <section class="page-container">
  3. <div class="page-main">
  4. <div class="row_1">
  5. <div class="r r1">
  6. <span style="color: #4779F6">{{formatNum(xmBranchState.projectCnt,0) || 0}}</span>
  7. <p>项目数</p>
  8. </div>
  9. <div class="r r2">
  10. <span style="color: #4779F6">{{formatNum(xmBranchState.budgetWorkload,0) || 0}}</span>
  11. <p>项目总工时</p>
  12. </div>
  13. <div class="r r3">
  14. <span style="color: #F6AE47">{{formatNum(xmBranchState.productCnt,0) || 0}}</span>
  15. <p>产品数</p>
  16. </div>
  17. <div class="r r4">
  18. <span style="color: #F6AE47">{{formatNum(xmBranchState.productBudgetWorkload,0) || 0}}</span>
  19. <p>产品总工时</p>
  20. </div>
  21. <div class="r r5">
  22. <span style="color: #47CBF6">{{formatNum(xmBranchState.phaseCnt,0) || 0}}</span>
  23. <p>计划数</p>
  24. </div>
  25. <div class="r r6">
  26. <span style="color: #47CBF6">{{formatNum(xmBranchState.iterationCnt,0) || 0}}</span>
  27. <p>迭代数</p>
  28. </div>
  29. <div class="r r7">
  30. <span style="color: #F68D47">{{formatNum(xmBranchState.planWorkerCnt,0) || 0}}</span>
  31. <p>总人数</p>
  32. </div>
  33. <div class="r r8">
  34. <span style="color: #7D7D7D">{{formatNum(xmBranchState.taskCnt,0) || 0}}</span>
  35. <p>任务数</p>
  36. </div>
  37. <div class="r r9">
  38. <span style="color: #7D7D7D">{{formatNum(xmBranchState.menuCnt,0) || 0}}</span>
  39. <p>需求数</p>
  40. </div>
  41. </div>
  42. <div class="row_2">
  43. <div class="r1">
  44. <p class="r_text">项目进度</p>
  45. <div class="message">
  46. <div>
  47. <span>{{formatNum(this.xmBranchState.estimateWorkload,0) || 0}}h</span>
  48. <p>预估工时</p>
  49. </div>
  50. <div>
  51. <span>{{formatNum(this.xmBranchState.actWorkload,0) || 0}}h</span>
  52. <p>登记工时</p>
  53. </div>
  54. <div>
  55. <span>{{ formatNum(workloadProgress,0) || 0}}%</span>
  56. <p>工时进度</p>
  57. </div>
  58. <div>
  59. <span>{{ formatNum(remainWorkload,0) || 0}}h</span>
  60. <p>剩余工时</p>
  61. </div>
  62. <div>
  63. <span>{{ formatNum(deviation,0)|| 0}}h</span>
  64. <p>预估偏差</p>
  65. </div>
  66. <div>
  67. <span>{{ formatNum(deviationRate,0) || 0}}%</span>
  68. <p>预估偏差率</p>
  69. </div>
  70. </div>
  71. <div style="padding: 0 40px">
  72. <el-divider></el-divider>
  73. </div>
  74. <div class="chart">
  75. <div class="desc">
  76. <span>项目预计进度</span>
  77. <span>项目实际进度</span>
  78. </div>
  79. <div class="process">
  80. <el-progress class="pc" :stroke-width="14" :percentage="planProgress"></el-progress>
  81. <el-progress class="pc" :stroke-width="14" color="#47CBF6" :percentage="realProgress"></el-progress>
  82. </div>
  83. </div>
  84. </div>
  85. <div class="r2">
  86. <p class="r_text">工作量分布</p>
  87. <div class="chart">
  88. <div id="workloadDistribution" :style="{width: '100%', height: '250px'}"></div>
  89. </div>
  90. </div>
  91. </div>
  92. <div class="row_3">
  93. <div class="r1">
  94. <p class="r_text">任务每日状态趋势</p>
  95. <div class="chart">
  96. <div id="taskChart" :style="{width: '100%', height: '320px'}"></div>
  97. </div>
  98. </div>
  99. <div class="r2">
  100. <p class="r_text">工作项数量分布</p>
  101. <div class="chart">
  102. <div id="allChart" :style="{width: '100%', height: '320px'}"></div>
  103. </div>
  104. </div>
  105. </div>
  106. <div class="row_4">
  107. <div class="r4_1">
  108. <p class="r_text">总预算情况</p>
  109. <div class="chart">
  110. <div id="planTotalCostPie" :style="{width: '100%', height: '410px'}"></div>
  111. </div>
  112. </div>
  113. <div class="r4_2">
  114. <p class="r_text">总缺陷情况</p>
  115. <div class="chart">
  116. <div id="bugPieChart" :style="{width: '100%', height: '410px'}"></div>
  117. </div>
  118. </div>
  119. <div class="r4_3">
  120. <p class="r_text">所含产品和迭代情况</p>
  121. <div class="chart">
  122. <div id="iterationAndProduct" :style="{width: '100%', height: '320px'}"></div>
  123. </div>
  124. </div>
  125. </div>
  126. </div>
  127. </section>
  128. </template>
  129. <script>
  130. import util from "@/common/js/util"; // 全局公共库
  131. import { mapGetters } from "vuex";
  132. import { listXmBranchState } from '@/api/xm/core/xmBranchState';
  133. import { listXmBranchFiveDayTaskCnt } from '@/api/xm/core/xmBranchStateHis';
  134. import Guider from '@/components/Guider/Index.js';
  135. export default {
  136. computed: {
  137. ...mapGetters(["userInfo"]),
  138. finish: function (){
  139. return this.xmBranchState.taskFinishCnt;
  140. },
  141. notStart: function() {
  142. return this.xmBranchState.taskCnt-this.xmBranchState.taskFinishCnt;
  143. },
  144. totalTask: function() {
  145. return this.xmBranchState.taskCnt;
  146. },
  147. taskProgress: function (){
  148. return this.xmBranchState.finishRate;
  149. },
  150. taskStartTime: function (){
  151. return this.xmBranchState.startTime.substring(0,10);
  152. },
  153. taskEndTime: function (){
  154. return this.xmBranchState.endTime.substring(0,10);
  155. },
  156. taskMng: function (){
  157. return this.xmBranchState.createUsername;
  158. },
  159. workloadProgress:function (){
  160. if(!this.xmBranchState.budgetWorkload){
  161. return 0;
  162. }
  163. if(this.xmBranchState.actWorkload < this.xmBranchState.budgetWorkload){
  164. return Math.round(this.xmBranchState.actWorkload/this.xmBranchState.budgetWorkload*100)
  165. }else{
  166. return 100;
  167. }
  168. },
  169. deviation:function (){
  170. return Math.round(this.xmBranchState.actWorkload-this.xmBranchState.estimateWorkload);
  171. },
  172. deviationRate:function (){
  173. return Math.round((this.xmBranchState.actWorkload-this.xmBranchState.estimateWorkload)/this.xmBranchState.estimateWorkload*100);
  174. },
  175. remainWorkload:function (){
  176. return this.xmBranchState.budgetWorkload - this.xmBranchState.actWorkload;
  177. },
  178. planProgress:function (){
  179. if(!this.xmBranchState.budgetWorkload){
  180. return 0;
  181. }
  182. return Math.round( this.xmBranchState.estimateWorkload/this.xmBranchState.budgetWorkload*100)
  183. },
  184. realProgress:function (){
  185. if(!this.xmBranchState.budgetWorkload){
  186. return 0;
  187. }
  188. if(this.xmBranchState.actWorkload < this.xmBranchState.budgetWorkload){
  189. return Math.round(this.xmBranchState.actWorkload/this.xmBranchState.budgetWorkload*100)
  190. }else{
  191. return 100;
  192. }
  193. },
  194. xmTaskFiveDaysCpd(){
  195. if(this.xmBranchFiveDayTaskCnts.length==0){
  196. return [
  197. ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
  198. [120, 132, 101, 134, 90, 230, 210],
  199. [220, 182, 191, 234, 290, 330, 310]
  200. ]
  201. }else{
  202. var datas=this.xmBranchFiveDayTaskCnts;
  203. datas.sort((a,b)=>Date.parse(a.bizDate) - Date.parse(b.bizDate));
  204. var datas2=[
  205. datas.map(i=>this.getWeek(i.bizDate)),
  206. datas.map(i=>i.taskUnstartCnt),
  207. datas.map(i=>i.taskExecCnt)
  208. ]
  209. return datas2;
  210. }
  211. },
  212. xmBranchStateCpd(){
  213. return this.xmBranchState
  214. },
  215. },
  216. watch:{
  217. xmBranchStateCpd:function(){
  218. this.drawWorkload();
  219. this.drawAllBar();
  220. this.drawCostPie();
  221. this.drawPieBug();
  222. this.drawIterationProduct();
  223. },
  224. xmTaskFiveDaysCpd:function(){
  225. this.drawTaskByDate();
  226. }
  227. },
  228. data() {
  229. return {
  230. isActive: true,
  231. xmBranchState:{},
  232. maxTableHeight:300,
  233. xmBranchFiveDayTaskCnts:[],
  234. // options: getDefOptions(),//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]}
  235. };
  236. },
  237. methods:{
  238. drawAllBar() {
  239. // 基于准备好的dom,初始化echarts实例
  240. let allChart = this.$echarts.init(document.getElementById("allChart"));
  241. let option = {
  242. color:['#A3BCFA', '#A3BCFA', '#A3BCFA'],
  243. grid: {
  244. left: '3%',
  245. right: '4%',
  246. bottom: '3%',
  247. containLabel: true
  248. },
  249. yAxis: {
  250. type: 'value',
  251. axisLine: {
  252. show: false
  253. },
  254. axisTick: {
  255. show: false
  256. },
  257. },
  258. xAxis: {
  259. type: 'category',
  260. boundaryGap: true,
  261. data: ['需求', '任务', '缺陷'],
  262. },
  263. series: [
  264. {
  265. name: '需求',
  266. type: 'line',
  267. stack: 'Total',
  268. emphasis: {
  269. focus: 'series'
  270. },
  271. data: [this.xmBranchState.menuCnt],
  272. markPoint: {
  273. data: [{
  274. type: 'max',
  275. name: 'max'
  276. }],
  277. }
  278. },
  279. {
  280. name: '任务',
  281. type: 'line',
  282. stack: 'Total',
  283. emphasis: {
  284. focus: 'series'
  285. },
  286. data: [0, this.xmBranchState.taskCnt],
  287. markPoint: {
  288. data: [{
  289. type: 'max',
  290. name: 'max'
  291. }],
  292. },
  293. },
  294. {
  295. name: '缺陷',
  296. type: 'line',
  297. stack: 'Total',
  298. emphasis: {
  299. focus: 'series'
  300. },
  301. data: [0, 0, this.xmBranchState.bugCnt],
  302. markPoint: {
  303. data: [{
  304. type: 'max',
  305. name: 'max'
  306. }],
  307. },
  308. }
  309. ]
  310. };
  311. // 绘制图表
  312. allChart.setOption(option);
  313. },
  314. drawTaskByDate() {
  315. let taskChart = this.$echarts.init(document.getElementById("taskChart"));
  316. let option = {
  317. tooltip: {
  318. trigger: 'axis'
  319. },
  320. color:['#76AEF7', '#A8E5FA'],
  321. legend: {
  322. data: ['未开始', '进行中']
  323. },
  324. grid: {
  325. left: '1%',
  326. right: '3%',
  327. bottom: '5%',
  328. containLabel: true
  329. },
  330. xAxis: {
  331. type: 'category',
  332. boundaryGap: false,
  333. data: this.xmTaskFiveDaysCpd[0],
  334. splitLine: {
  335. show: true,
  336. lineStyle: {
  337. color: 'rgba(0, 0, 0, .05)'
  338. }
  339. },
  340. axisLine: {
  341. lineStyle: {
  342. color: 'rgba(0, 0, 0, .1)'
  343. }
  344. },
  345. axisTick: {
  346. lineStyle: {
  347. color: 'rgba(0, 0, 0, .1)'
  348. }
  349. },
  350. axisLabel: {
  351. color: '#555'
  352. }
  353. },
  354. yAxis: {
  355. type: 'value',
  356. boundaryGap: false,
  357. axisLine: {
  358. show: false
  359. },
  360. axisTick: {
  361. show: false
  362. },
  363. splitLine: {
  364. lineStyle: {
  365. color: 'rgba(0, 0, 0, .05)'
  366. }
  367. }
  368. },
  369. series: [
  370. {
  371. name: '未开始',
  372. type: 'line',
  373. smooth: true,
  374. data: this.xmTaskFiveDaysCpd[1],
  375. areaStyle: {},
  376. label: {
  377. show: true,
  378. position: 'right',
  379. color: '#888',
  380. formatter: ({
  381. data
  382. }) => data == 0 ? '' : `${data}`
  383. },
  384. markPoint: {
  385. data: [
  386. {
  387. type: 'min',
  388. name: 'min'
  389. },
  390. {
  391. type: 'max',
  392. name: 'max'
  393. }
  394. ],
  395. },
  396. areaStyle: {
  397. normal: {
  398. color: {
  399. type: "linear",
  400. x: 0,
  401. y: 0,
  402. x2: 0,
  403. y2: 1,
  404. colorStops: [
  405. {
  406. offset: 0,
  407. color: "rgba(118,174,247,.4)"
  408. },
  409. {
  410. offset: 1,
  411. color: "rgba(118,174,247,0)"
  412. }
  413. ]
  414. }
  415. }
  416. },
  417. },
  418. {
  419. name: '进行中',
  420. type: 'line',
  421. smooth: true,
  422. data: this.xmTaskFiveDaysCpd[2],
  423. areaStyle: {
  424. opacity: 0.8,
  425. color: 'rgb(55, 162, 255)'
  426. },
  427. label: {
  428. show: true,
  429. position: 'right',
  430. color: '#888',
  431. formatter: ({
  432. data
  433. }) => data == 0 ? '' : `${data}`
  434. },
  435. markPoint: {
  436. data: [
  437. {
  438. type: 'min',
  439. name: 'min'
  440. },
  441. {
  442. type: 'max',
  443. name: 'max'
  444. }
  445. ],
  446. },
  447. areaStyle: {
  448. normal: {
  449. color: {
  450. type: "linear",
  451. x: 0,
  452. y: 0,
  453. x2: 0,
  454. y2: 1,
  455. colorStops: [
  456. {
  457. offset: 0,
  458. color: "rgba(35,184,210,.2)"
  459. },
  460. {
  461. offset: 1,
  462. color: "rgba(35,184,210,0)"
  463. }
  464. ]
  465. }
  466. }
  467. },
  468. },
  469. ],
  470. };
  471. // 绘制图表
  472. taskChart.setOption(option);
  473. },
  474. formatNum(num,defVal){
  475. if(num){
  476. return parseInt(num)
  477. }else{
  478. return defVal
  479. }
  480. },
  481. drawPieBug() {
  482. let bugPieChart = this.$echarts.init(document.getElementById("bugPieChart"));
  483. let option = {
  484. tooltip: {
  485. trigger: 'item',
  486. formatter: '{b} : {c} ({d}%)'
  487. },
  488. legend: {
  489. orient: 'horizontal',
  490. bottom: '80',
  491. data: ['已关闭', '已解决', '已激活', '已确认'],
  492. itemGap: 30,
  493. },
  494. series: [
  495. {
  496. center:['48%','40%'],//饼图位置
  497. type: 'pie',
  498. radius: '50%',//饼图半径大小
  499. label:{ //饼图图形上的文本标签
  500. normal:{
  501. show:true,
  502. position:'outer', //标签的位置:内部
  503. textStyle : {
  504. fontWeight : 100 ,
  505. fontSize: document.body.clientWidth / 120, //标签字体大小
  506. color: "#000000"
  507. },
  508. formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比
  509. alignTo:'edge',
  510. margin:10
  511. }
  512. },
  513. data: [
  514. {value: this.xmBranchState.closedBugs,
  515. itemStyle: {
  516. normal:{
  517. color: '#47CBF6'
  518. }
  519. },
  520. name: '已关闭',
  521. label: {
  522. normal: {
  523. color: '#47CBF6'
  524. }
  525. },
  526. labelLine: {
  527. normal: {
  528. position: "inner",
  529. show: false
  530. }
  531. }
  532. },
  533. {value: this.xmBranchState.resolvedBugs,
  534. itemStyle: {
  535. normal:{
  536. color: '#88B0BA'
  537. }
  538. },
  539. name: '已解决',
  540. label: {
  541. normal: {
  542. color: '#88B0BA'
  543. }
  544. },
  545. labelLine: {
  546. normal: {
  547. position: "inner",
  548. show: false
  549. }
  550. }
  551. },
  552. {value: this.xmBranchState.activeBugs,
  553. itemStyle: {
  554. normal:{
  555. color: '#F6AD48'
  556. }
  557. },
  558. name: '已激活',
  559. label: {
  560. normal: {
  561. color: '#F6AD48'
  562. }
  563. },
  564. labelLine: {
  565. normal: {
  566. position: "inner",
  567. show: false
  568. }
  569. }
  570. },
  571. {value: this.xmBranchState.confirmedBugs,
  572. itemStyle: {
  573. normal:{
  574. color: '#467AF6'
  575. }
  576. },
  577. name: '已确认',
  578. label: {
  579. normal: {
  580. color: '#467AF6'
  581. }
  582. },
  583. labelLine: {
  584. normal: {
  585. position: "inner",
  586. show: false
  587. }
  588. }
  589. },
  590. ],
  591. emphasis: {
  592. itemStyle: {
  593. shadowBlur: 10,
  594. shadowOffsetX: 0,
  595. shadowColor: 'rgba(0, 0, 0, 0.5)'
  596. }
  597. }
  598. }
  599. ]
  600. };
  601. // 绘制图表
  602. bugPieChart.setOption(option);
  603. },
  604. drawCostPie() {
  605. let planTotalCostPie = this.$echarts.init(document.getElementById("planTotalCostPie"));
  606. let option = {
  607. tooltip: {
  608. trigger: 'item',
  609. formatter: '{b} : {c} ({d}%)'
  610. },
  611. legend: {
  612. orient: 'horizontal',
  613. bottom: '80',
  614. data: ['非人力', '内部人力', '外购人力'],
  615. itemGap: 30,
  616. },
  617. series: [
  618. {
  619. center:['48%','40%'],//饼图位置
  620. type: 'pie',
  621. radius: '50%',//饼图半径大小
  622. label:{ //饼图图形上的文本标签
  623. normal:{
  624. show:true,
  625. position:'outer', //标签的位置:外部
  626. textStyle : {
  627. fontWeight : 100 ,
  628. fontSize: document.body.clientWidth / 120, //标签字体大小
  629. color: "#000000"
  630. },
  631. formatter:'{b}\n{c}({d}%)',//b:name,c:value,d:占比
  632. alignTo:'edge',
  633. margin:10
  634. }
  635. },
  636. data: [
  637. {
  638. value: this.xmBranchState.budgetNouserAt,
  639. itemStyle: {
  640. normal:{
  641. color: '#46CBF6'
  642. }
  643. },
  644. name: '非人力',
  645. label: {
  646. normal: {
  647. color: '#46CBF6'
  648. },
  649. },
  650. labelLine: {
  651. normal: {
  652. position: "inner",
  653. show: false
  654. }
  655. }
  656. },
  657. {value: this.xmBranchState.budgetIuserAt,
  658. itemStyle: {
  659. normal:{
  660. color: '#F7AE48'
  661. }
  662. },
  663. name: '内部人力',
  664. label: {
  665. normal: {
  666. color: '#F7AE48'
  667. },
  668. },
  669. labelLine: {
  670. normal: {
  671. position: "inner",
  672. show: false
  673. }
  674. }
  675. },
  676. {value: this.xmBranchState.budgetOuserAt,
  677. itemStyle: {
  678. normal:{
  679. color: '#4679F6'
  680. }
  681. },
  682. name: '外购人力',
  683. label: {
  684. normal: {
  685. color: '#4679F6'
  686. }
  687. },
  688. labelLine: {
  689. normal: {
  690. position: "inner",
  691. show: false
  692. }
  693. }
  694. },
  695. ],
  696. emphasis: {
  697. itemStyle: {
  698. shadowBlur: 10,
  699. shadowOffsetX: 0,
  700. shadowColor: 'rgba(0, 0, 0, 0.5)'
  701. }
  702. }
  703. }
  704. ]
  705. };
  706. // 绘制图表
  707. planTotalCostPie.setOption(option);
  708. },
  709. drawWorkload() {
  710. let workloadDistribution = this.$echarts.init(document.getElementById("workloadDistribution"));
  711. let that = this;
  712. let option = {
  713. tooltip: {
  714. trigger: 'item',
  715. formatter: '{b} :<br/> {c} ({d}%)'
  716. },
  717. legend: {
  718. orient: 'vertical',
  719. top: '20',
  720. right: '60',
  721. data: ['内部人力', '外购人力'],
  722. itemGap: 30,
  723. textStyle: {
  724. rich: {
  725. name: {
  726. color: '#7D7D7D',
  727. fontWeight: 'bold',
  728. fontSize: 18
  729. },
  730. val: {
  731. fontSize: '14',
  732. color: '#7D7D7D'
  733. },
  734. desc: {
  735. lineHeight: 20,
  736. color: '#7D7D7D'
  737. }
  738. }
  739. },
  740. formatter(params) {
  741. console.log(params);
  742. let total = that.xmBranchState.budgetIuserWorkload + that.xmBranchState.budgetOuserWorkload;
  743. if(params == '内部人力') {
  744. let p = ((that.xmBranchState.budgetIuserWorkload / total) * 100).toFixed(2)
  745. return [
  746. `{name|${that.xmBranchState.budgetIuserWorkload}}/{val|${p}%}`,
  747. `{desc|${params}}`
  748. ].join('\n')
  749. }
  750. if(params == '外购人力') {
  751. let p = ((that.xmBranchState.budgetOuserWorkload / total) * 100).toFixed(2)
  752. return [
  753. `{name|${that.xmBranchState.budgetOuserWorkload}}/{val|${p}%}`,
  754. `{desc|${params}}`
  755. ].join('\n')
  756. }
  757. return params;
  758. },
  759. },
  760. series: [
  761. {
  762. center:['30%','40%'],//饼图位置
  763. type: 'pie',
  764. radius: ['40%', '70%'],//饼图半径大小
  765. label:{ //饼图图形上的文本标签
  766. show: false,
  767. position: 'center'
  768. },
  769. data: [
  770. {
  771. value: this.xmBranchState.budgetIuserWorkload,
  772. itemStyle: {
  773. normal:{
  774. color: '#3AC2ED'
  775. }
  776. },
  777. name: '内部人力',
  778. label: {
  779. normal: {
  780. position: "inner",
  781. show: false
  782. }
  783. },
  784. labelLine: {
  785. normal: {
  786. position: "inner",
  787. show: false
  788. }
  789. }
  790. },
  791. {value: this.xmBranchState.budgetOuserWorkload,
  792. itemStyle: {
  793. normal:{
  794. color: '#4072F5'
  795. }
  796. },
  797. name: '外购人力',
  798. label: {
  799. normal: {
  800. position: "inner",
  801. show: false
  802. }
  803. },
  804. labelLine: {
  805. normal: {
  806. position: "inner",
  807. show: false
  808. }
  809. }
  810. },
  811. ],
  812. }
  813. ]
  814. };
  815. // 绘制图表
  816. workloadDistribution.setOption(option);
  817. },
  818. drawIterationProduct() {
  819. let iterationAndProduct = this.$echarts.init(document.getElementById("iterationAndProduct"));
  820. let option = {
  821. tooltip: {
  822. trigger: 'axis',
  823. formatter: '{b} : {c}',
  824. axisPointer: { // 坐标轴指示器,坐标轴触发有效
  825. type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
  826. },
  827. },
  828. grid: {
  829. left: '1%',
  830. right: '3%',
  831. bottom: '5%',
  832. containLabel: true
  833. },
  834. xAxis: {
  835. type: 'value',
  836. boundaryGap: [0, 0.01],
  837. splitLine: {
  838. show: true,
  839. lineStyle: {
  840. color: 'rgba(0, 0, 0, .05)'
  841. }
  842. },
  843. axisLine: {
  844. lineStyle: {
  845. color: 'rgba(0, 0, 0, .1)'
  846. }
  847. },
  848. axisTick: {
  849. lineStyle: {
  850. color: 'rgba(0, 0, 0, .1)'
  851. }
  852. },
  853. axisLabel: {
  854. color: '#555'
  855. }
  856. },
  857. yAxis: {
  858. type: 'category',
  859. data: ['产品数', '迭代数'],
  860. splitLine: {
  861. show: true,
  862. lineStyle: {
  863. color: 'rgba(0, 0, 0, .05)'
  864. }
  865. },
  866. axisLine: {
  867. lineStyle: {
  868. color: 'rgba(0, 0, 0, .1)'
  869. }
  870. },
  871. axisTick: {
  872. lineStyle: {
  873. color: 'rgba(0, 0, 0, .1)'
  874. }
  875. },
  876. axisLabel: {
  877. color: '#555'
  878. }
  879. },
  880. series: [{
  881. label: {
  882. normal:{
  883. show: true,
  884. position: 'inside',
  885. color:'#fff',
  886. fontSize: '14'
  887. }
  888. },
  889. data: [this.xmBranchState.productCnt, this.xmBranchState.iterationCnt],
  890. type: 'bar',
  891. showBackground: true,
  892. itemStyle: {
  893. normal:{
  894. color: '#467AF6'
  895. }
  896. },
  897. backgroundStyle: {
  898. color: '#FFFFFF'
  899. }
  900. }]
  901. };
  902. // 绘制图表
  903. iterationAndProduct.setOption(option);
  904. },
  905. searchXmBranchState(callBack){
  906. listXmBranchState({branchId:this.userInfo.branchId}).then(res=>{
  907. var tips=res.data.tips;
  908. if(tips.isOk && res.data.data.length>0){
  909. this.xmBranchState=res.data.data[0]
  910. }
  911. if(callBack){
  912. this.$nextTick(()=>{
  913. callBack();
  914. })
  915. }
  916. });
  917. },
  918. searchXmBranchFiveDayTaskCnt(callBack){
  919. listXmBranchFiveDayTaskCnt({branchId:this.userInfo.branchId}).then(res=>{
  920. var tips=res.data.tips;
  921. if(tips.isOk && res.data.data.length>0){
  922. this.xmBranchFiveDayTaskCnts=res.data.data
  923. }
  924. if(callBack){
  925. this.$nextTick(()=>{
  926. callBack();
  927. })
  928. }
  929. });
  930. },
  931. //路由跳转
  932. gotolink(link) {
  933. this.$router.replace(link);
  934. },
  935. /**end 自定义函数请在上面加**/
  936. guiderStart(forceDisplayWhileClosed) { // 初始化引导页
  937. Guider.startByName('xmHomePage',forceDisplayWhileClosed);
  938. },
  939. getWeek(dateString) {
  940. var dateArray = dateString.split("-");
  941. var date = new Date(dateArray[0], parseInt(dateArray[1] - 1), dateArray[2]);
  942. return "周" + "日一二三四五六".charAt(date.getDay());
  943. }
  944. },
  945. mounted() {
  946. //this.searchXmBranchState( this.guiderStart );
  947. this.searchXmBranchState();
  948. this.searchXmBranchFiveDayTaskCnt();
  949. this.drawWorkload();
  950. this.drawTaskByDate();
  951. this.drawAllBar();
  952. this.drawCostPie();
  953. this.drawPieBug();
  954. this.drawIterationProduct();
  955. },
  956. };
  957. </script>
  958. <style scoped lang="scss">
  959. .page-container {
  960. width: 100%;
  961. height: 100%;
  962. background-color: #F4F5F8;
  963. .page-main {
  964. padding: 18px;
  965. overflow: hidden;
  966. h2 {
  967. margin-top: 16px;
  968. font-size: 24px;
  969. color: #7D7D7D;
  970. }
  971. h2:before {
  972. content: " ";
  973. border-left: 10px #AEB8CE solid;
  974. margin-right: 12px;
  975. }
  976. .row_1 {
  977. background-color: #fff;
  978. display: flex;
  979. flex-direction: row;
  980. height: 120px;
  981. margin-top: 10px;
  982. .r {
  983. flex: 1;
  984. display: flex;
  985. flex-direction: column;
  986. justify-content: center;
  987. align-items: center;
  988. span {
  989. margin-bottom: 14px;
  990. font-size: 24px;
  991. font-weight: bold;
  992. }
  993. p {
  994. font-size: 18px;
  995. color: #7D7D7D;
  996. font-weight: bold;
  997. opacity: 0.55;
  998. }
  999. }
  1000. }
  1001. .row_2 {
  1002. height: 354px;
  1003. margin-top: 22px;
  1004. display: flex;
  1005. flex-direction: row;
  1006. .r1 {
  1007. flex: 2;
  1008. background-color: #fff;
  1009. margin-right: 20px;
  1010. .message {
  1011. display: flex;
  1012. margin: 0 43px;
  1013. div {
  1014. flex: 1;
  1015. display: flex;
  1016. flex-direction: column;
  1017. align-items: center;
  1018. justify-content: center;
  1019. span {
  1020. margin-bottom: 8px;
  1021. font-weight: bold;
  1022. color: #7D7D7D;
  1023. }
  1024. p {
  1025. color: #7D7D7D;
  1026. opacity: 0.55;
  1027. }
  1028. }
  1029. }
  1030. .chart {
  1031. display: flex;
  1032. flex-direction: row;
  1033. margin: 0 47px 0 47px;
  1034. height: 120px;
  1035. .desc {
  1036. display: flex;
  1037. flex-direction: column;
  1038. margin-right: 20px;
  1039. font-size: 18px;
  1040. color: #7D7D7D;
  1041. justify-content: center;
  1042. span:nth-child(1) {
  1043. margin-bottom: 20px;
  1044. }
  1045. }
  1046. .process {
  1047. display: flex;
  1048. flex-direction: column;
  1049. flex: 1;
  1050. justify-content: center;
  1051. .pc:nth-child(1) {
  1052. margin-bottom: 20px;
  1053. }
  1054. }
  1055. .tj {
  1056. display: flex;
  1057. flex: 1;
  1058. justify-content: center;
  1059. align-items: center;
  1060. }
  1061. .chart {
  1062. flex: 1;
  1063. }
  1064. }
  1065. }
  1066. .r2 {
  1067. width: 540px;
  1068. background-color: #fff;
  1069. .r2 {
  1070. width: 100%;
  1071. height: 100%;
  1072. display: flex;
  1073. align-items: center;
  1074. justify-content: center;
  1075. }
  1076. }
  1077. }
  1078. .row_3 {
  1079. height: 450px;
  1080. display: flex;
  1081. flex-direction: row;
  1082. margin-top: 24px;
  1083. .r1 {
  1084. display: flex;
  1085. flex: 1;
  1086. background-color: #fff;
  1087. flex-direction: column;
  1088. margin-right: 20px;
  1089. }
  1090. .r2 {
  1091. flex: 1;
  1092. background-color: #fff;
  1093. display: flex;
  1094. flex-direction: column;
  1095. }
  1096. }
  1097. .row_4 {
  1098. height: 445px;
  1099. display: flex;
  1100. margin-top: 21px;
  1101. .r4_1 {
  1102. flex: 1;
  1103. background-color: #fff;
  1104. margin-right: 25px;
  1105. display: flex;
  1106. flex-direction: column;
  1107. }
  1108. .r4_2 {
  1109. flex: 1;
  1110. background-color: #fff;
  1111. margin-right: 25px;
  1112. display: flex;
  1113. flex-direction: column;
  1114. }
  1115. .r4_3 {
  1116. display: flex;
  1117. flex-direction: column;
  1118. background-color: #fff;
  1119. flex: 1;
  1120. }
  1121. }
  1122. .r_text {
  1123. font-size: 20px;
  1124. color: #7D7D7D;
  1125. margin: 26px 0 50px 28px;
  1126. }
  1127. }
  1128. }
  1129. </style>