whychdw
2020-08-19 5abac21c35a9d859cf49d486ddfc8d7b0966784e
内容提交
8个文件已添加
10个文件已修改
773 ■■■■■ 已修改文件
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/basic.css 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/theme/science-blue.css 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ContentBox.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/MyElTree.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chart/BarChart.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chart/LineChart.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chart/PieChart.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/chart/theme/transparent.js 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/global/ChartManage.js 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/global/index.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/history.vue 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/dataTest/realTime.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/home.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -9,6 +9,7 @@
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "echarts": "^4.8.0",
    "element-ui": "^2.13.2",
    "vue": "^2.6.11",
    "vue-router": "^3.4.3"
public/index.html
@@ -5,6 +5,8 @@
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=WYFBZ-2Z5LD-EKL4B-HN6ZN-JFOTV-MQFHJ"></script>
    <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=WYFBZ-2Z5LD-EKL4B-HN6ZN-JFOTV-MQFHJ"></script>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
src/assets/css/basic.css
@@ -12,4 +12,22 @@
fieldset,img{border:0;}
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
.clearfix{*zoom:1;}
/*basic end*/
/*basic end*/
div::-webkit-scrollbar {
    /* 滚动条整体样式 */
    width: 0.03rem;
    height: 0.1rem;
}
div::-webkit-scrollbar-thumb {
    /* 滚动条里面小方块 */
    border-radius: 0.1rem;
    -webkit-box-shadow: inset 0 0 0.05rem rgba(0,0,0,0.2);
    background: #f9fafa;
}
div::-webkit-scrollbar-track {
    /* 滚动条里面轨道 */
    -webkit-box-shadow: inset 0 0 0.05rem rgba(0,0,0,0.2);
    border-radius: 0.1rem;
    background: #003d64;
}
src/assets/css/theme/science-blue.css
@@ -72,4 +72,15 @@
/* tree */
.el-science-blue .el-tree{
    background: none;
    color: #FFFFFF;
}
.el-science-blue .el-tree .el-tree-node:focus>.el-tree-node__content {
    background: none;
}
.el-science-blue .el-tree .el-tree-node>.el-tree-node__content:hover {
    background-color: #499ca1;
}
.el-science-blue .el-tree .el-tree-node.is-current>.el-tree-node__content{
    background-color: #499ca1;
}
src/components/ContentBox.vue
@@ -1,6 +1,6 @@
<template>
    <div class="content-box" :class="{'no-border': noborder}">
        <div class="content-box-title" :class="getTitlePos">
        <div class="content-box-title" :class="getTitlePos" v-if="!noHeader">
            <slot name="title">{{title}}</slot>
        </div>
        <div class="content-box-content">
