Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/chongzhou-screen
13个文件已修改
17个文件已删除
3个文件已添加
| | |
| | | .DS_Store |
| | | node_modules |
| | | /dist |
| | | package-lock.json |
| | | |
| | | |
| | | # local env files |
| | |
| | | # chongzhou-screen |
| | | # 崇州市自主安置购房信息化大数据平台 |
| | | |
| | | ## Project setup |
| | | ``` |
| | |
| | | "webpack-merge": "^5.7.3", |
| | | "webpack-virtual-modules": "^0.4.2", |
| | | "whatwg-fetch": "^3.6.2" |
| | | }, |
| | | "dependencies": { |
| | | "@vue/vue-loader-v15": { |
| | | "version": "npm:vue-loader@15.11.1", |
| | | "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz", |
| | | "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==", |
| | | "dev": true, |
| | | "requires": { |
| | | "@vue/component-compiler-utils": "^3.1.0", |
| | | "hash-sum": "^1.0.2", |
| | | "loader-utils": "^1.1.0", |
| | | "vue-hot-reload-api": "^2.3.0", |
| | | "vue-style-loader": "^4.1.0" |
| | | }, |
| | | "dependencies": { |
| | | "hash-sum": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz", |
| | | "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", |
| | | "dev": true |
| | | } |
| | | } |
| | | }, |
| | | "json5": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", |
| | | "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", |
| | | "dev": true, |
| | | "requires": { |
| | | "minimist": "^1.2.0" |
| | | } |
| | | }, |
| | | "loader-utils": { |
| | | "version": "1.4.2", |
| | | "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", |
| | | "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", |
| | | "dev": true, |
| | | "requires": { |
| | | "big.js": "^5.2.2", |
| | | "emojis-list": "^3.0.0", |
| | | "json5": "^1.0.1" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "@vue/cli-shared-utils": { |
| | |
| | | }, |
| | | "@vue/vue-loader-v15": { |
| | | "version": "npm:vue-loader@15.11.1", |
| | | "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/vue-loader/-/vue-loader-15.11.1.tgz", |
| | | "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==", |
| | | "dev": true, |
| | | "requires": { |
| | |
| | | "dependencies": { |
| | | "hash-sum": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/hash-sum/-/hash-sum-1.0.2.tgz", |
| | | "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", |
| | | "dev": true |
| | | }, |
| | | "json5": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/json5/-/json5-1.0.2.tgz", |
| | | "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", |
| | | "dev": true, |
| | | "requires": { |
| | |
| | | }, |
| | | "loader-utils": { |
| | | "version": "1.4.2", |
| | | "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/loader-utils/-/loader-utils-1.4.2.tgz", |
| | | "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", |
| | | "dev": true, |
| | | "requires": { |
| | |
| | | "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", |
| | | "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", |
| | | "dev": true |
| | | }, |
| | | "claygl": { |
| | | "version": "1.3.0", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/claygl/-/claygl-1.3.0.tgz", |
| | | "integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==" |
| | | }, |
| | | "clean-css": { |
| | | "version": "5.3.3", |
| | |
| | | }, |
| | | "echarts": { |
| | | "version": "5.6.0", |
| | | "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/echarts/-/echarts-5.6.0.tgz", |
| | | "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", |
| | | "requires": { |
| | | "tslib": "2.3.0", |
| | |
| | | "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
| | | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" |
| | | } |
| | | } |
| | | }, |
| | | "echarts-gl": { |
| | | "version": "2.0.9", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/echarts-gl/-/echarts-gl-2.0.9.tgz", |
| | | "integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==", |
| | | "requires": { |
| | | "claygl": "^1.2.1", |
| | | "zrender": "^5.1.1" |
| | | } |
| | | }, |
| | | "ee-first": { |
| | |
| | | }, |
| | | "vue-hot-reload-api": { |
| | | "version": "2.3.4", |
| | | "resolved": "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", |
| | | "resolved": "https://mirrors.cloud.tencent.com/npm/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", |
| | | "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", |
| | | "dev": true |
| | | }, |
| | |
| | | "axios": "^1.8.4", |
| | | "core-js": "^3.8.3", |
| | | "echarts": "^5.6.0", |
| | | "echarts-gl": "^2.0.9", |
| | | "register-service-worker": "^1.7.2", |
| | | "vue": "^2.6.14", |
| | | "vue-echarts": "^7.0.3", |
| | |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width,initial-scale=1.0"> |
| | | <!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> --> |
| | | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
| | | <title><%= htmlWebpackPlugin.options.title %></title> |
| | | </head> |
| | | <body> |
| | |
| | | <img src="@/assets/center-top-right.png" alt=""> |
| | | <div> |
| | | <div class="label">本月应补偿总额(万元)</div> |
| | | <div class="value">{{ data.monthCompensationAmount }} <span>环比</span><span class="value-change value-change-down">{{ data.monthCompensationAmountRate }}</span></div> |
| | | <div class="value">{{ data.monthCompensationAmount }} <span>环比</span><span |
| | | class="value-change value-change-down">{{ data.monthCompensationAmountRate }}</span></div> |
| | | </div> |
| | | </div> |
| | | <div class="data-item"> |
| | | <img src="@/assets/center-top-right.png" alt=""> |
| | | <div> |
| | | <div class="label">下月应补偿总额(万元)</div> |
| | | <div class="value">{{ data.nextMonthCompensationAmount }} <span>环比</span><span class="value-change value-change-up">{{ data.nextMonthCompensationAmountRate }}</span></div> |
| | | <div class="value">{{ data.nextMonthCompensationAmount }} <span>环比</span><span |
| | | class="value-change value-change-up">{{ data.nextMonthCompensationAmountRate }}</span></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <!-- 中间下部数据 --> |
| | | <div class="center-bottom panel-item"> |
| | | |
| | | <div class="compensation-table"> |
| | | <div class="table-header"> |
| | | <div class="batch-number txt-center">安置批次</div> |
| | | <div class="household-count txt-center">户主名称</div> |
| | | <div class="people-count txt-center">安置人数</div> |
| | | <div class="progress-wrapper txt-center">补偿阶段</div> |
| | | </div> |
| | | <div class="table-content"> |
| | | <div class="table-row" v-for="(item, index) in data.quarterProcessResponses" :key="index"> |
| | | <div class="batch-number text-center">{{ item.batchNumber }}</div> |
| | | <div class="household-count text-center">{{ item.householdHead }}</div> |
| | | <div class="people-count text-center">{{ item.currentCount }}</div> |
| | | <div class="progress-wrapper"> |
| | | <div class="progress-bar"> |
| | | <div class="progress-fill"> |
| | | <div class="progress-color" |
| | | :class="item.process <= 5 ? 'progress-yellow' : item.process <= 10&&item.process>5 ? 'progress-green' : item.process <= 15&&item.process>10 ? 'progress-blue' : 'progress-gray'"> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="progress-text">{{ item.process }}/20</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | { label: '已受理', value: '2021103000001', percentage: 90 }, |
| | | { label: '已审核', value: '2021103000002', percentage: 70 }, |
| | | { label: '已完成', value: '2021103000003', percentage: 50 } |
| | | ], |
| | | compensationList: [ |
| | | |
| | | ] |
| | | }; |
| | | } |
| | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .pl-20 { |
| | | padding-left: 20px; |
| | | } |
| | | |
| | | .text-center { |
| | | text-align: center; |
| | | } |
| | | |
| | | .center-panel { |
| | | position: absolute; |
| | | left: 481px; |
| | |
| | | height: 245px; |
| | | background: url('@/assets/center-bottom-bg.png') no-repeat center center; |
| | | background-size: 100% 100%; |
| | | padding: 20px; |
| | | |
| | | .compensation-table { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .table-header { |
| | | display: flex; |
| | | align-items: center; |
| | | color: rgba(255, 255, 255, 0.6); |
| | | font-size: 12px; |
| | | // margin-top: 20px; |
| | | margin-bottom: 15px; |
| | | |
| | | >div { |
| | | margin-right: 40px; |
| | | } |
| | | |
| | | .batch-number { |
| | | width: 150px; |
| | | } |
| | | |
| | | .household-count { |
| | | width: 80px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .people-count { |
| | | width: 100px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .progress-wrapper { |
| | | flex: 1; |
| | | padding-right: 20px; |
| | | padding-left: 20px; |
| | | } |
| | | } |
| | | |
| | | .table-content { |
| | | // flex: 1; |
| | | height: 174px; |
| | | display: flex; |
| | | overflow-y: auto; |
| | | scrollbar-width: none; |
| | | /* Firefox */ |
| | | -ms-overflow-style: none; |
| | | |
| | | /* IE 和 Edge */ |
| | | &::-webkit-scrollbar { |
| | | display: none; |
| | | /* Chrome, Safari 和 Opera */ |
| | | } |
| | | |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | |
| | | .table-row { |
| | | display: flex; |
| | | align-items: center; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | padding: 8px 0; |
| | | margin-bottom: 5px; |
| | | box-sizing: border-box; |
| | | |
| | | >div { |
| | | margin-right: 40px; |
| | | } |
| | | |
| | | .batch-number { |
| | | width: 150px; |
| | | } |
| | | |
| | | .household-count { |
| | | width: 80px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .people-count { |
| | | width: 100px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .progress-wrapper { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .progress-bar { |
| | | flex: 1; |
| | | height: 10px; |
| | | background: rgba(255, 255, 255, 0.1); |
| | | border-radius: 5px; |
| | | margin-right: 15px; |
| | | overflow: hidden; |
| | | |
| | | .progress-fill { |
| | | height: 100%; |
| | | display: flex; |
| | | |
| | | .progress-yellow { |
| | | height: 100%; |
| | | background: #FEDB65; |
| | | } |
| | | |
| | | .progress-blue { |
| | | height: 100%; |
| | | background: #00C6FF; |
| | | } |
| | | |
| | | .progress-green { |
| | | height: 100%; |
| | | background: rgba(0, 220, 171, 1); |
| | | } |
| | | |
| | | .progress-gray { |
| | | height: 100%; |
| | | background: rgba(0, 242, 240, 1); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | .progress-text { |
| | | width: 50px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | |
| | | &:nth-child(2n + 1) { |
| | | background: url('@/assets/bg.png') no-repeat center center; |
| | | border: 2px solid; |
| | | border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(1, 10, 40, 0), rgba(255, 255, 255, 0.6)) 2 2; |
| | | } |
| | | |
| | | &:nth-child(2n) { |
| | | background: url('@/assets/unbg.png') no-repeat center center; |
| | | border: 2px solid; |
| | | border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(1, 10, 40, 0), rgba(255, 255, 255, 0.2)) 2 2; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .txt-center { |
| | | text-align: center; |
| | | font-size: 12px; |
| | | color: #19ECFF; |
| | | line-height: 18px; |
| | | } |
| | | |
| | | .map-data { |
| | |
| | | .data-item { |
| | | display: flex; |
| | | flex-shrink: 0; |
| | | |
| | | img { |
| | | width: 94px; |
| | | height: 80px; |
| | |
| | | <div class="header"> |
| | | <!-- 左侧天气 --> |
| | | <div class="weather"> |
| | | <!-- <img :src="require(`@/assets/weather/${weatherInfo.icon}.png`)" alt="weather" class="weather-icon"> --> |
| | | <span class="weather-text">{{ weatherInfo.text }}</span> |
| | | <div class="mask"></div> |
| | | <div class="box"></div> |
| | | <iframe allowtransparency="true" frameborder="0" width="180" height="36" scrolling="no" |
| | | src="//tianqi.2345.com/plugin/widget/index.htm?s=3&z=3&t=1&v=0&d=3&bd=0&k=000000&f=ffffff<f=ffffff&htf=ffffff&q=1&e=1&a=1&c=60910&w=103&h=36&align=left" /> |
| | | </div> |
| | | |
| | | <!-- 中间标题 --> |
| | |
| | | display: flex; |
| | | margin-top: 61px; |
| | | |
| | | .weather-icon { |
| | | width: 30px; |
| | | height: 30px; |
| | | margin-right: 10px; |
| | | |
| | | .mask { |
| | | position: absolute; |
| | | width: 180px; |
| | | height: 36px; |
| | | z-index: 1; |
| | | filter: alpha(opacity=0); |
| | | opacity: 0; |
| | | background: #040A56 |
| | | } |
| | | |
| | | .weather-text { |
| | | color: #fff; |
| | | font-size: 16px; |
| | | .box { |
| | | position: absolute; |
| | | width: 20px; |
| | | height: 36px; |
| | | left: 140px; |
| | | z-index: 1; |
| | | background: #040A56 |
| | | } |
| | | } |
| | | |
| | |
| | | <div class="right-panel"> |
| | | <!-- 右侧第一块 --> |
| | | <div class="panel-item top-panel-item"> |
| | | <div class="box-title">本月进度值比</div> |
| | | <div class="circle-progress"> |
| | | <!-- <v-chart class="chart" :option="circleOption" autoresize /> --> |
| | | <div class="box-title">安置房类型占比</div> |
| | | <div class="house-type-content"> |
| | | <div class="relative"> |
| | | <div class="cityGreenLand-charts" ref="cityGreenLandCharts"></div> |
| | | <div class="chartBg"></div> |
| | | <div class="chart-content"> |
| | | <div class="chart-num">{{ currentType.rate }}</div> |
| | | <div class="chart-title">{{ currentType.type }}</div> |
| | | </div> |
| | | <div class="chart-black"></div> |
| | | </div> |
| | | |
| | | <div class="right-content"> |
| | | <div class="table-header"> |
| | | <div class="header-item">数量</div> |
| | | <div class="header-item">面积</div> |
| | | <div class="header-item">占比</div> |
| | | </div> |
| | | <div class="data-list"> |
| | | <div |
| | | class="data-item" |
| | | :class="{ activeItem: item.type === currentType.type }" |
| | | v-for="(item, index) in houseTypeData" |
| | | :key="index" |
| | | @click="changeCurrentType(item)" |
| | | > |
| | | <div class="item-dot" :style="{ background: item.color }"></div> |
| | | <div class="item-name">{{ item.type }}</div> |
| | | <div class="item-value" :style="{ color: item.color }"> |
| | | {{ item.total }} |
| | | </div> |
| | | <div class="item-area" :style="{ color: item.color }"> |
| | | {{ item.area }} |
| | | </div> |
| | | <div class="item-percent" :style="{ color: item.color }"> |
| | | {{ item.rate }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 右侧第二块 --> |
| | | <div class="panel-item middle-panel-item"> |
| | | <div class="box-title">各季度进度值统计</div> |
| | | <div class="bar-chart"> |
| | | <!-- <v-chart class="chart" :option="barOption" autoresize /> --> |
| | | <div class="box-title">本月应补偿占比</div> |
| | | <div class="compensation-content"> |
| | | <div class="circle-chart"> |
| | | <div |
| | | ref="compensationCharts" |
| | | id="compensationCharts" |
| | | style="width: 100%; height: 100%" |
| | | ></div> |
| | | <div class="compensation-list"> |
| | | <div class="compensation-center"> |
| | | <div class="total-value">{{ (total * 1).toFixed(2) }}</div> |
| | | <div class="total-name">总额(万元)</div> |
| | | </div> |
| | | <div class="compensation-item"> |
| | | <div |
| | | class="compensation-item-name" |
| | | v-for="item in twoEcharts" |
| | | :key="item.name" |
| | | > |
| | | <div class="item-name">{{ item.amountRate }}</div> |
| | | <div class="item-value">{{ item.type }}</div> |
| | | <div class="item-dot" :style="{ background: item.color }"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 右侧第三块 --> |
| | | <div class="panel-item bottom-panel-item"> |
| | | <div class="box-title">安置房类型分布</div> |
| | | <div class="box-title">各季度应补偿金额</div> |
| | | <div class="pie-chart"> |
| | | <!-- <v-chart class="chart" :option="typeDistOption" autoresize /> --> |
| | | <v-chart class="chart" :option="barOption" autoresize /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from "echarts"; |
| | | import "echarts-gl"; |
| | | |
| | | export default { |
| | | name: 'RightPanel', |
| | | name: "RightPanel", |
| | | props: { |
| | | data: { |
| | | type: Object, |
| | | default: () => {}, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | circleOption: { |
| | | series: [{ |
| | | type: 'pie', |
| | | radius: ['75%', '80%'], |
| | | label: { |
| | | show: false |
| | | }, |
| | | data: [ |
| | | { |
| | | value: 78.8, |
| | | name: '完成率', |
| | | itemStyle: { |
| | | color: '#00ffff' |
| | | } |
| | | }, |
| | | { |
| | | value: 21.2, |
| | | name: '剩余', |
| | | itemStyle: { |
| | | color: 'rgba(0,255,255,0.2)' |
| | | } |
| | | } |
| | | ] |
| | | }] |
| | | }, |
| | | barOption: { |
| | | houseTypeData: [], |
| | | currentType: {}, |
| | | total: null, |
| | | barOption: {}, |
| | | twoEcharts: [], |
| | | typeDistOption: { |
| | | tooltip: { |
| | | trigger: 'axis' |
| | | trigger: "item", |
| | | }, |
| | | series: [ |
| | | { |
| | | type: "pie", |
| | | radius: ["65%", "80%"], |
| | | label: { |
| | | show: false, |
| | | }, |
| | | data: [ |
| | | { value: 40, name: "商品房" }, |
| | | { value: 30, name: "安置房" }, |
| | | { value: 30, name: "其他" }, |
| | | ], |
| | | itemStyle: { |
| | | color: function (params) { |
| | | const colorList = ["#00ffff", "#7cb9e8", "rgba(0,255,255,0.5)"]; |
| | | return colorList[params.dataIndex]; |
| | | }, |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.init(this.data.placementTypeResponses); |
| | | this.initCompensationOption(this.data.monthCompensationResponses); |
| | | this.initBarChart(); |
| | | }); |
| | | }, |
| | | methods: { |
| | | changeCurrentType(type) { |
| | | this.currentType = type; |
| | | }, |
| | | initBarChart() { |
| | | if (!this.data.quarterPayResponses || !this.data.quarterPayResponses[0]) |
| | | return; |
| | | |
| | | const sortedData = Object.entries(this.data.quarterPayResponses[0]).sort( |
| | | (a, b) => { |
| | | const dateA = new Date(a[0].replace("-", "/")); |
| | | const dateB = new Date(b[0].replace("-", "/")); |
| | | return dateA - dateB; |
| | | } |
| | | ); |
| | | |
| | | const maxValue = Math.max(...sortedData.map((item) => item[1])); |
| | | const yAxisMax = Math.ceil(maxValue / 100) * 100; |
| | | |
| | | this.barOption = { |
| | | tooltip: { |
| | | trigger: "axis", |
| | | formatter: function (params) { |
| | | const dataParams = params[1]; |
| | | // 获取当前柱子的颜色(取渐变色的起始色) |
| | | let color; |
| | | if (dataParams.dataIndex === 0) { |
| | | color = "#FFEF00"; |
| | | } else if (dataParams.dataIndex === 1) { |
| | | color = "#00FFC3"; |
| | | } else if (dataParams.dataIndex === 2) { |
| | | color = "#00DBFF"; |
| | | } else { |
| | | color = "#057BFF"; |
| | | } |
| | | return `${dataParams.name}<br/><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background-color:${color};margin-right:6px;"></span>${dataParams.value}`; |
| | | }, |
| | | backgroundColor: "#ffffff", |
| | | borderWidth: 1, |
| | | textStyle: { |
| | | color: "#333333", |
| | | fontSize: 14, |
| | | }, |
| | | padding: [8, 12], |
| | | }, |
| | | grid: { |
| | | top: "10%", |
| | | left: "3%", |
| | | right: "4%", |
| | | bottom: "3%", |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: ['2023年4月', '2023年5月', '2023年7月', '2023年10月'], |
| | | type: "category", |
| | | data: sortedData.map((item) => item[0]), |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#7cb9e8' |
| | | } |
| | | color: "rgba(30, 44, 88, 1)", |
| | | }, |
| | | }, |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | axisLabel: { |
| | | color: '#7cb9e8' |
| | | } |
| | | color: "#ffffff", |
| | | fontSize: 12, |
| | | }, |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#7cb9e8' |
| | | } |
| | | }, |
| | | type: "value", |
| | | max: yAxisMax, |
| | | splitNumber: 4, |
| | | axisLabel: { |
| | | color: '#7cb9e8' |
| | | color: "rgba(88, 115, 150, 1)", |
| | | fontSize: 12, |
| | | }, |
| | | splitLine: { |
| | | lineStyle: { |
| | | color: 'rgba(124,185,232,0.1)' |
| | | } |
| | | } |
| | | }, |
| | | series: [{ |
| | | data: [120, 200, 150, 80], |
| | | type: 'bar', |
| | | itemStyle: { |
| | | color: '#00ffff' |
| | | } |
| | | }] |
| | | }, |
| | | typeDistOption: { |
| | | tooltip: { |
| | | trigger: 'item' |
| | | }, |
| | | series: [{ |
| | | type: 'pie', |
| | | radius: ['65%', '80%'], |
| | | label: { |
| | | show: false |
| | | color: "rgba(30, 44, 88, 1)", |
| | | }, |
| | | }, |
| | | data: [ |
| | | { value: 40, name: '商品房' }, |
| | | { value: 30, name: '安置房' }, |
| | | { value: 30, name: '其他' } |
| | | ], |
| | | itemStyle: { |
| | | color: function(params) { |
| | | const colorList = ['#00ffff', '#7cb9e8', 'rgba(0,255,255,0.5)']; |
| | | return colorList[params.dataIndex]; |
| | | } |
| | | } |
| | | }] |
| | | }, |
| | | series: [ |
| | | { |
| | | type: "bar", |
| | | barWidth: "30%", |
| | | z: 1, |
| | | data: Array(sortedData.length).fill(yAxisMax), |
| | | itemStyle: { |
| | | color: "rgba(0, 255, 255, 0.1)", |
| | | }, |
| | | }, |
| | | { |
| | | type: "pictorialBar", |
| | | symbol: "roundRect", |
| | | symbolSize: [20, 6], |
| | | symbolRepeat: "fixed", |
| | | symbolMargin: 1, |
| | | symbolClip: true, |
| | | symbolPosition: "start", |
| | | symbolOffset: [0, 0], |
| | | symbolBoundingData: yAxisMax, |
| | | z: 2, |
| | | data: sortedData.map((item, index) => ({ |
| | | value: item[1], |
| | | itemStyle: { |
| | | color: |
| | | index === 0 |
| | | ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#FFEF00" }, |
| | | { offset: 0.5, color: "#C86A01" }, |
| | | { offset: 1, color: "#402303" }, |
| | | ]) |
| | | : index === 1 |
| | | ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#00FFC3" }, |
| | | { offset: 1, color: "#008570" }, |
| | | ]) |
| | | : index === 2 |
| | | ? new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#00DBFF" }, |
| | | { offset: 1, color: "#0093A8" }, |
| | | ]) |
| | | : new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#05DBFF" }, |
| | | { offset: 0.5, color: "#057BFF" }, |
| | | { offset: 1, color: "#030E3F" }, |
| | | ]), |
| | | }, |
| | | })), |
| | | }, |
| | | ], |
| | | }; |
| | | }, |
| | | init(data) { |
| | | if (!data || data.length == 0) { |
| | | this.houseTypeData = []; |
| | | this.currentType = {}; |
| | | return; |
| | | } |
| | | }; |
| | | } |
| | | const chartDom = this.$refs.cityGreenLandCharts; |
| | | if (!chartDom) return; |
| | | |
| | | const myChart = echarts.init(chartDom); |
| | | |
| | | let colors = ["#286DF7ee", "#04F7FDee", "#E23AA9ee", "#FFC852ee"]; |
| | | this.houseTypeData = data.map((item, index) => { |
| | | return { |
| | | ...item, |
| | | color: colors[index], |
| | | }; |
| | | }); |
| | | this.currentType = this.houseTypeData[0]; |
| | | let xData = data.map((item) => item.type); |
| | | let yData = data.map((item) => item.total); |
| | | // 传入数据生成 option |
| | | let optionsData = []; |
| | | for (let i = 0; i < xData.length; i++) { |
| | | optionsData.push({ |
| | | name: xData[i], |
| | | value: yData[i], |
| | | itemStyle: { |
| | | color: colors[i], |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | const series = this.getPie3D(optionsData, 0.55); |
| | | |
| | | series.push({ |
| | | name: "pie2d", |
| | | type: "pie", |
| | | labelLine: { |
| | | show: false, |
| | | length: 60, |
| | | length2: 60, |
| | | }, |
| | | startAngle: -50, |
| | | clockwise: false, |
| | | radius: ["0", "0"], |
| | | center: ["50%", "50%"], |
| | | data: optionsData, |
| | | itemStyle: { |
| | | opacity: 0, |
| | | }, |
| | | }); |
| | | |
| | | let option = { |
| | | animation: true, |
| | | labelLine: { |
| | | show: false, |
| | | }, |
| | | xAxis3D: { |
| | | min: -1, |
| | | max: 1, |
| | | }, |
| | | yAxis3D: { |
| | | min: -1, |
| | | max: 1, |
| | | }, |
| | | zAxis3D: { |
| | | min: -1, |
| | | max: 1, |
| | | }, |
| | | grid3D: { |
| | | show: false, |
| | | boxHeight: 1, |
| | | bottom: "50%", |
| | | viewControl: { |
| | | distance: 280, |
| | | alpha: 30, |
| | | beta: 40, |
| | | zoom: 40, |
| | | rotateSensitivity: 0, |
| | | zoomSensitivity: 0, |
| | | panSensitivity: 0, |
| | | autoRotate: false, |
| | | }, |
| | | }, |
| | | series: series, |
| | | }; |
| | | |
| | | myChart.setOption(option); |
| | | |
| | | window.addEventListener("resize", () => { |
| | | myChart.resize(); |
| | | }); |
| | | }, |
| | | |
| | | getParametricEquation( |
| | | startRatio, |
| | | endRatio, |
| | | isSelected, |
| | | isHovered, |
| | | k, |
| | | height |
| | | ) { |
| | | let midRatio = (startRatio + endRatio) / 2; |
| | | let startRadian = startRatio * Math.PI * 2; |
| | | let endRadian = endRatio * Math.PI * 2; |
| | | let midRadian = midRatio * Math.PI * 2; |
| | | |
| | | if (startRatio === 0 && endRatio === 1) { |
| | | isSelected = false; |
| | | } |
| | | |
| | | k = typeof k !== "undefined" ? k : 1 / 3; |
| | | |
| | | let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0; |
| | | let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0; |
| | | |
| | | let hoverRate = isHovered ? 1.05 : 1; |
| | | |
| | | return { |
| | | u: { |
| | | min: -Math.PI, |
| | | max: Math.PI * 3, |
| | | step: Math.PI / 32, |
| | | }, |
| | | v: { |
| | | min: 0, |
| | | max: Math.PI * 2, |
| | | step: Math.PI / 20, |
| | | }, |
| | | x: function (u, v) { |
| | | if (u < startRadian) { |
| | | return ( |
| | | offsetX + |
| | | Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate |
| | | ); |
| | | } |
| | | if (u > endRadian) { |
| | | return ( |
| | | offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate |
| | | ); |
| | | } |
| | | return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate; |
| | | }, |
| | | y: function (u, v) { |
| | | if (u < startRadian) { |
| | | return ( |
| | | offsetY + |
| | | Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate |
| | | ); |
| | | } |
| | | if (u > endRadian) { |
| | | return ( |
| | | offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate |
| | | ); |
| | | } |
| | | return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate; |
| | | }, |
| | | z: function (u, v) { |
| | | if (u < -Math.PI * 0.5) { |
| | | return Math.sin(u); |
| | | } |
| | | if (u > Math.PI * 2.5) { |
| | | return Math.sin(u); |
| | | } |
| | | return Math.sin(v) > 0 ? 27 : -1; //柱状体高度 |
| | | }, |
| | | }; |
| | | }, |
| | | |
| | | getPie3D(pieData, internalDiameterRatio) { |
| | | let series = []; |
| | | let sumValue = 0; |
| | | let startValue = 0; |
| | | let endValue = 0; |
| | | let k = |
| | | typeof internalDiameterRatio !== "undefined" |
| | | ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) |
| | | : 1 / 3; |
| | | |
| | | for (let i = 0; i < pieData.length; i++) { |
| | | sumValue += pieData[i].value; |
| | | |
| | | let seriesItem = { |
| | | name: |
| | | typeof pieData[i].name === "undefined" |
| | | ? `series${i}` |
| | | : pieData[i].name, |
| | | type: "surface", |
| | | parametric: true, |
| | | wireframe: { |
| | | show: false, |
| | | }, |
| | | pieData: pieData[i], |
| | | pieStatus: { |
| | | selected: false, |
| | | hovered: false, |
| | | k: k, |
| | | }, |
| | | }; |
| | | |
| | | if (typeof pieData[i].itemStyle != "undefined") { |
| | | let itemStyle = {}; |
| | | typeof pieData[i].itemStyle.color != "undefined" |
| | | ? (itemStyle.color = pieData[i].itemStyle.color) |
| | | : null; |
| | | typeof pieData[i].itemStyle.opacity != "undefined" |
| | | ? (itemStyle.opacity = pieData[i].itemStyle.opacity) |
| | | : null; |
| | | seriesItem.itemStyle = itemStyle; |
| | | } |
| | | series.push(seriesItem); |
| | | } |
| | | |
| | | for (let i = 0; i < series.length; i++) { |
| | | endValue = startValue + series[i].pieData.value; |
| | | series[i].pieData.startRatio = startValue / sumValue; |
| | | series[i].pieData.endRatio = endValue / sumValue; |
| | | series[i].parametricEquation = this.getParametricEquation( |
| | | series[i].pieData.startRatio, |
| | | series[i].pieData.endRatio, |
| | | false, |
| | | false, |
| | | k, |
| | | series[i].pieData.value |
| | | ); |
| | | startValue = endValue; |
| | | } |
| | | |
| | | series.push({ |
| | | name: "mouseoutSeries", |
| | | type: "surface", |
| | | parametric: true, |
| | | wireframe: { |
| | | show: false, |
| | | }, |
| | | itemStyle: { |
| | | opacity: 0, |
| | | color: "#f0f", |
| | | }, |
| | | parametricEquation: { |
| | | u: { |
| | | min: 0, |
| | | max: Math.PI * 2, |
| | | step: Math.PI / 20, |
| | | }, |
| | | v: { |
| | | min: 0, |
| | | max: Math.PI, |
| | | step: Math.PI / 20, |
| | | }, |
| | | x: function (u, v) { |
| | | return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2; |
| | | }, |
| | | y: function (u, v) { |
| | | return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2; |
| | | }, |
| | | z: function (u, v) { |
| | | return Math.cos(v) > 0 ? 0 : -20; |
| | | }, |
| | | }, |
| | | }); |
| | | series.push({ |
| | | name: "mouseoutSeries", |
| | | type: "surface", |
| | | parametric: true, |
| | | wireframe: { |
| | | show: false, |
| | | }, |
| | | itemStyle: { |
| | | opacity: 0.05, |
| | | color: "#0ff", |
| | | }, |
| | | parametricEquation: { |
| | | u: { |
| | | min: 0, |
| | | max: Math.PI * 2, |
| | | step: Math.PI / 20, |
| | | }, |
| | | v: { |
| | | min: 0, |
| | | max: Math.PI, |
| | | step: Math.PI / 20, |
| | | }, |
| | | x: function (u, v) { |
| | | return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2; |
| | | }, |
| | | y: function (u, v) { |
| | | return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2; |
| | | }, |
| | | z: function (u, v) { |
| | | return Math.cos(v) > 0 ? -15 : -30; |
| | | }, |
| | | }, |
| | | }); |
| | | return series; |
| | | }, |
| | | // 随机颜色 |
| | | getRandomColor() { |
| | | const letters = "0123456789ABCDEF"; |
| | | let color = "#"; |
| | | for (let i = 0; i < 6; i++) { |
| | | color += letters[Math.floor(Math.random() * 16)]; |
| | | } |
| | | return color; |
| | | }, |
| | | |
| | | initCompensationOption(data) { |
| | | if (!data || !data.length) { |
| | | this.twoEcharts = []; |
| | | return; |
| | | } |
| | | let list = ["#00ffff", "#34D160", "#F8B551"]; |
| | | data = data.map((item, index) => { |
| | | return { |
| | | ...item, |
| | | color: list[index], |
| | | }; |
| | | }); |
| | | this.twoEcharts = data || []; |
| | | |
| | | const chartDom = this.$refs.compensationCharts; |
| | | if (!chartDom) return; |
| | | |
| | | const chartCompensation = echarts.init(chartDom); |
| | | |
| | | let option = { |
| | | polar: { |
| | | radius: [50, "70%"], |
| | | center: ["50%", "40%"], |
| | | }, |
| | | grid: { |
| | | left: "10%", |
| | | bottom: "40%", |
| | | width: "80%", |
| | | height: "100%", |
| | | }, |
| | | angleAxis: { |
| | | max: 7, |
| | | startAngle: 75, |
| | | show: false, |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | axisLine: { show: false }, |
| | | minorSplitLine: { show: false }, |
| | | }, |
| | | radiusAxis: { |
| | | type: "category", |
| | | show: false, |
| | | data: [], |
| | | axisTick: { |
| | | show: false, |
| | | }, |
| | | }, |
| | | tooltip: { show: false }, |
| | | series: { |
| | | type: "bar", |
| | | barMaxWidth: "11px", |
| | | showBackground: true, |
| | | roundCap: true, |
| | | backgroundStyle: { |
| | | color: "rgba(255, 255, 255, 0.1)", |
| | | }, |
| | | data: [], |
| | | coordinateSystem: "polar", |
| | | }, |
| | | }; |
| | | |
| | | let max = 0; |
| | | let total = 0; |
| | | let arr = []; |
| | | for (let i = 0; i < data.length; i++) { |
| | | max = Math.max(max, data[i].amount); |
| | | total += data[i].amount; |
| | | arr.push({ |
| | | value: data[i].amount, |
| | | itemStyle: { color: data[i].color }, |
| | | }); |
| | | } |
| | | this.total = total; |
| | | option.angleAxis.max = total; |
| | | option.radiusAxis.data = data.map((item) => item.type); |
| | | option.series.data = arr; |
| | | |
| | | chartCompensation.setOption(option); |
| | | |
| | | window.addEventListener("resize", () => { |
| | | chartCompensation.resize(); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .water-eval-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .cityGreenLand-charts { |
| | | width: 170px; |
| | | height: 100%; |
| | | } |
| | | |
| | | .right-panel { |
| | | position: absolute; |
| | | top: 111px; |
| | |
| | | |
| | | .top-panel-item { |
| | | height: 268px; |
| | | background: url('@/assets/right-top-bg.png') no-repeat center center; |
| | | background: url("@/assets/right-middle-bg.png") no-repeat center center; |
| | | background-size: 100% 100%; |
| | | } |
| | | |
| | | .middle-panel-item { |
| | | margin-top: 21px; |
| | | height: 303px; |
| | | background: url('@/assets/right-middle-bg.png') no-repeat center center; |
| | | background: url("@/assets/right-middle-bg.png") no-repeat center center; |
| | | background-size: 100% 100%; |
| | | } |
| | | |
| | | .bottom-panel-item { |
| | | margin-top: 21px; |
| | | height: 335px; |
| | | background: url('@/assets/right-bottom-bg.png') no-repeat center center; |
| | | background: url("@/assets/right-bottom-bg.png") no-repeat center center; |
| | | background-size: 100% 100%; |
| | | } |
| | | |
| | | .box-title { |
| | | font-size: 14px; |
| | | color: #19ECFF; |
| | | color: #19ecff; |
| | | text-align: center; |
| | | padding-top: 9px; |
| | | line-height: 21px; |
| | | } |
| | | |
| | | .house-type-content { |
| | | height: calc(100% - 30px); |
| | | display: flex; |
| | | padding: 10px 13px; |
| | | .relative { |
| | | position: relative; |
| | | |
| | | .chartBg { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 58%; |
| | | top: 56px; |
| | | left: 0px; |
| | | background: url("@/assets/echartsBg.png") no-repeat center center; |
| | | background-size: 100% 100%; |
| | | } |
| | | .chart-content { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | top: 0px; |
| | | left: 0px; |
| | | z-index: 99; |
| | | text-align: center; |
| | | display: flex; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | .chart-num { |
| | | height: 20px; |
| | | font-family: "pangmenzhengdao"; |
| | | font-size: 20px; |
| | | color: #ffffff; |
| | | text-shadow: 0px 2px 4px #40a9ff; |
| | | } |
| | | .chart-title { |
| | | font-family: PingFangSC, PingFang SC; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #ffffff; |
| | | margin-top: 23px; |
| | | margin-bottom: 60px; |
| | | } |
| | | } |
| | | .chart-black { |
| | | position: absolute; |
| | | left: 55px; |
| | | top: 86px; |
| | | height: 12%; |
| | | width: 35%; |
| | | background: rgba(0, 0, 0, 0.5); |
| | | border-radius: 28px / 10px; |
| | | padding-top: 17px; |
| | | } |
| | | } |
| | | |
| | | .pie-chart { |
| | | position: relative; |
| | | width: 45%; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &::after { |
| | | content: ""; |
| | | position: absolute; |
| | | bottom: 15%; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | width: 60%; |
| | | height: 10px; |
| | | background: radial-gradient( |
| | | ellipse at center, |
| | | rgba(0, 255, 255, 0.3) 0%, |
| | | rgba(0, 0, 0, 0) 70% |
| | | ); |
| | | border-radius: 50%; |
| | | filter: blur(3px); |
| | | z-index: 0; |
| | | } |
| | | |
| | | .center-text { |
| | | position: absolute; |
| | | left: 40%; |
| | | top: 50%; |
| | | transform: translate(-50%, -50%); |
| | | text-align: center; |
| | | z-index: 2; |
| | | padding: 10px 15px; |
| | | border-radius: 4px; |
| | | background: rgba(0, 0, 0, 0.2); |
| | | backdrop-filter: blur(2px); |
| | | |
| | | .percent { |
| | | display: block; |
| | | font-size: 28px; |
| | | color: #fff; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .type { |
| | | display: block; |
| | | font-size: 14px; |
| | | color: #19ecff; |
| | | margin-top: 5px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .type-list { |
| | | flex: 1; |
| | | margin-left: 30px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-around; |
| | | |
| | | .type-item { |
| | | display: grid; |
| | | grid-template-columns: auto 1fr 1fr 1fr; |
| | | gap: 15px; |
| | | align-items: center; |
| | | cursor: pointer; |
| | | padding: 5px 10px; |
| | | transition: all 0.3s; |
| | | position: relative; |
| | | |
| | | &:hover { |
| | | background: rgba(25, 236, 255, 0.1); |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: -5px; |
| | | height: 1px; |
| | | background: linear-gradient( |
| | | 90deg, |
| | | transparent, |
| | | rgba(25, 236, 255, 0.2), |
| | | transparent |
| | | ); |
| | | } |
| | | |
| | | .dot { |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | margin-right: 8px; |
| | | box-shadow: 0 0 5px rgba(255, 255, 255, 0.3); |
| | | } |
| | | |
| | | .name { |
| | | color: #fff; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .value { |
| | | color: #00ffff; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .area { |
| | | color: #00ffff; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .percent { |
| | | color: #00ffff; |
| | | font-size: 14px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .right-content { |
| | | flex: 1; |
| | | height: 100%; |
| | | overflow: hidden; |
| | | display: flex; |
| | | flex-direction: column; |
| | | padding-top: 27px; |
| | | |
| | | .table-header { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 0 19px 0px 118px; |
| | | margin-bottom: 8px; |
| | | |
| | | .header-item { |
| | | color: #b6d9fc; |
| | | font-weight: 400; |
| | | font-size: 10px; |
| | | text-align: center; |
| | | |
| | | &:nth-child(1) { |
| | | width: 60px; |
| | | } |
| | | |
| | | &:nth-child(2) { |
| | | width: 80px; |
| | | } |
| | | |
| | | &:nth-child(3) { |
| | | width: 60px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .data-list { |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | // padding-right: 10px; |
| | | |
| | | &::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | |
| | | .data-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 5px 7px 5px 4px; |
| | | position: relative; |
| | | margin-bottom: 21px; |
| | | cursor: pointer; |
| | | |
| | | &:not(:last-child)::after { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | height: 1px; |
| | | background: linear-gradient( |
| | | 90deg, |
| | | transparent, |
| | | rgba(25, 236, 255, 0.2), |
| | | transparent |
| | | ); |
| | | } |
| | | |
| | | .item-dot { |
| | | width: 8px; |
| | | height: 8px; |
| | | flex-shrink: 0; |
| | | border-radius: 50%; |
| | | margin-right: 3px; |
| | | box-shadow: 0 0 5px rgba(255, 255, 255, 0.3); |
| | | } |
| | | |
| | | .item-name { |
| | | font-family: "pangmenzhengdao"; |
| | | width: 100px; |
| | | color: #fff; |
| | | font-weight: 500; |
| | | font-size: 12px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | .item-value { |
| | | width: 60px; |
| | | color: #00ffff; |
| | | font-size: 12px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .item-area { |
| | | width: 80px; |
| | | color: #00ffff; |
| | | font-size: 12px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .item-percent { |
| | | width: 60px; |
| | | color: #00ffff; |
| | | font-size: 12px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | .activeItem { |
| | | box-sizing: border-box; |
| | | background: rgba(105, 192, 255, 0.12); |
| | | border-radius: 4px; |
| | | border: 1px solid rgba(105, 192, 255, 0.29); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart { |
| | | width: 100%; |
| | | height: calc(100% - 35px); |
| | | height: 100%; |
| | | } |
| | | |
| | | .middle-panel-item { |
| | | .compensation-content { |
| | | height: calc(100% - 30px); |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | padding: 20px; |
| | | |
| | | .circle-chart { |
| | | width: 100%; |
| | | height: 260px; |
| | | position: relative; |
| | | } |
| | | |
| | | .compensation-list { |
| | | position: absolute; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-top: 20px; |
| | | padding: 0 40px 0px 40px; |
| | | .compensation-center { |
| | | display: flex; |
| | | flex: 1; |
| | | justify-content: center; |
| | | align-items: center; |
| | | flex-direction: column; |
| | | .total-value { |
| | | font-family: PangMenZhengDao; |
| | | font-size: 28px; |
| | | color: #ffffff; |
| | | margin-bottom: 11px; |
| | | } |
| | | .total-name { |
| | | font-family: SourceHanSansCN, SourceHanSansCN; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: rgba(255, 255, 255, 1); |
| | | } |
| | | } |
| | | |
| | | .compensation-item { |
| | | width: 100%; |
| | | height: 45px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .compensation-item-name { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | .item-name { |
| | | font-size: 16px; |
| | | color: #ffffff; |
| | | margin-bottom: 5px; |
| | | font-family: "pangmenzhengdao"; |
| | | } |
| | | .item-value { |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: #ffffff; |
| | | margin-bottom: 2px; |
| | | } |
| | | .item-dot { |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | .pie-chart { |
| | | height: calc(100% - 35px); |
| | | } |
| | | </style> |
| | |
| | | // 生成标记点系列的配置 |
| | | getMarkerSeries(type) { |
| | | return { |
| | | name: type === "blue" ? "蓝色标记" : "橙色标记", // 系列名称 |
| | | type: "scatter", // 散点图类型 |
| | | coordinateSystem: "geo", // 使用地理坐标系 |
| | | geoIndex: 0, // 关联第一个geo组件 |
| | | data: this.mapPoints.filter(point => point.type === type), // 筛选对应类型的数据 |
| | | symbol: `image://${type === "blue" ? tooltipBlue : tooltipOrange}`, // 标记图标 |
| | | symbolSize: [20, 30], // 标记大小 |
| | | symbolOffset: [0, -15], // 标记偏移量 |
| | | z: 20, // 层级 |
| | | name: type === "blue" ? "蓝色标记" : "橙色标记", |
| | | type: "scatter", |
| | | coordinateSystem: "geo", |
| | | geoIndex: 0, |
| | | data: this.mapPoints.filter(point => point.type === type), |
| | | symbol: `image://${type === "blue" ? tooltipBlue : tooltipOrange}`, |
| | | symbolSize: MAP_CONSTANTS.MARKER.SIZE, |
| | | symbolOffset: MAP_CONSTANTS.MARKER.OFFSET, |
| | | z: MAP_CONSTANTS.MARKER.Z_INDEX, |
| | | |
| | | // 提示框配置 |
| | | label: { |
| | | show: false // 禁用标签显示 |
| | | }, |
| | | |
| | | // 修复tooltip配置 |
| | | tooltip: { |
| | | show: true, // 显示提示框 |
| | | trigger: 'item', // 触发类型:数据项 |
| | | backgroundColor: 'transparent', // 背景透明 |
| | | borderWidth: 0, // 无边框 |
| | | padding: [0, 0, 0, 0], // 内边距 |
| | | // 提示框位置 |
| | | show: true, |
| | | trigger: 'item', |
| | | backgroundColor: 'transparent', |
| | | borderWidth: 0, |
| | | padding: 0, |
| | | className: 'map-tooltip', |
| | | position: function (point) { |
| | | // 固定偏移量 |
| | | return [point[0] - 100, point[1] - 160]; |
| | | }, |
| | | // 提示框内容格式化 |
| | | formatter: function (params) { |
| | | // 返回自定义HTML结构的提示框内容 |
| | | return `<div style=" |
| | | background: url(${tooltipBg}) no-repeat center center; |
| | | background-size: 100% 100%; |
| | | width: 211px; |
| | | padding-bottom: 24px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | "> |
| | | <div style="color: #fff; font-size: 16px; margin: 21px 0;font-weight: bold;">${params.name}</div> |
| | | <div style="display: flex; justify-content: space-around; width: 100%;"> |
| | | <div style="text-align: center;"> |
| | | <div style="color: rgba(102, 255, 255, 1); font-size: 20px;margin-bottom: 8px;font-family: 'pangmenzhengdao';">${params.data.householdCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置户数(户)</div> |
| | | </div> |
| | | <div style="text-align: center;"> |
| | | <div style="color: rgba(102, 255, 255, 1); font-size: 20px;margin-bottom: 8px;font-family: 'pangmenzhengdao';">${params.data.personCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置人数(人)</div> |
| | | const { name, data } = params; |
| | | return ` |
| | | <div style=" |
| | | background: url(${tooltipBg}) no-repeat center center; |
| | | background-size: 100% 100%; |
| | | width: 211px; |
| | | padding: 20px 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | "> |
| | | <div style="color: #fff; font-size: 16px; margin-bottom: 16px; font-weight: bold;">${name}</div> |
| | | <div style="display: flex; justify-content: space-around; width: 100%; padding: 0 21px;"> |
| | | <div style="text-align: center;"> |
| | | <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.householdCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置户数(户)</div> |
| | | </div> |
| | | <div style="text-align: center;"> |
| | | <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.personCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置人数(人)</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div>`; |
| | | `; |
| | | } |
| | | }, |
| | | |
| | | // 标签配置 |
| | | label: { |
| | | show: false // 不显示标签 |
| | | }, |
| | | |
| | | // 高亮效果配置 |
| | | emphasis: { |
| | | scale: true, // 启用缩放效果 |
| | | scaleSize: 1.2, // 放大比例 |
| | | scale: true, |
| | | scaleSize: 1.2, |
| | | itemStyle: { |
| | | shadowBlur: 10, // 阴影模糊大小 |
| | | shadowColor: type === "blue" ? '#00eaff' : '#ff8e3a' // 根据类型设置阴影颜色 |
| | | shadowBlur: 10, |
| | | shadowColor: type === "blue" ? MAP_CONSTANTS.SHADOW.COLOR : '#ff8e3a' |
| | | } |
| | | } |
| | | }; |
| | |
| | | disabled: false, // 启用高亮效果 |
| | | label: { |
| | | show: true, // 显示标签 |
| | | textStyle: { // 标签文字样式 |
| | | color: "#fff", |
| | | fontSize: 10, |
| | | fontWeight: "normal", |
| | | opacity: 1 |
| | | } |
| | | color: "#fff", // 文字颜色 |
| | | fontSize: 10, // 文字大小 |
| | | fontWeight: "normal", // 文字粗细 |
| | | opacity: 1 // 不透明度 |
| | | }, |
| | | itemStyle: { // 高亮时的样式 |
| | | itemStyle: { |
| | | areaColor: { // 区域填充,保持与正常状态相同的背景 |
| | | type: 'pattern', |
| | | image: mapBg, |
| | |
| | | // 标签配置 |
| | | label: { |
| | | show: true, // 显示标签 |
| | | textStyle: { // 标签文字样式 |
| | | color: "#fff", |
| | | fontSize: 10, |
| | | fontWeight: "normal", |
| | | opacity: 1 |
| | | } |
| | | color: "#fff", // 文字颜色 |
| | | fontSize: 10, // 文字大小 |
| | | fontWeight: "normal", // 文字粗细 |
| | | opacity: 1 // 不透明度 |
| | | }, |
| | | |
| | | tooltip: { |
| | |
| | | import router from './router' |
| | | import store from './store' |
| | | import * as echarts from 'echarts'; |
| | | import 'echarts-gl' |
| | | import ECharts from 'vue-echarts'; |
| | | import '@/assets/font/font.css' |
| | | import 'echarts/lib/chart/pie'; |
| | | import 'echarts/lib/chart/bar'; |
| | | import 'echarts/lib/component/tooltip'; |
| | |
| | | { |
| | | "type": "Feature", |
| | | "properties": { |
| | | "name": "三江镇", |
| | | "name": "三江街道", |
| | | "BM_Time": "2025-03-21 16:00:33", |
| | | "BM_Area": 48138721.767335184, |
| | | "adcode": "510184101000" |
| | |
| | | { |
| | | "type": "Feature", |
| | | "properties": { |
| | | "name": "江源镇", |
| | | "name": "江源街道", |
| | | "BM_Time": "2025-03-21 16:00:33", |
| | | "BM_Area": 26895967.457464911, |
| | | "adcode": "510184102000" |
| | |
| | | { |
| | | "type": "Feature", |
| | | "properties": { |
| | | "name": "羊马镇", |
| | | "name": "羊马街道", |
| | | "BM_Time": "2025-03-21 16:00:33", |
| | | "BM_Area": 42733001.744975172, |
| | | "adcode": "510184103000" |
| | |
| | | { |
| | | "type": "Feature", |
| | | "properties": { |
| | | "name": "大划镇", |
| | | "name": "大划街道", |
| | | "BM_Time": "2025-03-21 16:00:34", |
| | | "BM_Area": 18404576.628594477, |
| | | "adcode": "510184116000" |
| | |
| | | // 请求拦截 |
| | | service.interceptors.request.use( |
| | | config => { |
| | | const token = localStorage.getItem('token') || 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImxvZ2luX3VzZXJfa2V5IjoiZWFjMDUyNWMtZjk4Mi00OWY3LWI5MTYtOTZlMmM0NzNjYjg1In0.zUMiAEKOfuto9pX4r3sKK7rfRDm-YRfSERi-0bRoBnvZKB7mApG2SdYPKRIiB6IyX7Fwz7o8IC9D3Svl2v5gMw' |
| | | if (token) { |
| | | // 添加token到请求头 |
| | | config.headers['Authorization'] = token |
| | | } |
| | | // const token = localStorage.getItem('token') || 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImxvZ2luX3VzZXJfa2V5IjoiZWFjMDUyNWMtZjk4Mi00OWY3LWI5MTYtOTZlMmM0NzNjYjg1In0.zUMiAEKOfuto9pX4r3sKK7rfRDm-YRfSERi-0bRoBnvZKB7mApG2SdYPKRIiB6IyX7Fwz7o8IC9D3Svl2v5gMw' |
| | | // if (token) { |
| | | // // 添加token到请求头 |
| | | // config.headers['Authorization'] = token |
| | | // } |
| | | if (config.method == 'get') { |
| | | if (!config.params) config.params = {}; |
| | | config.params = { |
| | |
| | | <template> |
| | | <div class="data-screen" :style="screenStyle"> |
| | | <div v-if="!isFullscreen" class="fullscreen-mask" @click="enterFullScreen"> |
| | | <div class="fullscreen-tip"> |
| | | <i class="el-icon-full-screen"></i> |
| | | <p>点击进入全屏模式</p> |
| | | </div> |
| | | </div> |
| | | <header-panel /> |
| | | <left-panel v-if="!loading" :data="data" /> |
| | | <center-panel v-if="!loading" :data="data" /> |
| | | <right-panel /> |
| | | <right-panel v-if="!loading" :data="data" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | transformOrigin: 'left top' |
| | | }, |
| | | data: {}, |
| | | loading: true |
| | | loading: true, |
| | | isFullscreen: false, |
| | | timer: null |
| | | }; |
| | | }, |
| | | created() { |
| | | this.handleResize(); |
| | | getData().then(res => { |
| | | this.data = res.data; |
| | | this.loading = false; |
| | | }); |
| | | this.timer = setInterval(() => { |
| | | getData().then(res => { |
| | | this.data = res.data; |
| | | this.loading = false; |
| | | }); |
| | | }, 10000); |
| | | }, |
| | | mounted() { |
| | | window.addEventListener('resize', this.handleResize); |
| | | document.addEventListener('fullscreenchange', this.handleFullscreenChange); |
| | | document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange); |
| | | document.addEventListener('mozfullscreenchange', this.handleFullscreenChange); |
| | | document.addEventListener('MSFullscreenChange', this.handleFullscreenChange); |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener('resize', this.handleResize); |
| | | document.removeEventListener('fullscreenchange', this.handleFullscreenChange); |
| | | document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange); |
| | | document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange); |
| | | document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange); |
| | | this.exitFullScreen(); |
| | | clearInterval(this.timer); |
| | | }, |
| | | methods: { |
| | | handleResize() { |
| | | this.screenStyle.transform = `scale(${window.innerWidth / 1920})`; |
| | | const widthScale = window.innerWidth / 1920; |
| | | const heightScale = window.innerHeight / 1080; |
| | | const scale = Math.min(widthScale, heightScale); |
| | | this.screenStyle.transform = `scale(${scale})`; |
| | | }, |
| | | handleFullscreenChange() { |
| | | this.isFullscreen = document.fullscreenElement || |
| | | document.webkitFullscreenElement || |
| | | document.mozFullScreenElement || |
| | | document.msFullscreenElement; |
| | | }, |
| | | enterFullScreen() { |
| | | const element = document.documentElement; |
| | | try { |
| | | if (element.requestFullscreen) { |
| | | element.requestFullscreen(); |
| | | } else if (element.webkitRequestFullscreen) { |
| | | element.webkitRequestFullscreen(); |
| | | } else if (element.mozRequestFullScreen) { |
| | | element.mozRequestFullScreen(); |
| | | } else if (element.msRequestFullscreen) { |
| | | element.msRequestFullscreen(); |
| | | } |
| | | } catch (error) { |
| | | console.error('全屏请求失败:', error); |
| | | } |
| | | }, |
| | | exitFullScreen() { |
| | | const element = document; |
| | | try { |
| | | if (element.exitFullscreen) { |
| | | element.exitFullscreen(); |
| | | } else if (element.webkitExitFullscreen) { |
| | | element.webkitExitFullscreen(); |
| | | } else if (element.mozCancelFullScreen) { |
| | | element.mozCancelFullScreen(); |
| | | } else if (element.msExitFullscreen) { |
| | | element.msExitFullscreen(); |
| | | } |
| | | } catch (error) { |
| | | console.error('退出全屏失败:', error); |
| | | } |
| | | } |
| | | } |
| | | }; |
| | |
| | | overflow: hidden; |
| | | background: url('@/assets/背景色.png') no-repeat center center; |
| | | background-size: 100% 100%; |
| | | |
| | | .fullscreen-mask { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | z-index: 9999; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | cursor: pointer; |
| | | |
| | | .fullscreen-tip { |
| | | text-align: center; |
| | | color: #fff; |
| | | |
| | | i { |
| | | font-size: 48px; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | p { |
| | | font-size: 24px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |