【add】-首页增加大屏模块的代码

This commit is contained in:
fengchenchen
2023-03-20 15:56:44 +08:00
parent 497e676234
commit 115411a50a
36 changed files with 4453 additions and 2 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

+135 -2
View File
@@ -1,9 +1,27 @@
<template>
<div style="min-width: 1100px" class="analysis-container">
<div class="location-icon">
<a-dropdown overlayClassName="screen-dropdown-box">
<img src="../../assets/screenNew/icon_location.png" alt="">
<template #overlay>
<a-menu>
<a-menu-item
v-for="item in menuData"
:key="item.value"
>
<a :href="'#' + item.href">{{ item.name }}</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
<div class="screen-btn">
<!-- v-has="'dashboard:screen'"-->
<a-button type="primary" @click="goScreen">大屏</a-button>
</div>
<!--只是单纯的用于定位-->
<div id="income"></div>
<!-- 其他人展示消息-->
<template v-if="roleCoe">
<user-announcement-list :is-show-seach="true"></user-announcement-list>
@@ -48,7 +66,32 @@
<!-- 企业客户统计年度待确收金额前二十-->
</template>
<!-- 所领导 部门领导展示统计图 -->
<!--大屏模块的信息-->
<template>
<!-- 制修订 -->
<template>
<div class="first-title" id="preparationRevisionScreen">
制修订
</div>
<preparation-revision-screen></preparation-revision-screen>
</template>
<!-- 中国汽车国际法规工作平台-ISO-->
<template>
<div class="first-title" id="ISO">
ISO
</div>
<i-s-o-screen></i-s-o-screen>
</template>
<!-- 中国汽车国际法规工作平台-WP.29 -->
<template>
<div class="first-title" id="WP">
WP.29
</div>
<w-p-screen></w-p-screen>
</template>
</template>
</div>
</template>
@@ -63,6 +106,11 @@ import AllMoneyTenEcharts from '@views/dashboard/AllMoneyTenEcharts'
import ThreeYearEcharts from '@views/dashboard/ThreeYearEcharts'
import NotReceivedEcharts from '@views/dashboard/NotReceivedEcharts'
import PreparationRevisionScreen from './screen/preparationRevision/index'
import WPScreen from './screen/wp29/index'
import ISOScreen from './screen/iso/index'
export default {
name: 'Analysis',
components: {
@@ -73,7 +121,11 @@ export default {
IncomeSortEcharts,
AllMoneyTenEcharts,
ThreeYearEcharts,
NotReceivedEcharts
NotReceivedEcharts,
// 大屏模块的组件
PreparationRevisionScreen,
WPScreen,
ISOScreen
},
computed: {
// 所领导 部门负责人 还是其他角色
@@ -82,7 +134,14 @@ export default {
}
},
data() {
return {}
return {
menuData: [
{name: '汽车标准化工作平台', value: '1', href: 'income'},
{name: '汽车标准制修订管理系统', value: '2', href: 'preparationRevisionScreen'},
{name: '中国汽车国际标准工作平台-ISO', value: '3', href: 'ISO'},
{name: '中国汽车国际法规工作平台-WP.29', value: '4', href: 'WP'}
]
}
},
created() {
console.log()
@@ -178,4 +237,78 @@ export default {
display: flex;
justify-content: flex-end;
}
// 大屏模块的样式增加
/* 右侧定位的按钮*/
.location-icon{
position: fixed;
z-index: 200;
top: 165px;
right: 10px;
cursor: pointer;
//background-color: rgba(6, 159, 153, 0.2);
//border-radius: 50%;
img{
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 50%;
}
}
// 大标题
.first-title {
height: 60px;
line-height: 60px;
background: #FFFFFF;
border-radius: 1px;
margin: 10px 0 0;
padding: 0 20px;
&::before {
content: "";
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: #069F99;
vertical-align: middle;
margin-right: 8px;
}
}
// 面板的标题
/deep/.panel-box {
background: #FFFFFF;
border-radius: 4px;
margin-top: 10px;
.panel-title {
height: 58px;
box-shadow: 0 2px 9px 0 rgba(5,5,37,0.04);
border-radius: 2px 2px 0 0;
padding: 0 32px;
line-height: 58px;
font-size: 0px;
font-family: PingFang SC;
font-weight: 500;
color: #050525;
position: relative;
img {
width: 18px;
height: 18px;
margin-right: 11px;
vertical-align: middle;
}
& > span {
font-size: 18px;
display: inline-block;
vertical-align: middle;
}
}
.panel-content {
padding: 32px;
}
}
/deep/.full-box{
width: 100%;
}
</style>
@@ -0,0 +1,177 @@
<!--国际专家统计-->
<template>
<div class="panel-box full-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_expert.png" alt="">
<span>国际专家统计</span>
<div class="title-right-sub">
<span>专家总数</span>
<span class="num">{{totalAll}}</span>
</div>
</div>
<div class="select-info-box">
</div>
<div class="panel-content">
<div class="search-select-box">
<!--@change="fieldSelectChange"-->
<span>技术领域</span>
<a-select
class="right-select active"
style='width: 300px'
v-model="searchParams.field"
mode="multiple"
placeholder="请选择技术领域"
:bordered="false"
:maxTagCount="1"
show-search
:filter-option="filterOption"
dropdown-class-name="ant-select-screen-new"
>
<a-select-option
v-for="(item, index) in fieldOptionData"
:key="index + item.orgCode"
:value="item.orgCode"
>
{{item.departName}}
</a-select-option>
</a-select>
<a-button type="primary" icon="search" @click="fieldSelectChange">查询</a-button>
<a-button icon="reload" @click="searchReset" class="reset-button">重置</a-button>
</div>
<div class="echarts-box " id="isoExpertChart"></div>
</div>
</div>
</template>
<script>
import { GetExpertChartData, GetTechnicalFieldData } from '@/screenApi/api'
import { createLineChart } from '../util/LineOptions'
export default {
name: 'ExpertChart',
data() {
return {
searchParams: {},
totalAll: '',
fieldOptionData: [], // 技术领域的下拉框数据
}
},
methods: {
getData() {
// 技术领域的参数值: orgCode: 后面是逗号分隔
let params = {}
if(this.searchParams.field && this.searchParams.field.length > 0) {
params.orgCode = this.searchParams.field.join()
}
GetExpertChartData(params).then(res => {
if(res.success) {
let data = res.result || {}
this.$nextTick(() => {
this.initChart(data)
})
}
})
},
/**
* count: 112
leftDate: ["第一季度", "第二季度", "第三季度", "第四季度"]
resultMapList: []
0: {orgName: "国际注册专家", count: ["89", "102", "108", "111"]}
1: {orgName: "国内支撑专家", count: ["0", "1", "1", "1"]}
* @param data
*/
initChart(data) {
let xData = data.leftDate
let echartsData = data.resultMapList || []
let totalAll = echartsData.reduce((pre, val) => {
// 取最后一个季度的数据算出总数
let innerNum = val.count[val.count.length - 1]
return Number(pre) + Number(innerNum)
}, 0)
this.totalAll = totalAll
let option = {
xAxis: {
data: xData,
},
series: [
{
data: echartsData[0].count
},
{
data: echartsData[1].count
}
]
}
createLineChart('isoExpertChart', option, true)
},
getOptionData() {
/*{departName: "SAG", orgCode: "A01A01"}*/
GetTechnicalFieldData().then(res => {
if(res.success) {
this.fieldOptionData = res.result.departList || []
}
})
},
// 下拉框发生改变
fieldSelectChange() {
this.getData()
},
// 重置
searchReset() {
this.searchParams.field = undefined
this.getData()
},
// 下拉框的搜索
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
)
},
},
created() {
this.getData()
this.getOptionData()
}
}
</script>
<style scoped lang="less">
@white: #fff;
.title-right-sub {
position: absolute;
right: 32px;
top: 0;
span {
font-size: 16px;
color: #050525;
display: inline-block;
vertical-align: middle;
//text-shadow: 0 0 5px #88D8FB;
}
span.num {
font-size: 20px;
color: #FA9D81;
}
}
.panel-content{
height: 483px;
display: flex;
flex-direction: column;
.echarts-box{
flex: 1;
width: 100%;
}
}
.search-select-box{
button {
margin-left: 15px;
}
}
</style>
@@ -0,0 +1,262 @@
<!--中国牵头标准信息统计-->
<template>
<div class="panel-box full-box iso-full-table">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>中国牵头标准信息统计</span>
</div>
<div class="panel-content">
<a-table
ref="table"
size="middle"
bordered
rowKey="projectId"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:scroll="{x: 1200, y: 540}"
@change="handleTableChange"
class="j-table-force-nowrap main-table iso-table">
<template slot="text" slot-scope="text">
<a-tooltip>
<template slot="title">{{ text }}</template>
<div class="table-text">{{ text }}</div>
</a-tooltip>
</template>
<span v-for="item in columns" :slot="item.dataIndex" :key="item.dataIndex">
<j-ellipsis :length="7" :value=" item[item.dataIndex] "></j-ellipsis>
</span>
<template slot="standard-name" slot-scope="text, record">
<a-tooltip>
<template slot="title">
<div>{{ record.standardNameChinese }}</div>
<div>{{ record.standardNameEnglish }}</div>
</template>
<div class="name-div-inner">
<div class="">{{ record.standardNameChinese }}</div>
<div class="">{{ record.standardNameEnglish }}</div>
</div>
</a-tooltip>
</template>
</a-table>
</div>
</div>
</template>
<script>
import { GetLeadingStandardData } from '@/screenApi/api'
const defaultSorter = {
column: 'createTime',
order: 'desc'
}
export default {
name: 'LeadingStandardChart',
data() {
return {
columns: [
{
title: '序号',
dataIndex: 'rowIndex',
width: 70,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '标准号',
align: 'center',
dataIndex: 'standardNumber',
width: '200px',
scopedSlots: {customRender: 'text'},
},
{
title: '标准名称',
align: 'center',
width: '500px',
dataIndex: 'standardName',
scopedSlots: { customRender: 'standard-name' }
},
{
title: '技术领域',
align: 'center',
dataIndex: 'technosphere',
scopedSlots: { customRender: 'text' }
},
{
title: '牵头单位',
align: 'center',
dataIndex: 'unit',
scopedSlots: { customRender: 'text' }
},
{
title: '目前状态',
align: 'center',
dataIndex: 'stageDescribe',
scopedSlots: { customRender: 'text' }
}
],
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 5,
pageSizeOptions: ['5', '10'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: false,
total: 0
},
/* 排序参数 */
isorter: {
column: 'createTime',
order: 'desc'
},
/* table加载状态 */
loading: false
}
},
methods: {
getData(arg) {
if (arg === 1) {
this.ipagination.current = 1
}
let param = Object.assign({}, this.isorter)
param.pageNo = this.ipagination.current
param.pageSize = this.ipagination.pageSize
this.loading = true
GetLeadingStandardData(param).then((res) => {
if (res.success) {
this.dataSource = res.result.records || res.result
if (res.result.total) {
this.ipagination.total = res.result.total
} else {
this.ipagination.total = 0
}
this.operateData(this.dataSource)
}
if (res.code === 510) {
this.$message.warning(res.message)
}
this.loading = false
}).finally(() => {
this.loading = false
})
},
// 操作表格中的数据
operateData(data) {
data.map(tt => {
tt.technosphere = `${tt.technosphereSc_dictText || ''} ${tt.technosphereWg_dictText || ''}`
tt.standardNumber = `ISO ${tt.standardNumber}`
if(tt.standardYear) {
tt.standardNumber = `${tt.standardNumber}${tt.standardYear}`
}
if(tt.supplement) {
tt.standardNumber = `${tt.standardNumber} / ${tt.supplement}`
}
// tt.standardNameChinese = '评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标评价标准评价标准十个'
// tt.standardNameEnglish = '评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个'
// tt.standardNameChinese = '评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个评价标准评价标准十个'
})
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field
if (sorter.order) {
// 如果当前有列选中筛选条件
this.isorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
} else {
// 没有筛选值则 isorter 重置为初始值
this.isorter.column = defaultSorter.column
this.isorter.order = defaultSorter.order
}
} else {
this.isorter.column = defaultSorter.column
this.isorter.order = defaultSorter.order
}
this.ipagination = pagination
this.getData()
}
},
created() {
this.getData()
}
}
</script>
<style scoped lang="less">
/deep/ .ant-table-body > table{
color: #050525;
}
// 表格样式的修改
/deep/ .ant-table-thead tr > th {
font-weight: bold;
background: transparent;
padding-bottom: 20px;
}
/deep/ .ant-table-tbody tr > td {
padding: 10px 8px!important;
.name-div-inner{
min-height: 84px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
div{
width: 100%;
white-space: pre-wrap;
word-break: break-word;
}
}
}
/deep/.ant-empty-description{
color: #050525;
}
// 高度必须固定否则没有办法出滚动条
.iso-full-table.full-box{
//height: 810px;
padding-top: 0;
.panel-content{
padding-bottom: 10px;
}
}
::v-deep .ant-table-bordered.ant-table-fixed-header .ant-table-scroll .ant-table-header.ant-table-hide-scrollbar .ant-table-thead > tr:only-child > th:last-child{
border-right-color: #e8e8e8;
}
.iso-table{
width: 100%;
height: 100%;
}
.table-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/*表格滚动条*/
/deep/.ant-table-body {
overflow-x: auto!important;
overflow-y: auto!important;
}
/deep/ .ant-table-header{
overflow: hidden!important;
height: 55px;
}
</style>
@@ -0,0 +1,361 @@
<!--iso-国际会议统计-->
<template>
<div class="panel-box full-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_meeting.png" alt="">
<span>国际会议统计</span>
<div class='header-num'>
<span>会议总数</span>
<span class='num'>{{this.scheduleList.length}}</span>
</div>
</div>
<div class="panel-content">
<div class="content-header">
<img class="header-img" @click="prev" src="../../../../assets/screenNew/calendar_left_icon.png" alt="">
<span class="header-text">{{ time }}主要会议安排</span>
<img class="header-img" @click="next" src="../../../../assets/screenNew/calendar_right_icon.png" alt="">
</div>
<div class="header-right">
<div class="header-right-text">
<span class="radius" style="background:#069F99"></span>
<span class="text">TC 22</span>
</div>
<div class="header-right-text">
<span class="radius" style="background:#6C9DA3"></span>
<span class="text">SC</span>
</div>
<div class="header-right-text">
<span class="radius" style="background:#B1CAC5"></span>
<span class="text">WG</span>
</div>
</div>
<full-calendar ref="fullCalendar" style="height: 100%" :options="calendarOptions"></full-calendar>
</div>
</div>
</template>
<script>
import { GetISOMeetingCalendarData } from '@/screenApi/api'
// 引入日历组件
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import tippy from 'tippy.js'
export default {
name: 'MeetingCalendar',
components: {
FullCalendar
},
data() {
return {
calendarOptions: {
// timeGridPlugin 可显示每日时间段
height: 700,
// contentHeight: 'auto',
plugins: [dayGridPlugin, interactionPlugin],
headerToolbar: null,
firstDay: 0,
editable: false,
selectable: false,
navLinks: false,
// displayEventEnd: true,//所有视图显示结束时间
initialView: 'dayGridMonth', // 设置默认显示月,可选周、日
// dateClick: this.handleDateClick,
// eventClick: this.handleEventClick,
eventMouseEnter: this.eventMouseoverOne,
eventMouseLeave: this.eventMouseoutOne,
// timezone
// 设置日程
events: [],
eventColor: '#f08f00', // 修改日程背景色
weekNumberCalculation: 'ISO', // 周数
fixedWeekCount: false, //月份 固定周数
customButtons: {}
},
scheduleList: [],
time: '',
calendarApi: {}
}
},
methods: {
getData() {
let query = {
// orgCode: this.orgCode,
// cutTime: ''
}
GetISOMeetingCalendarData(query).then((res) => {
if (res.success) {
this.scheduleList = res.result || []
this.getReservationList(res.result)
} else {
this.scheduleList = []
}
})
},
prev() {
this.calendarApi.prev()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
},
// 切换下一个按钮事件
next() {
this.calendarApi.next()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
},
// 点击今天按钮
today() {
this.calendarApi.today()
},
handleDateClick: function(arg) {
this.$forceUpdate()
console.log(arg, '事件1')
},
getReservationList(arrayData) {
let newArr = []
arrayData.forEach((item) => {
if (item.orgType === 'TC22') {
item.status = '#069F99'
item.textColor = '#FFFFFF'
} else if (item.orgType === 'SC') {
item.status = '#47858C'
item.textColor = '#FFFFFF'
} else {
item.status = '#9DBDB7'
item.textColor = '#FFFFFF'
}
newArr.push({
start: this.dealWithTime(item.time),
end: this.addDate(this.dealWithTime(item.endTime), 1),
color: item.status,
textColor: item.textColor,
id: item.meetingId,
title: `${item.name}`
})
})
this.calendarOptions.events = newArr
},
getShowTime(beginDate, endDate) {
this.form.startDate = this.dealWithTime(beginDate)
this.form.startTime = this.getHoursMin(beginDate)
this.form.endDate = this.dealWithTime(endDate)
this.form.endTime = this.getHoursMin(endDate)
},
// 获取时分时间
getHoursMin(value) {
return value.substring(11, 16)
},
// 处理会议时间格式
dealWithTime(date) {
let newDate = /\d{4}-\d{1,2}-\d{1,2}/g.exec(date)[0]
return newDate
},
// 日期加1天
addDate(date, days) {
var d = new Date(date)
d.setDate(d.getDate() + days)
var mon = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1
let endD = d.getDate() < 10 ? '0' + d.getDate() : d.getDate()
return `${d.getFullYear()}-${mon}-${endD}`
},
eventMouseoverOne(data) {
let content = this.scheduleList.filter(res => {
return res.meetingId == data.event.id
})
//todo 缺一个type的字段
tippy(data.el, {
content:
'<div class="tippy-content-box-new" style="">' +
'<span style="margin-right: 10px;" class="text-index">' + content[0].orgType + '</span>' + '<span class="text-index">' + content[0].name + '</span>' +
'<div class="tippy-content">技术领域: ' + content[0].type + '</div>' + '' +
'<div class="tippy-content">时间: ' + content[0].timeAll + '</div>' + '' +
'<div class="tippy-content">地点: ' + content[0].place + '</div>' +
'<div class="tippy-content">参会人: ' + content[0].meetingPersons + '</div>' + '</div>',
interactive: false,
// placement: 'top',
allowHTML: true
})
},
eventMouseoutOne() {
},
// 获取会议事件title
getTitle(date1, date2) {
let start = date1.substring(11, 16)
let end = date2.substring(11, 16)
return `${start}~${end}`
}
},
created() {
// 获取用户信息
this.$nextTick(() => {
this.calendarApi = this.$refs.fullCalendar.getApi()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
})
// this.getReservationList(this.scheduleList)
this.getData()
},
}
</script>
<style scoped lang="less">
@white: #fff;
@normal-color: #050525;
.content-header {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
margin-bottom: 20px;
}
.header-img {
width: 28px;
height: 28px;
cursor: pointer;
}
.header-text {
font-size: 20px;
font-family: PingFang SC;
font-weight: 800;
color: #069F99;
margin-left: 26px;
margin-right: 26px;
}
.header-right {
display: flex;
justify-content: flex-end;
align-items: center;
transform: translateY(-35px);
height: 0;
}
.header-right-text {
display: flex;
align-items: center;
margin-left: 28px;
}
.radius {
width: 14px;
height: 14px;
border-radius: 4px;
display: inline-block;
}
.text {
font-size: 14px;
font-family: PingFang SC;
font-weight: 500;
color: #333333;
margin-left: 8px;
}
.header-num{
position: absolute;
right: 32px;
top: 0;
span {
font-size: 16px;
color: #050525;
display: inline-block;
vertical-align: middle;
}
span.num {
font-size: 20px;
color: #FA9D81;
}
}
/*日历组件的修改 */
::v-deep .fc-theme-standard td,
::v-deep.fc-theme-standard .fc-scrollgrid,
::v-deep .fc-theme-standard th{
border-color: #E9E9E9;
}
::v-deep .fc-daygrid-day .fc-daygrid-day-number {
font-weight: bold;
font-size: 14px;
margin-right: 6px;
}
// 周日和周六的颜色不同
::v-deep .fc-day-sun .fc-col-header-cell-cushion ,
::v-deep .fc-day-sat .fc-col-header-cell-cushion {
color: #9E0000;
}
::v-deep .fc-day-other {
background: #F1F1F1;
.fc-daygrid-day-number {
color: @normal-color;
font-size: 14px;
margin-right: 6px;
}
}
::v-deep .fc-col-header-cell-cushion {
font-size: 14px;
font-family: PingFang SC;
font-weight: bold;
color: @normal-color;
}
::v-deep .fc-col-header-cell {
height: 38px;
line-height: 38px;
background-color: #FCFBFB;
}
::v-deep .fc-event-main {
padding: 2px 10px;
}
::v-deep .fc-toolbar-chunk .fc-button-primary {
display: none;
}
::v-deep .fc .fc-daygrid-day.fc-day-today{
background-color: rgba(6, 159, 153, 0.1);
}
::v-deep .fc-event-title{
font-weight: 800!important;
}
</style>
<style lang="less">
.tippy-content-box-new {
background: #fff;
color: #050525;
border-radius: 6px;
padding: 12px;
box-sizing: border-box;
box-shadow: 0 2px 9px 0 rgba(5,5,37,0.04);
.text-index {
font-size: 16px;
font-family: PingFang SC;
font-weight: 800;
color: #050525;
}
.tippy-content {
font-size: 14px;
font-family: PingFang SC;
font-weight: 500;
color: #050525;
margin-top: 8px;
}
}
</style>
+41
View File
@@ -0,0 +1,41 @@
<template>
<div class="screen-iso">
<!-- 中国牵头标准信息统计 -->
<leading-standard-chart></leading-standard-chart>
<!-- 国际会议统计-->
<meeting-calendar></meeting-calendar>
<!-- 国际专家统计-->
<expert-chart></expert-chart>
</div>
</template>
<script>
//中国牵头标准信息统计
import LeadingStandardChart from './LeadingStandardChart'
// //国际会议统计
import MeetingCalendar from './MeetingCalendar'
// //国际专家统计
import ExpertChart from './ExpertChart'
export default {
name: 'index',
components: {
// 中国牵头标准信息统计
LeadingStandardChart,
// 国际会议统计
MeetingCalendar,
// 国际专家统计
ExpertChart
}
}
</script>
<style scoped lang="less">
.screen-iso{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
</style>
@@ -0,0 +1,112 @@
<!--标准归口情况-->
<template>
<div class="panel-box full-box">
<div class="panel-title"><img src="../../.././../assets/screenNew/icon_title.png" alt=""><span>标准归口情况</span></div>
<div class="panel-content">
<div class="echarts-box" id="centralizedChart"></div>
</div>
</div>
</template>
<script>
import { GetCentralizedData } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
export default {
name: 'CentralizedChart',
data() {
return {
xData: [],
yData: [[], []], // [在研数量[], 标准数量[]]
}
},
methods: {
getData() {
GetCentralizedData().then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
/*
* arr--对象数组,每个对象的key值如下
* "标准": 121,
* "在研": 9,
* "tm_code": "SC1"
*
* */
initData(arr) {
this.xData = []
this.yData = [[], []]
arr.map(item => {
this.xData.push(item.tm_code)
this.yData[0].push(item['在研'])
this.yData[1].push(item['标准'])
})
},
// 初始化图表
initChart() {
let option = {
xAxis: {
data: this.xData
},
tooltip: {
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
})
// return dataStr + ` <div style="padding-left: 10px;color: #7599E8">完成比例:${percent}</div>`
return dataStr
},
},
series: [
{
name:'在研数量',
data: this.yData[0],
type: 'bar',
barMaxWidth:20,
itemStyle:{
borderRadius:[4,4,0,0]
}
},
{
name:'标准数量',
data: this.yData[1],
type: 'bar',
barMaxWidth:20,
itemStyle:{
borderRadius:[4,4,0,0]
}
},
]
}
createBarChart('centralizedChart', option)
},
},
created() {
this.getData()
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,132 @@
<!--各SC历年应完成项目情况-->
<template>
<div class="panel-box half-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>各SC历年应完成项目情况</span>
<ul class="panel-title-right">
<a-select
v-model="selectValue"
style="width: 90px"
placeholder="各SC"
:bordered="false"
show-search
:show-arrow="true"
allow-clear
@change="selectChange"
dropdown-class-name="ant-select-screen-new"
>
<a-select-option
v-for="(item, index) in SCOptionData"
:key="index"
:value="item"
>
{{item}}
</a-select-option>
</a-select>
</ul>
</div>
<div class="panel-content">
<div class="echarts-box" id="completionProjectChart"></div>
</div>
</div>
</template>
<script>
import { GetCompletionProjectData, GetShouldBeCompletedProjectData } from '@/screenApi/api'
import { createBarAndLineChart } from '../util/BarAndLineOptions'
export default {
name: 'CompletionProjectChart',
data() {
return {
selectValue: undefined, // 选中的SC
SCOptionData: [],
}
},
methods: {
selectChange() {
this.getData()
},
// 初始化下拉框的数据
async getOptionData() {
let year = new Date().getFullYear()
let yearData = []
for(let i = year; i > year - 5; i--) {
yearData.unshift({value: i, label: i + '年'})
}
this.yearData = yearData
// 默认选中当前年
// this.selectValue = year
// 先通过接口获取所有的SC数据
let {result, success} = await GetShouldBeCompletedProjectData({year})
if(success) {
this.initSCData(result || [])
this.selectValue = undefined
}
},
getData() {
GetCompletionProjectData({scCode: this.selectValue}).then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
/*
* {"应报批总数2":2,"完成率字符串":"0.00%","应报批总数":2,"完成率数值2":0.00,"完成率数值":0.00,"tm_code":"SC1","完成数":0,"完成率字符串2":"0.00%","完成数2":0}
* */
initSCData(arr) {
this.SCOptionData = []
arr.map(item => {
this.SCOptionData.push(item.tm_code)
})
},
/*
* {"应报批总数2":186,"完成率字符串":"54.47%","应报批总数":123,"完成率数值2":40.32,"year":2022,"完成率数值":54.47,"完成数":67,"完成率字符串2":"40.32%","完成数2":75}
* */
initData(arr) {
this.yData = [[], [], []]
this.yearData.map(year => {
let item = arr.find(a => (a.year + '') === (year.value + ''))
if(item) {
this.yData[0].push(item['应报批总数'])
this.yData[1].push(item['完成数'])
this.yData[2].push(item['完成率数值'] === -1 ? undefined : item['完成率数值'])
}
})
},
// 初始化图表
initChart() {
let option = {
xAxis: { data: this.yearData },
series: [
{ data: this.yData[0] },
{ data: this.yData[1] },
{ data: this.yData[2] },
]
}
createBarAndLineChart('completionProjectChart', option)
},
},
created() {
// 获取下拉框数据
this.getOptionData()
// 获取图表数据
this.getData()
}
}
</script>
<style scoped lang="less">
/* 增加媒体查询的限制*/
@media screen and (max-width: 1400px) {
.preparation-half-box .box-title {
font-size: 14px;
}
}
</style>
@@ -0,0 +1,94 @@
<!--第一起草单位贡献度排名-->
<template>
<div class="panel-box half-box">
<div class="panel-title"><img src="../../.././../assets/screenNew/icon_title.png" alt=""><span>第一起草单位贡献度排名</span></div>
<div class="panel-content">
<div class="echarts-box" id="enterpriseContributionChart"></div>
</div>
</div>
</template>
<script>
import { GetEnterpriseContributionData } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
export default {
name: 'EnterpriseContributionChart',
data() {
return {
// 纵坐标分类的数据
categoryData: [],
barData: [[], []]
}
},
methods: {
getData() {
GetEnterpriseContributionData().then(res => {
if(res.success) {
this.initData(res.result || [])
this.$nextTick(() => {
this.initChart()
})
}
})
},
/*
* 初始化图表显示的数据 计划数量、标准数量
* {"unit":"中国汽车技术研究中心","planNum":4,"total":232,"stdNum":228}
* */
initData(arr) {
let barData = [[], []]
let categoryData = []
arr.map(item => {
categoryData.unshift(item.unit)
barData[0].unshift(item.planNum) // 计划数量
barData[1].unshift(item.stdNum) // 标准数量
})
this.barData = barData
this.categoryData = categoryData
},
initChart() {
let option = {
yAxis: {
data: this.categoryData
},
series: [
{
name:'计划数量',
type: 'bar',
stack: 'total',
barMaxWidth:20,
itemStyle:{
borderRadius:[0,0,0,0],
},
data: this.barData[0]
},
{
name:'标准数量',
type: 'bar',
stack: 'total',
barMaxWidth:20,
itemStyle:{
borderRadius:[0,4,4,0]
},
data: this.barData[1]
}
]
}
createBarChart('enterpriseContributionChart', option, true)
}
},
created() {
this.getData()
}
}
</script>
<style scoped lang="less">
/* 增加媒体查询的限制*/
@media screen and (max-width: 1400px) {
.preparation-half-box .box-title {
font-size: 14px;
}
}
</style>
@@ -0,0 +1,158 @@
<!--汽车标准项目总体情况-->
<template>
<div class="panel-box full-box general-situation-box">
<div class="panel-title"><img src="../../.././../assets/screenNew/icon_title.png" alt=""><span>汽车标准项目总体情况</span></div>
<div class="panel-content">
<!-- 发布国行标数量-->
<div class="general-situation-chart" id="releaseChart">
<img src="../../.././../assets/screenNew/icon_release.png" alt="">
<div>
<span>发布国行标数量</span>
<span>{{releaseAll}}</span>
</div>
</div>
<!-- 在研国行标数量-->
<div class="general-situation-chart" id="researchChart">
<img src="../../.././../assets/screenNew/icon_research.png" alt="">
<div>
<span>在研国行标数量</span>
<span>{{researchAll}}</span>
</div>
</div>
<!-- 立项上报国行标数量-->
<div class="general-situation-chart" id="publicChart">
<img src="../../.././../assets/screenNew/icon_public.png" alt="">
<div>
<span>立项上报国行标数量</span>
<span>{{publicAll}}</span>
</div>
</div>
<!-- 外文版项目数量-->
<div class="general-situation-chart" id="foreignChart">
<img src="../../.././../assets/screenNew/icon_foreign.png" alt="">
<div>
<span>外文版项目数量</span>
<span>{{foreignAll}}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { StanderProjectGeneralSituation } from '@/screenApi/api'
export default {
name: 'GeneralSituationChart',
data() {
return {
// 发布国行标数量
releaseData : [
{value: '', name: '国家标准'},
{value: '', name: '行业标准'},
],
releaseAll: '',
// 在研国行标数量
researchData : [
{value: '', name: '国家标准'},
{value: '', name: '行业标准'},
],
researchAll: '',
// 立项上报国行标数量
publicData : [
{value: '', name: '国家标准'},
{value: '', name: '行业标准'},
],
publicAll: '',
// 外文版项目数量
foreign: [
{value: '', name: '在研'},
{value: '', name: '发布'},
],
foreignAll: ''
}
},
methods: {
// 获取数据
getData() {
StanderProjectGeneralSituation().then(res => {
if(res.success) {
let result = res.result || {}
this.releaseData[0].value = result.stdGb
this.releaseData[1].value = result.stdHb
this.releaseAll = result.stdAll
this.researchData[0].value = result.planGb
this.researchData[1].value = result.planHb
this.researchAll = result.planAll
this.publicData[0].value = result.projectGb
this.publicData[1].value = result.projectHb
this.publicAll = result.projectAll
this.foreign[0].value = result.wwzy
this.foreign[1].value = result.wwfb
this.foreignAll = result.wwzy + result.wwfb
}
})
},
},
created() {
this.getData()
}
}
</script>
<style scoped lang="less">
.general-situation-chart{
width: 25%;
min-height: 120px;
background: #069F99;
border-radius: 12px;
padding: 25px 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: baseline;
img{
height: 30px;
width: auto;
display: inline-block;
}
div {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: #FFFFFF;
font-family: WenYue;
font-weight: normal;
span{
display: inline-block;
}
span:nth-of-type(1) {
font-size: 26px;
}
span:nth-of-type(2) {
font-size: 40px;
}
}
}
.general-situation-chart + .general-situation-chart {
margin-left: 60px;
}
.general-situation-chart:nth-of-type(2) {
background-color: #0799D4;
}
.general-situation-chart:nth-of-type(3) {
background-color: #2DC6CD;
}
.general-situation-chart:nth-of-type(4) {
background-color: #16CC9C;
}
.general-situation-box .panel-content{
display: flex;
flex-direction: row;
}
</style>
@@ -0,0 +1,121 @@
<!--各SC超期情况统计-->
<template>
<div class="panel-box full-box">
<div class="panel-title"><img src="../../.././../assets/screenNew/icon_title.png" alt=""><span>各SC超期情况统计</span></div>
<div class="panel-content">
<div class="echarts-box" id="overdueChart"></div>
</div>
</div>
</template>
<script>
import { GetOverdueData } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
export default {
name: 'OverdueChart',
data() {
return {
}
},
methods: {
getData() {
GetOverdueData().then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
/*
* {"延期后超期数":"0","项目总数":9,"延期后正常数":"0","完全超期数":"3","正常超期数":"3","没有延期完全正常数":"6","tm_code":"SC1"
* */
initData(arr) {
this.xData = []
this.yData = [[], [], []]
arr.map(item => {
this.xData.push(item.tm_code)
this.yData[0].push(item['没有延期完全正常数'])
this.yData[1].push(item['延期后正常数'])
this.yData[2].push(item['完全超期数'])
})
},
// 初始化图表
initChart() {
let option = {
color: ['#069F99', '#3CC3BE', '#97E3E0'],
//
xAxis: {
data: this.xData
},
tooltip: {
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
})
return dataStr
},
},
series: [
{
name:'正常完成',
data: this.yData[0],
type: 'bar',
barMaxWidth:20,
stack: 'total',
colorBy: 'series',
itemStyle:{
borderRadius:[0,0,0,0],
}
},
{
name:'延期完成',
data: this.yData[1],
type: 'bar',
barMaxWidth:20,
stack: 'total',
itemStyle:{
borderRadius:[0,0,0,0]
}
},
{
name:'完全超期',
data: this.yData[2],
type: 'bar',
barMaxWidth:20,
stack: 'total',
itemStyle:{
borderRadius:[4,4,0,0]
}
},
]
}
createBarChart('overdueChart', option)
},
},
created() {
this.getData()
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,186 @@
<!--汽车标准制修订情况 -->
<template>
<div class="panel-box full-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>汽车标准制修订情况</span>
<ul class="panel-title-right">
<li :class="{'active': selectType === 1}" @click="selectTypeChange(1)">总体</li>
<a-select
:class="{'active': selectType === 2}"
v-model="selectValue"
style="width: 70px"
placeholder="各SC"
:bordered="false"
show-search
:show-arrow="false"
@change="selectChange"
class="screen-select-no-border"
dropdown-class-name="ant-select-screen-new ant-select-screen-new-center"
>
<a-select-option
v-for="(item, index) in SCOptionData"
:key="index"
:value="item"
>
{{item}}
</a-select-option>
</a-select>
</ul>
</div>
<div class="panel-content no-padding-top">
<div class="echarts-box" id="preparationRevisionChart"></div>
</div>
</div>
</template>
<script>
import { GetPreparationRevisionSC, GetPreparationRevisionSituation } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
export default {
name: 'PreparationRevisionChart',
data() {
return {
selectType: 1, // 统计的维度 1-总体 2-SC下拉框
selectValue: undefined, // 选中的SC
SCOptionData: [],
// SC所有请求的数据 key
SCData: {},
allData: { }, // 请求总体的数据
barData: [],
xData: ['预研', '待下达', '起草', '征求意见', '审查', '报批', '批准发布', '已发布']
}
},
methods: {
getData() {
GetPreparationRevisionSituation().then((res) => {
if (res.success) {
this.allData = res.result || {}
// 默认显示全部
this.initData(this.allData)
this.$nextTick(() =>{
this.initChart()
})
}
})
GetPreparationRevisionSC().then((res) => {
if (res.success) {
try{
let result = res.result || []
let SCData = []
this.SCData = {}
result.map(item =>{
this.SCData[item.tm_code] = item
// let obj = {label: item.tm_code, value: item.tm_code}
SCData.push(item.tm_code)
})
this.SCOptionData = SCData
} catch (e) {
console.log('----e--------', e)
}
}
})
},
initData(obj) {
this.barData = []
this.xData.map(x => {
this.barData.push(obj[x])
})
},
// 初始化图表
initChart() {
let option = {
tooltip:{
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
// console.log('------item--------', item)
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.axisValue}</span>
<span style="color:#333;">${item.data}</span>
</div>
</div>`
})
return dataStr
}
},
xAxis: {
data: this.xData
},
series: [
{
// name:'年度待确收金额',
data: this.barData,
type: 'bar',
barMaxWidth:40,
itemStyle:{
borderRadius:[4,4,0,0]
}
},
]
}
createBarChart('preparationRevisionChart', option)
},
selectTypeChange(val) {
this.selectType = val
this.selectValue = undefined
// 操作数据
this.initData(this.allData)
this.initChart()
},
selectChange(val) {
if(val) {
this.selectType = 2
// 操作数据
this.initData(this.SCData[val])
this.initChart()
} else {
this.selectType = 1
}
},
// 点击中间的图片 做维度的转换
changeType() {
if(this.selectType === 1) {
this.selectValue = this.SCOptionData[0]
this.selectChange(this.SCOptionData[0])
} else {
this.selectTypeChange(1)
}
}
},
created() {
this.selectType = 1
this.getData()
}
}
</script>
<style scoped lang="less">
// 修改右侧额下拉框居中显示数据
::v-deep .ant-select-selection .ant-select-selection__rendered{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
::v-deep .ant-select-selection__placeholder{
right: 0;
width: 100%;
text-align: center;
}
</style>
@@ -0,0 +1,214 @@
<!--历年计划下达情况-->
<template>
<div class="panel-box half-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>历年计划下达情况</span>
<ul class="panel-title-right">
<li :class="{'active': selectType === 1}" @click="selectTypeChange(1)">总体</li>
<!--<img class="splice-icon" @click="changeType" src="../../../../assets/screen/split_icon.png" alt="">-->
<a-select
:class="{'active': selectType === 2}"
v-model="selectValue"
style="width: 70px"
placeholder="各SC"
:bordered="false"
show-search
:show-arrow="false"
@change="selectChange"
class="screen-select-no-border"
dropdown-class-name="ant-select-screen-new ant-select-screen-new-center"
>
<a-select-option
v-for="(item, index) in SCOptionData"
:key="index"
:value="item"
>
{{item}}
</a-select-option>
</a-select>
</ul>
</div>
<div class="panel-content">
<div class="echarts-box" id="releasePlanChart"></div>
</div>
</div>
</template>
<script>
import {
GetReleasePlanData,
GetReleasePlanDataBySC,
GetReleasePlanSCData
} from '@/screenApi/api'
import { createBarAndLineChart } from '../util/BarAndLineOptions'
import * as echarts from 'echarts'
export default {
name: 'ReleasePlanChart',
data() {
return {
selectType: 1, // 统计的维度 1-总体 2-SC下拉框
selectValue: undefined, // 选中的SC
SCOptionData: [],
yearData: [],
allData: [], // 总体请求的数据
}
},
methods: {
selectTypeChange(val) {
this.selectType = val
this.selectValue = undefined
// 操作数据
this.initData(this.allData)
this.initChart()
},
selectChange(val) {
if(val) {
this.selectType = 2
// 获取数据
this.getDataBySC(val)
} else {
this.selectType = 1
}
},
// 点击中间的图片 做维度的转换
changeType() {
if(this.selectType === 1) {
this.selectValue = this.SCOptionData[0]
this.selectChange(this.SCOptionData[0])
} else {
this.selectTypeChange(1)
}
},
getYearData() {
let year = new Date().getFullYear()
let yearData = []
for(let i = year; i > year - 5; i--) {
yearData.unshift({value: i, label: i + '年'})
}
this.yearData = yearData
},
/*
* 初始化SC下拉框的数据
* {"gbNum":23,"num":82,"hbNum":59,"tm_code":"SC1"}
* */
initSCData(arr) {
this.SCOptionData = []
arr.map(item => {
this.SCOptionData.push(item.tm_code)
})
},
// 获取SC下拉框的数据
getOptionData() {
// 先通过接口获取所有的SC数据
GetReleasePlanSCData().then((res) => {
if (res.success) {
this.initSCData(res.result || [])
}
})
},
/*
* 初始化图表显示的数据--取5年的数据做展示
* {"gbNum":51,"year":2012,"num":110,"hbNum":59}
* */
initData(arr) {
this.yData = [[], []]
this.yearData.map(year => {
let item = arr.find(a => (a.year + '') === (year.value + ''))
// console.log(item, '11111111111')
if(item) {
this.yData[0].push(item.gbNum) // 国家标准
this.yData[1].push(item.hbNum) // 行业标准
}
})
},
// 获取图表的数据-总体
getAllData() {
// 总体
GetReleasePlanData().then((res) => {
if (res.success) {
this.allData = res.result || []
// 默认显示全部
this.initData(this.allData)
this.$nextTick(() =>{
this.initChart()
})
}
})
},
// 获取图表的数据- SC
getDataBySC(scCode) {
GetReleasePlanDataBySC({scCode}).then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
initChart() {
let option = {
color: ['#069F99', 'rgba(22, 204, 156, 1)'],
xAxis: { data: this.yearData },
series: [
{
name:'国家标准',
data: this.yData[0]
},
{
name:'行业标准',
type: 'line',
showSymbol: false,
symbol: 'path://M 30 10 A 20 20 0 1 0 30 50 A 20 20 0 1 0 30 10 Z M 30 15 A 15 15 0 1 1 30 45 A 15 15 0 1 1 30 15 Z',
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(22, 204, 156, 1)'
},
{
offset: 1,
color: 'rgba(22, 204, 156, 0.1)'
}
])
},
data: this.yData[1],
}
]
}
createBarAndLineChart('releasePlanChart', option)
}
},
created() {
this.selectType = 1
// 操作进5年的年份值
this.getYearData()
// 获取SC下拉框数据
this.getOptionData()
// 获取总体图表数据
this.getAllData()
}
}
</script>
<style scoped lang="less">
// 修改右侧额下拉框居中显示数据
::v-deep .ant-select-selection .ant-select-selection__rendered{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
::v-deep .ant-select-selection__placeholder{
right: 0;
width: 100%;
text-align: center;
}
</style>
@@ -0,0 +1,209 @@
<!--历年标准发布情况-->
<template>
<div class="panel-box half-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>历年标准发布情况</span>
<ul class="panel-title-right">
<li :class="{'active': selectType === 1}" @click="selectTypeChange(1)">总体</li>
<!--<img class="splice-icon" @click="changeType" src="../../../../assets/screen/split_icon.png" alt="">-->
<a-select
:class="{'active': selectType === 2}"
v-model="selectValue"
style="width: 70px"
placeholder="各SC"
:bordered="false"
show-search
:show-arrow="false"
@change="selectChange"
class="screen-select-no-border"
dropdown-class-name="ant-select-screen-new ant-select-screen-new-center"
>
<a-select-option
v-for="(item, index) in SCOptionData"
:key="index"
:value="item"
>
{{item}}
</a-select-option>
</a-select>
</ul>
</div>
<div class="panel-content">
<div class="echarts-box" id="releaseStandardChart"></div>
</div>
</div>
</template>
<script>
import {
GetReleaseStandardData,
GetReleaseStandardSCData,
GetReleaseStandardDataBySC
} from '@/screenApi/api'
import { createBarAndLineChart } from '../util/BarAndLineOptions'
import * as echarts from 'echarts'
export default {
name: 'ReleaseStandardChart',
data() {
return {
selectType: 1, // 统计的维度 1-总体 2-SC下拉框
selectValue: undefined, // 选中的SC
SCOptionData: [],
allData: [], // 总体请求的数据
}
},
methods: {
selectTypeChange(val) {
this.selectType = val
this.selectValue = undefined
// 操作数据
this.initData(this.allData)
this.initChart()
},
selectChange(val) {
if(val) {
this.selectType = 2
// 获取数据
this.getDataBySC(val)
} else {
this.selectType = 1
}
},
// 点击中间的图片 做维度的转换
changeType() {
if(this.selectType === 1) {
this.selectValue = this.SCOptionData[0]
this.selectChange(this.SCOptionData[0])
} else {
this.selectTypeChange(1)
}
},
getYearData() {
let year = new Date().getFullYear()
let yearData = []
for(let i = year; i > year - 5; i--) {
yearData.unshift({value: i, label: i + '年'})
}
this.yearData = yearData
},
/*
* 初始化SC下拉框的数据
* {"gbNum":23,"num":82,"hbNum":59,"tm_code":"SC1"}
* */
initSCData(arr) {
this.SCOptionData = []
arr.map(item => {
this.SCOptionData.push(item.tm_code)
})
},
// 获取SC下拉框的数据
getOptionData() {
// 先通过接口获取所有的SC数据
GetReleaseStandardSCData().then((res) => {
if (res.success) {
this.initSCData(res.result || [])
}
})
},
/*
* 初始化图表显示的数据--取5年的数据做展示
* {"gbNum":51,"year":2012,"num":110,"hbNum":59}
* */
initData(arr) {
this.yData = [[], []]
this.yearData.map(year => {
let item = arr.find(a => (a.year + '') === (year.value + ''))
if(item) {
this.yData[0].push(item.gbNum) // 国家标准
this.yData[1].push(item.hbNum) // 行业标准
}
})
},
// 获取图表的数据-总体
getAllData() {
// 总体
GetReleaseStandardData().then((res) => {
if (res.success) {
this.allData = res.result || []
// 默认显示全部
this.initData(this.allData)
this.$nextTick(() =>{
this.initChart()
})
}
})
},
// 获取图表的数据- SC
getDataBySC(scCode) {
GetReleaseStandardDataBySC({scCode}).then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
initChart() {
let option = {
color: ['#069F99', 'rgba(22, 204, 156, 1)'],
xAxis: { data: this.yearData },
series: [
{
name:'国家标准',
data: this.yData[0]
},
{
name:'行业标准',
type: 'line',
showSymbol: false,
symbol: 'path://M 30 10 A 20 20 0 1 0 30 50 A 20 20 0 1 0 30 10 Z M 30 15 A 15 15 0 1 1 30 45 A 15 15 0 1 1 30 15 Z',
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(22, 204, 156, 1)'
},
{
offset: 1,
color: 'rgba(22, 204, 156, 0.1)'
}
])
},
data: this.yData[1],
}
]
}
createBarAndLineChart('releaseStandardChart', option)
}
},
created() {
this.selectType = 1
// 操作进5年的年份值
this.getYearData()
// 获取SC下拉框数据
this.getOptionData()
// 获取总体图表数据
this.getAllData()
}
}
</script>
<style scoped lang="less">
// 修改右侧额下拉框居中显示数据
::v-deep .ant-select-selection .ant-select-selection__rendered{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
::v-deep .ant-select-selection__placeholder{
right: 0;
width: 100%;
text-align: center;
}
</style>
@@ -0,0 +1,111 @@
<!--各年应完成项目情况-->
<template>
<div class="panel-box full-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_title.png" alt="">
<span>各年应完成项目情况</span>
<ul class="panel-title-right">
<a-select
v-model="selectValue"
style="width: 100px"
placeholder="年份"
:bordered="false"
show-search
:show-arrow="true"
@change="selectChange"
dropdown-class-name="ant-select-screen-new"
>
<a-select-option
v-for="(item, index) in yearData"
:key="index"
:value="item.value"
>
{{item.label}}
</a-select-option>
</a-select>
</ul>
</div>
<div class="panel-content">
<div class="echarts-box" id="shouldBeCompletedProjectChart"></div>
</div>
</div>
</template>
<script>
import { GetShouldBeCompletedProjectData } from '@/screenApi/api'
import { createBarAndLineChart } from '../util/BarAndLineOptions'
export default {
name: 'ShouldBeCompletedProjectChart',
data() {
return {
selectValue: undefined, // 选中的SC
yearData: [],
}
},
methods: {
selectChange() {
this.getData()
},
// 初始化下拉框的数据
getOptionData() {
let year = new Date().getFullYear()
let yearData = []
for(let i = year; i > year - 5; i--) {
yearData.push({value: i, label: i + '年'})
}
this.yearData = yearData
// 默认选中当前年
this.selectValue = year
},
getData() {
GetShouldBeCompletedProjectData({year: this.selectValue}).then((res) => {
if (res.success) {
this.initData(res.result || [])
this.$nextTick(() =>{
this.initChart()
})
}
})
},
/*
* {"应报批总数2":2,"完成率字符串":"0.00%","应报批总数":2,"完成率数值2":0.00,"完成率数值":0.00,"tm_code":"SC1","完成数":0,"完成率字符串2":"0.00%","完成数2":0}
* */
initData(arr) {
this.xData = []
this.yData = [[], [], []]
arr.map(item => {
this.xData.push(item.tm_code)
this.yData[0].push(item['应报批总数'])
this.yData[1].push(item['完成数'])
this.yData[2].push(item['完成率数值'] === -1 ? undefined : item['完成率数值'])
})
},
// 初始化图表
initChart() {
let option = {
xAxis: { data: this.xData },
series: [
{ data: this.yData[0] },
{ data: this.yData[1] },
{ data: this.yData[2] },
]
}
createBarAndLineChart('shouldBeCompletedProjectChart', option)
},
},
created() {
this.getOptionData()
this.getData()
}
}
</script>
<style scoped lang="less">
.title-right {
right: 1%;
}
</style>
@@ -0,0 +1,184 @@
<template>
<div class="screen-preparation-revision">
<!-- 汽车标准项目-总体情况-->
<general-situation-chart></general-situation-chart>
<!-- 汽车标准制修订情况-->
<preparation-revision-chart></preparation-revision-chart>
<!-- 标准归口情况-->
<centralized-chart></centralized-chart>
<!-- 历年计划下达情况-->
<release-plan-chart></release-plan-chart>
<!-- 历年标准发布情况-->
<release-standard-chart></release-standard-chart>
<!-- 各SC历年应完成项目情况-->
<completion-project-chart></completion-project-chart>
<!-- 第一起草单位贡献度排名-->
<enterprise-contribution-chart></enterprise-contribution-chart>
<!-- 各年应完成项目情况-->
<should-be-completed-project-chart></should-be-completed-project-chart>
<!-- 各SC超期情况统计-->
<overdue-chart></overdue-chart>
</div>
</template>
<script>
//汽车标准项目总体情况 GeneralSituationChart
import GeneralSituationChart from './GeneralSituationChart'
//汽车标准制修订情况 PreparationRevisionChart
import PreparationRevisionChart from './PreparationRevisionChart'
//标准归口情况 CentralizedChart
import CentralizedChart from './CentralizedChart'
//历年计划下达情况 ReleasePlanChart
import ReleasePlanChart from './ReleasePlanChart'
//历年标准发布情况 ReleaseStandardChart
import ReleaseStandardChart from './ReleaseStandardChart'
//各SC历年应完成项目情况 CompletionProjectChart
import CompletionProjectChart from './CompletionProjectChart'
//第一起草单位贡献度排名 EnterpriseContributionChart
import EnterpriseContributionChart from './EnterpriseContributionChart'
//各年应完成项目情况 ShouldBeCompletedProjectChart
import ShouldBeCompletedProjectChart from './ShouldBeCompletedProjectChart'
//各SC超期情况统计 OverdueChart
import OverdueChart from './OverdueChart'
export default {
name: 'index',
components: {
// 汽车标准项目总体情况
GeneralSituationChart,
// 汽车标准制修订情况
PreparationRevisionChart,
// 标准归口情况
CentralizedChart,
// 历年计划下达情况
ReleasePlanChart,
// 历年标准发布情况
ReleaseStandardChart,
// 各SC历年应完成项目情况
CompletionProjectChart,
// 第一起草单位贡献度排名
EnterpriseContributionChart,
// 各年应完成项目情况
ShouldBeCompletedProjectChart,
// 各SC超期情况统计
OverdueChart
}
}
</script>
<style scoped lang="less">
.screen-preparation-revision{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
@general-height: 480px;
.panel-box:not(.general-situation-box) {
height: @general-height;
display: flex;
flex-direction: column;
// 内容的部分
/deep/ .panel-content {
flex: 1;
.echarts-box {
width: 100%;
height: 100%;
}
}
/deep/.no-padding-top {
padding-top: 0;
}
}
@normal-color: #5C5C5A;
@primary: #069F99;
@white: #fff;
// 半屏 标题右侧的样式
/deep/.panel-title-right{
width: 50%;
height: 100%;
position: absolute;
right: 32px;
top: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
z-index: 100;
font-size: 0;
li{
font-size: 16px;
list-style: none;
color: @normal-color;
cursor: pointer;
padding: 0 10px;
margin-right: 20px;
}
li.active{
color: @primary-color;
position: relative;
&::after {
content: '';
display: inline-block;
width: 100%;
height: 2px;
background-color: @primary-color;
position: absolute;
bottom: 0;
left: 0;
}
}
.ant-select.active {
//text-align: center;
&::after {
content: '';
display: inline-block;
width: 100%;
height: 2px;
background-color: @primary-color;
position: absolute;
bottom: -12px;
left: 0;
}
}
}
//没有边框的下拉框
/deep/.screen-select-no-border{
//下拉框样式的修改
.ant-select-selection{
border: none!important;
background: transparent;
color: @normal-color;
}
&.ant-select-focused .ant-select-selection, &.ant-select-selection:focus, &.ant-select-selection:active{
border: none!important;
box-shadow: none;
}
}
/deep/.half-box {
width: calc(50% - 5px);
}
// 偶数位增加 10px的右边框
/deep/.half-box:nth-of-type(2n) {
margin-right: 10px;
}
</style>
<style lang="less">
// 居中的下拉框
.ant-select-screen-new-center li{
text-align: center;
}
</style>
@@ -0,0 +1,214 @@
import * as echarts from 'echarts'
import { deepMerge } from '@/utils/util'
export const BarAndLineOptions = {
color: ['#069F99', '#FFA17A', '#16CC9C'],
tooltip: {
trigger: 'axis',
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
if(item.seriesType === 'bar') {
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
} else {
let valueText = item.value
// 求比例的时候特殊处理
if(item.seriesName.indexOf('比例') > -1) {
valueText = item.value === undefined ? '-' : `${item.value}%`
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:2px;background-color:${color};vertical-align: middle"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${valueText}</span>
</div>
</div>`
}
})
return dataStr
},
borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
lineStyle: {
opacity: 0
},
itemWidth: 14,
// itemHeight: 14,
right: '0',
// top: '1%'
},
grid: {
left: '0',
right: '0',
bottom: '0',
containLabel: true
},
toolbox: {},
xAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95',
interval: 0,
formatter: function(params) {
let newParamsName = '' // 最终拼接成的字符串
let paramsNameNumber = params.length // 实际标签的个数
let provideNumber = 8 // 每行能显示的字的个数
let rowNumber = Math.ceil(paramsNameNumber / provideNumber) // 换行的话,需要显示几行,向上取整
/**
* 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
*/
// 条件等同于rowNumber>1
if (paramsNameNumber > provideNumber) {
/** 循环每一行,p表示行 */
for (let p = 0; p < rowNumber; p++) {
let tempStr = ''// 表示每一次截取的字符串
let start = p * provideNumber // 开始截取的位置
let 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
}
},
type: 'category',
boundaryGap: ['30%', '20%'],
// 刻度线设置
axisTick: {
show: false
},
// TODO 需要自己扩展的
data: []
},
yAxis: [
{
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
splitLine: {
lineStyle: {
color: '#F2F2F2',
type: 'solid'
}
},
type: 'value',
nameTextStyle: {
color: '#20203D'
}
},
{
type: 'value',
// min: 0,
// max: 100,
axisLabel: {
show: false,
formatter: '{value} %',
},
splitLine: {
show: false
}
}
],
series: [
{
name:'应完成项目数',
// data: this.yData[0],
type: 'bar',
barMaxWidth:20,
itemStyle:{
borderRadius:[4,4,0,0]
}
},
{
name:'实际完成项目数',
// data: this.yData[1],
type: 'bar',
barMaxWidth:20,
itemStyle:{
borderRadius:[4,4,0,0]
}
},
{
name:'实际完成比例',
// data: this.yData[2],
type: 'line',
yAxisIndex: 1,
showSymbol: false,
symbol: 'path://M 30 10 A 20 20 0 1 0 30 50 A 20 20 0 1 0 30 10 Z M 30 15 A 15 15 0 1 1 30 45 A 15 15 0 1 1 30 15 Z',
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(22, 204, 156, 1)'
},
{
offset: 1,
color: 'rgba(22, 204, 156, 0.1)'
}
])
},
},
]
}
// 生成柱折状图---制修订、各项目完成情况专用
export function createBarAndLineChart(idName, option) {
const chartDom = document.getElementById(idName)
echarts.dispose(chartDom)
// debugger
let chartOption = deepMerge({}, BarAndLineOptions, option)
let myChart = echarts.init(chartDom)
chartOption && myChart.setOption(chartOption)
window.addEventListener('resize', () => {
myChart.resize()
})
}
@@ -0,0 +1,263 @@
import * as echarts from 'echarts'
import { formatMoney } from '@/utils/formatMoney'
import { deepMerge } from '@/utils/util'
// 正常的柱状图配置
export const BarOptions = {
// color: ['#4471EF', '#00D8F1', '#6CFBCE'],
color: ['#069F99', '#FFA17A','#6CFBCE'],
tooltip: {
trigger: 'axis',
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<div>
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
</div>
<div style="color:#333;">${formatMoney(item.value)}</div>
</div>
</div>`
})
// return dataStr + ` <div style="padding-left: 10px;color: #7599E8">完成比例:${percent}</div>`
return dataStr
},
borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
itemWidth: 14,
// itemHeight: 14,
right: '0'
},
grid: {
left: '0',
right: '0',
bottom: '0',
// top: '40px',
containLabel: true
},
toolbox: {},
xAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95',
interval: 0,
formatter: function(params) {
let newParamsName = '' // 最终拼接成的字符串
let paramsNameNumber = params.length // 实际标签的个数
let provideNumber = 8 // 每行能显示的字的个数
let rowNumber = Math.ceil(paramsNameNumber / provideNumber) // 换行的话,需要显示几行,向上取整
/**
* 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
*/
// 条件等同于rowNumber>1
if (paramsNameNumber > provideNumber) {
/** 循环每一行,p表示行 */
for (let p = 0; p < rowNumber; p++) {
let tempStr = ''// 表示每一次截取的字符串
let start = p * provideNumber // 开始截取的位置
let 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
}
},
type: 'category',
boundaryGap: ['30%', '20%'],
// 刻度线设置
axisTick: {
show: false
},
// TODO 需要自己扩展的
data: []
},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
splitLine: {
lineStyle: {
color: '#F2F2F2',
type: 'solid'
}
},
type: 'value',
nameTextStyle: {
color: '#20203D'
}
}
}
// X轴是value的配置
export const BarAxisTransformOptions = {
color: ['#069F99', '#FFA17A','#6CFBCE'],
tooltip: {
trigger: 'axis',
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ` <div style="color:#666">${params[0].name}</div>`
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
})
return dataStr
},
borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
itemWidth: 14,
right: '2%'
},
grid: {
left: '0',
right: '3%',
bottom: '0',
containLabel: true
},
toolbox: {},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95',
interval: 0,
formatter: function(params) {
let newParamsName = '' // 最终拼接成的字符串
let paramsNameNumber = params.length // 实际标签的个数
let provideNumber = 10 // 每行能显示的字的个数
// let rowNumber = Math.ceil(paramsNameNumber / provideNumber) // 换行的话,需要显示几行,向上取整
/**
* 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
*/
// 条件等同于rowNumber>1
if (paramsNameNumber > provideNumber) {
let tempStr = params.substring(0, provideNumber) + '...'
newParamsName += tempStr
} else {
// 将旧标签的值赋给新标签
newParamsName = params
}
return newParamsName
}
},
type: 'category',
boundaryGap: ['30%', '20%'],
// 刻度线设置
axisTick: {
show: false
},
// TODO 需要自己扩展的
data: []
},
xAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
splitLine: {
lineStyle: {
color: '#F2F2F2',
type: 'solid'
}
},
type: 'value',
nameTextStyle: {
color: '#20203D'
}
}
}
/**
* 生成柱状图
* @param idName --- 当前dom的id
* @param option --- 配置项
* @param xValue --- 横坐标是否是value,默认不传
*/
export function createBarChart(idName, option, xValue) {
const chartDom = document.getElementById(idName)
echarts.dispose(chartDom)
// debugger
let chartOption = deepMerge({}, BarOptions, option)
if(xValue) {
chartOption = deepMerge({},BarAxisTransformOptions, option)
}
let myChart = echarts.init(chartDom)
chartOption && myChart.setOption(chartOption)
window.addEventListener('resize', () => {
myChart.resize()
})
}
@@ -0,0 +1,236 @@
import * as echarts from 'echarts'
import { formatMoney } from '@/utils/formatMoney'
import { deepMerge } from '@/utils/util'
export const LineOptions = {
color: ['#069F99', '#FFA17A','#6CFBCE'],
tooltip: {
trigger: 'axis',
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:transparent;border: 2px solid ${item.color};border-radius: 50%"></span>
<span style="color: #666">${item.seriesName}</span>
<span style="float:right;color:#333;margin-left:20px;">${formatMoney(item.data)}</span>
</div>
</div>`
})
return dataStr
},
// alwaysShowContent: true,
// borderColor: 'rgba(255,255,50,1)',
borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
data: [ '确认收入金额', '开票金额', '到账金额'],
icon: 'path://M 30 10 A 20 20 0 1 0 30 50 A 20 20 0 1 0 30 10 Z M 30 15 A 15 15 0 1 1 30 45 A 15 15 0 1 1 30 15 Z',
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
// itemWidth: 14,
// itemHeight: 14,
right: '0',
},
grid: {
left: '2.4%',
right: '3%',
bottom: '0',
containLabel: true
},
toolbox: {},
xAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
type: 'category',
boundaryGap: ['30%','20%'],
// 刻度线设置
axisTick: {
show: false
},
// TODO 需要自己扩展的
data: []
},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
splitLine: {
lineStyle: {
color: '#F2F2F2',
type: 'solid'
}
},
type: 'value',
nameTextStyle: {
color: '#20203D'
},
},
}
export const ISOLineOptions = {
color: ['#069F99', '#FFA17A','#6CFBCE'],
tooltip: {
trigger: 'axis',
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
params.forEach(item => {
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:transparent;border: 2px solid ${item.color};border-radius: 50%"></span>
<span style="color: #666">${item.seriesName}</span>
<span style="float:right;color:#333;margin-left:20px;">${item.data}</span>
</div>
</div>`
})
return dataStr
},
borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
data: [ '国际注册专家', '国内支撑专家'],
icon: 'path://M 30 10 A 20 20 0 1 0 30 50 A 20 20 0 1 0 30 10 Z M 30 15 A 15 15 0 1 1 30 45 A 15 15 0 1 1 30 15 Z',
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
right: '0',
},
grid: {
left: '0',
right: '0',
bottom: '0%',
containLabel: true
},
toolbox: {},
xAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
type: 'category',
boundaryGap: ['30%','20%'],
// 刻度线设置
axisTick: {
show: false
},
data: []
},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: '#F2F2F2'
}
},
axisLabel: {
show: true,
color: '#8E8E95'
},
splitLine: {
lineStyle: {
color: '#F2F2F2',
type: 'solid'
}
},
type: 'value',
nameTextStyle: {
color: '#20203D'
}
},
series: [
{
name: '国际注册专家',
type: 'line',
showSymbol: false,
symbolSize: 8,
data: [],
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(6, 159, 153, 1)'
},
{
offset: 1,
color: 'rgba(6, 159, 153, 0.2)'
}
])
},
},
{
name: '国内支撑专家',
type: 'line',
showSymbol: false,
symbolSize: 8,
data: [],
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#EBAB91'
},
{
offset: 1,
color: '#ffffff'
}
])
},
}
]
}
// 生成折线图
export function createLineChart(idName, option, isISO) {
const chartDom = document.getElementById(idName)
echarts.dispose(chartDom)
// debugger
let chartOption = deepMerge({}, LineOptions, option)
if(isISO) {
chartOption = deepMerge({}, ISOLineOptions, option)
}
let myChart = echarts.init(chartDom)
chartOption && myChart.setOption(chartOption)
window.addEventListener('resize', () => {
myChart.resize()
})
}
@@ -0,0 +1,126 @@
import * as echarts from 'echarts'
import { formatMoney } from '@/utils/formatMoney'
import { deepMerge } from '@/utils/util'
const color = ['#069F99', '#6D7FD0', '#8ACA9D', '#F58952', '#FAB152', '#6A956A', '#519FD1', '#55433B', '#9ABECA']
export const PieOptions = {
title: {
show: false,
text: '',
textStyle: {
color: '#333',
fontWeight: 500,
fontSize: 14
},
left: 'center',
top: '10%'
},
color,
tooltip: {
show: true,
trigger: 'item',
formatter: (param) => {
let color = ''
if(typeof param.color === 'string') {
color = param.color
} else {
color = param.color.colorStops[0].color
}
return `<div>
<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${color};"></span>
<span style="color: #666">${param.name}</span>
<span style="color: #333">${formatMoney(param.data.money)}</span>
</div>`
},
// borderWidth: 0,
//提示框浮层的背景颜色
// backgroundColor: '#233062',
//额外附加到浮层的 css 样式。如下为浮层添加阴影的示例:
// extraCssText: 'box-shadow: 0 0 4px #7599E8 inset;'
},
legend: {
show: false,
//图例的公用文本样式。
textStyle: {
color: '#050525'
},
bottom: '0',
right: '0',
padding: [0,70, 0, 70],
itemGap: 40 // 图例之间的间距
},
toolbox: {},
labelLine: {
lineStyle: {
color: '#999999'
}
},
series: [
{
type: 'pie',
radius: ['20%', '60%'],
center: ['50%', '50%'],
// roseType: 'area', // 南丁格尔图,所有扇区圆心角相同,仅通过半径展现数据大小。
roseType: 'radius', // 南丁格尔图,扇区圆心角展现数据的百分比,半径展现数据的大小。
itemStyle: {
borderRadius: [0, 0, 5, 5]
},
label: {
show: true,
color: '#333333',
formatter: '{b}: {d}%'
}
}
]
}
// 处理label中圆点
function initPoint(data, color) {
// 这步主要是为了让小圆点的颜色和饼状图的块对应
let setLabel = (data) => {
let opts = []
for (let i = 0; i < data.length; i++) {
let item = {}
item.name = data[i].name
item.value = data[i].value
item.label = {
normal: {
//控制引导线上文字颜色和位置,此处a是显示文字区域,b做一个小圆圈在引导线尾部显示
show: true,
formatter: '{point|}{a|}{c}',
rich: {
a: {
padding: [0, 0, 0, 4]
},
point: {
height: 7,
width: 7,
lineHeight: 7,
borderRadius: 50,
backgroundColor: color[i], // 圆点颜色和饼图块状颜色一致
},
}
},
}
opts.push(item)
}
return opts
}
return setLabel(data)
}
// 生成柱状图
export function createPieChart(idName, option) {
const chartDom = document.getElementById(idName)
echarts.dispose(chartDom)
// debugger
let chartOption = deepMerge({}, PieOptions, option)
chartOption.series[0].data = initPoint(chartOption.series[0].data, color)
let myChart = echarts.init(chartDom)
chartOption && myChart.setOption(chartOption)
window.addEventListener('resize', () => {
myChart.resize()
})
}
@@ -0,0 +1,115 @@
<!--专家数量统计-->
<template>
<div class="panel-box expert-quantity-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_expert.png" alt="">
<span>专家数量统计</span>
<div class='header-num'>
<span>专家总数</span>
<span class="num">{{totalAll}}</span>
</div>
</div>
<div class="panel-content">
<div class="echarts-box" id="expertQuantityChart"></div>
</div>
</div>
</template>
<script>
import { createPieChart } from '../util/PieOptions'
import { GetExpertQuantityData } from '@/screenApi/api'
export default {
name: 'ExpertQuantityChart',
data() {
return {
totalAll: '' // 法规总数
}
},
methods: {
getData() {
GetExpertQuantityData().then(res => {
if(res.success) {
let data = res.result || []
if(data.length > 0) {
this.totalAll = data[0].total
}
this.$nextTick(() => {
this.initChart(data)
})
}
})
},
/**
* 初始化图表
* @param data --{"technicalField":"GRSP","count":"23","total":"52"}
*/
initChart(data) {
let echartsData = data.reduce((pre, val) => {
return pre.concat({value: val.count, name: val.technicalField, total: val.total})
}, [])
let option = {
legend: {
show: true,
type: 'scroll',
orient: 'vertical',
right: '-20px',
top: 'center',
itemGap: 10 // 图例之间的间距
},
grid: {
left: '0',
right: '0',
},
tooltip: {
formatter: (param) => {
let color = ''
if(typeof param.color === 'string') {
color = param.color
} else {
color = param.color.colorStops[0].color
}
return `<div>
<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${color};"></span>
<span style="color: #666">${param.name}</span>
<span style="color: #333">${param.value}</span>
</div>`
},
},
series: [
{
center: ['42%', '50%'],
// label: {
// formatter: '{hr|} {c}',
// rich: {
// hr: {
// backgroundColor: 'red',
// borderRadius: 50,
// width: 7,
// height: 7,
// }
//
// }
// },
data: echartsData
}
]
}
createPieChart('expertQuantityChart', option)
}
},
created() {
this.getData()
}
}
</script>
<style scoped lang="less">
.expert-quantity-box{
width: 40%;
}
</style>
@@ -0,0 +1,368 @@
<!--会议信息日历-->
<template>
<div class="panel-box full-box calendar-panel-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_meeting.png" alt="">
<span>会议信息日历</span>
<div class='header-num'>
<span>会议总数</span>
<span class='num'>{{this.scheduleList.length}}</span>
</div>
</div>
<div class="panel-content">
<div class="content-header">
<img class="header-img" @click="prev" src="../../../../assets/screenNew/calendar_left_icon.png" alt="">
<span class="header-text">{{ time }}主要会议安排</span>
<img class="header-img" @click="next" src="../../../../assets/screenNew/calendar_right_icon.png" alt="">
</div>
<div class="header-right">
<div class="header-right-text">
<span class="radius" style="background:#069F99"></span>
<span class="text">WP.29</span>
</div>
<div class="header-right-text">
<span class="radius" style="background:#6C9DA3"></span>
<span class="text">GR</span>
</div>
<div class="header-right-text">
<span class="radius" style="background:#B1CAC5"></span>
<span class="text">IWG</span>
</div>
</div>
<full-calendar ref="fullCalendar" style="height: 100%" :options="calendarOptions"></full-calendar>
</div>
</div>
</template>
<script>
import { GetMeetingCalendarData } from '@/screenApi/api'
// 引入日历组件
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import tippy from 'tippy.js'
export default {
name: 'MeetingCalendar',
components: {
FullCalendar
},
data() {
return {
calendarOptions: {
// timeGridPlugin 可显示每日时间段
height: 700,
plugins: [dayGridPlugin, interactionPlugin],
headerToolbar: null,
firstDay: 0,
editable: false,
selectable: false,
navLinks: false,
// displayEventEnd: true,//所有视图显示结束时间
initialView: 'dayGridMonth', // 设置默认显示月,可选周、日
// dateClick: this.handleDateClick,
// eventClick: this.handleEventClick,
eventMouseEnter: this.eventMouseoverOne,
eventMouseLeave: this.eventMouseoutOne,
// timezone
// 设置日程
events: [],
eventColor: '#f08f00', // 修改日程背景色
weekNumberCalculation: 'ISO', // 周数
fixedWeekCount: false, //月份 固定周数
customButtons: {}
},
scheduleList: [],
time: '',
calendarApi: {}
}
},
created() {
// 获取用户信息
this.$nextTick(() => {
this.calendarApi = this.$refs.fullCalendar.getApi()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
})
// this.getReservationList(this.scheduleList)
this.getData()
},
methods: {
getData() {
let query = {
// orgCode: this.orgCode,
// cutTime: ''
}
GetMeetingCalendarData(query).then((res) => {
if (res.success) {
this.scheduleList = res.result || []
this.getReservationList(res.result)
} else {
this.scheduleList = []
}
})
},
prev() {
this.calendarApi.prev()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
},
// 切换下一个按钮事件
next() {
this.calendarApi.next()
let currentDate = new Date(this.calendarApi.currentData.currentDate)
this.time = currentDate.getFullYear() + '年' + (currentDate.getMonth() + 1) + '月'
},
// 点击今天按钮
today() {
this.calendarApi.today()
},
handleDateClick: function(arg) {
this.$forceUpdate()
console.log(arg, '事件1')
},
handleEventClick(calEvent) {
let params = { orgCode: calEvent.event.id, thisType: 2, type: 2 }
this.$router.push({
path: '/meetinginfo',
query: params
})
},
getReservationList(arrayData) {
let newArr = []
arrayData.forEach((item) => {
if (item.orgType == 'GR') {
item.status = '#069F99'
item.textColor = '#FFFFFF'
} else if (item.orgType == 'IWG') {
item.status = '#47858C'
item.textColor = '#FFFFFF'
} else {
item.status = '#9DBDB7'
item.textColor = '#FFFFFF'
}
newArr.push({
start: this.dealWithTime(item.time),
end: this.addDate(this.dealWithTime(item.endTime), 1),
color: item.status,
textColor: item.textColor,
id: item.meetingId,
title: `${item.name}`
})
})
this.calendarOptions.events = newArr
},
getShowTime(beginDate, endDate) {
this.form.startDate = this.dealWithTime(beginDate)
this.form.startTime = this.getHoursMin(beginDate)
this.form.endDate = this.dealWithTime(endDate)
this.form.endTime = this.getHoursMin(endDate)
},
// 获取时分时间
getHoursMin(value) {
return value.substring(11, 16)
},
// 处理会议时间格式
dealWithTime(date) {
let newDate = /\d{4}-\d{1,2}-\d{1,2}/g.exec(date)[0]
return newDate
},
// 日期加1天
addDate(date, days) {
var d = new Date(date)
d.setDate(d.getDate() + days)
var mon = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1
let endD = d.getDate() < 10 ? '0' + d.getDate() : d.getDate()
return `${d.getFullYear()}-${mon}-${endD}`
},
eventMouseoverOne(data) {
let content = this.scheduleList.filter(res => {
return res.meetingId == data.event.id
})
//todo 缺一个type的字段
tippy(data.el, {
content:
'<div class="tippy-content-box-new" style="">' +
'<span style="margin-right: 10px;" class="text-index">' + content[0].orgType + '</span>' + '<span class="text-index">' + content[0].name + '</span>' +
'<div class="tippy-content">技术领域: ' + content[0].type + '</div>' + '' +
'<div class="tippy-content">时间: ' + content[0].timeAll + '</div>' + '' +
'<div class="tippy-content">地点: ' + content[0].place + '</div>' +
'<div class="tippy-content">参会人: ' + content[0].meetingPersons + '</div>' + '</div>',
interactive: false,
// placement: 'top',
allowHTML: true
})
},
eventMouseoutOne() {
},
// 获取会议事件title
getTitle(date1, date2) {
let start = date1.substring(11, 16)
let end = date2.substring(11, 16)
return `${start}~${end}`
}
}
}
</script>
<style scoped lang="less">
@white: #fff;
@normal-color: #050525;
.content-header {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
margin-bottom: 20px;
}
.header-img {
width: 28px;
height: 28px;
cursor: pointer;
}
.header-text {
font-size: 18px;
font-family: PingFang SC;
font-weight: 800;
color: #069F99;
margin-left: 26px;
margin-right: 26px;
}
.header-right {
display: flex;
justify-content: flex-end;
align-items: center;
transform: translateY(-35px);
height: 0;
}
.header-right-text {
display: flex;
align-items: center;
margin-left: 28px;
}
.radius {
width: 14px;
height: 14px;
border-radius: 4px;
display: inline-block;
}
.text {
font-size: 14px;
font-family: PingFang SC;
font-weight: 500;
color: @normal-color;
margin-left: 8px;
}
.header-num{
position: absolute;
right: 32px;
top: 0;
span {
font-size: 16px;
color: #050525;
display: inline-block;
vertical-align: middle;
}
span.num {
font-size: 20px;
color: #FA9D81;
}
}
/*日历组件的修改 */
::v-deep .fc-theme-standard td,
::v-deep.fc-theme-standard .fc-scrollgrid{
border-color: #E9E9E9;
}
// 周日和周六的颜色不同
::v-deep .fc-day-sun .fc-col-header-cell-cushion ,
::v-deep .fc-day-sat .fc-col-header-cell-cushion {
color: #9E0000;
}
::v-deep .fc-daygrid-day .fc-daygrid-day-number {
font-weight: bold;
font-size: 14px;
margin-right: 6px;
}
::v-deep .fc-day-other {
background: #F1F1F1;
.fc-daygrid-day-number {
color: @normal-color;
font-size: 14px;
margin-right: 6px;
}
}
::v-deep .fc-col-header-cell-cushion {
font-size: 14px;
font-family: PingFang SC;
font-weight: bold;
color: @normal-color;
}
::v-deep .fc-col-header-cell {
height: 38px;
line-height: 38px;
background-color: #FCFBFB;
}
::v-deep .fc-event-main {
padding: 2px 10px;
}
::v-deep .fc-toolbar-chunk .fc-button-primary {
display: none;
}
::v-deep .fc .fc-daygrid-day.fc-day-today{
background-color: rgba(6, 159, 153, 0.1);
}
::v-deep .fc-event-title{
font-weight: 800!important;
}
::v-deep .fc-scrollgrid-section-header .fc-scroller {
overflow: hidden!important;
}
</style>
<style lang="less">
@normal-color: #050525;
.tippy-content-box-new {
background: #fff;
color: @normal-color;
border-radius: 6px;
padding: 12px;
box-sizing: border-box;
box-shadow: 0 2px 9px 0 rgba(5,5,37,0.04);
.text-index {
font-size: 16px;
font-family: PingFang SC;
font-weight: 800;
color: @normal-color;
}
.tippy-content {
font-size: 14px;
font-family: PingFang SC;
font-weight: 500;
color: @normal-color;
margin-top: 8px;
}
}
</style>
@@ -0,0 +1,338 @@
<!--会议信息统计-->
<template>
<div class="panel-box meeting-wp-panel-box full-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_meetingWp.png" alt="">
<span>会议信息统计</span>
<ul class="panel-title-right">
<li
v-for="item in dimensionOptionData"
:key="item.value"
:class="{'active': dimensionValue === item.value}"
@click="dimensionSelectChange(item)"
>{{ item.text }}</li>
</ul>
</div>
<div class="panel-content">
<div class="select-info-box">
<div class="left-select">
<span class="label">选择时间</span>
<j-year-date
v-if="dimensionValue !== 'month'"
format="YYYY"
:allowClear="false"
placeholder="请选择年份"
v-model="searchParams.year"
@change="onYearChange"
dropdown-class-name="ant-calendar-dropdown-screen"
></j-year-date>
<a-month-picker
v-if="dimensionValue === 'month'"
placeholder="请选择月份"
format="YYYY-MM"
value-format="YYYY-MM"
:allowClear="false"
dropdown-class-name="ant-calendar-dropdown-screen"
v-model='searchParams.month'
@change="onMonthChange" >
</a-month-picker>
<a-select
v-if="dimensionValue === 'quarter'"
class="right-select active"
v-model="searchParams.quarter"
placeholder="季度"
style="width: 180px"
show-search
@change="quarterSelectChange"
>
<a-select-option
v-for="(item, index) in quarterOptionData"
:key="index"
:value="item.text"
>
{{item.text}}
</a-select-option>
</a-select>
</div>
<div class="title-right-sub">
<span>会议总数</span>
<span class="num">{{totalAll}}</span>
</div>
</div>
<div class="echarts-box " id="meetingInformationChart"></div>
</div>
</div>
</template>
<script>
import { GetMeetingInformationData } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
import JYearDate from '@/components/jero/JYearDate'
export default {
name: 'MeetingInformationChart',
components: {
JYearDate
},
data() {
return {
totalAll: '', // 会议总数
dimensionValue: 'year', // 查询维度 默认是’year
// 维度查询的下拉框数据
dimensionOptionData: [
{text: '年份', value: 'year'},
{text: '季度', value: 'quarter'},
{text: '月份', value: 'month'},
],
quarterOptionData: [
{text: '第一季度', value: '1'},
{text: '第二季度', value: '2'},
{text: '第三季度', value: '3'},
{text: '第四季度', value: '4'},
],
// 查询条件
searchParams:{},
currentDateObj: {
year: '',
month: '',
quarter: ''
}
}
},
methods: {
getCurrentData() {
// 获取当前年份、月份和季度
let data = new Date()
let year = data.getFullYear()
let month = data.getMonth() + 1
this.currentDateObj.year = year
this.currentDateObj.month = month
switch (true) {
case (month < 4) :
this.currentDateObj.quarter = '第一季度'
break
case (month < 7) :
this.currentDateObj.quarter = '第二季度'
break
case (month < 10) :
this.currentDateObj.quarter = '第三季度'
break
case (month <= 12) :
this.currentDateObj.quarter = '第四季度'
break
default:
break
}
},
dimensionSelectChange(item) {
this.dimensionValue = item.value
if(this.dimensionValue === 'year') {
this.searchParams.year = this.currentDateObj.year + ''
} else if(this.dimensionValue === 'month') {
this.searchParams.month = `${this.currentDateObj.year}-${this.currentDateObj.month}`
} else if(this.dimensionValue === 'quarter') {
this.searchParams.year = this.currentDateObj.year + ''
this.searchParams.quarter = this.currentDateObj.quarter
}
this.getData()
},
onYearChange() {
this.getData()
},
onMonthChange() {
this.getData()
},
quarterSelectChange() {
this.getData()
},
// 获取查询参数
getQueryParams() {
let params = {
flag: this.dimensionValue,
}
if(this.dimensionValue === 'year') {
params.createTime = this.searchParams.year
} else if(this.dimensionValue === 'month') {
params.createTime = this.searchParams.month
} else if(this.dimensionValue === 'quarter') {
params.createTime = this.searchParams.quarter
params.year = this.searchParams.year
}
return params
},
getData() {
let params = this.getQueryParams()
GetMeetingInformationData(params).then(res => {
if(res.success) {
let data = res.result || {}
this.totalAll = data.total
this.$nextTick(() => {
this.initChart(data)
})
}
})
},
/**
* 初始化图表
* @param data = {leftData: X轴数据 resultMapList[] 柱状图数据}
*/
initChart(data) {
let xData = data.leftData
let echartsData = data.resultMapList[0].count
let tooltipTitle = data.resultMapList[0].cogName
let option = {
legend: {
show: false
},
grid: {
top: '40px'
},
tooltip: {
formatter: params => {
// 获取xAxis data中的数据
let dataStr = `<div style="color:#333;margin-left: 8px;font-size: 14px;margin-bottom: 10px;">${tooltipTitle}</div>`
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.name}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
})
return dataStr
}
},
xAxis: {
data: xData
},
series: [
{
name: '数量',
type: 'bar',
barMaxWidth:30,
itemStyle:{
borderRadius:[4,4,0,0],
},
data: echartsData
}
]
}
createBarChart('meetingInformationChart', option)
},
// 初始化查询条件的数据
initData() {
this.dimensionValue = 'year'
this.searchParams = {
year: this.currentDateObj.year + ''
}
}
},
created() {
this.getCurrentData()
//初始化数据
this.initData()
this.getData()
}
}
</script>
<style scoped lang="less">
@white: #fff;
@normal-color: #5C5C5A;
@primary: #069F99;
.select-info-box{
display: flex;
align-items: center;
justify-content: space-between;
.left-select > span:not(.label) {
margin-right: 15px;
color: @normal-color;
}
.label{
color: @normal-color;
}
}
// 会议总数的样式
.title-right-sub {
text-align: right;
margin-top: 5px;
span {
font-size: 16px;
color: #050525;
display: inline-block;
vertical-align: middle;
}
span.num {
font-size: 20px;
color: #FA9D81;
}
}
// 标题右侧的样式
.panel-title-right {
width: 50%;
height: 100%;
position: absolute;
right: 32px;
top: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
z-index: 100;
font-size: 0;
li {
font-size: 16px;
list-style: none;
color: @normal-color;
cursor: pointer;
padding: 0 10px;
margin-left: 20px;
}
li.active {
color: @primary-color;
position: relative;
&::after {
content: '';
display: inline-block;
width: 100%;
height: 2px;
background-color: @primary-color;
position: absolute;
bottom: 0;
left: 0;
}
}
}
.panel-box{
height: auto;
}
.meeting-wp-panel-box{
margin-bottom: 10px;
height: 530px!important;
.panel-content{
display: flex;
flex-direction: column;
.echarts-box{
flex: 1;
width: 100%;
}
}
}
</style>
@@ -0,0 +1,145 @@
<!--法规数量统计-->
<template>
<div class="panel-box regulation-box">
<div class="panel-title">
<img src="../../.././../assets/screenNew/icon_regulation.png" alt="">
<span>法规数量统计</span>
<div class='header-num'>
<span>法规总数</span>
<span class="num">{{totalAll}}</span>
</div>
</div>
<div class="panel-content">
<div class="echarts-box" id="regulationQuantityChart"></div>
</div>
</div>
</template>
<script>
import { GetRegulationQuantityData } from '@/screenApi/api'
import { createBarChart } from '../util/BarOptions'
export default {
name: 'RegulationQuantityChart',
data() {
return {
totalAll: '' // 法规总数
}
},
methods: {
getData() {
GetRegulationQuantityData().then(res => {
if(res.success) {
let data = res.result.data || []
this.initData(data)
this.$nextTick(() => {
this.initChart()
})
}
})
},
/**
*
* @param arr --data(数据), name(类名), totalAll(数据和), xaxisx轴字段)
*/
initData(arr) {
this.totalAll = arr[0].totalAll
this.xAxisData = arr[0].xaxis
this.yData = []
this.legendData = []
arr.map(tt => {
this.yData.push(tt.data || [])
this.legendData.push(tt.name)
})
},
// 初始化图表
initChart() {
let option = {
color: ['#069F99', '#3CC3BE','#97E3E0'],
grid: {
left: '0',
right: '0',
},
legend: {
right: 0
},
tooltip: {
formatter: params => {
// 获取xAxis data中的数据
let dataStr = ''
let total = 0
for (let i = 0; i < params.length; i++) {
total += parseInt(params[i].data)
}
dataStr += ` <div style="color:#333;margin-left: 8px;font-size: 14px">总数: ${total}</div>`
params.forEach(item => {
let color = ''
if(typeof item.color === 'string') {
color = item.color
} else {
color = item.color.colorStops[0].color
}
dataStr += `<div>
<div style="margin: 0 8px;">
<span style="display:inline-block;margin-right:5px;width:15px;height:10px;background-color:${color};border-radius: 3px"></span>
<span style="color:#666">${item.seriesName}</span>
<span style="color:#333;">${item.value}</span>
</div>
</div>`
})
return dataStr
}
},
xAxis: {
data: this.xAxisData
},
series: [
{
name: this.legendData[0],
type: 'bar',
stack: 'total',
barMaxWidth:20,
itemStyle:{
borderRadius:[0,0,0,0],
},
data: this.yData[0]
},
{
name: this.legendData[1],
type: 'bar',
stack: 'total',
barMaxWidth:20,
itemStyle:{
borderRadius:[0,0,0,0],
},
data: this.yData[1]
},
{
name: this.legendData[2],
type: 'bar',
stack: 'total',
barMaxWidth:20,
itemStyle:{
borderRadius:[4,4,0,0],
},
data: this.yData[2]
},
]
}
createBarChart('regulationQuantityChart', option)
}
},
created() {
this.getData()
}
}
</script>
<style scoped lang="less">
.regulation-box{
width: calc(60% - 10px);
margin-right: 10px;
}
</style>
+151
View File
@@ -0,0 +1,151 @@
<template>
<div class="screen-wp">
<!-- 法规数量统计-->
<regulation-quantity-chart></regulation-quantity-chart>
<!-- 专家数量统计-->
<expert-quantity-chart></expert-quantity-chart>
<!-- 会议信息日历-->
<meeting-calendar></meeting-calendar>
<!-- 会议信息统计-->
<meeting-information-chart></meeting-information-chart>
</div>
</template>
<script>
//法规数量统计 RegulationQuantityChart
import RegulationQuantityChart from './RegulationQuantityChart'
//专家数量统计 ExpertQuantityChart
import ExpertQuantityChart from './ExpertQuantityChart'
//会议信息日历 MeetingCalendar
import MeetingCalendar from './MeetingCalendar'
//会议信息统计 MeetingInformationChart
import MeetingInformationChart from './MeetingInformationChart'
export default {
name: 'index',
components: {
// 法规数量统计
RegulationQuantityChart,
// 专家数量统计
ExpertQuantityChart,
// // 会议信息日历
MeetingCalendar,
// 会议信息统计
MeetingInformationChart
}
}
</script>
<style scoped lang="less">
.screen-wp{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
@general-height: 480px;
.panel-box:not(.calendar-panel-box){
height: @general-height;
display: flex;
flex-direction: column;
// 内容的部分
/deep/ .panel-content {
flex: 1;
.echarts-box {
width: 100%;
height: 100%;
}
}
}
.calendar-panel-box{
height: auto;
}
// 标题右侧的文字
::v-deep .header-num{
position: absolute;
right: 32px;
top: 0;
span {
font-size: 16px;
color: #050525;
display: inline-block;
vertical-align: middle;
//text-shadow: 0 0 5px #88D8FB;
}
span.num {
font-size: 20px;
color: #FA9D81;
}
}
// 偶数位增加 10px的右边框
::v-deep .half-box:nth-of-type(2n + 1) {
margin-right: 10px;
}
::v-deep .half-box:nth-of-type(2n + 2) {
margin-right: 0!important;
}
</style>
<style lang="less">
//@normal-color: rgba(256, 256, 256, 0.2);
//.ant-calendar-dropdown-screen{
// .ant-calendar{
// border: none;
// box-shadow: 0 0 4px #7599E8 inset;
// }
// .ant-calendar-month-panel-body,
// .ant-calendar-month-panel-header,
// .ant-calendar-year-panel-body,
// .ant-calendar-year-panel-header
// {
// background-color: #181F55;
// border: none!important;
// color: #fff;
// }
// td a,
// .ant-calendar-month-panel-year-select-content,
// .ant-calendar-year-panel-decade-select
// {
// color: #fff;
// }
// .ant-calendar-month-panel-prev-year-btn::after,
// .ant-calendar-month-panel-prev-year-btn::before,
// .ant-calendar-month-panel-next-year-btn::before,
// .ant-calendar-month-panel-next-year-btn::after
// {
// border-color: #fff;
// }
// // 选中的效果
// .ant-calendar-month-panel-selected-cell .ant-calendar-month-panel-month,
// .ant-calendar-year-panel-selected-cell .ant-calendar-year-panel-year{
// background-color: #4364C2;
// }
//
// .ant-calendar-header a:hover{
// color: #fff;
// background-color: #7599E8;
// //&::after,
// //&::before{
// // color: #fff;
// //}
// }
//
// .ant-calendar-year-panel-last-decade-cell a,
// .ant-calendar-year-panel-next-decade-cell a
// {
// color: @normal-color;
// }
//// 年份选择器上面的输入框
// .ant-calendar-input-wrap{
// background-color: #181F55;
// border-color: @normal-color;
// input{
// background-color: #181F55;
// border: none!important;
// color: #fff;
// }
// }
//}
</style>