黔西南大屏
This commit is contained in:
784
packages/bigscreen/dv/AppQxnDv.vue
Normal file
784
packages/bigscreen/dv/AppQxnDv.vue
Normal file
@@ -0,0 +1,784 @@
|
||||
<template>
|
||||
<div class="AppQxnDv">
|
||||
<div class="left">
|
||||
<AiDvPanel style="width: 100%" border="border6" title="单位列表">
|
||||
<div class="left-list">
|
||||
<div class="left-item" v-for="(item, index) in 16" :key="index">
|
||||
<i>{{ index + 1 }}</i>
|
||||
<div class="left-item__top">
|
||||
<h2>黔西南州公安局</h2>
|
||||
<el-select v-model="value" size="mini" placeholder="请选择派出所">
|
||||
<el-option label="南京派出所" value="1"></el-option>
|
||||
<el-option label="北京派出所" value="2"></el-option>
|
||||
<el-option label="长安派出所" value="3"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="left-item__bottom">
|
||||
<span>居民数量:17246</span>
|
||||
<span>成员:2057</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AiDvPanel>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="right-left">
|
||||
<AiDvPanel style="width: 100%" border="border6" title="微警务群概况">
|
||||
<div class="right-left__total AppQxnDv-total">
|
||||
<div class="item" v-for="(item, index) in 4" :key="index">
|
||||
<h2>全部人员数</h2>
|
||||
<div class="item-bottom">
|
||||
<span>726,079</span>
|
||||
<i>人</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>增长情况</h2>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 200px; width: 500px;"
|
||||
:ref="'chart'"
|
||||
:data="lineData"
|
||||
:ops="lineChart1">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
<div class="right-left__middle">
|
||||
<div class="left">
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>覆盖率</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="60"></DoughnutChart>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>群标签化率</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="95"></DoughnutChart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>群标签情况</h2>
|
||||
<el-select v-model="value" style="width: 92px" size="mini" placeholder="专属">
|
||||
<el-option label="XXX派出所" value="1"></el-option>
|
||||
<el-option label="XXX派出所" value="2"></el-option>
|
||||
<el-option label="XXX派出所" value="3"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 230px; width: 245px;"
|
||||
:ref="'chart2'"
|
||||
:data="lineData1"
|
||||
:ops="barChart8">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-left__bottom">
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>单位成员关系人数</h2>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 210px; width: 100%;"
|
||||
:ref="'chart2'"
|
||||
:data="lineData1"
|
||||
:ops="barChart8">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>群人数规模分布</h2>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 160px; width: 100%;"
|
||||
:ref="'chart2'"
|
||||
:data="lineData1"
|
||||
:ops="pieChart">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
</div>
|
||||
</AiDvPanel>
|
||||
</div>
|
||||
<div class="right-middle">
|
||||
<AiDvPanel style="width: 100%" border="border6" title="综合概况图">
|
||||
<div class="right-left__total AppQxnDv-total">
|
||||
<div class="item" v-for="(item, index) in 5" :key="index">
|
||||
<h2>分局数量</h2>
|
||||
<div class="item-bottom">
|
||||
<span>726,079</span>
|
||||
<i>人</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<DvMap style="width: 100%; height: 420px;"></DvMap>
|
||||
</div>
|
||||
<div class="right-middle__middle">
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>成员激活</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="95"></DoughnutChart>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>日均活跃率</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="95"></DoughnutChart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-middle__bottom">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>近期成员使用分布</h2>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 210px; width: 100%;"
|
||||
:ref="'chart'"
|
||||
:data="lineData"
|
||||
:ops="lineChart1">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
</AiDvPanel>
|
||||
</div>
|
||||
<div class="right-right">
|
||||
<AiDvPanel style="width: 100%" border="border6" title="微警务群概况">
|
||||
<div class="right-left__total AppQxnDv-total">
|
||||
<div class="item" v-for="(item, index) in 4" :key="index">
|
||||
<h2>群动态概况</h2>
|
||||
<div class="item-bottom">
|
||||
<span>726,079</span>
|
||||
<i>人</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-right__top">
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>群活跃率(7日)</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="95"></DoughnutChart>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>人员活跃(7日)</h2>
|
||||
</div>
|
||||
<DoughnutChart :ratio="95"></DoughnutChart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-left__middle">
|
||||
<div class="AppQxnDv-title">
|
||||
<h2>各单位群主及群分布</h2>
|
||||
</div>
|
||||
<ai-echart-v2
|
||||
style="height: 210px; width: 100%;"
|
||||
:ref="'chart5'"
|
||||
:data="barData"
|
||||
:ops="barChart">
|
||||
</ai-echart-v2>
|
||||
</div>
|
||||
</AiDvPanel>
|
||||
<AiDvPanel style="width: 100%; height: 340px;" border="border6" title="群动态多维度排行">
|
||||
<AiDvTable
|
||||
:heigth="'100%'"
|
||||
stripe
|
||||
:isShowIndex="true"
|
||||
:config="[{
|
||||
width: '',
|
||||
color: '',
|
||||
align: ''
|
||||
},
|
||||
{
|
||||
width: '',
|
||||
color: '',
|
||||
align: ''
|
||||
},
|
||||
{
|
||||
width: '',
|
||||
color: '',
|
||||
align: ''
|
||||
}]"
|
||||
:data="[{name: '列1', v: 23, v2: 3},
|
||||
{name: '列2', v: 12, v2: 4},
|
||||
{name: '列2', v: 12, v2: 4}]">
|
||||
</AiDvTable>
|
||||
</AiDvPanel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DvMap from './components/DvMap'
|
||||
import DoughnutChart from './components/DoughnutChart'
|
||||
export default {
|
||||
name: 'AppQxnDv',
|
||||
label: '警民互联',
|
||||
|
||||
components: {
|
||||
DvMap,
|
||||
DoughnutChart
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
value: '',
|
||||
lineData: [
|
||||
{
|
||||
"name": "阿斯达",
|
||||
"v1": 23,
|
||||
"v2": 33
|
||||
},
|
||||
{
|
||||
"name": "水电费",
|
||||
"v1": 12,
|
||||
"v2": 34
|
||||
},
|
||||
{
|
||||
"name": "凡哥",
|
||||
"v1": 67,
|
||||
"v2": 25
|
||||
},
|
||||
{
|
||||
"name": "党费",
|
||||
"v1": 98,
|
||||
"v2": 85
|
||||
}
|
||||
],
|
||||
lineData1: [
|
||||
{
|
||||
"name": "1月",
|
||||
"v1": 23
|
||||
},
|
||||
{
|
||||
"name": "2月",
|
||||
"v1": 12
|
||||
},
|
||||
{
|
||||
"name": "3月",
|
||||
"v1": 67
|
||||
},
|
||||
{
|
||||
"name": "4月",
|
||||
"v1": 98
|
||||
}
|
||||
],
|
||||
lineChart1: {
|
||||
legend: { show: false },
|
||||
grid: {
|
||||
left: 50,
|
||||
right: '2%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0, 102, 154, 0.65)',
|
||||
borderColor: 'rgba(0, 102, 154, 0.65)',
|
||||
textStyle: { color: '#fff' },
|
||||
axisPointer: { type: 'cross' }
|
||||
},
|
||||
color: ['#7AA3CC', '#33CCCC'],
|
||||
xAxis: {
|
||||
type: "category",
|
||||
axisTick: {show: false},
|
||||
axisLine: {show: false},
|
||||
axisLabel: {color: '#8FABBF', fontSize: 12},
|
||||
},
|
||||
yAxis: {
|
||||
nameGap: 23,
|
||||
minInterval: 1,
|
||||
splitLine: { lineStyle: { color: 'rgba(108, 128, 151, 0.3)', type: 'dashed' } },
|
||||
axisLabel: {color: '#8FABBF', fontSize: 12},
|
||||
axisPointer: { snap: true }
|
||||
},
|
||||
daemon: (color) => ({
|
||||
showSymbol: false,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
shadowBlur: 4,
|
||||
shadowOffsetY: 2,
|
||||
width: 2
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
x2: 0,
|
||||
y: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: this.Hex2RGBA(color, 0.3) },
|
||||
{ offset: 1, color: this.Hex2RGBA(color, 0.1) }
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
barChart8: {
|
||||
legend: {show: false},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(0, 102, 154, 0.65)',
|
||||
borderColor: 'rgba(0, 102, 154, 0.65)',
|
||||
textStyle: { color: '#fff' },
|
||||
axisPointer: { type: 'cross' }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
axisLabel: {color: '#8FABBF', fontSize: 12},
|
||||
axisTick: {show: false},
|
||||
axisLine: {show: false},
|
||||
},
|
||||
xAxis: {
|
||||
nameGap: 23, minInterval: 1,
|
||||
splitLine: {lineStyle: {color: 'rgba(108, 128, 151, 0.3)', type: 'dashed'}},
|
||||
axisLabel: {color: '#8FABBF', fontSize: 12},
|
||||
},
|
||||
daemon: {
|
||||
type: 'bar', barWidth: 10, barGap: '40%',
|
||||
label: {show: true, position: 'insideRight', color: '#fff', fontSize: 14},
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: 'rgba(123, 165, 255, .2)'
|
||||
},
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear', x: 0, x2: 1, y: 0, y2: 0,
|
||||
colorStops: [{offset: 0, color: 'rgba(0, 89, 84, 0)'}, {offset: 1, color: '#66E1DF'}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
barChart: {
|
||||
yAxis: {
|
||||
nameGap: 23,
|
||||
minInterval: 1,
|
||||
splitLine: { lineStyle: { color: 'rgba(255,255,255,.2)', type: 'dashed' } },
|
||||
axisLabel: { color: '#C3C4C4' },
|
||||
axisPointer: { show: false }
|
||||
},
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
triggerTooltip: false,
|
||||
shadowStyle: { color: 'rgba(46, 153, 255, .2)' }
|
||||
},
|
||||
color: [
|
||||
{
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
x2: 0,
|
||||
y: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(51, 204, 204, 1)' },
|
||||
{ offset: 1, color: 'rgba(31, 89, 89, 0.25)' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
x2: 0,
|
||||
y: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(219, 179, 110, 0.1)' },
|
||||
{ offset: 1, color: 'rgba(219, 179, 110, 1)' }
|
||||
]
|
||||
}
|
||||
],
|
||||
daemon: {
|
||||
type: 'bar',
|
||||
barWidth: 14,
|
||||
barCategoryGap: 40,
|
||||
itemStyle: {}
|
||||
}
|
||||
},
|
||||
barData: [
|
||||
{
|
||||
"name": "兴仁公安局",
|
||||
"v1": 223,
|
||||
"v11": 23
|
||||
},
|
||||
{
|
||||
"name": "兴仁公安局1",
|
||||
"v1": 22,
|
||||
"v11": 29
|
||||
},
|
||||
{
|
||||
"name": "兴仁公安局2",
|
||||
"v1": 67,
|
||||
"v11": 23
|
||||
},
|
||||
{
|
||||
"name": "兴仁公安局3",
|
||||
"v1": 98,
|
||||
"v11": 23
|
||||
}
|
||||
],
|
||||
pieData: [
|
||||
{ value: 1048, name: 'Search Engine' },
|
||||
{ value: 735, name: 'Direct' },
|
||||
{ value: 580, name: 'Email' },
|
||||
{ value: 484, name: 'Union Ads' },
|
||||
{ value: 300, name: 'Video Ads' }] ,
|
||||
pieChart: {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
grid: {
|
||||
left: '6%',
|
||||
top: '6%',
|
||||
right: '6%',
|
||||
bottom: '6%'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['50%', '66%'],
|
||||
labelLine:{
|
||||
normal:{
|
||||
length: 0.01,
|
||||
lineStyle: {
|
||||
color: '#526D7A'
|
||||
}
|
||||
}
|
||||
},
|
||||
startAngle: 90,
|
||||
minAngle: 5,
|
||||
avoidLabelOverlap: true,
|
||||
label: {
|
||||
show: true,
|
||||
normal: {
|
||||
textStyle: {
|
||||
color: '#9BB7D4',
|
||||
fontSize: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
Hex2RGBA(color, alpha = 1) {
|
||||
let hex = 0;
|
||||
if (color.charAt(0) == "#") {
|
||||
if (color.length == 4) {
|
||||
//检测诸如#FFF简写格式
|
||||
color = "#" + color.charAt(1).repeat(2) +
|
||||
color.charAt(2).repeat(2) +
|
||||
color.charAt(3).repeat(2);
|
||||
}
|
||||
hex = parseInt(color.slice(1), 16);
|
||||
}
|
||||
let r = hex >> 16 & 0xFF;
|
||||
let g = hex >> 8 & 0xFF;
|
||||
let b = hex & 0xFF;
|
||||
return `rgba(${r},${g},${b},${alpha})`;
|
||||
},
|
||||
RGBtoHex(r, g, b) {
|
||||
let hex = r << 16 | g << 8 | b;
|
||||
return "#" + hex.toString(16);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppQxnDv {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 16px;
|
||||
box-sizing: border-box;
|
||||
background: #0c0c0c;
|
||||
overflow: hidden;
|
||||
|
||||
.wrapper {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.AppQxnDv-title {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
color: rgba(172, 201, 230, 0.8);
|
||||
background-image: linear-gradient(270deg, rgba(31, 67, 102, 0) 0%, rgba(31, 67, 102, 0.25) 100%);
|
||||
|
||||
h2 {
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
padding: 0 10px;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 27px;
|
||||
z-index: 1;
|
||||
width: 9px;
|
||||
height: 2px;
|
||||
background: rgba(41, 77, 102, 1);
|
||||
content: ' ';
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 9px;
|
||||
height: 2px;
|
||||
background: #5299CC;
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 14px;
|
||||
z-index: 1;
|
||||
width: 9px;
|
||||
height: 2px;
|
||||
background: rgba(41, 77, 102, 1);
|
||||
content: ' ';
|
||||
}
|
||||
}
|
||||
|
||||
.AppQxnDv-total {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
color: #02FEFF;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-left: 4px;
|
||||
font-style: normal;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-select) {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
padding: 0 26px 0 6px;
|
||||
font-size: 12px;
|
||||
color: rgba(179, 229, 229, 1);
|
||||
border: 1px solid #2A7A92;
|
||||
border-radius: 2px;
|
||||
background: transparent;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(179, 229, 229, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
right: 1px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #B3E5E5;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
min-height: 20px;
|
||||
background-clip: content-box;
|
||||
box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
& > .right {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.right-left {
|
||||
width: 500px;
|
||||
|
||||
.right-left__middle {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
width: 245px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.right-left__bottom {
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-middle {
|
||||
width: 522px;
|
||||
margin: 0 20px;
|
||||
|
||||
.right-middle__middle {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-right {
|
||||
flex: 1;
|
||||
|
||||
.right-right__top {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
|
||||
& > div {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
width: 240px;
|
||||
margin-right: 14px;
|
||||
|
||||
.left-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
.left-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
padding: 30px 14px 14px;
|
||||
background-image: linear-gradient(0deg, rgba(40, 182, 253, 0.08) 1%, rgba(0, 102, 154, 0.65) 100%);
|
||||
border-radius: 6px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 22px;
|
||||
height: 21px;
|
||||
line-height: 21px;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
background-image: linear-gradient(177deg, #02eeee66 0%, #0190d866 100%);
|
||||
border-radius: 6px 0 6px 0;
|
||||
}
|
||||
|
||||
.left-item__bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
span {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.left-item__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-select {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
22
packages/bigscreen/dv/AppQxnEventDv.vue
Normal file
22
packages/bigscreen/dv/AppQxnEventDv.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div class="AppQxnEventDv"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppQxnEventDv',
|
||||
label: '事件上报',
|
||||
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppQxnEventDv {
|
||||
|
||||
}
|
||||
</style>
|
||||
185
packages/bigscreen/dv/components/DoughnutChart.vue
Normal file
185
packages/bigscreen/dv/components/DoughnutChart.vue
Normal file
@@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<div class="DoughnutChart-wrapper">
|
||||
<div class="DoughnutChart" :id="id">
|
||||
<canvas :id="canvasId"></canvas>
|
||||
<div class="DonutChart-text">
|
||||
<span>{{ ratio }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="DoughnutChart-explain">
|
||||
<div class="item">
|
||||
<i></i>
|
||||
<span>已激活成员</span>
|
||||
<p>2142</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<i></i>
|
||||
<span>未激活成员</span>
|
||||
<p>2142</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['ratio'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
id: `DonutChart-${Math.ceil(Math.random() * 10000)}`,
|
||||
canvasId: `DonutChartCanvas-${Math.ceil(Math.random() * 10000)}`,
|
||||
canvasWidth: 90,
|
||||
canvasHeight: 90
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
drawLine(ctx, options) {
|
||||
const { beginX, beginY, endX, endY, lineColor, lineWidth } = options
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.strokeStyle = lineColor
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(beginX, beginY)
|
||||
ctx.lineTo(endX, endY)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
},
|
||||
|
||||
angle (a, i, ox, oy, or) {
|
||||
var hudu = (2 * Math.PI / 360) * a * i
|
||||
var x = ox + Math.sin(hudu) * or
|
||||
var y = oy - Math.cos(hudu) * or
|
||||
return x + '_' + y
|
||||
},
|
||||
|
||||
mapColor (value) {
|
||||
if (value < 25) {
|
||||
return '#FFC139'
|
||||
}
|
||||
|
||||
if (value < 50) {
|
||||
return '#21E03E'
|
||||
}
|
||||
|
||||
return '#05C8FF'
|
||||
},
|
||||
|
||||
init () {
|
||||
const ctx = document.querySelector(`#${this.canvasId}`).getContext('2d')
|
||||
const canvasWidth = document.querySelector(`#${this.id}`).offsetWidth
|
||||
const canvasHeight = document.querySelector(`#${this.id}`).offsetHeight
|
||||
const angle = this.ratio / 100 * 2
|
||||
let radian = 0
|
||||
|
||||
ctx.width = canvasWidth
|
||||
ctx.height = canvasHeight
|
||||
const x = canvasWidth / 2
|
||||
const y = canvasHeight / 2
|
||||
ctx.lineWidth = 4
|
||||
ctx.strokeStyle = 'rgba(102, 121, 138, 0.3)'
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, x - 8, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.lineWidth = 4
|
||||
var g = ctx.createLinearGradient(0, 0, 0, 80)
|
||||
g.addColorStop(0, 'rgba(44, 150, 231, 0.8)')
|
||||
g.addColorStop(1, 'rgba(92, 255, 243, 1)')
|
||||
ctx.strokeStyle = g
|
||||
|
||||
if (this.ratio < 25) {
|
||||
radian = 3 / 2 + angle
|
||||
ctx.arc(x, y, x - 8, Math.PI + Math.PI / 2, Math.PI * radian, false)
|
||||
} else if (this.ratio === 100) {
|
||||
ctx.arc(x, y, x - 8, 0, Math.PI * 2)
|
||||
} else {
|
||||
radian = (this.ratio - 25) / 100 * 2
|
||||
ctx.arc(x, y, x - 8, Math.PI + Math.PI / 2, Math.PI * radian, false)
|
||||
}
|
||||
ctx.stroke()
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.strokeStyle = 'rgba(102, 121, 138, 0.4)'
|
||||
ctx.lineWidth = 1
|
||||
ctx.arc(x, y, x - 15, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.DoughnutChart-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
padding-top: 12px;
|
||||
|
||||
.DoughnutChart-explain {
|
||||
flex: 1;
|
||||
margin-left: 12px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-right: 6px;
|
||||
border-radius: 50%;
|
||||
background: #5AF9F0;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-right: 24px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #9BB7D4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
&:last-child i {
|
||||
background: rgba(102, 121, 138, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.DoughnutChart {
|
||||
position: relative;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
overflow: hidden;
|
||||
|
||||
.DonutChart-text {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
span {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #02FEFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
271
packages/bigscreen/dv/components/DvMap.vue
Normal file
271
packages/bigscreen/dv/components/DvMap.vue
Normal file
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<div class="AiDvMap" v-resize="onDomResize">
|
||||
<div class="chart-map" :class="v" style="width: 100%; height: 100%"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import http from "dui/lib/js/request";
|
||||
|
||||
export default {
|
||||
name: 'AiDvMap',
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
v: `AiDvMap-${new Date().getTime()}`,
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
resize: {
|
||||
bind(el, binding) {
|
||||
let width = ''
|
||||
let height = ''
|
||||
|
||||
function isReize() {
|
||||
const style = document.defaultView.getComputedStyle(el)
|
||||
if (width !== style.width || height !== style.height) {
|
||||
binding.value({
|
||||
width: style.width,
|
||||
height: style.height
|
||||
})
|
||||
}
|
||||
width = style.width
|
||||
height = style.height
|
||||
}
|
||||
|
||||
el.__vueSetInterval__ = setInterval(isReize, 300)
|
||||
},
|
||||
|
||||
unbind(el) {
|
||||
clearInterval(el.__vueSetInterval__)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
onDomResize() {
|
||||
this.$nextTick(() => {
|
||||
this.chart.resize()
|
||||
})
|
||||
},
|
||||
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.querySelector(`.${this.v}`))
|
||||
this.getData().then(res => {
|
||||
if (res.code === 0) {
|
||||
echarts.registerMap('黔西南', res.data)
|
||||
|
||||
let option = {
|
||||
geo: [
|
||||
{
|
||||
map: "黔西南",
|
||||
aspectScale: 1,
|
||||
zoom: 0.65,
|
||||
layoutCenter: ["50%", "50%"],
|
||||
layoutSize: "180%",
|
||||
show: true,
|
||||
roam: false,
|
||||
emphasis: {
|
||||
show: true,
|
||||
label: {
|
||||
textStyle: {
|
||||
color: "#FFFFFF"
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
// areaColor: '#fff'
|
||||
}
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
color: '#fff',
|
||||
fontSize: '15'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderColor: "rgba(2, 254, 255, 0.7)",
|
||||
borderWidth: 2,
|
||||
shadowColor: "rgba(2, 254, 255, 0.1)",
|
||||
shadowOffsetY: 10,
|
||||
shadowBlur: 120,
|
||||
areaColor: "#0f7295",
|
||||
},
|
||||
}
|
||||
},
|
||||
// 重影
|
||||
{
|
||||
type: "map",
|
||||
map: "黔西南",
|
||||
zlevel: -1,
|
||||
aspectScale: 1,
|
||||
zoom: 0.65,
|
||||
layoutCenter: ["50%", "51%"],
|
||||
layoutSize: "180%",
|
||||
roam: false,
|
||||
silent: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderWidth: 1,
|
||||
// borderColor:"rgba(17, 149, 216,0.6)",
|
||||
borderColor: "rgba(2, 254, 255, 0.3)",
|
||||
shadowColor: "rgba(2, 254, 255, 0.3)",
|
||||
shadowOffsetY: 5,
|
||||
shadowBlur: 15,
|
||||
areaColor: "rgba(5,21,35,0.1)",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "map",
|
||||
map: "黔西南",
|
||||
zlevel: -2,
|
||||
aspectScale: 1,
|
||||
zoom: 0.65,
|
||||
layoutCenter: ["50%", "52%"],
|
||||
layoutSize: "180%",
|
||||
roam: false,
|
||||
silent: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderWidth: 1,
|
||||
// borderColor: "rgba(57, 132, 188,0.4)",
|
||||
borderColor: "rgba(2, 254, 255, 0.2)",
|
||||
shadowColor: "rgba(2, 254, 255, 0.24)",
|
||||
shadowOffsetY: 5,
|
||||
shadowBlur: 15,
|
||||
areaColor: "transpercent",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "map",
|
||||
map: "黔西南",
|
||||
zlevel: -3,
|
||||
aspectScale: 1,
|
||||
zoom: 0.65,
|
||||
layoutCenter: ["50%", "53%"],
|
||||
layoutSize: "180%",
|
||||
roam: false,
|
||||
silent: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
borderWidth: 1,
|
||||
// borderColor: "rgba(11, 43, 97,0.8)",
|
||||
borderColor: "rgba(2, 254, 255, 0.1)",
|
||||
shadowColor: "rgba(2, 254, 255, 0.1)",
|
||||
shadowOffsetY: 15,
|
||||
shadowBlur: 10,
|
||||
areaColor: "transpercent",
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'scatter',
|
||||
map: "黔西南",
|
||||
coordinateSystem: 'geo',
|
||||
z: 3,
|
||||
zlevel: 3,
|
||||
// symbol: 'none',
|
||||
symbolSize: 16,
|
||||
rippleEffect: {
|
||||
period: 2,
|
||||
scale: 4,
|
||||
brushType: 'fill'
|
||||
},
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
roam: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: '#000',
|
||||
borderColor: '#a18a3a',
|
||||
borderWidth: 1
|
||||
},
|
||||
emphasis: {
|
||||
show: false,
|
||||
areaColor: null
|
||||
}
|
||||
},
|
||||
// label: {
|
||||
// show: true,
|
||||
// formatter: e => {
|
||||
// const name = e.data[3]
|
||||
// const value = e.data[2]
|
||||
// return `{a|${name}}\n{b|${value}}`
|
||||
// },
|
||||
// fontSize: 16,
|
||||
// rich: {
|
||||
// a: {
|
||||
// width: '100%',
|
||||
// color: '#fff',
|
||||
// lineHeight: 20,
|
||||
// fontSize: 16
|
||||
// },
|
||||
// b: {
|
||||
// backgroundColor: {
|
||||
// // image: require('@/assets/images/point.png')
|
||||
// },
|
||||
// color: '#fff',
|
||||
// height: 56,
|
||||
// align: 'center',
|
||||
// width: 50,
|
||||
// fontSize: 16
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
this.chart.setOption(option)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
convertData(data) {
|
||||
return data.map(v => {
|
||||
return [this.qqMapTransBMap(v.point[1], v.point[0]).lng, this.qqMapTransBMap(v.point[1], v.point[0]).lat, v.value, v.name]
|
||||
})
|
||||
},
|
||||
|
||||
qqMapTransBMap(lng, lat) {
|
||||
const x_pi = 3.14159265358979324 * 3000.0 / 180.0
|
||||
var x = lng
|
||||
var y = lat
|
||||
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi)
|
||||
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi)
|
||||
|
||||
return {
|
||||
lng: z * Math.cos(theta) + 0.0065,
|
||||
lat: z * Math.sin(theta) + 0.006
|
||||
}
|
||||
},
|
||||
|
||||
getData() {
|
||||
return http.post(`/app/appdvcpconfig/apiForward?url=${encodeURIComponent(`https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=522300_full`)}`,)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiDvMap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user