| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- <template>
- <Card :title="title" :subTitle="subTitle" :icon="icon" class="online-pay-day">
- <div class="info margin-r-20" v-if="showInfo">
- <div class="text">
- <p class="p1">线上缴费</p>
- <p class="p2 margin-tg-20">日热度统计</p>
- <p class="p3">(近12月日平均)</p>
- </div>
- <div class="legend">
- <p class="legend1">
- <span class="legend1-color"></span>
- <span>时段缴费</span>
- </p>
- <p class="legend2 margin-tg-20">
- <span class="legend2-color"></span>
- <span>时段占比</span>
- </p>
- <p class="legend3">
- <span class="legend3-color"><b class="inner"></b></span>
- <span>时段比例</span>
- </p>
- </div>
- </div>
- <div ref="onlinePayDayBar" class="online-pay-day-bar flex-1"></div>
- </Card>
- </template>
- <script>
- import * as echarts from 'echarts'
- import { huiJiaApi } from '@/api'
- // import { getBigNumberWithUint } from '@/libs/tools.js'
- import Card from '@/views/hui-jia/components/card'
- import icon from './images/icon-title.png'
- export default {
- name: 'OnlinePayDay',
- components: {
- Card
- },
- props: {
- showMarkPoint: {
- type: Boolean,
- default: () => true
- },
- showInfo: {
- type: Boolean,
- default: () => true
- }
- },
- data () {
- return {
- onlinePayDayBarInstance: null,
- xAxisData: ['01:00', '04:00', '07:00', '10:00', '13:00', '16:00', '19:00', '22:00'],
- seriesData: [0, 0, 0, 0, 0, 0, 0, 0],
- title: '线上缴费日热度',
- subTitle: '近12个月',
- icon: icon
- }
- },
- mounted () {
- this.initChart()
- this.getOnlinePayDay()
- window.addEventListener("resize", this.handleResize)
- },
- beforeDestroy() {
- if (this.onlinePayDayBarInstance) {
- this.onlinePayDayBarInstance.dispose()
- }
- window.removeEventListener("resize", this.handleResize)
- },
- methods: {
- getOnlinePayDay () {
- huiJiaApi.getOnlinePayDay().then(res => {
- this.xAxisData = (res.data.data.list || []).map(item => item.statData)
- this.seriesData = (res.data.data.list || []).map(item => item.payAmount)
- this.initChart()
- })
- },
- /**
- * 获取一个和max最接近的能被5整除的无零头整数
- */
- getMax (max) {
- if (max <= 10) return 10
- let pow = max.toString().length - 2
- pow = Math.pow(10, pow)
- max = Math.ceil(max / pow / 10) * 10 * pow
- return max
- },
- initChart () {
- this.onlinePayDayBarInstance = echarts.init(this.$refs.onlinePayDayBar)
- const xAxisData = this.xAxisData
- const seriesData = this.seriesData
- let all = seriesData.reduce((total, num) => {
- return Number(total) + Number(num)
- }, 0)
- let markPointData = []
- seriesData.forEach((item, i) => {
- const value = (all > 0 ? (Number(item) / all) * 100 : 0).toFixed(1) + '%'
- markPointData.push({
- value,
- xAxis: i,
- yAxis: item,
- itemStyle: {
- opacity: xAxisData[i].indexOf('hide') !== -1 ? 0 : 1
- }
- })
- })
- let lineData = []
- let min = seriesData.reduce((min, num) => {
- return Math.min(Number(min), Number(num))
- }, 0)
- let max = seriesData.reduce((min, num) => {
- return Math.max(Number(min), Number(num))
- }, 0)
- seriesData.forEach((item, i) => {
- lineData.push(Number(item) - min * 0.5)
- }, 0)
- const textSize = (text, fontSize) => {
- var span = document.createElement('span')
- var result = {
- 'width': span.offsetWidth,
- 'height': span.offsetHeight
- }
- span.style.visibility = 'hidden'
- span.style.fontSize = fontSize || '14px'
- document.body.appendChild(span)
- if (typeof span.textContent !== 'undefined') { span.textContent = text || '国' } else span.innerText = text || '国'
- result.width = span.offsetWidth - result.width
- result.height = span.offsetHeight - result.height
- span.parentNode.removeChild(span)
- return result
- }
- const option = {
- tooltip: {},
- legend: {
- show: false
- },
- grid: {
- top: this.showMarkPoint ? '10%' : '6%',
- bottom: '0px',
- left: '0px',
- right: '0px',
- containLabel: true
- },
- xAxis: {
- axisLabel: {
- color: '#fff',
- margin: 15,
- fontSize: 12,
- formatter: function (val, idx) {
- let value = xAxisData[idx]
- return value
- }
- },
- axisLine: {
- show: true,
- lineStyle: {
- color: '#666',
- opacity: 1,
- cap: 'round'
- }
- },
- boundaryGap: true,
- axisTick: {
- alignWithLabel: true,
- length: 7,
- lineStyle: {
- width: 3,
- color: '#fff',
- opacity: 0.5
- }
- },
- splitLine: {
- show: true,
- lineStyle: {
- color: '#fff',
- opacity: 0.3,
- cap: 'round',
- type: [5, 10]
- }
- },
- max: function (value) { // x轴左侧留白
- return value.max + 0.3
- },
- min: function (value) { // x轴左侧留白
- return -0.3
- },
- data: xAxisData
- },
- yAxis: [
- {
- axisLabel: {
- color: 'rgba(160, 179, 214, 0.7)',
- fontSize: 11,
- margin: 12
- },
- axisLine: {
- show: false,
- lineStyle: {
- color: '#fff'
- }
- },
- axisTick: {
- length: 14,
- lineStyle: {
- width: 2,
- fontSize: 16
- }
- },
- splitLine: {
- show: true,
- lineStyle: {
- color: '#fff',
- opacity: 0.3,
- cap: 'round',
- type: 'dashed',
- dashOffset: 5
- }
- }
- },
- {
- type: 'value',
- position: 'right',
- axisLabel: {
- show: false
- },
- axisTick: {
- show: true,
- length: 14,
- lineStyle: {
- width: 2,
- fontSize: 16
- }
- },
- axisLine: {
- show: false
- }
- }
- ],
- series: [
- {
- type: 'line',
- silent: true,
- symbolSize: 10,
- yAxisIndex: 0,
- itemStyle: {
- color: '#FFE1D4',
- borderColor: 'rgba(255, 162, 41, 0.7)',
- borderWidth: 3
- },
- lineStyle: {
- // opacity: 0
- color: '#3D7BF8',
- width: 2
- },
- markPoint: {
- // symbol: 'none',
- symbol: this.showMarkPoint ? 'path://m 0,0 h 48 a 5 5 0 0 1 4 4 v 20 a 5 5 0 0 1 -4 4 h -18 l -5,5 l -5,-5 h -18 a 5 5 0 0 1 -4 -4 v -20 a 5 5 0 0 1 4 -4 z' : 'none', // 带下箭头的圆角矩形
- symbolSize: function (val) {
- return [textSize(val, '14px').width + 20, 55] // 设置宽高
- },
- itemStyle: {
- color: '#262BB3' // %值的背景颜色
- },
- symbolOffset: ['0', '-40%'], // 相对位置
- symbolKeepAspect: true, // 是否保持宽高比
- label: {
- position: 'insideTop',
- fontSize: 14,
- distance: 10
- },
- data: markPointData,
- silent: true
- },
- areaStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [{
- offset: 0, color: 'rgba(21, 147, 222, 1)' // 0% 处的颜色
- }, {
- offset: max ? (max - min) / max : 1, color: 'rgba(61,123,248,0)' // 50% 处的颜色
- }, {
- offset: 1, color: 'rgba(61,123,248,0)' // 100% 处的颜色
- }],
- global: false // 缺省为 false
- }
- },
- data: lineData
- },
- {
- type: 'bar',
- barWidth: '25%',
- labelLine: {
- show: false
- },
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: '#491CC7' },
- { offset: 1, color: '#E29163' }
- ])
- },
- data: seriesData
- }]
- }
- this.onlinePayDayBarInstance.setOption(option)
- this.onlinePayDayBarInstance.resize()
- },
- handleResize() {
- if (this.onlinePayDayBarInstance) {
- this.onlinePayDayBarInstance.resize()
- }
- },
- }
- }
- </script>
- <style lang="scss">
- @import '@/assets/css/function.scss';
- .online-pay-day-bar {
- width: 100%;
- // height: halfH(350);
- }
- .online-pay-day {
- .card-body{
- display: flex;
- }
- .total{
- height: halfH(24);
- line-height: halfH(24);
- padding: halfH(18) halfW(18);
- color: #fff;
- float: left;
- font-size: halfW(14);
- border-radius: 5px;
- background-color: rgba(17, 28, 48, 1);
- text-align: center;
- border: 1px solid rgba(0, 123, 211, 0.2);
- }
- .img{
- width: halfW(40);
- height: halfH(40);
- margin-right: halfW(27);
- margin-top: halfH(-7);
- padding: halfH(8) halfW(8);
- box-sizing: border-box;
- background: #12223C;
- border-radius: 50%;
- .icon{
- width: 100%;
- height: 100%;
- }
- }
- .info{
- width: halfW(160);
- // height: calc(100% - halfH(60));
- border: 1px solid rgba(0, 123, 211, 0.2);
- border-radius: halfW(5) halfH(5);
- display: flex;
- flex-direction: column;
- .p1{
- font-size: halfW(14);
- color: #B9E3F4;
- }
- .p2{
- font-size: halfW(18);
- color: #fff;
- }
- .p3{
- font-size: halfW(12);
- color: #9FA5B7;
- }
- }
- .text,.legend{
- padding: halfH(30) halfW(16);
- }
- .text{
- // height: halfH(125);
- flex: 1;
- // line-height: halfH(40);
- }
- .legend{
- color: #808BAD;
- background: #111C30;
- font-size: halfW(14);
- flex: 1;
- // line-height: halfH(40);
- .legend1-color, .legend2-color{
- display: inline-block;
- width: halfW(20);
- height: halfH(8);
- margin-right: halfW(10);
- vertical-align: middle;
- }
- .legend1-color{
- background: linear-gradient(90deg, #FEA373 0%, #FF678B 100%);
- }
- .legend2-color{
- background: linear-gradient(90deg, #0F67F8 0%, #98D7F1 50%, #77ECED 100%);
- }
- .legend3-color{
- display: inline-block;
- width: halfW(20);
- height: halfH(20);
- background: linear-gradient(90deg, #F6D1A7 0%, #F5BD7C 50%, #F4A850 100%);
- border-radius: 50%;
- margin-right: halfW(10);
- position: relative;
- .inner{
- display: inline-block;
- width: halfW(10);
- height: halfH(10);
- background: linear-gradient(90deg, #C9FFBF 0%, #FFB0BE 100%);
- border-radius: 50%;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- }
- }
- }
- </style>
|