Commit c30c2744 authored by 郭铭瑶's avatar 郭铭瑶 🤘

海洋牧场

parent b20ccf4a
......@@ -11,6 +11,7 @@
}
</style>
<!-- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> -->
<script language="javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=ee2b5d5c0c44c768f1d2593eb4a7dfa6&plugin=AMap.DistrictSearch,AMap.ControlBar,ElasticMarker"></script>
</head>
<body>
<div id="app"></div>
......
......@@ -59,3 +59,14 @@ $color-main = #5BD5FF
top 1rem
right .5rem
width 7rem
.back-btn
position fixed
top .6rem
left 2rem
z-index 9999
color $edgeColor
font-weight bold
cursor pointer
font-size 1.1rem
&:hover
text-shadow 0 0 0.8rem $edgeColor
......@@ -9,7 +9,7 @@
<div class="edge bottom-right"/>
<div class="card-title" :style="`color:${color}`">
<img src="@/assets/images/arrow.png"/>
{{title}}
<span>{{title}}</span>
<img src="@/assets/images/arrow.png" style="transform:rotate(180deg)"/>
</div>
<div class="card-content">
......@@ -39,12 +39,12 @@ export default {
.card-title
display flex
align-items center
justify-content space-around
color $edgeColor
justify-content center
span
font-size 1.2rem
color $edgeColor
font-weight bold
width 50%
margin .5rem auto
margin 0.5rem 1rem
img
width 1rem
// .card-content
......
......@@ -55,7 +55,7 @@ export default {
{name: '病害防控', title: '病害防控大数据', path: '/disease'},
{name: '质量安全', title: '水产品质量安全大数据', path: '/quality-safety'},
{name: '稻鱼种养', title: '稻鱼综合种养分析', path: '/rice-fish'},
{name: '海洋牧场'},
{name: '海洋牧场', title: '海洋牧场分析', path: '/ocean-farm'},
{name: '水产价格', title: '水产品价格分析', path: '/fishing-price'},
{name: '苗种'},
],
......@@ -106,13 +106,16 @@ export default {
},
},
watch: {
$route(cur) {
'$route': {
handler(cur) {
const {path} = cur
if (path === '/') {
this.curIndex = 0
} else {
this.curIndex = this.menus.findIndex(menu => path.startsWith(menu.path))
}
},
immediate: true,
}
}
}
......
......@@ -5,6 +5,7 @@ const Disease = () => import('@/views/disease')
const FishingPrice = () => import('@/views/fishing-price')
const QualitySafety = () => import('@/views/quality-safety.vue')
const RiceFish = () => import('@/views/rice-fish.vue')
const OceanFarm = () => import('@/views/ocean-farm.vue')
Vue.use(Router)
......@@ -34,5 +35,10 @@ export default new Router({
path: '/rice-fish',
component: RiceFish,
},
{
name: 'ocean-farm',
path: '/ocean-farm',
component: OceanFarm,
}
]
})
......@@ -149,8 +149,11 @@ export default {
setTimeout(this.init, 0)
},
computed: {
sizeRate() {
return Number((screen.height / 800).toFixed(1))
},
fontSize() {
return Math.floor(screen.height * 1.48 / 100)
return this.sizeRate * 12
},
},
methods: {
......
<template>
<div class="area-count" v-if="showChart">
<m-chart :config="config" :data="data"/>
<p>面积(公顷)</p>
<p>数量(个)</p>
</div>
</template>
<script>
export default {
name: 'AreaCount',
data() {
return {
showChart: false,
config: {
colors: [['#f6a017', '#fbd42a'], ['#4af3a7', '#45e1f0']],
legend: {
hide: true,
},
shape: [
{key: 'area', type: 'bar', barWidth: '20%', barGap: '50%', yAxisIndex: 0, borderRadius: [10, 10, 10, 10]},
{key: 'count', type: 'bar', barWidth: '20%', barGap: '50%', yAxisIndex: 1, borderRadius: [10, 10, 10, 10]},
],
xAxis: {
key: 'year',
},
},
data: [
{year: '2015', area: 200000, count: 300000},
{year: '2016', area: 300000, count: 450000},
{year: '2017', area: 400000, count: 500000},
{year: '2018', area: 500000, count: 650000},
{year: '2019', area: 600000, count: 750000},
]
}
},
mounted() {
setTimeout(() => this.showChart = true)
},
}
</script>
<style lang="stylus" scoped>
.area-count
width 100%
height 80%
margin-top 2rem
overflow hidden
p
position absolute
top 3rem
font-size .8rem
font-weight bold
color #cfa628
&:first-child
left 1rem
&:last-child
color #43d6b1
right 1rem
</style>
<template>
<div class="data-identify">
<div>
<p><span/>海洋种类</p>
<span class="tips">本月识别种类:鱿鱼、鲳鱼、鲷鱼、尤头鱼</span>
<div class="chart" ref="chart" />
</div>
<div>
<p><span/>种群数量</p>
<span class="tips">本月识别种数量:15,238尾</span>
<div class="chart" ref="chart2" />
</div>
</div>
</template>
<script>
const mock = [
{year: '2020.01', value: 35},
{year: '2020.02', value: 29},
{year: '2020.03', value: 33},
{year: '2020.04', value: 20},
{year: '2020.05', value: 36},
{year: '2020.06', value: 25},
{year: '2020.07', value: 30},
{year: '2020.08', value: 28},
]
const mock2 = [
{year: '2020.01', value: 35000},
{year: '2020.02', value: 29000},
{year: '2020.03', value: 33000},
{year: '2020.04', value: 20000},
{year: '2020.05', value: 36000},
{year: '2020.06', value: 25000},
{year: '2020.07', value: 30000},
{year: '2020.08', value: 28000},
]
import echarts from 'echarts'
export default {
name: 'DataIdentify',
data() {
return {
option: {
tooltip: {
trigger: 'axis',
confine: true,
},
legend: {
show: false,
// width: '100%',
// textStyle: {
// color: '#ccc',
// fontSize: this.fontSize,
// },
// data: ['综合-具有可比性', '综合-不具可比性', '海水产品-具有可比性', '海水产品-不具可比性', '淡水产品-具有可比性', '淡水产品-不具可比性'],
},
grid: {
top: '20%',
left: '3%',
right: '3%',
bottom: 'auto',
width: 'auto',
height: '60%',
containLabel: true,
},
xAxis: {
type: 'category',
axisLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
axisLabel: {
textStyle: {
color: '#46b9ef',
},
fontSize: this.fontSize,
},
data: mock.map(item => item.year)
},
yAxis: [
{
type: 'value',
name: '单位:个',
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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{offset: 0, color: '#0fa8f1'},
{offset: 1, color: '#775deb'}
]),
barBorderRadius: [10, 10, 10, 10],
}, type: 'bar', barWidth: '20%', data: mock.map(item => item.value)},
],
dataZoom: [{
start: 0,
end: 100,
backgroundColor: '#105179',
fillerColor: '#46b9ef',
borderColor: 'transparent',
left: '5%',
right: '5%',
bottom: '13%',
height: 10,
borderRadius: 10,
handleSize: '200%',
handleStyle: {
color: '#fff',
},
textStyle: {
color: '#fff',
},
}],
},
option2: {
tooltip: {
trigger: 'axis',
confine: true,
},
legend: {
show: false,
},
grid: {
top: '20%',
left: '3%',
right: '3%',
bottom: 'auto',
width: 'auto',
height: '60%',
containLabel: true,
},
xAxis: {
type: 'category',
axisLine: {
lineStyle: {
color: 'rgba(91,213,255,0.1)'
}
},
axisLabel: {
textStyle: {
color: '#46b9ef',
},
fontSize: this.fontSize,
},
data: mock2.map(item => item.year)
},
yAxis: [
{
type: 'value',
name: '单位:尾',
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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{offset: 0, color: '#ffe225'},
{offset: 1, color: '#f6a316'}
]),
barBorderRadius: [10, 10, 10, 10],
}, type: 'bar', barWidth: '20%', data: mock2.map(item => item.value)},
],
dataZoom: [{
start: 0,
end: 100,
backgroundColor: '#105179',
fillerColor: '#46b9ef',
borderColor: 'transparent',
left: '5%',
right: '5%',
bottom: '13%',
height: 10,
borderRadius: 10,
handleSize: '200%',
handleStyle: {
color: '#fff',
},
textStyle: {
color: '#fff',
},
}],
},
}
},
mounted() {
setTimeout(this.init, 0)
},
computed: {
sizeRate() {
return Number((screen.height / 800).toFixed(1))
},
fontSize() {
return this.sizeRate * 12
},
},
methods: {
init() {
this.$echarts.init(this.$refs.chart).setOption(this.option)
this.$echarts.init(this.$refs.chart2).setOption(this.option2)
}
},
}
</script>
<style lang="stylus" scoped>
.data-identify
width 100%
height 100%
overflow hidden
>div
width 100%
height 50%
position relative
.unit
position absolute
right 1rem
top 1rem
span
display block
text-align center
color $edgeColor
p
display flex
font-size 1.2rem
font-weight bold
align-items center
span
display inline-block
width .3rem
height 1.2rem
background $edgeColor
margin-right .5rem
>.chart
height calc(100% - 2rem)
</style>
<template>
<div class="farm-build">
<div class="sum">
<div v-for="item in sum" :key="item.name">
<p>{{item.name}}</p>
<m-count class="count" :value="item.value" :decimal="0"/>
</div>
</div>
<div class="list">
<Row class="row row-title">
<i-col class="col" v-for="col in layout" :key="col.key" :span="col.width" :offset="col.offset || 0">
<div :style="`text-align: ${col.align || 'left'};width:100%;`">{{col.title}}</div>
</i-col>
</Row>
<m-scroll :length="model.length" :limit="12">
<Row class="row" v-for="(row, rowIndex) in model" :key="rowIndex" :style="`${row.count >= 15 ? 'color:#d04e4b': ''}`">
<i-col class="col" v-for="col in layout" :key="col.key" :span="col.width" :offset="col.offset || 0">
<div v-if="typeof row[col.key] === 'number'" :style="`text-align: ${col.align || 'left'};color: ${col.color};width:100%;`">
<m-count :value="row[col.key]" :decimal="0"/>
</div>
<div v-else :style="`text-align: ${col.align || 'left'};color: ${col.color};width:100%;`">{{row[col.key]}}</div>
</i-col>
</Row>
</m-scroll>
</div>
</div>
</template>
<script>
export default {
name: 'FarmBuild',
data() {
return {
sum: [
{name: '总数量(个)', value: 5847884},
{name: '总面积(公顷)', value: 879944},
{name: '总投资额(万元)', value: 9875645},
],
layout: [
{
title: '省份',
key: 'province',
width: 4,
align: 'center',
},
{
title: '数量(个)',
key: 'number',
width: 6,
align: 'center',
},
{
title: '面积(公顷)',
key: 'area',
width: 6,
align: 'center',
},
{
title: '投资总额(万元)',
key: 'invest',
width: 8,
align: 'center',
},
],
model: [
{province: '福建', number: 6558745, area: 5487, invest: 59895464},
{province: '山东', number: 6558745, area: 5487, invest: 59895464},
{province: '上海', number: 6558745, area: 5487, invest: 59895464},
{province: '浙江', number: 6558745, area: 5487, invest: 59895464},
{province: '江苏', number: 6558745, area: 5487, invest: 59895464},
{province: '福建', number: 6558745, area: 5487, invest: 59895464},
{province: '山东', number: 6558745, area: 5487, invest: 59895464},
{province: '上海', number: 6558745, area: 5487, invest: 59895464},
{province: '浙江', number: 6558745, area: 5487, invest: 59895464},
{province: '江苏', number: 6558745, area: 5487, invest: 59895464},
{province: '福建', number: 6558745, area: 5487, invest: 59895464},
{province: '山东', number: 6558745, area: 5487, invest: 59895464},
{province: '上海', number: 6558745, area: 5487, invest: 59895464},
{province: '浙江', number: 6558745, area: 5487, invest: 59895464},
{province: '江苏', number: 6558745, area: 5487, invest: 59895464},
],
}
},
}
</script>
<style lang="stylus" scoped>
.farm-build
width 100%
height 100%
overflow hidden
display flex
flex-direction column
.sum
display flex
justify-content space-around
margin-bottom 1rem
>div
text-align center
.count
color $edgeColor !important
font-weight bold !important
font-size 1.1rem !important
.list
flex 1
.row
display flex
align-items center
// line-height 2.4rem
line-height 2.5
&.row-title
font-weight bold
background-color $color-map()
font-size 1rem
&:nth-child(2n)
background-color $color-map(0.15)
.col
padding 0 .5rem
display flex
align-items center
flex-wrap wrap
font-size .9rem
</style>
<template>
<div class="farm-rate" v-if="showChart">
<m-chart :config="config" :data="data" :options="{legend: {top: '25%'}}"/>
</div>
</template>
<script>
export default {
name: 'FarmRate',
data() {
return {
showChart: false,
config: {
colors: ['#feec40', '#05bbfd', '#fe4949'],
tooltip: {
trigger: 'item',
formatter: '{b}<br/>{c}公顷'
},
legend: {
align: 'right',
orient: 'vertical',
},
shape: [
{type: 'pie', startAngle: 135, radius: [40 * Number((screen.height / 800).toFixed(1)), 55 * Number((screen.height / 800).toFixed(1))], center: ['40%', '50%'], label: {show: true, formatter: '{d}%'}}
],
},
data: [
{name: '养护型', value: 62485},
{name: '增殖型', value: 29000},
{name: '休闲型', value: 31244},
]
}
},
mounted() {
setTimeout(() => this.showChart = true, 0)
}
}
</script>
<style lang="stylus" scoped>
.farm-rate
width 100%
height 100%
overflow hidden
</style>
<template>
<m-grid
area="grid"
:template="[
'left . right',
]"
columns="1fr 2fr 1fr"
rows="1fr"
gap="0.5rem">
<div id="oceanMap"/>
<div v-if="showDetail" class="back-btn" @click="handleBack">
<Icon type="md-arrow-round-back" /> 返回
</div>
<div v-if="!showDetail" class="sum-wrapper">
<BorderBox class="sum">
<p>海洋牧场数量</p>
<h2><m-count class="count" :value="348745" :decimal="0"/></h2>
</BorderBox>
<BorderBox class="sum">
<p>人工鱼礁数量</p>
<h2><m-count class="count" :value="5448745" :decimal="0"/></h2>
</BorderBox>
</div>
<m-animate enter="fadeInLeft" leave="fadeOutLeft">
<div v-show="!showDetail" area="left" class="content part-left">
<m-card title="近5年面积与数量对比">
<AreaCount />
</m-card>
<m-card title="各地区海洋牧场建设情况">
<FarmBuild />
</m-card>
</div>
</m-animate>
<m-animate enter="fadeInRight" leave="fadeOutRight">
<div v-show="!showDetail" area="right" class="content part-right">
<m-card title="各类海洋牧场占比">
<FarmRate />
</m-card>
<m-card title="各地区人工鱼礁建设情况">
<FarmBuild />
</m-card>
</div>
</m-animate>
<m-animate enter="fadeInLeft" leave="fadeOutLeft">
<div v-show="showDetail" area="left" class="content part-left2">
<m-card title="文字介绍">
<p style="text-indent:2rem;line-height:1.5;">采用规模化渔业设施和系统化管理体制,利用自然的海洋生态环境,将人工放流的经济海洋生物聚集起来,像在陆地放牛羊一样,对鱼、虾、蟹、贝、藻等海洋资源进行有计划和有目的的海上放养。</p>
<p style="text-indent:2rem;line-height:1.5;">采用规模化渔业设施和系统化管理体制,利用自然的海洋生态环境,将人工放流的经济海洋生物聚集起来,像在陆地放牛羊一样,对鱼、虾、蟹、贝、藻等海洋资源进行有计划和有目的的海上放养。</p>
</m-card>
<m-card title="图片介绍">
<img style="width:100%;height:92%;" src="@/assets/images/img1.png"/>
</m-card>
<m-card title="视频介绍">
<img style="width:100%;height:92%;" src="@/assets/images/img2.png"/>
</m-card>
</div>
</m-animate>
<m-animate enter="fadeInRight" leave="fadeOutRight">
<div v-show="showDetail" area="right" class="content part-right">
<m-card title="视频监控">
<Select class="custom-select" value="线路1" transfer>
<Option v-for="item in ['线路1']" :key="item" :value="item">{{item}}</Option>
</Select>
<img style="width:100%;height:92%;" src="@/assets/images/img3.png"/>
</m-card>
<m-card title="数据识别">
<DataIdentify v-if="showDetail"/>
</m-card>
</div>
</m-animate>
</m-grid>
</template>
<script>
const {AMap} = window
import AreaCount from './components/ocean-farm/area-count'
import FarmRate from './components/ocean-farm/farm-rate'
import FarmBuild from './components/ocean-farm/farm-build'
import BorderBox from './components/border-box'
import DataIdentify from './components/ocean-farm/data-identify'
export default {
name: 'OceanFarm',
components: {
AreaCount,
FarmRate,
FarmBuild,
BorderBox,
DataIdentify,
},
data() {
return {
map: null,
showDetail: false,
mapConfig: {
zoom: 7,
zooms: [6, 8],
center: [121.973849, 28.142576], // 钓鱼岛附近
mapStyle: 'amap://styles/blue',
features: ['bg', 'road', 'point'],
},
mapPolygon: null,
mapMarker: null,
infoWindow: null,
}
},
mounted() {
this.$nextTick(this.initMap)
},
methods: {
initMap() {
this.map = new AMap.Map('oceanMap', this.mapConfig)
this.mapPolygon = new AMap.Polygon({ // 上色小区的底板颜色
fillColor: 'gold',
fillOpacity: 0.1,
strokeWeight: 1,
strokeColor: 'gold',
cursor: 'pointer',
path: [
[122.767281, 29.920257],
[123.767281, 29.920257],
[124.767281, 28.920257],
[123.767281, 27.920257],
[122.767281, 27.920257],
[122.267281, 28.920257],
]
}).on('click', e => {
this.showDetail = true
const location = [e.lnglat.getLng(), e.lnglat.getLat()]
this.map.setZoomAndCenter(8, location)
if (!this.mapMarker) {
this.mapMarker = new AMap.Marker({
position: [123.424044, 29.028291],
zIndex: 99,
icon: new AMap.Icon({
// size: [30, 10],
image: require('@/assets/images/title-arrow.png'),
}),
// extData: {
// community: item.name,
// buildingNo: item.buildingNo,
// intention: item.intention,
// lon: item.lon,
// lat: item.lat,
// color: item.color,
// ...curObj
// },
}).on('click', e => {
const location = [e.lnglat.getLng(), e.lnglat.getLat()]
new AMap.InfoWindow({
content: `
<div class="map-tooltip-info">
<h3>人工鱼礁名称</h3>
<p><span>申请年份:</span>2015年</p>
<p><span>建设类型:</span>养护型、休闲型</p>
</div>
`
}).open(this.map, location)
})
this.map.add([this.mapMarker])
this.mapPolygon.off('mouseover', this.polygonListener)
}
}).on('mouseover', this.polygonListener).on('mouseout', () => {
this.infoWindow.close()
})
this.map.add([this.mapPolygon])
},
handleBack() {
this.showDetail = false
const {zoom, center} = this.mapConfig
this.map.setZoomAndCenter(zoom, center)
this.map.remove(this.mapMarker)
this.mapPolygon.on('mouseover', this.polygonListener)
},
polygonListener(e) {
const location = [e.lnglat.getLng(), e.lnglat.getLat()]
this.infoWindow = new AMap.InfoWindow({
content: `
<div class="map-tooltip-info">
<h3>苏州市大有乡鑫富洋海参养殖场</h3>
<p><span>地址:</span>海洋牧场1号</p>
<p><span>申请年份:</span>2015年</p>
<p><span>建设类型:</span>养护型、休闲型</p>
</div>
`
})
this.infoWindow.open(this.map, location)
},
}
}
</script>
<style lang="stylus" scoped>
#oceanMap
z-index 9
width 100%
height 100%
position absolute
.monitor-card
z-index 10
.sum-wrapper
z-index 99
position absolute
left 0
right 0
width 35%
margin 2rem auto 0
display flex
justify-content space-around
.sum
width 45%
text-align center
font-weight bold
h2,.count
color $edgeColor !important
font-family $font-pang !important
font-size 1.5rem !important
.content
display flex
flex-direction column
width 100%
height 100%
overflow hidden
>div
margin-top .5rem
&.part-left,
&.part-right
>div
&:nth-child(1)
flex 1
&:nth-child(2)
flex 2
&.part-left2
>div
flex 1
</style>
<style lang="stylus">
.amap-logo
.amap-copyright
display none !important
.amap-icon
img
width 100%
height 100%
.menu
.ivu-collapse-content
max-height 80vh
overflow-y auto
overflow-x hidden
padding 0 1rem
.ivu-collapse-content-box
padding 1rem 0
button
text-align left
font-size 1rem
.tab-menu
.ivu-tabs-bar
margin-bottom 0
.ivu-tabs-nav
.ivu-tabs-tab
&:last-child
margin-right 0
.amap-info-content.amap-info-outer
background rgba(0,0,0,0.5)
padding 0 !important
.map-tooltip-info
color $edgeColor
padding 1rem
border .1rem solid $edgeColor
span
color #fff
</style>
......@@ -3,7 +3,7 @@
<div style="flex:1">
<RiceFishMap ref="map" @select="handleMapSelect" area="map" />
</div>
<div v-if="showProvince" class="back" @click="handleBack">
<div v-if="showProvince" class="back-btn" @click="handleBack">
<Icon type="md-arrow-round-back" /> 返回
</div>
<div style="flex:1.3">
......@@ -55,15 +55,4 @@ export default {
width 100%
height 100%
display flex
.back
position absolute
top .6rem
left 2rem
z-index 9999
color $edgeColor
font-weight bold
cursor pointer
font-size 1.1rem
&:hover
text-shadow 0 0 0.8rem $edgeColor
</style>
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