index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. <template>
  2. <div>
  3. <el-container>
  4. <el-main>
  5. <el-row>
  6. <el-col span="12" offset="6" style="border: #b11116 solid 1px;padding: 15px">
  7. <el-row>
  8. <el-col span="24" style="text-align: center">
  9. <h3>中国招投标公共服务平台爬虫</h3>
  10. <h5>https://ctbpsp.com/</h5>
  11. </el-col>
  12. <el-col span="8" style="text-align: center">
  13. 爬取总数: <span v-html="allCount"></span>
  14. <div id="allCount"></div>
  15. </el-col>
  16. <el-col span="8" style="text-align: center">
  17. 招标公告:<span v-html="jgCount"></span>
  18. <div id="JGCount"></div>
  19. </el-col>
  20. <el-col span="8" style="text-align: center">
  21. 中标结果公示:<span v-html="zbCount"></span>
  22. <div id="ZBCount"></div>
  23. </el-col>
  24. <el-col span="24" style="text-align: center">
  25. <h6>全国中标价格数据热力图</h6>
  26. <div id="chinaByPrice"></div>
  27. </el-col>
  28. <el-col span="24">
  29. <h6>每月份招标公告和中标结果公示分析{{this.titleNameAddr}}</h6>
  30. <div id="ZBandJGByMon"></div>
  31. </el-col>
  32. <el-col span="24">
  33. <h6>招标公告中招标人分析{{this.titleNameAddr}}</h6>
  34. <div id="depByMon"></div>
  35. </el-col>
  36. <el-col span="24">
  37. <h6>中标结果公示每月金额分析{{this.titleNameAddr}}</h6>
  38. <div id="priceByMon"></div>
  39. </el-col>
  40. <el-col span="24">
  41. <div id="echarts">
  42. <div id="myChart"></div>
  43. <div id="myChart2"></div>
  44. </div>
  45. </el-col>
  46. </el-row>
  47. </el-col>
  48. </el-row>
  49. </el-main>
  50. </el-container>
  51. </div>
  52. </template>
  53. <script type="text/javascript">
  54. import axios from 'axios';
  55. import chinaJson from '../../static/json/china_full.json'
  56. import {getAllCount,selectAllSumPriceByMon,getCleanCake,getTypeByMon,getCountByDepType,getSumPriceByAddr} from "../../static/js/api/echarts"
  57. export default {
  58. name: 'Echarts',
  59. head(){
  60. return{
  61. title:"中国招投标公共服务平台爬虫分析"
  62. }
  63. },
  64. data () {
  65. return {
  66. onMapClick:false,
  67. onMapName:'',
  68. chinaMapData:'',
  69. titleNameAddr:'',
  70. key:'',
  71. allCount:0,
  72. zbCount:0,
  73. jgCount:0
  74. }
  75. },
  76. methods: {
  77. echartsInit () {
  78. // 找到容器
  79. let myChart = this.$echarts.init(document.getElementById('myChart'))
  80. // 开始渲染
  81. myChart.setOption({
  82. title: {text: '在Vue中使用echarts'},
  83. tooltip: {},
  84. xAxis: {
  85. data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
  86. },
  87. yAxis: {},
  88. series: [{
  89. name: '销量',
  90. type: 'bar',
  91. data: [5, 20, 36, 10, 10, 20]
  92. }]
  93. })
  94. },
  95. echartsInit0(){
  96. let mCharts = this.$echarts.init(document.getElementById('chinaByPrice'));
  97. let airData = [
  98. {name:'北京市',value:39.93},
  99. {name:'天津市',value:39.13},
  100. ]
  101. let thiss=this
  102. getSumPriceByAddr().then(res=>{
  103. this.$echarts.registerMap('chinaMap',chinaJson)
  104. thiss.chinaMapData=res
  105. let option = {
  106. tooltip: {
  107. trigger: 'item'
  108. },
  109. geo: {
  110. type: 'map',
  111. map: 'chinaMap', //chinaMap需要和registerMap中的第一个参数保持一致
  112. roam: true, // 设置允许缩放以及拖动的效果
  113. label: {
  114. show: true //展示标签
  115. },
  116. zoom: 3, //设置初始化的缩放比例
  117. center: [104.114129, 37.550339],
  118. },
  119. series: [
  120. {
  121. name:"中标总金额(元)",
  122. data: res.data,
  123. geoIndex: 0, //将空气质量的数据和第0个geo配置关联在一起
  124. type:'map',
  125. label: {
  126. formatter: '{b}',
  127. position: 'right',
  128. show: true
  129. },
  130. }
  131. ],
  132. visualMap:{
  133. min:0,
  134. max:4000000000000,
  135. inRange:{
  136. color:['white', 'red'], //控制颜色渐变的范围
  137. },
  138. calculable: true //出现滑块
  139. }
  140. }
  141. let that=this
  142. mCharts.on('click', function (params) {
  143. if (typeof(params.data)!="undefined"&&that.onMapName!=params.data.name){
  144. // alert("1")
  145. that.onMapClick=true;
  146. that.onMapName=params.data.name
  147. }else if(typeof(params.data)!="undefined"&&that.onMapName==params.data.name) {
  148. // alert("12")
  149. that.onMapClick=false;
  150. that.onMapName=''
  151. }else if(typeof(params.data)=="undefined"){
  152. // alert("123")
  153. that.onMapClick=false;
  154. that.onMapName='1'
  155. }
  156. // alert( that.onMapName)
  157. if ( that.onMapClick){
  158. that.key=params.data.name+' 工程';
  159. that.titleNameAddr="("+params.data.name+")"
  160. that.echartsInit5()
  161. that.echartsInit6()
  162. that.echartsInit4()
  163. }else {
  164. that.key='';
  165. that.titleNameAddr=''
  166. that.echartsInit5()
  167. that.echartsInit6()
  168. that.echartsInit4()
  169. }
  170. });
  171. mCharts.setOption(option)
  172. })
  173. let that=this;
  174. console.log(airData)
  175. },
  176. echartsInit1 () {
  177. let that=this
  178. getAllCount().then(res=>{
  179. that.allCount=res.data.clean;
  180. let myChart = this.$echarts.init(document.getElementById('allCount'))
  181. myChart.setOption({
  182. // title: {text: 'echarts 饼图'},
  183. tooltip: {
  184. trigger: 'item'
  185. },
  186. legend: {
  187. orient: 'vertical',
  188. left: 'left'
  189. },
  190. label:{
  191. show:true,
  192. position:'inner',
  193. formatter:'{d}%'
  194. },
  195. series: [
  196. {
  197. name: '访问来源',
  198. type: 'pie',
  199. radius: '55%',
  200. data: [
  201. {value: (res.data.clean-res.data.noClean-res.data.dirty), name: '已清洗'},
  202. {value: res.data.noClean, name: '未清洗'},
  203. {value: res.data.dirty, name: '模糊数据'},
  204. ]
  205. }
  206. ]
  207. })
  208. })
  209. },
  210. echartsInit2 () {
  211. let that=this
  212. getCleanCake().then(res=>{
  213. that.zbCount=res.data[0].count;
  214. that.jgCount=res.data[1].count;
  215. let myChart1 = this.$echarts.init(document.getElementById('ZBCount'))
  216. myChart1.setOption({
  217. // title: {text: 'echarts 饼图'},
  218. tooltip: {
  219. trigger: 'item'
  220. },
  221. legend: {
  222. orient: 'vertical',
  223. left: 'left'
  224. },
  225. label:{
  226. show:true,
  227. position:'inner',
  228. formatter:'{d}%'
  229. },
  230. series: [
  231. {
  232. name: '访问来源',
  233. type: 'pie',
  234. radius: '55%',
  235. data: [
  236. {value: (res.data[0].count-res.data[2].count-res.data[4].count), name: '已清洗'},
  237. {value: res.data[2].count, name: '未清洗'},
  238. {value: res.data[4].count, name: '模糊数据'},
  239. ]
  240. }
  241. ]
  242. })
  243. let myChart2 = this.$echarts.init(document.getElementById('JGCount'))
  244. myChart2.setOption({
  245. // title: {text: 'echarts 饼图'},
  246. tooltip: {
  247. trigger: 'item'
  248. },
  249. legend: {
  250. orient: 'vertical',
  251. left: 'left'
  252. },
  253. label:{
  254. show:true,
  255. position:'inner',
  256. formatter:'{d}%'
  257. },
  258. series: [
  259. {
  260. name: '访问来源',
  261. type: 'pie',
  262. radius: '55%',
  263. data: [
  264. {value: (res.data[1].count-res.data[3].count-res.data[5].count), name: '已清洗'},
  265. {value: res.data[3].count, name: '未清洗'},
  266. {value: res.data[5].count, name: '模糊数据'},
  267. ]
  268. }
  269. ]
  270. })
  271. })
  272. },
  273. echartsInit3 () {
  274. },
  275. echartsInit4 () {
  276. getTypeByMon(this.key).then(res=>{
  277. var data1=['招标公告'];
  278. var data2=['中标结果公示'];
  279. var data3=['日期'];
  280. for(let i=0;i<res.data.gg.length;i++){
  281. data3.push(res.data.gg[i].mon)
  282. }
  283. for(let i=0;i<res.data.gg.length;i++){
  284. data1.push(res.data.gg[i].count)
  285. }
  286. for(let i=0;i<res.data.jg.length;i++){
  287. data2.push(res.data.jg[i].count)
  288. }
  289. var chartDom = document.getElementById('ZBandJGByMon');
  290. var myChart = this.$echarts.init(chartDom);
  291. var option;
  292. setTimeout(function () {
  293. option = {
  294. legend: {},
  295. tooltip: {
  296. trigger: 'axis',
  297. showContent: false
  298. },
  299. dataset: {
  300. source: [
  301. data3,data1,data2,
  302. ]
  303. },
  304. xAxis: { type: 'category' },
  305. yAxis: { gridIndex: 0 },
  306. grid: { top: '55%' },
  307. series: [
  308. {
  309. type: 'line',
  310. smooth: true,
  311. seriesLayoutBy: 'row',
  312. emphasis: { focus: 'series' }
  313. },
  314. {
  315. type: 'line',
  316. smooth: true,
  317. seriesLayoutBy: 'row',
  318. emphasis: { focus: 'series' }
  319. },
  320. {
  321. type: 'line',
  322. smooth: true,
  323. seriesLayoutBy: 'row',
  324. emphasis: { focus: 'series' }
  325. },
  326. {
  327. type: 'line',
  328. smooth: true,
  329. seriesLayoutBy: 'row',
  330. emphasis: { focus: 'series' }
  331. },
  332. {
  333. type: 'pie',
  334. id: 'pie',
  335. radius: '30%',
  336. center: ['50%', '25%'],
  337. emphasis: {
  338. focus: 'self'
  339. },
  340. label: {
  341. formatter: '{b}: {@2012} ({d}%)'
  342. },
  343. encode: {
  344. itemName: 'product',
  345. value: '2012',
  346. tooltip: '2012'
  347. }
  348. }
  349. ]
  350. };
  351. myChart.on('updateAxisPointer', function (event) {
  352. const xAxisInfo = event.axesInfo[0];
  353. if (xAxisInfo) {
  354. const dimension = xAxisInfo.value + 1;
  355. myChart.setOption({
  356. series: {
  357. id: 'pie',
  358. label: {
  359. formatter: '{b}: {@[' + dimension + ']} ({d}%)'
  360. },
  361. encode: {
  362. value: dimension,
  363. tooltip: dimension
  364. }
  365. }
  366. });
  367. }
  368. });
  369. myChart.setOption(option);
  370. });
  371. option && myChart.setOption(option);
  372. })
  373. },
  374. echartsInit5 () {
  375. getCountByDepType(this.key).then(res=>{
  376. var data1=[];
  377. var data2=[];
  378. var data3=[];
  379. for(let i=0;i<res.data.dw.length;i++){
  380. data3.push(res.data.dw[i].mon)
  381. }
  382. for(let i=0;i<res.data.dw.length;i++){
  383. data1.push(res.data.dw[i].count)
  384. }
  385. for(let i=0;i<res.data.gs.length;i++){
  386. data2.push(res.data.gs[i].count)
  387. }
  388. var chartDom = document.getElementById('depByMon');
  389. var myChart = this.$echarts.init(chartDom);
  390. var option;
  391. option = {
  392. title: {
  393. // text: '招标公告中招标人成分分析'
  394. },
  395. tooltip: {
  396. trigger: 'axis',
  397. axisPointer: {
  398. type: 'cross',
  399. label: {
  400. backgroundColor: '#6a7985'
  401. }
  402. }
  403. },
  404. legend: {
  405. data: ['公司', '单位']
  406. },
  407. toolbox: {
  408. feature: {
  409. saveAsImage: {}
  410. }
  411. },
  412. grid: {
  413. left: '3%',
  414. right: '4%',
  415. bottom: '3%',
  416. containLabel: true
  417. },
  418. xAxis: [
  419. {
  420. type: 'category',
  421. boundaryGap: false,
  422. data: data3
  423. }
  424. ],
  425. yAxis: [
  426. {
  427. type: 'value'
  428. }
  429. ],
  430. series: [
  431. {
  432. name: '公司',
  433. type: 'line',
  434. stack: 'Total',
  435. areaStyle: {},
  436. emphasis: {
  437. focus: 'series'
  438. },
  439. data: data2
  440. },
  441. {
  442. name: '单位',
  443. type: 'line',
  444. stack: 'Total',
  445. areaStyle: {},
  446. emphasis: {
  447. focus: 'series'
  448. },
  449. data: data1
  450. },
  451. ]
  452. };
  453. option && myChart.setOption(option);
  454. })
  455. },
  456. echartsInit6 () {
  457. selectAllSumPriceByMon(this.key).then(res=>{
  458. var data1=[];
  459. var data2=[];
  460. for(let i=0;i<res.data.length;i++){
  461. data1.push(res.data[i].mon)
  462. }
  463. for(let i=0;i<res.data.length;i++){
  464. data2.push(res.data[i].price)
  465. }
  466. var chartDom = document.getElementById('priceByMon');
  467. var myChart = this.$echarts.init(chartDom);
  468. var option;
  469. option = {
  470. tooltip: {
  471. trigger: 'item'
  472. },
  473. legend: {
  474. orient: 'vertical',
  475. left: 'top'
  476. },
  477. xAxis: {
  478. type: 'category',
  479. data: data1
  480. },
  481. yAxis: {
  482. type: 'value'
  483. },
  484. series: [
  485. {
  486. data: data2,
  487. type: 'bar'
  488. }
  489. ],
  490. dataZoom: [
  491. {
  492. show: true,
  493. start: 74,
  494. end: 100
  495. },
  496. {
  497. type: 'inside',
  498. start: 94,
  499. end: 100
  500. },
  501. {
  502. show: true,
  503. yAxisIndex: 0,
  504. filterMode: 'empty',
  505. width: 30,
  506. height: '80%',
  507. showDataShadow: false,
  508. left: '93%'
  509. }
  510. ],
  511. };
  512. option && myChart.setOption(option);
  513. })
  514. },
  515. },
  516. mounted () {
  517. this.echartsInit0();
  518. this.echartsInit()
  519. this.echartsInit1()
  520. this.echartsInit2()
  521. this.echartsInit3()
  522. this.echartsInit4()
  523. this.echartsInit5()
  524. this.echartsInit6()
  525. }
  526. }
  527. </script>
  528. <style scoped >
  529. h6{
  530. text-align: center;
  531. }
  532. #chinaByPrice{
  533. width: 100%;
  534. height: 600px;
  535. margin-left: auto;
  536. margin-right: auto;
  537. float: left;
  538. }
  539. #ZBCount{
  540. width: 100%;
  541. height: 300px;
  542. margin-left: auto;
  543. margin-right: auto;
  544. float: left;
  545. }
  546. #JGCount{
  547. width: 100%;
  548. height: 300px;
  549. margin-left: auto;
  550. margin-right: auto;
  551. float: right;
  552. }
  553. #allCount{
  554. width: 100%;
  555. height: 300px;
  556. margin-left: auto;
  557. margin-right: auto;
  558. float: right;
  559. }
  560. #ZBandJGByMon{
  561. width: 100%;
  562. height: 700px;
  563. margin-left: auto;
  564. margin-right: auto;
  565. float: right;
  566. }
  567. #depByMon{
  568. width: 100%;
  569. height: 700px;
  570. margin-left: auto;
  571. margin-right: auto;
  572. float: right;
  573. }
  574. #priceByMon{
  575. width: 100%;
  576. height: 500px;
  577. margin-left: auto;
  578. margin-right: auto;
  579. float: right;
  580. }
  581. h6{
  582. font-size: 18px;
  583. margin-top: 25px;
  584. text-align: center;
  585. }
  586. </style>