|
|
@@ -0,0 +1,495 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ class="edit-view"
|
|
|
+ :style="{
|
|
|
+ backgroundImage: `url(${require('../assets/pc_shuju_bg.jpg')})`
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-tooltip class="item" v-if="selectValue !== '320000'" content="返回江苏省地图" placement="bottom">
|
|
|
+ <el-button
|
|
|
+ class="back"
|
|
|
+ type="warning"
|
|
|
+ icon="el-icon-arrow-left"
|
|
|
+ circle
|
|
|
+ @click="changeSelect('320000')"
|
|
|
+ ></el-button>
|
|
|
+ </el-tooltip>
|
|
|
+
|
|
|
+ <div class="header">{{ title }}</div>
|
|
|
+ <div ref="chart" id="map-chart"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import 'echarts-gl';
|
|
|
+import '../map';
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ myChart: null,
|
|
|
+ active: '南京市',
|
|
|
+ preActive: '南京市',
|
|
|
+ flag: true,
|
|
|
+ isOn: false,
|
|
|
+ timeData: null,
|
|
|
+ desc: 200,
|
|
|
+ sndStat: {},
|
|
|
+ showLables: [],
|
|
|
+ type: 1,
|
|
|
+ title: '',
|
|
|
+ selectValue: '320000',
|
|
|
+ valList: [30, 1000],
|
|
|
+ showLabel: true,
|
|
|
+ allInfo: {}
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ mapInfos() {
|
|
|
+ return echarts.getMap(this.selectValue) ? echarts.getMap(this.selectValue).geoJson.features : [];
|
|
|
+ },
|
|
|
+ selectName() {
|
|
|
+ let allCitys = echarts.getMap('320000') ? echarts.getMap('320000').geoJson.features : [];
|
|
|
+
|
|
|
+ let info = allCitys.find(item => {
|
|
|
+ return item.properties.adcode === this.selectValue;
|
|
|
+ });
|
|
|
+ return info ? info.properties.name : '江苏省';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.type = this.$route.query.type || '1';
|
|
|
+ this.$nextTick(() => {
|
|
|
+ var chartDom = document.getElementById('map-chart');
|
|
|
+ this.myChart = echarts.init(chartDom);
|
|
|
+ if (Number(this.type) === 1) {
|
|
|
+ this.initScatter();
|
|
|
+ } else {
|
|
|
+ this.init3D();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ window.addEventListener('resize', this.resize);
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ active() {
|
|
|
+ this.changeChoose();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ changeSelect(code, max = 1000, min = 30, showLabel = true) {
|
|
|
+ if (code.toString().indexOf('00') !== -1) {
|
|
|
+ this.selectValue = code;
|
|
|
+ this.valList = [min, max];
|
|
|
+ this.showLabel = showLabel;
|
|
|
+ if (Number(this.type) === 1) {
|
|
|
+ this.initScatter();
|
|
|
+ } else {
|
|
|
+ this.init3D();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ resize() {
|
|
|
+ this.myChart.resize();
|
|
|
+ },
|
|
|
+ initScatter() {
|
|
|
+ this.title = this.selectName + '考级活动分布图';
|
|
|
+ let _datas = this.produceDataSeries(this.mapInfos.length, this.valList[1]);
|
|
|
+ this.myChart.setOption({
|
|
|
+ geo: {
|
|
|
+ map: this.selectValue,
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ color: '#fff'
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: '#0C4189',
|
|
|
+ borderColor: '#8CD9FD'
|
|
|
+ },
|
|
|
+ silent: true
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ },
|
|
|
+ visualMap: {
|
|
|
+ show: true,
|
|
|
+ bottom: 30,
|
|
|
+ left: 'center',
|
|
|
+ orient: 'horizontal',
|
|
|
+ min: 0,
|
|
|
+ max: this.getMax(_datas),
|
|
|
+ seriesIndex: 0,
|
|
|
+ calculable: true,
|
|
|
+ inRange: {
|
|
|
+ color: ['#FDA033', '#FD6C33', '#FD4C33']
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ let points = this.mapInfos.map((item, index) => {
|
|
|
+ return {
|
|
|
+ value: [...item.properties.center, _datas[index]],
|
|
|
+ name: item.properties.name,
|
|
|
+ adcode: item.properties.adcode
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.myChart.setOption({
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'effectScatter',
|
|
|
+ coordinateSystem: 'geo',
|
|
|
+ data: points,
|
|
|
+ selectedMode: 'single',
|
|
|
+ symbolSize: function(val) {
|
|
|
+ let size = val[2];
|
|
|
+ if (size < 20) {
|
|
|
+ size = size * 5;
|
|
|
+ }
|
|
|
+ return size;
|
|
|
+ },
|
|
|
+ encode: {
|
|
|
+ value: 2
|
|
|
+ },
|
|
|
+ showEffectOn: 'render',
|
|
|
+ rippleEffect: {
|
|
|
+ brushType: 'stroke'
|
|
|
+ },
|
|
|
+ hoverAnimation: true,
|
|
|
+ label: {
|
|
|
+ formatter: params => {
|
|
|
+ if (this.showLabel) {
|
|
|
+ return params.name + '\r\n' + params.value[2];
|
|
|
+ } else {
|
|
|
+ return params.value[2];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show: true,
|
|
|
+ color: '#fff',
|
|
|
+ fontWeight: 'bold'
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowColor: '#333'
|
|
|
+ },
|
|
|
+ zlevel: 1
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+
|
|
|
+ this.myChart.on('click', params => {
|
|
|
+ this.changeSelect(params.data.adcode, params.data.value[2], 0, false);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ produceDataSeries(account = 7, total = 100) {
|
|
|
+ let arr = new Array(account).fill(0);
|
|
|
+ for (let i = 0; i < total; i++) {
|
|
|
+ var num = parseInt((Math.random() * account).toString());
|
|
|
+ arr[num]++;
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ },
|
|
|
+ getRamdom(min, max) {
|
|
|
+ return Math.floor(Math.random() * (max - min)) + min;
|
|
|
+ },
|
|
|
+ getMax(list) {
|
|
|
+ list.sort((num1, num2) => {
|
|
|
+ return num1 - num2 < 0;
|
|
|
+ });
|
|
|
+ return list[0];
|
|
|
+ },
|
|
|
+ init3D() {
|
|
|
+ this.title = this.selectName + '本月各市考级数量柱状图';
|
|
|
+ this.myChart.clear();
|
|
|
+ setTimeout(() => {
|
|
|
+ this.allInfo = {
|
|
|
+ labels: this.mapInfos.map(item => {
|
|
|
+ return item.properties.name;
|
|
|
+ }),
|
|
|
+ data: this.produceDataSeries(this.mapInfos.length, this.valList[1])
|
|
|
+ };
|
|
|
+ this.active = this.mapInfos[0].properties.name;
|
|
|
+ this.myChart.setOption({
|
|
|
+ color: '#0A2B6A',
|
|
|
+ geo3D: {
|
|
|
+ map: `${this.selectValue}`,
|
|
|
+ shading: 'lambert',
|
|
|
+ instancing: true,
|
|
|
+ label: {
|
|
|
+ show: false,
|
|
|
+ formatter: params => {
|
|
|
+ this.active = params.name;
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ light: {
|
|
|
+ main: {
|
|
|
+ intensity: 1
|
|
|
+ },
|
|
|
+ ambient: {
|
|
|
+ intensity: 0.5
|
|
|
+ }
|
|
|
+ },
|
|
|
+ regionHeight: 5,
|
|
|
+ boxHeight: 40,
|
|
|
+ viewControl: {
|
|
|
+ distance: 200,
|
|
|
+ minDistance: 150,
|
|
|
+ alpha: 35,
|
|
|
+ beta: -10,
|
|
|
+ rotateSensitivity: [1, 0]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ zAxis3D: {
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: 40
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ id: 'value',
|
|
|
+ type: 'bar3D',
|
|
|
+ name: '江苏省数据',
|
|
|
+ coordinateSystem: 'geo3D',
|
|
|
+ shading: 'lambert',
|
|
|
+ data: [],
|
|
|
+ bevelSize: 0.3,
|
|
|
+ barSize: 5,
|
|
|
+ minHeight: 0,
|
|
|
+ bevelSmoothness: 2,
|
|
|
+ zlevel: 1,
|
|
|
+ silent: true,
|
|
|
+ light: {
|
|
|
+ main: {
|
|
|
+ intensity: 1.2
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'name',
|
|
|
+ type: 'bar3D',
|
|
|
+ name: '江苏省名称',
|
|
|
+ coordinateSystem: 'geo3D',
|
|
|
+ shading: 'lambert',
|
|
|
+ data: this.mapInfos.map(item => {
|
|
|
+ let value = this.getCenter(item, true);
|
|
|
+
|
|
|
+ if (this.active === item) {
|
|
|
+ value.push(15);
|
|
|
+ } else {
|
|
|
+ value.push(0);
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ name: item,
|
|
|
+ value: value,
|
|
|
+ itemStyle: {
|
|
|
+ color: this.active === item ? '#FA8816' : '#0A2B6A'
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ barSize: 1,
|
|
|
+ minHeight: 0,
|
|
|
+ bevelSmoothness: 0,
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ formatter: params => {
|
|
|
+ return params.name;
|
|
|
+ },
|
|
|
+ distance: 0,
|
|
|
+ textStyle: {
|
|
|
+ color: '#fff'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ silent: true,
|
|
|
+ zlevel: 2
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ this.myChart.getZr().on('mouseout', () => {
|
|
|
+ this.isOn = true;
|
|
|
+ });
|
|
|
+ this.myChart.getZr().on('globalout', () => {
|
|
|
+ this.isOn = false;
|
|
|
+ this.animationMove();
|
|
|
+ });
|
|
|
+ this.myChart.getZr().on('click', () => {
|
|
|
+ let isOn = document.getElementById('map-chart').children[0].style.cursor === 'pointer';
|
|
|
+ if (isOn) {
|
|
|
+ let code = this.getCode(this.active);
|
|
|
+ let index = this.mapInfos.findIndex(item => {
|
|
|
+ return this.active === item.properties.name;
|
|
|
+ });
|
|
|
+ this.changeSelect(code, this.allInfo.data[index], 0, false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.changeChoose();
|
|
|
+ this.animationMove();
|
|
|
+ }, 500);
|
|
|
+ },
|
|
|
+ changeChoose() {
|
|
|
+ const res = { ...this.allInfo };
|
|
|
+ let regions = res.labels.map(item => {
|
|
|
+ return {
|
|
|
+ name: item,
|
|
|
+ height: this.active === item ? 15 : 5,
|
|
|
+ itemStyle:
|
|
|
+ this.active === item
|
|
|
+ ? {
|
|
|
+ color: '#FA8816',
|
|
|
+ borderWidth: 1,
|
|
|
+ borderColor: '#FA8816'
|
|
|
+ }
|
|
|
+ : {
|
|
|
+ color: '#0A2B6A',
|
|
|
+ borderWidth: 1,
|
|
|
+ borderColor: '#8CD9FD'
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle:
|
|
|
+ this.active === item
|
|
|
+ ? {
|
|
|
+ color: '#FA8816'
|
|
|
+ }
|
|
|
+ : {
|
|
|
+ color: '#0A2B6A'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.myChart.setOption({
|
|
|
+ geo3D: {
|
|
|
+ regions: regions
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ id: 'value',
|
|
|
+ name: '江苏省数据',
|
|
|
+ data: res.labels.map((item, index) => {
|
|
|
+ let value = 0;
|
|
|
+ let _value = res.data[index] < 20 ? res.data[index] * 6 : res.data[index];
|
|
|
+ if (this.active === item) {
|
|
|
+ value = _value + this.desc;
|
|
|
+ } else {
|
|
|
+ value = _value;
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ name: item,
|
|
|
+ value: [...this.getCenter(item), value],
|
|
|
+ itemStyle: {
|
|
|
+ color: this.active === item ? '#ffc38c' : '#5AC1FF',
|
|
|
+ opacity: 0.8
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ formatter: params => {
|
|
|
+ if (params.name === this.active) {
|
|
|
+ return params.value[2] - this.desc;
|
|
|
+ } else {
|
|
|
+ return params.value[2];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ distance: 2,
|
|
|
+ textStyle: {
|
|
|
+ color: this.active === item ? '#FA8816' : '#fff',
|
|
|
+ fontSize: this.active === item ? 18 : 12,
|
|
|
+ opacity: 1,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ })
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'name',
|
|
|
+ name: '江苏省名称',
|
|
|
+ data: res.labels.map(item => {
|
|
|
+ let value = this.getCenter(item, true);
|
|
|
+ value.push(0);
|
|
|
+ return {
|
|
|
+ name: item,
|
|
|
+ value: value,
|
|
|
+ itemStyle: {
|
|
|
+ color: this.active === item ? '#FA8816' : '#0A2B6A'
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ distance: this.active === item ? 10 : 2,
|
|
|
+ textStyle: {
|
|
|
+ fontSize: this.active === item ? 18 : 12
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ })
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getCenter(name, isLable = false) {
|
|
|
+ let info = this.mapInfos.find(item => {
|
|
|
+ return name === item.properties.name;
|
|
|
+ });
|
|
|
+ let center = info ? info.properties.center : [0, 0];
|
|
|
+ if (isLable) {
|
|
|
+ center = [center[0] + 0.200151, center[1] - 0.276493];
|
|
|
+ }
|
|
|
+ return center;
|
|
|
+ },
|
|
|
+ getCode(name) {
|
|
|
+ let info = this.mapInfos.find(item => {
|
|
|
+ return name === item.properties.name;
|
|
|
+ });
|
|
|
+ let adcode = info ? info.properties.adcode : '320000';
|
|
|
+ return adcode;
|
|
|
+ },
|
|
|
+ animationMove() {
|
|
|
+ if (this.timeData) {
|
|
|
+ clearTimeout(this.timeData);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.timeData = setTimeout(() => {
|
|
|
+ if (!this.flag || this.isOn) {
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ const citys = this.mapInfos;
|
|
|
+ let index =
|
|
|
+ citys.findIndex(item => {
|
|
|
+ return this.active === item.properties.name;
|
|
|
+ }) || 0;
|
|
|
+ this.active = citys[(index + 1) % citys.length].properties.name;
|
|
|
+ this.animationMove();
|
|
|
+ }
|
|
|
+ }, 3000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+#map-chart {
|
|
|
+ flex-grow: 1;
|
|
|
+}
|
|
|
+.edit-view {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ background-position: center center;
|
|
|
+ background-size: cover;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.back {
|
|
|
+ position: absolute;
|
|
|
+ left: 30px;
|
|
|
+ top: 30px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.header {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 35px;
|
|
|
+ color: #ffffff;
|
|
|
+ line-height: 40px;
|
|
|
+ text-shadow: 0px 2px 19px rgba(55, 164, 224, 0.56), 0px 3px 0px #fff;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+}
|
|
|
+</style>
|