@@ -28,6 +28,10 @@
            type: Boolean,
            default: false
        },
        noHeader: {
            type: Boolean,
            default: false
        }
    },
    computed: {
        getTitlePos: function() {
src/components/MyElTree.vue
New file
@@ -0,0 +1,52 @@
<template>
    <el-tree
    class="filter-tree"
    :data="data"
    :props="defaultProps"
    node-key="id"
    ref="tree"
    @node-click="nodeClick">
    </el-tree>
</template>
<script>
export default {
    name: 'MyElTree',
    props:{
        data:{
            type: Array,
            default() {
                return [];
            }
        }
    },
    data(){
        return {
            current: '',
            defaultProps: {
                children: 'children',
                label: 'label',
            }
        }
    },
    methods: {
        nodeClick(data, node) {
            node.isCurrent = node.isLeaf;
            if(node.isLeaf && this.current != node.key) {
                this.current = node.key;
                this.$emit('node-click', data);
            }
            this.$refs.tree.setCurrentKey(this.current);
        },
    }
}
</script>
<style scoped>
.filter-tree {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
</style>
src/components/chart/BarChart.vue
src/components/chart/LineChart.vue
src/components/chart/PieChart.vue
New file
@@ -0,0 +1,99 @@
<template>
    <div class="e-chart-root">
        <div class="e-chart-container">
            <div class="e-chart" :id="id" :ref="id"></div>
        </div>
    </div>
</template>
<script>
// 引入 ECharts 主模块
import ECharts from "echarts/lib/echarts";
//引入折线图
import "echarts/lib/chart/pie";
//引入提示框
import "echarts/lib/component/tooltip";
//引入标题
import "echarts/lib/component/title";
//引入图例标志
import "echarts/lib/component/legend";
//区域缩放
import "echarts/lib/component/dataZoom";
// 引入自定义主题
import "./theme/transparent"
export default {
    props: {
        id: {
            type: String,
            required: true,
        }
    },
    methods:{
        setOption() {
            let option = {
                title: {
                    // text: '某站点用户访问来源',
                    // subtext: '纯属虚构',
                    // left: 'center'
                },
                tooltip: {
                    trigger: 'item',
                    confine: true,
                    formatter: '{a} <br/>{b} : {c} ({d}%)'
                },
                legend: {
                    show: false,
                    orient: 'vertical',
                    left: 'left',
                    data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
                },
                series: [
                    {
                        name: '访问来源',
                        type: 'pie',
                        radius: '55%',
                        center: ['50%', '60%'],
                        data: [
                            {value: 335, name: '直接访问'},
                            {value: 310, name: '邮件营销'},
                            {value: 234, name: '联盟广告'},
                            {value: 135, name: '视频广告'},
                            {value: 1548, name: '搜索引擎'}
                        ],
                        emphasis: {
                            itemStyle: {
                                shadowBlur: 10,
                                shadowOffsetX: 0,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        }
                    }
                ]
            };
            // 设置配置项
            this.$G.chartManage.get(this.id).setOption(option);
        }
    },
    mounted() {
        // 基于准备好的dom,初始化echarts实例
        let chart = ECharts.init(this.$refs[this.id], 'transparent');
        // 将图表添加到图表管理
        this.$G.chartManage.set(this.id, chart);
        // 设置配置项
        this.setOption();
    }
}
</script>
<style scoped>
.e-chart-root,
.e-chart-container,
.e-chart {
    height: 100%;
    box-sizing: border-box;
}
</style>
src/components/chart/theme/transparent.js
New file
@@ -0,0 +1,177 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// 引入 ECharts 主模块
import ECharts from "echarts/lib/echarts";
var contrastColor = '#15E3F3';
var axisCommon = function () {
  return {
    axisLine: {
      lineStyle: {
        color: contrastColor
      }
    },
    axisTick: {
      show: false,
      lineStyle: {
        color: contrastColor
      }
    },
    axisLabel: {
      show: false,
      textStyle: {
        color: contrastColor
      }
    },
    splitLine: {
      show: false,
      lineStyle: {
        type: 'dashed',
        color: '#aaa'
      }
    },
    splitArea: {
      areaStyle: {
        color: contrastColor
      }
    }
  };
};
var colorPalette = ['#15E3F3', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53', '#eedd78', '#73a373', '#73b9bc', '#7289ab', '#91ca8c', '#f49f42'];
var theme = {
  color: colorPalette,
  backgroundColor: '',
  tooltip: {
    axisPointer: {
      lineStyle: {
        color: contrastColor
      },
      crossStyle: {
        color: contrastColor
      },
      label: {
        color: '#000'
      }
    }
  },
  legend: {
    textStyle: {
      color: contrastColor
    }
  },
  textStyle: {
    color: contrastColor
  },
  title: {
    textStyle: {
      color: contrastColor
    }
  },
  toolbox: {
    iconStyle: {
      normal: {
        borderColor: contrastColor
      }
    }
  },
  dataZoom: {
    textStyle: {
      color: contrastColor
    }
  },
  visualMap: {
    textStyle: {
      color: contrastColor
    }
  },
  timeline: {
    lineStyle: {
      color: contrastColor
    },
    itemStyle: {
      normal: {
        color: colorPalette[1]
      }
    },
    label: {
      normal: {
        textStyle: {
          color: contrastColor
        }
      }
    },
    controlStyle: {
      normal: {
        color: contrastColor,
        borderColor: contrastColor
      }
    }
  },
  timeAxis: axisCommon(),
  logAxis: axisCommon(),
  valueAxis: axisCommon(),
  categoryAxis: axisCommon(),
  line: {
    symbol: 'circle'
  },
  graph: {
    color: colorPalette
  },
  gauge: {
    title: {
      textStyle: {
        color: contrastColor
      }
    }
  },
  candlestick: {
    itemStyle: {
      normal: {
        color: '#FD1050',
        color0: '#0CF49B',
        borderColor: '#FD1050',
        borderColor0: '#0CF49B'
      }
    }
  }
};
ECharts.registerTheme('transparent', theme);
src/global/ChartManage.js
New file
@@ -0,0 +1,97 @@
// 引入 ECharts 主模块
import ECharts from "echarts/lib/echarts"
function ChartManage() {
    this.charts = {};
    this.group = '';
}
/**
 * [setChart description]
 *
 * @param   {String}  id     chart对象的id
 * @param   {Echarts}  chart  echarts对象
 */
ChartManage.prototype.set = function(id, chart) {
    // 将id和chart绑定
    this.charts[id] = chart;
};
ChartManage.prototype.get = function(id) {
    return this.charts[id]?this.charts[id]:-1;
};
ChartManage.prototype.del = function(id) {
    let chart = this.get(id);
    if(chart != -1) {
        // 销毁echarts
        chart.dispose();
        delete this.charts[id];
    }
};
ChartManage.prototype.resize = function(id) {
    let chart = this.get(id);
    if(chart != -1) {
        chart.resize();
    }
};
ChartManage.prototype.connect = function(ids) {
    let self = this;
    let groups = ids.map(function(id) {
        let chart = self.get(id);
        if(chart != -1) {
            return chart;
        }
    });
    let endChart = groups[groups.length-1];
    // 未获取的chart对象列表
    if(groups.length == 0 || !endChart) {
        return;
    }
    let dataZoom = endChart.getOption().dataZoom[0];
    groups.forEach(chart=> {
        chart.dispatchAction({
            type: 'dataZoom',
            batch: [
                {
                    // 第一个 dataZoom 组件
                    start: dataZoom.start,
                    end: dataZoom.end,
                }
            ]
        });
    });
    // 清空分组
    this.disconnect();
    this.group = ECharts.connect(groups);
}
ChartManage.prototype.disconnect = function() {
    ECharts.disconnect(this.group);
    // 清除分组信息
    Object.keys(this.charts).forEach(id=>{
        delete this.charts[id].group;
    });
}
ChartManage.prototype.changeDataZoom = function(id, range) {
    let chart = this.get(id);
    if(chart != -1) {
        chart.dispatchAction({
            type: 'dataZoom',
            batch: [
                {
                    // 第一个 dataZoom 组件
                    start: range[0],
                    end: range[1],
                }
            ]
        });
    }
}
export default new ChartManage();
src/global/index.js
New file
@@ -0,0 +1,5 @@
import chartManage from './ChartManage'
export default {
    chartManage
};
src/main.js
@@ -9,10 +9,19 @@
import './assets/css/basic.css'
import './assets/js/unCtrl'
import G from './global'
import layer from 'vue-layer'
import 'vue-layer/lib/vue-layer.css';
Vue.prototype.$layer = layer(Vue);
Vue.use(ElementUI);
Vue.config.productionTip = false
Vue.prototype.$G = G;
new Vue({
    router,
    render: h => h(App),
src/pages/dataTest/history.vue
@@ -1,15 +1,80 @@
<template>
    <flex-layout direction="row" class="page-history">
        <div style="width:360px" slot="header">
            树状导航
        </div>
        <content-box title="站点列表"
        slot="header" style="width:320px">
            <my-el-tree
            :data="data"></my-el-tree>
        </content-box>
        历史内容
    </flex-layout>
</template>
<script>
import ContentBox from '../../components/ContentBox'
import MyElTree from '../../components/MyElTree'
export default {
    components: {
        ContentBox,
        MyElTree,
    },
    data() {
        return {
            data: [
                {
                    id: '湖北省',
                    label: '湖北省',
                    children: [
                        {
                            id: '湖北省-武汉市',
                            label: '武汉市',
                            children: [
                                {
                                    id: '湖北省-武汉市-东西湖区',
                                    label: '东西湖区',
                                    children: [
                                        {
                                            id: '湖北省-武汉市-东西湖区-测试机房',
                                            label: '测试机房',
                                            children: [
                                                {
                                                    id: '湖北省-武汉市-东西湖区-测试机房-电池组1',
                                                    label: '电池组1',
                                                }
                                            ]
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                },
                {
                    id: '河南省',
                    label: '河南省',
                    children: [
                        {
                            id: '河南省-驻马店市',
                            label: '驻马店市',
                            children: [
                                {
                                    id: '河南省-驻马店市-驿城区',
                                    label: '驿城区',
                                    children: [
                                        {
                                            id: '河南省-驻马店市-驿城区-测试机房',
                                            label: '测试机房',
                                            children: []
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                }
            ]
        }
    }
}
</script>
src/pages/dataTest/realTime.vue
@@ -1,15 +1,83 @@
<template>
    <flex-layout direction="row" class="page-real-time">
        <div style="width:360px" slot="header">
        </div>
        <content-box title="站点列表"
        slot="header" style="width:320px">
            <my-el-tree
            :data="data"></my-el-tree>
        </content-box>
        实时内容
    </flex-layout>
</template>
<script>
import ContentBox from '../../components/ContentBox'
import MyElTree from '../../components/MyElTree'
export default {
    components: {
        ContentBox,
        MyElTree,
    },
    data() {
        return {
            data: [
                {
                    id: '湖北省',
                    label: '湖北省',
                    children: [
                        {
                            id: '湖北省-武汉市',
                            label: '武汉市',
                            children: [
                                {
                                    id: '湖北省-武汉市-东西湖区',
                                    label: '东西湖区',
                                    children: [
                                        {
                                            id: '湖北省-武汉市-东西湖区-测试机房',
                                            label: '测试机房',
                                            children: [
                                                {
                                                    id: '湖北省-武汉市-东西湖区-测试机房-电池组1',
                                                    label: '电池组1',
                                                }
                                            ]
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                },
                {
                    id: '河南省',
                    label: '河南省',
                    children: [
                        {
                            id: '河南省-驻马店市',
                            label: '驻马店市',
                            children: [
                                {
                                    id: '河南省-驻马店市-驿城区',
                                    label: '驿城区',
                                    children: [
                                        {
                                            id: '河南省-驻马店市-驿城区-测试机房',
                                            label: '测试机房',
                                            children: []
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                }
            ]
        }
    },
    mounted() {
    }
}
</script>
src/pages/home.vue
@@ -50,6 +50,15 @@
            drawer: false,
        }
    },
    watch: {
        acTabs: {
            handler(name) {  // 监测tab激活的位置
                // 存储激活的sessionStorage
                sessionStorage.setItem('acTabs', name);
            },
            immediate: true,
        }
    },
    methods: {
        removeTab(targetName) {
            let tabs = this.tabs;
@@ -86,7 +95,7 @@
            // 设置激活的导航
            this.acTabs = menu.name;
        },
    }
    },
}
</script>
src/pages/index.vue
@@ -2,56 +2,118 @@
    <flex-layout direction="row" class="page-index">
        <content-box title="站点列表" 
        slot="header" style="width:320px">
            <el-tree
            class="filter-tree"
            <my-el-tree
            :data="data"
            :props="defaultProps"
            ref="tree">
            </el-tree>
            @node-click="nodeClick"></my-el-tree>
        </content-box>
        <div class="map">地图</div>
        <div slot="footer" style="width:320px">
            4个饼状图
        <div class="map-container">
            <div ref="map" class="map-content"></div>
        </div>
        <content-box title="站点列表"
        slot="footer" style="width:320px" no-header>
            <div class="pie-list">
                <div class="pie-item">
                    <pie-chart id="chart1"></pie-chart>
                </div>
                <div class="pie-item">
                    <pie-chart id="chart2"></pie-chart>
                </div>
                <div class="pie-item">
                    <pie-chart id="chart3"></pie-chart>
                </div>
                <div class="pie-item">
                    <pie-chart id="chart4"></pie-chart>
                </div>
            </div>
        </content-box>
    </flex-layout>
</template>
<script>
import TMap from 'TMap'
import ContentBox from '../components/ContentBox'
import MyElTree from '../components/MyElTree'
import PieChart from '../components/chart/PieChart'
import { setInterval } from 'timers';
let map;
export default {
    components: {
        ContentBox
        ContentBox,
        MyElTree,
        PieChart,
    },
    data() {
        return {
            data: [
                {
                    id: 1,
                    label: '一级 1',
                    id: '湖北省',
                    label: '湖北省',
                    children: [
                        {
                            id: 4,
                            label: '二级 1-1',
                            id: '湖北省-武汉市',
                            label: '武汉市',
                            children: [
                                {
                                    id: 9,
                                    label: '三级 1-1-1'
                                },
                                    id: '湖北省-武汉市-东西湖区',
                                    label: '东西湖区',
                                    children: [
                                        {
                                            id: '湖北省-武汉市-东西湖区-测试机房',
                                            label: '测试机房',
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                },
                {
                    id: '河南省',
                    label: '河南省',
                    children: [
                        {
                            id: '河南省-驻马店市',
                            label: '驻马店市',
                            children: [
                                {
                                    id: 10,
                                    label: '三级 1-1-2'
                                }
                                    id: '河南省-驻马店市-驿城区',
                                    label: '驿城区',
                                    children: [
                                        {
                                            id: '河南省-驻马店市-驿城区-测试机房',
                                            label: '测试机房',
                                            children: []
                                        }
                                    ]
                                },
                            ]
                        }
                    ]
                }
            ],
            defaultProps: {
                children: 'children',
                label: 'label'
            }
        }
    },
    methods: {
        initMap() {
            map = new TMap.Map(this.$refs.map, {
                center: new TMap.LatLng(39.916527, 116.397128), //设置地图中心点坐标
                zoom: 17, //设置地图缩放级别
                viewMode: "3D",
                setPitch: 50
            });
            console.log(map);
        },
        nodeClick(data) {
            console.log(data);
        },
    },
    mounted() {
        // 初始化地图
        this.initMap();
        setInterval(()=>{
            console.log(sessionStorage.getItem('acTabs'));
        }, 2000);
    }
}
</script>
@@ -60,6 +122,24 @@
.page-index {
    color: #FFFFFF;
}
.map-container {
    margin-right: 4px;
    margin-left: 4px;
    box-sizing: border-box;
    height:100%;
}
.map-content {
    height: 100%;
}
.pie-list {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    height: 100%;
}
.pie-item {
    flex: 1;
}
</style>
vue.config.js
New file
@@ -0,0 +1,8 @@
module.exports = {
    publicPath: './',
    configureWebpack: config=> {
        config.externals = {
            TMap: "TMap"
        }
    }
}