Browse Source

三维地图

master
井乐禹 2 years ago
parent
commit
502adc750b
  1. 6
      package.json
  2. 26
      src/main.js
  3. 2
      src/style/right1.scss
  4. 2
      src/style/right2.scss
  5. 14
      src/views/index.vue
  6. 862
      src/views/screenCenter/screenCenter.vue
  7. 2
      src/views/screenHeader.vue
  8. 132
      src/views/screenLeft/left1.vue
  9. 418
      src/views/screenRight/right3.vue

6
package.json

@ -8,12 +8,15 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@turf/turf": "^6.5.0",
"axios": "^1.4.0", "axios": "^1.4.0",
"blueimp-md5": "^2.19.0",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"echarts": "^5.4.3", "echarts": "^5.4.3",
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"element-ui": "^2.15.13", "element-ui": "^2.15.13",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"mapbox-gl": "^2.4.1",
"node-gyp": "^9.4.0", "node-gyp": "^9.4.0",
"node-sass": "^4.12.0", "node-sass": "^4.12.0",
"vue": "^2.6.14", "vue": "^2.6.14",
@ -21,6 +24,7 @@
"vue-lazyload": "^3.0.0", "vue-lazyload": "^3.0.0",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vue-seamless-scroll": "^1.1.23", "vue-seamless-scroll": "^1.1.23",
"vue-tree-color": "^2.3.2",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
@ -34,6 +38,8 @@
"babel-plugin-component": "^1.1.1", "babel-plugin-component": "^1.1.1",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3", "eslint-plugin-vue": "^8.0.3",
"less": "^4.2.0",
"less-loader": "^11.1.3",
"sass": "^1.32.7", "sass": "^1.32.7",
"sass-loader": "^12.0.0", "sass-loader": "^12.0.0",
"svg-sprite-loader": "^6.0.11", "svg-sprite-loader": "^6.0.11",

26
src/main.js

@ -1,18 +1,18 @@
import Vue from 'vue' import Vue from 'vue';
import router from './router' import 'components/index'; //注册components下的组件
import store from './store' import scroll from 'vue-seamless-scroll'; //滚动
import App from './App.vue' import App from './App.vue';
import router from './router';
import 'components/index' //注册components下的组件 import store from './store';
import scroll from 'vue-seamless-scroll' //滚动
import './style/global.scss'
import './style/font.scss' // 字体文件
import { Popover } from 'element-ui'
import { Button } from 'element-ui'
import ElementUI, { Button, Popover } from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import Vue2OrgTree from 'vue-tree-color';
import './style/font.scss'; // 字体文件
import './style/global.scss';
Vue.use(Vue2OrgTree)
Vue.use(ElementUI);
Vue.config.productionTip = false Vue.config.productionTip = false
// Vue.component(Popover.name, Popover) // Vue.component(Popover.name, Popover)
Vue.use(Popover) Vue.use(Popover)

2
src/style/right1.scss

@ -69,7 +69,6 @@
} }
} }
.b-ytal {
.ytal-list { .ytal-list {
margin-top: 19px; margin-top: 19px;
margin-left: 18px; margin-left: 18px;
@ -113,4 +112,3 @@
} }
} }
} }
}

2
src/style/right2.scss

