Commit ac114344 by huangqy

库内作业总监控大屏初始化

parents
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.
## 一、项目描述
- [**React 版本请点击这里查看,全新界面超级好看!!!(o ゚ v ゚)ノ**](https://gitee.com/MTrun/react-big-screen)
- 一个基于 vue、datav、Echart 框架的 " **数据大屏项目** ",通过 vue 组件实现数据动态刷新渲染,内部图表可实现自由替换。部分图表使用 DataV 自带组件,可进行更改,详情请点击下方 DataV 文档。
- 项目需要全屏展示(按 F11)。
- 项目部分区域使用了全局注册方式,增加了打包体积,在实际运用中请使用**按需引入**
- 拉取项目之后,建议按照自己的功能区域重命名文件,现以简单的位置进行区分。
- 项目环境:vue-cli-3.0、webpack-4.0、npm-6.13、node-v12.16。
- 请拉取 master 分支的代码,其余是开发分支。
友情链接:
1. [DataV 官方文档(建议使用之前先浏览)](http://datav.jiaminghi.com/guide/)
2. [echarts 实例](https://www.echartsjs.com/examples/zh/index.html)[echarts 官方文档](https://www.echartsjs.com/zh/option.html#title)
3. [Vue 官方文档](https://cn.vuejs.org/v2/guide/instance.html)
4. [项目 gitee 地址(国内速度快)](https://gitee.com/MTrun/big-screen-vue-datav)
项目展示
![项目展示](https://images.gitee.com/uploads/images/2020/0411/221307_0f8af2e7_4964818.gif '20200411_221020.gif')
## 二、主要文件介绍
| 文件 | 作用/功能 |
| ------------------- | --------------------------------------------------- |
| main.js | 主目录文件,引入Echart/DataV等文件 |
| utils | 工具函数与 mixins 函数等 |
| views/ index.vue | 项目主结构 |
| views/其余文件 | 界面各个区域组件(按照位置来命名)ajax 接口请求位置 |
| assets | 静态资源目录,放置 logo 与背景图片 |
| assets / style.scss | 通用 CSS 文件,全局项目快捷样式调节 |
| assets / index.scss | Index 界面的 CSS 文件 |
| components/echart | 所有 echart 图表(按照位置来命名) |
| common/flexible.js | flexible 插件代码(适配屏幕尺寸,定制化修改) |
## 三、使用介绍
1. **如何启动项目**
需要提前安装好`nodejs``npm`,下载项目后在项目主目录下运行`npm/cnpm install`拉取依赖包,然后使用 `vue-cli` 或者直接使用命令`npm run serve`,就可以启动项目,启动项目后需要手动全屏(按 F11)。
2. **如何请求数据**
现在的项目未使用前后端数据请求,建议使用 axios 进行数据请求,在 main.js 位置进行全局配置,在 views/xx.vue 文件里进行前后端数据请求。
- axios 的 main.js 配置参考范例(因人而异)
```js
import axios from 'axios';
//把方法放到vue的原型上,这样就可以全局使用了
Vue.prototype.$http = axios.create({
//设置20秒超时时间
timeout: 20000,
baseURL: 'http://172.0.0.1:80080', //这里写后端地址
});
```
- 在 vue 页面中调用 axios 方法并通过 props 传给 echarts 图表子组件
```js
export default {
data() {
ListDataSelf:[]
},
mounted() {
this.fetchList(); //获取数据
},
methods: {
async fetchList(){
const { code,listData }= await this.$http.get("xx/xx/xx"x);
if(code === 200){
this.ListDataSelf= listData;
}
}
}
}
```
3. **如何动态渲染图表**
`components/echart`下的文件,比如`drawPie()`是渲染函数,`echartData`是需要动态渲染的数据,当外界通过`props`传入新数据,我们可以使用`watch()`方法去监听,一但数据变化就调用`this.drawPie()`并触发内部的`.setOption`函数,重新渲染一次图表。
```js
//这里是子组件内部
props: ["listData"],
watch: {
listData(newValue) {
this.echartData= newValue;
this.drawPie();
},
},
methods: {
drawPie() {
.....
'渲染节点名称'.setOption(option);
}
}
```
4. **如何复用图表组件**
因为 Echart 图表是根据`id/class`去获取 Dom 节点并进行渲染的,所以我们只要传入唯一的 id 值与需要的数据就可以进行复用。如中间部分的`任务通过率与任务达标率`组件就是采用复用的方式。
如:在调用处`views/center.vue`里去定义好数据并传入组件(项目里的所有`id`都不能重复!!!)
```js
//组件调用
<span>今日任务通过率</span>
<centerChart :id="rate[0].id" :tips="rate[0].tips" :colorObj="rate[0].colorData" />
<span>今日任务达标率</span>
<centerChart :id="rate[1].id" :tips="rate[1].tips" :colorObj="rate[1].colorData" />
...
import centerChart from "@/components/echart/center/centerChartRate";
data() {
return {
rate: [
{
id: "centerRate1",
tips: 60,
...
},
{
id: "centerRate2",
tips: 40,
colorData: {
...
}
}
]
}
}
```
然后在复用的组件`components/echart/center/centerChartRate`里进行接收并在用到的地方赋值。
5. **如何更换边框**
边框是使用了 DataV 自带的组件,只需要去 views 目录下去寻找对应的位置去查找并替换就可以,具体的种类请去 DavaV 官网查看
如:
```html
<dv-border-box-1></dv-border-box-1>
<dv-border-box-2></dv-border-box-2>
<dv-border-box-3></dv-border-box-3>
```
6. **如何更换图表**
直接进入 `components/echart` 下的文件修改成你要的 echarts 模样,可以去[echarts 官方社区](https://gallery.echartsjs.com/explore.html#sort=rank~timeframe=all~author=all)里面查看案例。
7. **Mixins 注入的问题**
使用 mixins 注入解决了图表重复书写响应式适配的代码,如果要更换(新增)图形,需要将`echarts.init()`函数赋值给`this.chart`,然后 mixins 才会自动帮你注入响应式功能。
8. **屏幕适配问题**
本项目借助了 flexible 插件,通过改变 rem 的值来进行适配,原设计为 1920px。 ,适配区间为:1366px ~ 2560px,本项目有根据实际情况进行源文件的更改,小屏幕(如:宽为 1366px)需要自己舍弃部分动态组件进行适配,如'动态文字变换组件'会影响布局,需要手动换成一般节点,
```js
// flexible文件位置: `common/flexible.js`,修改部分如下
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
// 最小1366px,最大适配2560px
if (width / dpr < 1366) {
width = 1366 * dpr;
} else if (width / dpr > 2560) {
width = 2560 * dpr;
}
// 原项目是1920px我设置成24等份,这样1rem就是80px
var rem = width / 24;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
```
## 四、更新情况
1. 增加了 Echart 组件复用的功能,如:中间任务达标率的两个百分比图使用的是同一个组件。
2. 修复了头部右侧的图案条不对称的问题。
3. 修复屏幕适配问题,更换了所有的尺寸单位,统一使用 rem。
4. 使用 Mixins 注入图表响应式代码。
5. vue-awesome 改成按需引入的方式
## 五、其余
这个项目是个人的作品,难免会有问题和 BUG,如果有问题请进行评论,我也会尽力去更新,自己也在前端学习的路上,欢迎交流,非常感谢!
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "big-screen-vue-datav",
"version": "1.0.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@babel/core": "^7.17.7",
"@babel/preset-env": "^7.16.11",
"@jiaminghi/data-view": "^2.10.0",
"@types/echarts": "^4.4.3",
"core-js": "^3.6.4",
"echarts": "^4.6.0",
"axios": "^0.21.0",
"vue": "^2.6.11",
"vue-awesome": "^4.0.2",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-eslint": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.1.2",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>平面库监控平台</title>
<script>
window._CONFIG = {};
window._CONFIG['domianURL'] = 'http://192.168.3.130:10029';
window._CONFIG['refreshTime'] = 1000 * 60;
window._CONFIG['isLTK'] = true
</script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<router-view />
</div>
</template>
<style lang="scss">
body {
margin: 0;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
import Vue from 'vue'
import { axios } from '@/utils/request'
//post
export function postAction(url,parameter) {
return axios({
url: url,
method:'post' ,
data: parameter
})
}
//post method= {post | put}
export function httpAction(url,parameter,method) {
return axios({
url: url,
method:method ,
data: parameter
})
}
//put
export function putAction(url,parameter) {
return axios({
url: url,
method:'put',
data: parameter
})
}
//get
export function getAction(url,parameter) {
return axios({
url: url,
method: 'get',
params: parameter
})
}
//deleteAction
export function deleteAction(url,parameter) {
return axios({
url: url,
method: 'delete',
params: parameter
})
}
export function getUserList(parameter) {
return axios({
url: api.user,
method: 'get',
params: parameter
})
}
export function getRoleList(parameter) {
return axios({
url: api.role,
method: 'get',
params: parameter
})
}
export function getServiceList(parameter) {
return axios({
url: api.service,
method: 'get',
params: parameter
})
}
export function getPermissions(parameter) {
return axios({
url: api.permissionNoPager,
method: 'get',
params: parameter
})
}
// id == 0 add post
// id != 0 update put
export function saveService(parameter) {
return axios({
url: api.service,
method: parameter.id == 0 ? 'post' : 'put',
data: parameter
})
}
/**
* 下载文件 用于excel导出
* @param url
* @param parameter
* @returns {*}
*/
export function downFile(url,parameter){
return axios({
url: url,
params: parameter,
method:'get' ,
responseType: 'blob'
})
}
/**
* 下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
if (!data || data.size === 0) {
Vue.prototype['$message'].warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
})
}
/**
* 文件上传 用于富文本上传图片
* @param url
* @param parameter
* @returns {*}
*/
export function uploadAction(url,parameter){
return axios({
url: url,
data: parameter,
method:'post' ,
headers: {
'Content-Type': 'multipart/form-data', // 文件上传
},
})
}
/**
* 获取文件服务访问路径
* @param avatar
* @param subStr
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,subStr) {
if(!subStr) subStr = 'http'
try {
if(avatar && avatar.startsWith(subStr)){
return avatar;
}else{
if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
return window._CONFIG['staticDomainURL'] + "/" + avatar;
}
}
}catch(err){
return;
}
}
This image diff could not be displayed because it is too large. You can view the blob instead.
// 颜色
$colors: (
"primary": #db9e3f,
"info-1": #4394e4,
"info": #4b67af,
"white": #ffffff,
"light": #f9f9f9,
"grey-1": #999999,
"grey": #666666,
"dark-1": #5f5f5f,
"dark": #222222,
"black-1": #171823,
"black": #000000,
);
// 字体大小
$base-font-size: 0.2rem;
$font-sizes: (
xxs: 0.1,
//8px
xs: 0.125,
//10px
sm: 0.2875,
//12px
md: 0.1625,
//13px
lg: 0.175,
//14px
xl: 0.2,
//16px
xxl: 0.225,
//18px
xxxl: 0.25 //20px,,,,
);
// 宽高
.w-100 {
width: 100%;
}
.h-100 {
height: 100%;
}
//flex
.d-flex {
display: flex;
}
.flex-column {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
}
$flex-jc: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
);
$flex-ai: (
start: flex-start,
end: flex-end,
center: center,
stretch: stretch,
);
.flex-1 {
flex: 1;
}
//.mt-1 => margin top
//spacing
$spacing-types: (
m: margin,
p: padding,
);
$spacing-directions: (
t: top,
r: right,
b: bottom,
l: left,
);
$spacing-base-size: 0.2rem;
$spacing-sizes: (
0: 0,
1: 0.25,
2: 0.5,
3: 1,
4: 1.5,
5: 3,
);
#index {
color: #d3d6dd;
background-color: #000000;
width: 100%;
height: 100%;
.bg {
padding: 0.2rem 0.2rem 0 0.2rem;
background-image: url("../assets/pageBg.png");
background-size: cover;
background-position: center center;
}
.active-ring-name {
padding: 10px !important;
}
.headerTitle {
font-size: 0.2rem;
color: #fff;
}
.host-body {
.title {
position: relative;
width: 6.25rem;
text-align: center;
background-size: cover;
background-repeat: no-repeat;
.title-text {
font-size: 0.4rem;
position: absolute;
bottom: 12px;
left: 50%;
transform: translate(-50%);
}
.title-bototm {
position: absolute;
bottom: -0.375rem;
left: 50%;
transform: translate(-50%);
}
}
// 平行四边形
.react-left {
cursor: pointer;
font-size: 0.225rem;
width: 3.75rem;
height: 0.625rem;
line-height: 0.625rem;
text-align: center;
transform: skewX(-45deg);
.react-after {
position: absolute;
right: -0.3125rem;
top: 0;
height: 0.625rem;
width: 0.625rem;
background-color: #0f1325;
transform: skewX(45deg);
}
.text {
display: inline-block;
transform: skewX(45deg);
}
}
.react-right {
cursor: pointer;
font-size: 0.225rem;
width: 3.75rem;
height: 0.625rem;
line-height: 0.625rem;
text-align: center;
transform: skewX(45deg);
.react-before {
position: absolute;
left: -0.3125rem;
top: 0;
height: 0.625rem;
width: 0.625rem;
background-color: #0f1325;
transform: skewX(-45deg);
}
.text {
display: inline-block;
transform: skewX(-45deg);
}
}
.body-box {
margin-top: 0.2rem;
display: flex;
flex-direction: column;
//下方区域的布局
.content-box {
display: grid;
grid-template-columns: 5.6fr 14fr;
/* 用于设置列间距 */
grid-column-gap: 4px;
}
// 底部数据
.bototm-box {
margin-top: 0.125rem;
display: grid;
grid-template-columns: 5.6fr 14fr;
grid-column-gap: 4px;
}
}
}
}
@import "./variables";
// 全局样式
* {
margin: 0;
padding: 0;
list-style-type: none;
box-sizing: border-box;
outline: none;
}
html {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
line-height: 1.2em;
background-color: #f1f1f1;
margin: 0;
padding: 0;
}
a {
color: #343440;
text-decoration: none;
}
.clearfix {
&::after {
content: "";
display: table;
height: 0;
line-height: 0;
visibility: hidden;
clear: both;
}
}
//浮动
.float-r {
float: right;
}
//浮动
.float-l {
float: left;
}
// 字体加粗
.fw-b {
font-weight: bold;
}
//文章一行显示,多余省略号显示
.title-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.bg-color-black {
background-color: rgba(19, 25, 47, 0.6);
}
.bg-color-blue {
background-color: #1a5cd7;
}
.colorBlack {
color: #272727 !important;
&:hover {
color: #272727 !important;
}
}
.colorGrass {
color: #33cea0;
&:hover {
color: #33cea0 !important;
}
}
.colorRed {
color: #ff5722;
&:hover {
color: #ff5722 !important;
}
}
.colorText {
color: #d3d6dd !important;
&:hover {
color: #d3d6dd !important;
}
}
.colorBlue {
color: #257dff !important;
&:hover {
color: #257dff !important;
}
}
//颜色
@each $colorkey, $color in $colors {
.text-#{$colorkey} {
color: $color;
}
.bg-#{$colorkey} {
background-color: $color;
}
}
//对齐
@each $var in (left, center, right) {
.text-#{$var} {
text-align: $var !important;
}
}
//flex
@each $key, $value in $flex-jc {
.jc-#{$key} {
justify-content: $value;
}
}
@each $key, $value in $flex-ai {
.ai-#{$key} {
align-items: $value;
}
}
//字体
@each $fontkey, $fontvalue in $font-sizes {
.fs-#{$fontkey} {
font-size: $fontvalue * $base-font-size;
}
}
//.mt-1 => margin top
//spacing
@each $typekey, $type in $spacing-types {
//.m-1
@each $sizekey, $size in $spacing-sizes {
.#{$typekey}-#{$sizekey} {
#{$type}: $size * $spacing-base-size;
}
}
//.mx-1
@each $sizekey, $size in $spacing-sizes {
.#{$typekey}x-#{$sizekey} {
#{$type}-left: $size * $spacing-base-size;
#{$type}-right: $size * $spacing-base-size;
}
.#{$typekey}y-#{$sizekey} {
#{$type}-top: $size * $spacing-base-size;
#{$type}-bottom: $size * $spacing-base-size;
}
}
//.mt-1
@each $directionkey, $direction in $spacing-directions {
@each $sizekey, $size in $spacing-sizes {
.#{$typekey}#{$directionkey}-#{$sizekey} {
#{$type}-#{$direction}: $size * $spacing-base-size;
}
}
}
.#{$typekey} {
#{$type}: 0;
}
}
(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
console.warn("将根据已有的meta标签来设置缩放比例");
var match = metaEl
.getAttribute("content")
// eslint-disable-next-line no-useless-escape
.match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute("content");
if (content) {
// eslint-disable-next-line no-useless-escape
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
// eslint-disable-next-line no-useless-escape
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
// eslint-disable-next-line no-unused-vars
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute("data-dpr", dpr);
if (!metaEl) {
metaEl = doc.createElement("meta");
metaEl.setAttribute("name", "viewport");
metaEl.setAttribute(
"content",
"initial-scale=" +
scale +
", maximum-scale=" +
scale +
", minimum-scale=" +
scale +
", user-scalable=no"
);
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
// 最小1366px,最大适配2560px
if (width / dpr < 1366) {
width = 1366 * dpr;
} else if (width / dpr > 2560) {
width = 2560 * dpr;
}
// 设置成24等份,设计稿时1920px的,这样1rem就是80px
var rem = width / 24;
docEl.style.fontSize = rem + "px";
flexible.rem = win.rem = rem;
}
win.addEventListener(
"resize",
function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
},
false
);
win.addEventListener(
"pageshow",
function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
},
false
);
if (doc.readyState === "complete") {
doc.body.style.fontSize = 12 * dpr + "px";
} else {
doc.addEventListener(
"DOMContentLoaded",
// eslint-disable-next-line no-unused-vars
function(e) {
doc.body.style.fontSize = 12 * dpr + "px";
},
false
);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === "string" && d.match(/rem$/)) {
val += "px";
}
return val;
};
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === "string" && d.match(/px$/)) {
val += "rem";
}
return val;
};
})(window, window["lib"] || (window["lib"] = {}));
<template>
<div>
<div id="bottomLeftChart" style="width:11.25rem;height:6.25rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("bottomLeftChart"));
// ----------------------------------------------------------------
let category = [
"市区",
"万州",
"江北",
"南岸",
"北碚",
"綦南",
"长寿",
"永川",
"璧山",
"江津",
"城口",
"大足",
"垫江",
"丰都",
"奉节",
"合川",
"江津区",
"开州",
"南川",
"彭水",
"黔江",
"石柱",
"铜梁",
"潼南",
"巫山",
"巫溪",
"武隆",
"秀山",
"酉阳",
"云阳",
"忠县",
"川东",
"检修"
];
let lineData = [
18092,
20728,
24045,
28348,
32808,
36097,
39867,
44715,
48444,
50415,
56061,
62677,
59521,
67560,
18092,
20728,
24045,
28348,
32808,
36097,
39867,
44715,
48444,
50415,
36097,
39867,
44715,
48444,
50415,
50061,
32677,
49521,
32808
];
let barData = [
4600,
5000,
5500,
6500,
7500,
8500,
9900,
12500,
14000,
21500,
23200,
24450,
25250,
33300,
4600,
5000,
5500,
6500,
7500,
8500,
9900,
22500,
14000,
21500,
8500,
9900,
12500,
14000,
21500,
23200,
24450,
25250,
7500
];
let rateData = [];
for (let i = 0; i < 33; i++) {
let rate = barData[i] / lineData[i];
rateData[i] = rate.toFixed(2);
}
let option = {
title: {
text: "",
x: "center",
y: 0,
textStyle: {
color: "#B4B4B4",
fontSize: 16,
fontWeight: "normal"
}
},
tooltip: {
trigger: "axis",
backgroundColor: "rgba(255,255,255,0.1)",
axisPointer: {
type: "shadow",
label: {
show: true,
backgroundColor: "#7B7DDC"
}
}
},
legend: {
data: ["已贯通", "计划贯通", "贯通率"],
textStyle: {
color: "#B4B4B4"
},
top: "0%"
},
grid: {
x: "8%",
width: "88%",
y: "4%"
},
xAxis: {
data: category,
axisLine: {
lineStyle: {
color: "#B4B4B4"
}
},
axisTick: {
show: false
}
},
yAxis: [
{
splitLine: { show: false },
axisLine: {
lineStyle: {
color: "#B4B4B4"
}
},
axisLabel: {
formatter: "{value} "
}
},
{
splitLine: { show: false },
axisLine: {
lineStyle: {
color: "#B4B4B4"
}
},
axisLabel: {
formatter: "{value} "
}
}
],
series: [
{
name: "贯通率",
type: "line",
smooth: true,
showAllSymbol: true,
symbol: "emptyCircle",
symbolSize: 8,
yAxisIndex: 1,
itemStyle: {
normal: {
color: "#F02FC2"
}
},
data: rateData
},
{
name: "已贯通",
type: "bar",
barWidth: 10,
itemStyle: {
normal: {
barBorderRadius: 5,
color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#956FD4" },
{ offset: 1, color: "#3EACE5" }
])
}
},
data: barData
},
{
name: "计划贯通",
type: "bar",
barGap: "-100%",
barWidth: 10,
itemStyle: {
normal: {
barBorderRadius: 5,
color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(156,107,211,0.8)" },
{ offset: 0.2, color: "rgba(156,107,211,0.5)" },
{ offset: 1, color: "rgba(156,107,211,0.2)" }
])
}
},
z: -12,
data: lineData
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="bottomLeftLine" style="width: 8rem;height: 3rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
const echarts = require('echarts')
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {},
methods: {
draw(echartData) {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("bottomLeftLine"));
let xAxisData = echartData.map(v => v.monthTime)
let yAxisData1 = echartData.map(v => v.inCount)
let yAxisData2 = echartData.map(v => v.outCount)
const hexToRgba = (hex, opacity) => {
let rgbaColor = ""
let reg = /^#[\da-f]{6}$/i
if (reg.test(hex)) {
rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
"0x" + hex.slice(3, 5)
)},${parseInt("0x" + hex.slice(5, 7))},${opacity})`
}
return rgbaColor
}
let color = [
"#00CED1",
"#0179b6",
"#284527",
"#2a770d",
"#ebe8b1",
"#dde5cb",
]
let option = {
tooltip: {
trigger: "axis",
formatter: function(params) {
let html = ''
params.forEach(v => {
html += `<div style="color: #666;font-size: 14px;line-height: 24px">
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${color[v.componentIndex]};"></span>
${v.name} - ${v.seriesName}
<span style="color:${color[v.componentIndex]};font-weight:700;font-size: 18px">${v.value}</span>
件`
})
return html
},
extraCssText: 'background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;',
axisPointer: {
type: 'shadow',
shadowStyle: {
shadowColor: 'rgba(225,225,225,1)',
shadowBlur: 5
}
}
},
color: color,
legend: {
textStyle: {
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: xAxisData,
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
},
yAxis: {
type: 'value',
splitLine: { show: false },
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
},
series: [
{
name: "入库",
type: "line",
smooth: true,
symbolSize: 8,
zlevel: 3,
lineStyle: {
color: "#00CED1",
shadowBlur: 3,
shadowColor: hexToRgba("#00CED1", 0.9),
shadowOffsetY: 8
},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[{
offset: 0,
color: hexToRgba(color[0], 0.8)
},
{
offset: 1,
color: hexToRgba(color[0], 0.3)
}
],
false
),
shadowColor: hexToRgba(color[0], 0.9),
shadowBlur: 10
},
data: yAxisData1
},
{
name: "出库",
type: "line",
smooth: true,
symbolSize: 8,
zlevel: 3,
lineStyle: {
color: "#0179b6",
shadowBlur: 3,
shadowColor: hexToRgba("#0179b6", 0.5),
shadowOffsetY: 8
},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[{
offset: 0,
color: hexToRgba(color[1], 0.8)
},
{
offset: 1,
color: hexToRgba(color[1], 0.4)
}
],
false
),
shadowColor: hexToRgba(color[1], 0.1),
shadowBlur: 10
},
data: yAxisData2
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="bottomRightBar" style="width: 9rem;height: 3rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {},
methods: {
draw(data) {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("bottomRightBar"));
const labelOption = {
show: true,
position: 'insideBottom',
distance: '15',
align: 'left',
verticalAlign: 'middle',
rotate: '90',
fontSize: 14,
rich: {
name: {}
}
};
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
color: [ '#54cce2', '#1fd7fd', '#8aa4fa', '#93fd8b'],
legend: {
data: ['Forest', 'Steppe', 'Desert', 'Wetland'],
textStyle: {
color: '#fff'
}
},
toolbox: {
show: true,
itemSize: 20,
itemGap: 30,
showTitle: false,
orient: 'vertical',
left: 'right',
top: 'center',
iconStyle :{
color: '#fff'
},
feature: {
magicType: { show: true, type: [ 'bar', 'stack'] },
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
axisTick: { show: false },
data: data.nameList,
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
}
],
yAxis: [{
type: 'value',
splitLine: { show: false },
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
}],
series: [
{
name: '工作垛位',
type: 'bar',
barGap: 0,
label: labelOption,
emphasis: {
focus: 'series'
},
data: data.aisleList[0],
},
{
name: '有货垛位',
type: 'bar',
label: labelOption,
emphasis: {
focus: 'series'
},
data: data.aisleList[1]
},
{
name: '无货垛位',
type: 'bar',
label: labelOption,
emphasis: {
focus: 'series'
},
data: data.aisleList[2]
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="bottomRightChart" style="width:11.25rem;height:6rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mounted() {
this.draw();
this.charTimg();
},
mixins: [echartMixins],
methods: {
charTimg() {
setInterval(() => {
this.draw();
}, 6000);
},
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("bottomRightChart"));
// ----------------------------------------------------------------
// 数据
let dateBase = new Date();
let year = dateBase.getFullYear();
let dottedBase = +dateBase + 1000 * 3600 * 24;
let weekCategory = [];
let radarData = [];
let radarDataAvg = [];
let maxData = 12000;
let weekMaxData = [];
let weekLineData = [];
// 周数据
for (let i = 0; i < 7; i++) {
// 日期
var date = new Date((dottedBase -= 1000 * 3600 * 24));
weekCategory.unshift([date.getMonth() + 1, date.getDate()].join("/"));
// 折线图数据
weekMaxData.push(maxData);
var distance = Math.round(Math.random() * 11000 + 500);
weekLineData.push(distance);
// 雷达图数据
// 我的指标
var averageSpeed = +(Math.random() * 5 + 3).toFixed(3);
var maxSpeed = averageSpeed + +(Math.random() * 3).toFixed(2);
var hour = +(distance / 1000 / averageSpeed).toFixed(1);
var radarDayData = [distance, averageSpeed, maxSpeed, hour];
radarData.unshift(radarDayData);
// 平均指标
var distanceAvg = Math.round(Math.random() * 8000 + 4000);
var averageSpeedAvg = +(Math.random() * 4 + 4).toFixed(3);
var maxSpeedAvg = averageSpeedAvg + +(Math.random() * 2).toFixed(2);
var hourAvg = +(distance / 1000 / averageSpeed).toFixed(1);
var radarDayDataAvg = [
distanceAvg,
averageSpeedAvg,
maxSpeedAvg,
hourAvg
];
radarDataAvg.unshift(radarDayDataAvg);
}
// 颜色设置
let color = {
linearYtoG: {
type: "linear",
x: 0,
y: 0,
x2: 1,
y2: 1,
colorStops: [
{
offset: 0,
color: "#f5b44d"
},
{
offset: 1,
color: "#28f8de"
}
]
},
linearGtoB: {
type: "linear",
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: "#43dfa2"
},
{
offset: 1,
color: "#28f8de"
}
]
},
linearBtoG: {
type: "linear",
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: "#1c98e8"
},
{
offset: 1,
color: "#28f8de"
}
]
},
areaBtoG: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(35,184,210,.2)"
},
{
offset: 1,
color: "rgba(35,184,210,0)"
}
]
}
};
let option = {
title: {
text: "",
textStyle: {
color: "#D3D6DD",
fontSize: 24,
fontWeight: "normal"
},
subtext: year + "/" + weekCategory[6],
subtextStyle: {
color: "#fff",
fontSize: 16
},
top: 50,
left: 80
},
legend: {
top: 120,
left: 80,
orient: "vertical",
itemGap: 15,
itemWidth: 12,
itemHeight: 12,
data: ["平均指标", "我的指标"],
textStyle: {
color: "#fff",
fontSize: 14
}
},
tooltip: {
trigger: "item"
},
radar: {
center: ["68%", "27%"],
radius: "40%",
name: {
color: "#fff"
},
splitNumber: 8,
axisLine: {
lineStyle: {
color: color.linearYtoG,
opacity: 0.6
}
},
splitLine: {
lineStyle: {
color: color.linearYtoG,
opacity: 0.6
}
},
splitArea: {
areaStyle: {
color: "#fff",
opacity: 0.1,
shadowBlur: 25,
shadowColor: "#000",
shadowOffsetX: 0,
shadowOffsetY: 5
}
},
indicator: [
{
name: "服务态度",
max: maxData
},
{
name: "产品质量",
max: 10
},
{
name: "任务效率",
max: 12
},
{
name: "售后保障",
max: 3.5
}
]
},
grid: {
left: 90,
right: 80,
bottom: 40,
top: "60%"
},
xAxis: {
type: "category",
position: "bottom",
axisLine: true,
axisLabel: {
color: "rgba(255,255,255,.8)",
fontSize: 12
},
data: weekCategory
},
// 下方Y轴
yAxis: {
name: "工单",
nameLocation: "end",
nameGap: 24,
nameTextStyle: {
color: "rgba(255,255,255,.5)",
fontSize: 14
},
max: maxData,
splitNumber: 4,
axisLine: {
lineStyle: {
opacity: 0
}
},
splitLine: {
show: true,
lineStyle: {
color: "#fff",
opacity: 0.1
}
},
axisLabel: {
color: "rgba(255,255,255,.8)",
fontSize: 12
}
},
series: [
{
name: "",
type: "radar",
symbolSize: 0,
data: [
{
value: radarDataAvg[6],
name: "平均指标",
itemStyle: {
normal: {
color: "#f8d351"
}
},
lineStyle: {
normal: {
opacity: 0
}
},
areaStyle: {
normal: {
color: "#f8d351",
shadowBlur: 25,
shadowColor: "rgba(248,211,81,.3)",
shadowOffsetX: 0,
shadowOffsetY: -10,
opacity: 1
}
}
},
{
value: radarData[6],
name: "我的指标",
itemStyle: {
normal: {
color: "#43dfa2"
}
},
lineStyle: {
normal: {
opacity: 0
}
},
areaStyle: {
normal: {
color: color.linearGtoB,
shadowBlur: 15,
shadowColor: "rgba(0,0,0,.2)",
shadowOffsetX: 0,
shadowOffsetY: 5,
opacity: 0.8
}
}
}
]
},
{
name: "",
type: "line",
smooth: true,
symbol: "emptyCircle",
symbolSize: 8,
itemStyle: {
normal: {
color: "#fff"
}
},
lineStyle: {
normal: {
color: color.linearBtoG,
width: 3
}
},
areaStyle: {
normal: {
color: color.areaBtoG
}
},
data: weekLineData,
lineSmooth: true,
markLine: {
silent: true,
data: [
{
type: "average",
name: "平均值"
}
],
precision: 0,
label: {
normal: {
formatter: "平均值: \n {c}"
}
},
lineStyle: {
normal: {
color: "rgba(248,211,81,.7)"
}
}
},
tooltip: {
position: "top",
formatter: "{c} m",
backgroundColor: "rgba(28,152,232,.2)",
padding: 6
}
},
{
name: "占位背景",
type: "bar",
itemStyle: {
normal: {
show: true,
color: "#000",
opacity: 0
}
},
silent: true,
barWidth: "50%",
data: weekMaxData,
animation: false
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="centerChartBar" style="width: 10.25rem; height: 2.3rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centerChartBar"));
// ----------------------------------------------------------------
let option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar'
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
#centreRight2Chart1 {
margin: 0 auto;
}
</style>
\ No newline at end of file
<template>
<div>
<div id="centerChartLine" style="width: 5.2rem;height: 3rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
// this.draw();
},
methods: {
draw(data) {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById('centerChartLine'));
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
top: '15%',
left: '8%',
right: '10%',
bottom: '0%',
containLabel: true
},
legend: {
textStyle: {
color: '#fff'
}
},
xAxis: {
type: 'category',
data: data.timeList,
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
},
yAxis: {
type: 'value',
splitLine: { show: false },
axisLabel: {
show: true,
textStyle: {
color: '#fff', //更改坐标轴文字颜色
fontSize : 16 //更改坐标轴文字大小
}
},
axisLine:{
lineStyle: {
color:'#fff' //更改坐标轴颜色
}
}
},
series: [
{
name: '温度',
data: data.tlist,
type: 'line',
itemStyle:{
normal:{
color:'#9FE0B2', //折点颜色
lineStyle:{
color:'#9FE0B2' //折线颜色
}
}
},
markPoint: {
data: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
markLine: {
data: [
{type: 'average', name: '平均值'}
]
}
},
{
name: '湿度',
data: data.hlist,
type: 'line',
itemStyle:{
normal:{
color:'#5470C6', //折点颜色
lineStyle:{
color:'#5470C6' //折线颜色
}
}
},
markPoint: {
data: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
markLine: {
data: [
{type: 'average', name: '平均值'}
]
}
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="centerChartPie" style="width: 3.375rem;height: 3.22rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centerChartPie"));
// ----------------------------------------------------------------
let option = {
tooltip: {
trigger: 'item'
},
legend: {
x: 'center',
y: 'bottom',
textStyle: {
color: '#fff'
}
},
series: [
{
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
],
itemStyle: {
normal: {
color: function(params) {
var colorList = [
'#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293'
];
return colorList[params.dataIndex]
}
}
}
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
#centreRight2Chart1 {
margin: 0 auto;
}
</style>
\ No newline at end of file
<template>
<div>
<div :id="id" style="width:1.5rem;height:1.25rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
props: {
id: {
type: String,
required: true,
default: "chartRate"
},
tips: {
type: Number,
required: true,
default: 50
},
colorObj: {
type: Object,
default: function() {
return {
textStyle: "#3fc0fb",
series: {
color: ["#00bcd44a", "transparent"],
dataColor: {
normal: "#03a9f4",
shadowColor: "#97e2f5"
}
}
};
}
}
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById(this.id));
// ----------------------------------------------------------------
let tips = this.tips;
let option = {
title: [
{
text: tips * 1 + "%",
x: "center",
y: "center",
textStyle: {
color: this.colorObj.textStyle,
fontSize: 16
}
}
],
series: [
{
type: "pie",
radius: ["75%", "80%"],
center: ["50%", "50%"],
hoverAnimation: false,
color: this.colorObj.series.color,
label: {
normal: {
show: false
}
},
data: [
{
value: tips,
itemStyle: {
normal: {
color: this.colorObj.series.dataColor.normal,
shadowBlur: 10,
shadowColor: this.colorObj.series.dataColor.shadowColor
}
}
},
{
value: 100 - tips
}
]
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div :id="id" style="width: 2.4rem;height:1.5rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
props: {
id: {
type: String,
required: true,
default: "chartRate"
},
tips: {
type: Number,
required: true,
default: 50
},
colorObj: {
type: Object,
default: function() {
return {
textStyle: "#3fc0fb",
series: {
color: ["#00bcd44a", "transparent"],
dataColor: {
normal: "#03a9f4",
shadowColor: "#97e2f5"
}
}
};
}
}
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById(this.id));
let option = {
series: [
{
type: 'gauge',
center: ['50%', '60%'],
startAngle: 200,
endAngle: -20,
min: 0,
max: 60,
splitNumber: 12,
itemStyle: {
color: '#FFAB91'
},
progress: {
show: true,
width: 30
},
pointer: {
show: false
},
axisLine: {
lineStyle: {
width: 30
}
},
axisTick: {
distance: -45,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999'
}
},
splitLine: {
distance: -52,
length: 14,
lineStyle: {
width: 3,
color: '#999'
}
},
axisLabel: {
distance: -20,
color: '#999',
fontSize: 20
},
anchor: {
show: false
},
title: {
show: false
},
detail: {
valueAnimation: true,
width: '60%',
lineHeight: 40,
borderRadius: 8,
offsetCenter: [0, '-15%'],
fontSize: 20,
fontWeight: 'bolder',
formatter: '{value} °C',
color: 'auto'
},
data: [
{
value: 20
}
]
},
{
type: 'gauge',
center: ['50%', '60%'],
startAngle: 200,
endAngle: -20,
min: 0,
max: 60,
itemStyle: {
color: '#FD7347'
},
progress: {
show: true,
width: 8
},
pointer: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: {
show: false
},
detail: {
show: false
},
data: [
{
value: 20
}
]
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="centreLeft1Chart" style="width:3.25rem; height: 2.75rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centreLeft1Chart"));
// ----------------------------------------------------------------
this.chart.setOption({
color: [
"#37a2da",
"#32c5e9",
"#9fe6b8",
"#ffdb5c",
"#ff9f7f",
"#fb7293",
"#e7bcf3",
"#8378ea"
],
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
toolbox: {
show: true
},
calculable: true,
legend: {
orient: "horizontal",
icon: "circle",
bottom: 0,
x: "center",
data: ["rose1", "rose2", "rose3", "rose4", "rose5", "rose6"],
textStyle: {
color: "#fff"
}
},
series: [
{
name: "增值电信业务统计表",
type: "pie",
radius: [10, 60],
roseType: "area",
center: ["50%", "40%"],
data: [
{ value: 10, name: "rose1" },
{ value: 5, name: "rose2" },
{ value: 15, name: "rose3" },
{ value: 25, name: "rose4" },
{ value: 20, name: "rose5" },
{ value: 35, name: "rose6" }
]
}
]
});
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="centreLeft2Chart" style="width:4.125rem; height: 4.625rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centreLeft2Chart"));
// ----------------------------------------------------------------
let option = {
angleAxis: {
interval: 1,
type: "category",
data: [
"there1",
"there2",
"there3",
"there4",
"there5",
"there6",
"there7",
"there8",
"there9",
"there10 "
],
z: 10,
axisLine: {
show: true,
lineStyle: {
color: "#00c7ff",
width: 1,
type: "solid"
}
},
axisLabel: {
interval: 0,
show: true,
color: "#00c7ff",
margin: 8,
fontSize: 12
}
},
radiusAxis: {
min: 0,
max: 100,
interval: 20,
axisLine: {
show: true,
lineStyle: {
color: "#00c7ff",
width: 1,
type: "solid"
}
},
axisLabel: {
formatter: "{value} %",
show: false,
padding: [0, 0, 20, 0],
color: "#00c7ff",
fontSize: 16
},
splitLine: {
lineStyle: {
color: "#00c7ff",
width: 1,
type: "solid"
}
}
},
legend: {
show: true,
orient: "vartical",
top: "center",
bottom: "0%",
itemWidth: 16,
itemHeight: 8,
itemGap: 16,
textStyle: {
color: "#A3E2F4",
fontSize: 12,
fontWeight: 0
},
data: ["A"]
},
polar: {},
series: [
{
name: "A",
type: "bar",
radius: ["20%", "100%"],
data: [
{
value: 87,
itemStyle: {
normal: {
color: "#f54d4d"
}
}
},
{
value: 80,
itemStyle: {
normal: {
color: "#f87544"
}
}
},
{
value: 75,
itemStyle: {
normal: {
color: "#ffae00"
}
}
},
{
value: 69,
itemStyle: {
normal: {
color: "#dcff00"
}
}
},
{
value: 63,
itemStyle: {
normal: {
color: "#25d053"
}
}
},
{
value: 54,
itemStyle: {
normal: {
color: "#01fff5"
}
}
},
{
value: 47,
itemStyle: {
normal: {
color: "#007cff"
}
}
},
{
value: 40,
itemStyle: {
normal: {
color: "#4245ff"
}
}
},
{
value: 35,
itemStyle: {
normal: {
color: "#c32eff"
}
}
},
{
value: 33,
itemStyle: {
normal: {
color: "#ff62e8"
}
}
}
],
coordinateSystem: "polar"
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div>
<div id="centreRight2Chart1" style="width:3.25rem; height: 2.60rem;">123</div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centreRight2Chart1"));
// ----------------------------------------------------------------
let dataBJ = [
[94, 69, 114, 2.08, 73, 39, 22],
[99, 73, 110, 2.43, 76, 48, 23],
[31, 12, 30, 0.5, 32, 16, 24],
[42, 27, 43, 1, 53, 22, 25],
[154, 117, 157, 3.05, 92, 58, 26],
[234, 185, 230, 4.09, 123, 69, 27],
[160, 120, 186, 2.77, 91, 50, 28]
];
let dataGZ = [
[84, 94, 140, 2.238, 68, 18, 22],
[93, 77, 104, 1.165, 53, 7, 23],
[99, 130, 227, 3.97, 55, 15, 24],
[146, 84, 139, 1.094, 40, 17, 25],
[113, 108, 137, 1.481, 48, 15, 26],
[81, 48, 62, 1.619, 26, 3, 27],
[56, 48, 68, 1.336, 37, 9, 28]
];
let dataSH = [
[91, 45, 125, 0.82, 34, 23, 1],
[65, 27, 78, 0.86, 45, 29, 2],
[83, 60, 84, 1.09, 73, 27, 3],
[109, 81, 121, 1.28, 68, 51, 4],
[106, 77, 114, 1.07, 55, 51, 5],
[109, 81, 121, 1.28, 68, 51, 6],
[106, 77, 114, 1.07, 55, 51, 7]
];
let lineStyle = {
normal: {
width: 1,
opacity: 0.5
}
};
let option = {
radar: {
indicator: [
{ name: "AQI", max: 300 },
{ name: "PM2.5", max: 250 },
{ name: "PM10", max: 300 },
{ name: "CO", max: 5 },
{ name: "NO2", max: 200 },
{ name: "SO2", max: 100 }
],
shape: "circle",
splitNumber: 5,
name: {
textStyle: {
color: "rgb(238, 197, 102)"
}
},
splitLine: {
lineStyle: {
color: [
"rgba(238, 197, 102, 0.1)",
"rgba(238, 197, 102, 0.2)",
"rgba(238, 197, 102, 0.4)",
"rgba(238, 197, 102, 0.6)",
"rgba(238, 197, 102, 0.8)",
"rgba(238, 197, 102, 1)"
].reverse()
}
},
splitArea: {
show: false
},
axisLine: {
lineStyle: {
color: "rgba(238, 197, 102, 0.5)"
}
}
},
series: [
{
name: "北京",
type: "radar",
lineStyle: lineStyle,
data: dataBJ,
symbol: "none",
itemStyle: {
normal: {
color: "#F9713C"
}
},
areaStyle: {
normal: {
opacity: 0.1
}
}
},
{
name: "上海",
type: "radar",
lineStyle: lineStyle,
data: dataSH,
symbol: "none",
itemStyle: {
normal: {
color: "#B3E4A1"
}
},
areaStyle: {
normal: {
opacity: 0.05
}
}
},
{
name: "广州",
type: "radar",
lineStyle: lineStyle,
data: dataGZ,
symbol: "none",
itemStyle: {
normal: {
color: "rgb(238, 197, 102)"
}
},
areaStyle: {
normal: {
opacity: 0.05
}
}
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
#centreRight2Chart1 {
margin: 0 auto;
}
</style>
\ No newline at end of file
<template>
<div>
<div id="centreRight2Chart2" style="width:3.25rem; height: 3.7rem;"></div>
</div>
</template>
<script>
import echartMixins from "@/utils/resizeMixins";
export default {
data() {
return {
chart: null
};
},
mixins: [echartMixins],
mounted() {
this.draw();
},
methods: {
draw() {
// 基于准备好的dom,初始化echarts实例
this.chart = this.$echarts.init(document.getElementById("centreRight2Chart2"));
// ----------------------------------------------------------------
let lineStyle = {
normal: {
width: 1,
opacity: 0.5
}
};
let option = {
color: ['#62DBE8'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
padding: [5, 10, 0, 10],
itemGap: 50,
textStyle: { //图例文字的样式
color: '#fff',
fontSize: 8
}
},
grid: {
top: '6%',
left: '4%',
right: '16%',
bottom: '3%',
containLabel: true
},
xAxis: {
show: false // 不显示横坐标
},
yAxis: {
type: 'category',
data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],
offset: 15,
boundaryGap: ['20%', '20%'],
axisLabel: {
show: true,
textStyle: {
color: '#fff',
fontSize: '10',
fontWeight: 'bold'
}
}
},
series: [
{
type: 'bar',
data: [19325, 23438, 31000, 121594, 134141, 68180],
barWidth: 16, //柱子宽度
barGap: 0, //柱子之间间距
itemStyle: {
normal: {
label: {
formatter: "{c}"+"件",
show: true,
position: [140, 0],
textStyle: {
fontWeight: "bold",
fontSize: "10",
color: "#fff"
}
},
opacity: 1
}
}
}
]
};
this.chart.setOption(option);
}
},
destroyed() {
window.onresize = null;
}
};
</script>
<style lang="scss" scoped>
#centreRight2Chart2 {
margin: 0 auto;
}
</style>
\ No newline at end of file
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import dataV from '@jiaminghi/data-view';
Vue.use(dataV);
// 按需引入vue-awesome图标
import Icon from 'vue-awesome/components/Icon';
import 'vue-awesome/icons/chart-bar.js';
import 'vue-awesome/icons/chart-area.js';
import 'vue-awesome/icons/chart-pie.js';
import 'vue-awesome/icons/chart-line.js';
import 'vue-awesome/icons/align-left.js';
// 全局注册图标
Vue.component('icon', Icon);
// 适配flex
import '@/common/flexible.js';
// 引入全局css
import './assets/scss/style.scss';
//引入echart
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [{
path: '/',
name: 'index',
component: () => import('../views/index.vue')
}]
const router = new VueRouter({
mode: "history",
routes
})
export default router
\ No newline at end of file
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
const VueAxios = {
vm: {},
// eslint-disable-next-line no-unused-vars
install(Vue, router = {}, instance) {
if (this.installed) {
return;
}
this.installed = true;
if (!instance) {
// eslint-disable-next-line no-console
console.error('You have to install axios');
return;
}
Vue.axios = instance;
Object.defineProperties(Vue.prototype, {
axios: {
get: function get() {
return instance;
}
},
$http: {
get: function get() {
return instance;
}
}
});
}
};
export {
VueAxios,
// eslint-disable-next-line no-undef
//instance as axios
}
\ No newline at end of file
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result;
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp;
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function(...args) {
context = this;
timestamp = +new Date();
const callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
}
/**
* @param {date} time 需要转换的时间
* @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
*/
export function formatTime(time, fmt) {
if (!time) return ''
else {
const date = new Date(time)
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'H+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
'S': date.getMilliseconds()
}
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : ((
'00' + o[k]).substr(('' + o[k]).length)))
}
}
return fmt
}
}
import axios from 'axios'
import { VueAxios } from './axios'
let apiBaseUrl = window._CONFIG['domianURL'] || '/'
// 创建 axios 实例
const request = axios.create({
// API 请求的默认前缀
baseURL: apiBaseUrl,
timeout: 3000 // 请求超时时间
})
axios.interceptors.request.use((request) => {
return request
})
request.interceptors.response.use((response) => {
return response.data
})
const installer = {
vm: {},
install (Vue) {
Vue.use(VueAxios, request)
}
}
export default request
export {
installer as VueAxios,
request as axios
}
// 混入代码 resize-mixins.js
import { debounce } from '@/utils/index';
const resizeChartMethod = '$__resizeChartMethod';
export default {
data() {
// 在组件内部将图表init的引用映射到chart属性上
return {
chart: null,
};
},
created() {
window.addEventListener('resize', this[resizeChartMethod], false);
},
beforeDestroy() {
window.removeEventListener('reisze', this[resizeChartMethod]);
},
methods: {
// 通过lodash的防抖函数来控制resize的频率
[resizeChartMethod]: debounce(function() {
if (this.chart) {
this.chart.resize();
}
}, 100),
},
};
<template>
<div class="bottom-charts">
<div class="bc-chart-item">
<div class="bcci-header">巷道1</div>
<dv-active-ring-chart :config="config1" />
</div>
<dv-decoration-2 class="decoration-1" :reverse="true" style="width:5px;" />
<div class="bc-chart-item">
<div class="bcci-header">巷道2</div>
<dv-active-ring-chart :config="config2" />
</div>
<dv-decoration-2 class="decoration-2" :reverse="true" style="width:5px;" />
<div class="bc-chart-item">
<div class="bcci-header">巷道3</div>
<dv-active-ring-chart :config="config3" />
</div>
<dv-decoration-2 class="decoration-3" :reverse="true" style="width:5px;" />
<div class="bc-chart-item">
<div class="bcci-header">巷道4</div>
<dv-active-ring-chart :config="config4" />
</div>
<dv-decoration-2 class="decoration-3" :reverse="true" style="width:5px;" />
<div class="bc-chart-item">
<div class="bcci-header">巷道5</div>
<dv-active-ring-chart :config="config4" />
</div>
<dv-decoration-2 class="decoration-3" :reverse="true" style="width:5px;" />
<div class="bc-chart-item-right">
<Label-Tag :config="labelConfig" />
</div>
</div>
</template>
<script>
import LabelTag from './LabelTag'
export default {
name: 'BottomCharts',
components: {
LabelTag
},
data () {
return {
config1: {
data: [
{
name: '收费站',
value: 356
},
{
name: '监控中心',
value: 215
},
{
name: '道路外场',
value: 90
},
{
name: '其他',
value: 317
}
],
color: ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b'],
radius: '65%',
activeRadius: '70%',
digitalFlopStyle: {
fontSize: 20
}
},
config2: {
data: [
{
name: '收费站',
value: 615
},
{
name: '监控中心',
value: 322
},
{
name: '道路外场',
value: 198
},
{
name: '其他',
value: 80
}
],
color: ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b'],
radius: '65%',
activeRadius: '70%',
digitalFlopStyle: {
fontSize: 20
}
},
config3: {
data: [
{
name: '收费站',
value: 452
},
{
name: '监控中心',
value: 512
},
{
name: '道路外场',
value: 333
},
{
name: '其他',
value: 255
}
],
color: ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b'],
radius: '65%',
activeRadius: '70%',
digitalFlopStyle: {
fontSize: 20
}
},
config4: {
data: [
{
name: '收费站',
value: 156
},
{
name: '监控中心',
value: 415
},
{
name: '道路外场',
value: 90
},
{
name: '其他',
value: 210
}
],
color: ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b'],
radius: '65%',
activeRadius: '70%',
digitalFlopStyle: {
fontSize: 20
}
},
labelConfig: {
data: ['收费站', '监控中心', '道路外场', '其他']
}
}
}
}
</script>
<style lang="less">
.bottom-charts {
width: 100%;
height: 100%;
display: flex;
position: relative;
.bc-chart-item {
width: 20%;
height: 100%;
padding-top: 20px;
box-sizing: border-box;
}
.bc-chart-item-right {
width: 14%;
height: 100%;
padding-top: 30px;
box-sizing: border-box;
}
.bcci-header {
height: 50px;
text-align: center;
line-height: 50px;
font-size: 18px;
}
.dv-active-ring-chart {
height: calc(~"100% - 80px");
}
.label-tag {
height: 24px;
}
.active-ring-name {
font-size: 10px !important;
}
.decoration-1, .decoration-2, .decoration-3 {
display: absolute;
left: 0%;
}
}
</style>
<template>
<div class="bottom-charts">
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-bar"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">近一月收发物资统计</span>
</div>
</div>
<div class="bottom-charts-left">
<bottomLeftLine ref="bll"/>
</div>
</div>
<dv-decoration-2 style="height: 3rem;width: 5px;" :reverse="true"/>
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-bar"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">区域垛位状态统计</span>
</div>
</div>
<div class="bottom-charts-right">
<bottomRightBar ref="brb" />
</div>
</div>
</div>
</template>
<script>
import bottomLeftLine from '@/components/echart/bottom/bottomLeftLine'
import bottomRightBar from '@/components/echart/bottom/bottomRightBar'
import { getAction } from '@/api/manage'
export default {
name: 'BottomCharts',
components: {
bottomLeftLine,
bottomRightBar
},
data () {
return {
url: '/firstDynamic/searchStoreByToday',
getGoodsByArea: '/big/getGoodsByArea'
}
},
mounted() {
this.getData()
setInterval(() => {
this.getData()
}, window._CONFIG['refreshTime'])
},
methods: {
getData() {
getAction(window._CONFIG['domianURL'] + this.url, {storeCode: this.$route.query.storeCode, datetime: new Date().getFullYear() + '-' + (new Date().getMonth() + 1).toString().padStart(2, '0') }).then(res => {
this.$refs.bll.draw(res.data)
})
getAction(window._CONFIG['domianURL'] + this.getGoodsByArea, {storeCode: this.$route.query.storeCode}).then(res => {
this.$refs.brb.draw(res.data)
})
}
}
}
</script>
<style lang="less">
.bottom-charts {
width: 100%;
height: 100%;
display: flex;
// flex-direction: column;
position: relative;
.bottom-charts-left .bottom-charts-right {
width: 50%;
}
}
</style>
<template>
<div class="label-tag">
<template v-if="mergedConfig">
<div class="label-item" v-for="(label, i) in mergedConfig.data" :key="label">
<div :style="`background-color: ${mergedConfig.colors[i % mergedConfig.colors.length]};`" />
<span>{{ label }}</span>
</div>
</template>
</div>
</template>
<script>
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
export default {
name: 'LabelTag',
props: {
config: {
type: Object,
default: () => ([])
}
},
data () {
return {
defaultConfig: {
/**
* @description Label data
* @type {Array<String>}
* @default data = []
* @example data = ['label1', 'label2']
*/
data: [],
/**
* @description Label color (Hex|Rgb|Rgba|color keywords)
* @type {Array<String>}
* @default colors = ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b']
* @example colors = ['#666', 'rgb(0, 0, 0)', 'rgba(0, 0, 0, 1)', 'red']
*/
colors: ['#00baff', '#3de7c9', '#fff', '#ffc530', '#469f4b']
},
mergedConfig: null
}
},
watch: {
config () {
const { mergeConfig } = this
mergeConfig()
}
},
methods: {
mergeConfig () {
let { config, defaultConfig } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
}
},
mounted () {
const { mergeConfig } = this
mergeConfig()
}
}
</script>
<style lang="less">
.label-tag {
display: flex;
flex-direction: column;
align-items: center;
.label-item {
padding: 15px;
font-size: 15px;
div {
width: 12px;
height: 12px;
margin-left: 5px;
float: left;
}
}
}
</style>
<template>
<div id="bottomLeft">
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-bar"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">发物计划列表</span>
</div>
</div>
<dv-scroll-board :config="config" style="width: 5.1rem;height: 4.44rem;margin-top: 10px;" />
</div>
</div>
</template>
<script>
import { postAction } from '@/api/manage'
export default {
data() {
return {
url: '/bill/query',
config: {}
};
},
mounted() {
this.getOutPage()
setInterval(() => {
this.getOutPage()
}, window._CONFIG['refreshTime'])
},
methods: {
getOutPage() {
postAction(window._CONFIG['domianURL'] + this.url, { pageNo: 1, pageSize: 20, condition: {
storeCode: this.$route.query.storeCode,
type: 'OUT'
}}).then(res => {
let arr = []
res.data.records.forEach(element => {
var itemArr = []
itemArr.push(element.name)
itemArr.push(element.deptName)
itemArr.push(element.storeName)
itemArr.push(element.amount)
if (element.state === 'T') {
itemArr.push("<span class='colorRed'>" + "待执行" + "</span>")
}
if (element.state === 'W') {
itemArr.push("<span class='colorRed'>" + "进行中" + "</span>")
}
if (element.state === 'D') {
itemArr.push("<span class='colorGrass'>" + "已完成" + "</span>")
}
arr.push(itemArr)
})
this.config = {
header: ["凭证字", "发物单位", "库房名", "数量", "任务状态"],
data: arr,
rowNum: 7, //表格行数
headerHeight: 35,
headerBGC: "#0C2869", //表头
oddRowBGC: "rgb(15,47,130, 0.5)", //奇数行
evenRowBGC: "rgb(5,19,104, 0.5)", //偶数行
columnWidth: [120, 150,150, 100, 150],
align: ["center"]
}
})
}
}
};
</script>
<style lang="scss">
#bottomLeft {
border-radius: 0.0625rem;
.text {
color: #c3cbde;
}
}
</style>
\ No newline at end of file
<template>
<div id="bottomRight">
<div class="bg-color-black">
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-area"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">工单修复以及满意度统计图</span>
<div class="decoration2">
<dv-decoration-2 :reverse="true" style="width:5px;height:480px;" />
</div>
</div>
</div>
<div>
<bottomRightChart />
</div>
</div>
</div>
</template>
<script>
import bottomRightChart from "@/components/echart/bottom/bottomRightChart";
export default {
data() {
return {};
},
components: {
bottomRightChart
},
mounted() {},
methods: {}
};
</script>
<style lang="scss">
#bottomRight {
padding: 0.2rem 0.2rem 0;
height: 6.5rem;
min-width: 3.75rem;
border-radius: 0.0625rem;
.bg-color-black {
height: 6.1875rem;
border-radius: 0.125rem;
}
.text {
color: #c3cbde;
} //下滑线动态
.decoration2 {
position: absolute;
right: 0.125rem;
}
.chart-box {
margin-top: 0.2rem;
width: 2.125rem;
height: 2.125rem;
.active-ring-name {
padding-top: 0.125rem;
}
}
}
</style>
\ No newline at end of file
<template>
<div id="center">
<div class="up">
<div class="item" style="height: 2.2rem">
<span style="font-size: 0.3875rem;">库存物资总数</span>
<dv-decoration-12 style="width: 2rem;height: 2rem;margin: 0 auto;color: #fff" :color="['#046DB5', '#046DB5']">
<span style="font-size: 0.6rem;color: rgb(61,231,201)">{{ amount }}</span><span style="color: rgb(61,231,201);font-size: 0.56rem;margin-left: 10px;"></span></dv-decoration-12>
</div>
<div class="item" style="height: 1.6rem;margin-top: 0.2rem;">
<span style="font-size: 0.3875rem;display: block;">本年度收发总数</span>
<div style="display: flex;">
<span style="font-size: 0.3875rem;margin-top: 55px;display: block;width: 20%;text-align: center;">收物:</span>
<dv-digital-flop :config="inAmount" style="height:1.625rem;width: 30%" />
<span style="font-size: 0.3875rem;margin-top: 55px;display: block;width: 20%;text-align: center;">发物:</span>
<dv-digital-flop :config="outAmount" style="height:1.625rem;width: 30%" />
</div>
</div>
</div>
<div class="extra">
<div class="item">
<span style="font-size: 0.3rem;">垛位总数</span>
<span style="margin-left: 38px;color: #03a9f4;font-size: 0.32rem;font-weight: 700;">{{ rackAmount }}</span>
</div>
</div>
<div class="down">
<div class="leftNm">
<div class="item">
<span>工作垛位</span>
<span style="margin-left: 55px;font-size: 0.25rem;color: #03a9f4;">{{ workRackAmount }}</span>
</div>
<div class="item">
<span>有货垛位</span>
<span style="margin-left: 55px;font-size: 0.25rem;color: #03a9f4;">{{ usedRackAmount }}</span>
</div>
<div class="item">
<span>无货垛位</span>
<span style="margin-left: 55px;font-size: 0.25rem;color: #03a9f4;">{{ nullRackAmount }}</span>
</div>
</div>
<div class="percent">
<dv-active-ring-chart :config="config" style="width: 3.775rem;height: 3.775rem;margin-left: -20px;margin-top: -45px;" />
</div>
</div>
</div>
</template>
<script>
import centerChart from "@/components/echart/center/centerChartRate";
import centerChartPie from '@/components/echart/center/centerChartPie'
import { getAction } from '@/api/manage'
export default {
data () {
return {
url: '/big/getGoodsByBig',
amount: 0,
inAmount: {},
outAmount: {},
nullPalletAmount: 0,
nullRackAmount: 0,
rackAmount: 0,
usedRackAmount: 0,
workRackAmount: 0,
config: {
},
water: {
data: [24, 45],
shape: "roundRect",
formatter: "{value}%",
waveNum: 3
},
};
},
components: {
centerChart,
centerChartPie
},
mounted() {
this.initData()
setInterval(() => {
this.initData()
}, window._CONFIG['refreshTime'])
},
methods: {
initData() {
getAction(window._CONFIG['domianURL'] + this.url, {storeCode: this.$route.query.storeCode}).then(res => {
this.amount = res.data.stockVo.amount
this.inAmount = {
number: [res.data.stockVo.inAmount],
content: "{nt}件",
style: {
fontSize: 30,
fill: '#3de7c9'
}
}
this.outAmount = {
number: [res.data.stockVo.outAmount],
content: "{nt}件",
style: {
fontSize: 30,
fill: '#3de7c9'
}
}
this.rackAmount = res.data.rackVo.rackAmount
this.nullRackAmount = res.data.rackVo.nullRackAmount
this.usedRackAmount = res.data.rackVo.usedRackAmount
this.workRackAmount = res.data.rackVo.workRackAmount
this.config = {
data: [
{
name: '工作垛位',
value: this.workRackAmount
},
{
name: '有货垛位',
value: this.usedRackAmount
},
{
name: '无货垛位',
value: this.nullRackAmount
}
],
lineWidth: 40,
digitalFlopStyle: {
fontSize: 20
},
showOriginValue: true,
animationFrame: 10,
color: [ '#54cce2', '#1fd7fd', '#8aa4fa', '#93fd8b'],
}
})
}
}
};
</script>
<style lang="scss" scoped>
#center {
display: flex;
flex-direction: column;
margin-top: 40px;
.up {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
.item {
padding-top: 0.2rem;
width: 100%;
}
}
.extra {
width: 100%;
display: flex;
flex-wrap: wrap;
height: 0.6rem;
.item {
width: 100%;
// height: 15%;
span {
// font-size: 0.25rem;
line-height: 0.6rem;
margin-left: 0.14rem;
}
}
}
.down {
width: 100%;
display: flex;
height: 2.6rem;
justify-content: space-between;
.bg-color-black {
border-radius: 0.0625rem;
}
.percent {
width: 55%;
}
}
.leftNm {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
.item {
width: 100%;
height: 20%;
span {
font-size: 0.25rem;
line-height: 0.8rem;
margin-left: 0.14rem;
}
}
}
}
</style>
\ No newline at end of file
<template>
<div id="centreLeft1">
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-line"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">收物计划列表</span>
</div>
</div>
<dv-scroll-board :config="config" style="width: 5.1rem;height: 4.44rem;margin-top: 10px;" />
<dv-decoration-2 style="height:10px;" />
</div>
</div>
</template>
<script>
import { postAction } from '@/api/manage'
export default {
data() {
return {
url: '/bill/query',
config: {}
};
},
mounted() {
this.getInPage()
setInterval(() => {
this.getInPage()
}, window._CONFIG['refreshTime'])
},
methods: {
getInPage() {
postAction(window._CONFIG['domianURL'] + this.url, { pageNo: 1, pageSize: 20, condition: {
storeCode: this.$route.query.storeCode,
type: 'IN'
}}).then(res => {
let arr = []
res.data.records.forEach(element => {
var itemArr = []
itemArr.push(element.name)
itemArr.push(element.deptName)
itemArr.push(element.storeName)
itemArr.push(element.amount)
if (element.state === 'T') {
itemArr.push("<span class='colorRed'>" + "待执行" + "</span>")
}
if (element.state === 'W') {
itemArr.push("<span class='colorRed'>" + "进行中" + "</span>")
}
if (element.state === 'D') {
itemArr.push("<span class='colorGrass'>" + "已完成" + "</span>")
}
arr.push(itemArr)
})
this.config = {
header: ["凭证字", "发物单位", "库房名", "数量", "任务状态"],
data: arr,
rowNum: 7, //表格行数
headerHeight: 35,
headerBGC: "#0C2869", //表头
oddRowBGC: "rgb(15,47,130, 0.5)", //奇数行
evenRowBGC: "rgb(5,19,104, 0.5)", //偶数行
columnWidth: [120, 150,150, 100, 150],
align: ["center"]
}
})
}
}
};
</script>
<style lang="scss">
#centreLeft1 {
border-radius: 0.0625rem;
.bg-color-black {
border-radius: 0.125rem;
}
.text {
color: #c3cbde;
}
}
</style>
\ No newline at end of file
<template>
<div id="centreLeft2">
<div class="percent">
<div class="poItem">
<span v-if="currentData && currentData.length > 0">{{currentData[0].name}}</span>
</div>
<div class="item">
<span>当前温度</span>
<dv-decoration-9 style="width: 1.5rem;height: 1.5rem;margin-left: 35px;" :color="colors1">
<span style="font-size: 0.25rem;color: rgb(61,231,201);font-weight: bold;" v-if="currentData && currentData.length > 0">{{ currentData[0].temperature }}</span>
</dv-decoration-9>
</div>
<div class="item">
<span>当前湿度</span>
<dv-water-level-pond :config="water1" style="width: 1.5rem;height: 1.5rem;margin-left: 30px;" />
</div>
</div>
<div class="percent">
<div class="poItem">
<span v-if="currentData && currentData.length > 0">{{currentData[1].name}}</span>
</div>
<div class="item">
<span>当前温度</span>
<dv-decoration-9 style="width: 1.5rem;height: 1.5rem;margin-left: 35px;" :color="colors2">
<span style="font-size: 0.25rem;color: rgb(61,231,201);font-weight: bold;" v-if="currentData && currentData.length > 0">{{ currentData[1].temperature }}</span>
</dv-decoration-9>
</div>
<div class="item">
<span>当前湿度</span>
<dv-water-level-pond :config="water2" style="width: 1.5rem; height: 1.5rem;margin-left: 30px;" />
</div>
</div>
<centerChartLine ref="ccl" style="margin-top: 10px;"/>
</div>
</template>
<script>
import centerChartLine from "@/components/echart/center/centerChartLine";
import centerChartWd from "@/components/echart/center/centerChartWd";
import { getAction } from '@/api/manage'
export default {
data() {
return {
water1: {},
water2: {},
url: '/big/getHumitureLog',
getHumitureConfig: '/big/getHumitureConfig',
getHumitureNow: '/big/getHumitureNow',
humidityMax: '',
humidityMin: '',
temperatureMax: '',
temperatureMin: '',
currentData: {},
colors1: [],
colors2: [],
device1Name: '',
device2Name: ''
};
},
components: {
centerChartLine,
centerChartWd
},
mounted() {
this.getData()
setInterval(() => {
this.getData()
}, window._CONFIG['refreshTime'])
},
methods: {
getData() {
const _this = this
let params = window._CONFIG['isLTK'] ? {storeCode: this.$route.query.storeCode} : ''
getAction(this.url, params).then(res => {
this.$refs.ccl.draw(res.data)
})
getAction(this.getHumitureConfig, params).then(res => {
_this.humidityMax = res.data.humidityMax
_this.humidityMin = res.data.humidityMin
_this.temperatureMax = res.data.temperatureMax
_this.temperatureMin = res.data.temperatureMin
getAction(this.getHumitureNow, params).then(res => {
this.currentData = res.data
const colors1 = parseFloat(res.data[0].humidity).toFixed(2) > _this.humidityMax ? ['#FFA500', '#FF7F50'] : parseFloat(res.data[0].humidity).toFixed(2) < _this.humidityMin ? ['#F0F8FF','#ADD8E6'] : ['#00BAFF', '#3DE7C9']
const colors2 = parseFloat(res.data[1].humidity).toFixed(2) > _this.humidityMax ? ['#FFA500', '#FF7F50'] : parseFloat(res.data[1].humidity).toFixed(2) < _this.humidityMin ? ['#F0F8FF','#ADD8E6'] : ['#00BAFF', '#3DE7C9']
_this.colors1 = parseFloat(res.data[0].temperature).toFixed(2) > _this.temperatureMax ? ['#FFA500', '#FF7F50'] : parseFloat(res.data[0].temperature).toFixed(2) < _this.temperatureMin ? ['#F0F8FF','#ADD8E6'] : []
_this.colors2 = parseFloat(res.data[1].temperature).toFixed(2) > _this.temperatureMax ? ['#FFA500', '#FF7F50'] : parseFloat(res.data[1].temperature).toFixed(2) < _this.temperatureMin ? ['#F0F8FF','#ADD8E6'] : []
const waveNum1 = parseFloat(res.data[0].humidity).toFixed(2) > _this.humidityMax ? 4 : parseFloat(res.data[0].humidity).toFixed(2) < _this.humidityMin ? 2 : 3
const waveNum2 = parseFloat(res.data[1].humidity).toFixed(2) > _this.humidityMax ? 4 : parseFloat(res.data[1].humidity).toFixed(2) < _this.humidityMin ? 2 : 3
this.water1 = {
data: [parseFloat(res.data[0].humidity).toFixed(2)],
shape: "roundRect",
formatter: "{value}%",
waveNum: waveNum1, // 波浪数量
waveHeight: 20, // 波浪高度
colors: colors1
}
this.water2 = {
data: [parseFloat(res.data[1].humidity).toFixed(2)],
shape: "roundRect",
formatter: "{value}%",
waveNum: waveNum2,
waveHeight: 20,
colors: colors2
}
})
})
}
}
};
</script>
<style lang="scss">
#centreLeft2 {
margin-top: 40px;
width: 100%;
.text {
color: #c3cbde;
}
.percent {
width: 100%;
display: flex;
flex-wrap: wrap;
.poItem {
width: 20%;
height: 1.875rem;
span {
margin-top: 0.0875rem;
display: flex;
font-size: 0.2rem;
line-height: 1.5rem;
justify-content: center;
}
}
.item {
width: 40%;
height: 1.875rem;
.centerRate {
margin-left: 1rem;
}
span {
margin-top: 0.0875rem;
display: flex;
justify-content: center;
}
}
.water {
width: 100%;
}
}
}
</style>
\ No newline at end of file
<template>
<div id="centreRight1">
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="chart-line"></icon>
</span>
<div class="d-flex">
<span class="fs-xl text mx-2 headerTitle">作业队列管理</span>
</div>
</div>
<div class="d-flex jc-center body-box">
<dv-scroll-board :config="config" style="width: 4.6rem;height: 3.2rem"/>
</div>
</div>
<dv-decoration-2 style="height:10px;" />
</div>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
data() {
return {
url: '/big/getWorkPage',
config: {}
};
},
components: {},
mounted() {
this.getWorkPage()
setInterval(() => {
this.getWorkPage()
}, window._CONFIG['refreshTime'])
},
methods: {
getWorkPage() {
getAction(window._CONFIG['domianURL'] + this.url, {storeCode: this.$route.query.storeCode}).then(res => {
let arr = []
res.data.forEach(element => {
var itemArr = []
itemArr.push(element.areaName)
itemArr.push(element.type == 'OUT'? '出库': '入库')
itemArr.push(element.positionName)
// itemArr.push(element.statusName)
arr.push(itemArr)
})
this.config = {
header: ["区域号", "作业类型", "垛位号"],
data: arr,
rowNum: 5, //表格行数
headerHeight: 35,
headerBGC: "#0C2869", //表头
oddRowBGC: "rgb(15,47,130, 0.5)", //奇数行
evenRowBGC: "rgb(5,19,104, 0.5)", //偶数行
index: false,
columnWidth: [100,100,150],
align: ["center"]
}
})
}
}
};
</script>
<style lang="scss">
#centreRight1 {
border-radius: 0.0625rem;
.bg-color-black {
border-radius: 0.125rem;
}
.text {
color: #c3cbde;
}
.body-box {
border-radius: 0.125rem;
overflow: hidden;
}
}
</style>
\ No newline at end of file
<template>
<div id="centreRight2">
<div>
<div class="d-flex pt-2 pl-2">
<span style="color:#5cd9e8">
<icon name="align-left"></icon>
</span>
<span class="fs-xl text mx-2 headerTitle">库内物资排行</span>
</div>
<dv-capsule-chart :config="config" style="width: 4.6rem;height: 3.4rem" />
</div>
</div>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
data() {
return {
url: '/big/getStockByStoreCode',
config: {}
};
},
mounted() {
this.getGoodsStock()
setInterval(() => {
this.getGoodsStock()
}, window._CONFIG['refreshTime'])
},
methods: {
getGoodsStock() {
getAction(window._CONFIG['domianURL'] + this.url, {storeCode: this.$route.query.storeCode}).then(res => {
let data = []
res.data.forEach(item => {
const obj = {
name: item.goodsName,
value: item.amount
}
data.push(obj)
})
this.config = {
data,
unit: '件',
showValue: true
}
})
}
}
};
</script>
<style lang="scss">
#centreRight2 {
border-radius: 0.0625rem;
.bg-color-black {
padding: 0.0625rem;
// height: 5.0625rem;
border-radius: 0.125rem;
}
.text {
color: #c3cbde;
}
.body-box {
border-radius: 0.125rem;
overflow: hidden;
}
}
</style>
\ No newline at end of file
<template>
<div id="index">
<dv-full-screen-container class="bg">
<dv-loading v-if="loading">加载中...</dv-loading>
<div v-else class="host-body">
<div class="d-flex jc-center">
<dv-decoration-10 style="width:33.3%;height:.0425rem;" :color="['#568aea', '#131E88']"/>
<div class="d-flex jc-center">
<dv-decoration-8 :color="['#568aea', '#131E88']" style="width:2.5rem;height:.425rem;" />
<div class="title">
<span class="title-text">平面库监控平台</span>
</div>
<dv-decoration-8
:reverse="true"
:color="['#568aea', '#131E88']"
style="width:2.5rem;height:.425rem;"
/>
</div>
<dv-decoration-10 style="width:33.3%;height:.0625rem; transform: rotateY(180deg);" :color="['#568aea', '#131E88']"/>
</div>
<div class="d-flex jc-center">
<dv-decoration-5 style="width: 500px;height: 30px;margin-bottom: 5px;" :color="['#568aea', '#131E88']"/>
</div>
<dv-border-box-1 class="main-container">
<dv-border-box-10 class="left-chart-container">
<div style="cursor: pointer;font-size: 0.5rem;width: 5.1rem;height: 1.225rem;line-height: 0.645rem; text-align: center;">
<span class="react-before"></span>
<span class="text" style="display: block;">{{dateYear}}</span>
<span class="text" style="display: block;">{{dateDay}}</span>
</div>
<dv-decoration-2 style="height:10px;" />
<centerLeft1 />
<bottomLeft />
</dv-border-box-10>
<div class="right-main-container">
<div class="rmc-top-container">
<dv-border-box-11 title="库内物资">
<center/>
</dv-border-box-11>
<dv-border-box-11 title="库内温湿度">
<centerLeft2/>
</dv-border-box-11>
<div class="rmctc-right-container">
<dv-border-box-10 class="rmctc-chart-1">
<centerRight1 />
<centerRight2 />
</dv-border-box-10>
</div>
</div>
<dv-border-box-10 class="rmc-bottom-container">
<Bottom-Charts />
</dv-border-box-10>
</div>
</dv-border-box-1>
</div>
</dv-full-screen-container>
</div>
</template>
<script>
import { formatTime } from '../utils/index.js'
import centerLeft1 from "./centerLeft1";
import centerLeft2 from "./centerLeft2";
import centerRight1 from "./centerRight1";
import centerRight2 from "./centerRight2";
import center from "./center";
import bottomLeft from "./bottomLeft";
import bottomRight from "./bottomRight";
import BottomCharts from "./BottomCharts"
import centerChartBar from "../components/echart/center/centerChartBar"
export default {
data () {
return {
loading: true,
dateDay: null,
dateYear: null,
dateWeek: null,
weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
};
},
components: {
centerLeft1,
centerLeft2,
centerRight1,
centerRight2,
center,
bottomLeft,
bottomRight,
BottomCharts,
centerChartBar
},
mounted () {
this.timeFn();
this.cancelLoading();
},
methods: {
timeFn () {
setInterval(() => {
this.dateDay = formatTime(new Date(), 'HH: mm: ss');
this.dateYear = formatTime(new Date(), 'yyyy-MM-dd');
this.dateWeek = this.weekday[new Date().getDay()];
}, 1000)
},
cancelLoading () {
setTimeout(() => {
this.loading = false;
}, 500);
}
}
};
</script>
<style lang="scss">
@import '../assets/scss/index.scss';
</style>
<style lang="less">
.main-container {
height: calc(~"100% - 80px");
.border-box-content {
padding: 20px;
box-sizing: border-box;
display: flex;
}
}
.left-chart-container {
width: 24%;
// padding: 10px;
box-sizing: border-box;
.border-box-content {
flex-direction: column;
}
}
.right-main-container {
width: 76%;
padding-left: 5px;
box-sizing: border-box;
}
.rmc-top-container {
height: 68%;
display: flex;
}
.rmctc-left-container {
width: 65%;
}
.rmctc-right-container {
width: 40%;
height: 99%;
}
.rmc-bottom-container {
height: 30%;
}
.rmcc-top-center-container {
display: flex;
.border-box-content {
flex-direction: column;
}
}
.rmctc-chart-1, .rmctc-chart-2 {
.border-box-content {
flex-direction: column;
}
}
</style>
\ No newline at end of file
const path = require('path')
const resolve = dir => {
return path.join(__dirname, dir)
}
module.exports = {
publicPath: './',
devServer: {
port: 9602,
},
lintOnSave: false,
chainWebpack: config => {
config.resolve.alias
.set('_c', resolve('src/components')) // key,value自行定义,比如.set('@@', resolve('src/components'))
config.resolve.alias
.set('@', resolve('src'))
},
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论