Compare commits

...

113 Commits

Author SHA1 Message Date
529b0154db update dist 2019-09-04 11:24:03 +08:00
26a5c3cedd add unit configuration item 2019-09-04 11:23:59 +08:00
10824d0c88 update version to 2.4.3 2019-09-04 11:23:41 +08:00
c34c493eb4 update changelog 2019-09-04 11:23:29 +08:00
1708d58215 update readme 2019-09-04 09:04:33 +08:00
948d6e0672 update readme 2019-09-04 08:56:40 +08:00
0a82102ec6 update readme 2019-09-04 08:54:48 +08:00
1aa5979968 add note 2019-09-03 16:02:07 +08:00
ff964f6b72 remove useless folder 2019-09-03 11:12:47 +08:00
b2b83d9474 Add import suffix 2019-09-03 11:08:17 +08:00
a1d7d4626d update build process 2019-09-03 11:07:45 +08:00
170facb3fc update dependencies 2019-09-03 11:07:26 +08:00
5224e80321 add feedback group img 2019-09-02 18:49:58 +08:00
1c4fa02e45 update readme 2019-09-02 18:49:37 +08:00
70164efe70 add TODO 2019-09-02 14:17:07 +08:00
7c0992e19f update lib 2019-08-30 18:24:50 +08:00
66c9a542cf update version to 2.4.2 2019-08-30 18:23:44 +08:00
47c2652ab4 update template 2019-08-30 14:40:45 +08:00
2c78715ff5 github template 2019-08-30 14:38:59 +08:00
4f078d984b update change log 2019-08-30 12:54:58 +08:00
720fd878b1 Class name compatibility optimization 2019-08-30 12:54:10 +08:00
f64ed65d3a update demo img 2019-08-30 12:53:43 +08:00
50fa3099a7 update readme 2019-08-30 12:53:31 +08:00
54bc52c1bf update lib 2019-08-30 09:44:38 +08:00
24a0c8a9e8 update version to 2.4.1 2019-08-29 17:47:40 +08:00
7bac2c6760 update changelog for v 2.4.1 2019-08-29 17:47:35 +08:00
0f9b00b525 Adaptive display unit 2019-08-29 17:47:14 +08:00
5376f01e3c add new component (borderBox10, capsuleChart) 2019-08-29 16:50:55 +08:00
8d1e0064a7 update lib 2019-08-29 16:50:19 +08:00
6adcd9c6cb update readme 2019-08-29 16:49:17 +08:00
3464c6b254 update version to 2.4.0 2019-08-29 16:49:09 +08:00
bd88a27ddc update change log for v2.4.0 2019-08-29 16:49:00 +08:00
bc0bf58baf update readme 2019-08-27 18:42:33 +08:00
46c72a9a68 update readme 2019-08-27 18:40:06 +08:00
1c33d4d7b8 update readme 2019-08-27 18:38:18 +08:00
0d59ebcc04 update version to v 2.3.9 2019-08-27 18:34:02 +08:00
c47f6133f4 update readme and add demo img 2019-08-27 18:33:14 +08:00
f8870f763a update change log for v 2.3.9 2019-08-27 18:27:54 +08:00
9f00506e73 Compatibility enhancement 2019-08-27 11:30:28 +08:00
e069d52544 Fixes: Style compatibility and gradient exceptions 2019-08-27 10:21:42 +08:00
4bd17d0a07 update version to 2.3.8 2019-08-27 10:21:02 +08:00
a1edd0d6f2 update change log for v 2.3.8 2019-08-27 10:20:52 +08:00
3cba31db56 Bug Fixes: bug #6 v 2.3.7 2019-08-26 17:07:00 +08:00
c6974cd2e4 update version to 2.3.7 2019-08-26 17:06:11 +08:00
56cc4534d1 update changelog for v 2.3.7 2019-08-26 17:06:01 +08:00
8884121c4c update change log 2019-08-24 13:11:05 +08:00
60bf393fd7 svg animation compatibility enhancement 2019-08-24 13:05:15 +08:00
d497dfa7d7 update version to 2.3.6 2019-08-24 13:04:26 +08:00
37469f7097 update changelog 2019-08-24 13:04:17 +08:00
JM
104e636bd7 Merge pull request #5 from Xiaoleng123/master
Bug Fixes: Enhance the animation compatibility of borderbox1 and fix spelling errors
2019-08-24 12:50:03 +08:00
0d1b1d9c29 🐛 animate compatible with Firefox 2019-08-23 22:20:40 +08:00
429e5b9478 update change log for v 2.3.5 2019-08-22 14:49:03 +08:00
e470b2ed8a update note 2019-08-22 14:42:51 +08:00
fdf5b76fe0 update version to 2.3.5 2019-08-22 14:41:11 +08:00
93bc3615ea add lib folder 2019-08-22 14:41:07 +08:00
e98f7caf96 update changelog for v2.3.5 2019-08-22 14:39:47 +08:00
7a2c0e7e4e update ignore 2019-08-22 14:39:21 +08:00
b86fd4d222 remove lock file 2019-08-22 14:38:53 +08:00
3ee305df19 Merge branch 'master' of https://github.com/jiaming743/DataV 2019-08-22 14:29:38 +08:00
JM
26a05978f5 Merge pull request #3 from chenhui7373/master
Fix 修复动态环图配置 color 环颜色无效
2019-08-22 14:26:57 +08:00
1ed7740a39 update color note 2019-08-22 14:07:34 +08:00
ec1bb34018 modify note 2019-08-22 14:01:35 +08:00
4ab07bffcc Fix 修复动态环图配置 color 环颜色无效
感谢作者提供这么好的库
2019-08-22 11:28:10 +08:00
71ce19e303 update version to 2.3.4 2019-08-15 16:51:12 +08:00
0103850f87 update changelog for version V 2.3.4-alpha 2019-08-15 16:50:40 +08:00
a88685812d Bux Fixes for V2.3.4-alpha (2019-00-15) 2019-08-15 16:50:12 +08:00
ae6a779561 update keywords 2019-07-31 10:31:31 +08:00
e108afaccf update readme 2019-07-31 10:09:35 +08:00
d7b6afccfe update changelog 2019-07-22 18:58:05 +08:00
a92e36067b Fix potential namespace conflicts 2019-07-22 18:56:49 +08:00
2d316d3629 Error caused by namespace conflict. 2019-07-22 18:50:42 +08:00
f0fcefd08a update changelog 2019-07-22 18:50:30 +08:00
38cb5e87de update version to 2.3.3 2019-07-22 18:50:22 +08:00
9699837d0e update publish process 2019-07-09 11:44:10 +08:00
132a817933 update readme 2019-07-05 16:25:54 +08:00
2408c821e7 update change log 2019-07-05 16:23:58 +08:00
af32755617 move components use statments 2019-07-05 16:19:18 +08:00
084f4c4c9c add fun dirForEach 2019-07-05 16:18:40 +08:00
98536da7d1 Automatically add export statements 2019-07-05 16:18:29 +08:00
b755a487aa update readme 2019-07-05 16:17:52 +08:00
46da621c70 update changelog 2019-07-05 16:17:33 +08:00
a86a4193ec add README_CN.md 2019-07-05 16:17:15 +08:00
e33096164c update version to v2.3.2 2019-07-05 13:52:20 +08:00
7edef8b9c8 update change log 2019-07-05 13:51:38 +08:00
6d4baac3b6 Explicitly set the SVG width and height 2019-07-05 13:49:42 +08:00
72433f8ff1 update version to 2.3.1 2019-07-04 17:12:29 +08:00
9c1ef5ed3b update change log 2019-07-04 17:12:10 +08:00
4ac3ad8c5b Fix potential rendering exceptions. 2019-07-04 17:12:04 +08:00
658537f155 Enhanced style compatibility. 2019-07-04 17:11:54 +08:00
6f784a3e36 Strengthen autoResize stability 2019-07-04 17:11:32 +08:00
3e5b960abd update version to v2.3.0 2019-07-04 10:36:11 +08:00
52889640ad update change log 2019-07-04 10:35:52 +08:00
3f22338861 perfect some style 2019-07-04 09:41:44 +08:00
JM
070a47011b perfect prepublish process 2019-07-03 22:00:43 +08:00
JM
ca392ba2f7 update ignore 2019-07-03 21:59:59 +08:00
3fb3936aa9 update prepublish process 2019-07-03 18:56:55 +08:00
bfc7cc7c57 for prepublish 2019-07-03 18:34:58 +08:00
f7d702588c update ignore 2019-07-03 18:34:31 +08:00
ee62dae22c update package.json 2019-07-03 18:33:57 +08:00
23e19af8b9 update ignore 2019-07-03 18:33:19 +08:00
6c5b5593d4 Modify package structure 2019-07-03 18:32:59 +08:00
376d723a2b update version to 2.2.0-alpha 2019-06-29 19:53:17 +08:00
562a262bf4 update change log 2019-06-29 19:52:57 +08:00
addf491d2b add new component 2019-06-29 19:51:13 +08:00
a842010afd Bug Fixes: Life cycle error 2019-06-28 20:18:30 +08:00
7b55614d43 remove slot because of occlusion 2019-06-28 20:17:59 +08:00
d586db9176 update version to v2.1.1-alpha 2019-06-28 20:16:32 +08:00
ad090aca3b update changelog 2019-06-28 20:15:09 +08:00
b9a1f667ee remove useless console 2019-06-27 19:50:50 +08:00
14c5ba753d update version to 2.1.0-alpha 2019-06-27 19:29:34 +08:00
a8ef114cc2 update changelog 2019-06-27 19:29:24 +08:00
16a31ed68f use Eslint formatter code 2019-06-27 19:28:07 +08:00
3cde8e553a add new components conicalColumnChart... 2019-06-27 19:27:37 +08:00
188 changed files with 31316 additions and 324 deletions

28
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,28 @@
---
name: Bug report
about: 提交Bug反馈
---
<!-- 请确定这是一个Bug反馈而不是一个需求反馈或问题求助否则ISSUE可能被关闭 -->
<!-- 请提供可供复现Bug的必要条件否则ISSUE可能被关闭 -->
<!-- 创建Bug反馈前请确定你的DataV是最新版的 -->
## Bug report
#### 出现Bug的组件
#### 组件配置数据?
<!-- (config等props若无配置请忽略) -->
#### 控制台错误输出?
<!-- (若无错误输出请忽略) -->
#### 期望情况?
#### 实际情况?
#### 其他相关信息
- DataV版本
- 浏览器版本
- 其他

View File

@ -0,0 +1,14 @@
---
name: Feature request
about: 新特性建议
---
<!-- 创建新特性建议前请确定你的DataV是最新版的 -->
## Feature request
#### 这个特性解决了什么问题?
#### 这个特性的实现形式?
#### 是否愿意为此特性提交PR

View File

@ -0,0 +1,20 @@
---
name: Component request
about: 新组件建议
---
<!-- 创建新组件建议前请确定你的DataV是最新版的 -->
<!-- (将[ ]修改为[x]) -->
## Component request
#### 新组件的类型?
* [ ] 边框
* [ ] 装饰
* [ ] 图表
* [ ] 其他
#### 这个组件的功能描述 (边框及装饰类,请提供样图)
#### 是否愿意为此组件提交PR

33
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,33 @@
<!-- (将[ ]修改为[x]) -->
**该PR的类型是** (至少选择一个)
- [ ] Bug修复
- [ ] 新特性
- [ ] 新组件
**该PR是否向下兼容?** (选择任一)
- [ ]
- [ ]
如果为否,请描述冲突情况:
**涉及到的ISSUE:**
- [ ] 该PR如果涉及到某个ISSUE, 请在PR标题中描述出来 (例如. `fix #xxx[,#xxx]`, "xxx"为ISSUE序号)
**是否在Chrome浏览器下进行过测试**
- [ ]
- [ ]
如果这是一个**新特性**或**新组件**相关的PR请提供如下信息
- [ ] 添加该特性或组件的原因
- [ ] 文档应该修改哪些信息
- [ ] 测试相关
提交**新特性**或**新组件**前请先发起一个相关的ISSUE请求
**其他信息:**

5
.gitignore vendored
View File

@ -1,8 +1,6 @@
.DS_Store
node_modules
/dist
/.svn
/DataV
package-lock.json
# local env files
.env.local
@ -12,6 +10,7 @@ node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock
# Editor directories and files
.idea

View File