@ -94,7 +94,7 @@
} }
} }
.b-xjph { .b-xjph,.b-hztj {
height: 269px; height: 269px;
.table { .table {

14
src/views/index.vue

@ -6,13 +6,14 @@
transform: `scale(${shibeiScale}) translate(-50%, -50%)` transform: `scale(${shibeiScale}) translate(-50%, -50%)`
}"> --> }"> -->
<!--屏幕调整--> <!--屏幕调整-->
<div class="shibei-screen-home" <!-- class="shibei-screen-home"
:style="{ :style="{
width: width + 'px', width: width + 'px',
height: height + 'px', height: height + 'px',
transform: `scale(0.6) ` transform: `scale(0.6) `
}"> }" -->
<div style="background-color: #052431;width: fit-content;">
<screen-header></screen-header> <screen-header></screen-header>
<agency-select></agency-select> <agency-select></agency-select>
<screen-content></screen-content> <screen-content></screen-content>
@ -23,12 +24,11 @@
<script> <script>
// //
import { debounce } from './../utils/common'
import screenHeader from './screenHeader'
import agencySelect from './agencySelect' import agencySelect from './agencySelect'
import screenContent from './screenContent' import screenContent from './screenContent'
import screenHeader from './screenHeader'
// import projectBox from './components/projectBox' // import projectBox from './components/projectBox'
import { mapGetters, mapActions } from 'vuex' import { mapActions, mapGetters } from 'vuex'
let width = 0 let width = 0
let height = 0 let height = 0
export default { export default {
@ -99,8 +99,8 @@ export default {
background-size: 100% 100%; background-size: 100% 100%;
position: absolute; position: absolute;
// //
// left: 50%; left: 50%;
// top: 50%; top: 50%;
left: -110%; left: -110%;
top: 10%; top: 10%;
transition: 0.2s; transition: 0.2s;

862
src/views/screenCenter/screenCenter.vue

@ -1,17 +1,865 @@
<template> <template>
<div class="screen-center"> <div class="screen-center">
screen-left <div id="map"
style="height: 100%;width: 100%;position: relative;min-width:1000px">
<div style="position: absolute;left:16%;top: 10px;cursor: pointer;z-index: 100;color: #fff;font-size: 40px;">
<div style="display: flex;justify-content: space-around;flex-direction: row;width: 30vw;">
<div v-for="item in topNum"
:key="item.value"
style="background-color: rgba(8, 31, 45, 0.6);padding: 30px;display: flex;flex-direction: column;align-items: center;">
<div style="padding-bottom: 20px;">
{{item.value&&getThousandth(item.value)}}
</div> </div>
</template> <div style="border-top: 5px solid #36acd3;padding-top: 20px;display: flex;align-items: center;white-space: nowrap;">
<el-image style="height: 60px;"
:src="require('../../assets/shuline.png')"
fit="fill"></el-image>
{{item.label||"--" }}
</div>
</div>
</div>
</div>
<div @click="initialization"
style="position: absolute;left: 100px;bottom: 100px;cursor: pointer;z-index: 100;">
<el-image style="width: 50px; height: 50px;"
:src="require('../../assets/back.png')"
fit="fill"></el-image>
</div>
<div style="position: absolute;right:50px;bottom:50px;z-index: 100;border-radius: 16px;padding:20px; border: 1px solid #045775;font-size: 40px;color: #fff;height: 400px;display: flex;flex-direction: column;justify-content: space-around;"
v-if="layersIndex==3">
<div v-for="item in buttonPiece"
:key="item.value"
style="display: flex;align-items: center;cursor: pointer;padding: 8px 0;"
@click="selectType(item.value,item.label)"
:style="{background: item.value==buttonIndex?'linear-gradient(to top, rgba(16, 98, 130,1), rgba(16, 98, 130,0))':''}">
<el-image style="width: 40px; height: 40px;margin-right: 12px;"
:src="require('../../assets/ling.png')"
fit="fill"></el-image>
{{item.label}}
</div>
</div>
<div v-if="showFirst"
style="position: absolute;right:1200px;bottom:200px;z-index: 100;padding:20px;font-size: 40px;color: #fff;height: 500px;display: flex;flex-direction: column;justify-content:space-around;border-radius: 16px;padding:20px; border: 1px solid #045775;align-items: center;background-color: rgba(5, 36, 49,0.5);">
<div style="margin-bottom: 24px;display: flex;justify-content: space-between;align-items: center;width: 100%;">
<div>
<script> </div>
<div>
微网格信息
</div>
<div style="color: #fff;cursor: pointer;"
@click="close">
x
</div>
</div>
<div v-for="item in microgridArr"
:key="item.value"
style="display: flex;flex-direction: row;align-items: center;cursor: pointer;padding: 4px;"
@click="microgridDetails(item)"
:style="{background: item.value==microgridIndex?'linear-gradient(to right, rgba(16, 98, 130,1), rgba(16, 98, 130,0))':''}">
<div style="margin-right:80px">
<el-image style="width: 40px; height: 40px;margin-right: 12px;vertical-align: text-top;"
:src="require('../../assets/ling.png')"
fit="fill"></el-image>
{{ item.label }}
</div>
<div>
>
</div>
</div>
</div>
<div v-if="showMicrogridDetails"
style="position: absolute;right:400px;bottom:100px;z-index: 100;padding:20px;font-size: 40px;color: #fff;height: auto;display: flex;flex-direction: column;border-radius: 16px;padding:20px; border: 1px solid #045775;background-color: rgba(7, 100, 133,0.5);">
<div style="margin-bottom: 38px;">
<div
style="background: linear-gradient(to right, rgba(6, 227, 218,1), rgba(6, 227, 218,0));display: flex;justify-content: space-between;flex-direction: row;padding: 12px;margin-bottom: 38px;">
<div>
{{ microgridObj.firstTitle||"--" }}
</div>
<div style="color: #fff;cursor: pointer;"
@click="showMicrogridDetails=false">
x
</div>
</div>
<div>
<div style="margin-bottom: 38px;">
微网格长{{microgridObj.leader}}
</div>
<div style="margin-bottom: 38px;">
性别{{microgridObj.gender}}
</div>
<div style="margin-bottom: 38px;">
电话{{microgridObj.phone}}
</div>
<div style="margin-bottom: 38px;">
住址{{microgridObj.address}}
</div>
</div>
</div>
<div>
<div
style="background: linear-gradient(to right, rgba(6, 227, 218,1), rgba(6, 227, 218,0));display: flex;justify-content: space-between;flex-direction: row;padding: 12px;margin-bottom: 38px;">
<div>
{{ microgridObj.secondTitle||"--" }}
</div>
<div>
总数{{ microgridObj.total||"--" }}
</div>
</div>
<div style="max-width: 700px;min-width: 700px;overflow-x: clip; text-overflow:ellipsis;white-space: nowrap;">
<div v-for="item in microgridObj.list"
:key="item.value"
style="margin-bottom: 30px;cursor: pointer;"
:title="item.label">
<span style="margin-right: 12px;">
{{ item.value }}
</span>
<span>
{{ item.label }}
</span>
</div>
</div>
</div>
<div style="display: flex;justify-content: flex-end;">
<el-pagination background
layout="prev, pager, next"
:total="microgridObj.total"
@current-change="handleCurrentChange">
</el-pagination>
</div>
</div>
</div>
</div>
</template>
<script>
import markIcon from "@/assets/position.png";
import markIcons from "@/assets/positions.png";
import * as turf from '@turf/turf';
import axios from 'axios';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import { mapGetters } from "vuex";
const md5 = require('blueimp-md5');
export default { export default {
name: "screen-center", name: "screen-center",
data() { data() {
return { return {
map: null,
colorList: ["#F84E2D", "#1372EC", "#44DEA3", "#FFC544", "#6C44FF"],
attrAndColor: [],
shibeiJson: null,
resolutions: [
156543.03392800014, 78271.516963999937, 39135.758482000092, 19567.879240999919,
9783.9396204999593, 4891.9698102499797, 2445.9849051249898, 1222.9924525624949, 611.49622628137968,
305.74811314055756, 152.87405657041106, 76.437028285073239, 38.21851414253662, 19.10925707126831,
9.5546285356341549, 4.7773142679493699, 2.3886571339746849, 1.1943285668550503, 0.59716428355981721,
0.29858214164761665, 0.149291070823808325, 0.0746455354119041625
],
hoveredStateId: null,
topNum: [
{
label: "用户总数",
value: 330195
},
{
label: "党员总数",
value: 74830
},
{
label: "党群总数",
value: 9501
},
{
label: "话题总数",
value: 286508
},
{
label: "议题总数",
value: 223829
},
{
label: "诉求总数",
value: 215450
}
],
buttonPiece: [
{
value: 1,
label: "居民"
},
{
value: 2,
label: "房屋"
},
{
value: 3,
label: "党支部"
},
{
value: 4,
label: "用户"
},
{
value: 5,
label: "党员"
},
{
value: 6,
label: "事件"
}
],
buttonIndex: 0,
markerJson: null,
layersIndex: 1,
features: {},
showFirst: false,
showMicrogridDetails: false,
microgridArr: [
{
value: 1,
label: "第一微网格"
},
{
value: 2,
label: "第二微网格"
},
{
value: 3,
label: "第三微网格"
},
{
value: 4,
label: "第四微网格"
},
{
value: 5,
label: "第五微网格"
},
{
value: 6,
label: "第六微网格"
},
],
microgridIndex: 0,
microgridObj: {
firstTitle: "",
leader: "张俊凯",
gender: "男",
phone: "15623523200",
address: "市北区",
secondTitle: "包干房屋",
total: 37,
list: [
{
value: 1,
label: "市北区台柳路12号4单元101"
},
{
value: 2,
label: "市北区敦化路53号4号楼2单元202"
},
{
value: 3,
label: "市北区山东路168号时代国际广场1402号"
},
{
value: 4,
label: "市北区山东路120号玫瑰花园6号楼3单元506"
},
{
value: 5,
label: "市北区南宁路32号2单元501"
},
{
value: 6,
label: "市北区台柳路12号4单元101"
},
{
value: 7,
label: "市北区台柳路12号4单元101"
},
{
value: 8,
label: "市北区台柳路12号4单元101"
},
{
value: 9,
label: "市北区台柳路12号4单元101"
},
{
value: 10,
label: "市北区台柳路12号4单元101"
},
{
value: 11,
label: "市北区台柳路12号4单元101"
},
{
value: 12,
label: "市北区台柳路12号4单元101"
},
{
value: 13,
label: "市北区台柳路12号4单元101"
},
{
value: 14,
label: "市北区台柳路12号4单元101"
},
{
value: 15,
label: "市北区台柳路12号4单元101"
},
{
value: 16,
label: "市北区台柳路12号4单元101"
},
{
value: 17,
label: "市北区台柳路12号4单元101"
},
{
value: 18,
label: "市北区台柳路12号4单元101"
},
{
value: 19,
label: "市北区台柳路12号4单元101"
},
{
value: 20,
label: "市北区台柳路12号4单元101"
},
]
},
microgridObjCopy: {
firstTitle: "",
leader: "张俊凯",
gender: "男",
phone: "15623523200",
address: "市北区",
secondTitle: "包干房屋",
total: 37,
list: [
{
value: 1,
label: "市北区台柳路12号4单元101"
},
{
value: 2,
label: "市北区敦化路53号4号楼2单元202"
},
{
value: 3,
label: "市北区山东路168号时代国际广场1402号"
},
{
value: 4,
label: "市北区山东路120号玫瑰花园6号楼3单元506"
},
{
value: 5,
label: "市北区南宁路32号2单元501"
},
{
value: 6,
label: "市北区台柳路12号4单元101"
},
{
value: 7,
label: "市北区台柳路12号4单元101"
},
{
value: 8,
label: "市北区台柳路12号4单元101"
},
{
value: 9,
label: "市北区台柳路12号4单元101"
},
{
value: 10,
label: "市北区台柳路12号4单元101"
},
{
value: 11,
label: "市北区台柳路12号4单元101"
},
{
value: 12,
label: "市北区台柳路12号4单元101"
},
{
value: 13,
label: "市北区台柳路12号4单元101"
},
{
value: 14,
label: "市北区台柳路12号4单元101"
},
{
value: 15,
label: "市北区台柳路12号4单元101"
},
{
value: 16,
label: "市北区台柳路12号4单元101"
},
{
value: 17,
label: "市北区台柳路12号4单元101"
},
{
value: 18,
label: "市北区台柳路12号4单元101"
},
{
value: 19,
label: "市北区台柳路12号4单元101"
},
{
value: 20,
label: "市北区台柳路12号4单元101"
},
]
},
}
},
mounted() {
this.shibeiJson = require('./shibei.json');
this.markerJson = require('./markerJson.json');
this.init()
this.microgridObj.list = JSON.parse(JSON.stringify(this.microgridObjCopy.list)).slice(0, 5)
},
computed: {
...mapGetters(['shibeiAId', 'shibeiName', 'shibeiAgencyType']),
getThousandth() {
return function (val) {
if (!val) {
return "--"
}
return val.toLocaleString()
}
}
},
watch: {
shibeiAId(value) {
this.topNum.forEach((f, i, arr) => {
arr[i]["value"] = f.value - 1000
})
}
},
methods: {
init() {
// map
mapboxgl.accessToken = "pk.eyJ1IjoiZGp4YyIsImEiOiJjanlxdzNlbW0wNHNyM29yMzZibHczOHlpIn0.TOUXgB6IHHhnmA6RsL6pWw";
this.map = new mapboxgl.Map({
container: 'map', // container id
center: [120.38140448734, 36.11044959486], // starting position [lng, lat]
zoom: 12.5, // starting zoom
// maxZoom: 12.5, // 22
// minZoom: 9,
bearing: 0,
pitch: 40,
style: {
version: 8,
sources: {},
glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
layers: []
}
});
const _this = this;
this.map.on('load', function () {
_this.getPolygonJson(_this.shibeiJson)
_this.map.on('mousemove', 'shibeiPolygonLayer', function (e) {
_this.map.getCanvas().style.cursor = 'pointer'; //
});
_this.map.on("click", "shibeiPolygonLayer", function (e) {
const features = _this.map.queryRenderedFeatures(e.point);
if (features.length > 0) {
_this.features = features[0]
if (features[0]["properties"]["type"] && features[0]["properties"]["type"] == "marker") {
_this.makeMarker(features[0])
return
}
if (features[0]["properties"]["name"].indexOf("网格") != -1) {
return
}
_this.getBoundary(features[0]["properties"]["adcode"] || features[0]["properties"]["subId"])
_this.map.setZoom(13.5)
_this.map.setCenter(features[0]["geometry"]["coordinates"][0][0])
if (_this.map.getLayer("shibeiPolygonLayer")) {
_this.map.removeLayer("shibeiPolygonLayer")
_this.map.removeLayer("text_JSON_layer")
_this.map.removeSource("shibeiPolygonSource")
}
if (_this.map.getLayer("SinglePolygonLayer")) {
_this.map.removeLayer("SinglePolygonLayer")
_this.map.removeLayer("SingleTextLayer")
_this.map.removeSource("SinglePolygonSource")
}
for (let i = 8; i <= 18; i++) {
if (_this.map.getLayer("lineBufferLayer-" + i)) {
_this.map.removeLayer("lineBufferLayer-" + i)
_this.map.removeSource("lineBufferSource-" + i)
}
}
}
// _this.addSinglePolygon(features[0])
});
//
// _this.map.on('mousemove', 'shibeiPolygonLayer', function (e) {
// _this.map.getCanvas().style.cursor = 'pointer'; //
// if (_this.map.getLayer("heightPolygonLayer")) {
// _this.map.removeLayer("heightPolygonLayer")
// _this.map.removeSource("heightPolygonSource")
// }
// let feature = e.features[0];
// _this.addHeightPolygon(feature)
// });
// _this.map.on('mouseleave', 'shibeiPolygonLayer', function (e) {
// if (_this.map.getLayer("heightPolygonLayer")) {
// _this.map.removeLayer("heightPolygonLayer")
// _this.map.removeSource("heightPolygonSource")
// }
// });
})
},
getPolygonJson(obj) {
let shibeiPolyline = JSON.parse(JSON.stringify(obj))
for (let i = 0; i < shibeiPolyline.features.length; i++) {
shibeiPolyline.features[i].geometry.type = 'MultiLineString' //线
shibeiPolyline.features[i].geometry.coordinates = this.convertPolygonToPolyline(shibeiPolyline.features[
i].geometry.coordinates)
}
this.addPolygon(obj)
this.addPolyline(shibeiPolyline)
},
convertPolygonToPolyline(MultiPolygon) {
let MultiLineString = []
MultiPolygon.forEach(Polygon => {
Polygon.forEach(LinearRing => {
let LineString = LinearRing
MultiLineString.push(LineString)
})
});
return MultiLineString
},
addPolygon(geojson) {
this.map.addSource('shibeiPolygonSource', {
'type': 'geojson',
'data': geojson
});
this.map.addLayer({
'id': 'shibeiPolygonLayer',
'type': 'fill-extrusion',
'source': 'shibeiPolygonSource',
'paint': {
'fill-extrusion-vertical-gradient': true,
'fill-extrusion-color': "#1d597b",
'fill-extrusion-height': 300,
'fill-extrusion-base': 0,
'fill-extrusion-opacity': 1
}
});
this.map.addLayer({
id: "text_JSON_layer",
type: "symbol",
source: "shibeiPolygonSource",
// minzoom: 5,
// maxzoom: 22,
interactive: true,
paint: {
'text-color': '#fff',
},
"layout": {
"text-field": "{name}",
'text-size': 40
}
});
},
addSinglePolygon(geojson) {
this.map.addSource('SinglePolygonSource', {
'type': 'geojson',
'data': geojson
});
this.map.addLayer({
'id': 'SinglePolygonLayer',
'type': 'fill-extrusion',
'source': 'SinglePolygonSource',
'paint': {
'fill-extrusion-vertical-gradient': true,
'fill-extrusion-color': "#1d597b",
'fill-extrusion-height': 300,
'fill-extrusion-base': 0,
'fill-extrusion-opacity': 1
}
});
this.map.addLayer({
id: "SingleTextLayer",
type: "symbol",
source: "SinglePolygonSource",
// minzoom: 5,
// maxzoom: 22,
interactive: true,
paint: {
'text-color': '#fff',
},
"layout": {
"text-field": "{name}",
'text-size': 40
}
});
},
addHeightPolygon(geojson) {
this.map.addSource('heightPolygonSource', {
'type': 'geojson',
'data': geojson
});
this.map.addLayer({
'id': 'heightPolygonLayer',
'type': 'fill-extrusion',
'source': 'heightPolygonSource',
'paint': {
'fill-extrusion-vertical-gradient': true,
'fill-extrusion-color': "#b3b817",
'fill-extrusion-height': 300,
'fill-extrusion-base': 0,
'fill-extrusion-opacity': 1
},
});
},
addPolyline(geojson) {
// 8 ~ 18
for (let i = 8; i <= 18; i++) {
let radius = 1 * this.resolutions[i + 1] // 24
let lineBuffer = turf.buffer(geojson, radius, {
units: 'meters'
});
this.map.addSource('lineBufferSource-' + i, {
'type': 'geojson',
'data': lineBuffer
});
this.map.addLayer({
'id': 'lineBufferLayer-' + i,
'type': 'fill-extrusion',
'source': 'lineBufferSource-' + i,
"minzoom": (i - 1),
"maxzoom": (i + 1),
'paint': {
'fill-extrusion-vertical-gradient': true,
'fill-extrusion-color': '#4bbdd8',
'fill-extrusion-height': 310, //
'fill-extrusion-base': 300,//
'fill-extrusion-opacity': 0.3
}
});
}
},
initialization() {
if (this.map.getLayer("shibeiPolygonLayer")) {
this.map.removeLayer("shibeiPolygonLayer")
this.map.removeLayer("text_JSON_layer")
this.map.removeSource("shibeiPolygonSource")
}
if (this.map.getLayer("SinglePolygonLayer")) {
this.map.removeLayer("SinglePolygonLayer")
this.map.removeLayer("SingleTextLayer")
this.map.removeSource("SinglePolygonSource")
}
for (let i = 8; i <= 18; i++) {
if (this.map.getLayer("lineBufferLayer-" + i)) {
this.map.removeLayer("lineBufferLayer-" + i)
this.map.removeSource("lineBufferSource-" + i)
}
}
if (this.map.getLayer("pointDimensions")) {
this.map.removeLayer("pointDimensions")
this.map.removeSource("pointDimensions")
this.map.removeImage("markIcons")
}
if (this.map.getLayer("pointDimension")) {
this.map.removeLayer("pointDimension")
this.map.removeSource("pointDimension")
this.map.removeImage("markIcon")
}
this.layersIndex = 1
this.buttonIndex = 0
this.getPolygonJson(this.shibeiJson)
this.map.setZoom(12.5)
this.map.setCenter([120.38140448734, 36.11044959486])
},
selectType(value, label) {
if (value === this.buttonIndex) {
this.buttonIndex = 0
this.makeMarkers(this.markerJson)
return
}
this.buttonIndex = value
let json = {
"type": "FeatureCollection",
"features": JSON.parse(JSON.stringify(this.markerJson.features)).filter(f => {
return f.properties.name == label
})
}
this.makeMarkers(json)
},
getBoundary(id) {
const ts = Date.now();
let signConfig = {
key: '612d304095c50369c3ef06e490f05779eeb8f19ff16566c73aeafafc5fa01970',
dataType: 'real',
appId: 'acc4ad66c82a7b46e741364b4c62dce2',
customerId: 'b09527201c4409e19d1dbc5e3c3429a1',
authType: 'md5',
}
const token = md5(`${signConfig.key}:${ts}`);
axios({
method: "post",
url: "https://epmet-open.elinkservice.cn/api/data/report/screen/agency/compartment",
data: {
agencyId: id
},
headers: {
AccessToken: token,
AppId: signConfig.appId,
CustomerId: signConfig.customerId,
AuthType: signConfig.authType,
ts
}
}).then(e => {
if (e.data.code == 0 && e.data.data) {
if (e.data.data.agencyDistribution && e.data.data.agencyDistribution.length == 0) {
return
}
if (this.map.getLayer("shibeiPolygonLayer")) {
this.map.removeLayer("shibeiPolygonLayer")
this.map.removeLayer("text_JSON_layer")
this.map.removeSource("shibeiPolygonSource")
}
if (this.map.getLayer("SinglePolygonLayer")) {
this.map.removeLayer("SinglePolygonLayer")
this.map.removeLayer("SingleTextLayer")
this.map.removeSource("SinglePolygonSource")
}
for (let i = 8; i <= 18; i++) {
if (this.map.getLayer("lineBufferLayer-" + i)) {
this.map.removeLayer("lineBufferLayer-" + i)
this.map.removeSource("lineBufferSource-" + i)
}
}
let obj = {
type: "FeatureCollection",
name: "index",
features: e.data.data.agencyDistribution
}
obj.features.forEach(f => {
f.type = "Feature"
f.properties = {}
f.geometry = {}
f.properties.subId = f.subId || ""
f.properties.name = f.subName || ""
f.geometry.type = "MultiPolygon"
f.geometry.coordinates = [[JSON.parse(f.subAreaMarks)]] || []
delete f.agencyLevel
delete f.subAreaMarks
delete f.subCenterMark
delete f.subId
delete f.subName
})
this.getPolygonJson(obj)
if (this.features["properties"]["name"].indexOf("社区") != -1) {
this.selectType(0, "")
this.layersIndex = 3
}
}
}).catch(f => {
console.log(f);
})
},
makeMarkers(json) {
const _this = this;
if (_this.map.getLayer("pointDimension")) {
_this.map.removeLayer("pointDimension")
_this.map.removeSource("pointDimension")
_this.map.removeImage("markIcon")
}
_this.map.loadImage(markIcon, function (error, image) {
_this.map.addImage("markIcon", image);
_this.map.addSource("pointDimension", {
type: "geojson" /* geojson类型资源 */,
data: json
});
_this.map.addLayer({
id: "pointDimension",
type: "symbol" /* symbol类型layer,一般用来绘制点*/,
source: "pointDimension",
layout: {
"icon-image": "markIcon",
"icon-size": 2,
},
// paint: {
// "circle-radius": 4,
// "circle-color": "#B42222"
// }
});
_this.layersIndex = 3
});
},
makeMarker(json) {
const _this = this;
if (_this.map.getLayer("pointDimensions")) {
_this.map.removeLayer("pointDimensions")
_this.map.removeSource("pointDimensions")
_this.map.removeImage("markIcons")
}
_this.showFirst = true
_this.map.loadImage(markIcons, function (error, image) {
_this.map.addImage("markIcons", image);
_this.map.addSource("pointDimensions", {
type: "geojson" /* geojson类型资源 */,
data: json
});
_this.map.addLayer({
id: "pointDimensions",
type: "symbol" /* symbol类型layer,一般用来绘制点*/,
source: "pointDimensions",
layout: {
"icon-image": "markIcons",
"icon-size": 2,
},
// paint: {
// "circle-radius": 4,
// "circle-color": "#B42222"
// }
});
});
},
microgridDetails(item) {
this.showMicrogridDetails = true
this.microgridIndex = item.value
this.microgridObj.firstTitle = item.label
},
close() {
this.showFirst = false
this.showMicrogridDetails = false
},
handleCurrentChange(e) {
let times = 5
this.microgridObj.list = JSON.parse(JSON.stringify(this.microgridObjCopy.list)).slice(e * times - times, e * times)
} }
} }
} }
@ -19,5 +867,13 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.screen-center { .screen-center {
flex: 1;
min-width: 1000px;
}
::v-deep .mapboxgl-ctrl {
display: none !important;
}
::v-deep .el-pagination.is-background .el-pager li:not(.disabled).active {
background-color: #0aabca;
} }
</style> </style>

2
src/views/screenHeader.vue

@ -65,7 +65,7 @@ img {
display: flex; display: flex;
} }
.main-title { .main-title {
margin-left: 499px; margin-left: 15vw;
position: relative; position: relative;
.title-img { .title-img {

132
src/views/screenLeft/left1.vue

@ -2,7 +2,12 @@
<div class="bg-content left1"> <div class="bg-content left1">
<div class='b-dlzz'> <div class='b-dlzz'>
<screen-title :titleName="'动力主轴'"></screen-title> <screen-title :titleName="'动力主轴'"></screen-title>
<div class="dlzz-tree"></div> <div class="dlzz-tree">
<el-image style="width: 90%; height: 85%;"
:src="require('../../assets/images/dlzz.png')"
@click="goShowDlzz"></el-image>
</div>
<div class="dlzz-static"> <div class="dlzz-static">
<div class="dlzz-static-item"> <div class="dlzz-static-item">
<img class="item-img" <img class="item-img"
@ -82,12 +87,41 @@
</div> </div>
</div> </div>
<el-dialog :visible.sync="ifShowDlzz"
width="90%"
:modal="false">
<div style="color: #fff;display: flex; align-items: center;
justify-content: center;flex-direction: column;">
<div class="first"
@click="NodeClick(null,{label:'市北区委'})">
<el-image style="width: 80px; height: 60px;margin-right: 8px;"
:src="require('../../assets/images/hq.png')"></el-image>
{{list.label}}
</div>
<div>
<el-image style="width: 130px; height: 90px;"
:src="require('../../assets/images/xx.png')"></el-image>
</div>
<!-- <div style="display: flex;flex-wrap: nowrap;max-width: 100%;overflow-x: auto;margin-bottom: 12px;">
<div class="second"
v-for="(item,index) in list.children"
:key="index">
{{ item.label }}
</div>
</div> -->
<vue2-org-tree :data="list"
class="orgTree"
style="max-width: 100%;overflow-x: auto;background-color: #03374c;font-size: 30px;"
@on-node-click="NodeClick" />
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getOrgTree } from "api/index"
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getDyfcList } from 'api/index'
export default { export default {
name: "screen-left1", name: "screen-left1",
@ -124,7 +158,9 @@ export default {
}, },
dyfcList: [], dyfcList: [],
showContent: '', showContent: '',
popupVisible: false popupVisible: false,
ifShowDlzz: false,
list: {},
} }
}, },
computed: { computed: {
@ -294,6 +330,40 @@ export default {
},
async getOrgTree() {
try {
const res = await getOrgTree()
this.list = JSON.parse(JSON.stringify(res.data).replace(/value/g, "id"));
this.$nextTick(() => {
let dom = document.querySelector('.orgTree');
let intViewportWidth = window.innerWidth;
dom.scrollLeft = intViewportWidth * 5
let dom1 = document.querySelector(".org-tree-node-label");
dom1.remove()
})
} catch (err) {
console.error(err)
}
},
goShowDlzz() {
this.ifShowDlzz = true;
this.getOrgTree()
},
NodeClick(e, data) {
if (data.label.indexOf("党工委") != -1) {
this.list.children = []
this.list.children.push(data)
this.$nextTick(() => {
let dom = document.querySelector(".org-tree-node")
console.log(dom, 999);
})
}
if (data.label == "市北区委") {
this.getOrgTree()
}
} }
} }
} }
@ -310,14 +380,13 @@ export default {
.dlzz-tree { .dlzz-tree {
height: 484px; height: 484px;
background-color: #03364b;
display: flex;
justify-content: center;
align-items: center;
} }
.dlzz-static { .dlzz-static {
background: linear-gradient( background: #03364b;
0deg,
rgba(0, 204, 211, 0.38) 0%,
rgba(10, 218, 234, 0) 100%
);
box-sizing: border-box; box-sizing: border-box;
padding: 14px 24px 16px 17px; padding: 14px 24px 16px 17px;
@ -431,4 +500,49 @@ export default {
} }
} }
} }
.first {
background-image: linear-gradient(#055b8d, #0695b7);
width: fit-content;
padding: 20px 40px;
display: flex;
align-items: center;
font-size: 40px;
cursor: pointer;
}
.second {
background-image: linear-gradient(#055b8d, #0695b7);
width: fit-content;
height: auto;
font-size: 30px;
padding: 20px 30px;
margin-right: 12px;
white-space: nowrap;
}
::v-deep {
.el-dialog {
background-color: #03374c;
}
.el-dialog__headerbtn {
font-size: 63px;
color: #09e5ea;
}
.org-tree-node-label-inner {
background-image: linear-gradient(#055b8d, #0695b7);
cursor: pointer;
}
.org-tree-node:not(:first-child):before,
.org-tree-node:not(:last-child):after {
border-top: 1px solid #188eb6;
}
.org-tree-node:after {
border-left: 1px solid #188eb6;
}
.org-tree-node-children:before {
border-left: 1px solid #188eb6;
}
.org-tree-node-label .org-tree-node-label-inner {
padding: 20px 25px;
// font-size: 34px;
}
}
</style> </style>

418
src/views/screenRight/right3.vue

@ -4,12 +4,49 @@
<div b-sjtj> <div b-sjtj>
<screen-title :titleName="'数据统计'" <screen-title :titleName="'数据统计'"
style="width:310px" style="width:310px"
:type="'short'"></screen-title> :type="'short'"
:ifShowDropdown="true"></screen-title>
<div class="dataStatistics">
<div>
<div style="display: flex;">
<el-image style="width: 120px; height: 100px;margin-right: 8px;"
:src="require('../../assets/images/dataicon.png')"></el-image>
<div style="color:#fff;font-weight: 600;">
<div style="font-size: 24px;margin-bottom: 6px;">
{{format(dataTotal)}}
</div>
<div style="font-size: 16px;">总数</div>
</div>
</div>
<div>
<div style="display: flex;flex-direction: row;width: 100%;flex-wrap: wrap;justify-content: space-between;">
<div v-for="item in type"
:key="item.id"
style="width: 33%;display: flex;margin-bottom: 18px;">
<div :style="{width: '8px',height: '8px',backgroundColor:item.color,margin:'8px 8px 0 0'}"></div>
<div>
<div>
<span style="color:#188ab3;font-size: 18px;">{{ item.title }}</span>
</div>
<div style="color: #fff;font-size: 20px;">
{{format(item.num ) }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<div b-myd> <div b-myd>
<screen-title :titleName="'满意度'" <screen-title :titleName="'满意度'"
style="width:310px" style="width:310px"
:type="'short'"></screen-title> :type="'short'"></screen-title>
<div class="Satisfaction">
<div style="width: 290px;height: 290px;"
ref="chart"></div>
</div>
</div> </div>
</div> </div>
<div class='b-row2'> <div class='b-row2'>
@ -17,32 +54,400 @@
<screen-title :titleName="'事件类型分析'" <screen-title :titleName="'事件类型分析'"
style="width:310px" style="width:310px"
:type="'short'"></screen-title> :type="'short'"></screen-title>
<div class="Satisfaction">
<div style="width: 290px;height: 290px;"
ref="charts"></div>
</div>
</div> </div>
<div b-dxal> <div b-dxal>
<screen-title :titleName="'典型案例'" <screen-title :titleName="'典型案例'"
style="width:310px" style="width:310px"
:type="'short'"></screen-title> :type="'short'"></screen-title>
<div @mouseenter="tableMouseEnter"
@mouseleave="tableMouseLeave"
class="ytal-list">
<div class="ytal-list-tran"
:style="{top: top, transition: transition}">
<div class="ytal-item"
v-for="(item,index) in ytalList"
:key="index">
<div class="ytal-item-detail">{{item.detail}}</div>
<div class="ytal-item-line"></div>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div class='b-hztj'> <div class='b-hztj'>
<screen-title :titleName="'汇总统计'"></screen-title> <screen-title :titleName="'汇总统计'"></screen-title>
<div class="table">
<screen-custom-table :headerColor="'#BDE8FF'"
:headerHeight="'36px'"
:bodyTdColor="'#FFFFFF'"
:bodyTdFontSize="'18px'"
:tableHeight="104"
:showTableLine="true"
:dataList="dataListResult"
:isChangeColor=false
:rowColor="'rgba(11,68,135,0.16)'"
:noData="noData"
:pageSize="pageSize"
:headerList="headerList">
</screen-custom-table>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts';
import { loadXjphList, loadYtalList } from './../../data/index';
export default { export default {
name: "screen-right3", name: "screen-right3",
data() { data() {
return { return {
DropdownData: [
{ id: 1, name: "测试测试测试测试测试测试" },
{ id: 2, name: "测试测试测试" },
{ id: 3, name: "测试测试" },
],
dataTotal: 27054,
type: [{
id: 0,
title: "待响应",
num: 20,
color: "#f54f05"
}, {
id: 1,
title: "处理中",
num: 542,
color: "#00f097"
}, {
id: 2,
title: "已结案",
num: 26492,
color: "#00c3ff"
}, {
id: 3,
title: "红灯事件",
num: 21,
color: "#ff1466"
}, {
id: 4,
title: "黄灯事件",
num: 4,
color: "#f1be01"
}, {
id: 5,
title: "绿灯事件",
num: 537,
color: "#08c42c"
}],
charData: [
{
name: '不满意',
value: 20
},
{
name: '非常满意',
value: 45
},
{
name: '基本满意',
value: 35
}
],
charsData: [
{
name: '城市管理',
value: 20
},
{
name: '居民生活',
value: 45
},
{
name: '城管执法',
value: 35
},
{
name: '环境保护',
value: 20
},
{
name: '交通运输',
value: 45
},
{
name: '其他',
value: 35
}
],
chart: null,
charts: null,
ytalList: [],
top: 0,
scrollTime: 0,
transition: 'top 1s linear',
timer: '',
pageSize: 7,
tableHeight: 104,
dataList: [],
dataListResult: [],
headerList: [{ title: '排名', width: '400px' }, { title: '街道', width: '1000px' }, { title: '诉求总数', width: '800px' }, { title: '民生诉求', width: '800px' }, { title: '发展诉求', width: '800px' }, '执法', { title: '响应率', color: '#00E099' }, { title: '办事率', color: '#FFB400' }],
noData: false,
} }
},
mounted() {
this.renderChart()
this.renderCharts()
const _this = this
window.addEventListener("resize", () => {
_this.chart.resize();
_this.charts.resize();
});
_this.ytalList = loadYtalList()
_this.dataList = loadXjphList()
_this.$nextTick(function () {
_this.initList()
});
},
watch: {
ytalList: {
immediate: true,
handler: function (newvalue) {
if (newvalue.length > 0) {
this.scrollView()
} else {
clearInterval(this.timer)
} }
} }
</script> }
},
methods: {
format(num) {
var reg = /\d{1,3}(?=(\d{3})+$)/g;
return (num + '').replace(reg, '$&,');
},
renderChart() {
const chart = echarts.init(this.$refs.chart);
let option;
if (this.charData.length > 0) {
option = {
title: {
textStyle: {
fontWeight: "normal",
fontSize: 16
},
left: "center"
},
color: ["#f14f0c", "#15aae4", "#16e49c"],
tooltip: {
trigger: "item",
formatter: "{b}:{d}%"
},
series: [
{
type: "pie",
center: ["50%", "30%"],//
radius: ["20%", "40%"],
label: {
show: true,
},
labelLine: {
normal: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)'
},
smooth: 0.2,
length: "10"
}
},
data: this.charData
}
]
};
} else {
option = {
title: {
// text: this.charTitle,
textStyle: {
fontWeight: "normal",
fontSize: 16
},
left: "center"
},
tooltip: {
trigger: "none"
},
color: ["#d3d3d3"],
series: [
{
type: "pie",
radius: ["30%", "60%"],
left: "center",
label: {
show: true,
formatter: "{b}"
},
data: [{ value: 1, name: "暂无数据" }]
}
]
};
}
chart.setOption(option);
this.chart = chart;
},
renderCharts() {
const chart = echarts.init(this.$refs.charts);
let option;
if (this.charData.length > 0) {
option = {
title: {
textStyle: {
fontWeight: "normal",
fontSize: 16
},
left: "center"
},
color: ["#1bd140", "#2aaee9", "#f0200a", "#fb8010", "#9232f0", "#d1124d"],
tooltip: {
trigger: "item",
formatter: "{b}:{d}%"
},
legend: {
orient: 'horizontal',
itemWidth: 8,//
itemHeight: 8,//
itemGap: 20,//
top: 200,
textStyle: {//
color: "#fff",
fontSize: 14,
fontFamily: "微软雅黑"
}
},
series: [
{
type: "pie",
radius: ["30%", "50%"],
center: ["50%", "30%"],//
label: {
show: false,
position: 'center'
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: this.charsData
}
]
};
} else {
option = {
title: {
// text: this.charTitle,
textStyle: {
fontWeight: "normal",
fontSize: 16
},
left: "center"
},
tooltip: {
trigger: "none"
},
color: ["#d3d3d3"],
series: [
{
type: "pie",
radius: ["30%", "60%"],
label: {
show: true,
formatter: "{b}"
},
data: [{ value: 1, name: "暂无数据" }]
}
]
};
}
chart.setOption(option);
this.charts = chart;
},
tableMouseEnter() {
clearInterval(this.timer)
},
tableMouseLeave() {
this.scrollView()
},
scrollView() {
clearInterval(this.timer)
this.timer = setInterval(() => {
if (this.ytalList.length % this.pageSize === 0) {
if (this.scrollTime < this.ytalList.length / this.pageSize - 1) {
this.transition = 'top 1s linear'
this.scrollTime += 1
this.top = `-${this.tableHeight * this.scrollTime}%`
} else {
this.transition = 'top 1s ease-in-out'
this.top = '0px'
this.scrollTime = 0
}
} else {
if (
this.scrollTime < Math.floor(this.ytalList.length / this.pageSize)
) {
this.transition = 'top 1s linear'
this.scrollTime += 1
this.top = `-${this.tableHeight * this.scrollTime}%`
} else {
this.transition = 'top 1s ease-in-out'
this.top = '0px'
this.scrollTime = 0
}
}
}, 5000)
},
initList() {
this.dataListResult = []
this.dataList.forEach(element => {
this.dataListResult.push([
element.no,
element.unit,
element.dys,
element.hts,
element.yts,
element.sqs,
element.jal,
element.myl,
])
});
},
}
}
</script>
<style lang="scss" src="style/right1.scss" scoped></style>
<style src="style/right2.scss" lang="scss" scoped></style>
<style lang="scss" scoped> <style lang="scss" scoped>
.right3 { .right3 {
margin-left: 12px; margin-left: 12px;
@ -50,6 +455,13 @@ export default {
.b-row1 { .b-row1 {
height: 328px; height: 328px;
display: flex; display: flex;
.dataStatistics {
padding: 24px 0 0 24px;
}
.Satisfaction {
padding: 24px 0 0 24px;
}
} }
.b-row2 { .b-row2 {

Loading…
Cancel
Save