@ -0,0 +1,163 @@
|
||||
<div class="box"> |
||||
<div class="topbox"> |
||||
<div class="top1"> |
||||
<div class="top1-1 fffcard"> |
||||
<div class="top1-1item flexcolumn"> |
||||
<div class="title"> |
||||
任务总数 188个 |
||||
</div> |
||||
<div class="taskNum" id="taskNumCharts"> |
||||
|
||||
</div> |
||||
</div> |
||||
<div class="top1-1item flexcolumn"> |
||||
<div class="title"> |
||||
协助任务数量排名TOP5 |
||||
</div> |
||||
<div class="assistTaskRanking"> |
||||
<div class="taskRankingItem" *ngFor="let item of assistTaskRankingData"> |
||||
<img [src]="item.url" alt=""> |
||||
{{item.name}} |
||||
<div class="border"></div> |
||||
<div class="num"> |
||||
{{item.num}} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="top1-2 fffcard flexcolumn"> |
||||
<div class="title "> |
||||
不合格单位趋势图 |
||||
</div> |
||||
<div class="disqualificationUnit "> |
||||
<div class="searchbox"> |
||||
<div class="searchitem1"> |
||||
<div class="titleblue"> |
||||
27% |
||||
</div> |
||||
<span>9月合格率</span> |
||||
</div> |
||||
<div class="searchitem1"> |
||||
<div class="titlered"> |
||||
121 |
||||
</div> |
||||
<span>9月不合格数量</span> |
||||
</div> |
||||
<!-- <div class="rangepicker"> |
||||
<nz-range-picker></nz-range-picker> |
||||
</div> --> |
||||
</div> |
||||
<div id="disqualificationUnit"> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="top2"> |
||||
<div class="mapcardbox"> |
||||
<div class="mapcarditem" *ngFor="let item of maocard"> |
||||
<div class="mapcarditemname"> |
||||
<span class="mapcarditemname1"> |
||||
{{item.name}} |
||||
</span> |
||||
<span class="mapcarditemname2"> |
||||
{{item.num}} |
||||
</span> |
||||
</div> |
||||
<div class="mapcarditemimg"> |
||||
<img [src]="item.url" alt=""> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="mapbox" id="mapbox"> |
||||
|
||||
</div> |
||||
</div> |
||||
<div class="top3"> |
||||
<div class="top3-1 fffcard flexcolumn"> |
||||
<div class="title "> |
||||
企业支持度排名 |
||||
</div> |
||||
<div class="companySupport"> |
||||
<div class="companySupporttitle"> |
||||
<span> |
||||
消防机构 |
||||
</span> |
||||
<span> |
||||
支持度 |
||||
</span> |
||||
</div> |
||||
<div class="rankingListBox"> |
||||
<div class="rankingListItem" *ngFor="let item of rankingList1"> |
||||
<div class="name" [title]="item.name"> |
||||
{{item.name}} |
||||
</div> |
||||
<div class="progress"> |
||||
<nz-progress [nzStrokeColor]="'#2C4DC0'" [nzStrokeLinecap]="'square'" |
||||
[nzShowInfo]="false" [nzPercent]="item.num"></nz-progress> |
||||
</div> |
||||
<div class="num"> |
||||
<span>{{item.num}}%</span> |
||||
<ng-container *ngIf="item.type == 'up'; else elseTemplate"> |
||||
<img src="../../../../assets/statistic-analysis/up.png" alt=""> |
||||
</ng-container> |
||||
<ng-template #elseTemplate> |
||||
<img src="../../../../assets/statistic-analysis/down.png" alt=""> |
||||
</ng-template> |
||||
<span class="numchange" |
||||
[ngClass]="{'numchangered': item.type == 'down','invariant': item.type == 'invariant','numchangegreen': item.type == 'up'}"> |
||||
{{item.changeNum}} |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="top3-2 fffcard flexcolumn"> |
||||
<div class="title"> |
||||
持证人数排名 |
||||
</div> |
||||
<div class="holdCertificate"> |
||||
<div class="rankingListBox"> |
||||
<div class="rankingListItem" *ngFor="let item of rankingList2"> |
||||
<div class="name" [title]="item.name"> |
||||
{{item.name}} |
||||
</div> |
||||
<div class="progress"> |
||||
<nz-progress [nzStrokeColor]="'#2C4DC0'" [nzStrokeLinecap]="'square'" |
||||
[nzShowInfo]="false" [nzPercent]="item.num"></nz-progress> |
||||
</div> |
||||
<div class="num"> |
||||
<span>{{item.num}}</span> |
||||
<ng-container *ngIf="item.type == 'up'; else elseTemplate"> |
||||
<img src="../../../../assets/statistic-analysis/up.png" alt=""> |
||||
</ng-container> |
||||
<ng-template #elseTemplate> |
||||
<img src="../../../../assets/statistic-analysis/down.png" alt=""> |
||||
</ng-template> |
||||
<span class="numchange" |
||||
[ngClass]="{'numchangered': item.type == 'down','invariant': item.type == 'invariant','numchangegreen': item.type == 'up'}"> |
||||
{{item.changeNum}} |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="bottombox fffcard flexcolumn"> |
||||
<div class="title"> |
||||
任务完成情况 |
||||
</div> |
||||
<div class="completionOfTask"> |
||||
<div class="completionOfTask1" id="completionOfTask1"> |
||||
|
||||
</div> |
||||
<div class="completionOfTask2" id="completionOfTask2"> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,351 @@
|
||||
.box { |
||||
width: 100%; |
||||
height: 100%; |
||||
box-sizing: border-box; |
||||
padding: 18px; |
||||
display: flex; |
||||
flex-direction: column; |
||||
color: #303133; |
||||
text-align: left; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.fffcard { |
||||
background: #fff; |
||||
box-shadow: 0px 3px 8px 1px rgba(0, 0, 0, 0.08); |
||||
border-radius: 4px 4px 4px 4px; |
||||
border: 1px solid #E4E7EC; |
||||
} |
||||
|
||||
|
||||
.flexcolumn { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
|
||||
.taskNum, |
||||
.assistTaskRanking, |
||||
.disqualificationUnit, |
||||
.companySupport, |
||||
.holdCertificate, |
||||
.completionOfTask { |
||||
flex: 1; |
||||
} |
||||
|
||||
.assistTaskRanking { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-around; |
||||
box-sizing: border-box; |
||||
padding: 18px 0 18px 16px; |
||||
|
||||
.taskRankingItem { |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
img { |
||||
margin-right: 3px; |
||||
} |
||||
|
||||
.border { |
||||
flex: 1; |
||||
border-bottom: 1px dashed #E4E7EC; |
||||
margin: 0 3px; |
||||
} |
||||
|
||||
.num { |
||||
width: 50px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.disqualificationUnit { |
||||
display: flex; |
||||
flex-direction: column; |
||||
|
||||
.searchbox { |
||||
width: 100%; |
||||
height: 60px; |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
.searchitem1 { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
box-sizing: border-box; |
||||
padding: 0 18px; |
||||
|
||||
.titleblue { |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
color: #2C4DC0; |
||||
margin-right: 5%; |
||||
} |
||||
|
||||
.titlered { |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
color: #FF0000; |
||||
} |
||||
} |
||||
|
||||
.rangepicker { |
||||
height: 32px; |
||||
width: 45%; |
||||
text-align: right; |
||||
margin-left: 10%; |
||||
} |
||||
} |
||||
|
||||
#disqualificationUnit { |
||||
flex: 1; |
||||
} |
||||
} |
||||
|
||||
.companySupport, |
||||
.holdCertificate { |
||||
display: flex; |
||||
flex-direction: column; |
||||
overflow: hidden; |
||||
|
||||
.companySupporttitle { |
||||
width: 100%; |
||||
height: 42px; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
color: #C7CAD0; |
||||
box-sizing: border-box; |
||||
padding: 0 18px; |
||||
} |
||||
|
||||
.rankingListBox { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: flex-start; |
||||
box-sizing: border-box; |
||||
padding: 0px 18px; |
||||
padding-bottom: 8px; |
||||
overflow-y: auto; |
||||
|
||||
.rankingListItem { |
||||
display: flex; |
||||
align-items: center; |
||||
margin-bottom: 8px; |
||||
|
||||
.name { |
||||
width: 35%; |
||||
white-space: nowrap; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
margin-right: 8%; |
||||
} |
||||
|
||||
.progress { |
||||
flex: 1; |
||||
margin-bottom: 2px; |
||||
} |
||||
|
||||
.num { |
||||
display: flex; |
||||
align-items: center; |
||||
margin-left: 12%; |
||||
position: relative; |
||||
|
||||
img { |
||||
margin-left: 3px; |
||||
} |
||||
|
||||
.numchange { |
||||
font-size: 14px; |
||||
|
||||
} |
||||
|
||||
.numchangered { |
||||
color: #ff1515; |
||||
} |
||||
|
||||
.numchangegreen { |
||||
color: #58c694; |
||||
} |
||||
.invariant{ |
||||
opacity: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.holdCertificate { |
||||
.rankingListBox { |
||||
padding-bottom: 8px; |
||||
padding-top: 8px; |
||||
} |
||||
} |
||||
|
||||
.completionOfTask { |
||||
display: flex; |
||||
|
||||
.completionOfTask1 { |
||||
flex: 1; |
||||
} |
||||
|
||||
.completionOfTask2 { |
||||
flex: 4.6; |
||||
} |
||||
} |
||||
|
||||
.title { |
||||
width: 100%; |
||||
height: 50px; |
||||
line-height: 50px; |
||||
box-sizing: border-box; |
||||
padding-left: 18px; |
||||
border-bottom: 1px solid #E4E7EC; |
||||
} |
||||
|
||||
.topbox { |
||||
flex: 2; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
margin-bottom: 18px; |
||||
overflow: hidden; |
||||
|
||||
.top1 { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
|
||||
.top1-1 { |
||||
flex: 1; |
||||
margin-bottom: 18px; |
||||
display: flex; |
||||
|
||||
.top1-1item { |
||||
flex: 1; |
||||
} |
||||
} |
||||
|
||||
.top1-2 { |
||||
flex: 1.3; |
||||
} |
||||
} |
||||
|
||||
.top2 { |
||||
flex: 1.5; |
||||
margin: 0 18px; |
||||
position: relative; |
||||
|
||||
.mapcardbox { |
||||
position: absolute; |
||||
left: 0; |
||||
top: 18px; |
||||
height: 100px; |
||||
width: 100%; |
||||
z-index: 999; |
||||
display: flex; |
||||
padding: 0 18px; |
||||
box-sizing: border-box; |
||||
|
||||
.mapcarditem { |
||||
flex: 1; |
||||
height: 100%; |
||||
background: #FFFFFF; |
||||
box-shadow: 0px 3px 8px 1px rgba(0, 0, 0, 0.08); |
||||
border-radius: 4px 4px 4px 4px; |
||||
border: 1px solid #E4E7EC; |
||||
box-sizing: border-box; |
||||
padding: 16px; |
||||
display: flex; |
||||
|
||||
.mapcarditemname { |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-between; |
||||
|
||||
.mapcarditemname1 { |
||||
font-size: 16px; |
||||
} |
||||
|
||||
.mapcarditemname2 { |
||||
font-size: 26px; |
||||
font-weight: 600; |
||||
} |
||||
} |
||||
|
||||
.mapcarditemimg { |
||||
width: 68px; |
||||
height: 68px; |
||||
border-radius: 68px; |
||||
text-align: center; |
||||
line-height: 68px; |
||||
} |
||||
} |
||||
|
||||
.mapcarditem:nth-child(1) { |
||||
.mapcarditemname2 { |
||||
color: #2C4DC0; |
||||
} |
||||
|
||||
.mapcarditemimg { |
||||
background: linear-gradient(to bottom, #94ACFF, #2C4DC0); |
||||
} |
||||
} |
||||
|
||||
.mapcarditem:nth-child(2) { |
||||
margin: 0 18px; |
||||
|
||||
.mapcarditemname2 { |
||||
color: #FF0000; |
||||
} |
||||
|
||||
.mapcarditemimg { |
||||
background: linear-gradient(to bottom, #FF9191, #FF0000); |
||||
} |
||||
} |
||||
|
||||
.mapcarditem:nth-child(3) { |
||||
.mapcarditemname2 { |
||||
color: #42B983; |
||||
} |
||||
|
||||
.mapcarditemimg { |
||||
background: linear-gradient(to bottom, #AFF8D7, #42B983); |
||||
} |
||||
} |
||||
} |
||||
|
||||
.mapbox { |
||||
width: 100%; |
||||
height: 100%; |
||||
box-shadow: 0px 3px 8px 1px rgba(0, 0, 0, 0.08); |
||||
border-radius: 4px 4px 4px 4px; |
||||
border: 1px solid #E4E7EC; |
||||
} |
||||
} |
||||
|
||||
.top3 { |
||||
flex: .8; |
||||
display: flex; |
||||
flex-direction: column; |
||||
overflow: hidden; |
||||
|
||||
.top3-1 { |
||||
flex: 1.1; |
||||
margin-bottom: 18px; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.top3-2 { |
||||
flex: 1; |
||||
overflow: hidden; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.bottombox { |
||||
flex: 0.9; |
||||
} |
@ -0,0 +1,474 @@
|
||||
import { HttpClient } from '@angular/common/http'; |
||||
import { Component, OnInit } from '@angular/core'; |
||||
declare var AMap: any; |
||||
declare var AMapUI: any; |
||||
import * as echarts from 'echarts'; |
||||
@Component({ |
||||
selector: 'app-home', |
||||
templateUrl: './home.component.html', |
||||
styleUrls: ['./home.component.scss'] |
||||
}) |
||||
export class HomeComponent implements OnInit { |
||||
|
||||
constructor(private http: HttpClient) { } |
||||
taskNumCharts |
||||
taskNumChartsOption = { |
||||
title: [ |
||||
{ |
||||
text: `{val|195}\n{name|任务总数}`, |
||||
top: 'center', |
||||
left: '61%', |
||||
textStyle: { |
||||
rich: { |
||||
val: { |
||||
fontSize: 28, |
||||
fontWeight: 'bold', |
||||
color: '#333333' |
||||
}, |
||||
name: { |
||||
fontSize: 14, |
||||
color: '#666666', |
||||
padding: [2, 0] |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
], |
||||
color: ['#5483EA', '#34E0A3', '#E4E7EC'], |
||||
tooltip: { |
||||
trigger: 'item' |
||||
}, |
||||
legend: { |
||||
top: 'center', |
||||
left: '5%', |
||||
itemGap: 15, |
||||
itemWidth: 10, |
||||
itemHeight: 10, |
||||
orient: 'vertical', |
||||
formatter: (name) => { |
||||
let data = this.taskNumChartsOption.series[0].data |
||||
let total = 0 |
||||
let tarValue |
||||
for (let i = 0; i < data.length; i++) { |
||||
total += data[i].value |
||||
if (data[i].name == name) { |
||||
tarValue = data[i].value |
||||
} |
||||
} |
||||
let v = tarValue + '个' |
||||
//计算出百分比
|
||||
// let p = Math.round((tarValue / total) * 100) + '%'
|
||||
return `${name} ${v}` |
||||
//name是名称,v是数值
|
||||
}, |
||||
}, |
||||
|
||||
series: [ |
||||
{ |
||||
|
||||
type: 'pie', |
||||
radius: ['50%', '65%'], |
||||
center: ['72%', '50%'], |
||||
avoidLabelOverlap: false, |
||||
label: { |
||||
show: false, |
||||
position: 'center' |
||||
}, |
||||
labelLine: { |
||||
show: false |
||||
}, |
||||
data: [ |
||||
{ value: 37, name: '上级派发任务' }, |
||||
{ value: 56, name: '自主任务' }, |
||||
{ value: 102, name: '协助任务' } |
||||
] |
||||
} |
||||
] |
||||
}; |
||||
|
||||
disqualificationUnitCharts |
||||
disqualificationUnitChartsOption = { |
||||
grid: { |
||||
left: '8%', |
||||
right: '5%', |
||||
top: '15%', |
||||
bottom: '15%' |
||||
}, |
||||
xAxis: { |
||||
type: 'category', |
||||
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], |
||||
axisTick: { //x轴刻度尺
|
||||
show: false |
||||
}, |
||||
axisLine: {//x轴线条颜色
|
||||
show: false, |
||||
lineStyle: { |
||||
color: '#C7CAD0' |
||||
} |
||||
}, |
||||
}, |
||||
yAxis: { |
||||
type: 'value', |
||||
splitLine: {//网格线
|
||||
lineStyle: { |
||||
type: 'solid', //设置网格线类型 dotted:虚线 solid:实线
|
||||
color: '#ECEFF1' //网格线颜色
|
||||
}, |
||||
}, |
||||
axisLine: {//y轴线条颜色
|
||||
show: false, |
||||
lineStyle: { |
||||
color: '#C7CAD0' |
||||
} |
||||
}, |
||||
}, |
||||
series: [ |
||||
{ |
||||
data: [8, 7, 8, 6, 11, 16, 18, 10, 14, 10, 9, 5], |
||||
type: 'line', |
||||
showSymbol: false,//去除面积图节点圆
|
||||
smooth: true,//面积图改成弧形状
|
||||
areaStyle: { |
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
||||
offset: 0, |
||||
color: 'rgba(84,131,234,0.6)' |
||||
}, { |
||||
offset: 1, |
||||
color: 'rgba(255,255,255,0)' |
||||
}]) |
||||
} |
||||
} |
||||
] |
||||
}; |
||||
|
||||
completionOfTaskPie |
||||
completionOfTaskPieOption = { |
||||
title: [ |
||||
{ |
||||
text: `{val|195}\n{name|任务总数}`, |
||||
top: 'center', |
||||
left: '26%', |
||||
textStyle: { |
||||
rich: { |
||||
val: { |
||||
fontSize: 28, |
||||
fontWeight: 'bold', |
||||
color: '#333333' |
||||
}, |
||||
name: { |
||||
fontSize: 14, |
||||
color: '#666666', |
||||
padding: [2, 0] |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
], |
||||
color: ['#34E0A3', '#E4E7EC'], |
||||
tooltip: { |
||||
trigger: 'item' |
||||
}, |
||||
legend: { |
||||
top: 'center', |
||||
right: '10%', |
||||
itemGap: 15, |
||||
itemWidth: 10, |
||||
itemHeight: 10, |
||||
orient: 'vertical', |
||||
formatter: (name) => { |
||||
let data = this.completionOfTaskPieOption.series[0].data |
||||
let total = 0 |
||||
let tarValue |
||||
for (let i = 0; i < data.length; i++) { |
||||
total += data[i].value |
||||
if (data[i].name == name) { |
||||
tarValue = data[i].value |
||||
} |
||||
} |
||||
let v = tarValue |
||||
//计算出百分比
|
||||
// let p = Math.round((tarValue / total) * 100) + '%'
|
||||
return `${name} ${v}` |
||||
//name是名称,v是数值
|
||||
}, |
||||
}, |
||||
|
||||
series: [ |
||||
{ |
||||
|
||||
type: 'pie', |
||||
radius: ['50%', '65%'], |
||||
center: ['35%', '50%'], |
||||
avoidLabelOverlap: false, |
||||
label: { |
||||
show: false, |
||||
position: 'center' |
||||
}, |
||||
labelLine: { |
||||
show: false |
||||
}, |
||||
data: [ |
||||
{ value: 157, name: '已完成' }, |
||||
{ value: 38, name: '未完成' } |
||||
] |
||||
} |
||||
] |
||||
}; |
||||
|
||||
completionOfTaskBar |
||||
completionOfTaskBarOption = { |
||||
grid: { |
||||
left: '3%', |
||||
right: '7%', |
||||
top: '15%', |
||||
bottom: '20%' |
||||
}, |
||||
legend: { |
||||
top: 'center', |
||||
right: '2%', |
||||
itemGap: 15, |
||||
itemWidth: 10, |
||||
itemHeight: 10, |
||||
orient: 'vertical' |
||||
}, |
||||
tooltip: { |
||||
trigger: 'axis', |
||||
axisPointer: { |
||||
// Use axis to trigger tooltip
|
||||
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
|
||||
} |
||||
}, |
||||
color: ['#34E0A3', '#39CCF4'], |
||||
xAxis: { |
||||
type: 'category', |
||||
data: ['历下区大队', '南部山区大队', '市中区大队', '槐荫区大队', '天桥区大队', '历城区大队', '高新技术产业开发区大队', '长清区大队', '章丘区大队', '平阴县大队', '商河县大队', '济阳县大队', '莱芜区大队'], |
||||
axisTick: { //x轴刻度尺
|
||||
show: false |
||||
}, |
||||
axisLine: {//x轴线条颜色
|
||||
show: false, |
||||
lineStyle: { |
||||
color: '#C7CAD0' |
||||
} |
||||
}, |
||||
axisLabel: { |
||||
show: true, |
||||
interval: 0,//使x轴上的文字显示完全,
|
||||
//设置一行显示几个字,自己设置
|
||||
formatter: function (params) { |
||||
var newParamsName = ""; |
||||
var paramsNameNumber = params.length; |
||||
var provideNumber = 6; |
||||
var rowNumber = Math.ceil(paramsNameNumber / provideNumber); |
||||
if (paramsNameNumber > provideNumber) { |
||||
for (var p = 0; p < rowNumber; p++) { |
||||
var tempStr = ""; |
||||
var start = p * provideNumber; |
||||
var end = start + provideNumber; |
||||
if (p == rowNumber - 1) { |
||||
tempStr = params.substring(start, paramsNameNumber); |
||||
} else { |
||||
tempStr = params.substring(start, end) + "\n"; |
||||
} |
||||
newParamsName += tempStr; |
||||
} |
||||
} else { |
||||
newParamsName = params; |
||||
} |
||||
return newParamsName; |
||||
} |
||||
} |
||||
}, |
||||
yAxis: { |
||||
type: 'value', |
||||
splitLine: {//网格线
|
||||
lineStyle: { |
||||
type: 'solid', //设置网格线类型 dotted:虚线 solid:实线
|
||||
color: '#ECEFF1' //网格线颜色
|
||||
}, |
||||
}, |
||||
axisLine: {//y轴线条颜色
|
||||
show: false, |
||||
lineStyle: { |
||||
color: '#C7CAD0' |
||||
} |
||||
}, |
||||
}, |
||||
series: [ |
||||
{ |
||||
name: '已完成', |
||||
type: 'bar', |
||||
barWidth: 16, // 柱子宽度
|
||||
stack: 'total', |
||||
label: { |
||||
show: false |
||||
}, |
||||
emphasis: { |
||||
focus: 'series' |
||||
}, |
||||
data: [8, 17, 10, 14, 8, 16, 10, 11, 10, 15, 9, 10, 18] |
||||
}, |
||||
{ |
||||
name: '未完成', |
||||
type: 'bar', |
||||
barWidth: 16, // 柱子宽度
|
||||
stack: 'total', |
||||
label: { |
||||
show: false |
||||
}, |
||||
emphasis: { |
||||
focus: 'series' |
||||
}, |
||||
data: [3, 2, 1, 5, 3, 3, 4, 5, 2, 3, 4, 2, 2] |
||||
} |
||||
] |
||||
}; |
||||
|
||||
ngOnInit(): void { |
||||
window.setTimeout(() => { |
||||
this.mapInit() //初始化地图
|
||||
}, 0) |
||||
|
||||
// 任务总数
|
||||
this.taskNumCharts = echarts.init(document.getElementById('taskNumCharts'), null, { devicePixelRatio: 2 }); |
||||
this.disqualificationUnitCharts = echarts.init(document.getElementById('disqualificationUnit'), null, { devicePixelRatio: 2 }); |
||||
this.completionOfTaskPie = echarts.init(document.getElementById('completionOfTask1'), null, { devicePixelRatio: 2 }); |
||||
this.completionOfTaskBar = echarts.init(document.getElementById('completionOfTask2'), null, { devicePixelRatio: 2 }); |
||||
|
||||
this.getData() |
||||
this.echartsSetData() |
||||
} |
||||
|
||||
//获得统计数据
|
||||
getData() { |
||||
this.http.get('/api/PlanTasks/Dashboard').subscribe((data: any) => { |
||||
console.log('统计数据', data) |
||||
}) |
||||
} |
||||
|
||||
echartsSetData() { |
||||
this.taskNumCharts && this.taskNumCharts.setOption(this.taskNumChartsOption); |
||||
this.disqualificationUnitCharts && this.disqualificationUnitCharts.setOption(this.disqualificationUnitChartsOption); |
||||
this.completionOfTaskPie && this.completionOfTaskPie.setOption(this.completionOfTaskPieOption); |
||||
this.completionOfTaskBar && this.completionOfTaskBar.setOption(this.completionOfTaskBarOption); |
||||
} |
||||
|
||||
assistTaskRankingData = [ |
||||
{ name: '济南市消防救援支队', num: 28, url: "../../../../assets/statistic-analysis/one.png" }, |
||||
{ name: '历下区大队', num: 25, url: "../../../../assets/statistic-analysis/two.png" }, |
||||
{ name: '南部山区大队', num: 18, url: "../../../../assets/statistic-analysis/three.png" }, |
||||
{ name: '市中区大队', num: 16, url: "../../../../assets/statistic-analysis/four.png" }, |
||||
{ name: '天桥区大队', num: 15, url: "../../../../assets/statistic-analysis/five.png" } |
||||
] |
||||
|
||||
rankingList1 = [ |
||||
{ name: '济南市消防救援支队', num: 80, type: "up", changeNum: 1 }, |
||||
{ name: '历下区大队', num: 75, type: "down", changeNum: 1 }, |
||||
{ name: '南部山区大队', num: 75, type: "up", changeNum: 2 }, |
||||
{ name: '市中区大队', num: 75, type: "up", changeNum: 1 }, |
||||
{ name: '槐荫区大队', num: 70, type: "up", changeNum: 3 }, |
||||
{ name: '天桥区大队', num: 60, type: "up", changeNum: 1 } |
||||
] |
||||
|
||||
|
||||
rankingList2 = [ |
||||
{ name: '历下区大队', num: 100, type: "up", changeNum: 2 }, |
||||
{ name: '高新技术产业开发区大队', num: 90, type: "down", changeNum: 1 }, |
||||
{ name: '槐荫区大队', num: 88, type: "down", changeNum: 1 }, |
||||
{ name: '天桥区大队', num: 80, type: "up", changeNum: 2 }, |
||||
{ name: '历城区大队', num: 70, type: "up", changeNum: 1 }, |
||||
{ name: '长清区大队', num: 53, type: "up", changeNum: 2 }, |
||||
{ name: '南部山区大队', num: 80, type: "up", changeNum: 1 }, |
||||
{ name: '章丘区大队', num: 70, type: "up", changeNum: 1 }, |
||||
{ name: '平阴县大队', num: 53, type: "down", changeNum: 1 }, |
||||
{ name: '济阳区大队', num: 80, type: "up", changeNum: 1 }, |
||||
{ name: '市中区大队', num: 70, type: "down", changeNum: 2 }, |
||||
{ name: '商河县大队', num: 53, type: "down", changeNum: 3 }, |
||||
{ name: '莱芜区大队', num: 80, type: "down", changeNum: 1 }, |
||||
{ name: '钢城区大队', num: 70, type: "up", changeNum: 3 }, |
||||
{ name: '起步区大队', num: 50, type: "down", changeNum: 2 }, |
||||
{ name: '特勤大队', num: 50, type: "up", changeNum: 2 }, |
||||
] |
||||
|
||||
maocard = [ |
||||
{ name: "重点单位数量", num: 19273, url: '../../../../assets/statistic-analysis/unit.png' }, |
||||
{ name: "不合格单位数量", num: 121, url: '../../../../assets/statistic-analysis/ununit.png' }, |
||||
{ name: "协作任务数量", num: 102, url: '../../../../assets/statistic-analysis/task.png' } |
||||
] |
||||
|
||||
|
||||
map |
||||
mapInit() { |
||||
//创建地图
|
||||
this.map = new AMap.Map('mapbox', { |
||||
cursor: 'default', |
||||
zooms: [8, 16], |
||||
mapStyle: "amap://styles/light", |
||||
// bubble: true
|
||||
}); |
||||
|
||||
let colors = [ |
||||
"#EE30B3", "#B37CF0", "#BD2CE6", "#7768EE", "#359EEF", "#7B95CA", "#CAFBF8", "#43D0E1", |
||||
"#72C6EF" |
||||
]; |
||||
|
||||
AMapUI.loadUI(['geo/DistrictExplorer'], (DistrictExplorer) => { |
||||
|
||||
//创建一个实例
|
||||
let districtExplorer = new DistrictExplorer({ |
||||
map: this.map, |
||||
eventSupport: true, //打开事件支持
|
||||
}); |
||||
|
||||
// let adcode = this.adcode; //行政编码
|
||||
let adcode = 370100 |
||||
|
||||
|
||||
districtExplorer.loadAreaNode(adcode, (error, areaNode) => { |
||||
|
||||
//更新地图视野
|
||||
this.map.setBounds(areaNode.getBounds(), null, null, true); |
||||
|
||||
//设置定位节点,支持鼠标位置识别
|
||||
//注意节点的顺序,前面的高优先级
|
||||
districtExplorer.setAreaNodesForLocating(areaNode); |
||||
|
||||
//清除已有的绘制内容
|
||||
districtExplorer.clearFeaturePolygons(); |
||||
|
||||
//绘制子区域
|
||||
districtExplorer.renderSubFeatures(areaNode, (feature, i) => { |
||||
// console.log(111, feature)
|
||||
let fillColor = colors[i % colors.length]; |
||||
let strokeColor = colors[colors.length - 1 - i % colors.length]; |
||||
return { |
||||
cursor: 'default', |
||||
bubble: true, |
||||
strokeColor: strokeColor, //线颜色
|
||||
strokeOpacity: 1, //线透明度
|
||||
strokeWeight: 1, //线宽
|
||||
fillColor: fillColor, //填充色
|
||||
fillOpacity: 0.8, //填充透明度
|
||||
}; |
||||
}); |
||||
|
||||
//绘制父区域
|
||||
districtExplorer.renderParentFeature(areaNode, { |
||||
cursor: 'default', |
||||
bubble: true, |
||||
strokeColor: 'black', //线颜色
|
||||
strokeOpacity: 1, //线透明度
|
||||
strokeWeight: 1, //线宽
|
||||
fillColor: null, //填充色
|
||||
fillOpacity: 0.5, //填充透明度
|
||||
}); |
||||
|
||||
// 更新地图视野以适合区划面
|
||||
this.map.setFitView(districtExplorer.getAllFeaturePolygons()); |
||||
}); |
||||
|
||||
}); |
||||
|
||||
|
||||
} |
||||
} |
@ -1,4 +1 @@
|
||||
|
||||
<div class="box"> |
||||
<nz-empty></nz-empty> |
||||
</div> |
||||
<router-outlet></router-outlet> |
@ -0,0 +1,31 @@
|
||||
<div class="box"> |
||||
<form nz-form [formGroup]="validateForm"> |
||||
<nz-form-item> |
||||
<nz-form-label [nzSpan]="5" nzFor="result" nzRequired>检查结果</nz-form-label> |
||||
<nz-form-control [nzSpan]="12" nzErrorTip="请选择结果!" style="max-width: 100%;"> |
||||
<nz-select id="result" formControlName="result" nzPlaceHolder="请选择结果"> |
||||
<nz-option nzValue="检查完成" nzLabel="检查完成"></nz-option> |
||||
<nz-option nzValue="未发现违法违规情况" nzLabel="未发现违法违规情况"></nz-option> |
||||
<nz-option nzValue="责令限期改正" nzLabel="责令限期改正"></nz-option> |
||||
<nz-option nzValue="因客观原因无法开展检查" nzLabel="因客观原因无法开展检查"></nz-option> |
||||
</nz-select> |
||||
</nz-form-control> |
||||
</nz-form-item> |
||||
<nz-form-item style="margin-bottom: 0;"> |
||||
<nz-form-label [nzSpan]="5" nzFor="file">上传附件</nz-form-label> |
||||
<div class="uploadbox"> |
||||
<button nz-button [nzLoading]="isLoadingSave"> |
||||
<span nz-icon nzType="upload"></span> |
||||
点击上传 |
||||
</button> |
||||
<input type="file" name="" id="" (change)="filechange($event)" *ngIf="!isLoadingSave"> |
||||
<ul> |
||||
<li *ngFor="let item of fileList;let key = index"> |
||||
<span class="filename" (click)="lookfile(item)">{{item | fileName}}</span> |
||||
<span (click)="delete(fileList,key)">x</span> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</nz-form-item> |
||||
</form> |
||||
</div> |
@ -0,0 +1,49 @@
|
||||
.uploadbox { |
||||
display: flex; |
||||
flex-direction: column; |
||||
position: relative; |
||||
width: 75%; |
||||
white-space: nowrap; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
|
||||
button { |
||||
margin-bottom: 8px; |
||||
width: 110px; |
||||
} |
||||
|
||||
input { |
||||
opacity: 0; |
||||
width: 110px; |
||||
height: 32px; |
||||
position: absolute; |
||||
left: 0; |
||||
top: 0; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
ul { |
||||
margin-bottom: 0; |
||||
|
||||
li { |
||||
|
||||
display: flex; |
||||
justify-content: space-between; |
||||
span{ |
||||
cursor: pointer; |
||||
} |
||||
.filename { |
||||
flex: 1; |
||||
display: inline-block; |
||||
white-space: nowrap; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
|
||||
.filename:hover { |
||||
text-decoration: underline; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,139 @@
|
||||
import { HttpClient } from '@angular/common/http'; |
||||
import { Component, Input, OnInit } from '@angular/core'; |
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; |
||||
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; |
||||
import { ObjectsSimpleService } from 'src/app/service/objectsSimple.service'; |
||||
import Viewer from 'viewerjs'; |
||||
@Component({ |
||||
selector: 'app-upload', |
||||
templateUrl: './upload.component.html', |
||||
styleUrls: ['./upload.component.scss'] |
||||
}) |
||||
export class UploadComponent implements OnInit { |
||||
@Input() data?: any; |
||||
validateForm!: FormGroup; |
||||
constructor(private modal: NzModalRef, private fb: FormBuilder, private http: HttpClient, private objectsSrv: ObjectsSimpleService, private modal2: NzModalService) { } |
||||
|
||||
ngOnInit(): void { |
||||
console.log(this.data) |
||||
this.data.resultAttachment ? this.fileList = this.data.resultAttachment : this.fileList = [] |
||||
this.validateForm = this.fb.group({ |
||||
result: [this.data.inspectionResult, [Validators.required]], |
||||
}); |
||||
} |
||||
destroyModal(): void { |
||||
this.modal.destroy({ data: 'this the result data' }); |
||||
} |
||||
|
||||
|
||||
fileList = [] |
||||
|
||||
isLoadingSave: boolean = false |
||||
uploadIndex: string |
||||
filechange(e) { |
||||
this.isLoadingSave = true |
||||
let file = e.target.files[0] || null //获取上传的文件
|
||||
this.openFileSelect(file, `resultAttachment/${this.data.id}/`) |
||||
} |
||||
//设置文件路径并上传
|
||||
postFilePath |
||||
async openFileSelect(file: File, extensionPath: string) { |
||||
this.postFilePath = extensionPath; |
||||
let fileSize = file.size || null //上传文件的总大小
|
||||
let shardSize = 5 * 1024 * 1024 //5MB 超过5MB要分块上传
|
||||
if (fileSize >= shardSize) // 超过5MB要分块上传
|
||||
{ |
||||
await this.postFileByMul(file); |
||||
} |
||||
else //普通上传
|
||||
{ |
||||
await this.postFile(file); |
||||
} |
||||
} |
||||
//上传文件
|
||||
async postFile(file: File) { |
||||
await new Promise((resolve, reject) => { |
||||
this.objectsSrv.postFile(this.postFilePath, file).subscribe(data => { |
||||
let dataObj = data as any; |
||||
let filePath: string = ObjectsSimpleService.baseUrl + dataObj.objectName; |
||||
this.fileList.push(filePath) |
||||
this.isLoadingSave = false |
||||
resolve('success') |
||||
}); |
||||
}) |
||||
} |
||||
|
||||
/** |
||||
* 分块上传 |
||||
* @param file
|
||||
*/ |
||||
postFileByMul(file: File) { |
||||
this.objectsSrv.postFile_MultipartUpload(this.postFilePath, file).then((value) => { |
||||
let dataObj = value as any; |
||||
let filePath = dataObj.filePath |
||||
this.fileList.push(filePath) |
||||
this.isLoadingSave = false |
||||
}); |
||||
|
||||
} |
||||
//获取文件格式
|
||||
getFileType(name: string): string { |
||||
let suffix |
||||
if (name.substring(name.length - 4).includes('png') || name.substring(name.length - 4).includes('jpg') || name.substring(name.length - 4).includes('jpeg') || name.substring(name.length - 4).includes('webp')) { |
||||
suffix = 'img' |
||||
} else if (name.substring(name.length - 4).includes('doc') || name.substring(name.length - 4).includes('docx')) { |
||||
suffix = 'word' |
||||
} else if (name.substring(name.length - 4).includes('pdf')) { |
||||
suffix = 'pdf' |
||||
} |
||||
return suffix |
||||
} |
||||
|
||||
lookfile(item) { |
||||
if (!item) { |
||||
return |
||||
} |
||||
if (this.getFileType(item) == 'word') { |
||||
let arr = item.split('.') |
||||
arr[arr.length - 1] = 'pdf' |
||||
window.open(arr.join('.')) |
||||
} else if (this.getFileType(item) == 'pdf') { |
||||
window.open(item) |
||||
} else { |
||||
this.viewImg(item) |
||||
} |
||||
} |
||||
|
||||
|
||||
//查看图片
|
||||
viewImg(url) { |
||||
let dom = document.getElementById(`viewerjs`) |
||||
let pObjs = dom.childNodes; |
||||
let node = document.createElement("img") |
||||
node.style.display = "none"; |
||||
node.src = url; |
||||
node.id = 'img' |
||||
dom.appendChild(node) |
||||
setTimeout(() => { |
||||
let viewer = new Viewer(document.getElementById(`viewerjs`), { |
||||
hidden: () => { |
||||
dom.removeChild(pObjs[0]); |
||||
viewer.destroy(); |
||||
} |
||||
}); |
||||
node.click(); |
||||
}, 0); |
||||
} |
||||
delete(fileList, key) { |
||||
this.modal2.confirm({ |
||||
nzTitle: `确定要删除这个文件吗?`, |
||||
nzOkText: '确定', |
||||
nzOkType: 'primary', |
||||
nzOnOk: () => { |
||||
fileList.splice(key, 1) |
||||
}, |
||||
nzCancelText: '取消' |
||||
}); |
||||
|
||||
} |
||||
} |
@ -1,17 +0,0 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'; |
||||
/* |
||||
* Raise the value exponentially |
||||
* Takes an exponent argument that defaults to 1. |
||||
* Usage: |
||||
* value | exponentialStrength:exponent |
||||
* Example: |
||||
* {{ 2 | exponentialStrength:10 }} |
||||
* formats to: 1024 |
||||
*/ |
||||
@Pipe({ name: 'cameraType' }) |
||||
export class cameraType implements PipeTransform { |
||||
transform(value: number): string { |
||||
let arr = ['进出口', '加油区', '卸油区', '便利店'] |
||||
return arr[value] |
||||
} |
||||
} |
@ -0,0 +1,9 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'; |
||||
|
||||
@Pipe({ name: 'fileName' }) |
||||
export class fileName implements PipeTransform { |
||||
transform(value: string): string { |
||||
let a = value.split('/')[value.split('/').length - 1] |
||||
return a |
||||
} |
||||
} |
After Width: | Height: | Size: 640 B |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1012 B |
After Width: | Height: | Size: 480 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 536 B |
After Width: | Height: | Size: 751 B |
After Width: | Height: | Size: 404 B |