@ -1,3 +1,192 @@
# 2.4.3-alpha (2019-09-04)
### Perfect
- **scrollRankingBoard:** Add a unit configuration item.
# 2.4.2-alpha (2019-08-30)
### Perfect
- **capsuleChart:** Class name compatibility optimization.
# 2.4.1-alpha (2019-08-29)
### Perfect
- **capsuleChart:** Adaptive display unit.
# 2.4.0-alpha (2019-08-29)
### New
- **borderBox10**
- **capsuleChart**
# 2.3.9-alpha (2019-08-27)
### Perfect
- **percentPond:** Compatibility enhancement.
# 2.3.8-alpha (2019-08-27)
### Bug Fixes
- **percentPond:** Style compatibility and gradient exceptions.
# 2.3.7-alpha (2019-08-26)
### Bug Fixes
- **borderBox1:** Parent container setting `text-align: center` to cause display exception [(#6)](https://github.com/jiaming743/DataV/issues/6).
# 2.3.6-alpha (2019-08-24)
### Bug Fixes
- **borderBox1:** Animation exception caused by incompatible syntax and spelling mistake [(#4)](https://github.com/jiaming743/DataV/issues/4)[(#5)](https://github.com/jiaming743/DataV/pull/5).
### Perfect
- **svg:** Svg animation compatibility enhancement.
# 2.3.5-alpha (2019-08-22)
### Bug Fixes
- **activeRingChart:** Color configuration does not take effect [(#3)](https://github.com/jiaming743/DataV/pull/3).
# 2.3.4-alpha (2019-08-15)
### Bug Fixes
- **package.json:** Import exception caused by incorrect entry path configuration.
# 2.3.3-alpha (2019-07-22)
### Bug Fixes
- **waterPondLevel:** Potential namespace conflict.
- **digitalFlop:** Potential namespace conflict.
# 2.3.2-alpha (2019-07-05)
### Perfect
- **decoration:** Explicitly set the SVG width and height to enhance stability.
- **Introduced on demand**
```js
import { borderBox1 } from '@jiaminghi/data-view'
Vue.use(borderBox1)
```
# 2.3.1-alpha (2019-07-04)
### Perfect
- **charts:** Enhanced style compatibility.
- **scrollBoard:** Enhanced style compatibility.
- **fullScreenContainer:** Fix potential rendering exceptions.
- **mixin:** Strengthen `autoResize` stability.
# 2.3.0-alpha (2019-07-04)
### Directory Structure Change
* **before**
```
.
├── components
│ ├── borderBox1
│ │ └── index.vue
│ ├── borderBox2
│ │ └── index.vue
│ ├── etc.
│ └── index.js
├── mixins
│ └── autoResize.js
├── util
│ └── index.js
├── index.js
├── package.json // main: 'index.js'
└── etc.
```
* **after**
```
.
├── lib // After compilation
│ ├── components
│ │ ├── borderBox1
│ │ | ├── src
│ │ | | ├── main.vue
│ │ | | └── main.css
│ │ | └── index.js
│ │ ├── etc.
│ │ └── index.js
│ ├── mixin
│ │ └── autoResize.js
│ ├── util
│ │ └── index.js
│ └── index.js
├── publish // For pre-publish process
├── src // For development environments
│ ├── components
│ │ ├── borderBox1
│ │ | ├── src
│ │ | | └── main.vue
│ │ | └── index.js
│ │ ├── etc.
│ │ └── index.js
│ ├── mixin
│ │ └── autoResize.js
│ ├── util
│ │ └── index.js
│ └── index.js
├── package.json // main: '/lib/index.js'
├── publish.js
└── etc.
```
- **Introduced on demand**
```js
import borderBox1 from '@jiaminghi/data-view/lib/components/borderBox1'
Vue.use(borderBox1)
```
# 2.2.0-alpha (2019-06-29)
### New
- **borderBox**
- **decoration**
# 2.1.1-alpha (2019-06-28)
### Bug Fixes
- **autoResize:** Exception caused by `autoResize` mixin.
- **charts:** `Legend` is blocked by slot and can't click.
# 2.1.0-alpha (2019-06-27)
### New
- **conicalColumnChart**
- **scrollRankingBoard**
# 2.0.0-alpha (2019-06-26)
### Perfect

BIN
QQGroup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,20 +1,67 @@
<h1 align="center">DataV</h1>
[ENGLISH](./README_EN.md)
<h1 align="center">DataV</h1>
<p align="center">
<a href="https://github.com/jiaming743/datav/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/jiaming743/datav.svg" alt="LICENSE" />
</a>
<a href="https://www.npmjs.com/package/@jiaminghi/datav">
<a href="https://www.npmjs.com/package/@jiaminghi/data-view">
<img src="https://img.shields.io/npm/v/@jiaminghi/data-view.svg" alt="LICENSE" />
</a>
</p>
<h2 align="center">Vue large screen data display component library</h2>
## DataV是干什么的?
### Install with npm
* DataV是一个基于**Vue**的数据可视化组件库.
* 提供用于提升页面视觉效果的**SVG**边框和装饰.
* 提供常用的**图表**如折线图等.
* 飞线图/轮播表等其他组件.
### npm安装
```shell
$ npm install @jiaminghi/data-view
```
Detailed documents and examples can be viewed on the [HomePage](http://datav.jiaminghi.com).
### 使用
```js
import Vue from 'vue'
import DataV from '@jiaminghi/data-view'
Vue.use(DataV)
// 按需引入
import { borderBox1 } from '@jiaminghi/data-view'
Vue.use(borderBox1)
```
详细文档及示例请移步[HomePage](http://datav.jiaminghi.com).
### TODO
* **边框**及**装饰**添加颜色及其他必要配置项,增强可配置性及灵活性.
### 致谢
组件库的开发基于个人学习和兴趣由于技术水平及经验的限制组件尚有许多不完善之处如有BUG可及时提交[issue](https://github.com/jiaming743/DataV/issues/new?template=bug_report.md)或添加反馈群进行反馈,也欢迎提供指正和建议,感谢各位的支持。
### 反馈
![Feedback](./QQGroup.png)
### Demo
Demo页面使用了全屏组件请F11全屏后查看。
* [施工养护综合数据](http://datav.jiaminghi.com/demo/construction-data/index.html)
![construction-data](./demoImg/construction-data.jpg)
* [机电运维管理台](http://datav.jiaminghi.com/demo/manage-desk/index.html)
![manage-desk](./demoImg/manage-desk.jpg)
* [机电设备电子档案](http://datav.jiaminghi.com/demo/electronic-file/index.html)
![electronic-file](./demoImg/electronic-file.jpg)

68
README_EN.md Normal file
View File

@ -0,0 +1,68 @@
[中文](./README.md)
<h1 align="center">DataV</h1>
<p align="center">
<a href="https://github.com/jiaming743/datav/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/jiaming743/datav.svg" alt="LICENSE" />
</a>
<a href="https://www.npmjs.com/package/@jiaminghi/data-view">
<img src="https://img.shields.io/npm/v/@jiaminghi/data-view.svg" alt="LICENSE" />
</a>
</p>
## What is DataV?
* DataV is a data **visualization** components library based on **Vue**.
* Provide cool **SVG** borders and decorations.
* Provide common **charts** such as line chart, etc..
* flying line chart, carousel table and etc.
### Install with npm
```shell
$ npm install @jiaminghi/data-view
```
### use
```js
import Vue from 'vue'
import DataV from '@jiaminghi/data-view'
Vue.use(DataV)
// Introduced on demand
import { borderBox1 } from '@jiaminghi/data-view'
Vue.use(borderBox1)
```
Detailed documents and examples can be viewed on the [HomePage](http://datav.jiaminghi.com).
### TODO
* Add color and other necessary configuration to the **borderBox** and **decoration** to enhance configurability and flexibility.
### Acknowledgement
The development of the component library is based on personal learning and interest. Due to technical level and experience limitations, there are still many imperfections in the components. If there are errors, you can submit [issue](https://github.com/jiaming743/DataV/issues/new?template=bug_report.md) in time or add feedback groups for feedback. Welcome to provide corrections and suggestions. Thank you for your support.
### Feedback
![Feedback](./QQGroup.png)
### Demo
The Demo page uses the full-screen component, please view it after F11 full screen.
* [Construction Data](http://datav.jiaminghi.com/demo/construction-data/index.html)
![construction-data](./demoImg/construction-data.jpg)
* [Manage-Desk](http://datav.jiaminghi.com/demo/manage-desk/index.html)
![manage-desk](./demoImg/manage-desk.jpg)
* [Electronic-File](http://datav.jiaminghi.com/demo/electronic-file/index.html)
![electronic-file](./demoImg/electronic-file.jpg)

4
build/entry.js Normal file
View File

@ -0,0 +1,4 @@
import Vue from 'vue'
import datav from '../src/index'
Vue.use(datav)

211
build/index.js Normal file
View File

@ -0,0 +1,211 @@
const { copyDir, fileForEach, readFile, writeFile, unlinkDirFileByExtname, dirForEach } = require('@jiaminghi/fs')
const print = require('./plugin/print')
const path = require('path')
const exec = require('./plugin/exec')
const PACKAGE_SRC = './src'
const COMPILE_SRC = './lib'
const COMPONENTS_DIR = '/components'
const ENTRANCE = '/index.js'
const libName = 'datav'
async function start () {
// Compile for NPM
const copyPackage = await copyDir(PACKAGE_SRC, COMPILE_SRC)
if (!copyPackage) {
print.error('Exception in file copy!')
return false
}
print.success('Complete file copy!')
const abstract = await abstractLessFromVue()
if (!abstract) {
print.error('Exception in less file extraction!')
return false
}
print.success('Complete less file extraction!')
await compileLessToCss()
print.success('Complete less compilation to css!')
const unlink = await unlinkDirFileByExtname(COMPILE_SRC, ['.less'])
if (!unlink) {
print.error('Exception in less file deletion!')
return false
}
print.success('Complete less file deletion!')
const addImport = await addCssImport()
if (!addImport) {
print.error('Exception in adding css import statement!')
return false
}
print.success('Finish adding css import statement!')
const componentsExport = await addComponentsExport()
if (!componentsExport) {
print.error('Exception in adding components export statement!')
return false
}
print.success('Finish adding components export statement!')
// Compile for UMD version
const rollupCompile = await exec(`rollup -c build/rollup.config.js`)
if (!rollupCompile) {
print.error('Exception in rollupCompile')
return
}
print.tip('After rollupCompile')
// const uglifyjs = await exec(`uglifyjs dist/${libName}.map.js -o dist/${libName}.min.js`)
// if (!uglifyjs) {
// print.error('Exception in uglifyjs')
// return
// }
// print.tip('After uglifyjs')
print.yellow('-------------------------------------')
print.success(' DataV Lib Compile Success! ')
print.yellow('-------------------------------------')
return true
}
async function abstractLessFromVue () {
let abstractSuccess = true
await fileForEach(COMPILE_SRC, async src => {
if (path.extname(src) !== '.vue') return
let template = await readFile(src)
let style = template.match(/<style[ \S\n\r]*/g)
if (style) style = style[0]
if (!style) return
style = style.replace(/<style[ a-z="']*>(\n|\r)?|<\/style>/g, '')
style = style.replace(/[\n\r]*$/, '')
const styleSrc = src.replace('.vue', '.less')
let write = await writeFile(styleSrc, style)
if (!write) {
print.error(styleSrc + ' write error!')
abstractSuccess = false
}
template = template.replace(/<style[ \S\n\r]*/g, '')
template = template.replace(/[\n\r]*$/, '')
write = await writeFile(src, template)
if (!write) {
print.error(src + ' rewrite error!')
abstractSuccess = false
}
})
return abstractSuccess
}
async function compileLessToCss () {
let compileSuccess = true
await fileForEach(COMPILE_SRC, async src => {
if (path.extname(src) !== '.less') return
src = src.replace('./', '')
const execString = `lessc ${src} ${src.replace('less', 'css')}`
print.yellow(execString, {
maxBuffer: 1024 ** 5
})
const compile = await exec(execString)
if (!compile) {
print.error(execString + ' Error!')
compileSuccess = false
}
})
return compileSuccess
}
async function addCssImport () {
let importSuccess = true
await fileForEach(COMPILE_SRC + COMPONENTS_DIR, async src => {
if (path.extname(src) !== '.js') return
let content = await readFile(src)
if (content.search(/import[ \S]* from '[\S]*\.vue'/) === -1) return
content = `import './src/main.css'\n` + content
let write = await writeFile(src, content)
if (!write) {
print.error(src + ' write import error!')
importSuccess = false
}
})
return importSuccess
}
async function addComponentsExport () {
const components = []
await dirForEach(COMPILE_SRC + COMPONENTS_DIR, src => {
components.push(src.split('/').slice(-1)[0])
})
const importString = components.reduce((all, current) => {
return all + '\n' + `export { default as ${current} } from '.${COMPONENTS_DIR}/${current}/index'`
}, '/**\n * EXPORT COMPONENTS\n */') + '\n'
const targetSrc = COMPILE_SRC + ENTRANCE
let content = await readFile(targetSrc)
content = importString + content
let write = await writeFile(targetSrc, content)
return write
}
async function compileUMDVersion () {
}
start()

19
build/plugin/exec.js Normal file
View File

@ -0,0 +1,19 @@
const { exec } = require('child_process')
function doExec (execString, maxBuffer = 1024 ** 5) {
return new Promise(resolve => {
exec(execString, {
maxBuffer
}, err => {
if (err) {
console.error(err)
resolve(false)
} else {
resolve(true)
}
})
})
}
module.exports = doExec

22
build/plugin/print.js Normal file
View File

@ -0,0 +1,22 @@
const print = {
log (info) {
console.log(info)
},
warn (info) {
console.log('\033[31;33m' + info + '\033[0m')
},
error (info) {
console.log('\033[31;40m' + info + '\033[0m')
},
tip (info) {
console.log('\033[40;32m' + info + '\033[0m')
},
success (info) {
console.log('\033[42;30m' + info + '\033[0m')
},
yellow (info) {
console.log('\033[31;33m' + info + '\033[0m')
}
}
module.exports = print

23
build/rollup.config.js Normal file
View File

@ -0,0 +1,23 @@
import resolve from 'rollup-plugin-node-resolve'
import vue from 'rollup-plugin-vue'
import commonjs from 'rollup-plugin-commonjs'
import babel from 'rollup-plugin-babel'
export default {
input: 'build/entry.js',
// input: 'src/index.js',
output: {
format: 'umd',
file: 'dist/datav.map.js',
name: 'datav'
},
plugins: [
resolve(),
babel({
exclude: 'node_modules/**'
}),
commonjs(),
vue(),
],
external: ['Vue']
}

View File

@ -1,68 +0,0 @@
<template>
<div id="dv-full-screen-container" ref="full-screen-container">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'FullScreenContainer',
data () {
return {
scale: 0,
datavRoot: ''
}
},
methods: {
init () {
const { initConfig, setAppScale, bindReSizeEventHandler } = this
initConfig()
setAppScale()
bindReSizeEventHandler()
},
initConfig () {
const { width, height } = screen
this.allWidth = width
const datavRoot = this.datavRoot = this.$refs['full-screen-container']
datavRoot.style.width = `${width}px`
datavRoot.style.height = `${height}px`
},
setAppScale () {
const { allWidth, datavRoot } = this
const currentWidth = document.body.clientWidth
datavRoot.style.transform = `scale(${currentWidth / allWidth})`
},
bindReSizeEventHandler () {
const { debounce, setAppScale } = this
if (!debounce) return
window.addEventListener('resize', debounce(100, setAppScale))
}
},
mounted () {
const { init } = this
init()
}
}
</script>
<style lang="less">
#dv-full-screen-container {
position: fixed;
top: 0px;
left: 0px;
overflow: hidden;
transform-origin: left top;
z-index: 999;
}
</style>

View File

@ -1,69 +0,0 @@
import fullScreenContainer from './fullScreenContainer'
import loading from './loading/index.vue'
// border box
import borderBox1 from './borderBox1/index'
import borderBox2 from './borderBox2/index'
import borderBox3 from './borderBox3/index'
import borderBox4 from './borderBox4/index'
import borderBox5 from './borderBox5/index'
import borderBox6 from './borderBox6/index'
import borderBox7 from './borderBox7/index'
import borderBox8 from './borderBox8/index'
// decoration
import decoration1 from './decoration1/index'
import decoration2 from './decoration2/index'
import decoration3 from './decoration3/index'
import decoration4 from './decoration4/index'
import decoration5 from './decoration5/index'
import decoration6 from './decoration6/index'
import decoration7 from './decoration7/index'
import decoration8 from './decoration8/index'
// charts
import charts from './charts/index.vue'
import activeRingChart from './activeRingChart'
import waterLevelPond from './waterLevelPond/index.vue'
import percentPond from './percentPond/index.vue'
import flylineChart from './flylineChart'
import digitalFlop from './digitalFlop'
import scrollBoard from './scrollBoard/index.vue'
export default function (Vue) {
Vue.component('dvFullScreenContainer', fullScreenContainer)
Vue.component('dvLoading', loading)
// border box
Vue.component('dvBorderBox1', borderBox1)
Vue.component('dvBorderBox2', borderBox2)
Vue.component('dvBorderBox3', borderBox3)
Vue.component('dvBorderBox4', borderBox4)
Vue.component('dvBorderBox5', borderBox5)
Vue.component('dvBorderBox6', borderBox6)
Vue.component('dvBorderBox7', borderBox7)
Vue.component('dvBorderBox8', borderBox8)
// decoration
Vue.component('dvDecoration1', decoration1)
Vue.component('dvDecoration2', decoration2)
Vue.component('dvDecoration3', decoration3)
Vue.component('dvDecoration4', decoration4)
Vue.component('dvDecoration5', decoration5)
Vue.component('dvDecoration6', decoration6)
Vue.component('dvDecoration7', decoration7)
Vue.component('dvDecoration8', decoration8)
// charts
Vue.component('dvCharts', charts)
Vue.component('dvActiveRingChart', activeRingChart)
Vue.component('dvWaterLevelPond', waterLevelPond)
Vue.component('dvPercentPond', percentPond)
Vue.component('dvFlylineChart', flylineChart)
Vue.component('dvDigitalFlop', digitalFlop)
Vue.component('dvScrollBoard', scrollBoard)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
demoImg/electronic-file.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
demoImg/manage-desk.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

23693
dist/datav.map.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +0,0 @@
import components from './components/index'
export default function (Vue) {
components(Vue)
}

View File

@ -0,0 +1,6 @@
import './src/main.css'
import ActiveRingChart from './src/main.vue'
export default function (Vue) {
Vue.component(ActiveRingChart.name, ActiveRingChart)
}

View File

@ -0,0 +1,32 @@
.dv-active-ring-chart {
position: relative;
}
.dv-active-ring-chart .active-ring-chart-container {
width: 100%;
height: 100%;
}
.dv-active-ring-chart .active-ring-info {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.dv-active-ring-chart .active-ring-info .dv-digital-flop {
width: 100px;
height: 30px;
}
.dv-active-ring-chart .active-ring-info .active-ring-name {
width: 100px;
height: 30px;
color: #fff;
text-align: center;
vertical-align: middle;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

View File

@ -0,0 +1,265 @@
<template>
<div class="dv-active-ring-chart">
<div class="active-ring-chart-container" ref="active-ring-chart" />
<div class="active-ring-info">
<dv-digital-flop :config="digitalFlop" />
<div class="active-ring-name" :style="fontSize">{{ ringName }}</div>
</div>
</div>
</template>
<script>
import Charts from '@jiaminghi/charts'
import dvDigitalFlop from '../../digitalFlop/src/main.vue'
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
export default {
name: 'DvActiveRingChart',
components: {
dvDigitalFlop
},
props: {
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
defaultConfig: {
/**
* @description Ring radius
* @type {String|Number}
* @default radius = '50%'
* @example radius = '50%' | 100
*/
radius: '50%',
/**
* @description Active ring radius
* @type {String|Number}
* @default activeRadius = '55%'
* @example activeRadius = '55%' | 110
*/
activeRadius: '55%',
/**
* @description Ring data
* @type {Array<Object>}
* @default data = [{ name: '', value: 0 }]
*/
data: [{ name: '', value: 0 }],
/**
* @description Ring line width
* @type {Number}
* @default lineWidth = 20
*/
lineWidth: 20,
/**
* @description Active time gap (ms)
* @type {Number}
* @default activeTimeGap = 3000
*/
activeTimeGap: 3000,
/**
* @description Ring color (hex|rgb|rgba|color keywords)
* @type {Array<String>}
* @default color = [Charts Default Color]
* @example color = ['#000', 'rgb(0, 0, 0)', 'rgba(0, 0, 0, 1)', 'red']
*/
color: [],
/**
* @description Digital flop style
* @type {Object}
*/
digitalFlopStyle: {
fontSize: 25,
fill: '#fff'
},
/**
* @description CRender animationCurve
* @type {String}
* @default animationCurve = 'easeOutCubic'
*/
animationCurve: 'easeOutCubic',
/**
* @description CRender animationFrame
* @type {String}
* @default animationFrame = 50
*/
animationFrame: 50
},
mergedConfig: null,
chart: null,
activeIndex: 0,
animationHandler: ''
}
},
computed: {
digitalFlop () {
const { mergedConfig, activeIndex } = this
if (!mergedConfig) return {}
const { digitalFlopStyle, data } = mergedConfig
const value = data.map(({ value }) => value)
const sum = value.reduce((all, v) => all + v, 0)
const percent = parseInt(value[activeIndex] / sum * 100)
return {
content: '{nt}%',
number: [percent],
style: digitalFlopStyle
}
},
ringName () {
const { mergedConfig, activeIndex } = this
if (!mergedConfig) return ''
return mergedConfig.data[activeIndex].name
},
fontSize () {
const { mergedConfig } = this
if (!mergedConfig) return ''
return `font-size: ${mergedConfig.digitalFlopStyle.fontSize}px;`
}
},
watch: {
config () {
const { animationHandler, mergeConfig, setRingOption } = this
clearTimeout(animationHandler)
this.activeIndex = 0
mergeConfig()
setRingOption()
}
},
methods: {
init () {
const { initChart, mergeConfig, setRingOption } = this
initChart()
mergeConfig()
setRingOption()
},
initChart () {
const { $refs } = this
this.chart = new Charts($refs['active-ring-chart'])
},
mergeConfig () {
const { defaultConfig, config } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
},
setRingOption () {
const { getRingOption, chart, ringAnimation } = this
const option = getRingOption()
chart.setOption(option)
ringAnimation()
},
getRingOption () {
const { mergedConfig, getRealRadius } = this
const radius = getRealRadius()
mergedConfig.data.forEach(dataItem => {
dataItem.radius = radius
})
return {
series: [
{
type: 'pie',
...mergedConfig,
outsideLabel: {
show: false
}
}
],
color: mergedConfig.color
}
},
getRealRadius (active = false) {
const { mergedConfig, chart } = this
const { radius, activeRadius, lineWidth } = mergedConfig
const maxRadius = Math.min(...chart.render.area) / 2
const halfLineWidth = lineWidth / 2
let realRadius = active ? activeRadius : radius
if (typeof realRadius !== 'number') realRadius = parseInt(realRadius) / 100 * maxRadius
const insideRadius = realRadius - halfLineWidth
const outSideRadius = realRadius + halfLineWidth
return [insideRadius, outSideRadius]
},
ringAnimation () {
let { activeIndex, getRingOption, chart, getRealRadius } = this
const radius = getRealRadius()
const active = getRealRadius(true)
const option = getRingOption()
const { data } = option.series[0]
data.forEach((dataItem, i) => {
if (i === activeIndex) {
dataItem.radius = active
} else {
dataItem.radius = radius
}
})
chart.setOption(option)
const { activeTimeGap } = option.series[0]
this.animationHandler = setTimeout(foo => {
activeIndex += 1
if (activeIndex >= data.length) activeIndex = 0
this.activeIndex = activeIndex
this.ringAnimation()
}, activeTimeGap)
}
},
mounted () {
const { init } = this
init()
},
beforeDestroy () {
const { animationHandler } = this
clearTimeout(animationHandler)
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox1 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox1.name, BorderBox1)
}

View File

@ -0,0 +1,27 @@
.dv-border-box-1 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-1 .border {
position: absolute;
display: block;
}
.dv-border-box-1 .right-top {
right: 0px;
transform: rotateY(180deg);
}
.dv-border-box-1 .left-bottom {
bottom: 0px;
transform: rotateX(180deg);
}
.dv-border-box-1 .right-bottom {
right: 0px;
bottom: 0px;
transform: rotateX(180deg) rotateY(180deg);
}
.dv-border-box-1 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,63 @@
<template>
<div class="dv-border-box-1">
<svg
width="150px"
height="150px"
:key="item"
v-for="item in border"
:class="`${item} border`"
>
<polygon
fill="#4fd2dd"
points="6,66 6,18 12,12 18,12 24,6 27,6 30,9 36,9 39,6 84,6 81,9 75,9 73.2,7 40.8,7 37.8,10.2 24,10.2 12,21 12,24 9,27 9,51 7.8,54 7.8,63"
>
<animate
attributeName="fill"
values="#4fd2dd;#235fa7;#4fd2dd"
dur="0.5s"
begin="0s"
repeatCount="indefinite"
/>
</polygon>
<polygon
fill="#235fa7"
points="27.599999999999998,4.8 38.4,4.8 35.4,7.8 30.599999999999998,7.8"
>
<animate
attributeName="fill"
values="#235fa7;#4fd2dd;#235fa7"
dur="0.5s"
begin="0s"
repeatCount="indefinite"
/>
</polygon>
<polygon
fill="#4fd2dd"
points="9,54 9,63 7.199999999999999,66 7.199999999999999,75 7.8,78 7.8,110 8.4,110 8.4,66 9.6,66 9.6,54"
>
<animate
attributeName="fill"
values="#4fd2dd;#235fa7;transparent"
dur="1s"
begin="0s"
repeatCount="indefinite"
/>
</polygon>
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'DvBorderBox1',
data () {
return {
border: ['left-top', 'right-top', 'left-bottom', 'right-bottom']
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox10 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox10.name, BorderBox10)
}

View File

@ -0,0 +1,29 @@
.dv-border-box-10 {
position: relative;
width: 100%;
height: 100%;
box-shadow: inset 0 0 25px 3px #1d48c4;
border-radius: 6px;
}
.dv-border-box-10 .border {
position: absolute;
display: block;
}
.dv-border-box-10 .right-top {
right: 0px;
transform: rotateY(180deg);
}
.dv-border-box-10 .left-bottom {
bottom: 0px;
transform: rotateX(180deg);
}
.dv-border-box-10 .right-bottom {
right: 0px;
bottom: 0px;
transform: rotateX(180deg) rotateY(180deg);
}
.dv-border-box-10 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,31 @@
<template>
<div class="dv-border-box-10">
<svg
width="150px"
height="150px"
:key="item"
v-for="item in border"
:class="`${item} border`"
>
<polygon
fill="#d3e1f8"
points="40, 0 5, 0 0, 5 0, 16 3, 19 3, 7 7, 3 35, 3"
/>
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'DvBorderBox10',
data () {
return {
border: ['left-top', 'right-top', 'left-bottom', 'right-bottom']
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox2 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox2.name, BorderBox2)
}

View File

@ -0,0 +1,30 @@
.dv-border-box-2 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-2 .dv-border-svg-container {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
}
.dv-border-box-2 .dv-border-svg-container polyline {
fill: none;
stroke-width: 1;
}
.dv-border-box-2 .dv-border-svg-container circle {
fill: #fff;
}
.dv-border-box-2 .dv-bb2-line1 {
stroke: #fff;
}
.dv-border-box-2 .dv-bb2-line2 {
stroke: rgba(255, 255, 255, 0.6);
}
.dv-border-box-2 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,32 @@
<template>
<div class="dv-border-box-2" :ref="ref">
<svg class="dv-border-svg-container" :width="width" :height="height">
<polyline class="dv-bb2-line1"
:points="`2, 2 ${width - 2} ,2 ${width - 2}, ${height - 2} 2, ${height - 2} 2, 2`" />
<polyline class="dv-bb2-line2"
:points="`6, 6 ${width - 6}, 6 ${width - 6}, ${height - 6} 6, ${height - 6} 6, 6`" />
<circle cx="11" cy="11" r="1" />
<circle :cx="width - 11" cy="11" r="1" />
<circle :cx="width - 11" :cy="height - 11" r="1" />
<circle cx="11" :cy="height - 11" r="1" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox2',
mixins: [autoResize],
data () {
return {
ref: 'border-box-2'
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox3 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox3.name, BorderBox3)
}

View File

@ -0,0 +1,27 @@
.dv-border-box-3 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-3 .dv-border-svg-container {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
}
.dv-border-box-3 .dv-border-svg-container polyline {
fill: none;
stroke: #2862b7;
}
.dv-border-box-3 .dv-bb3-line1 {
stroke-width: 3;
}
.dv-border-box-3 .dv-bb3-line2 {
stroke-width: 1;
}
.dv-border-box-3 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,32 @@
<template>
<div class="dv-border-box-3" :ref="ref">
<svg class="dv-border-svg-container" :width="width" :height="height">
<polyline class="dv-bb3-line1"
:points="`4, 4 ${width - 22} ,4 ${width - 22}, ${height - 22} 4, ${height - 22} 4, 4`" />
<polyline class="dv-bb3-line2"
:points="`10, 10 ${width - 16}, 10 ${width - 16}, ${height - 16} 10, ${height - 16} 10, 10`" />
<polyline class="dv-bb3-line2"
:points="`16, 16 ${width - 10}, 16 ${width - 10}, ${height - 10} 16, ${height - 10} 16, 16`" />
<polyline class="dv-bb3-line2"
:points="`22, 22 ${width - 4}, 22 ${width - 4}, ${height - 4} 22, ${height - 4} 22, 22`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox3',
mixins: [autoResize],
data () {
return {
ref: 'border-box-3'
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox4 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox4.name, BorderBox4)
}

View File

@ -0,0 +1,82 @@
.dv-border-box-4 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-4 .dv-reverse {
transform: rotate(180deg);
}
.dv-border-box-4 .dv-border-svg-container {
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
}
.dv-border-box-4 .dv-border-svg-container polyline {
fill: none;
}
.dv-border-box-4 .sred {
stroke: red;
}
.dv-border-box-4 .sblue {
stroke: rgba(0, 0, 255, 0.8);
}
.dv-border-box-4 .sw1 {
stroke-width: 1;
}
.dv-border-box-4 .sw3 {
stroke-width: 3px;
stroke-linecap: round;
}
.dv-border-box-4 .dv-bb4-line-1 {
stroke: red;
stroke-width: 1;
}
.dv-border-box-4 .dv-bb4-line-2 {
stroke: rgba(0, 0, 255, 0.8);
stroke-width: 1;
}
.dv-border-box-4 .dv-bb4-line-3 {
stroke: red;
stroke-width: 3px;
stroke-linecap: round;
}
.dv-border-box-4 .dv-bb4-line-4 {
stroke: red;
stroke-width: 3px;
stroke-linecap: round;
}
.dv-border-box-4 .dv-bb4-line-5 {
stroke: red;
stroke-width: 1;
}
.dv-border-box-4 .dv-bb4-line-6 {
stroke: rgba(0, 0, 255, 0.8);
stroke-width: 1;
}
.dv-border-box-4 .dv-bb4-line-7 {
stroke: rgba(0, 0, 255, 0.8);
stroke-width: 1;
}
.dv-border-box-4 .dv-bb4-line-8 {
stroke: rgba(0, 0, 255, 0.8);
stroke-width: 3px;
stroke-linecap: round;
}
.dv-border-box-4 .dv-bb4-line-9 {
stroke: red;
stroke-width: 3px;
stroke-linecap: round;
stroke-dasharray: 100 250;
}
.dv-border-box-4 .dv-bb4-line-10 {
stroke: rgba(0, 0, 255, 0.8);
stroke-width: 1;
stroke-dasharray: 80 270;
}
.dv-border-box-4 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,42 @@
<template>
<div class="dv-border-box-4" :ref="ref">
<svg :class="`dv-border-svg-container ${reverse && 'dv-reverse'}`" :width="width" :height="height">
<polyline class="dv-bb4-line-1" :points="`145, ${height - 5} 40, ${height - 5} 10, ${height - 35}
10, 40 40, 5 150, 5 170, 20 ${width - 15}, 20`"/>
<polyline class="dv-bb4-line-2" :points="`245, ${height - 1} 36, ${height - 1} 14, ${height - 23}
14, ${height - 100}`" />
<polyline class="dv-bb4-line-3" :points="`7, ${height - 40} 7, ${height - 75}`" />
<polyline class="dv-bb4-line-4" :points="`28, 24 13, 41 13, 64`" />
<polyline class="dv-bb4-line-5" :points="`5, 45 5, 140`" />
<polyline class="dv-bb4-line-6" :points="`14, 75 14, 180`" />
<polyline class="dv-bb4-line-7" :points="`55, 11 147, 11 167, 26 250, 26`" />
<polyline class="dv-bb4-line-8" :points="`158, 5 173, 16`" />
<polyline class="dv-bb4-line-9" :points="`200, 17 ${width - 10}, 17`" />
<polyline class="dv-bb4-line-10" :points="`385, 17 ${width - 10}, 17`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox4',
mixins: [autoResize],
data () {
return {
ref: 'border-box-4'
}
},
props: {
reverse: {
type: Boolean,
default: false
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox5 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox5.name, BorderBox5)
}

View File

@ -0,0 +1,40 @@
.dv-border-box-5 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-5 .dv-reverse {
transform: rotate(180deg);
}
.dv-border-box-5 .dv-svg-container {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
.dv-border-box-5 .dv-svg-container polyline {
fill: none;
}
.dv-border-box-5 .dv-bb5-line-1 {
stroke-width: 1;
stroke: rgba(255, 255, 255, 0.35);
}
.dv-border-box-5 .dv-bb5-line-2 {
stroke: rgba(255, 255, 255, 0.2);
}
.dv-border-box-5 .dv-bb5-line-3,
.dv-border-box-5 .dv-bb5-line-6 {
stroke-width: 5;
stroke: rgba(255, 255, 255, 0.15);
}
.dv-border-box-5 .dv-bb5-line-4,
.dv-border-box-5 .dv-bb5-line-5 {
stroke-width: 2;
stroke: rgba(255, 255, 255, 0.15);
}
.dv-border-box-5 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,38 @@
<template>
<div class="dv-border-box-5" :ref="ref">
<svg :class="`dv-svg-container ${reverse && 'dv-reverse'}`" :width="width" :height="height">
<polyline class="dv-bb5-line-1" :points="`8, 5 ${width - 5}, 5 ${width - 5}, ${height - 100}
${width - 100}, ${height - 5} 8, ${height - 5} 8, 5`" />
<polyline class="dv-bb5-line-2" :points="`3, 5 ${width - 20}, 5 ${width - 20}, ${height - 60}
${width - 74}, ${height - 5} 3, ${height - 5} 3, 5`" />
<polyline class="dv-bb5-line-3" :points="`50, 13 ${width - 35}, 13`" />
<polyline class="dv-bb5-line-4" :points="`15, 20 ${width - 35}, 20`" />
<polyline class="dv-bb5-line-5" :points="`15, ${height - 20} ${width - 110}, ${height - 20}`" />
<polyline class="dv-bb5-line-6" :points="`15, ${height - 13} ${width - 110}, ${height - 13}`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox5',
mixins: [autoResize],
data () {
return {
ref: 'border-box-5'
}
},
props: {
reverse: {
type: Boolean,
default: false
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox6 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox6.name, BorderBox6)
}

View File

@ -0,0 +1,25 @@
.dv-border-box-6 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-6 .dv-svg-container {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
.dv-border-box-6 .dv-svg-container circle {
fill: gray;
}
.dv-border-box-6 .dv-svg-container polyline {
fill: none;
stroke-width: 1;
stroke: rgba(255, 255, 255, 0.35);
}
.dv-border-box-6 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,40 @@
<template>
<div class="dv-border-box-6" :ref="ref">
<svg class="dv-svg-container" :width="width" :height="height">
<circle cx="5" cy="5" r="2"/>
<circle :cx="width - 5" cy="5" r="2" />
<circle :cx="width - 5" :cy="height - 5" r="2" />
<circle cx="5" :cy="height - 5" r="2" />
<polyline :points="`10, 4 ${width - 10}, 4`" />
<polyline :points="`10, ${height - 4} ${width - 10}, ${height - 4}`" />
<polyline :points="`5, 70 5, ${height - 70}`" />
<polyline :points="`${width - 5}, 70 ${width - 5}, ${height - 70}`" />
<polyline :points="`3, 10, 3, 50`" />
<polyline :points="`7, 30 7, 80`" />
<polyline :points="`${width - 3}, 10 ${width - 3}, 50`" />
<polyline :points="`${width - 7}, 30 ${width - 7}, 80`" />
<polyline :points="`3, ${height - 10} 3, ${height - 50}`" />
<polyline :points="`7, ${height - 30} 7, ${height - 80}`" />
<polyline :points="`${width - 3}, ${height - 10} ${width - 3}, ${height - 50}`" />
<polyline :points="`${width - 7}, ${height - 30} ${width - 7}, ${height - 80}`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize.js'
export default {
name: 'DvBorderBox6',
mixins: [autoResize],
data () {
return {
ref: 'border-box-6'
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox7 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox7.name, BorderBox7)
}

View File

@ -0,0 +1,31 @@
.dv-border-box-7 {
position: relative;
width: 100%;
height: 100%;
box-shadow: inset 0 0 40px rgba(128, 128, 128, 0.3);
border: 1px solid rgba(128, 128, 128, 0.3);
}
.dv-border-box-7 .dv-svg-container {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
.dv-border-box-7 .dv-svg-container polyline {
fill: none;
stroke-linecap: round;
}
.dv-border-box-7 .dv-bb7-line-width-2 {
stroke: rgba(128, 128, 128, 0.3);
stroke-width: 2;
}
.dv-border-box-7 .dv-bb7-line-width-5 {
stroke: rgba(128, 128, 128, 0.5);
stroke-width: 5;
}
.dv-border-box-7 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,33 @@
<template>
<div class="dv-border-box-7" :ref="ref">
<svg class="dv-svg-container" :width="width" :height="height">
<polyline class="dv-bb7-line-width-2" :points="`0, 25 0, 0 25, 0`" />
<polyline class="dv-bb7-line-width-2" :points="`${width - 25}, 0 ${width}, 0 ${width}, 25`" />
<polyline class="dv-bb7-line-width-2" :points="`${width - 25}, ${height} ${width}, ${height} ${width}, ${height - 25}`" />
<polyline class="dv-bb7-line-width-2" :points="`0, ${height - 25} 0, ${height} 25, ${height}`" />
<polyline class="dv-bb7-line-width-5" :points="`0, 10 0, 0 10, 0`" />
<polyline class="dv-bb7-line-width-5" :points="`${width - 10}, 0 ${width}, 0 ${width}, 10`" />
<polyline class="dv-bb7-line-width-5" :points="`${width - 10}, ${height} ${width}, ${height} ${width}, ${height - 10}`" />
<polyline class="dv-bb7-line-width-5" :points="`0, ${height - 10} 0, ${height} 10, ${height}`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox7',
mixins: [autoResize],
data () {
return {
ref: 'border-box-7'
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox8 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox8.name, BorderBox8)
}

View File

@ -0,0 +1,17 @@
.dv-border-box-8 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-8 svg {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
}
.dv-border-box-8 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,86 @@
<template>
<div class="dv-border-box-8" :ref="ref">
<svg class="dv-svg-container" :width="width" :height="height">
<defs>
<path
:id="path"
:d="`M2.5, 2.5 L${width - 2.5}, 2.5 L${width - 2.5}, ${height - 2.5} L2.5, ${height - 2.5} L2.5, 2.5`"
fill="transparent"
/>
<radialGradient
:id="gradient"
cx="50%" cy="50%" r="50%"
>
<stop
offset="0%" stop-color="#fff"
stop-opacity="1"
/>
<stop
offset="100%" stop-color="#fff"
stop-opacity="0"
/>
</radialGradient>
<mask :id="mask">
<circle cx="0" cy="0" r="150" :fill="`url(#${gradient})`">
<animateMotion
dur="3s"
:path="`M2.5, 2.5 L${width - 2.5}, 2.5 L${width - 2.5}, ${height - 2.5} L2.5, ${height - 2.5} L2.5, 2.5`"
rotate="auto"
repeatCount="indefinite"
/>
</circle>
</mask>
</defs>
<use
stroke="#235fa7"
stroke-width="1"
:xlink:href="`#${path}`"
/>
<use
stroke="#4fd2dd"
stroke-width="3"
:xlink:href="`#${path}`"
:mask="`url(#${mask})`"
>
<animate
attributeName="stroke-dasharray"
:from="`0, ${length}`"
:to="`${length}, 0`"
dur="3s"
repeatCount="indefinite"
/>
</use>
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox8',
mixins: [autoResize],
data () {
return {
ref: 'border-box-8',
path: `border-box-8-path-${(new Date()).getTime()}`,
gradient: `border-box-8-gradient-${(new Date()).getTime()}`,
mask: `border-box-8-mask-${(new Date()).getTime()}`
}
},
computed: {
length () {
const { width, height } = this
return (width + height - 5) * 2
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import BorderBox9 from './src/main.vue'
export default function (Vue) {
Vue.component(BorderBox9.name, BorderBox9)
}

View File

@ -0,0 +1,17 @@
.dv-border-box-9 {
position: relative;
width: 100%;
height: 100%;
}
.dv-border-box-9 svg {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
}
.dv-border-box-9 .border-box-content {
position: relative;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,100 @@
<template>
<div class="dv-border-box-9" :ref="ref">
<svg class="dv-svg-container" :width="width" :height="height">
<defs>
<linearGradient :id="gradientId" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#11eefd" />
<stop offset="100%" stop-color="#0078d2" />
</linearGradient>
<mask :id="maskId">
<polyline
stroke="#fff"
stroke-width="3"
fill="transparent"
:points="`8, ${height * 0.4} 8, 3, ${width * 0.4 + 7}, 3`"
/>
<polyline
fill="#fff"
:points="
`8, ${height * 0.15} 8, 3, ${width * 0.1 + 7}, 3
${width * 0.1}, 8 14, 8 14, ${height * 0.15 - 7}
`"
/>
<polyline
stroke="#fff"
stroke-width="3"
fill="transparent"
:points="`${width * 0.5}, 3 ${width - 3}, 3, ${width - 3}, ${height * 0.25}`"
/>
<polyline
fill="#fff"
:points="`
${width * 0.52}, 3 ${width * 0.58}, 3
${width * 0.58 - 7}, 9 ${width * 0.52 + 7}, 9
`"
/>
<polyline
fill="#fff"
:points="`
${width * 0.9}, 3 ${width - 3}, 3 ${width - 3}, ${height * 0.1}
${width - 9}, ${height * 0.1 - 7} ${width - 9}, 9 ${width * 0.9 + 7}, 9
`"
/>
<polyline
stroke="#fff"
stroke-width="3"
fill="transparent"
:points="`8, ${height * 0.5} 8, ${height - 3} ${width * 0.3 + 7}, ${height - 3}`"
/>
<polyline
fill="#fff"
:points="`
8, ${height * 0.55} 8, ${height * 0.7}
2, ${height * 0.7 - 7} 2, ${height * 0.55 + 7}
`"
/>
<polyline
stroke="#fff"
stroke-width="3"
fill="transparent"
:points="`${width * 0.35}, ${height - 3} ${width - 3}, ${height - 3} ${width - 3}, ${height * 0.35}`"
/>
<polyline
fill="#fff"
:points="`
${width * 0.92}, ${height - 3} ${width - 3}, ${height - 3} ${width - 3}, ${height * 0.8}
${width - 9}, ${height * 0.8 + 7} ${width - 9}, ${height - 9} ${width * 0.92 + 7}, ${height - 9}
`"
/>
</mask>
</defs>
<rect x="0" y="0" :width="width" :height="height" :fill="`url(#${gradientId})`" :mask="`url(#${maskId})`" />
</svg>
<div class="border-box-content">
<slot></slot>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvBorderBox9',
mixins: [autoResize],
data () {
return {
ref: 'border-box-9',
gradientId: `border-box-9-gradient-${(new Date()).getTime()}`,
maskId: `border-box-9-mask-${(new Date()).getTime()}`
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import CapsuleChart from './src/main.vue'
export default function (Vue) {
Vue.component(CapsuleChart.name, CapsuleChart)
}

View File

@ -0,0 +1,55 @@
.dv-capsule-chart {
position: relative;
display: flex;
flex-direction: row;
box-sizing: border-box;
padding: 10px;
color: #fff;
}
.dv-capsule-chart .label-column {
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
padding-right: 10px;
text-align: right;
font-size: 12px;
}
.dv-capsule-chart .label-column div {
height: 20px;
line-height: 20px;
}
.dv-capsule-chart .capsule-container {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.dv-capsule-chart .capsule-item {
box-shadow: 0 0 3px #999;
height: 10px;
margin: 5px 0px;
border-radius: 5px;
}
.dv-capsule-chart .capsule-item div {
height: 8px;
margin-top: 1px;
border-radius: 5px;
transition: all 0.3s;
}
.dv-capsule-chart .unit-label {
height: 20px;
font-size: 12px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.dv-capsule-chart .unit-text {
text-align: right;
display: flex;
align-items: flex-end;
font-size: 12px;
line-height: 20px;
margin-left: 10px;
}

View File

@ -0,0 +1,114 @@
<template>
<div class="dv-capsule-chart">
<template v-if="mergedConfig">
<div class="label-column">
<div v-for="item in mergedConfig.data" :key="item.name">{{ item.name }}</div>
<div>&nbsp;</div>
</div>
<div class="capsule-container">
<div
class="capsule-item"
v-for="(capsule, index) in capsuleLength"
:key="index"
>
<div :style="`width: ${capsule * 100}%; background-color: ${mergedConfig.colors[index % mergedConfig.colors.length]};`"></div>
</div>
<div class="unit-label">
<div v-for="(label, index) in labelData" :key="label + index">{{ label }}</div>
</div>
</div>
<div class="unit-text" v-if="mergedConfig.unit">{{ mergedConfig.unit }}</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: 'DvCapsuleChart',
props: {
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
defaultConfig: {
/**
* @description Capsule chart data
* @type {Array<Object>}
* @default data = []
* @example data = [{ name: 'foo1', value: 100 }, { name: 'foo2', value: 100 }]
*/
data: [],
/**
* @description Colors (hex|rgb|rgba|color keywords)
* @type {Array<String>}
* @default color = ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293']
* @example color = ['#000', 'rgb(0, 0, 0)', 'rgba(0, 0, 0, 1)', 'red']
*/
colors: ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293'],
/**
* @description Chart unit
* @type {String}
* @default unit = ''
*/
unit: ''
},
mergedConfig: null,
capsuleLength: [],
labelData: []
}
},
watch: {
config () {
const { calcData } = this
calcData()
}
},
methods: {
calcData () {
const { mergeConfig, calcCapsuleLengthAndLabelData } = this
mergeConfig()
calcCapsuleLengthAndLabelData()
},
mergeConfig () {
let { config, defaultConfig } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
},
calcCapsuleLengthAndLabelData () {
const { data } = this.mergedConfig
if (!data.length) return
const capsuleValue = data.map(({ value }) => value)
const maxValue = Math.max(...capsuleValue)
this.capsuleLength = capsuleValue.map(v => maxValue ? v / maxValue : 0)
const oneFifth = maxValue / 5
this.labelData = new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))
}
},
mounted () {
const { calcData } = this
calcData()
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Charts from './src/main.vue'
export default function (Vue) {
Vue.component(Charts.name, Charts)
}

View File

@ -0,0 +1,9 @@
.dv-charts-container {
position: relative;
width: 100%;
height: 100%;
}
.dv-charts-container .charts-canvas-container {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,64 @@
<template>
<div class="dv-charts-container" :ref="ref">
<div class="charts-canvas-container" :ref="chartRef" />
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
import Charts from '@jiaminghi/charts'
export default {
name: 'DvCharts',
mixins: [autoResize],
props: {
option: {
type: Object,
default: () => ({})
}
},
data () {
return {
ref: `charts-container-${(new Date()).getTime()}`,
chartRef: `chart-${(new Date()).getTime()}`,
chart: null
}
},
watch: {
option () {
let { chart, option } = this
if (!chart) return
if (!option) option = {}
chart.setOption(option)
}
},
methods: {
afterAutoResizeMixinInit () {
const { initChart } = this
initChart()
},
initChart () {
const { $refs, chartRef, option } = this
const chart = this.chart = new Charts($refs[chartRef])
if (!option) return
chart.setOption(option)
},
onResize () {
const { chart } = this
if (!chart) return
chart.resize()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import ConicalColumnChart from './src/main.vue'
export default function (Vue) {
Vue.component(ConicalColumnChart.name, ConicalColumnChart)
}

View File

@ -0,0 +1,7 @@
.dv-conical-column-chart {
width: 100%;
height: 100%;
}
.dv-conical-column-chart text {
text-anchor: middle;
}

View File

@ -0,0 +1,208 @@
<template>
<div class="dv-conical-column-chart" :ref="ref">
<svg :width="width" :height="height">
<g
v-for="(item, i) in column"
:key="i"
>
<path
:d="item.d"
:fill="mergedConfig.columnColor"
/>
<text
:style="`fontSize:${mergedConfig.fontSize}px`"
:fill="mergedConfig.textColor"
:x="item.x"
:y="height - 4"
>
{{ item.name }}
</text>
<image
v-if="mergedConfig.img.length"
:xlink:href="mergedConfig.img[i % mergedConfig.img.length]"
:width="mergedConfig.imgSideLength"
:height="mergedConfig.imgSideLength"
:x="item.x - mergedConfig.imgSideLength / 2"
:y="item.y - mergedConfig.imgSideLength"
/>
<text
v-if="mergedConfig.showValue"
:style="`fontSize:${mergedConfig.fontSize}px`"
:fill="mergedConfig.textColor"
:x="item.x"
:y="item.textY"
>
{{ item.value }}
</text>
</g>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
export default {
name: 'DvConicalColumnChart',
mixins: [autoResize],
props: {
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
ref: 'conical-column-chart',
defaultConfig: {
/**
* @description Chart data
* @type {Array<Object>}
* @default data = []
*/
data: [],
/**
* @description Chart img
* @type {Array<String>}
* @default img = []
*/
img: [],
/**
* @description Chart font size
* @type {Number}
* @default fontSize = 12
*/
fontSize: 12,
/**
* @description Img side length
* @type {Number}
* @default imgSideLength = 30
*/
imgSideLength: 30,
/**
* @description Column color
* @type {String}
* @default columnColor = 'rgba(0, 194, 255, 0.4)'
*/
columnColor: 'rgba(0, 194, 255, 0.4)',
/**
* @description Text color
* @type {String}
* @default textColor = '#fff'
*/
textColor: '#fff',
/**
* @description Show value
* @type {Boolean}
* @default showValue = false
*/
showValue: false
},
mergedConfig: null,
column: []
}
},
watch: {
config () {
const { calcData } = this
calcData()
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcData } = this
calcData()
},
onResize () {
const { calcData } = this
calcData()
},
calcData () {
const { mergeConfig, initData, calcSVGPath } = this
mergeConfig()
initData()
calcSVGPath()
},
mergeConfig () {
const { defaultConfig, config } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
},
initData () {
const { mergedConfig } = this
let { data } = mergedConfig
data = deepClone(data, true)
data.sort(({ value: a }, { value: b }) => {
if (a > b) return -1
if (a < b) return 1
if (a === b) return 0
})
const max = data[0] ? data[0].value : 10
data = data.map(item => ({
...item,
percent: item.value / max
}))
mergedConfig.data = data
},
calcSVGPath () {
const { mergedConfig, width, height } = this
const { imgSideLength, fontSize, data } = mergedConfig
const itemNum = data.length
const gap = width / (itemNum + 1)
const useAbleHeight = height - imgSideLength - fontSize - 5
const svgBottom = height - fontSize - 5
this.column = data.map((item, i) => {
const { percent } = item
const middleXPos = gap * (i + 1)
const leftXPos = gap * i
const rightXpos = gap * (i + 2)
const middleYPos = svgBottom - useAbleHeight * percent
const controlYPos = useAbleHeight * percent * 0.6 + middleYPos
const d = `
M${leftXPos}, ${svgBottom}
Q${middleXPos}, ${controlYPos} ${middleXPos},${middleYPos}
M${middleXPos},${middleYPos}
Q${middleXPos}, ${controlYPos} ${rightXpos},${svgBottom}
L${leftXPos}, ${svgBottom}
Z
`
const textY = (svgBottom + middleYPos) / 2 + fontSize / 2
return {
...item,
d,
x: middleXPos,
y: middleYPos,
textY
}
})
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration1 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration1.name, Decoration1)
}

View File

@ -0,0 +1,7 @@
.dv-decoration-1 {
width: 100%;
height: 100%;
}
.dv-decoration-1 svg {
transform-origin: left top;
}

View File

@ -0,0 +1,166 @@
<template>
<div class="dv-decoration-1" :ref="ref">
<svg :width="`${svgWH[0]}px`" :height="`${svgWH[1]}px`" :style="`transform:scale(${svgScale[0]},${svgScale[1]});`">
<template
v-for="(point, i) in points"
>
<rect
v-if="Math.random() > 0.6"
:key="i"
fill="#fff"
:x="point[0] - halfPointSideLength"
:y="point[1] - halfPointSideLength"
:width="pointSideLength"
:height="pointSideLength"
>
<animate
v-if="Math.random() > 0.6"
attributeName="fill"
values="#fff;transparent"
dur="1s"
:begin="Math.random() * 2"
repeatCount="indefinite"
/>
</rect>
</template>
<rect
v-if="rects[0]"
fill="#0de7c2"
:x="rects[0][0] - pointSideLength"
:y="rects[0][1] - pointSideLength"
:width="pointSideLength * 2"
:height="pointSideLength * 2"
>
<animate
attributeName="width"
:values="`0;${pointSideLength * 2}`"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="height"
:values="`0;${pointSideLength * 2}`"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="x"
:values="`${rects[0][0]};${rects[0][0] - pointSideLength}`"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="y"
:values="`${rects[0][1]};${rects[0][1] - pointSideLength}`"
dur="2s"
repeatCount="indefinite"
/>
</rect>
<rect
v-if="rects[1]"
fill="#0de7c2"
:x="rects[1][0] - 40"
:y="rects[1][1] - pointSideLength"
:width="40"
:height="pointSideLength * 2"
>
<animate
attributeName="width"
values="0;40;0"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="x"
:values="`${rects[1][0]};${rects[1][0] - 40};${rects[1][0]}`"
dur="2s"
repeatCount="indefinite"
/>
</rect>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration1',
mixins: [autoResize],
data () {
const pointSideLength = 2.5
return {
ref: 'decoration-1',
svgWH: [200, 50],
svgScale: [1, 1],
rowNum: 4,
rowPoints: 20,
pointSideLength,
halfPointSideLength: pointSideLength / 2,
points: [],
rects: []
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcSVGData } = this
calcSVGData()
},
calcSVGData () {
const { calcPointsPosition, calcRectsPosition, calcScale } = this
calcPointsPosition()
calcRectsPosition()
calcScale()
},
calcPointsPosition () {
const { svgWH, rowNum, rowPoints } = this
const [w, h] = svgWH
const horizontalGap = w / (rowPoints + 1)
const verticalGap = h / (rowNum + 1)
let points = new Array(rowNum).fill(0).map((foo, i) =>
new Array(rowPoints).fill(0).map((foo, j) => [
horizontalGap * (j + 1), verticalGap * (i + 1)
]))
this.points = points.reduce((all, item) => [...all, ...item], [])
},
calcRectsPosition () {
const { points, rowPoints } = this
const rect1 = points[rowPoints * 2 - 1]
const rect2 = points[rowPoints * 2 - 3]
this.rects = [rect1, rect2]
},
calcScale () {
const { width, height, svgWH } = this
const [w, h] = svgWH
this.svgScale = [width / w, height / h]
},
onResize () {
const { calcSVGData } = this
calcSVGData()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration10 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration10.name, Decoration10)
}

View File

@ -0,0 +1,5 @@
.dv-decoration-10 {
width: 100%;
height: 100%;
display: flex;
}

View File

@ -0,0 +1,168 @@
<template>
<div class="dv-decoration-10" :ref="ref">
<svg :width="width" :height="height">
<polyline
stroke="rgba(0, 194, 255, 0.3)"
stroke-width="2"
:points="`0, ${height / 2} ${width}, ${height / 2}`"
/>
<polyline
stroke="rgba(0, 194, 255, 1)"
stroke-width="2"
:points="`5, ${height / 2} ${width * 0.2 - 3}, ${height / 2}`"
:stroke-dasharray="`0, ${width * 0.2}`"
fill="freeze"
>
<animate
:id="animationId2"
attributeName="stroke-dasharray"
:values="`0, ${width * 0.2};${width * 0.2}, 0;`"
dur="3s"
:begin="`${animationId1}.end`"
fill="freeze"
/>
<animate
attributeName="stroke-dasharray"
:values="`${width * 0.2}, 0;0, ${width * 0.2}`"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</polyline>
<polyline
stroke="rgba(0, 194, 255, 1)"
stroke-width="2"
:points="`${width * 0.2 + 3}, ${height / 2} ${width * 0.8 - 3}, ${height / 2}`"
:stroke-dasharray="`0, ${width * 0.6}`"
>
<animate
:id="animationId4"
attributeName="stroke-dasharray"
:values="`0, ${width * 0.6};${width * 0.6}, 0`"
dur="3s"
:begin="`${animationId3}.end + 1s`"
fill="freeze"
/>
<animate
attributeName="stroke-dasharray"
:values="`${width * 0.6}, 0;0, ${width * 0.6}`"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</polyline>
<polyline
stroke="rgba(0, 194, 255, 1)"
stroke-width="2"
:points="`${width * 0.8 + 3}, ${height / 2} ${width - 5}, ${height / 2}`"
:stroke-dasharray="`0, ${width * 0.2}`"
>
<animate
:id="animationId6"
attributeName="stroke-dasharray"
:values="`0, ${width * 0.2};${width * 0.2}, 0`"
dur="3s"
:begin="`${animationId5}.end + 1s`"
fill="freeze"
/>
<animate
attributeName="stroke-dasharray"
:values="`${width * 0.2}, 0;0, ${width * 0.3}`"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</polyline>
<circle cx="2" :cy="height / 2" r="2" fill="#03709f">
<animate
:id="animationId1"
attributeName="fill"
values="#03709f;#00c2ff"
:begin="`0s;${animationId7}.end`"
dur="0.3s"
fill="freeze"
/>
</circle>
<circle :cx="width * 0.2" :cy="height / 2" r="2" fill="#03709f">
<animate
:id="animationId3"
attributeName="fill"
values="#03709f;#00c2ff"
:begin="`${animationId2}.end`"
dur="0.3s"
fill="freeze"
/>
<animate
attributeName="fill"
values="#03709f;#03709f"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</circle>
<circle :cx="width * 0.8" :cy="height / 2" r="2" fill="#03709f">
<animate
:id="animationId5"
attributeName="fill"
values="#03709f;#00c2ff"
:begin="`${animationId4}.end`"
dur="0.3s"
fill="freeze"
/>
<animate
attributeName="fill"
values="#03709f;#03709f"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</circle>
<circle :cx="width - 2" :cy="height / 2" r="2" fill="#03709f">
<animate
:id="animationId7"
attributeName="fill"
values="#03709f;#00c2ff"
:begin="`${animationId6}.end`"
dur="0.3s"
fill="freeze"
/>
<animate
attributeName="fill"
values="#03709f;#03709f"
dur="0.01s"
:begin="`${animationId7}.end`"
fill="freeze"
/>
</circle>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration10',
mixins: [autoResize],
data () {
return {
ref: 'decoration-10',
animationId1: `d10ani1${(new Date()).getTime()}`,
animationId2: `d10ani2${(new Date()).getTime()}`,
animationId3: `d10ani3${(new Date()).getTime()}`,
animationId4: `d10ani4${(new Date()).getTime()}`,
animationId5: `d10ani5${(new Date()).getTime()}`,
animationId6: `d10ani6${(new Date()).getTime()}`,
animationId7: `d10ani7${(new Date()).getTime()}`
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration2 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration2.name, Decoration2)
}

View File

@ -0,0 +1,7 @@
.dv-decoration-2 {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,91 @@
<template>
<div class="dv-decoration-2" :ref="ref">
<svg :width="`${width}px`" :height="`${height}px`">
<rect :x="x" :y="y" :width="w" :height="h" fill="#3faacb">
<animate
:attributeName="reverse ? 'height' : 'width'"
from="0"
:to="reverse ? height : width"
dur="6s"
calcMode="spline"
keyTimes="0;1"
keySplines=".42,0,.58,1"
repeatCount="indefinite"
/>
</rect>
<rect :x="x" :y="y" width="1" height="1" fill="#fff">
<animate
:attributeName="reverse ? 'y' : 'x'"
from="0"
:to="reverse ? height : width"
dur="6s"
calcMode="spline"
keyTimes="0;1"
keySplines="0.42,0,0.58,1"
repeatCount="indefinite"
/>
</rect>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration2',
mixins: [autoResize],
props: {
reverse: {
type: Boolean,
default: false
}
},
data () {
return {
ref: 'decoration-2',
x: 0,
y: 0,
w: 0,
h: 0
}
},
watch: {
reverse () {
const { calcSVGData } = this
calcSVGData()
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcSVGData } = this
calcSVGData()
},
calcSVGData () {
const { reverse, width, height } = this
if (reverse) {
this.w = 1
this.h = height
this.x = width / 2
this.y = 0
} else {
this.w = width
this.h = 1
this.x = 0
this.y = height / 2
}
},
onResize () {
const { calcSVGData } = this
calcSVGData()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration3 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration3.name, Decoration3)
}

View File

@ -0,0 +1,7 @@
.dv-decoration-3 {
width: 100%;
height: 100%;
}
.dv-decoration-3 svg {
transform-origin: left top;
}

View File

@ -0,0 +1,97 @@
<template>
<div class="dv-decoration-3" :ref="ref">
<svg :width="`${svgWH[0]}px`" :height="`${svgWH[1]}px`" :style="`transform:scale(${svgScale[0]},${svgScale[1]});`">
<template
v-for="(point, i) in points"
>
<rect
:key="i"
fill="#7acaec"
:x="point[0] - halfPointSideLength"
:y="point[1] - halfPointSideLength"
:width="pointSideLength"
:height="pointSideLength"
>
<animate
v-if="Math.random() > 0.6"
attributeName="fill"
values="#7acaec;transparent"
:dur="Math.random() + 1 + 's'"
:begin="Math.random() * 2"
repeatCount="indefinite"
/>
</rect>
</template>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration3',
mixins: [autoResize],
data () {
const pointSideLength = 7
return {
ref: 'decoration-3',
svgWH: [300, 35],
svgScale: [1, 1],
rowNum: 2,
rowPoints: 25,
pointSideLength,
halfPointSideLength: pointSideLength / 2,
points: []
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcSVGData } = this
calcSVGData()
},
calcSVGData () {
const { calcPointsPosition, calcScale } = this
calcPointsPosition()
calcScale()
},
calcPointsPosition () {
const { svgWH, rowNum, rowPoints } = this
const [w, h] = svgWH
const horizontalGap = w / (rowPoints + 1)
const verticalGap = h / (rowNum + 1)
let points = new Array(rowNum).fill(0).map((foo, i) =>
new Array(rowPoints).fill(0).map((foo, j) => [
horizontalGap * (j + 1), verticalGap * (i + 1)
]))
this.points = points.reduce((all, item) => [...all, ...item], [])
},
calcScale () {
const { width, height, svgWH } = this
const [w, h] = svgWH
this.svgScale = [width / w, height / h]
},
onResize () {
const { calcSVGData } = this
calcSVGData()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration4 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration4.name, Decoration4)
}

View File

@ -0,0 +1,38 @@
.dv-decoration-4 {
position: relative;
width: 100%;
height: 100%;
}
.dv-decoration-4 .container {
display: flex;
overflow: hidden;
position: absolute;
}
.dv-decoration-4 .normal {
height: 0% !important;
animation: ani-height 3s ease-in-out infinite;
left: 50%;
margin-left: -2px;
}
.dv-decoration-4 .reverse {
width: 0% !important;
animation: ani-width 3s ease-in-out infinite;
top: 50%;
margin-top: -2px;
}
@keyframes ani-height {
70% {
height: 100%;
}
100% {
height: 100%;
}
}
@keyframes ani-width {
70% {
width: 100%;
}
100% {
width: 100%;
}
}

View File

@ -0,0 +1,38 @@
<template>
<div class="dv-decoration-4" :ref="ref">
<div
:class="`container ${reverse ? 'reverse' : 'normal'}`"
:style="reverse ? `width:${width}px;height:5px` : `width:5px;height:${height}px;`"
>
<svg :width="reverse ? width : 5" :height="reverse ? 5 : height">
<polyline
stroke="rgba(255, 255, 255, 0.3)"
:points="reverse ? `0, 2.5 ${width}, 2.5` : `2.5, 0 2.5, ${height}`"
/>
<polyline
class="bold-line"
stroke="rgba(255, 255, 255, 0.3)"
stroke-width="3"
stroke-dasharray="20, 80"
stroke-dashoffset="-30"
:points="reverse ? `0, 2.5 ${width}, 2.5` : `2.5, 0 2.5, ${height}`"
/>
</svg>
</div>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration4',
mixins: [autoResize],
props: ['reverse'],
data () {
return {
ref: 'decoration-4'
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration5 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration5.name, Decoration5)
}

View File

@ -0,0 +1,4 @@
.dv-decoration-5 {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,103 @@
<template>
<div class="dv-decoration-5" :ref="ref">
<svg :width="width" :height="height">
<polyline
fill="transparent"
stroke="#3f96a5"
stroke-width="3"
:points="line1Points"
>
<animate
attributeName="stroke-dasharray"
attributeType="XML"
:from="`0, ${line1Length / 2}, 0, ${line1Length / 2}`"
:to="`0, 0, ${line1Length}, 0`"
dur="1.2s"
begin="0s"
calcMode="spline"
keyTimes="0;1"
keySplines="0.4,1,0.49,0.98"
repeatCount="indefinite"
/>
</polyline>
<polyline
fill="transparent"
stroke="#3f96a5"
stroke-width="2"
:points="line2Points"
>
<animate
attributeName="stroke-dasharray"
attributeType="XML"
:from="`0, ${line2Length / 2}, 0, ${line2Length / 2}`"
:to="`0, 0, ${line2Length}, 0`"
dur="1.2s"
begin="0s"
calcMode="spline"
keyTimes="0;1"
keySplines=".4,1,.49,.98"
repeatCount="indefinite"
/>
</polyline>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
import { getPolylineLength } from '@jiaminghi/charts/lib/util'
export default {
name: 'DvDecoration5',
mixins: [autoResize],
data () {
return {
ref: 'decoration-5',
line1Points: '',
line2Points: '',
line1Length: 0,
line2Length: 0
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcSVGData } = this
calcSVGData()
},
calcSVGData () {
const { width, height } = this
let line1Points = [
[0, height * 0.2], [width * 0.18, height * 0.2], [width * 0.2, height * 0.4], [width * 0.25, height * 0.4],
[width * 0.27, height * 0.6], [width * 0.72, height * 0.6], [width * 0.75, height * 0.4],
[width * 0.8, height * 0.4], [width * 0.82, height * 0.2], [width, height * 0.2]
]
let line2Points = [
[width * 0.3, height * 0.8], [width * 0.7, height * 0.8]
]
const line1Length = getPolylineLength(line1Points)
const line2Length = getPolylineLength(line2Points)
line1Points = line1Points.map(point => point.join(',')).join(' ')
line2Points = line2Points.map(point => point.join(',')).join(' ')
this.line1Points = line1Points
this.line2Points = line2Points
this.line1Length = line1Length
this.line2Length = line2Length
},
onResize () {
const { calcSVGData } = this
calcSVGData()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration6 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration6.name, Decoration6)
}

View File

@ -0,0 +1,7 @@
.dv-decoration-6 {
width: 100%;
height: 100%;
}
.dv-decoration-6 svg {
transform-origin: left top;
}

View File

@ -0,0 +1,122 @@
<template>
<div class="dv-decoration-6" :ref="ref">
<svg :width="`${svgWH[0]}px`" :height="`${svgWH[1]}px`" :style="`transform:scale(${svgScale[0]},${svgScale[1]});`">
<template
v-for="(point, i) in points"
>
<rect
:key="i"
fill="#7acaec"
:x="point[0] - halfRectWidth"
:y="point[1] - heights[i] / 2"
:width="rectWidth"
:height="heights[i]"
>
<animate
attributeName="y"
:values="`${point[1] - minHeights[i] / 2};${point[1] - heights[i] / 2};${point[1] - minHeights[i] / 2}`"
:dur="`${randoms[i]}s`"
keyTimes="0;0.5;1"
calcMode="spline"
keySplines="0.42,0,0.58,1;0.42,0,0.58,1"
begin="0s"
repeatCount="indefinite"
/>
<animate
attributeName="height"
:values="`${minHeights[i]};${heights[i]};${minHeights[i]}`"
:dur="`${randoms[i]}s`"
keyTimes="0;0.5;1"
calcMode="spline"
keySplines="0.42,0,0.58,1;0.42,0,0.58,1"
begin="0s"
repeatCount="indefinite"
/>
</rect>
</template>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
import { randomExtend } from '../../../util'
export default {
name: 'DvDecoration6',
mixins: [autoResize],
data () {
const rectWidth = 7
return {
ref: 'decoration-6',
svgWH: [300, 35],
svgScale: [1, 1],
rowNum: 1,
rowPoints: 40,
rectWidth,
halfRectWidth: rectWidth / 2,
points: [],
heights: [],
minHeights: [],
randoms: []
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcSVGData } = this
calcSVGData()
},
calcSVGData () {
const { calcPointsPosition, calcScale } = this
calcPointsPosition()
calcScale()
},
calcPointsPosition () {
const { svgWH, rowNum, rowPoints } = this
const [w, h] = svgWH
const horizontalGap = w / (rowPoints + 1)
const verticalGap = h / (rowNum + 1)
let points = new Array(rowNum).fill(0).map((foo, i) =>
new Array(rowPoints).fill(0).map((foo, j) => [
horizontalGap * (j + 1), verticalGap * (i + 1)
]))
this.points = points.reduce((all, item) => [...all, ...item], [])
const heights = this.heights = new Array(rowNum * rowPoints)
.fill(0).map(foo =>
Math.random() > 0.8 ? randomExtend(0.7 * h, h) : randomExtend(0.2 * h, 0.5 * h))
this.minHeights = new Array(rowNum * rowPoints)
.fill(0).map((foo, i) => heights[i] * Math.random())
this.randoms = new Array(rowNum * rowPoints)
.fill(0).map(foo => Math.random() + 1.5)
},
calcScale () {
const { width, height, svgWH } = this
const [w, h] = svgWH
this.svgScale = [width / w, height / h]
},
onResize () {
const { calcSVGData } = this
calcSVGData()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration7 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration7.name, Decoration7)
}

View File

@ -0,0 +1,7 @@
.dv-decoration-7 {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,39 @@
<template>
<div class="dv-decoration-7">
<svg width="21px" height="20px">
<polyline
stroke-width="4"
fill="transparent"
stroke="#1dc1f5"
points="10, 0 19, 10 10, 20"
/>
<polyline
stroke-width="2"
fill="transparent"
stroke="#1dc1f5"
points="2, 0 11, 10 2, 20"
/>
</svg>
<slot></slot>
<svg width="21px" height="20px">
<polyline
stroke-width="4"
fill="transparent"
stroke="#1dc1f5"
points="11, 0 2, 10 11, 20"
/>
<polyline
stroke-width="2"
fill="transparent"
stroke="#1dc1f5"
points="19, 0 10, 10 19, 20"
/>
</svg>
</div>
</template>
<script>
export default {
name: 'DvDecoration7'
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration8 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration8.name, Decoration8)
}

View File

@ -0,0 +1,5 @@
.dv-decoration-8 {
display: flex;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,55 @@
<template>
<div class="dv-decoration-8" :ref="ref">
<svg :width="width" :height="height">
<polyline
stroke="#3f96a5"
stroke-width="2"
fill="transparent"
:points="`${xPos(0)}, 0 ${xPos(30)}, ${height / 2}`"
/>
<polyline
stroke="#3f96a5"
stroke-width="2"
fill="transparent"
:points="`${xPos(20)}, 0 ${xPos(50)}, ${height / 2} ${xPos(width)}, ${height / 2}`"
/>
<polyline
stroke="#3f96a5"
fill="transparent"
stroke-width="3"
:points="`${xPos(0)}, ${height - 3}, ${xPos(200)}, ${height - 3}`"
/>
</svg>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration8',
mixins: [autoResize],
props: {
reverse: {
type: Boolean,
default: false
}
},
data () {
return {
ref: 'decoration-8'
}
},
methods: {
xPos (pos) {
const { reverse, width } = this
if (!reverse) return pos
return width - pos
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import Decoration9 from './src/main.vue'
export default function (Vue) {
Vue.component(Decoration9.name, Decoration9)
}

View File

@ -0,0 +1,14 @@
.dv-decoration-9 {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.dv-decoration-9 svg {
position: absolute;
left: 0px;
top: 0px;
transform-origin: left top;
}

View File

@ -0,0 +1,123 @@
<template>
<div class="dv-decoration-9" :ref="ref">
<svg :width="`${svgWH[0]}px`" :height="`${svgWH[1]}px`" :style="`transform:scale(${svgScale[0]},${svgScale[1]});`">
<defs>
<polygon :id="polygonId" points="15, 46.5, 21, 47.5, 21, 52.5, 15, 53.5" />
</defs>
<circle
cx="50"
cy="50"
r="45"
fill="transparent"
stroke="rgba(3, 166, 224, 0.5)"
stroke-width="10"
stroke-dasharray="80, 100, 30, 100"
>
<animateTransform
attributeName="transform"
type="rotate"
values="0 50 50;360 50 50"
dur="3s"
repeatCount="indefinite"
/>
</circle>
<circle
cx="50"
cy="50"
r="45"
fill="transparent"
stroke="rgba(3, 166, 224, 0.8)"
stroke-width="6"
stroke-dasharray="50, 66, 100, 66"
>
<animateTransform
attributeName="transform"
type="rotate"
values="0 50 50;-360 50 50"
dur="3s"
repeatCount="indefinite"
/>
</circle>
<circle
cx="50"
cy="50"
r="38"
fill="transparent"
stroke="rgba(3, 166, 224, 0.2)"
stroke-width="1"
stroke-dasharray="5, 1"
/>
<use
v-for="(foo, i) in new Array(20).fill(0)"
:key="i"
:xlink:href="`#${polygonId}`"
stroke="rgba(3, 166, 224, 0.6)"
:fill="Math.random() > 0.4 ? 'transparent' : 'rgba(3, 166, 224, 0.8)'"
>
<animateTransform
attributeName="transform"
type="rotate"
values="0 50 50;360 50 50"
dur="3s"
:begin="`${i * 0.15}s`"
repeatCount="indefinite"
/>
</use>
<circle
cx="50"
cy="50"
r="26"
fill="transparent"
stroke="rgba(3, 166, 224, 0.2)"
stroke-width="1"
stroke-dasharray="5, 1"
/>
</svg>
<slot></slot>
</div>
</template>
<script>
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvDecoration9',
mixins: [autoResize],
data () {
return {
ref: 'decoration-9',
polygonId: `decoration-9-polygon-${(new Date()).getTime()}`,
svgWH: [100, 100],
svgScale: [1, 1]
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcScale } = this
calcScale()
},
calcScale () {
const { width, height, svgWH } = this
const [w, h] = svgWH
this.svgScale = [width / w, height / h]
},
onResize () {
const { calcScale } = this
calcScale()
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import DigitalFlop from './src/main.vue'
export default function (Vue) {
Vue.component(DigitalFlop.name, DigitalFlop)
}

View File

@ -0,0 +1,4 @@
.dv-digital-flop canvas {
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,184 @@
<template>
<div class="dv-digital-flop">
<canvas ref="digital-flop" />
</div>
</template>
<script>
import CRender from '@jiaminghi/c-render'
import '@jiaminghi/charts/lib/extend/index'
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
export default {
name: 'DvDigitalFlop',
props: {
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
renderer: null,
defaultConfig: {
/**
* @description Number for digital flop
* @type {Array<Number>}
* @default number = []
* @example number = [10]
*/
number: [],
/**
* @description Content formatter
* @type {String}
* @default content = ''
* @example content = '{nt}个'
*/
content: '',
/**
* @description Number toFixed
* @type {Number}
* @default toFixed = 0
*/
toFixed: 0,
/**
* @description Text align
* @type {String}
* @default textAlign = 'center'
* @example textAlign = 'center' | 'left' | 'right'
*/
textAlign: 'center',
/**
* @description Text style configuration
* @type {Object} {CRender Class Style}
*/
style: {
fontSize: 30,
fill: '#3de7c9'
},
/**
* @description CRender animationCurve
* @type {String}
* @default animationCurve = 'easeOutCubic'
*/
animationCurve: 'easeOutCubic',
/**
* @description CRender animationFrame
* @type {String}
* @default animationFrame = 50
*/
animationFrame: 50
},
mergedConfig: null,
graph: null
}
},
watch: {
config () {
const { update } = this
update()
}
},
methods: {
init () {
const { initRender, mergeConfig, initGraph } = this
initRender()
mergeConfig()
initGraph()
},
initRender () {
const { $refs } = this
this.renderer = new CRender($refs['digital-flop'])
},
mergeConfig () {
const { defaultConfig, config } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
},
initGraph () {
const { getShape, getStyle, renderer, mergedConfig } = this
const { animationCurve, animationFrame } = mergedConfig
const shape = getShape()
const style = getStyle()
this.graph = renderer.add({
name: 'numberText',
animationCurve,
animationFrame,
shape,
style
})
},
getShape () {
const { number, content, toFixed, textAlign } = this.mergedConfig
const [w, h] = this.renderer.area
const position = [w / 2, h / 2]
if (textAlign === 'left') position[0] = 0
if (textAlign === 'right') position[0] = w
return {
number,
content,
toFixed,
position
}
},
getStyle () {
const { style, textAlign } = this.mergedConfig
return deepMerge(style, {
textAlign,
textBaseline: 'middle'
})
},
update () {
const { mergeConfig, mergeShape, getShape, getStyle, graph, mergedConfig } = this
mergeConfig()
if (!graph) return
const { animationCurve, animationFrame } = mergedConfig
const shape = getShape()
const style = getStyle()
mergeShape(graph, shape)
graph.animationCurve = animationCurve
graph.animationFrame = animationFrame
graph.animation('style', style, true)
graph.animation('shape', shape)
},
mergeShape (graph, shape) {
const cacheNum = graph.shape.number.length
const shapeNum = shape.number.length
if (cacheNum !== shapeNum) graph.shape.number = shape.number
}
},
mounted () {
const { init } = this
init()
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import FlylineChart from './src/main.vue'
export default function (Vue) {
Vue.component(FlylineChart.name, FlylineChart)
}

View File

@ -0,0 +1,12 @@
.dv-flyline-chart {
display: flex;
flex-direction: column;
background-size: 100% 100%;
}
.dv-flyline-chart polyline {
transition: all 0.3s;
}
.dv-flyline-chart text {
text-anchor: middle;
dominant-baseline: middle;
}

View File

@ -0,0 +1,492 @@
<template>
<div
class="dv-flyline-chart"
ref="dv-flyline-chart"
:style="`background-image: url(${mergedConfig ? mergedConfig.bgImgUrl : ''})`"
@click="consoleClickPos"
>
<svg v-if="mergedConfig" :width="width" :height="height">
<defs>
<radialGradient
:id="gradientId"
cx="50%" cy="50%" r="50%"
>
<stop
offset="0%" stop-color="#fff"
stop-opacity="1"
/>
<stop
offset="100%" stop-color="#fff"
stop-opacity="0"
/>
</radialGradient>
<radialGradient
:id="gradient2Id"
cx="50%" cy="50%" r="50%"
>
<stop
offset="0%" stop-color="#fff"
stop-opacity="0"
/>
<stop
offset="100%" stop-color="#fff"
stop-opacity="1"
/>
</radialGradient>
<circle
v-if="paths[0]"
:id="`circle${paths[0].toString()}`"
:cx="paths[0][2][0]"
:cy="paths[0][2][1]"
>
<animate
attributeName="r"
:values="`1;${mergedConfig.halo.radius}`"
:dur="mergedConfig.halo.duration / 10 + 's'"
repeatCount="indefinite"
/>
<animate
attributeName="opacity"
values="1;0"
:dur="mergedConfig.halo.duration / 10 + 's'"
repeatCount="indefinite"
/>
</circle>
</defs>
<image
v-if="paths[0]"
:xlink:href="mergedConfig.centerPointImg.url"
:width="mergedConfig.centerPointImg.width"
:height="mergedConfig.centerPointImg.height"
:x="paths[0][2][0] - mergedConfig.centerPointImg.width / 2"
:y="paths[0][2][1] - mergedConfig.centerPointImg.height / 2"
/>
<mask :id="`maskhalo${paths[0].toString()}`">
<use
v-if="paths[0]"
:xlink:href="`#circle${paths[0].toString()}`"
:fill="`url(#${gradient2Id})`"
/>
</mask>
<use
v-if="paths[0] && mergedConfig.halo.show"
:xlink:href="`#circle${paths[0].toString()}`"
:fill="mergedConfig.halo.color"
:mask="`url(#maskhalo${paths[0].toString()})`"
/>
<g
v-for="(path, i) in paths"
:key="i"
>
<defs>
<path
:id="`path${path.toString()}`"
:ref="`path${i}`"
:d="`M${path[0].toString()} Q${path[1].toString()} ${path[2].toString()}`"
fill="transparent"
/>
</defs>
<use
:xlink:href="`#path${path.toString()}`"
:stroke-width="mergedConfig.lineWidth"
:stroke="mergedConfig.orbitColor"
/>
<use
v-if="lengths[i]"
:xlink:href="`#path${path.toString()}`"
:stroke-width="mergedConfig.lineWidth"
:stroke="mergedConfig.flylineColor"
:mask="`url(#mask${unique}${path.toString()})`"
>
<animate
attributeName="stroke-dasharray"
:from="`0, ${lengths[i]}`"
:to="`${lengths[i]}, 0`"
:dur="times[i] || 0"
repeatCount="indefinite"
/>
</use>
<mask :id="`mask${unique}${path.toString()}`">
<circle cx="0" cy="0" :r="mergedConfig.flylineRadius" :fill="`url(#${gradientId})`">
<animateMotion
:dur="times[i] || 0"
:path="`M${path[0].toString()} Q${path[1].toString()} ${path[2].toString()}`"
rotate="auto"
repeatCount="indefinite"
/>
</circle>
</mask>
<image
:xlink:href="mergedConfig.pointsImg.url"
:width="mergedConfig.pointsImg.width"
:height="mergedConfig.pointsImg.height"
:x="path[0][0] - mergedConfig.pointsImg.width / 2"
:y="path[0][1] - mergedConfig.pointsImg.height / 2"
/>
<text
:style="`fontSize:${mergedConfig.text.fontSize}px;`"
:fill="mergedConfig.text.color"
:x="path[0][0] + mergedConfig.text.offset[0]"
:y="path[0][1] + mergedConfig.text.offset[1]"
>
{{ texts[i] }}
</text>
</g>
</svg>
</div>
</template>
<script>
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
import { randomExtend, getPointDistance } from '../../../util/index'
import autoResize from '../../../mixin/autoResize'
export default {
name: 'DvFlylineChart',
mixins: [autoResize],
props: {
config: {
type: Object,
default: () => ({})
},
dev: {
type: Boolean,
default: false
}
},
data () {
return {
ref: 'dv-flyline-chart',
unique: Math.random(),
maskId: `flyline-mask-id-${(new Date()).getTime()}`,
maskCircleId: `mask-circle-id-${(new Date()).getTime()}`,
gradientId: `gradient-id-${(new Date()).getTime()}`,
gradient2Id: `gradient2-id-${(new Date()).getTime()}`,
defaultConfig: {
/**
* @description Flyline chart center point
* @type {Array<Number>}
* @default centerPoint = [0, 0]
*/
centerPoint: [0, 0],
/**
* @description Flyline start points
* @type {Array<Array<Number>>}
* @default points = []
* @example points = [[10, 10], [100, 100]]
*/
points: [],
/**
* @description Flyline width
* @type {Number}
* @default lineWidth = 1
*/
lineWidth: 1,
/**
* @description Orbit color
* @type {String}
* @default orbitColor = 'rgba(103, 224, 227, .2)'
*/
orbitColor: 'rgba(103, 224, 227, .2)',
/**
* @description Flyline color
* @type {String}
* @default orbitColor = '#ffde93'
*/
flylineColor: '#ffde93',
/**
* @description K value
* @type {Number}
* @default k = -0.5
* @example k = -1 ~ 1
*/
k: -0.5,
/**
* @description Flyline curvature
* @type {Number}
* @default curvature = 5
*/
curvature: 5,
/**
* @description Flyline radius
* @type {Number}
* @default flylineRadius = 100
*/
flylineRadius: 100,
/**
* @description Flyline animation duration
* @type {Array<Number>}
* @default duration = [20, 30]
*/
duration: [20, 30],
/**
* @description Relative points position
* @type {Boolean}
* @default relative = true
*/
relative: true,
/**
* @description Back ground image url
* @type {String}
* @default bgImgUrl = ''
* @example bgImgUrl = './img/bg.jpg'
*/
bgImgUrl: '',
/**
* @description Text configuration
* @type {Object}
*/
text: {
/**
* @description Text offset
* @type {Array<Number>}
* @default offset = [0, 15]
*/
offset: [0, 15],
/**
* @description Text color
* @type {String}
* @default color = '#ffdb5c'
*/
color: '#ffdb5c',
/**
* @description Text font size
* @type {Number}
* @default fontSize = 12
*/
fontSize: 12
},
/**
* @description Halo configuration
* @type {Object}
*/
halo: {
/**
* @description Weather to show halo
* @type {Boolean}
* @default show = true
* @example show = true | false
*/
show: true,
/**
* @description Halo animation duration (10 = 1s)
* @type {Number}
* @default duration = 30
*/
duration: 30,
/**
* @description Halo color
* @type {String}
* @default color = '#fb7293'
*/
color: '#fb7293',
/**
* @description Halo max radius
* @type {Number}
* @default radius = 120
*/
radius: 120
},
/**
* @description Center point img configuration
* @type {Object}
*/
centerPointImg: {
/**
* @description Center point img width
* @type {Number}
* @default width = 40
*/
width: 40,
/**
* @description Center point img height
* @type {Number}
* @default height = 40
*/
height: 40,
/**
* @description Center point img url
* @type {String}
* @default url = ''
*/
url: ''
},
/**
* @description Points img configuration
* @type {Object}
* @default radius = 120
*/
pointsImg: {
/**
* @description Points img width
* @type {Number}
* @default width = 15
*/
width: 15,
/**
* @description Points img height
* @type {Number}
* @default height = 15
*/
height: 15,
/**
* @description Points img url
* @type {String}
* @default url = ''
*/
url: ''
}
},
mergedConfig: null,
paths: [],
lengths: [],
times: [],
texts: []
}
},
watch: {
config () {
const { calcData } = this
calcData()
}
},
methods: {
afterAutoResizeMixinInit () {
const { calcData } = this
calcData()
},
onResize () {
const { calcData } = this
calcData()
},
async calcData () {
const { mergeConfig, createFlylinePaths, calcLineLengths } = this
mergeConfig()
createFlylinePaths()
await calcLineLengths()
const { calcTimes, calcTexts } = this
calcTimes()
calcTexts()
},
mergeConfig () {
let { config, defaultConfig } = this
const mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
const { points } = mergedConfig
mergedConfig.points = points.map(item => {
if (item instanceof Array) {
return { position: item, text: '' }
}
return item
})
this.mergedConfig = mergedConfig
},
createFlylinePaths () {
const { getPath, mergedConfig, width, height } = this
let { centerPoint, points, relative } = mergedConfig
points = points.map(({ position }) => position)
if (relative) {
centerPoint = [width * centerPoint[0], height * centerPoint[1]]
points = points.map(([x, y]) => [width * x, height * y])
}
this.paths = points.map(point => getPath(centerPoint, point))
},
getPath (center, point) {
const { getControlPoint } = this
const controlPoint = getControlPoint(center, point)
return [point, controlPoint, center]
},
getControlPoint ([sx, sy], [ex, ey]) {
const { getKLinePointByx, mergedConfig } = this
const { curvature, k } = mergedConfig
const [mx, my] = [(sx + ex) / 2, (sy + ey) / 2]
const distance = getPointDistance([sx, sy], [ex, ey])
const targetLength = distance / curvature
const disDived = targetLength / 2
let [dx, dy] = [mx, my]
do {
dx += disDived
dy = getKLinePointByx(k, [mx, my], dx)[1]
} while (getPointDistance([mx, my], [dx, dy]) < targetLength)
return [dx, dy]
},
getKLinePointByx (k, [lx, ly], x) {
const y = ly - k * lx + k * x
return [x, y]
},
async calcLineLengths () {
const { $nextTick, paths, $refs } = this
await $nextTick()
this.lengths = paths.map((foo, i) => $refs[`path${i}`][0].getTotalLength())
},
calcTimes () {
const { duration, points } = this.mergedConfig
this.times = points.map(foo => randomExtend(...duration) / 10)
},
calcTexts () {
const { points } = this.mergedConfig
this.texts = points.map(({ text }) => text)
},
consoleClickPos ({ offsetX, offsetY }) {
const { width, height, dev } = this
if (!dev) return
const relativeX = (offsetX / width).toFixed(2)
const relativeY = (offsetY / height).toFixed(2)
console.warn(`dv-flyline-chart DEV: \n Click Position is [${offsetX}, ${offsetY}] \n Relative Position is [${relativeX}, ${relativeY}]`)
}
}
}
</script>

View File

@ -0,0 +1,6 @@
import './src/main.css'
import FullScreenContainer from './src/main.vue'
export default function (Vue) {
Vue.component(FullScreenContainer.name, FullScreenContainer)
}

Some files were not shown because too many files have changed in this diff Show More