Commit 95a84f90 authored by 郭铭瑶's avatar 郭铭瑶 🤘

病害防控

parent 9d107014
<template>
<div id="app">
<m-loader v-show="$store.state.showLoading"/>
<m-title hideDate hideTime :bgImg="require('@/assets/images/title-bg3.png')"/>
<DiseaseMap />
<router-view :key="$route.fullPath"/>
</div>
</template>
<script>
import DiseaseMap from './views/components/disease-map'
export default {
name: 'App',
components: {
DiseaseMap,
}
}
</script>
<style lang="stylus" scoped>
#app
background url('./assets/images/bg.png') no-repeat
background-size 110%
background-position 90% -50%
</style>
<style lang="stylus">
@import './assets/css/reset.styl'
@font-face
font-family DIN
src url(./assets/font/DIN-Medium.otf)
// @font-face
// font-family Microsoft YaHei UI
// src url(./assets/font/Microsoft-YaHei-UI-Bold.ttf)
@font-face
font-family Microsoft YaHei UI
src url(./assets/font/Hei.ttf)
@font-face
font-family Pangmenzhengdao
src url(./assets/font/pangmenzhengdao.ttf)
html, body
background-color #000 !important
width 100%
height 100%
height 100vh
overflow hidden
user-select none
#app
font-family DIN, 'Avenir', Helvetica, Arial, sans-serif
font-family Microsoft YaHei UI, DIN, 'Avenir', Helvetica, Arial, sans-serif
-webkit-font-smoothing antialiased
-moz-osx-font-smoothing grayscale
width 100%
height 100%
font-size 1rem
overflow: hidden
color #ccc
color #fff
user-select none
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width: 0.5rem;
......
......@@ -12,9 +12,9 @@ $color-main = #5BD5FF
height 100%
.ivu-select-selected-value
height 100%
font-size 1rem
font-weight bold
line-height 2
font-size .8rem
// font-weight bold
line-height 1.5
.ivu-select-selection
.ivu-select-dropdown
font-size 1rem
......@@ -28,11 +28,11 @@ $color-main = #5BD5FF
$blur()
.ivu-select-arrow
color $color-main
line-height 2
font-size 1rem
line-height 1.5
font-size .8rem
.ivu-select-item
.ivu-dropdown-item
font-size 1rem !important
font-size .8rem !important
text-align center
color #fff
background rgba(0,0,0,0.8)
......@@ -40,3 +40,8 @@ $color-main = #5BD5FF
&.ivu-select-item-selected
color $edgeColor
font-weight bold
.custom-select
position absolute
top 1rem
right 1rem
width 7rem
This diff is collapsed.
<template>
<div class="card-wrapper">
<div class="card-wrapper" :style="`background-image:url(${require('@/assets/images/card-bg.png')})`">
<div class="card-title" :style="`color:${color}`">
<img src="@/assets/images/arrow.png"/>
{{title}}
<div class="dot"/>
<div class="line"/>
<img src="@/assets/images/arrow.png" style="transform:rotate(180deg)"/>
</div>
<div class="card-content">
<slot />
......@@ -28,24 +28,18 @@ export default {
<style lang="stylus" scoped>
.card-wrapper
background $cardBg
border-right 0.2rem solid $edgeColor
background-size cover
.card-title
display flex
align-items center
color $cardFontColor
font-size 1.4rem
font-family $font-pang
.dot
width 0.4rem
height 1rem
background $edgeColor
margin 0 0.5rem
.line
height 1px
flex 1
background $edgeColor
opacity 0.3
.card-content
padding 0.5rem 1rem
justify-content space-around
color $edgeColor
font-size 1.2rem
font-weight bold
width 50%
margin .5rem auto
img
width 1rem
// .card-content
// padding 0.5rem 1rem
</style>
......@@ -116,7 +116,7 @@ export default {
Object.assign({}, this.defaultOptions.yAxis, {min: 0, max: y2Max, interval: y2Max / 5}),
]
} else {
options.yAxis = Object.assign({}, this.defaultOptions.yAxis, yAxis)
options.yAxis = Object.assign({}, this.defaultOptions.yAxis, yAxis, this.options.yAxis)
}
// 如果key在yAxis上则x、y轴对调
......
......@@ -73,7 +73,7 @@ export default {
height 100%
background-size cover
background-position center
background-color #061627
// background-color #061627
position relative
display grid
grid-gap 1rem
......
......@@ -7,7 +7,13 @@
</span>
<span v-if="!hideTime" class="moment time">{{time}}</span>
<img :src="bgImg" draggable="false"/>
<p :style="style"><slot /></p>
<p :style="style">{{menus[curIndex].title}}</p>
<div class="menu menu-left">
<div @click="curIndex = menus.indexOf(item)" v-for="item in menus.slice(0,3)" :key="item.name" :class="`${menus[curIndex].name === item.name ? 'on' : ''}`"><span>{{item.name}}</span></div>
</div>
<div class="menu menu-right">
<div @click="curIndex = menus.indexOf(item)" v-for="item in menus.slice(3)" :key="item.name" :class="`${menus[curIndex].name === item.name ? 'on' : ''}`"><span>{{item.name}}</span></div>
</div>
</div>
</template>
......@@ -35,7 +41,7 @@ export default {
},
size: {
type: String,
default: '2.8rem',
default: '1.4rem',
},
},
data() {
......@@ -44,6 +50,15 @@ export default {
timer: null,
time: null,
style: {},
curIndex: 0,
menus: [
{name: '病害防控', title: '病害防控大数据管理与服务平台'},
{name: '质量安全'},
{name: '稻鱼种养'},
{name: '海洋牧场'},
{name: '水产价格', title: '水产品价格分析驾驶舱'},
{name: '苗种数据'},
],
}
},
mounted() {
......@@ -54,9 +69,9 @@ export default {
}
if (this.color) {
this.style = {
'text-shadow': `0 0.2rem 0.4rem ${this.color}`,
// 'text-shadow': `0 0.2rem 0.4rem ${this.color}`,
'color': this.color,
'background-image': `linear-gradient(to bottom, #fff, ${this.color})`
// 'background-image': `linear-gradient(to bottom, #fff, ${this.color})`
}
}
this.style = {...this.style, 'font-size': this.size}
......@@ -88,6 +103,7 @@ export default {
</script>
<style lang="stylus" scoped>
$color = #25e7f6
.monitor-title
display flex
align-items center
......@@ -95,7 +111,36 @@ export default {
position relative
background-size cover
background-position center
font-family $font-pang
// font-family $font-pang
height 4rem
.menu
position absolute
display flex
align-items center
justify-content space-around
color $color
font-weight bold
width 20%
padding-top 1rem
&.menu-left
left 15%
&.menu-right
right 15%
>div
cursor pointer
padding .3rem 1rem
border .1rem solid transparent
box-sizing content-box
transform skew(30deg)
>span
display inline-block
transform skew(-30deg)
&:hover,
&.on
border-color $color
background $color-map()
&.on
color #fff
.moment
z-index 100
position absolute
......@@ -113,27 +158,13 @@ export default {
transform translateY(-80%)
img
position absolute
width 100%
width 120%
height 100%
top 0
left 0
animation shine 2.5s linear reverse infinite
left -10%
>p
text-shadow 0 0.2rem 0.4rem #25e7f6
background-clip text
-webkit-background-clip text
color #25e7f6
-webkit-text-fill-color transparent
background-image linear-gradient(to bottom, #fff, #25e7f6)
@keyframes shine {
0% {
opacity 1
}
50% {
opacity 0.7
}
100% {
opacity 1
}
}
color $color
z-index 9
letter-spacing .1rem
font-weight bold
</style>
......@@ -5,11 +5,12 @@ import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import {Row, Col, Select, Option, DatePicker} from 'view-design'
import {Row, Col, Select, Option, DatePicker, Icon} from 'view-design'
import ajax from '@/server/ajax'
import api from '@/server/api'
import common from '@/util/common'
import moment from 'moment'
import echarts from 'echarts'
import MonitorComponents from '@/components/MonitorComponents'
import 'view-design/dist/styles/iview.css'
import 'moment/locale/zh-cn'
......@@ -20,12 +21,14 @@ Vue.prototype.$ajax = ajax
Vue.prototype.$api = api
Vue.prototype.$com = common
Vue.prototype.$moment = moment
Vue.prototype.$echarts = echarts
Vue.use(MonitorComponents)
Vue.component('Row', Row)
Vue.component('i-col', Col)
Vue.component('Select', Select)
Vue.component('Option', Option)
Vue.component('DatePicker', DatePicker)
Vue.component('Icon', Icon)
/* eslint-disable no-new */
new Vue({
el: '#app',
......
<template>
<div class="border-box">
<div class="edge"></div>
<div class="edge"></div>
<div class="edge"></div>
<div class="edge"></div>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'BorderBox',
data() {
return {}
},
}
</script>
<style lang="stylus" scoped>
.border-box
border .1rem solid $color-map(.8)
position relative
padding 1rem 2rem
background-color rgba(0,0,0,.5)
>.edge
width 0
height 0
border .3rem solid $edgeColor
position absolute
&:nth-of-type(1)
top 0
left 0
border-right-color transparent
border-bottom-color transparent
&:nth-of-type(2)
top 0
right 0
border-left-color transparent
border-bottom-color transparent
&:nth-of-type(3)
bottom 0
left 0
border-right-color transparent
border-top-color transparent
&:nth-of-type(4)
bottom 0
right 0
border-left-color transparent
border-top-color transparent
</style>
<template>
<div class="map-wrapper">
<div id="map" ref="map"/>
<div v-if="data.length > 0" class="visualmap">
<p>{{visualLabel[0]}}</p>
<div class="bar" />
<p>{{visualLabel[1]}}</p>
</div>
</div>
</template>
<script>
import china from 'echarts/map/json/china.json'
const mapData = [
{ name: '北京', value: 177 },
{ name: '天津', value: 42 },
{ name: '河北', value: 102 },
{ name: '山西', value: 81 },
{ name: '内蒙古', value: 17 },
{ name: '辽宁', value: 67 },
{ name: '吉林', value: 182 },
{ name: '黑龙江', value: 100 },
{ name: '上海', value: 24 },
{ name: '江苏', value: 299 },
{ name: '浙江', value: 114 },
{ name: '安徽', value: 29 },
{ name: '福建', value: 316 },
{ name: '江西', value: 91 },
{ name: '山东', value: 19 },
{ name: '河南', value: 137 },
{ name: '湖北', value: 26 },
{ name: '湖南', value: 114 },
{ name: '重庆', value: 91 },
{ name: '四川', value: 25 },
{ name: '贵州', value: 62 },
{ name: '云南', value: 83 },
{ name: '西藏', value: 9 },
{ name: '陕西', value: 80 },
{ name: '甘肃', value: 256 },
{ name: '青海', value: 10 },
{ name: '宁夏', value: 18 },
{ name: '新疆', value: 67 },
{ name: '广东', value: 123 },
{ name: '广西', value: 59 },
{ name: '海南', value: 14 }
]
export default {
name: 'ChinaMap',
props: {
data: {
type: Array,
default() {
return []
}
},
visualLabel: {
type: Array,
default() {
return ['高', '低']
}
},
visualFormatter: {
type: [String, Function],
// default: '{b}<br/>综合种养产量:{c}'
default() {
return (e) => {
const {data} = e
return `
<h3>${data.name}</h3>
<p>养殖面积:${data.area || 0}(公顷)</p>
<p>淡水养殖产量:${data.water || 0}(吨)</p>
<p>稻田产量:${data.farm || 0}(吨)</p>
`
}
}
},
visualConfig: {
type: Object,
default() {
return {}
}
},
},
data() {
return {
map: null,
mapName: 'china',
config: {
geo: {
map: 'china',
left: '1%',
right: '1%',
bottom: '3%',
top: 'auto',
zoom: 1, //当前视角的缩放比例
// roam: true, //是否开启平游或缩放
// scaleLimit: { //滚轮缩放的极限控制
// min: 0.8,
// max: 2,
// },
label: {
show: true,
color: '#fff',
fontSize: 12 * this.sizeRate,
// normal: {
// show: false,
// color: '#cfcfcf',
// },
emphasis: {
color: '#fff',
// fontSize: Math.floor(screen.height * 2 / 100),
// fontFamily: 'Pangmenzhengdao',
}
},
itemStyle: {
normal: {
areaColor: 'rgba(0, 191, 255, 0.1)',
borderColor: 'rgba(0, 191, 255, 0.9)',
borderWidth: 0.4,
},
emphasis: {
areaColor: 'rgba(0, 191, 255, 0.9)',
}
},
regions: [],
},
series: []
},
curProvince: null,
}
},
mounted() {
this.$nextTick(this.initMap)
},
computed: {
sizeRate() {
return Number((screen.height / 800).toFixed(1))
},
},
methods: {
initMap() {
// 初始化echarts
this.$echarts.registerMap(this.mapName, china)
this.map = this.$echarts.init(this.$refs.map)
this.map.setOption(this.config)
this.addEvent()
this.config.series.push({
type: 'map',
map: this.mapName,
geoIndex: 0,
data: mapData,
})
this.config.tooltip = {
trigger: 'item',
formatter: this.visualFormatter,
}
this.config.visualMap = Object.assign({
show: false,
inRange: {
opacity: 0.5,
color: ['rgba(91, 213, 255, 0.1)', 'rgba(91, 213, 255, 0.8)']
}
}, this.visualConfig)
this.map.setOption(this.config)
},
addEvent() {
// 监听地图点击事件
this.map.on('click', (ev) => {
const {name} = ev.data
console.log(name)
this.setRegions(name)
this.curProvince = name
this.$emit('select', name)
})
// 点击空白处则取消选中状态
this.map.getZr().on('click', e => {
if (!e.target && this.curProvince) {
const name = this.curProvince
this.setRegions(null)
this.$emit('select', name)
}
})
},
setRegions(name) {
this.curProvince = name
if (!name) {
this.config.geo.regions = []
this.map.setOption(this.config)
return
}
let regions = [{
name,
selected: true,
itemStyle: {
areaColor: '#5ad4ff',
shadowColor: 'rgba(0, 0, 0, 1)',
shadowBlur: 10,
shadowOffsetY: 10,
shadowOffsetX: -5,
}
}]
if (this.config.geo.regions.length > 0 && this.config.geo.regions[0].name == name) {
regions = []
}
this.config.geo.regions = regions
this.map.setOption(this.config)
},
},
watch: {
data(cur, past) {
if (cur && cur !== past && cur.length > 0) {
this.config.series.push({
type: 'map',
map: this.mapName,
geoIndex: 0,
data: cur,
})
this.config.tooltip = {
trigger: 'item',
formatter: this.visualFormatter,
}
this.config.visualMap = Object.assign({
show: false,
inRange: {
opacity: 0.5,
color: ['rgba(91, 213, 255, 0.1)', 'rgba(91, 213, 255, 0.8)']
}
}, this.visualConfig)
this.map.setOption(this.config)
}
}
}
}
</script>
<style lang="stylus" scoped>
.map-wrapper
width 42%
height 94%
position absolute
#map
width 100%
height 100%
z-index 99
.visualmap
color #fff
position absolute
top 50%
left 5%
text-align center
.bar
width 2rem
height 6rem
background linear-gradient(to bottom, rgba(91, 213, 255, 0.8), rgba(91, 213, 255, 0.1))
</style>
<template>
<div class="consultation-sum">
<div>
<p>区域会诊统计</p><span>单位:个</span>
<div class="list-wrapper">
<div v-for="(item, index) in areas" :key="item.name">
<p>{{index + 1}}.{{item.name}}</p>
<div class="bar-wrapper"><div :style="`width:${item.rate}%;background-color:${colors[index]}`"></div></div>
<m-count :value="item.count" :decimal="0"/>
</div>
</div>
</div>
<div>
<p>病种会诊统计</p><span>单位:个</span>
<div class="list-wrapper">
<div v-for="(item, index) in areas" :key="item.name">
<p>{{index + 1}}.{{item.name}}</p>
<div class="bar-wrapper"><div :style="`width:${item.rate}%;background-color:${colors[index]}`"></div></div>
<m-count :value="item.count" :decimal="0"/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ConsultationSum',
data() {
return {
colors: ['#f24044', '#fca53a', '#edcd3c', '#eee53a', '#83dc29', '#1fcea9', '#25add1'],
areas: [
{name: '广东', count: 33240, rate: 90},
{name: '辽宁', count: 23450, rate: 80},
{name: '四川', count: 13423, rate: 70},
{name: '江苏', count: 2342, rate: 60},
{name: '甘肃', count: 2098, rate: 50},
{name: '陕西', count: 1342, rate: 40},
{name: '青海', count: 876, rate: 30},
],
diseases: [
{name: '小瓜虫病', count: 23423, rate: 60},
{name: '出血性腐烂病', count: 21002, rate: 55},
{name: '烂鳍病', count: 14532, rate: 50},
{name: '烂腮病', count: 9834, rate: 45},
{name: '棉口病', count: 8723, rate: 40},
{name: '水霉病', count: 6789, rate: 30},
{name: '锚头虱病', count: 345, rate: 20},
],
}
},
}
</script>
<style lang="stylus" scoped>
.consultation-sum
width 100%
height 100%
overflow hidden
display flex
>div
flex 1
padding-right .5rem
>p
color $edgeColor
font-weight bold
>span
display block
text-align right
font-size .9rem
.list-wrapper
height 80%
overflow-y auto
padding-right .5rem
>div
display flex
align-items center
justify-content space-between
line-height 1.8
.bar-wrapper
flex 1
margin 0 .5rem
>div
height .5rem
border-radius .5rem
</style>
<template>
<div class="disease-forecast">
<div class="chart" ref="chart" />
<Select class="custom-select" v-model="type">
<Option v-for="item in options" :key="item" :value="item">{{item}}</Option>
</Select>
</div>
</template>
<script>
import echarts from 'echarts'
export default {
name: 'DiseaseForecast',
data() {
return {
type: '小龙虾',
options: ['小龙虾'],
chart: null,
option: {
tooltip: {
trigger: 'axis',
},
grid: {
top: '15%',
left: '5%',
right: '5%',
bottom: '10%',
width: 'auto',
height: 'auto',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
axisLabel: {
textStyle: {
color: '#ccc',
},
fontSize: this.fontSize,
},
data: ['2014', '2015', '2016', '2017', '2018', '2019', '2020'],
},
yAxis: {
type: 'value',
// name: '单位:个',
max: 500,
min: 0,
interval: 100,
axisLine: {
show: false,
},
axisLabel: {
textStyle: {
color: '#fff',
},
fontSize: this.fontSize,
},
nameTextStyle: {
color: '#ccc',
fontSize: this.fontSize,
},
splitLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
},
series: [
{itemStyle: {color: 'gold'}, areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{offset: 0, color: 'rgba(255,215,0,0.8)'},
{offset: 1, color: 'rgba(255,215,0,0.1)'}
])},
smooth: true, type: 'line', data: [300, 280, 400, 380, 360, 320, 300]},
],
dataZoom: [{
start: 10,
end: 80,
backgroundColor: '#105179',
fillerColor: '#46b9ef',
borderColor: 'transparent',
bottom: '2%',
height: 10,
borderRadius: 10,
handleSize: '200%',
handleStyle: {
color: '#fff',
},
textStyle: {
color: '#fff',
},
}],
}
}
},
mounted() {
this.$nextTick(this.init)
},
computed: {
fontSize() {
return Math.floor(screen.height * 1.48 / 100)
},
},
methods: {
init() {
this.chart = this.$echarts.init(this.$refs.chart)
this.chart.setOption(this.option)
}
}
}
</script>
<style lang="stylus" scoped>
.disease-forecast
width 100%
height 100%
>.chart
width 100%
height 70%
</style>
<template>
<div class="map-wrapper">
<div id="map" ref="map"/>
</div>
</template>
<script>
import china from 'echarts/map/json/china.json'
const mapData = [
{name: '海门', value: [121.15, 31.89, 90]},
{name: '鄂尔多斯', value: [109.781327, 39.608266, 120]},
{name: '招远', value: [120.38, 37.35, 142]},
{name: '舟山', value: [122.207216, 29.985295, 123]},
// { name: '北京', value: 177 },
// { name: '天津', value: 42 },
// { name: '河北', value: 102 },
// { name: '山西', value: 81 },
// { name: '内蒙古', value: 17 },
// { name: '辽宁', value: 67 },
// { name: '吉林', value: 182 },
// { name: '黑龙江', value: 100 },
// { name: '上海', value: 24 },
// { name: '江苏', value: 299 },
// { name: '浙江', value: 114 },
// { name: '安徽', value: 29 },
// { name: '福建', value: 316 },
// { name: '江西', value: 91 },
// { name: '山东', value: 19 },
// { name: '河南', value: 137 },
// { name: '湖北', value: 26 },
// { name: '湖南', value: 114 },
// { name: '重庆', value: 91 },
// { name: '四川', value: 25 },
// { name: '贵州', value: 62 },
// { name: '云南', value: 83 },
// { name: '西藏', value: 9 },
// { name: '陕西', value: 80 },
// { name: '甘肃', value: 256 },
// { name: '青海', value: 10 },
// { name: '宁夏', value: 18 },
// { name: '新疆', value: 67 },
// { name: '广东', value: 123 },
// { name: '广西', value: 59 },
// { name: '海南', value: 14 }
]
export default {
name: 'DiseaseMap',
props: {
data: {
type: Array,
default() {
return []
}
},
visualLabel: {
type: Array,
default() {
return ['高', '低']
}
},
visualFormatter: {
type: [String, Function],
// default: '{b}<br/>综合种养产量:{c}'
default() {
return () => {
// const {data} = e
return `
<div class="disease-map-tooltip-info">
<h3>养殖场名称</h3>
<p><span>联系人:</span>陆建平</p>
<p><span>联系电话:</span>15623547899</p>
<p><span>地址:</span>苏州市吴中区金庭镇</p>
<p><span>监测点类型:</span>成鱼、虾、蟹、贝等养殖场</p>
<p><span>养殖品种:</span>中华绒螯蟹(河蟹)</p>
</div>
`
// return `
// <h3>${data.name}</h3>
// <p>养殖面积:${data.area || 0}(公顷)</p>
// <p>淡水养殖产量:${data.water || 0}(吨)</p>
// <p>稻田产量:${data.farm || 0}(吨)</p>
// `
}
}
},
visualConfig: {
type: Object,
default() {
return {}
}
},
},
data() {
return {
map: null,
mapName: 'china',
config: {
geo: {
map: 'china',
left: '1%',
right: '1%',
bottom: '3%',
top: 'auto',
zoom: 1, //当前视角的缩放比例
// roam: true, //是否开启平游或缩放
// scaleLimit: { //滚轮缩放的极限控制
// min: 0.8,
// max: 2,
// },
label: {
show: true,
color: '#fff',
fontSize: 12 * this.sizeRate,
// normal: {
// show: false,
// color: '#cfcfcf',
// },
emphasis: {
color: '#fff',
// fontSize: Math.floor(screen.height * 2 / 100),
// fontFamily: 'Pangmenzhengdao',
}
},
itemStyle: {
normal: {
areaColor: 'rgba(91, 213, 255, 0.2)',
borderColor: 'rgba(91, 213, 255, 0.9)',
borderWidth: 0.5,
},
emphasis: {
areaColor: 'rgba(91, 213, 255, 0.2)',
borderColor: 'rgba(91, 213, 255, 0.9)',
}
},
regions: [],
},
series: []
},
curProvince: null,
}
},
mounted() {
this.$nextTick(this.initMap)
},
computed: {
sizeRate() {
return Number((screen.height / 800).toFixed(1))
},
},
methods: {
initMap() {
// 初始化echarts
this.$echarts.registerMap(this.mapName, china)
this.map = this.$echarts.init(this.$refs.map)
// this.addEvent()
this.config.series.push({
type: 'scatter', // series图表类型
coordinateSystem: 'geo', // series坐标系类型
data: mapData,
itemStyle: {
color: 'gold'
},
symbolSize: 20 * this.sizeRate,
symbol: 'pin',
})
this.config.tooltip = {
trigger: 'item',
formatter: this.visualFormatter,
// extraCssText: `background-image:url(${require('@/assets/images/tooltip.png')});background-size:cover;`,
}
this.map.setOption(this.config)
},
addEvent() {
// 监听地图点击事件
this.map.on('click', (ev) => {
const {name} = ev.data
console.log(name)
this.setRegions(name)
this.curProvince = name
this.$emit('select', name)
})
// 点击空白处则取消选中状态
this.map.getZr().on('click', e => {
if (!e.target && this.curProvince) {
const name = this.curProvince
this.setRegions(null)
this.$emit('select', name)
}
})
},
setRegions(name) {
this.curProvince = name
if (!name) {
this.config.geo.regions = []
this.map.setOption(this.config)
return
}
let regions = [{
name,
selected: true,
itemStyle: {
areaColor: '#5ad4ff',
shadowColor: 'rgba(0, 0, 0, 1)',
shadowBlur: 10,
shadowOffsetY: 10,
shadowOffsetX: -5,
}
}]
if (this.config.geo.regions.length > 0 && this.config.geo.regions[0].name == name) {
regions = []
}
this.config.geo.regions = regions
this.map.setOption(this.config)
},
},
// watch: {
// data(cur, past) {
// if (cur && cur !== past && cur.length > 0) {
// this.config.series.push({
// type: 'scatter',
// coordinateSystem: 'geo',
// // map: this.mapName,
// // geoIndex: 0,
// data: cur,
// })
// this.config.tooltip = {
// trigger: 'item',
// formatter: this.visualFormatter,
// }
// // this.config.visualMap = Object.assign({
// // show: false,
// // inRange: {
// // opacity: 0.5,
// // color: ['rgba(91, 213, 255, 0.1)', 'rgba(91, 213, 255, 0.8)']
// // }
// // }, this.visualConfig)
// this.map.setOption(this.config)
// }
// }
// }
}
</script>
<style lang="stylus" scoped>
.map-wrapper
width 42%
height 94%
position absolute
#map
width 100%
height 100%
z-index 99
</style>
<style lang="stylus">
.disease-map-tooltip-info
color $edgeColor
padding 1rem
border .1rem solid $edgeColor
span
color #fff
</style>
<template>
<div class="disease-summary">
<div class="btn-wrapper">
<div v-for="btn in btns" :key="btn" @click="handleSelect(btn)" :class="`${btn === curBtn ? 'on' : ''}`">{{btn}}</div>
</div>
<div class="card-box">
<BorderBox>
<h3>远程诊断</h3>
<div class="wrapper">
<div v-for="item in long" :key="item.title">
<p>{{item.title}}</p>
<m-count class="count" :value="item.count" :decimal="0" color="#00f2ff"/>
</div>
</div>
</BorderBox>
<BorderBox>
<h3>专项检测</h3>
<div class="wrapper">
<div v-for="item in special" :key="item.title">
<p>{{item.title}}</p>
<m-count class="count" :value="item.count" :decimal="0" color="#00f2ff"/>
</div>
</div>
</BorderBox>
<BorderBox>
<h3>病情测报</h3>
<div class="wrapper">
<div v-for="item in disease" :key="item.title">
<p>{{item.title}}</p>
<m-count class="count" :value="item.count" :decimal="0" color="#00f2ff"/>
</div>
</div>
</BorderBox>
</div>
</div>
</template>
<script>
import BorderBox from './border-box'
export default {
name: 'DiseaseSum',
components: {
BorderBox,
},
data() {
return {
curBtn: '测报点',
btns: ['测报点', '鱼病医院'],
long: [
{'title': '年诊量', count: 568},
{'title': '当日诊断', count: 365},
{'title': '在线人数', count: 9852},
],
special: [
{'title': '年采样量', count: 235},
{'title': '年检测量', count: 587},
{'title': '阳性数量', count: 787},
],
disease: [
{'title': '年上报量', count: 25487},
{'title': '年发病上报量', count: 9852},
],
}
},
methods: {
handleSelect(name) {
this.curBtn = name
},
}
}
</script>
<style lang="stylus" scoped>
$color = #25e7f6
.disease-summary
width 100%
height 100%
z-index 999
.btn-wrapper
width 50%
margin 0 auto
display flex
align-items center
justify-content center
color #fff
>div
cursor pointer
padding .3rem 1rem
border .1rem solid $color
width 7rem
text-align center
&:first-child
border-radius 1.5rem 0 0 0
border-right none
&:last-child
border-radius 0 1.5rem 0 0
&:hover,
&.on
color #fff
background $color-map()
&.on
color $color
font-weight bold
.card-box
display flex
flex-wrap wrap
text-align center
h3
margin-bottom .5rem
.count
font-family $font-pang
font-size 1.4rem !important
>div
flex 0 0 45%
margin 1rem
.wrapper
display flex
justify-content space-between
</style>
<template>
<div class="disease">
<p>预警指标:预报,问诊,用药,天气情况</p>
<Select v-model="type" class="custom-select" size="small">
<Option v-for="item in options" :key="item" :value="item">{{item}}</Option>
</Select>
<div class="map" ref="map" />
</div>
</template>
<script>
import china from 'echarts/map/json/china.json'
const mapData = [
{ name: '北京', value: 177 },
{ name: '天津', value: 42 },
{ name: '河北', value: 102 },
{ name: '山西', value: 81 },
{ name: '内蒙古', value: 17 },
{ name: '辽宁', value: 67 },
{ name: '吉林', value: 182 },
{ name: '黑龙江', value: 100 },
{ name: '上海', value: 24 },
{ name: '江苏', value: 299 },
{ name: '浙江', value: 114 },
{ name: '安徽', value: 29 },
{ name: '福建', value: 316 },
{ name: '江西', value: 91 },
{ name: '山东', value: 19 },
{ name: '河南', value: 137 },
{ name: '湖北', value: 26 },
{ name: '湖南', value: 114 },
{ name: '重庆', value: 91 },
{ name: '四川', value: 25 },
{ name: '贵州', value: 62 },
{ name: '云南', value: 83 },
{ name: '西藏', value: 9 },
{ name: '陕西', value: 80 },
{ name: '甘肃', value: 256 },
{ name: '青海', value: 10 },
{ name: '宁夏', value: 18 },
{ name: '新疆', value: 67 },
{ name: '广东', value: 123 },
{ name: '广西', value: 59 },
{ name: '海南', value: 14 }
]
export default {
name: 'Disease',
data() {
return {
mapName: 'china',
map: null,
config: {
geo: {
map: 'china',
left: 0,
top: 0,
bottom: 0,
right: '15%',
zoom: 1,
itemStyle: {
areaColor: 'rgba(0, 191, 255, 0.1)',
borderColor: 'rgba(0, 191, 255, 0.9)',
// borderWidth: 0.1,
}
},
tooltip: {
trigger: 'item',
formatter: '{b}<br/>{c}(单位)'
},
toolbox: {
show: false,
},
visualMap: {
min: 0,
max: 200,
left: 'auto',
right: 0,
realtime: false,
calculable: true,
textStyle: {
color: '#fff',
},
inRange: {
color: ['green', 'yellow', 'red']
}
},
series: [
{
type: 'map',
geoIndex: 0,
map: this.mapName,
data: mapData,
}
],
},
options: [
'小龙虾',
],
type: '小龙虾',
}
},
mounted() {
this.$nextTick(this.init)
},
methods: {
init() {
this.$echarts.registerMap(this.mapName, china)
this.map = this.$echarts.init(this.$refs.map)
this.map.setOption(this.config)
},
}
}
</script>
<style lang="stylus" scoped>
.disease
width 100%
height 100%
.map
width 100%
height 90%
p
text-align center
</style>
<template>
<div class="questions">
<p>
年问答量:<span class="blue"><m-count color="#5bd5ff" :value="12932" :decimal="0"/></span>&nbsp;&nbsp;&nbsp;
月问答量:<span class="blue"><m-count color="#5bd5ff" :value="150" :decimal="0"/></span>
</p>
<div v-for="(item, index) in list" :key="index">
<span>{{item.name}}</span>
<p>问:{{item.question}}</p>
<span>{{item.time}}分钟前</span>
<span class="blue"><Icon type="md-text" /> {{item.reply}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'Questions',
data() {
return {
list: [
{name: '张衡', question: '高温天气草鱼生病是不是养殖密度', time: 2, reply: 2},
{name: '李星辰', question: '与头部和脊背发黑,独游,不吃食物', time: 10, reply: 0},
{name: '王兴鑫', question: '突然提前至夜间10时,浮头次数增多', time: 12, reply: 10},
{name: '周彦', question: '水温12-20℃的时候,鱼种成群打架', time: 14, reply: 4},
],
}
},
}
</script>
<style lang="stylus" scoped>
.questions
width 100%
height 100%
>p
text-align center
>div
display flex
align-items center
justify-content space-around
padding 1rem 0
&+div
border-top .1rem solid $cardFontColor
span
color $edgeColor
display inline-block
&:first-child
width 4rem
&:nth-of-type(2)
width 4.5rem
&:last-child
width 2.5rem
&.blue
color $cardFontColor
p
width 56%
overflow hidden
text-overflow ellipsis
white-space nowrap
</style>
<template>
<div class="special-monitoring">
<div class="chart" ref="chart" />
<Select class="custom-select" v-model="disease">
<Option v-for="item in options" :key="item" :value="item">{{item}}</Option>
</Select>
</div>
</template>
<script>
export default {
name: 'SpecialMonitoring',
data() {
return {
disease: '出血性腐烂病',
options: ['出血性腐烂病'],
chart: null,
option: {
tooltip: {
trigger: 'axis',
},
legend: {
width: '100%',
textStyle: {
color: '#ccc',
fontSize: this.fontSize,
},
data: ['阳性监测点数量', '阳性样品数量'],
},
grid: {
top: '15%',
left: '5%',
right: '5%',
bottom: '10%',
width: 'auto',
height: '70%',
containLabel: true,
},
xAxis: {
type: 'category',
axisLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
axisLabel: {
textStyle: {
color: '#ccc',
},
fontSize: this.fontSize,
},
data: ['2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020'],
},
yAxis: [
{
type: 'value',
// name: '单位:个',
max: 400,
min: 0,
interval: 100,
axisLine: {
show: false,
},
axisLabel: {
textStyle: {
color: 'gold',
},
fontSize: this.fontSize,
},
nameTextStyle: {
color: '#ccc',
fontSize: this.fontSize,
},
splitLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
},
{
type: 'value',
// name: '单位:个',
max: 600,
min: 0,
interval: 150,
axisLine: {
show: false,
},
axisLabel: {
textStyle: {
color: 'red',
},
fontSize: this.fontSize,
},
nameTextStyle: {
color: '#ccc',
fontSize: this.fontSize,
},
splitLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
}
],
series: [
{name: '阳性监测点数量', itemStyle: {color: 'gold'}, type: 'line', data: [150, 140, 100, 180, 150, 200, 210, 130]},
{name: '阳性样品数量', itemStyle: {color: 'red'}, yAxisIndex: 1, type: 'line', data: [280, 310, 270, 280, 310, 350, 350, 380, 350]},
],
dataZoom: [{
start: 10,
end: 80,
backgroundColor: '#105179',
fillerColor: '#46b9ef',
borderColor: 'transparent',
bottom: '2%',
height: 10,
borderRadius: 10,
handleSize: '200%',
handleStyle: {
color: '#fff',
},
textStyle: {
color: '#fff',
},
}],
}
}
},
mounted() {
this.$nextTick(this.init)
},
computed: {
fontSize() {
return Math.floor(screen.height * 1.48 / 100)
},
},
methods: {
init() {
this.chart = this.$echarts.init(this.$refs.chart)
this.chart.setOption(this.option)
}
}
}
</script>
<style lang="stylus" scoped>
.special-monitoring
width 100%
height 100%
>.chart
width 100%
height 70%
</style>
<template>
<div class="team-build">
<div>
<m-chart :data="data" :config="config"/>
</div>
<div>
<m-chart :data="data2" :config="config2" :options="{xAxis: {splitLine: {show: false}}, yAxis: {splitLine: {show: false}}}"/>
</div>
<Select v-model="area" class="custom-select" size="small">
<Option v-for="item in options" :key="item" :value="item">{{item}}</Option>
</Select>
</div>
</template>
<script>
export default {
name: 'TeamBuild',
data() {
return {
area: '华北地区',
options: ['华北地区'],
config: {
colors: ['#535af1', '#39d655', '#ffd825'],
legend: {
align: 'left',
orient: 'vertical',
},
shape: [
{type: 'pie', radius: [20, 40], roseType: 'radius', center: ['65%', '50%']}
]
},
data: [
{name: '执业人员', value: 50},
{name: '乡村兽医', value: 30},
{name: '官方兽医', value: 20},
],
config2: {
colors: ['#00d2ff'],
legend: {
hide: true,
},
shape: [
{type: 'bar', barWidth: '50%', key: 'value', label: {show: true, position: 'top', color: '#fff'}},
],
xAxis: {
key: 'name',
},
yAxis: {
axisLabel: {show: false},
axisLine: {show: false},
max: 15,
}
},
data2: [
{name: '北京', value: 3},
{name: '天津', value: 4},
{name: '河北', value: 2},
{name: '山西', value: 7},
{name: '内蒙古', value: 10},
],
}
},
}
</script>
<style lang="stylus" scoped>
.team-build
width 100%
height 100%
display flex
>div
flex 1
&:first-child
border-right .1rem solid #175d83
margin-right 1rem
</style>
<template>
<m-grid
:template="[
'title title title',
'box1 . box4',
'box1 . box3',
'box2 box2 box3',
'summary box1 box2',
'. box3 box4',
'. box5 box6',
]"
columns="1fr 2fr 1fr"
rows="4rem 1fr 1fr 1fr"
gap="0.8rem"
style="paddingTop: 0"
columns="1.5fr 1fr 1fr"
rows="1fr 1fr 1fr"
gap="0.5rem"
>
<m-map></m-map>
<m-title area="title" hideDate hideTime :bgImg="require('@/assets/images/title-bg.png')">测试专题</m-title>
<m-card area="box1" title="题目">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quia fugit dicta explicabo blanditiis dolorum ratione aliquid, consequuntur facere ex saepe consectetur! At, accusamus fuga placeat vero soluta facilis odio esse.
<DiseaseSum area="summary"/>
<m-card area="box1" title="病害预警">
<Disease />
</m-card>
<m-card area="box2">
box2
<m-card area="box2" title="会诊统计">
<ConsultationSum />
</m-card>
<m-card area="box3">
abc
<m-card area="box3" title="队伍建设">
<TeamBuild />
</m-card>
<m-card area="box4">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Sint pariatur quaerat hic consectetur qui omnis, exercitationem quo, molestias magnam aperiam asperiores non modi officiis quod delectus temporibus iusto necessitatibus quam.
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Necessitatibus animi fugiat officiis facere inventore quisquam assumenda aliquid, nulla quam, voluptate possimus. Cum ea possimus mollitia animi nemo at! Totam, porro?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus deserunt reiciendis iure ipsum asperiores dicta nostrum veritatis impedit voluptatum ducimus quia, eius incidunt sequi blanditiis, explicabo fuga error perspiciatis a?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint totam minima et commodi, doloremque veritatis ex, reiciendis nesciunt quaerat eligendi ullam cupiditate deleniti quisquam. Sapiente error commodi iusto accusamus minima.
<m-card area="box4" title="实时问答">
<Questions />
</m-card>
<m-card area="box5" title="专项监测">
<SpecialMonitoring />
</m-card>
<m-card area="box6" title="疫情测报">
<DiseaseForeCast />
</m-card>
</m-grid>
</template>
<script>
import Disease from './components/disease'
import ConsultationSum from './components/consultation-sum'
import TeamBuild from './components/team-build'
import Questions from './components/questions'
import SpecialMonitoring from './components/special-monitoring'
import DiseaseForeCast from './components/disease-forecast'
import DiseaseSum from './components/disease-sum'
export default {
name: 'Main',
components: {
Disease,
ConsultationSum,
TeamBuild,
Questions,
SpecialMonitoring,
DiseaseForeCast,
DiseaseSum,
},
}
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment