├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── index.html ├── package-lock.json ├── package.json ├── project_code_structure.png ├── src ├── App.vue ├── assets │ ├── data │ │ ├── dataForDynamicThreeD.json │ │ ├── dataTreeNodeName.json │ │ └── demoData │ │ │ ├── fakeData.json │ │ │ └── housePrice.json │ ├── img │ │ ├── add.png │ │ ├── close.png │ │ ├── close_eye.png │ │ ├── demo_data_aa.png │ │ ├── his_data.png │ │ ├── mind_map.png │ │ ├── open_eye.png │ │ ├── private_data.png │ │ ├── service.png │ │ ├── test1.jpg │ │ ├── test1_paper.png │ │ ├── test2.jpg │ │ ├── test2_paper.png │ │ ├── test3.png │ │ ├── test3_paper.png │ │ ├── test4.jpg │ │ └── test4_paper.png │ └── webService │ │ └── GWR_war.war ├── bus │ └── messageBus.js ├── components │ ├── DataSelector.vue │ ├── DataViewer.vue │ ├── Home.vue │ ├── MapViewer.vue │ ├── ParDefiner.vue │ ├── RightSideForDataView.vue │ ├── RightSideForDescription.vue │ ├── RightSideForResult.vue │ ├── firstPage.vue │ ├── firstPage │ │ ├── DynamicThreed.vue │ │ └── slides.vue │ ├── login │ │ ├── coverForReset.vue │ │ ├── coverForSign.vue │ │ └── coverForlogin.vue │ └── rightSideForResult │ │ ├── MapForResult.vue │ │ ├── chartAnalysis.vue │ │ ├── computeLog.vue │ │ └── precision.vue ├── main.js ├── router │ └── index.js ├── store │ └── store.js └── style │ ├── app.scss │ ├── coverLogin.scss │ ├── dataSelector.scss │ ├── dataViewer.scss │ ├── firstPage.scss │ ├── home.scss │ ├── main_style.scss │ ├── parDefiner.scss │ └── rightSideForResult.scss ├── static ├── .gitkeep └── dataTreeNodeName.json └── test ├── e2e ├── custom-assertions │ └── elementCount.js ├── nightwatch.conf.js ├── runner.js └── specs │ └── test.js └── unit ├── .eslintrc ├── jest.conf.js ├── setup.js └── specs └── HelloWorld.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | /test/unit/coverage/ 8 | /test/e2e/reports/ 9 | selenium-debug.log 10 | 11 | # Editor directories and files 12 | .idea 13 | .vscode 14 | *.suo 15 | *.ntvs* 16 | *.njsproj 17 | *.sln 18 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## GTWR计算平台说明 2 | 3 | GTWR计算平台,本网站意图辅助用户进行GWR或GTWR的在线计算,支持计算参数自定义、原始数据及计算结果的多维度可视化。该平台主要包括以下几个主要功能模块: 4 | 5 | * 首屏展播:基于echarts-al制作3D动态可视化效果,突出平台主要内容与地理回归相关;利用轮播图展示GTWR计算的相关应用案例,包含案例来源文章基本信息、文章链接、主要图表等内容。 6 | * 原始数据预览:平台提供示例数据,它们根据数据集分类组织为树形结构,平台支持对数据集中每一份单独属性数据的预览,预览包括数据具体内容、数据在地图上的空间可视化两部分。 7 | * 原始数据计算:平台支持自定义计算参数,参数可选择原始数据中的数据属性,也可手动输入固定常量;开始计算后如果参数设置不完全、计算参数设置不正确或计算接口调用失败,平台都会给出错误的计算日志;如果计算成功,除计算过程的计算日志之后,还会曝光计算结果图表展示、计算结果精度评定两个入口,其中计算结果图表展示模块包含地图可视化、数据图表两部分,数据图表部分支持用户添加图表容器、自定义图表参数。 8 | 9 | 以上功能的实现依赖于Java Servlet、Leaflet地图API、Echarts图表库和Vue前端框架,平台代码仓库地址为:[https://github.com/GTWR/gtwr_vue](https://github.com/GTWR/gtwr_vue),执行过程为: 10 | 11 | 1. 下载JDK,安装并配置Java环境;下载Tomcat,安装并配置Tomcat环境,配置后打开tomcat服务。[windows环境下tomcat下载安装教程地址](https://www.cnblogs.com/beginner-boy/p/7806680.html),[Mac环境下tomcat下载安装教程地址](https://blog.csdn.net/feng2qing/article/details/60968548) 12 | **注意**: 平台默认tomcat端口为8080,若端口不为8080,则需要在代码库中[gtwr_vue/src/components/ParDefiner.vue](https://github.com/GTWR/gtwr_vue/blob/master/src/components/ParDefiner.vue)中compute函数中修改变量requestUrl中端口的定义。 13 | 2. 下载node,npm以及cnpm,[node安装配置教程地址](http://www.runoob.com/nodejs/nodejs-install-setup.html),[npm安装配置教程地址](http://www.runoob.com/nodejs/nodejs-npm.html) 14 | 3. 在[gtwr的代码库:https://github.com/GTWR/gtwr_vue](https://github.com/GTWR/gtwr_vue)中下载平台源代码 15 | 4. 将代码库路径[gtwr/src/assets/webservice/gwr_war.war](https://github.com/GTWR/gtwr_vue/tree/master/src/assets/webService)中的gwr_war.war文件放置在tomcat安装文件下webapps中 16 | 5. 在终端中打开源代码文件路径,执行如下代码安装平台依赖: 17 | ``` 18 | cnpm install //安装平台的依赖工具包 19 | npm run dev //运行平台代码,会自动打开浏览器展示前端界面 20 | ``` 21 | 22 | 以上的安装配置过程能够保证平台正常展示,而平台代码的修改需要熟悉代码库的代码结构,其结构如下: 23 | 24 | 25 | 26 | 组件中引用的样式文件,在组件`` 8 | 9 | 10 | 11 | gtwr_portal 12 | 20 | 21 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gtwr_portal", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "gemma", 6 | "private": true, 7 | "scripts": { 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "unit": "jest --config test/unit/jest.conf.js --coverage", 11 | "e2e": "node test/e2e/runner.js", 12 | "test": "npm run unit && npm run e2e", 13 | "build": "node --max_old_space_size=8000 build/build.js" 14 | }, 15 | "dependencies": { 16 | "axios": "^0.18.0", 17 | "cookie-parser": "^1.4.3", 18 | "express": "^4.16.4", 19 | "install": "^0.12.2", 20 | "jquery": "^3.3.1", 21 | "multer": "^1.3.1", 22 | "nodemon": "^1.18.4", 23 | "swiper": "^4.2.0", 24 | "vtip": "^1.0.6", 25 | "vue": "^2.5.2", 26 | "vue-awesome-swiper": "^3.1.3", 27 | "vue-concise-slider": "^2.4.8", 28 | "vue-resource": "^1.5.1", 29 | "vue-router": "^3.0.1" 30 | }, 31 | "devDependencies": { 32 | "autoprefixer": "^7.1.2", 33 | "babel-core": "^6.22.1", 34 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 35 | "babel-jest": "^21.0.2", 36 | "babel-loader": "^7.1.4", 37 | "babel-plugin-dynamic-import-node": "^1.2.0", 38 | "babel-plugin-syntax-jsx": "^6.18.0", 39 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", 40 | "babel-plugin-transform-runtime": "^6.22.0", 41 | "babel-plugin-transform-vue-jsx": "^3.5.0", 42 | "babel-preset-env": "^1.3.2", 43 | "babel-preset-es2015": "^6.24.1", 44 | "babel-preset-stage-2": "^6.22.0", 45 | "babel-register": "^6.22.0", 46 | "jquery": "^3.3.1", 47 | "chalk": "^2.0.1", 48 | "chromedriver": "^2.27.2", 49 | "copy-webpack-plugin": "^4.0.1", 50 | "cross-spawn": "^5.0.1", 51 | "css-loader": "^0.28.0", 52 | "csv-loader": "^2.1.1", 53 | "echarts": "4.1.0", 54 | "echarts-gl": "^1.1.0", 55 | "extract-text-webpack-plugin": "^3.0.0", 56 | "file-loader": "^1.1.4", 57 | "friendly-errors-webpack-plugin": "^1.6.1", 58 | "html-webpack-plugin": "^2.30.1", 59 | "jest": "^22.0.4", 60 | "jest-serializer-vue": "^0.3.0", 61 | "json-loader": "^0.5.7", 62 | "leaflet": "^1.3.1", 63 | "nightwatch": "^0.9.12", 64 | "node-notifier": "^5.1.2", 65 | "node-sass": "^4.8.3", 66 | "optimize-css-assets-webpack-plugin": "^3.2.0", 67 | "ora": "^1.2.0", 68 | "portfinder": "^1.0.13", 69 | "postcss-import": "^11.0.0", 70 | "postcss-loader": "^2.0.8", 71 | "postcss-url": "^7.2.1", 72 | "rimraf": "^2.6.0", 73 | "sass-loader": "^6.0.7", 74 | "selenium-server": "^3.0.1", 75 | "semver": "^5.3.0", 76 | "shelljs": "^0.7.6", 77 | "uglifyjs-webpack-plugin": "^1.1.1", 78 | "url-loader": "^0.5.8", 79 | "vue-hot-reload-api": "^2.3.0", 80 | "vue-html-loader": "^1.2.4", 81 | "vue-jest": "^1.0.2", 82 | "vue-loader": "^13.3.0", 83 | "vue-style-loader": "^3.1.2", 84 | "vue-template-compiler": "^2.5.2", 85 | "vuex": "^3.0.1", 86 | "webpack": "^3.6.0", 87 | "webpack-bundle-analyzer": "^2.9.0", 88 | "webpack-dev-server": "^2.9.1", 89 | "webpack-merge": "^4.1.0" 90 | }, 91 | "engines": { 92 | "node": ">= 6.0.0", 93 | "npm": ">= 3.0.0" 94 | }, 95 | "browserslist": [ 96 | "> 1%", 97 | "last 2 versions", 98 | "not ie <= 8" 99 | ] 100 | } 101 | -------------------------------------------------------------------------------- /project_code_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/project_code_structure.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 101 | 102 | 105 | -------------------------------------------------------------------------------- /src/assets/data/dataTreeNodeName.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name":"Canada house price", 3 | "centerPosition":[], 4 | "zoom": 10, 5 | "dataContent": "housePrice", 6 | "url":"../assets/data/demoData/", 7 | "children": [ 8 | {"name":"Oprice","decribeName":"原始房价数据"}, 9 | {"name":"Constant","decribeName":"常量"}, 10 | {"name":"Living","decribeName":"居住环境"}, 11 | {"name":"Quality","decribeName":"空气质量"}, 12 | {"name":"Structure","decribeName":"基础设施"}, 13 | {"name":"Renovation","decribeName":"装修情况"}, 14 | {"name":"Condiction","decribeName":"传导"}, 15 | {"name":"Greenspace","decribeName":"绿化面积"}, 16 | {"name":"Traffic","decribeName":"交通情况"}, 17 | {"name":"VIEW","decribeName":"视野环境"} 18 | ] 19 | },{ 20 | "name":"GWR test data", 21 | "dataContent":"fakeData", 22 | "centerPosition":[], 23 | "zoom":17, 24 | "url":"../assets/data/demoData/", 25 | "children":[ 26 | {"name":"PctBach","decribeName":"参数1"}, 27 | {"name":"TotPop90","decribeName":"参数2"}, 28 | {"name":"PctRural","decribeName":"参数3"} 29 | ] 30 | }] -------------------------------------------------------------------------------- /src/assets/data/demoData/fakeData.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "type": "FeatureCollection" , 3 | "name": "fakeData", 4 | "features": [ 5 | { 6 | "type": "Feature", 7 | "properties": { 8 | "name":1, 9 | "X":114.289, 10 | "Y":30.5882, 11 | "PctBach":1, 12 | "TotPop90":1, 13 | "PctRural":3 14 | }, 15 | "geometry": { 16 | "type": "Point", 17 | "coordinates": [114.289,30.5882] 18 | } 19 | },{ 20 | "type": "Feature", 21 | "properties": { 22 | "name":2, 23 | "X":114.289, 24 | "Y":30.5883, 25 | "PctBach":2, 26 | "TotPop90":2, 27 | "PctRural":2 28 | }, 29 | "geometry": { 30 | "type": "Point", 31 | "coordinates": [114.289,30.5883] 32 | } 33 | },{ 34 | "type": "Feature", 35 | "properties": { 36 | "name":3, 37 | "X":114.289, 38 | "Y":30.5883, 39 | "PctBach":3, 40 | "TotPop90":1, 41 | "PctRural":1 42 | }, 43 | "geometry": { 44 | "type": "Point", 45 | "coordinates": [114.289,30.5883] 46 | } 47 | },{ 48 | "type": "Feature", 49 | "properties": { 50 | "name":4, 51 | "X":114.289, 52 | "Y":30.5884, 53 | "PctBach":4, 54 | "TotPop90":2, 55 | "PctRural":5 56 | }, 57 | "geometry": { 58 | "type": "Point", 59 | "coordinates": [114.289,30.5884] 60 | } 61 | },{ 62 | "type": "Feature", 63 | "properties": { 64 | "name":5, 65 | "X":114.288, 66 | "Y":30.5882, 67 | "PctBach":5, 68 | "TotPop90":2, 69 | "PctRural":1 70 | }, 71 | "geometry": { 72 | "type": "Point", 73 | "coordinates": [114.288,30.5882] 74 | } 75 | },{ 76 | "type": "Feature", 77 | "properties": { 78 | "name":6, 79 | "X":114.288, 80 | "Y":30.5881, 81 | "PctBach":6, 82 | "TotPop90":1, 83 | "PctRural":2 84 | }, 85 | "geometry": { 86 | "type": "Point", 87 | "coordinates": [114.288,30.5881] 88 | } 89 | },{ 90 | "type": "Feature", 91 | "properties": { 92 | "name":7, 93 | "X":114.288, 94 | "Y":30.5881, 95 | "PctBach":7, 96 | "TotPop90":2, 97 | "PctRural":3 98 | }, 99 | "geometry": { 100 | "type": "Point", 101 | "coordinates": [114.288,30.5881] 102 | } 103 | },{ 104 | "type": "Feature", 105 | "properties": { 106 | "name":8, 107 | "X":114.288, 108 | "Y":30.5882, 109 | "PctBach":8, 110 | "TotPop90":1, 111 | "PctRural":1 112 | }, 113 | "geometry": { 114 | "type": "Point", 115 | "coordinates": [114.288,30.5882] 116 | } 117 | },{ 118 | "type": "Feature", 119 | "properties": { 120 | "name":9, 121 | "X":114.288, 122 | "Y":30.5878, 123 | "PctBach":9, 124 | "TotPop90":3, 125 | "PctRural":2 126 | }, 127 | "geometry": { 128 | "type": "Point", 129 | "coordinates": [114.288,30.5878] 130 | } 131 | },{ 132 | "type": "Feature", 133 | "properties": { 134 | "name":10, 135 | "X":114.288, 136 | "Y":30.5878, 137 | "PctBach":10, 138 | "TotPop90":1, 139 | "PctRural":4 140 | }, 141 | "geometry": { 142 | "type": "Point", 143 | "coordinates": [114.288,30.5878] 144 | } 145 | },{ 146 | "type": "Feature", 147 | "properties": { 148 | "name":11, 149 | "X":114.288, 150 | "Y":30.5878, 151 | "PctBach":11, 152 | "TotPop90":2, 153 | "PctRural":2 154 | }, 155 | "geometry": { 156 | "type": "Point", 157 | "coordinates": [114.288,30.5878] 158 | } 159 | },{ 160 | "type": "Feature", 161 | "properties": { 162 | "name":12, 163 | "X":114.288, 164 | "Y":30.588, 165 | "PctBach":12, 166 | "TotPop90":2, 167 | "PctRural":1 168 | }, 169 | "geometry": { 170 | "type": "Point", 171 | "coordinates": [114.288,30.588] 172 | } 173 | },{ 174 | "type": "Feature", 175 | "properties": { 176 | "name":13, 177 | "X":114.288, 178 | "Y":30.588, 179 | "PctBach":13, 180 | "TotPop90":5, 181 | "PctRural":2 182 | }, 183 | "geometry": { 184 | "type": "Point", 185 | "coordinates": [114.288,30.588] 186 | } 187 | },{ 188 | "type": "Feature", 189 | "properties": { 190 | "name":14, 191 | "X":114.288, 192 | "Y":30.5878, 193 | "PctBach":14, 194 | "TotPop90":1, 195 | "PctRural":3 196 | }, 197 | "geometry": { 198 | "type": "Point", 199 | "coordinates": [114.288,30.5878] 200 | } 201 | },{ 202 | "type": "Feature", 203 | "properties": { 204 | "name":15, 205 | "X":114.288, 206 | "Y":30.5881, 207 | "PctBach":15, 208 | "TotPop90":2, 209 | "PctRural":2 210 | }, 211 | "geometry": { 212 | "type": "Point", 213 | "coordinates": [114.288,30.5881] 214 | } 215 | },{ 216 | "type": "Feature", 217 | "properties": { 218 | "name":16, 219 | "X":114.289, 220 | "Y":30.5882, 221 | "PctBach":16, 222 | "TotPop90":2, 223 | "PctRural":1 224 | }, 225 | "geometry": { 226 | "type": "Point", 227 | "coordinates": [114.289,30.5882] 228 | } 229 | },{ 230 | "type": "Feature", 231 | "properties": { 232 | "name":17, 233 | "X":114.289, 234 | "Y":30.5882, 235 | "PctBach":17, 236 | "TotPop90":1, 237 | "PctRural":3 238 | }, 239 | "geometry": { 240 | "type": "Point", 241 | "coordinates": [114.289,30.5882] 242 | } 243 | },{ 244 | "type": "Feature", 245 | "properties": { 246 | "name":18, 247 | "X":114.288, 248 | "Y":30.5883, 249 | "PctBach":18, 250 | "TotPop90":2, 251 | "PctRural":2 252 | }, 253 | "geometry": { 254 | "type": "Point", 255 | "coordinates": [114.288,30.5883] 256 | } 257 | },{ 258 | "type": "Feature", 259 | "properties": { 260 | "name":19, 261 | "X":114.288, 262 | "Y":30.5881, 263 | "PctBach":19, 264 | "TotPop90":1, 265 | "PctRural":1 266 | }, 267 | "geometry": { 268 | "type": "Point", 269 | "coordinates": [114.288,30.5881] 270 | } 271 | },{ 272 | "type": "Feature", 273 | "properties": { 274 | "name":20, 275 | "X":114.288, 276 | "Y":30.5881, 277 | "PctBach":20, 278 | "TotPop90":1, 279 | "PctRural":2 280 | }, 281 | "geometry": { 282 | "type": "Point", 283 | "coordinates": [114.288,30.5881] 284 | } 285 | } 286 | ] 287 | }] -------------------------------------------------------------------------------- /src/assets/img/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/add.png -------------------------------------------------------------------------------- /src/assets/img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/close.png -------------------------------------------------------------------------------- /src/assets/img/close_eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/close_eye.png -------------------------------------------------------------------------------- /src/assets/img/demo_data_aa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/demo_data_aa.png -------------------------------------------------------------------------------- /src/assets/img/his_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/his_data.png -------------------------------------------------------------------------------- /src/assets/img/mind_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/mind_map.png -------------------------------------------------------------------------------- /src/assets/img/open_eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/open_eye.png -------------------------------------------------------------------------------- /src/assets/img/private_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/private_data.png -------------------------------------------------------------------------------- /src/assets/img/service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/service.png -------------------------------------------------------------------------------- /src/assets/img/test1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test1.jpg -------------------------------------------------------------------------------- /src/assets/img/test1_paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test1_paper.png -------------------------------------------------------------------------------- /src/assets/img/test2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test2.jpg -------------------------------------------------------------------------------- /src/assets/img/test2_paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test2_paper.png -------------------------------------------------------------------------------- /src/assets/img/test3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test3.png -------------------------------------------------------------------------------- /src/assets/img/test3_paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test3_paper.png -------------------------------------------------------------------------------- /src/assets/img/test4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test4.jpg -------------------------------------------------------------------------------- /src/assets/img/test4_paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/img/test4_paper.png -------------------------------------------------------------------------------- /src/assets/webService/GWR_war.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/src/assets/webService/GWR_war.war -------------------------------------------------------------------------------- /src/bus/messageBus.js: -------------------------------------------------------------------------------- 1 | // refer page: https://github.com/vuejs/vue/issues/2873 2 | 3 | import Vue from 'vue' 4 | var messageBus = new Vue(); 5 | export default messageBus; -------------------------------------------------------------------------------- /src/components/DataSelector.vue: -------------------------------------------------------------------------------- 1 |  44 | 45 | -------------------------------------------------------------------------------- /src/components/DataViewer.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 97 | -------------------------------------------------------------------------------- /src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 33 | -------------------------------------------------------------------------------- /src/components/MapViewer.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 165 | 166 | -------------------------------------------------------------------------------- /src/components/ParDefiner.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 212 | -------------------------------------------------------------------------------- /src/components/RightSideForDataView.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /src/components/RightSideForDescription.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 98 | -------------------------------------------------------------------------------- /src/components/RightSideForResult.vue: -------------------------------------------------------------------------------- 1 |  13 | 14 | 86 | -------------------------------------------------------------------------------- /src/components/firstPage.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /src/components/firstPage/DynamicThreed.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/firstPage/slides.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/login/coverForReset.vue: -------------------------------------------------------------------------------- 1 | 31 | 175 | -------------------------------------------------------------------------------- /src/components/login/coverForSign.vue: -------------------------------------------------------------------------------- 1 | 28 | 147 | -------------------------------------------------------------------------------- /src/components/login/coverForlogin.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 66 | -------------------------------------------------------------------------------- /src/components/rightSideForResult/MapForResult.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 142 | -------------------------------------------------------------------------------- /src/components/rightSideForResult/chartAnalysis.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 275 | -------------------------------------------------------------------------------- /src/components/rightSideForResult/computeLog.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /src/components/rightSideForResult/precision.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import store from './store/store' 7 | import $ from 'jquery' 8 | import VueResource from 'vue-resource' 9 | 10 | import Vtip from 'vtip' 11 | import 'vtip/lib/index.min.css' 12 | 13 | Vue.use(VueResource) 14 | Vue.use(Vtip.directive)// 注册指令使用 15 | Vue.prototype.$tip = Vtip.tip// 工具函数调用 16 | Vue.config.productionTip = false 17 | 18 | /* eslint-disable no-new */ 19 | 20 | new Vue({ 21 | el: '#app', 22 | router, 23 | store, 24 | components: { App }, 25 | template: '', 26 | }) 27 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import login from '@/components/firstPage' 4 | import Home from '@/components/Home' 5 | import RightSideForDataView from '@/components/RightSideForDataView' 6 | import RightSideForDescription from '@/components/RightSideForDescription' 7 | import RightSideForResult from '@/components/RightSideForResult' 8 | import chartAnalysis from '@/components/rightSideForResult/chartAnalysis' 9 | import computeLog from '@/components/rightSideForResult/computeLog' 10 | import precision from '@/components/rightSideForResult/precision' 11 | import slides from '@/components/firstPage/slides' 12 | 13 | Vue.use(Router) 14 | 15 | 16 | export default new Router({ 17 | mode: 'history', 18 | scrollBehavior (to, from, savedPosition) { 19 | if (savedPosition) { 20 | return savedPosition 21 | } else { 22 | if (from.meta.keepAlive) { 23 | from.meta.savedPosition = document.body.scrollTop 24 | } 25 | return { x: 0, y: to.meta.savedPosition || 0 } 26 | } 27 | }, 28 | routes: [ 29 | { 30 | path: '/', 31 | redirect:'/login' 32 | }, 33 | { 34 | path:'/login', 35 | component: login, 36 | }, 37 | { 38 | path:'/demo', 39 | component: slides 40 | }, 41 | { 42 | path:'/', 43 | component:Home, 44 | children:[ 45 | { 46 | path: "home", 47 | component: RightSideForDataView 48 | }, 49 | { 50 | path: "description", 51 | component: RightSideForDescription 52 | }, 53 | { 54 | path:'computeresult', 55 | component: RightSideForResult, 56 | children:[ 57 | { 58 | path:"computeLog", 59 | component: computeLog, 60 | }, 61 | { 62 | path:"chartAnalysis", 63 | component: chartAnalysis, 64 | }, 65 | { 66 | path:'precision', 67 | component: precision 68 | } 69 | ] 70 | } 71 | ] 72 | } 73 | ] 74 | }) 75 | -------------------------------------------------------------------------------- /src/store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import demoLogo from '../assets/img/demo_data_aa.png' 4 | import privateLogo from '../assets/img/private_data.png' 5 | Vue.use(Vuex); 6 | 7 | //计算分层设色的最大值和最小值;设置当前数据的中心位置 8 | var dataTreeNodeName = require('../assets/data/dataTreeNodeName.json');//要获取的json文件 9 | for(let i=0;itable, .data-head>table { 95 | table-layout: fixed; 96 | } 97 | .data-container .data-table{ 98 | flex-grow : 1; 99 | overflow-y : scroll; 100 | } 101 | -------------------------------------------------------------------------------- /src/style/firstPage.scss: -------------------------------------------------------------------------------- 1 | @import 'main_style.scss'; 2 | 3 | $title_font_size:27px; 4 | $shadow_card_1:0 2px 2px 0 $black_for_shadow; 5 | 6 | .container{ 7 | width: 100%; 8 | height: 100%; 9 | #hello{ 10 | width: 100%; 11 | height: 100%; 12 | overflow: hidden; 13 | #dynamic{ 14 | height: 100%; 15 | width: 100%; 16 | } 17 | } 18 | .intro-text{ 19 | display: flex; 20 | justify-content: center; 21 | .title{ 22 | position: absolute; 23 | height: 50px; 24 | width: 427px; 25 | top: 20%; 26 | left: 0; 27 | right: 0; 28 | margin: 0 auto; 29 | color:white; 30 | font-size: $title_font_size * 2; 31 | } 32 | .link{ 33 | color:lightseagreen; 34 | position: absolute; 35 | display: block; 36 | height: 50px; 37 | width: 320px; 38 | top: 95%; 39 | left: 0; 40 | right: 0; 41 | margin: 0 auto; 42 | font-weight: bold; 43 | font-size: 20px; 44 | } 45 | } 46 | } 47 | 48 | .slides{ 49 | height: 100%; 50 | width: 100%; 51 | overflow: hidden; 52 | display: flex; 53 | justify-content:center; 54 | .playBtn{ 55 | position: absolute; 56 | bottom: 10px; 57 | margin:0px auto; 58 | .circle{ 59 | width:11px; 60 | height:11px; 61 | background-color: gray; 62 | margin-right: 20px; 63 | border-radius: 5.5px; 64 | border:none; 65 | } 66 | .circle:active,.circle:hover,.on{ 67 | background-color:$title_color; 68 | } 69 | } 70 | &_container{ 71 | display: flex; 72 | flex-direction: column; 73 | width: 100%; 74 | height: 100%; 75 | position: absolute; 76 | &_top{ 77 | flex: 1; 78 | display: flex; 79 | &_img{ 80 | flex: 1; 81 | text-align: center; 82 | box-shadow: $shadow_card_1,$shadow_card_1; 83 | &_img{ 84 | height: 100%; 85 | width: 100%; 86 | } 87 | } 88 | &_chartContainertop{ 89 | flex: 0 0 310px; 90 | height: 100%; 91 | display: flex; 92 | flex-direction: column; 93 | &_chart{ 94 | width: 310px; 95 | height: 50%; 96 | box-shadow: $shadow_card_1,$shadow_card_1; 97 | } 98 | } 99 | } 100 | &_bottom{ 101 | flex: 0 0 260px; 102 | display: flex; 103 | &_chart{ 104 | flex: 0 0 310px; 105 | width: 310px; 106 | height: 260px; 107 | box-shadow: $shadow_card_1,$shadow_card_1; 108 | } 109 | &_left{ 110 | flex: 1; 111 | display: flex; 112 | &_paper{ 113 | flex: 0 0 450px; 114 | width: 50%; 115 | padding: 5px; 116 | box-shadow: $shadow_card_1,$shadow_card_1; 117 | &_img{ 118 | width: 100%; 119 | height: 100%; 120 | border: 1px solid lightgray; 121 | } 122 | } 123 | &_abstract{ 124 | flex: 1; 125 | padding: 10px; 126 | box-shadow: $shadow_card_1,$shadow_card_1; 127 | } 128 | } 129 | } 130 | 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /src/style/home.scss: -------------------------------------------------------------------------------- 1 | @import 'main_style.scss'; 2 | 3 | .home{ 4 | height: 100%; 5 | width: 100%; 6 | display: flex; 7 | .left-side{ 8 | flex: 0 0 $left-side-width; 9 | padding: $card-margin_padding; 10 | border-right: 1px solid $black_for_shadow; 11 | overflow:auto; 12 | } 13 | .right-side{ 14 | flex: 1; 15 | padding:$card-margin_padding; 16 | overflow-y:auto; 17 | } 18 | } 19 | 20 | 21 | @media screen and (max-width: 800px) { 22 | .left-side{display: none; } 23 | } -------------------------------------------------------------------------------- /src/style/main_style.scss: -------------------------------------------------------------------------------- 1 | $black_for_shadow: rgba(0,0,0,0.1); 2 | $shadow_card:0 1px 1px 0 $black_for_shadow; 3 | $title_color:lightseagreen; 4 | $card-margin_padding: 7px; 5 | $title_height:30px; 6 | $left_sider_container_height:600px; 7 | $left-side-width: 350px; 8 | $hover_color:#f5f5f5; 9 | $grey: rgba(0,0,0,0.5); 10 | 11 | @mixin container($height){ 12 | background-color: white; 13 | box-shadow: $shadow_card,$shadow_card; 14 | width: 100%; 15 | height: $height; 16 | } 17 | 18 | .title{ 19 | height: $title_height; 20 | p{ 21 | color:$title_color; 22 | font-size: 17px; 23 | font-weight: bold; 24 | margin: 5px 10px; 25 | } 26 | } 27 | 28 | .map-container{ 29 | @include container(60%); 30 | min-height: 400px; 31 | } 32 | 33 | // 地图图例 34 | .map_legend { 35 | text-align: left; 36 | color: #555; 37 | background-color: white; 38 | padding: 8px; 39 | border-radius: 5px; 40 | box-shadow:$shadow_card,$shadow_card; 41 | .map_legend_div { width: 18px; height: 12px; opacity: 0.7; display: inline-block;} 42 | .map_legend_font{font: 14px Arial, Helvetica, sans-serif;} 43 | } 44 | 45 | .right-container{ 46 | display: flex; 47 | flex-direction:column; 48 | height: 100%; 49 | } 50 | 51 | .right-container-descrip{ 52 | @include container(99%); 53 | display: flex; 54 | flex-direction: column; 55 | height: 100%; 56 | width: 99.5%; 57 | &-info{ 58 | flex: 0 0 320px; 59 | box-shadow: $shadow_card,$shadow_card; 60 | display: flex; 61 | flex-direction: column; 62 | height: 100%; 63 | overflow: scroll; 64 | header{ 65 | flex: 0 0 10px; 66 | p{ 67 | color:$title_color; 68 | font-size: 17px; 69 | font-weight: bold; 70 | margin: 2px 10px; 71 | } 72 | } 73 | &_detail{ 74 | padding: 0 $card-margin_padding + 4px; 75 | flex: 1; 76 | p{ 77 | margin-top: 5px; 78 | margin-bottom: 10px; 79 | line-height: 20px; 80 | } 81 | .title{ 82 | width: 110px; 83 | font-weight: bold; 84 | } 85 | .content{ 86 | width: 60%; 87 | } 88 | } 89 | } 90 | &-extent{ 91 | margin-top: $card-margin_padding; 92 | flex: 1; 93 | box-shadow: $shadow_card,$shadow_card; 94 | display: flex; 95 | flex-direction: column; 96 | height: 100%; 97 | header{ 98 | flex: 0 0 10px; 99 | p{ 100 | color:$title_color; 101 | font-size: 17px; 102 | font-weight: bold; 103 | margin: 2px 10px; 104 | } 105 | } 106 | &_map{ 107 | padding: 0 $card-margin_padding + 4px; 108 | flex: 1; 109 | display: flex; 110 | flex-direction: column; 111 | span{ 112 | font-weight: bold; 113 | } 114 | p{ 115 | width: 70px; 116 | padding:1px; 117 | height: 20px; 118 | margin: 0 auto; 119 | border: 1px solid lightgray; 120 | } 121 | &_top,&_bot{ 122 | flex: 0 0 50px; 123 | text-align: center; 124 | } 125 | &_mid{ 126 | flex:1; 127 | display: flex; 128 | .left-cor,.right-cor{ 129 | flex: 0 0 100px; 130 | text-align: center; 131 | padding-top: 10%; 132 | } 133 | #extent-map{ 134 | flex: 1; 135 | height: 100%; 136 | } 137 | } 138 | } 139 | } 140 | } 141 | 142 | .cover{ 143 | position: absolute; 144 | width: 100%; 145 | height: 100%; 146 | background-color: rgba(0,0,0,0.4); 147 | z-index:1000; 148 | img{ 149 | position: absolute; 150 | top: 20px; 151 | right:20px; 152 | } 153 | } -------------------------------------------------------------------------------- /src/style/parDefiner.scss: -------------------------------------------------------------------------------- 1 | @import 'main_style.scss'; 2 | 3 | .par-container{ 4 | @include container($left_sider_container_height); 5 | margin-top: $card-margin_padding; 6 | display: flex; 7 | flex-direction: column; 8 | .par-list{ 9 | margin-left:10px; 10 | .par-title{ 11 | display:inline-block; 12 | width:80px; 13 | text-align:left; 14 | } 15 | input{ 16 | width: $left-side-width - 110; 17 | } 18 | select{ 19 | width: 20px; 20 | margin-left: -26px; 21 | border: none; 22 | outline: none; 23 | background-color: rgba(255,255,255,0); 24 | } 25 | p{ 26 | line-height: 10px; 27 | color:$grey; 28 | font-size:14px; 29 | } 30 | .submit{ 31 | width: 100px; 32 | height: 30px; 33 | float: right; 34 | margin-right: 5%; 35 | margin-top: -18px; 36 | display: inline-block; 37 | border-radius: 4px; 38 | background-color: rgba(0,139,139,0.8); 39 | border: none; 40 | color: #FFFFFF; 41 | cursor: pointer; 42 | } 43 | .submit span { 44 | cursor: pointer; 45 | display: inline-block; 46 | position: relative; 47 | transition: 0.5s; 48 | } 49 | } 50 | 51 | .GWRtab{ 52 | text-align: center; 53 | button{ 54 | color: lightseagreen; 55 | font-size: 15px; 56 | font-weight: bold; 57 | background-color: white; 58 | border: none; 59 | font-size: 16px; 60 | width: 150px; 61 | margin-top:5px; 62 | margin-bottom:5px; 63 | outline:none; 64 | cursor: pointer; 65 | } 66 | .active{ 67 | border:2px solid dodgerblue; 68 | } 69 | } 70 | 71 | } 72 | 73 | .btn-animation{ 74 | animation: btnAnimation 5s linear; 75 | } 76 | @keyframes btnAnimation{ 77 | from{ 78 | width: 0px; 79 | } 80 | to{ 81 | width: 100px; 82 | } 83 | } -------------------------------------------------------------------------------- /src/style/rightSideForResult.scss: -------------------------------------------------------------------------------- 1 | @import 'main_style.scss'; 2 | .result-canel{ 3 | height: 100%; 4 | width: 100%; 5 | display: flex; 6 | .content{ 7 | box-shadow: $shadow_card,$shadow_card; 8 | flex:1; 9 | } 10 | .tab{ 11 | flex: 0 0 40px; 12 | text-align: center; 13 | .last-btn{ 14 | box-shadow: $shadow_card,$shadow_card; 15 | background-color: white; 16 | border: none; 17 | font-size: 16px; 18 | height: 150px; 19 | } 20 | button{ 21 | @extend .last-btn; 22 | border-bottom: 1px dashed rgba(0,0,0,0.5); 23 | outline:none; 24 | } 25 | } 26 | } 27 | 28 | @mixin chartBar($width,$height){ 29 | width: $width; 30 | height: $height; 31 | margin-bottom: $card-margin_padding; 32 | box-shadow: $shadow_card,$shadow_card; 33 | } 34 | .chartAnalysis{ 35 | width: 100%; 36 | height: 100%; 37 | min-width: 934px; 38 | overflow-y: scroll; 39 | &_map{ 40 | height: 400px; 41 | width: 99.5%; 42 | } 43 | td{ 44 | min-width: 310px; 45 | height:233px; 46 | box-shadow: $shadow_card,$shadow_card; 47 | padding-right: 0px; 48 | .add-chart-container{ 49 | width: 100%; 50 | height: 100%; 51 | text-align: center; 52 | line-height: 233px; 53 | vertical-align: middle; 54 | color: lightgray; 55 | font-size: 200px; 56 | font-weight: bold; 57 | } 58 | .chart{ 59 | width:310px; 60 | height: 248px; 61 | padding-right: 0px; 62 | } 63 | .chart-par-setting{ 64 | width: 100%; 65 | height: 100%; 66 | margin-left: $card-margin_padding*2; 67 | p{ 68 | color:$title_color; 69 | } 70 | a{ 71 | display: inline-block; 72 | width: 75px; 73 | } 74 | input{ 75 | width: 180px; 76 | margin-left: $card-margin_padding -4px; 77 | } 78 | select{ 79 | border: 0.5px solid lightgray; 80 | outline: none; 81 | background-color: rgba(0,0,0,0); 82 | width: 188px; 83 | } 84 | img{ 85 | width: 10px; 86 | height: 10px; 87 | z-index: 3; 88 | } 89 | button{ 90 | width: 100px; 91 | height: 30px; 92 | display: inline-block; 93 | border-radius: 4px; 94 | background-color: $title_color; 95 | border: none; 96 | color: #FFFFFF; 97 | cursor: pointer; 98 | margin-top: $card-margin_padding*5; 99 | margin-left: 35%; 100 | } 101 | } 102 | } 103 | } 104 | 105 | #code{ 106 | padding: $card-margin_padding; 107 | color:black; 108 | font-family:"Consolas","Monaco","Bitstream Vera Sans Mono","Courier New","sans-serif"; 109 | font-size:13px; 110 | line-height: 20px; 111 | .keyword{color:#7f0055;font-weight:bold} 112 | .placeholder{margin-left:15px} 113 | .comments{color:#3f7f5f} 114 | .value{color:orange;} 115 | .error{color:red;} 116 | } 117 | 118 | .precision_container{ 119 | width: 100%; 120 | height: 100%; 121 | &_chart{ 122 | @include chartBar(99%,60%); 123 | } 124 | &_description{ 125 | margin-top: $card-margin_padding*2; 126 | @include chartBar(99%, 36%); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GTWR/gtwr_vue/7df2732d759510ce9f94aaf9e5a46d646f653395/static/.gitkeep -------------------------------------------------------------------------------- /static/dataTreeNodeName.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataName":"house price", 3 | "properties": [ 4 | {"name":"Price"}, 5 | {"name":"constant"}, 6 | {"name":"Living"}, 7 | {"name":"quality"}, 8 | {"name":"structure"}, 9 | {"name":"renovation"}, 10 | {"name":"condiction"}, 11 | {"name":"greenspace"}, 12 | {"name":"Traffic"}, 13 | {"name":"VIEW"} 14 | ] 15 | } -------------------------------------------------------------------------------- /test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // The assertion name is the filename. 3 | // Example usage: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // For more information on custom assertions see: 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | 10 | exports.assertion = function (selector, count) { 11 | this.message = 'Testing if element <' + selector + '> has count: ' + count 12 | this.expected = count 13 | this.pass = function (val) { 14 | return val === this.expected 15 | } 16 | this.value = function (res) { 17 | return res.value 18 | } 19 | this.command = function (cb) { 20 | var self = this 21 | return this.api.execute(function (selector) { 22 | return document.querySelectorAll(selector).length 23 | }, [selector], function (res) { 24 | cb.call(self, res) 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/gettingstarted#settings-file 5 | module.exports = { 6 | src_folders: ['test/e2e/specs'], 7 | output_folder: 'test/e2e/reports', 8 | custom_assertions_path: ['test/e2e/custom-assertions'], 9 | 10 | selenium: { 11 | start_process: true, 12 | server_path: require('selenium-server').path, 13 | host: '127.0.0.1', 14 | port: 4444, 15 | cli_args: { 16 | 'webdriver.chrome.driver': require('chromedriver').path 17 | } 18 | }, 19 | 20 | test_settings: { 21 | default: { 22 | selenium_port: 4444, 23 | selenium_host: 'localhost', 24 | silent: true, 25 | globals: { 26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | chrome: { 31 | desiredCapabilities: { 32 | browserName: 'chrome', 33 | javascriptEnabled: true, 34 | acceptSslCerts: true 35 | } 36 | }, 37 | 38 | firefox: { 39 | desiredCapabilities: { 40 | browserName: 'firefox', 41 | javascriptEnabled: true, 42 | acceptSslCerts: true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing' 3 | 4 | const webpack = require('webpack') 5 | const DevServer = require('webpack-dev-server') 6 | 7 | const webpackConfig = require('../../build/webpack.prod.conf') 8 | const devConfigPromise = require('../../build/webpack.dev.conf') 9 | 10 | let server 11 | 12 | devConfigPromise.then(devConfig => { 13 | const devServerOptions = devConfig.devServer 14 | const compiler = webpack(webpackConfig) 15 | server = new DevServer(compiler, devServerOptions) 16 | const port = devServerOptions.port 17 | const host = devServerOptions.host 18 | return server.listen(port, host) 19 | }) 20 | .then(() => { 21 | // 2. run the nightwatch test suite against it 22 | // to run in additional browsers: 23 | // 1. add an entry in test/e2e/nightwatch.conf.js under "test_settings" 24 | // 2. add it to the --env flag below 25 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 26 | // For more information on Nightwatch's config file, see 27 | // http://nightwatchjs.org/guide#settings-file 28 | let opts = process.argv.slice(2) 29 | if (opts.indexOf('--config') === -1) { 30 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) 31 | } 32 | if (opts.indexOf('--env') === -1) { 33 | opts = opts.concat(['--env', 'chrome']) 34 | } 35 | 36 | const spawn = require('cross-spawn') 37 | const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) 38 | 39 | runner.on('exit', function (code) { 40 | server.close() 41 | process.exit(code) 42 | }) 43 | 44 | runner.on('error', function (err) { 45 | server.close() 46 | throw err 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function (browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true 4 | }, 5 | "globals": { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/unit/jest.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | rootDir: path.resolve(__dirname, '../../'), 5 | moduleFileExtensions: [ 6 | 'js', 7 | 'json', 8 | 'vue' 9 | ], 10 | moduleNameMapper: { 11 | '^@/(.*)$': '/src/$1' 12 | }, 13 | transform: { 14 | '^.+\\.js$': '/node_modules/babel-jest', 15 | '.*\\.(vue)$': '/node_modules/vue-jest' 16 | }, 17 | testPathIgnorePatterns: [ 18 | '/test/e2e' 19 | ], 20 | snapshotSerializers: ['/node_modules/jest-serializer-vue'], 21 | setupFiles: ['/test/unit/setup'], 22 | mapCoverage: true, 23 | coverageDirectory: '/test/unit/coverage', 24 | collectCoverageFrom: [ 25 | 'src/**/*.{js,vue}', 26 | '!src/main.js', 27 | '!src/router/index.js', 28 | '!**/node_modules/**' 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /test/unit/setup.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | Vue.config.productionTip = false 4 | -------------------------------------------------------------------------------- /test/unit/specs/HelloWorld.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import HelloWorld from '@/components/HelloWorld' 3 | 4 | describe('HelloWorld.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(HelloWorld) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .toEqual('Welcome to Your Vue.js App') 10 | }) 11 | }) 12 | --------------------------------------------------------------------------------