├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── build
├── rollup.config.js
└── webpack.config.js
├── docs
├── .nojekyll
├── bar.md
├── bmap.md
├── event.md
├── favicon.ico
├── funnel.md
├── heatmap.md
├── histogram.md
├── index.html
├── install.md
├── line.md
├── map.md
├── pie.md
├── props-demo1.md
├── props-demo2.md
├── props.md
├── radar.md
├── ring.md
├── sankey.md
├── sidebar.md
├── skill-demo.md
├── start.md
├── style.css
├── toggle.md
└── waterfall.md
├── examples
├── App.vue
├── components
│ ├── code-section.vue
│ └── sidebar.vue
├── data
│ ├── bar.js
│ ├── chart.js
│ ├── funnel.js
│ ├── global.js
│ ├── heatmap.js
│ ├── histogram.js
│ ├── index.js
│ ├── line.js
│ ├── map.js
│ ├── pie.js
│ ├── radar.js
│ ├── ring.js
│ ├── sankey.js
│ └── waterfall.js
├── favicon.ico
├── index.html
├── main.js
├── pages
│ ├── bmap.vue
│ ├── chart.vue
│ ├── eventer.vue
│ ├── install.vue
│ ├── test.vue
│ └── toggle.vue
├── router.js
└── static
│ └── logo.png
├── package.json
├── src
├── component-list.js
├── components
│ ├── data-empty.vue
│ └── loading.vue
├── core.js
├── echarts-base.js
├── index.es.js
├── packages
│ ├── bar-mini
│ │ ├── index.js
│ │ └── main.js
│ ├── bar
│ │ ├── index.js
│ │ └── main.js
│ ├── bmap
│ │ ├── index.js
│ │ └── main.js
│ ├── chart
│ │ └── index.js
│ ├── funnel
│ │ ├── index.js
│ │ └── main.js
│ ├── heatmap
│ │ ├── index.js
│ │ └── main.js
│ ├── histogram-mini
│ │ └── index.js
│ ├── histogram
│ │ └── index.js
│ ├── index
│ │ └── index.js
│ ├── line-mini
│ │ ├── index.js
│ │ └── main.js
│ ├── line
│ │ ├── index.js
│ │ └── main.js
│ ├── map
│ │ ├── index.js
│ │ └── main.js
│ ├── pie
│ │ ├── index.js
│ │ └── main.js
│ ├── radar
│ │ ├── index.js
│ │ └── main.js
│ ├── ring
│ │ └── index.js
│ ├── sankey
│ │ ├── index.js
│ │ └── main.js
│ └── waterfall
│ │ ├── index.js
│ │ └── main.js
└── utils.js
├── test
├── index.js
├── karma.conf.js
└── load
│ ├── cdn
│ ├── all
│ │ └── index.html
│ ├── bmap
│ │ └── index.html
│ ├── heatmap
│ │ └── index.html
│ └── line
│ │ └── index.html
│ └── webpack
│ ├── all
│ ├── App.vue
│ ├── index.js
│ └── webpack.config.js
│ ├── css-part
│ ├── App.vue
│ ├── index.js
│ └── webpack.config.js
│ ├── esm
│ ├── App.vue
│ ├── index.js
│ └── webpack.config.js
│ ├── heatmap
│ ├── App.vue
│ ├── index.js
│ └── webpack.config.js
│ ├── index.html
│ └── line
│ ├── App.vue
│ ├── index.js
│ └── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["latest", {
4 | "es2015": { "modules": false }
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": ["transform-object-assign"]
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | lib/*
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | extends: 'standard',
13 | plugins: [
14 | 'html'
15 | ],
16 | rules: {
17 | 'no-mixed-operators': 'off'
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### Check List
2 | - [ ] Every Commit message is meaningful
3 | - [ ] Synchronized with the master branch
4 | - [ ] CI passed
5 | - [ ] Add suitable label
6 |
7 | #### What Changed
8 | -
9 |
10 | #### Breaking Change
11 | - [ ] Yes
12 | - [ ] No
13 |
14 | #### Document Update
15 | - [ ] Yes
16 | - [ ] No
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | umd
3 | node_modules
4 | dist
5 | npm-debug.log
6 | yarn-error.log
7 | lib
8 | docs/index.min.js
9 | docs/style.min.css
10 | .idea/
11 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | build
2 | examples
3 | docs
4 | .babelrc
5 | .eslintrc.js
6 | .travis.yml
7 | yarn.lock
8 | node_modules
9 | yarn-error.log
10 | npm-debug.log
11 | dist
12 | test
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 | branches:
5 | only:
6 | - master
7 | install:
8 | - yarn
9 | script:
10 | - npm run build
11 | - npm run test
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 西瓜
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # t-charts
2 |
3 | [](https://travis-ci.org/ElemeFE/v-charts)
4 | [](https://npmjs.org/package/v-charts)
5 | 
6 | [](https://www.npmjs.org/package/v-charts)
7 | 
8 | 
9 | [](https://gitter.im/ElemeFE/v-charts?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10 |
11 | 在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,t-charts的出现正是为了解决这个
12 | 痛点。基于Vue2.0和echarts封装的t-charts图表组件,只需要统一提供一种对前后端都友好的数据格式
13 | 设置简单的配置项,便可轻松生成常见的图表。
14 |
15 | ### 文档
16 |
17 | [https://talkingdata.github.io/t-charts/](https://talkingdata.github.io/t-charts/#/)
18 |
19 | ### 安装
20 | ---
21 |
22 | ```
23 | npm i t-charts -S
24 | ```
25 |
26 | ### 快速上手
27 | ---
28 |
29 | ```html
30 |
31 |
32 |
33 |
34 |
35 |
36 |
56 | ```
57 |
58 | ### LICENSE
59 | ---
60 |
61 | MIT
62 |
--------------------------------------------------------------------------------
/build/rollup.config.js:
--------------------------------------------------------------------------------
1 | const rollup = require('rollup')
2 | const vue = require('rollup-plugin-vue')
3 | const resolve = require('rollup-plugin-node-resolve')
4 | const babel = require('rollup-plugin-babel')
5 | const eslint = require('rollup-plugin-eslint')
6 | const componentInfo = require('../src/component-list')
7 | const uglify = require('rollup-plugin-uglify')
8 | const autoprefixer = require('autoprefixer')
9 | const cssnano = require('cssnano')
10 |
11 | let pkg = []
12 | const pkgTypeList = [
13 | { type: 'cjs', min: false, suffix: '.common.js' },
14 | { type: 'cjs', min: true, suffix: '.common.min.js' },
15 | { type: 'umd', min: false, suffix: '.js' },
16 | { type: 'umd', min: true, suffix: '.min.js' }
17 | ]
18 |
19 | pkgTypeList.forEach(({ type, min, suffix }) => {
20 | Object.keys(componentInfo).forEach(name => {
21 | const { src, dist } = componentInfo[name]
22 | pkg.push({
23 | min,
24 | type,
25 | suffix,
26 | globalName: name,
27 | src,
28 | dist
29 | })
30 | })
31 | })
32 |
33 | const addons = [
34 | {
35 | min: false,
36 | type: 'es',
37 | suffix: '.esm.js',
38 | globalName: '',
39 | src: 'src/index.es.js',
40 | dist: 'lib/index'
41 | }
42 | ]
43 | pkg = pkg.concat(addons)
44 |
45 | pkg.forEach(item => { rollupFn(item) })
46 |
47 | function rollupFn (item) {
48 | const vueSettings = item.min
49 | ? { css: 'lib/style.min.css', postcss: [autoprefixer, cssnano] }
50 | : { css: 'lib/style.css', postcss: [autoprefixer] }
51 |
52 | const plugins = [
53 | eslint({
54 | throwError: true,
55 | exclude: 'node_modules/**'
56 | }),
57 | vue(vueSettings),
58 | resolve({
59 | extensions: ['.js', '.vue']
60 | }),
61 | babel({
62 | exclude: 'node_modules/**',
63 | plugins: ['external-helpers']
64 | })
65 | ]
66 | if (item.min) plugins.push(uglify())
67 |
68 | rollup.rollup({
69 | entry: item.src,
70 | external: id => /^echarts/.test(id),
71 | plugins
72 | }).then(function (bundle) {
73 | const dest = item.dist + item.suffix
74 |
75 | bundle.write({
76 | format: item.type,
77 | moduleName: item.globalName,
78 | globals: {
79 | 'echarts/lib/echarts': 'echarts'
80 | },
81 | dest
82 | })
83 | }).catch((e) => {
84 | console.log(e)
85 | process.exit(1)
86 | })
87 | }
88 |
--------------------------------------------------------------------------------
/build/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const CopyWebpackPlugin = require('copy-webpack-plugin')
4 | const HtmlWebpackPlugin = require('html-webpack-plugin')
5 | const opn = require('opn')
6 |
7 | opn('http://localhost:8099')
8 | function resolve (dir) {
9 | return path.join(__dirname, '..', dir)
10 | }
11 |
12 | module.exports = {
13 | entry: {
14 | app: './examples/main.js'
15 | },
16 | output: {
17 | path: path.resolve(__dirname, '../dist'),
18 | filename: 'index.js',
19 | publicPath: '/'
20 | },
21 | resolve: {
22 | extensions: ['.js', '.vue'],
23 | alias: {
24 | 'vue$': 'vue/dist/vue.esm.js',
25 | '@': './src'
26 | }
27 | },
28 | devServer: {
29 | port: '8099',
30 | hot: true,
31 | contentBase: path.join(__dirname, 'dist'),
32 | stats: 'errors-only'
33 | },
34 | module: {
35 | rules: [
36 | {
37 | test: /\.(js|vue)$/,
38 | loader: 'eslint-loader',
39 | enforce: 'pre',
40 | include: [resolve('examples'), resolve('src')],
41 | options: {
42 | formatter: require('eslint-friendly-formatter')
43 | }
44 | },
45 | {
46 | test: /\.vue$/,
47 | loader: 'vue-loader',
48 | options: {
49 | sourceMap: true
50 | }
51 | },
52 | {
53 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
54 | loader: 'url-loader',
55 | options: {
56 | limit: 10000,
57 | name: 'img/[name].[hash:7].[ext]'
58 | }
59 | },
60 | {
61 | test: /\.js$/,
62 | loader: 'babel-loader',
63 | include: [resolve('./src'), resolve('./examples')]
64 | },
65 | {
66 | test: /\.css$/,
67 | use: [ 'style-loader', 'css-loader' ]
68 | }
69 | ]
70 | },
71 | plugins: [
72 | new CopyWebpackPlugin([
73 | {
74 | from: path.resolve(__dirname, '../examples/favicon.ico')
75 | }
76 | ]),
77 | new webpack.DefinePlugin({
78 | 'process.env': {
79 | NODE_ENV: '"development"'
80 | }
81 | }),
82 | new webpack.HotModuleReplacementPlugin(),
83 | new HtmlWebpackPlugin({
84 | filename: 'index.html',
85 | template: './examples/index.html',
86 | inject: true
87 | })
88 | ]
89 | }
90 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalkingData/t-charts/d553261687e19c92be2333421f74cb8e0fc86e4d/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/bar.md:
--------------------------------------------------------------------------------
1 | ### 条形图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 指定指标维度
8 |
9 |
10 |
11 |
37 |
38 |
39 | #### 排序条形图
40 |
41 |
42 |
43 |
72 |
73 |
74 | #### 条形轴配置双y轴
75 |
76 |
77 |
78 |
107 |
108 |
109 | #### 设置legend别名漏斗图
110 |
111 |
112 |
113 |
140 |
141 |
142 | #### 堆叠条形图
143 |
144 |
145 |
146 |
173 |
174 |
175 | #### 设置纵轴为连续的数值轴
176 |
177 |
178 |
179 |
204 |
205 |
206 | #### settings 配置项
207 |
208 | | 配置项 | 简介 | 类型 | 备注 |
209 | | --- | --- | --- | --- |
210 | | dimension | 维度 | Array | 默认columns第一项为维度 |
211 | | metrics | 指标 | Array | 默认columns第二项起为指标 |
212 | | xAxisType | 上下坐标轴数据类型 | Array | 可选值: KMB, normal, percent |
213 | | xAxisName | 上下坐标轴标题 | Array | - |
214 | | axisSite | 指标所在的轴 | Object | 默认不在top轴的指标都在bottom轴 |
215 | | stack | 堆叠选项 | Object | - |
216 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
217 | | dataOrder | 设置数据排序方式 | Boolean, Object | 默认为false |
218 | | scale | 是否是脱离 0 值比例 | Array | 默认为[false, false],表示左右
两个轴都不会脱离0值比例。
设置成 true 后坐标刻度不会
强制包含零刻度
|
219 | | min | 左右坐标轴最小值 | Array | - |
220 | | max | 左右坐标轴最大值 | Array | - |
221 | | labelMap | 设置指标的别名,同时作用于提示框和图例| Object | - |
222 | | legendName | 设置图表上方图例的别名 | Object | - |
223 | | label | 设置图形上的文本标签 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-bar.label) |
224 | | itemStyle | 图形样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-bar.itemStyle) |
225 | | yAxisType | 纵轴的类型 | String | 可选值'category','value',默认为'category' |
226 | | opacity | 透明度 | Number | - |
227 |
228 | > 备注1. axisSite 可以设置 top 和 bottom,例如示例所示 `axisSite: { top: ['占比'] }` 即将占比的数据置于上轴上。
229 |
230 | > 备注2. stack 用于将两数据堆叠起来,例如实例中所示`stack: { '销售额': ['销售额-1季度', '销售额-2季度'] }` 即将'销售额-1季度', '销售额-2季度'相应的数据堆叠在一起。
231 |
232 | > 备注3. dataOrder 用于设置数据的排序方式,用于更加清晰的展示数据的升降。例如: `{ label: '成本', order: 'asc }` 表示数据按照成本指标升序展示,降序为`desc`。
233 |
234 | > 备注4. min和max的值可以直接设置为数字,例如:`[100, 300]`;也可以设置为`['dataMin', 'dataMin']`, `['dataMax', 'dataMax']`,此时表示使用该坐标轴上的最小值或最大值为最小或最大刻度。
235 |
236 | > 备注5. 为了优化连续的数值型横轴显示多指标的时候样式,在此情况下默认设置opacity为0.5。
237 |
--------------------------------------------------------------------------------
/docs/bmap.md:
--------------------------------------------------------------------------------
1 | ### 百度地图
2 |
3 | 为了使在echarts上更简单的使用百度地图,t-charts封装了一个百度地图的‘壳子’,在settings中添加
4 | 关于图表的配置(key,bmap),在组件上直接设置 series, tooltip 等,便可生成以百度地图为坐标系
5 | 的 Echarts 图表。
6 |
7 | #### 示例
8 |
9 | ##### 简单地图
10 |
11 |
12 |
13 | #### 获取地图实例
14 |
15 |
16 |
17 |
18 | #### settings 配置项
19 |
20 | | 配置项 | 简介 | 类型 | 备注 |
21 | | --- | --- | --- | --- |
22 | | key | 百度地图 access_key | String | 可[由此](http://lbsyun.baidu.com/apiconsole/key)获取 |
23 | | bmap | 百度地图配置项 | Object | 参考[文档](https://github.com/ecomfe/echarts/tree/master/extension/bmap#使用)配置 |
24 |
25 | > 备注:百度地图在与其他地图搭配使用时,需要额外引入相应的 echarts 模块,例如使用热力图,则需
26 | 要`import 'echarts/lib/chart/heatmap'`。
27 |
--------------------------------------------------------------------------------
/docs/event.md:
--------------------------------------------------------------------------------
1 | ### 事件监听
2 |
3 | #### 示例
4 |
5 |
6 |
7 | 绑定事件通过传递一个带绑定事件和对应回调函数的对象实现,回调函数内的参数是点击部分,可以据此做相应的处理
8 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalkingData/t-charts/d553261687e19c92be2333421f74cb8e0fc86e4d/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/funnel.md:
--------------------------------------------------------------------------------
1 | ### 漏斗图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 指定指标维度
8 |
9 |
10 |
11 |
35 |
36 |
37 | #### 定制顺序漏斗图
38 |
39 |
40 |
41 |
64 |
65 |
66 | #### 指定数据类型漏斗图
67 |
68 |
69 |
70 |
93 |
94 |
95 | #### 修改legend别名漏斗图
96 |
97 |
98 |
99 |
124 |
125 |
126 | #### 金字塔
127 |
128 |
129 |
130 |
153 |
154 |
155 | #### settings 配置项
156 |
157 | | 配置项 | 简介 | 类型 | 备注 |
158 | | --- | --- | --- | --- |
159 | | dimension | 维度 | String | 默认columns第一项为维度 |
160 | | metrics | 指标 | String | 默认columns第二项为指标 |
161 | | dataType | 数据类型 | String | 可选值: KMB, normal, percent |
162 | | sequence | 数据显示顺序 | Array | 默认按照数据大小顺序 |
163 | | ascending | 是否显示为金字塔 | Boolean | 默认为false |
164 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
165 | | label | 设置文本标签样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-funnel.label) |
166 | | labelLine | 设置标签的视觉引导线样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-funnel.labelLine) |
167 | | itemStyle | 设置图形样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-funnel.itemStyle) |
168 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | t-charts
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
24 |
25 |
26 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/docs/install.md:
--------------------------------------------------------------------------------
1 | ### 安装
2 |
3 | #### npm安装
4 |
5 | ```
6 | npm i t-charts -S
7 | ```
8 |
9 | #### cdn
10 |
11 | ```html
12 |
13 |
14 |
15 | ```
16 |
17 | #### 示例
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/props-demo1.md:
--------------------------------------------------------------------------------
1 | ### 属性配置示例(1)
2 |
3 | #### 隐藏提示框与图例
4 |
5 |
6 |
7 |
33 |
34 |
35 | #### 设置图表容器样式
36 |
37 |
38 |
39 |
71 |
72 |
73 | #### 设置图表标线与标点
74 |
75 |
76 |
77 |
122 |
123 |
124 | #### 设置视觉映射组件
125 |
126 |
127 |
128 |
169 |
170 |
171 | #### 设置区域缩放组件
172 |
173 |
174 |
175 |
209 |
210 |
211 | #### 设置工具箱
212 |
213 |
214 |
215 |
248 |
249 |
250 | #### 修改颜色列表
251 |
252 |
253 |
254 |
280 |
281 |
282 |
--------------------------------------------------------------------------------
/docs/props-demo2.md:
--------------------------------------------------------------------------------
1 | ### 属性配置示例(2)
2 |
3 | #### 设置extend配置项
4 |
5 |
6 |
7 |
56 |
57 |
58 | #### 设置afterConfig函数
59 |
60 |
61 |
62 |
95 |
96 |
97 | #### 设置加载状态
98 |
99 |
100 |
101 |
131 |
132 |
133 | #### 设置暂无数据状态
134 |
135 |
136 |
137 |
160 |
161 |
162 | #### 增加自定义内容
163 |
164 |
165 |
166 |
202 |
203 |
--------------------------------------------------------------------------------
/docs/props.md:
--------------------------------------------------------------------------------
1 | ### t-charts属性
2 |
3 | ##### t-charts 的属性分为两种,一种是全部图表都具有的属性,例如 `colors`, `grid` 等
4 |
5 | ``
6 |
7 | 这样的属性有
8 |
9 | | 配置项 | 简介 | 类型 | 备注 |
10 | | --- | --- | --- | --- |
11 | | data | 图表数据 | Object | columns 代表指标和维度名称,
rows 为数据内容 |
12 | | width | 图表宽度 | String | 默认 auto |
13 | | height | 图表高度 | String | 默认 400px |
14 | | settings | 图表配置项 | Object | 内容参考图表具体的配置 |
15 | | colors | 颜色列表 | Array | 默认
`['#19d4ae', '#5ab1ef', '#fa6e86',`
` '#ffb980', '#0067a6', '#c4b4e4',`
` '#d87a80', '#9cbbff', '#d9d0c7',`
` '#87a997', '#d49ea2', '#5b4947']` |
16 | | tooltip-visible | 是否显示提示框 | Boolean | 默认为 true |
17 | | legend-visible | 是否显示图例 | Boolean | 默认为 true |
18 | | legend-position | 图例显示位置 | String | 可选`'left', 'top', 'right', 'bottom'` |
19 | | grid | 网格配置 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#grid) |
20 | | events | 为图表绑定事件 | Object | 内容为包含事件名-事件处理函数的对象 |
21 | | before-config | 对数据提前进行额外的处理 | Function | 在数据转化为配置项开始前触发
参数为 data,返回值为表格数据 |
22 | | after-config | 对生成好的echarts配置
进行额外的处理 | Function | 在数据转化为配置项结束后触发
参数为 options,返回值为 echarts 配置 |
23 | | after-set-option | 生成图后获取echarts实例 | Function | 参数为echarts实例 |
24 | | after-set-option-once | 生成图后获取echarts实例(只执行一次) | Function | 参数为echarts实例 |
25 | | mark-line | 图表标线 | Object | 配置项内容对应echarts中
关于markLine的部分
使用时需额外引入对应模块
`'echarts/lib/component/markLine'` |
26 | | mark-point | 图表标点 | Object | 配置项内容对应echarts中
关于markPoint的部分
使用时需额外引入对应模块
`'echarts/lib/component/markPoint'` |
27 | | mark-area | 图表标志区域 | Object | 配置项内容对应echarts中
关于markArea的部分
使用时需额外引入对应模块
`'echarts/lib/component/markAreae'` |
28 | | visual-map | 视觉映射组件 | Array, Object | 内容参考[文档](http://echarts.baidu.com/option.html#visualMap)
使用时需额外引入对应模块
`'echarts/lib/component/visualMap'` |
29 | | data-zoom | 区域缩放组件 | Array, Object | 内容参考[文档](http://echarts.baidu.com/option.html#dataZoom)
使用时需额外引入对应模块
`'echarts/lib/component/dataZoom'` |
30 | | toolbox | 工具箱 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#toolbox)
使用时需额外引入对应模块
`'echarts/lib/component/toolbox'` |
31 | | title | 图表标题 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#title)
使用时需额外引入对应模块
`'echarts/lib/component/title'` |
32 | | init-options | init 附加参数 | Object | 内容参考[文档](http://echarts.baidu.com/api.html#echarts.init) |
33 | | theme | 自定义主题 | Object | 内容为自定义主题参数 |
34 | | theme-name | 自定义主题名称 | String | 内容为全局注册的自定义主题名称 |
35 | | loading | 加载状态 | Boolean | 默认为false |
36 | | data-empty | 暂无数据状态 | Boolean | 默认为false |
37 | | judge-width | 是否处理生成图表时的宽度问题 | Boolean | 默认为 true |
38 | | width-change-delay | 容器宽度变化的延迟 | Number | 默认为300 |
39 |
40 | > 备注:使用loading和dataEmpty属性前需引入css `import 't-charts/lib/style.css'`
41 |
42 | 同时,为了能够更方便的设置属性配置项等,可以通过`extend`属性实现对已配置好的内部属性进行单独的设置,`extend`为对象类型,对象内的属性可以是函数,也可以对象,也可以是其他类型的值
43 | - 当属性为函数时,设置的是函数的返回值
44 | - 当属性为对象时,如果在options中对应的属性为对象(eg: tooltip)或包含对象的数组(eg: series),对应的配置会被合并,否则将直接覆盖对应的配置
45 |
46 | 具体使用方法可以参考下面的属性配置示例
47 |
48 | 最后,下面这些与echarts配置项对应的属性也被加到了组件上,设置后将会直接覆盖options原有的对应属性,使用方式可参考[文档](http://echarts.baidu.com/option.html)
49 | ```
50 | legend: Object
51 | xAxis: Object
52 | yAxis: Object
53 | radar: Object
54 | tooltip: Object
55 | axisPointer: Object
56 | brush: Object
57 | geo: Object
58 | timeline: Object
59 | graphic: Object
60 | series: [Object, Array]
61 | backgroundColor: [Object, String]
62 | textStyle: Object
63 | ```
64 |
65 | > 备注:如果某属性加上去之后没有生效,很可能是没有引入相应的模块,模块的位置可以参考此[文件](https://github.com/ecomfe/echarts/blob/master/index.js)
66 |
67 |
68 | ##### 另外一种是图表自身的属性,比如用户设置数据类型的`dataType`,这样的属性被置于settings内,每种图表的配置项不完全相同,具体参数参考下述图表文档中的配置项
69 |
70 | ### 示例
71 |
72 |
73 |
--------------------------------------------------------------------------------
/docs/radar.md:
--------------------------------------------------------------------------------
1 | ### 雷达图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 设置显示的指标维度
8 |
9 |
10 |
11 |
38 |
39 |
40 | #### 修改指标名称
41 |
42 |
43 |
44 |
75 |
76 |
77 | #### settings 配置项
78 |
79 | | 配置项 | 简介 | 类型 | 备注 |
80 | | --- | --- | --- | --- |
81 | | dimension | 维度 | String | 默认columns第一项为维度 |
82 | | metrics | 指标 | String | 默认columns第二项起为指标 |
83 | | dataType | 数据类型 | Object | 可选值: KMB, normal, percent |
84 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
85 | | label | 图形上的文本标签 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-radar.label) |
86 | | itemStyle | 折线拐点标志的样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-radar.itemStyle) |
87 | | lineStyle | 线条样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-radar.lineStyle) |
88 | | areaStyle | 区域填充样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-radar.areaStyle) |
89 |
90 |
91 | > 备注:dataType中直接设置对应维度的数据类型,例如示例的`{ '占比': 'percent' }`,即将占比数据设置为百分比类型
92 |
--------------------------------------------------------------------------------
/docs/ring.md:
--------------------------------------------------------------------------------
1 | ### 环图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 设置指标维度
8 |
9 |
10 |
11 |
37 |
38 |
39 | #### 玫瑰图
40 |
41 |
42 |
43 |
68 |
69 |
70 | #### 限制显示条数环图
71 |
72 |
73 |
74 |
104 |
105 |
106 | #### 设置数据类型
107 |
108 |
109 |
110 |
135 |
136 |
137 | #### 设置环图半径
138 |
139 |
140 |
141 |
167 |
168 |
169 | #### settings 配置项
170 |
171 | | 配置项 | 简介 | 类型 | 备注 |
172 | | --- | --- | --- | --- |
173 | | dimension | 维度 | String | 默认columns第一项为维度 |
174 | | metrics | 指标 | String | 默认columns第二项为指标 |
175 | | dataType | 数据类型 | String | 可选值: KMB, normal, percent |
176 | | legendLimit | legend显示数量限制 | Number | legend数量过多会导致环图样式错误,限制legend最大值并且当超过此值时,隐藏legend可以解决这个问题 |
177 | | selectedMode | 选中模式 | String | 可选值:single, multiple,默认为false |
178 | | hoverAnimation | 是否开启 hover 在扇区上的放大动画效果 | Boolean | 默认值为true |
179 | | radius | 环图外半径与内半径 | Array | - |
180 | | offsetY | 纵向偏移量 | Number | - |
181 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
182 | | roseType | 显示为南丁格尔玫瑰图 | String | 默认不展示为南丁格尔玫瑰图,可设置为`'radius', 'area'` |
183 | | label | 环图图形上的文本标签 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-pie.label) |
184 | | labelLine | 标签的视觉引导线样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-pie.labelLine) |
185 | | itemStyle | 图形样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-pie.itemStyle) |
186 | | limitShowNum | 设置超过此数字时使用‘其他’代替 | Number | 此时数据会按照由大到小顺序显示 |
187 |
--------------------------------------------------------------------------------
/docs/sankey.md:
--------------------------------------------------------------------------------
1 | ### 桑基图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 设置数据类型
8 |
9 |
10 |
11 |
45 |
46 |
47 |
48 |
49 | #### settings 配置项
50 |
51 | | 配置项 | 简介 | 类型 | 备注 |
52 | | --- | --- | --- | --- |
53 | | dimension | 维度 | String | 默认columns第一项为维度 |
54 | | metrics | 指标 | String | 默认columns第二项为指标 |
55 | | dataType | 数据类型 | Array | 数组的第一项为item的数据类型,
第二项为line的数据类型,
可选值: KMB, normal, percent |
56 | | links | 节点间的关系数据 | Array | 内容参考[文档](http://echarts.baidu.com/option.html#series-sankey.links) |
57 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
58 | | label | 每个矩形节点中文本标签的样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-sankey.label) |
59 | | itemStyle | 节点矩形的样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-sankey.itemStyle) |
60 | | lineStyle | 桑基图边的样式 | Object | 内容参考[文档](http://echarts.baidu.com/option.html#series-sankey.lineStyle) |
61 |
--------------------------------------------------------------------------------
/docs/sidebar.md:
--------------------------------------------------------------------------------
1 | - 介绍
2 | - [安装](/)
3 | - [开始使用](/start)
4 | - [图表属性](/props)
5 | - 图表
6 | - [折线图](/line)
7 | - [柱状图](/histogram)
8 | - [条形图](/bar)
9 | - [饼图](/pie)
10 | - [环图](/ring)
11 | - [瀑布图](/waterfall)
12 | - [漏斗图](/funnel)
13 | - [雷达图](/radar)
14 | - [地图](/map)
15 | - [桑基图](/sankey)
16 | - [热力图](/heatmap)
17 | - 其他
18 | - [事件监听](/event)
19 | - [图表切换](/toggle)
20 | - [百度地图](/bmap)
21 | - [属性配置示例(1)](/props-demo1)
22 | - [属性配置示例(2)](/props-demo2)
23 | - [常见问题示例](/skill-demo)
24 |
--------------------------------------------------------------------------------
/docs/skill-demo.md:
--------------------------------------------------------------------------------
1 | ### 常见问题示例
2 |
3 | #### 容器的初始宽度未知
4 |
5 | 在一个初始宽度未知的容器内绘制图表时,因为无法获取宽度,所以图表会绘制失败,解决的办法是在容器宽度已知后,
6 | 调用echarts的resize方法。
7 |
8 |
9 |
10 |
57 |
58 |
59 | #### 小数显示精度
60 |
61 | t-charts处理数据类型时默认保留两位有效数字,但是当数字较小并设置为百分比类型时,这种方式会导致显示上的问题,例如
62 |
63 |
64 |
65 |
91 |
92 |
93 | 每个图表内都有digit配置项,设置此属性,保证设置类型后,数值较小也能够正常显示
94 |
95 |
96 |
97 |
124 |
125 |
--------------------------------------------------------------------------------
/docs/start.md:
--------------------------------------------------------------------------------
1 | ## t-charts
2 |
3 | 在使用 echarts 生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,t-charts 的出现正是为了解决这个痛点。基于 Vue2.0 和 echarts 封装的 t-charts 图表组件,只需要统一提供一种对前后端都友好的数据格式设置简单的配置项,便可轻松生成常见的图表。
4 |
5 | t-charts 已经处理了关于echarts依赖引入的问题,保证所使用的图表,都是最小的文件。
6 |
7 | ### 引入t-charts
8 |
9 | #### 完整引入
10 | -----
11 |
12 | ```js
13 | // main.js
14 | import Vue from 'vue'
15 | import VCharts from 't-charts'
16 | import App from './App.vue'
17 |
18 | Vue.use(VCharts)
19 |
20 | new Vue({
21 | el: '#app',
22 | render: h => h(App)
23 | })
24 | ```
25 |
26 | #### 按需引入
27 | -----
28 |
29 | t-charts的每种图表组件,都单独打包到lib文件夹下
30 | ```
31 | |- lib/
32 | |- line.js -------------- 折线图
33 | |- bar.js --------------- 条形图
34 | |- histogram.js --------- 柱状图
35 | |- pie.js --------------- 饼图
36 | |- ring.js -------------- 环图
37 | |- funnel.js ------------ 漏斗图
38 | |- waterfall.js --------- 瀑布图
39 | |- radar.js ------------- 雷达图
40 | |- map.js --------------- 地图
41 | |- bmap.js -------------- 百度地图
42 | ```
43 | 使用时,可以直接将单个图表引入到项目中
44 | ```js
45 | import Vue from 'vue'
46 | import VeLine from 't-charts/lib/line'
47 | import App from './App.vue'
48 |
49 | Vue.component(VeLine.name, VeLine)
50 |
51 | new Vue({
52 | el: '#app',
53 | render: h => h(App)
54 | })
55 | ```
56 |
--------------------------------------------------------------------------------
/docs/style.css:
--------------------------------------------------------------------------------
1 | iframe {
2 | border: 2px solid #eee;
3 | }
4 |
5 | .vuep {
6 | height: 460px;
7 | }
8 |
9 | .cm-error {
10 | color: rgba(255, 83, 112, 1) !important;
11 | background-color: inherit !important;
12 | }
13 |
14 | .data-empty {
15 | position: absolute;
16 | left: 0;
17 | right: 0;
18 | top: 0;
19 | bottom: 0;
20 | display: flex;
21 | justify-content: center;
22 | align-items: center;
23 | background-color: rgba(255, 255, 255, .7);
24 | color: #888;
25 | font-size: 14px;
26 | }
27 |
--------------------------------------------------------------------------------
/docs/toggle.md:
--------------------------------------------------------------------------------
1 | ### 图表切换
2 |
3 | #### 示例
4 |
5 |
6 |
7 | 为了方便使用一份数据即可生成不同的表格,可以使用``组件,切换图表类型则只需要改变settings即可
8 |
--------------------------------------------------------------------------------
/docs/waterfall.md:
--------------------------------------------------------------------------------
1 | ### 瀑布图
2 |
3 | #### 示例
4 |
5 |
6 |
7 | #### 设置指标维度
8 |
9 |
10 |
11 |
34 |
35 |
36 | #### 设置数据类型
37 |
38 |
39 |
40 |
62 |
63 |
64 | #### 修改指标名称
65 |
66 |
67 |
68 |
92 |
93 |
94 | #### 设置 总计、剩余 的名称
95 |
96 |
97 |
98 |
122 |
123 |
124 | #### settings 配置项
125 |
126 | | 配置项 | 简介 | 类型 | 备注 |
127 | | --- | --- | --- | --- |
128 | | dimension | 维度 | String | 默认columns第一项为维度 |
129 | | metrics | 指标 | String | 默认columns第二项为指标 |
130 | | dataType | 数据类型 | String | 可选值: KMB, normal, percent |
131 | | totalNum | 总量 | Number | 默认瀑布图总量为所有数据的和 |
132 | | totalName | 总量的显示文案 | String | 默认显示总计 |
133 | | remainName | 剩余的显示文案 | String | 默认显示其他 |
134 | | digit | 设置数据类型为percent时保留的位数 | Number | 默认为2 |
135 |
--------------------------------------------------------------------------------
/examples/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
27 |
28 |
75 |
--------------------------------------------------------------------------------
/examples/components/code-section.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
32 |
33 |
39 |
--------------------------------------------------------------------------------
/examples/components/sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
42 |
43 |
90 |
--------------------------------------------------------------------------------
/examples/data/bar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '条形图',
3 | type: 'bar',
4 | data: [
5 | {
6 | name: '简单条形图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': '1-1', '余额': 123, '年龄': 3 },
11 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
12 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
13 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
14 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
15 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
16 | ]
17 | },
18 | settings: {}
19 | },
20 | {
21 | name: '排序条形图',
22 | data: {
23 | columns: ['日期', '余额', '年龄'],
24 | rows: [
25 | { '日期': '1-1', '余额': 123, '年龄': 3 },
26 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
27 | { '日期': '1-3', '余额': 2123, '年龄': 90 },
28 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
29 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
30 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
31 | ]
32 | },
33 | settings: {
34 | metrics: ['年龄'],
35 | dataOrder: {
36 | label: '年龄',
37 | order: 'desc'
38 | }
39 | }
40 | },
41 | {
42 | name: '带有较小百分比数值',
43 | data: {
44 | columns: ['日期', '比率'],
45 | rows: [
46 | { '日期': '1-1', '余额': 123, '比率': 0.00001 },
47 | { '日期': '1-2', '余额': 1223, '比率': 0.00002 },
48 | { '日期': '1-3', '余额': 2123, '比率': 0.00003 },
49 | { '日期': '1-4', '余额': 4123, '比率': 0.00007 },
50 | { '日期': '1-5', '余额': 3123, '比率': 0.00001 },
51 | { '日期': '1-6', '余额': 7123, '比率': 0.00003 }
52 | ]
53 | },
54 | settings: {
55 | xAxisType: ['percent'],
56 | digit: 4
57 | }
58 | },
59 | {
60 | name: '坐标轴配置',
61 | data: {
62 | columns: ['日期', '余额', '年龄'],
63 | rows: [
64 | { '日期': '1-1', '余额': 123, '年龄': 3 },
65 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
66 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
67 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
68 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
69 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
70 | ]
71 | },
72 | settings: {
73 | xAxisType: ['KMB', 'percent'],
74 | xAxisName: ['余额', '年龄'],
75 | axisSite: {
76 | top: ['年龄']
77 | }
78 | }
79 | },
80 | {
81 | name: '复杂坐标轴配置',
82 | data: {
83 | columns: ['日期', 'a', 'b', 'c'],
84 | rows: [
85 | { '日期': '1-1', 'a': 123, 'b': 3, c: 1 },
86 | { '日期': '1-2', 'a': 1223, 'b': 6, c: 1 },
87 | { '日期': '1-3', 'a': 2123, 'b': 9, c: 1 },
88 | { '日期': '1-4', 'a': 4123, 'b': 12, c: 1 },
89 | { '日期': '1-5', 'a': 3123, 'b': 15, c: 1 },
90 | { '日期': '1-6', 'a': 7123, 'b': 20, c: 1 }
91 | ]
92 | },
93 | settings: {
94 | axisSite: {
95 | top: ['a'],
96 | bottom: ['b']
97 | }
98 | }
99 | },
100 | {
101 | name: '指标维度配置',
102 | data: {
103 | columns: ['日期', '余额', '年龄'],
104 | rows: [
105 | { '日期': '1-1', '余额': 123, '年龄': 3 },
106 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
107 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
108 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
109 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
110 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
111 | ]
112 | },
113 | settings: {
114 | dimension: ['余额'],
115 | metrics: ['年龄']
116 | }
117 | },
118 | {
119 | name: '堆叠条形图',
120 | data: {
121 | columns: ['日期', '余额', '年龄'],
122 | rows: [
123 | { '日期': '1-1', '余额': 123, '年龄': 3 },
124 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
125 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
126 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
127 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
128 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
129 | ]
130 | },
131 | settings: {
132 | stack: {
133 | 'xxx': ['余额', '年龄']
134 | }
135 | }
136 | }
137 | ]
138 | }
139 |
--------------------------------------------------------------------------------
/examples/data/chart.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '图',
3 | type: 'chart',
4 | data: [
5 | {
6 | name: '折线图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': 1, '余额': 123, '年龄': 3 },
11 | { '日期': 2, '余额': 1223, '年龄': 6 },
12 | { '日期': 3, '余额': 2123, '年龄': 9 },
13 | { '日期': 4, '余额': 4123, '年龄': 12 },
14 | { '日期': 5, '余额': 3123, '年龄': 15 },
15 | { '日期': 6, '余额': 7123, '年龄': 20 }
16 | ]
17 | },
18 | settings: {
19 | type: 'line'
20 | }
21 | },
22 | {
23 | name: '柱状图',
24 | data: {
25 | columns: ['日期', '余额', '年龄'],
26 | rows: [
27 | { '日期': 1, '余额': 123, '年龄': 3 },
28 | { '日期': 2, '余额': 1223, '年龄': 6 },
29 | { '日期': 3, '余额': 2123, '年龄': 9 },
30 | { '日期': 4, '余额': 4123, '年龄': 12 },
31 | { '日期': 5, '余额': 3123, '年龄': 15 },
32 | { '日期': 6, '余额': 7123, '年龄': 20 }
33 | ]
34 | },
35 | settings: {
36 | type: 'histogram'
37 | }
38 | },
39 | {
40 | name: '饼图',
41 | data: {
42 | columns: ['日期', '余额', '年龄'],
43 | rows: [
44 | { '日期': 1, '余额': 123, '年龄': 3 },
45 | { '日期': 2, '余额': 1223, '年龄': 6 },
46 | { '日期': 3, '余额': 2123, '年龄': 9 },
47 | { '日期': 4, '余额': 4123, '年龄': 12 },
48 | { '日期': 5, '余额': 3123, '年龄': 15 },
49 | { '日期': 6, '余额': 7123, '年龄': 20 }
50 | ]
51 | },
52 | settings: {
53 | type: 'pie'
54 | }
55 | }
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/examples/data/funnel.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '漏斗图',
3 | type: 'funnel',
4 | data: [
5 | {
6 | name: '简单漏斗图',
7 | data: {
8 | columns: ['状态', '数值'],
9 | rows: [
10 | { '状态': '展示', '数值': 900 },
11 | { '状态': '访问', '数值': 600 },
12 | { '状态': '点击', '数值': 300 },
13 | { '状态': '订单', '数值': 100 }
14 | ]
15 | },
16 | settings: {}
17 | },
18 | {
19 | name: '定制维度顺序',
20 | data: {
21 | columns: ['状态', '数值'],
22 | rows: [
23 | { '状态': '展示', '数值': 900 },
24 | { '状态': '访问', '数值': 600 },
25 | { '状态': '点击', '数值': 300 },
26 | { '状态': '订单', '数值': 100 }
27 | ]
28 | },
29 | settings: {
30 | sequence: ['订单', '点击', '访问', '展示']
31 | }
32 | },
33 | {
34 | name: '数据类型配置',
35 | data: {
36 | columns: ['状态', '数值'],
37 | rows: [
38 | { '状态': '展示', '数值': 0.9 },
39 | { '状态': '访问', '数值': 0.6 },
40 | { '状态': '点击', '数值': 0.3 },
41 | { '状态': '订单', '数值': 0.00001 }
42 | ]
43 | },
44 | settings: {
45 | dataType: 'percent',
46 | digit: 4
47 | }
48 | },
49 | {
50 | name: '金字塔',
51 | data: {
52 | columns: ['状态', '数值'],
53 | rows: [
54 | { '状态': '展示', '数值': 900 },
55 | { '状态': '访问', '数值': 600 },
56 | { '状态': '点击', '数值': 300 },
57 | { '状态': '订单', '数值': 100 }
58 | ]
59 | },
60 | settings: {
61 | ascending: true
62 | }
63 | },
64 | {
65 | name: '指标维度配置',
66 | data: {
67 | columns: ['状态', '状态1', '数值'],
68 | rows: [
69 | { '状态': '展示', '状态1': '展示1', '数值': 900 },
70 | { '状态': '访问', '状态1': '访问1', '数值': 600 },
71 | { '状态': '点击', '状态1': '点击1', '数值': 300 },
72 | { '状态': '订单', '状态1': '订单1', '数值': 100 }
73 | ]
74 | },
75 | settings: {
76 | dimension: '状态1',
77 | metrics: '数值'
78 | }
79 | },
80 | {
81 | name: '样式配置',
82 | data: {
83 | columns: ['状态', '状态1', '数值'],
84 | rows: [
85 | { '状态': '展示', '状态1': '展示1', '数值': 900 },
86 | { '状态': '访问', '状态1': '访问1', '数值': 600 },
87 | { '状态': '点击', '状态1': '点击1', '数值': 300 },
88 | { '状态': '订单', '状态1': '订单1', '数值': 100 }
89 | ]
90 | },
91 | settings: {
92 | dimension: '状态1',
93 | metrics: '数值',
94 | label: {
95 | normal: {
96 | show: true,
97 | color: '#00f'
98 | }
99 | }
100 | }
101 | },
102 | {
103 | name: '设置legend别名漏斗图',
104 | data: {
105 | columns: ['状态', '数值'],
106 | rows: [
107 | { '状态': '展示', '数值': 0.9 },
108 | { '状态': '访问', '数值': 0.6 },
109 | { '状态': '点击', '数值': 0.3 },
110 | { '状态': '订单', '数值': 0.00001 }
111 | ]
112 | },
113 | settings: {
114 | legendName: {
115 | '订单': '订单biubiu~'
116 | }
117 | }
118 | }
119 | ]
120 | }
121 |
--------------------------------------------------------------------------------
/examples/data/global.js:
--------------------------------------------------------------------------------
1 | export default {
2 | data: {
3 | columns: ['日期', '余额', '年龄'],
4 | rows: [
5 | { '日期': '1-1', '余额': 123, '年龄': 3 },
6 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
7 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
8 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
9 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
10 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
11 | ]
12 | },
13 | grid: { left: 20, right: 20, top: 20, bottom: 20 },
14 | colors: ['#eee', '#222', '#333', '#444'],
15 | scale: { x: true, y: true }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/data/heatmap.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '热力图',
3 | type: 'heatmap',
4 | data: [
5 | {
6 | name: '简单热力图',
7 | data: {
8 | columns: ['时间', '地点', '人数'],
9 | rows: [
10 | { '时间': '星期一', '地点': '北京', '人数': 1000 },
11 | { '时间': '星期二', '地点': '上海', '人数': 400 },
12 | { '时间': '星期三', '地点': '杭州', '人数': 800 },
13 | { '时间': '星期二', '地点': '深圳', '人数': 200 },
14 | { '时间': '星期三', '地点': '长春', '人数': 100 },
15 | { '时间': '星期五', '地点': '南京', '人数': 300 },
16 | { '时间': '星期四', '地点': '江苏', '人数': 800 },
17 | { '时间': '星期一', '地点': '北京', '人数': 700 },
18 | { '时间': '星期三', '地点': '上海', '人数': 300 },
19 | { '时间': '星期二', '地点': '杭州', '人数': 500 }
20 | ]
21 | }
22 | },
23 | {
24 | name: '配置坐标轴显示内容',
25 | data: {
26 | columns: ['时间', '地点', '人数'],
27 | rows: [
28 | { '时间': '星期一', '地点': '北京', '人数': 1000 },
29 | { '时间': '星期二', '地点': '上海', '人数': 400 },
30 | { '时间': '星期三', '地点': '杭州', '人数': 800 },
31 | { '时间': '星期二', '地点': '深圳', '人数': 200 },
32 | { '时间': '星期三', '地点': '长春', '人数': 100 },
33 | { '时间': '星期五', '地点': '南京', '人数': 300 },
34 | { '时间': '星期四', '地点': '江苏', '人数': 800 },
35 | { '时间': '星期三', '地点': '北京', '人数': 700 },
36 | { '时间': '星期三', '地点': '上海', '人数': 300 },
37 | { '时间': '星期二', '地点': '杭州', '人数': 500 }
38 | ]
39 | },
40 | settings: {
41 | xAxisList: ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
42 | yAxisList: ['北京', '上海', '杭州', '深圳', '长春', '南京', '江苏']
43 | }
44 | },
45 | {
46 | name: '地图+热力图',
47 | data: {
48 | columns: ['lat', 'lng', '人数'],
49 | rows: [
50 | { 'lat': 115.892151, 'lng': 28.676493, '人数': 1000 },
51 | { 'lat': 117.000923, 'lng': 36.675807, '人数': 400 },
52 | { 'lat': 113.665412, 'lng': 34.757975, '人数': 800 },
53 | { 'lat': 114.298572, 'lng': 30.584355, '人数': 200 },
54 | { 'lat': 112.982279, 'lng': 28.19409, '人数': 100 },
55 | { 'lat': 113.280637, 'lng': 23.125178, '人数': 300 },
56 | { 'lat': 110.33119, 'lng': 20.031971, '人数': 800 },
57 | { 'lat': 104.065735, 'lng': 30.659462, '人数': 700 },
58 | { 'lat': 108.948024, 'lng': 34.263161, '人数': 300 },
59 | { 'lat': 103.823557, 'lng': 36.058039, '人数': 500 }
60 | ]
61 | },
62 | settings: {
63 | position: 'china',
64 | type: 'map',
65 | geo: {
66 | label: {
67 | emphasis: {
68 | show: false
69 | }
70 | },
71 | itemStyle: {
72 | normal: {
73 | areaColor: '#323c48',
74 | borderColor: '#111'
75 | },
76 | emphasis: {
77 | areaColor: '#2a333d'
78 | }
79 | }
80 | }
81 | }
82 | },
83 | {
84 | name: '百度地图+热力图',
85 | data: {
86 | columns: ['lat', 'lng'],
87 | rows: [
88 | { 'lat': 120.14322240845, 'lng': 30.236064370321 },
89 | { 'lat': 120.14301682797, 'lng': 30.236035316745 },
90 | { 'lat': 120.14138577045, 'lng': 30.236113748704 },
91 | { 'lat': 120.1400398833, 'lng': 30.235973050702 },
92 | { 'lat': 120.13893453465, 'lng': 30.23517220446 },
93 | { 'lat': 120.1382899739, 'lng': 30.234062922977 },
94 | { 'lat': 120.13265960629, 'lng': 30.231641351722 },
95 | { 'lat': 120.13170681763, 'lng': 30.229925745619 },
96 | { 'lat': 120.13119614803, 'lng': 30.228996846637 },
97 | { 'lat': 120.13023980134, 'lng': 30.228226570416 }
98 | ]
99 | },
100 | settings: {
101 | key: 'oBvDtR6nzWtVchkY4cLHtnah1VVZQKRK',
102 | bmap: {
103 | center: [120.14322240845, 30.236064370321],
104 | zoom: 14,
105 | roam: true
106 | },
107 | type: 'bmap'
108 | }
109 | }
110 | ]
111 | }
112 |
--------------------------------------------------------------------------------
/examples/data/histogram.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '柱状图',
3 | type: 'histogram',
4 | data: [
5 | {
6 | name: '简单柱状图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': '1-1', '余额': 12, '年龄': 3 },
11 | { '日期': '1-2', '余额': 12, '年龄': 6 },
12 | { '日期': '1-3', '余额': 21, '年龄': 9 },
13 | { '日期': '1-4', '余额': 41, '年龄': 12 },
14 | { '日期': '1-5', '余额': 31, '年龄': 15 },
15 | { '日期': '1-6', '余额': 71, '年龄': 20 }
16 | ]
17 | },
18 | settings: {
19 | stack: { '对比': ['余额', '年龄'] }
20 | }
21 | },
22 | {
23 | name: '数值轴柱状图',
24 | data: {
25 | columns: ['日期', '余额', '年龄', '成绩'],
26 | rows: [
27 | { '日期': 10, '余额': 12, '年龄': 3, '成绩': 32 },
28 | { '日期': 20, '余额': 12, '年龄': 6, '成绩': 53 },
29 | { '日期': 30, '余额': 21, '年龄': 9, '成绩': 33 },
30 | { '日期': 40, '余额': 41, '年龄': 12, '成绩': 36 },
31 | { '日期': 50, '余额': 34, '年龄': 15, '成绩': 23 },
32 | { '日期': 60, '余额': 71, '年龄': 20, '成绩': 13 },
33 | { '日期': 70, '余额': 71, '年龄': 20, '成绩': 13 },
34 | { '日期': 80, '余额': 71, '年龄': 20, '成绩': 13 }
35 | ]
36 | },
37 | settings: {
38 | // xAxisType: 'value'
39 | }
40 | },
41 | {
42 | name: '柱状图+折线图',
43 | data: {
44 | columns: ['日期', '余额', '年龄'],
45 | rows: [
46 | { '日期': '1-1', '余额': 123, '年龄': 3 },
47 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
48 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
49 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
50 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
51 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
52 | ]
53 | },
54 | settings: {
55 | axisSite: {
56 | right: ['年龄']
57 | },
58 | showLine: ['年龄']
59 | }
60 | },
61 | {
62 | name: '默认在柱子上显示数据',
63 | data: {
64 | columns: ['日期', '余额', '年龄'],
65 | rows: [
66 | { '日期': '1-1', '余额': 123, '年龄': 3 },
67 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
68 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
69 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
70 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
71 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
72 | ]
73 | },
74 | settings: {
75 | label: {
76 | normal: {
77 | show: true,
78 | position: 'top'
79 | }
80 | }
81 | }
82 | },
83 | {
84 | name: '设置指标维度名称',
85 | data: {
86 | columns: ['date', 'resume', 'uplevel'],
87 | rows: [
88 | { 'date': '1-1', 'resume': 123, 'uplevel': 0.3 },
89 | { 'date': '1-2', 'resume': 1223, 'uplevel': 0.6 },
90 | { 'date': '1-3', 'resume': 2123, 'uplevel': 0.9 },
91 | { 'date': '1-4', 'resume': 4123, 'uplevel': 0.12 },
92 | { 'date': '1-5', 'resume': 3123, 'uplevel': 0.15 },
93 | { 'date': '1-6', 'resume': 7123, 'uplevel': 0.2 }
94 | ]
95 | },
96 | settings: {
97 | labelMap: {
98 | date: '日期',
99 | resume: '余额',
100 | uplevel: '增长率'
101 | },
102 | yAxisType: ['KMB', 'percent'],
103 | axisSite: {
104 | right: ['uplevel']
105 | }
106 | }
107 | },
108 | {
109 | name: '坐标轴值域配置',
110 | data: {
111 | columns: ['日期', '余额', '年龄'],
112 | rows: [
113 | { '日期': '1-1', '余额': 1232, '年龄': 3 },
114 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
115 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
116 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
117 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
118 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
119 | ]
120 | },
121 | settings: {
122 | min: [1000]
123 | }
124 | },
125 | {
126 | name: '带有较小百分比数值',
127 | data: {
128 | columns: ['日期', '比率'],
129 | rows: [
130 | { '日期': '1-1', '余额': 123, '比率': 0.00001 },
131 | { '日期': '1-2', '余额': 1223, '比率': 0.00002 },
132 | { '日期': '1-3', '余额': 2123, '比率': 0.00003 },
133 | { '日期': '1-4', '余额': 4123, '比率': 0.00007 },
134 | { '日期': '1-5', '余额': 3123, '比率': 0.00001 },
135 | { '日期': '1-6', '余额': 7123, '比率': 0.00003 }
136 | ]
137 | },
138 | settings: {
139 | yAxisType: ['percent'],
140 | digit: 4
141 | }
142 | },
143 | {
144 | name: '坐标轴配置',
145 | data: {
146 | columns: ['日期', '余额', '年龄'],
147 | rows: [
148 | { '日期': '1-1', '余额': 123, '年龄': 3 },
149 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
150 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
151 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
152 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
153 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
154 | ]
155 | },
156 | settings: {
157 | yAxisType: ['KMB', 'percent'],
158 | yAxisName: ['余额', '年龄'],
159 | axisSite: {
160 | right: ['年龄']
161 | }
162 | }
163 | },
164 | {
165 | name: '复杂坐标轴配置',
166 | data: {
167 | columns: ['日期', 'a', 'b', 'c'],
168 | rows: [
169 | { '日期': '1-1', 'a': 123, 'b': 3, c: 1 },
170 | { '日期': '1-2', 'a': 1223, 'b': 6, c: 1 },
171 | { '日期': '1-3', 'a': 2123, 'b': 9, c: 1 },
172 | { '日期': '1-4', 'a': 4123, 'b': 12, c: 1 },
173 | { '日期': '1-5', 'a': 3123, 'b': 15, c: 1 },
174 | { '日期': '1-6', 'a': 7123, 'b': 20, c: 1 }
175 | ]
176 | },
177 | settings: {
178 | axisSite: {
179 | left: ['a'],
180 | right: ['b']
181 | }
182 | }
183 | },
184 | {
185 | name: '指标维度配置',
186 | data: {
187 | columns: ['日期', '余额', '年龄'],
188 | rows: [
189 | { '日期': '1-1', '余额': 123, '年龄': 3 },
190 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
191 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
192 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
193 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
194 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
195 | ]
196 | },
197 | settings: {
198 | dimension: ['余额'],
199 | metrics: ['年龄']
200 | }
201 | },
202 | {
203 | name: '堆叠柱状图',
204 | data: {
205 | columns: ['日期', '余额', '年龄'],
206 | rows: [
207 | { '日期': '1-1', '余额': 123, '年龄': 3 },
208 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
209 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
210 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
211 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
212 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
213 | ]
214 | },
215 | settings: {
216 | stack: {
217 | 'xxx': ['余额', '年龄']
218 | }
219 | }
220 | }
221 | ]
222 | }
223 |
--------------------------------------------------------------------------------
/examples/data/index.js:
--------------------------------------------------------------------------------
1 | import bar from './bar'
2 | import histogram from './histogram'
3 | import line from './line'
4 | import pie from './pie'
5 | import ring from './ring'
6 | import waterfall from './waterfall'
7 | import funnel from './funnel'
8 | import radar from './radar'
9 | import chart from './chart'
10 | import map from './map'
11 | import sankey from './sankey'
12 | import heatmap from './heatmap'
13 |
14 | export default {
15 | bar,
16 | histogram,
17 | line,
18 | pie,
19 | ring,
20 | waterfall,
21 | funnel,
22 | radar,
23 | chart,
24 | map,
25 | sankey,
26 | heatmap
27 | }
28 |
--------------------------------------------------------------------------------
/examples/data/line.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '折线图',
3 | type: 'line',
4 | data: [
5 | {
6 | name: '简单折线图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': '1-1', '余额': 123, '年龄': 3 },
11 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
12 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
13 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
14 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
15 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
16 | ]
17 | },
18 | settings: {}
19 | },
20 | {
21 | name: 'label 属性配置',
22 | data: {
23 | columns: ['日期', '余额', '年龄'],
24 | rows: [
25 | { '日期': '1-1', '余额': 123, '年龄': 3 },
26 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
27 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
28 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
29 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
30 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
31 | ]
32 | },
33 | settings: {
34 | label: {
35 | normal: {
36 | show: true
37 | }
38 | }
39 | }
40 | },
41 | {
42 | name: '设置指标名称',
43 | data: {
44 | columns: ['date', 'balance', 'age'],
45 | rows: [
46 | { 'date': '1-1', 'balance': 123, 'age': 3 },
47 | { 'date': '1-2', 'balance': 1223, 'age': 6 },
48 | { 'date': '1-3', 'balance': 2123, 'age': 9 },
49 | { 'date': '1-4', 'balance': 4123, 'age': 12 },
50 | { 'date': '1-5', 'balance': 3123, 'age': 15 },
51 | { 'date': '1-6', 'balance': 7123, 'age': 20 }
52 | ]
53 | },
54 | settings: {
55 | labelMap: {
56 | date: '日期',
57 | balance: '余额'
58 | }
59 | }
60 | },
61 | {
62 | name: '设置legend名称',
63 | data: {
64 | columns: ['日期', '余额', '年龄'],
65 | rows: [
66 | { '日期': '1-1', '余额': 123, '年龄': 3 },
67 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
68 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
69 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
70 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
71 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
72 | ]
73 | },
74 | settings: {
75 | legendName: {
76 | '余额': 'remain'
77 | }
78 | }
79 | },
80 | {
81 | name: '带有较小百分比数值',
82 | data: {
83 | columns: ['日期', '比率'],
84 | rows: [
85 | { '日期': '1-1', '余额': 123, '比率': 0.00001 },
86 | { '日期': '1-2', '余额': 1223, '比率': 0.00002 },
87 | { '日期': '1-3', '余额': 2123, '比率': 0.00003 },
88 | { '日期': '1-4', '余额': 4123, '比率': 0.00007 },
89 | { '日期': '1-5', '余额': 3123, '比率': 0.00001 },
90 | { '日期': '1-6', '余额': 7123, '比率': 0.00003 }
91 | ]
92 | },
93 | settings: {
94 | yAxisType: ['percent'],
95 | digit: 4
96 | }
97 | },
98 | {
99 | name: '坐标轴配置',
100 | data: {
101 | columns: ['日期', '余额', '比率'],
102 | rows: [
103 | { '日期': '1-1', '余额': 123, '比率': 0.3 },
104 | { '日期': '1-2', '余额': 1223, '比率': 0.6 },
105 | { '日期': '1-3', '余额': 2123, '比率': 0.9 },
106 | { '日期': '1-4', '余额': 4123, '比率': 0.12 },
107 | { '日期': '1-5', '余额': 3123, '比率': 0.15 },
108 | { '日期': '1-6', '余额': 7123, '比率': 0.20 }
109 | ]
110 | },
111 | settings: {
112 | axisSite: {
113 | right: ['比率']
114 | },
115 | yAxisType: ['KMB', 'percent']
116 | }
117 | },
118 | {
119 | name: '指标维度配置',
120 | data: {
121 | columns: ['日期', '余额', '比率'],
122 | rows: [
123 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
124 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
125 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
126 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
127 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
128 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
129 | ]
130 | },
131 | settings: {
132 | dimension: ['比率'],
133 | metrics: ['余额']
134 | }
135 | },
136 | {
137 | name: '坐标轴缩放配置',
138 | data: {
139 | columns: ['日期', '余额', '比率'],
140 | rows: [
141 | { '日期': '1-1', '余额': 1232, '比率': 0.1 },
142 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
143 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
144 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
145 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
146 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
147 | ]
148 | },
149 | settings: {
150 | dimension: ['比率'],
151 | metrics: ['余额'],
152 | scale: [true, true]
153 | }
154 | },
155 | {
156 | name: '坐标轴值域配置',
157 | data: {
158 | columns: ['日期', '余额', '比率'],
159 | rows: [
160 | { '日期': '1-1', '余额': 1232, '比率': 0.1 },
161 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
162 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
163 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
164 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
165 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
166 | ]
167 | },
168 | settings: {
169 | dimension: ['比率'],
170 | metrics: ['余额'],
171 | min: [1000],
172 | max: [5000]
173 | }
174 | },
175 | {
176 | name: '面积图',
177 | data: {
178 | columns: ['日期', '余额', '比率'],
179 | rows: [
180 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
181 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
182 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
183 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
184 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
185 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
186 | ]
187 | },
188 | settings: {
189 | area: true
190 | }
191 | },
192 | {
193 | name: '堆叠折线图',
194 | data: {
195 | columns: ['日期', '2015', '2016', '2017'],
196 | rows: [
197 | { '日期': '1-1', '2015': 100, '2016': 40, '2017': 22 },
198 | { '日期': '1-2', '2015': 110, '2016': 60, '2017': 25 },
199 | { '日期': '1-3', '2015': 140, '2016': 10, '2017': 14 },
200 | { '日期': '1-4', '2015': 260, '2016': 30, '2017': 75 },
201 | { '日期': '1-5', '2015': 300, '2016': 20, '2017': 45 },
202 | { '日期': '1-6', '2015': 380, '2016': 70, '2017': 310 }
203 | ]
204 | },
205 | settings: {
206 | area: true,
207 | stack: {
208 | '年份': ['2015', '2016', '2017']
209 | }
210 | }
211 | }
212 | ]
213 | }
214 |
--------------------------------------------------------------------------------
/examples/data/map.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '地图',
3 | type: 'map',
4 | data: [
5 | {
6 | name: '地图',
7 | data: {
8 | columns: ['位置', 'GDP'],
9 | rows: [
10 | { '位置': '吉林', 'GDP': 123 },
11 | { '位置': '北京', 'GDP': 1223 },
12 | { '位置': '上海', 'GDP': 2123 },
13 | { '位置': '浙江', 'GDP': 4123 }
14 | ]
15 | },
16 | settings: {
17 | position: 'china',
18 | dataType: {
19 | 'GDP': 'KMB'
20 | }
21 | }
22 | },
23 | {
24 | name: '自定义 JSON 地图',
25 | data: {
26 | columns: ['位置', ' 人口'],
27 | rows: [
28 | { '位置': 'North', ' 人口': 123 }
29 | ]
30 | },
31 | settings: {
32 | positionJsonLink: 'https://dn-quietcoder.qbox.me/HK_geo.json',
33 | position: 'HK',
34 | beforeRegisterMap (json) {
35 | // edit data here such as:
36 | // json.features[0].properties.cp = [121.509062, 26.044332]
37 | return json
38 | }
39 | }
40 | },
41 | {
42 | name: '设置数据标示',
43 | data: {
44 | columns: ['位置', 'GDP', '人口'],
45 | rows: [
46 | { '位置': '吉林', 'GDP': 123, '人口': 234 },
47 | { '位置': '北京', 'GDP': 1223, '人口': 1234 },
48 | { '位置': '上海', 'GDP': 2123, '人口': 3234 },
49 | { '位置': '浙江', 'GDP': 4123, '人口': 4234 }
50 | ]
51 | },
52 | settings: {
53 | position: 'china',
54 | selectData: true,
55 | label: false
56 | }
57 | },
58 | {
59 | name: '设置位置选择模式',
60 | data: {
61 | columns: ['位置', 'GDP'],
62 | rows: [
63 | { '位置': '吉林', 'GDP': 123 },
64 | { '位置': '北京', 'GDP': 1223 },
65 | { '位置': '上海', 'GDP': 2123 },
66 | { '位置': '浙江', 'GDP': 4123 }
67 | ]
68 | },
69 | settings: {
70 | position: 'china',
71 | selectedMode: 'multiple'
72 | }
73 | },
74 | {
75 | name: '设置省份显示',
76 | data: {
77 | columns: ['位置', 'GDP'],
78 | rows: [
79 | { '位置': '长春市', 'GDP': 123 },
80 | { '位置': '松原市', 'GDP': 1223 },
81 | { '位置': '辽源市', 'GDP': 2123 },
82 | { '位置': '白山市', 'GDP': 4123 }
83 | ]
84 | },
85 | settings: {
86 | position: 'province/jilin',
87 | selectData: true
88 | }
89 | },
90 | {
91 | name: '设置数据别名',
92 | data: {
93 | columns: ['位置', 'GDP', '人口'],
94 | rows: [
95 | { '位置': '吉林', 'GDP': 123, '人口': 234 },
96 | { '位置': '北京', 'GDP': 1223, '人口': 1234 },
97 | { '位置': '上海', 'GDP': 2123, '人口': 3234 },
98 | { '位置': '浙江', 'GDP': 4123, '人口': 4234 }
99 | ]
100 | },
101 | settings: {
102 | labelMap: {
103 | '人口': '人口密度'
104 | }
105 | }
106 | },
107 | {
108 | name: '设置legendName别名地图',
109 | data: {
110 | columns: ['位置', 'GDP', '人口'],
111 | rows: [
112 | { '位置': '吉林', 'GDP': 123, '人口': 234 },
113 | { '位置': '北京', 'GDP': 1223, '人口': 1234 },
114 | { '位置': '上海', 'GDP': 2123, '人口': 3234 },
115 | { '位置': '浙江', 'GDP': 4123, '人口': 4234 }
116 | ]
117 | },
118 | settings: {
119 | legendName: {
120 | '人口': '人口密度'
121 | }
122 | }
123 | }
124 | ]
125 | }
126 |
--------------------------------------------------------------------------------
/examples/data/pie.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '饼图',
3 | type: 'pie',
4 | data: [
5 | {
6 | name: '简单饼图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': '1-1', '余额': 123, '年龄': 3 },
11 | { '日期': '1-2', '余额': 123, '年龄': 6 },
12 | { '日期': '1-3', '余额': 123, '年龄': 9 },
13 | { '日期': '1-4', '余额': 123, '年龄': 12 },
14 | { '日期': '1-5', '余额': 123, '年龄': 15 },
15 | { '日期': '1-6', '余额': 123, '年龄': 20 }
16 | ]
17 | },
18 | settings: {}
19 | },
20 | {
21 | name: '玫瑰图',
22 | data: {
23 | columns: ['日期', '余额', '年龄'],
24 | rows: [
25 | { '日期': '1-1', '余额': 123, '年龄': 3 },
26 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
27 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
28 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
29 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
30 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
31 | ]
32 | },
33 | settings: {
34 | roseType: 'radius'
35 | }
36 | },
37 | {
38 | name: '限制显示条数',
39 | data: {
40 | columns: ['日期', '余额', '年龄'],
41 | rows: [
42 | { '日期': '1-1', '余额': 123, '年龄': 3 },
43 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
44 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
45 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
46 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
47 | { '日期': '1-6', '余额': 7123, '年龄': 20 },
48 | { '日期': '1-7', '余额': 4123, '年龄': 20 },
49 | { '日期': '1-8', '余额': 1123, '年龄': 20 },
50 | { '日期': '1-9', '余额': 5223, '年龄': 20 },
51 | { '日期': '1-10', '余额': 9123, '年龄': 20 },
52 | { '日期': '1-11', '余额': 4123, '年龄': 20 }
53 | ]
54 | },
55 | settings: {
56 | limitShowNum: 5
57 | }
58 | },
59 | {
60 | name: '多圆饼图',
61 | data: {
62 | columns: ['日期', '余额', '年龄'],
63 | rows: [
64 | { '日期': '1-1', '余额': 123, '年龄': 3 },
65 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
66 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
67 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
68 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
69 | { '日期': '1-6', '余额': 7123, '年龄': 20 },
70 | { '日期': '1-7', '余额': 4123, '年龄': 20 },
71 | { '日期': '1-8', '余额': 1123, '年龄': 20 },
72 | { '日期': '1-9', '余额': 5223, '年龄': 20 },
73 | { '日期': '1-10', '余额': 9123, '年龄': 20 },
74 | { '日期': '1-11', '余额': 4123, '年龄': 20 }
75 | ]
76 | },
77 | settings: {
78 | level: [
79 | ['1-1', '1-2', '1-3'],
80 | ['1-4', '1-5']
81 | ]
82 | }
83 | },
84 | {
85 | name: '设置数据类型',
86 | data: {
87 | columns: ['日期', '比率'],
88 | rows: [
89 | { '日期': '1-1', '余额': 123, '比率': 0.00001 },
90 | { '日期': '1-2', '余额': 1223, '比率': 0.0002 },
91 | { '日期': '1-3', '余额': 2123, '比率': 0.003 },
92 | { '日期': '1-4', '余额': 4123, '比率': 0.0004 },
93 | { '日期': '1-5', '余额': 3123, '比率': 0.005 },
94 | { '日期': '1-6', '余额': 7123, '比率': 0.06 }
95 | ]
96 | },
97 | settings: {
98 | dataType: 'percent',
99 | digit: 4
100 | }
101 | },
102 | {
103 | name: '指标维度配置',
104 | data: {
105 | columns: ['日期', '余额', '年龄'],
106 | rows: [
107 | { '日期': '1-1', '余额': 123, '年龄': 3 },
108 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
109 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
110 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
111 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
112 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
113 | ]
114 | },
115 | settings: {
116 | dimension: '余额',
117 | metrics: '年龄'
118 | }
119 | },
120 | {
121 | name: '限制legend显示长度',
122 | data: {
123 | columns: ['日期', '余额', '比率'],
124 | rows: [
125 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
126 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
127 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
128 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
129 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
130 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
131 | ]
132 | },
133 | settings: {
134 | legendLimit: 2
135 | }
136 | },
137 | {
138 | name: '设置饼图样式1',
139 | data: {
140 | columns: ['日期', '余额', '比率'],
141 | rows: [
142 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
143 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
144 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
145 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
146 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
147 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
148 | ]
149 | },
150 | settings: {
151 | radius: 10,
152 | offsetY: 300
153 | }
154 | },
155 | {
156 | name: '设置饼图样式2',
157 | data: {
158 | columns: ['日期', '余额', '比率'],
159 | rows: [
160 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
161 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
162 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
163 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
164 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
165 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
166 | ]
167 | },
168 | settings: {
169 | itemStyle: {
170 | normal: {
171 | borderWidth: 4,
172 | borderColor: '#58b4ff'
173 | }
174 | }
175 | }
176 | },
177 | {
178 | name: '设置legend别名饼图',
179 | data: {
180 | columns: ['日期', '余额', '比率'],
181 | rows: [
182 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
183 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
184 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
185 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
186 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
187 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
188 | ]
189 | },
190 | settings: {
191 | limitShowNum: 5,
192 | legendName: {
193 | '其他': '别的时间的时候biu~'
194 | }
195 | }
196 | }
197 | ]
198 | }
199 |
--------------------------------------------------------------------------------
/examples/data/radar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '雷达图',
3 | type: 'radar',
4 | data: [
5 | {
6 | name: '简单雷达图',
7 | data: {
8 | columns: ['城市', '房价', '收入', '人口比例'],
9 | rows: [
10 | { '房价': 10000, '收入': 4000, '人口比例': 0.4, '城市': '北京' },
11 | { '房价': 20000, '收入': 6000, '人口比例': 0.6, '城市': '上海' },
12 | { '房价': 30000, '收入': 8000, '人口比例': 0.2, '城市': '广州' }
13 | ]
14 | },
15 | settings: {
16 | dataType: {
17 | '人口比例': 'percent'
18 | }
19 | }
20 | },
21 | {
22 | name: '指标维度配置',
23 | data: {
24 | columns: ['城市', '房价', '收入', '人口比例'],
25 | rows: [
26 | { '房价': 10000, '收入': 4000, '人口比例': 0.4, '城市': '北京' },
27 | { '房价': 20000, '收入': 6000, '人口比例': 0.6, '城市': '上海' },
28 | { '房价': 30000, '收入': 8000, '人口比例': 0.2, '城市': '广州' }
29 | ]
30 | },
31 | settings: {
32 | dataType: {
33 | '人口比例': 'percent'
34 | },
35 | dimension: '城市',
36 | metrics: ['收入', '人口比例', '房价']
37 | }
38 | },
39 | {
40 | name: '样式配置',
41 | data: {
42 | columns: ['城市', '房价', '收入', '人口比例'],
43 | rows: [
44 | { '房价': 10000, '收入': 4000, '人口比例': 0.4, '城市': '北京' },
45 | { '房价': 20000, '收入': 6000, '人口比例': 0.6, '城市': '上海' },
46 | { '房价': 30000, '收入': 8000, '人口比例': 0.2, '城市': '广州' }
47 | ]
48 | },
49 | settings: {
50 | label: {
51 | normal: {
52 | color: 'red',
53 | show: true
54 | }
55 | }
56 | }
57 | },
58 | {
59 | name: '雷达图配置labelMap',
60 | data: {
61 | columns: ['city', 'housePrices', 'income', 'proportion'],
62 | rows: [
63 | { 'housePrices': 10000, 'income': 4000, 'proportion': 0.4, 'city': '北京' },
64 | { 'housePrices': 20000, 'income': 6000, 'proportion': 0.6, 'city': '上海' },
65 | { 'housePrices': 30000, 'income': 8000, 'proportion': 0.2, 'city': '广州' }
66 | ]
67 | },
68 | settings: {
69 | labelMap: {
70 | 'city': '城市',
71 | 'housePrices': '房价',
72 | 'income': '收入',
73 | 'proportion': '人口比例'
74 | }
75 | }
76 | },
77 | {
78 | name: '雷达图配置legendName',
79 | data: {
80 | columns: ['城市', '房价', '收入', '人口比例'],
81 | rows: [
82 | { '房价': 10000, '收入': 4000, '人口比例': 0.4, '城市': '北京' },
83 | { '房价': 20000, '收入': 6000, '人口比例': 0.6, '城市': '上海' },
84 | { '房价': 30000, '收入': 8000, '人口比例': 0.2, '城市': '广州' }
85 | ]
86 | },
87 | settings: {
88 | legendName: {
89 | '北京': 'BeiJing'
90 | }
91 | }
92 | },
93 | {
94 | name: '雷达图',
95 | data: {
96 | columns: ['投资人', '股票', '基金', '保险', '银行理财', '互联网金融', '期货'],
97 | rows: [
98 | { '股票': 10000, '基金': 4000, '保险': 0.4, '银行理财': 1, '互联网金融': 1, '期货': 1, '投资人': 'A' },
99 | { '股票': 20000, '基金': 6000, '保险': 0.6, '银行理财': 2, '互联网金融': 2, '期货': 2, '投资人': 'B' },
100 | { '股票': 30000, '基金': 8000, '保险': 0.2, '银行理财': 3, '互联网金融': 3, '期货': 3, '投资人': 'C' }
101 | ]
102 | },
103 | settings: {
104 | }
105 | }
106 | ]
107 | }
108 |
--------------------------------------------------------------------------------
/examples/data/ring.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '环图',
3 | type: 'ring',
4 | data: [
5 | {
6 | name: '简单环图',
7 | data: {
8 | columns: ['日期', '余额', '年龄'],
9 | rows: [
10 | { '日期': '1-1', '余额': 123, '年龄': 3 },
11 | { '日期': '1-2', '余额': 123, '年龄': 6 },
12 | { '日期': '1-3', '余额': 123, '年龄': 9 }
13 | // { '日期': '1-4', '余额': 123, '年龄': 12 },
14 | // { '日期': '1-5', '余额': 123, '年龄': 15 },
15 | // { '日期': '1-6', '余额': 123, '年龄': 20 }
16 | ]
17 | },
18 | settings: {
19 | label: {
20 | normal: {
21 | show: false,
22 | position: 'center'
23 | }
24 | },
25 | radius: [75, 100]
26 | }
27 | },
28 | {
29 | name: '简单环图2',
30 | data: {
31 | columns: ['日期', '余额', '年龄'],
32 | rows: [
33 | { '日期': '1-1', '余额': 123, '年龄': 3 },
34 | { '日期': '1-2', '余额': 123, '年龄': 6 },
35 | { '日期': '1-3', '余额': 123, '年龄': 9 },
36 | { '日期': '1-4', '余额': 123, '年龄': 12 },
37 | { '日期': '1-5', '余额': 123, '年龄': 15 },
38 | { '日期': '1-6', '余额': 123, '年龄': 20 }
39 | ]
40 | },
41 | settings: {
42 | label: {
43 | normal: {
44 | show: false,
45 | position: 'center'
46 | }
47 | },
48 | radius: [40, 90]
49 | }
50 | },
51 | {
52 | name: '玫瑰图',
53 | data: {
54 | columns: ['日期', '余额', '年龄'],
55 | rows: [
56 | { '日期': '1-1', '余额': 123, '年龄': 3 },
57 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
58 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
59 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
60 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
61 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
62 | ]
63 | },
64 | settings: {
65 | roseType: 'radius'
66 | }
67 | },
68 | {
69 | name: '限制显示条数',
70 | data: {
71 | columns: ['日期', '余额', '年龄'],
72 | rows: [
73 | { '日期': '1-1', '余额': 123, '年龄': 3 },
74 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
75 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
76 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
77 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
78 | { '日期': '1-6', '余额': 7123, '年龄': 20 },
79 | { '日期': '1-7', '余额': 4123, '年龄': 20 },
80 | { '日期': '1-8', '余额': 1123, '年龄': 20 },
81 | { '日期': '1-9', '余额': 5223, '年龄': 20 },
82 | { '日期': '1-10', '余额': 9123, '年龄': 20 },
83 | { '日期': '1-11', '余额': 4123, '年龄': 20 }
84 | ]
85 | },
86 | settings: {
87 | limitShowNum: 5
88 | }
89 | },
90 | {
91 | name: '设置数据类型',
92 | data: {
93 | columns: ['日期', '余额', '年龄'],
94 | rows: [
95 | { '日期': '1-1', '余额': 123, '年龄': 3 },
96 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
97 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
98 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
99 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
100 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
101 | ]
102 | },
103 | settings: {
104 | dataType: 'KMB'
105 | }
106 | },
107 | {
108 | name: '指标维度配置',
109 | data: {
110 | columns: ['日期', '余额', '年龄'],
111 | rows: [
112 | { '日期': '1-1', '余额': 123, '年龄': 3 },
113 | { '日期': '1-2', '余额': 1223, '年龄': 6 },
114 | { '日期': '1-3', '余额': 2123, '年龄': 9 },
115 | { '日期': '1-4', '余额': 4123, '年龄': 12 },
116 | { '日期': '1-5', '余额': 3123, '年龄': 15 },
117 | { '日期': '1-6', '余额': 7123, '年龄': 20 }
118 | ]
119 | },
120 | settings: {
121 | dimension: '余额',
122 | metrics: '年龄'
123 | }
124 | },
125 | {
126 | name: '限制legend显示长度',
127 | data: {
128 | columns: ['日期', '余额', '比率'],
129 | rows: [
130 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
131 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
132 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
133 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
134 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
135 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
136 | ]
137 | },
138 | settings: {
139 | legendLimit: 2
140 | }
141 | },
142 | {
143 | name: '设置环图样式',
144 | data: {
145 | columns: ['日期', '余额', '比率'],
146 | rows: [
147 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
148 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
149 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
150 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
151 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
152 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
153 | ]
154 | },
155 | settings: {
156 | radius: [100, 10],
157 | offsetY: 300
158 | }
159 | },
160 | {
161 | name: '设置legend别名环图',
162 | data: {
163 | columns: ['日期', '余额', '比率'],
164 | rows: [
165 | { '日期': '1-1', '余额': 123, '比率': 0.1 },
166 | { '日期': '1-2', '余额': 1223, '比率': 0.2 },
167 | { '日期': '1-3', '余额': 2123, '比率': 0.3 },
168 | { '日期': '1-4', '余额': 4123, '比率': 0.4 },
169 | { '日期': '1-5', '余额': 3123, '比率': 0.5 },
170 | { '日期': '1-6', '余额': 7123, '比率': 0.6 }
171 | ]
172 | },
173 | settings: {
174 | limitShowNum: 5,
175 | legendName: {
176 | '其他': '别的时间的时候biu~'
177 | }
178 | }
179 | }
180 | ]
181 | }
182 |
--------------------------------------------------------------------------------
/examples/data/sankey.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '桑基图',
3 | type: 'sankey',
4 | data: [
5 | {
6 | name: '简单桑基图',
7 | data: {
8 | columns: ['页面', '访问量'],
9 | rows: [
10 | { '页面': '首页', '访问量': 1000 },
11 | { '页面': '列表页a', '访问量': 200 },
12 | { '页面': '列表页b', '访问量': 800 },
13 | { '页面': '内容页a-1', '访问量': 100 },
14 | { '页面': '内容页a-2', '访问量': 100 },
15 | { '页面': '内容页b-1', '访问量': 600 },
16 | { '页面': '内容页b-2', '访问量': 200 }
17 | ]
18 | },
19 | settings: {
20 | links: [
21 | { source: '首页', target: '列表页a' },
22 | { source: '首页', target: '列表页b' },
23 | { source: '列表页a', target: '内容页a-1' },
24 | { source: '列表页a', target: '内容页a-2' },
25 | { source: '列表页b', target: '内容页b-1' },
26 | { source: '列表页b', target: '内容页b-2' }
27 | ]
28 | }
29 | },
30 | {
31 | name: '强制设置使用 rows 中的数据',
32 | data: {
33 | columns: ['页面', '访问量'],
34 | rows: [
35 | { '页面': '首页', '访问量': 1000 },
36 | { '页面': '列表页a', '访问量': 200 },
37 | { '页面': '列表页b', '访问量': 800 },
38 | { '页面': '内容页a-1', '访问量': 100 },
39 | { '页面': '内容页a-2', '访问量': 100 },
40 | { '页面': '内容页b-1', '访问量': 600 },
41 | { '页面': '内容页b-2', '访问量': 200 }
42 | ]
43 | },
44 | settings: {
45 | links: [
46 | { source: '首页', target: '列表页a', value: '' },
47 | { source: '首页', target: '列表页b', value: '' },
48 | { source: '列表页a', target: '内容页a-1', value: '' },
49 | { source: '列表页a', target: '内容页a-2', value: '' },
50 | { source: '列表页b', target: '内容页b-1', value: '' },
51 | { source: '列表页b', target: '内容页b-2', value: '' }
52 | ],
53 | useDataValue: true
54 | }
55 | },
56 | {
57 | name: '设置数据类型',
58 | data: {
59 | columns: ['页面', '访问量'],
60 | rows: [
61 | { '页面': '首页', '访问量': 100000 },
62 | { '页面': '列表页a', '访问量': 20000 },
63 | { '页面': '列表页b', '访问量': 80000 },
64 | { '页面': '内容页a-1', '访问量': 10000 },
65 | { '页面': '内容页a-2', '访问量': 10000 },
66 | { '页面': '内容页b-1', '访问量': 60000 },
67 | { '页面': '内容页b-2', '访问量': 20000 }
68 | ]
69 | },
70 | settings: {
71 | links: [
72 | { source: '首页', target: '列表页a', value: 0.1 },
73 | { source: '首页', target: '列表页b', value: 0.1 },
74 | { source: '列表页a', target: '内容页a-1', value: 0.1 },
75 | { source: '列表页a', target: '内容页a-2', value: 0.1 },
76 | { source: '列表页b', target: '内容页b-1', value: 0.1 },
77 | { source: '列表页b', target: '内容页b-2', value: 0.1 }
78 | ],
79 | dataType: ['KMB', 'percent']
80 | }
81 | },
82 | {
83 | name: '样式设置',
84 | data: {
85 | columns: ['页面', '访问量'],
86 | rows: [
87 | { '页面': '首页', '访问量': 100000 },
88 | { '页面': '列表页a', '访问量': 20000 },
89 | { '页面': '列表页b', '访问量': 80000 },
90 | { '页面': '内容页a-1', '访问量': 10000 },
91 | { '页面': '内容页a-2', '访问量': 10000 },
92 | { '页面': '内容页b-1', '访问量': 60000 },
93 | { '页面': '内容页b-2', '访问量': 20000 }
94 | ]
95 | },
96 | settings: {
97 | links: [
98 | { source: '首页', target: '列表页a', value: 0.1 },
99 | { source: '首页', target: '列表页b', value: 0.1 },
100 | { source: '列表页a', target: '内容页a-1', value: 0.1 },
101 | { source: '列表页a', target: '内容页a-2', value: 0.1 },
102 | { source: '列表页b', target: '内容页b-1', value: 0.1 },
103 | { source: '列表页b', target: '内容页b-2', value: 0.1 }
104 | ],
105 | label: {
106 | normal: {
107 | show: true,
108 | color: '#00f'
109 | }
110 | }
111 | }
112 | }
113 | ]
114 | }
115 |
--------------------------------------------------------------------------------
/examples/data/waterfall.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '瀑布图',
3 | type: 'waterfall',
4 | data: [
5 | {
6 | name: '简单瀑布图',
7 | data: {
8 | columns: ['活动', '时间'],
9 | rows: [
10 | { '活动': '吃饭', '时间': 4 },
11 | { '活动': '睡觉', '时间': 10 },
12 | { '活动': '打豆豆', '时间': 5 }
13 | ]
14 | },
15 | settings: {}
16 | },
17 | {
18 | name: '设定总量',
19 | data: {
20 | columns: ['活动', '时间'],
21 | rows: [
22 | { '活动': '吃饭', '时间': 4 },
23 | { '活动': '睡觉', '时间': 10 },
24 | { '活动': '打豆豆', '时间': 5 }
25 | ]
26 | },
27 | settings: {
28 | totalNum: 24
29 | }
30 | },
31 | {
32 | name: '设定总量并且子项超标',
33 | data: {
34 | columns: ['活动', '时间'],
35 | rows: [
36 | { '活动': '吃饭', '时间': 4 },
37 | { '活动': '睡觉', '时间': 20 },
38 | { '活动': '打豆豆', '时间': 5 }
39 | ]
40 | },
41 | settings: {
42 | totalNum: 24
43 | }
44 | },
45 | {
46 | name: '设定数据类型',
47 | data: {
48 | columns: ['活动', '时间'],
49 | rows: [
50 | { '活动': '吃饭', '时间': 0.1 },
51 | { '活动': '睡觉', '时间': 0.2 },
52 | { '活动': '打豆豆', '时间': 0.3 }
53 | ]
54 | },
55 | settings: {
56 | totalNum: 1,
57 | dataType: 'percent'
58 | }
59 | },
60 | {
61 | name: '设定总量及其他名称',
62 | data: {
63 | columns: ['活动', '时间'],
64 | rows: [
65 | { '活动': '吃饭', '时间': 4 },
66 | { '活动': '睡觉', '时间': 10 },
67 | { '活动': '打豆豆', '时间': 5 }
68 | ]
69 | },
70 | settings: {
71 | totalNum: 24,
72 | totalName: '总时间',
73 | remainName: '剩余时间'
74 | }
75 | },
76 | {
77 | name: '设定数据别名瀑布图',
78 | data: {
79 | columns: ['活动', '时间'],
80 | rows: [
81 | { '活动': '吃饭', '时间': 4 },
82 | { '活动': '睡觉', '时间': 10 },
83 | { '活动': '打豆豆', '时间': 5 }
84 | ]
85 | },
86 | settings: {
87 | labelMap: {
88 | '时间': 'time'
89 | }
90 | }
91 | }
92 | ]
93 | }
94 |
--------------------------------------------------------------------------------
/examples/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalkingData/t-charts/d553261687e19c92be2333421f74cb8e0fc86e4d/examples/favicon.ico
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | v-charts
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/main.js:
--------------------------------------------------------------------------------
1 | import App from './App'
2 | import Vue from 'vue'
3 | import router from './router'
4 | import CodeSection from './components/code-section'
5 | import 'normalize.css'
6 |
7 | Vue.component(CodeSection.name, CodeSection)
8 |
9 | /* eslint-disable no-new */
10 | new Vue({
11 | el: '#app',
12 | template: '',
13 | router,
14 | components: { App }
15 | })
16 |
--------------------------------------------------------------------------------
/examples/pages/bmap.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
49 |
--------------------------------------------------------------------------------
/examples/pages/chart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ d.name }}
6 |
10 |
11 |
12 |
13 |
数据格式
14 |
15 |
16 |
17 |
配置项
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
84 |
85 |
110 |
--------------------------------------------------------------------------------
/examples/pages/eventer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
事件监听
4 |
示例
5 |
9 |
10 |
被选中饼的名称: {{ name }}
11 |
12 |
13 |
14 |
15 |
16 |
49 |
--------------------------------------------------------------------------------
/examples/pages/install.vue:
--------------------------------------------------------------------------------
1 |
2 | v-charts
3 |
4 |
--------------------------------------------------------------------------------
/examples/pages/test.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
54 |
55 |
60 |
--------------------------------------------------------------------------------
/examples/pages/toggle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
图表切换
4 |
{{ contentList[0] }}
5 |
15 |
16 |
17 |
代码示例
18 |
19 |
20 |
21 |
22 |
23 |
24 |
145 |
--------------------------------------------------------------------------------
/examples/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Install from './pages/install'
4 | import Chart from './pages/chart'
5 | import Eventer from './pages/eventer'
6 | import Toggle from './pages/toggle'
7 | import Test from './pages/test'
8 | import Bmap from './pages/bmap.vue'
9 |
10 | Vue.use(Router)
11 |
12 | export default new Router({
13 | routes: [
14 | { path: '/', name: '安装', component: Install },
15 | { path: '/chart/:type', name: '测试图表', component: Chart },
16 | { path: '/eventer', name: '事件监听', component: Eventer },
17 | { path: '/toggle', name: '图表切换', component: Toggle },
18 | { path: '/test', name: '测试', component: Test },
19 | { path: '/bmap', name: '百度地图', component: Bmap }
20 | ]
21 | })
22 |
--------------------------------------------------------------------------------
/examples/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalkingData/t-charts/d553261687e19c92be2333421f74cb8e0fc86e4d/examples/static/logo.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "t-charts",
3 | "version": "1.2.6",
4 | "description": "",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "dev": "webpack-dev-server --config ./build/webpack.config.js",
8 | "build": "rm -f -r lib && node build/rollup.config.js && cp -f lib/index.min.js lib/style.min.css docs/",
9 | "prepublish": "npm run build",
10 | "test": "karma start ./test/karma.conf.js",
11 | "docs": "docsify serve docs",
12 | "deploy": "gh-pages -d docs"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+git@github.com:TalkingData/t-charts.git"
17 | },
18 | "keywords": [
19 | "vue",
20 | "echarts"
21 | ],
22 | "author": "xiguaxigua|t-charts team",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/TalkingData/t-charts/issues"
26 | },
27 | "homepage": "https://github.com/TalkingData/t-charts#readme",
28 | "dependencies": {
29 | "css-loader": "^0.27.3",
30 | "echarts": "^3.8.3",
31 | "file-loader": "^0.11.1",
32 | "iview": "^2.7.3",
33 | "url-loader": "^0.5.8"
34 | },
35 | "files": [
36 | "lib",
37 | "umd"
38 | ],
39 | "devDependencies": {
40 | "autoprefixer": "^7.1.5",
41 | "babel-core": "6.24.0",
42 | "babel-eslint": "7.1.1",
43 | "babel-loader": "6.4.1",
44 | "babel-plugin-external-helpers": "6.22.0",
45 | "babel-plugin-transform-object-assign": "6.22.0",
46 | "babel-polyfill": "6.23.0",
47 | "babel-preset-latest": "6.24.0",
48 | "babel-preset-stage-2": "6.22.0",
49 | "copy-webpack-plugin": "4.0.1",
50 | "css-loader": "0.27.3",
51 | "cssnano": "^3.10.0",
52 | "docsify": "^4.3.8",
53 | "es6-promise": "^4.1.1",
54 | "eslint": "3.17.1",
55 | "eslint-config-standard": "7.0.1",
56 | "eslint-friendly-formatter": "2.0.7",
57 | "eslint-loader": "1.6.3",
58 | "eslint-plugin-html": "3.2.1",
59 | "eslint-plugin-promise": "3.5.0",
60 | "eslint-plugin-standard": "2.1.1",
61 | "extract-text-webpack-plugin": "2.1.0",
62 | "file-loader": "0.11.1",
63 | "gh-pages": "^1.0.0",
64 | "html-webpack-plugin": "2.30.1",
65 | "jasmine-core": "2.6.2",
66 | "karma": "1.7.0",
67 | "karma-babel-preprocessor": "6.0.1",
68 | "karma-chrome-launcher": "2.1.1",
69 | "karma-commonjs": "1.0.0",
70 | "karma-jasmine": "1.1.0",
71 | "karma-phantomjs-launcher": "1.0.4",
72 | "karma-spec-reporter": "0.0.31",
73 | "karma-webpack": "2.0.3",
74 | "less": "2.7.2",
75 | "less-loader": "3.0.0",
76 | "lodash-es": "^4.17.4",
77 | "normalize.css": "5.0.0",
78 | "opn": "4.0.2",
79 | "optimize-css-assets-webpack-plugin": "1.3.0",
80 | "phantomjs-prebuilt": "2.1.14",
81 | "postcss-loader": "1.3.3",
82 | "prismjs": "1.6.0",
83 | "rollup": "0.41.6",
84 | "rollup-plugin-alias": "1.2.1",
85 | "rollup-plugin-babel": "2.7.1",
86 | "rollup-plugin-commonjs": "8.0.2",
87 | "rollup-plugin-eslint": "3.0.0",
88 | "rollup-plugin-node-resolve": "2.0.0",
89 | "rollup-plugin-uglify": "2.0.1",
90 | "rollup-plugin-vue": "2.5.2",
91 | "style-loader": "0.14.1",
92 | "url-loader": "0.5.8",
93 | "vue": "2.4.2",
94 | "vue-loader": "11.1.4",
95 | "vue-router": "2.3.0",
96 | "vue-style-loader": "2.0.4",
97 | "vue-template-compiler": "2.4.2",
98 | "webpack": "2.2.1",
99 | "webpack-dev-server": "2.4.2",
100 | "webpack-merge": "4.1.0"
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/component-list.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | VeBar: { src: 'src/packages/bar/index.js', dist: 'lib/bar' },
3 | VeBarMini: { src: 'src/packages/bar-mini/index.js', dist: 'lib/bar-mini' },
4 | VeHistogram: { src: 'src/packages/histogram/index.js', dist: 'lib/histogram' },
5 | VeHistogramMini: { src: 'src/packages/histogram-mini/index.js', dist: 'lib/histogram-mini' },
6 | VeFunnel: { src: 'src/packages/funnel/index.js', dist: 'lib/funnel' },
7 | VeLine: { src: 'src/packages/line/index.js', dist: 'lib/line' },
8 | VeLineMini: { src: 'src/packages/Line-mini/index.js', dist: 'lib/line-mini' },
9 | VePie: { src: 'src/packages/pie/index.js', dist: 'lib/pie' },
10 | VeRing: { src: 'src/packages/ring/index.js', dist: 'lib/ring' },
11 | VeRadar: { src: 'src/packages/radar/index.js', dist: 'lib/radar' },
12 | VeWaterfall: { src: 'src/packages/waterfall/index.js', dist: 'lib/waterfall' },
13 | VeIndex: { src: 'src/packages/index/index.js', dist: 'lib/index' },
14 | VeChart: { src: 'src/packages/chart/index.js', dist: 'lib/chart' },
15 | VeMap: { src: 'src/packages/map/index.js', dist: 'lib/map' },
16 | VeBmap: { src: 'src/packages/bmap/index.js', dist: 'lib/bmap' },
17 | VeSankey: { src: 'src/packages/sankey/index.js', dist: 'lib/sankey' },
18 | Veheatmap: { src: 'src/packages/heatmap/index.js', dist: 'lib/heatmap' }
19 | }
20 |
--------------------------------------------------------------------------------
/src/components/data-empty.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 暂无数据
4 |
5 |
6 |
7 |
22 |
--------------------------------------------------------------------------------
/src/components/loading.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
62 |
--------------------------------------------------------------------------------
/src/echarts-base.js:
--------------------------------------------------------------------------------
1 | import echarts from 'echarts/lib/echarts'
2 | import 'echarts/lib/component/tooltip'
3 | import 'echarts/lib/component/legend'
4 |
5 | echarts.registerTheme('ve-chart', {
6 | categoryAxis: {
7 | axisLine: { show: false },
8 | axisTick: { show: false },
9 | splitLine: { show: false }
10 | },
11 | valueAxis: {
12 | axisLine: {
13 | show: false
14 | },
15 | axisLabel: {
16 | show: true,
17 | margin: 15,
18 | textStyle: {
19 | color: '#80848F'
20 | }
21 | },
22 | splitLine: {
23 | show: true,
24 | lineStyle: {
25 | color: '#E9EAEC'
26 | }
27 | }
28 | },
29 | line: {
30 | smooth: true
31 | },
32 | grid: {
33 | containLabel: true,
34 | left: 10,
35 | right: 10
36 | }
37 | })
38 |
39 | export const itemPoint = (color) => {
40 | return [
41 | ''
49 | ].join('')
50 | }
51 |
52 | export const color = [
53 | '#2d8cf0', '#2de2c5', '#fcc45f',
54 | '#ff8454', '#db425a', '#34508c',
55 | '#5bb6fd', '#56d08b', '#b3e768',
56 | '#71808f'
57 | ]
58 |
59 | export const HEAT_MAP_COLOR = ['#313695', '#4575b4', '#74add1',
60 | '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090',
61 | '#fdae61', '#f46d43', '#d73027', '#a50026']
62 |
63 | export const HEAT_BMAP_COLOR = ['blue', 'blue', 'green', 'yellow', 'red']
64 |
65 | export default echarts
66 |
--------------------------------------------------------------------------------
/src/index.es.js:
--------------------------------------------------------------------------------
1 | import VeBar from './packages/bar'
2 | import VeBarMini from './packages/bar-mini'
3 | import VeHistogram from './packages/histogram'
4 | import VeHistogramMini from './packages/histogram-mini'
5 | import VeLine from './packages/line'
6 | import VeLineMini from './packages/line-mini'
7 | import VePie from './packages/pie'
8 | import VeRing from './packages/ring'
9 | import VeWaterfall from './packages/waterfall'
10 | import VeFunnel from './packages/funnel'
11 | import VeRadar from './packages/radar'
12 | import VeChart from './packages/chart'
13 | import VeMap from './packages/map'
14 | import VeBmap from './packages/bmap'
15 | import VeSankey from './packages/sankey'
16 | import VeHeatmap from './packages/heatmap'
17 |
18 | const components = [
19 | VeBar,
20 | VeBarMini,
21 | VeHistogram,
22 | VeHistogramMini,
23 | VeLine,
24 | VeLineMini,
25 | VePie,
26 | VeRing,
27 | VeWaterfall,
28 | VeFunnel,
29 | VeRadar,
30 | VeChart,
31 | VeMap,
32 | VeBmap,
33 | VeSankey,
34 | VeHeatmap
35 | ]
36 |
37 | function install (Vue, _) {
38 | components.forEach(component => {
39 | Vue.component(component.name, component)
40 | })
41 | }
42 |
43 | export {
44 | VeBar,
45 | VeBarMini,
46 | VeHistogram,
47 | VeHistogramMini,
48 | VeRing,
49 | VeLine,
50 | VeLineMini,
51 | VePie,
52 | VeWaterfall,
53 | VeFunnel,
54 | VeRadar,
55 | VeChart,
56 | VeMap,
57 | VeBmap,
58 | VeSankey,
59 | VeHeatmap,
60 | install
61 | }
62 |
--------------------------------------------------------------------------------
/src/packages/bar-mini/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { barmini } from './main'
3 | import Core from '../../core'
4 |
5 | export default {
6 | name: 'VeBarMini',
7 | mixins: [Core],
8 | created () {
9 | this.chartHandler = barmini
10 | this.echartsLib = echarts
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/packages/bar/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { bar } from './main'
3 | import Core from '../../core'
4 |
5 | export default {
6 | name: 'VeBar',
7 | mixins: [Core],
8 | created () {
9 | this.chartHandler = bar
10 | this.echartsLib = echarts
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/packages/bmap/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { bmap } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeBmap',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = bmap
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/bmap/main.js:
--------------------------------------------------------------------------------
1 | import 'echarts/extension/bmap/bmap'
2 | import { getBmap } from '../../utils'
3 |
4 | export const bmap = (_, __, settings) => {
5 | const {
6 | key,
7 | bmap
8 | } = settings
9 | if (!key) console.warn('settings.key must be a string.')
10 |
11 | return getBmap(key).then(_ => {
12 | return { bmap }
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/src/packages/chart/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { bar, histogram } from '../bar/main'
3 | import { line } from '../line/main'
4 | import { pie, ring } from '../pie/main'
5 | import { funnel } from '../funnel/main'
6 | import { radar } from '../radar/main'
7 | import { waterfall } from '../waterfall/main'
8 | import Core from '../../core'
9 | export default {
10 | name: 'VeChart',
11 | mixins: [Core],
12 | created () {
13 | this.chartLib = {
14 | bar,
15 | histogram,
16 | line,
17 | pie,
18 | ring,
19 | funnel,
20 | radar,
21 | waterfall
22 | }
23 | this.chartHandler = this.chartLib[this.settings.type]
24 | this.echartsLib = echarts
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/packages/funnel/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { funnel } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeFunnel',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = funnel
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/funnel/main.js:
--------------------------------------------------------------------------------
1 | import { itemPoint } from '../../echarts-base'
2 | import { getFormated } from '../../utils'
3 | import 'echarts/lib/chart/funnel'
4 |
5 | function getFunnelTooltip (dataType, digit) {
6 | return {
7 | trigger: 'item',
8 | formatter (item) {
9 | let tpl = []
10 | tpl.push(itemPoint(item.color))
11 | tpl.push(`${item.name}: ${getFormated(item.data.realValue, dataType, digit)}`)
12 | return tpl.join('')
13 | }
14 | }
15 | }
16 |
17 | function getFunnelLegend (args) {
18 | const { data, legendName } = args
19 | return {
20 | data,
21 | formatter (name) {
22 | return legendName[name] != null ? legendName[name] : name
23 | }
24 | }
25 | }
26 |
27 | function getFunnelSeries (args) {
28 | const {
29 | dimension,
30 | metrics,
31 | rows,
32 | sequence,
33 | ascending,
34 | label,
35 | labelLine,
36 | itemStyle
37 | } = args
38 | let series = { type: 'funnel' }
39 | rows.sort((a, b) => {
40 | return sequence.indexOf(a[dimension]) - sequence.indexOf(b[dimension])
41 | })
42 |
43 | let falseFunnel = false
44 | rows.some((row, index) => {
45 | if (index && row[metrics] > rows[index - 1][metrics]) {
46 | falseFunnel = true
47 | return true
48 | }
49 | })
50 |
51 | const step = 100 / rows.length
52 |
53 | if (falseFunnel) {
54 | series.data = rows.slice().reverse().map((row, index) => ({
55 | name: row[dimension],
56 | value: (index + 1) * step,
57 | realValue: row[metrics]
58 | }))
59 | } else {
60 | series.data = rows.map(row => ({
61 | name: row[dimension],
62 | value: row[metrics],
63 | realValue: row[metrics]
64 | }))
65 | }
66 |
67 | if (ascending) series.sort = 'ascending'
68 | if (label) series.label = label
69 | if (labelLine) series.labelLine = labelLine
70 | if (itemStyle) series.itemStyle = itemStyle
71 | return series
72 | }
73 |
74 | export const funnel = (outerColumns, outerRows, settings, extra) => {
75 | const columns = outerColumns.slice()
76 | const rows = outerRows.slice()
77 | const {
78 | dataType = 'normal',
79 | dimension = columns[0],
80 | sequence = rows.map(row => row[dimension]),
81 | digit = 2,
82 | ascending,
83 | label,
84 | labelLine,
85 | legendName = {},
86 | itemStyle
87 | } = settings
88 | const { tooltipVisible, legendVisible } = extra
89 | let metrics
90 | if (settings.metrics) {
91 | metrics = settings.metrics
92 | } else {
93 | let metricsTemp = columns.slice()
94 | metricsTemp.splice(columns.indexOf(dimension), 1)
95 | metrics = metricsTemp[0]
96 | }
97 |
98 | const tooltip = tooltipVisible && getFunnelTooltip(dataType, digit)
99 | const seriesParams = {
100 | dimension,
101 | metrics,
102 | rows,
103 | sequence,
104 | ascending,
105 | label,
106 | labelLine,
107 | itemStyle
108 | }
109 | const legend = legendVisible && getFunnelLegend({ data: sequence, legendName })
110 | const series = getFunnelSeries(seriesParams)
111 | const options = { tooltip, legend, series }
112 | return options
113 | }
114 |
--------------------------------------------------------------------------------
/src/packages/heatmap/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { heatmap } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeHeatmap',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = heatmap
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/heatmap/main.js:
--------------------------------------------------------------------------------
1 | import { default as echarts, itemPoint, HEAT_MAP_COLOR, HEAT_BMAP_COLOR } from '../../echarts-base'
2 | import 'echarts/lib/chart/heatmap'
3 | import 'echarts/lib/component/visualMap'
4 | import 'echarts/extension/bmap/bmap'
5 | import 'echarts/lib/chart/map'
6 | import { getBmap, getMapJSON, getFormated } from '../../utils'
7 |
8 | function getAxisList (rows, label) {
9 | const result = []
10 | rows.forEach(row => {
11 | if (!~result.indexOf(row[label])) result.push(row[label])
12 | })
13 | return result
14 | }
15 |
16 | function getData (args) {
17 | const { rows, innerXAxisList, innerYAxisList, xDim, yDim, metrics, type } = args
18 | let result = null
19 | if (type === 'cartesian') {
20 | result = rows.map(row => {
21 | const xIndex = innerXAxisList.indexOf(row[xDim])
22 | const yIndex = innerYAxisList.indexOf(row[yDim])
23 | const value = metrics ? row[metrics] : 1
24 | return [xIndex, yIndex, value]
25 | })
26 | } else {
27 | result = rows.map(row => {
28 | const value = metrics ? row[metrics] : 1
29 | return [row[xDim], row[yDim], value]
30 | })
31 | }
32 | return result
33 | }
34 |
35 | function getAxis (list, name) {
36 | return {
37 | type: 'category',
38 | data: list,
39 | name,
40 | nameLocation: 'end',
41 | splitArea: { show: true }
42 | }
43 | }
44 |
45 | function getVisualMap (args) {
46 | const { innerMin: min, innerMax: max, type, heatColor } = args
47 | let result = {
48 | min,
49 | max,
50 | calculable: true
51 | }
52 | let extra = null
53 | if (type === 'map') {
54 | extra = {
55 | orient: 'vertical',
56 | left: 0,
57 | bottom: 0,
58 | inRange: { color: heatColor || HEAT_MAP_COLOR }
59 | }
60 | } else if (type === 'bmap') {
61 | extra = {
62 | show: false,
63 | orient: 'vertical',
64 | left: 0,
65 | bottom: 0,
66 | inRange: { color: heatColor || HEAT_BMAP_COLOR }
67 | }
68 | } else {
69 | extra = {
70 | orient: 'horizontal',
71 | left: 'center',
72 | bottom: 10,
73 | inRange: heatColor && { color: heatColor }
74 | }
75 | }
76 |
77 | return Object.assign(result, extra)
78 | }
79 |
80 | function getSeries (args) {
81 | const { chartData } = args
82 | return [{
83 | type: 'heatmap',
84 | data: chartData
85 | }]
86 | }
87 |
88 | function getTooltip (args) {
89 | const { dataType, innerXAxisList, innerYAxisList, digit } = args
90 |
91 | return {
92 | trigger: 'item',
93 | formatter ({ color, data: [xDim, yDim, value] }) {
94 | const tpl = []
95 | tpl.push(`${innerYAxisList[yDim]}
`)
96 | tpl.push(`${itemPoint(color)} ${innerXAxisList[xDim]}: `)
97 | tpl.push(getFormated(value, dataType, digit))
98 | return tpl.join('')
99 | }
100 | }
101 | }
102 |
103 | export const heatmap = (columns, rows, settings, status) => {
104 | const {
105 | type = 'cartesian', // cartesian, map, bmap,
106 | xAxisList,
107 | yAxisList,
108 | dimension = [columns[0], columns[1]],
109 | metrics = columns[2],
110 | dataType = 'normal',
111 | min,
112 | max,
113 | digit,
114 | bmap,
115 | geo,
116 | key,
117 | position,
118 | positionJsonLink,
119 | beforeRegisterMap,
120 | pointSize = 10,
121 | blurSize = 5,
122 | heatColor,
123 | yAxisName,
124 | xAxisName
125 | } = settings
126 | const { tooltipVisible } = status
127 | let innerXAxisList = xAxisList
128 | let innerYAxisList = yAxisList
129 | let chartData = []
130 | if (type === 'cartesian') {
131 | if (!innerXAxisList || !innerXAxisList.length) {
132 | innerXAxisList = getAxisList(rows, dimension[0])
133 | }
134 | if (!innerYAxisList || !innerYAxisList.length) {
135 | innerYAxisList = getAxisList(rows, dimension[1])
136 | }
137 | chartData = getData({
138 | rows,
139 | innerXAxisList,
140 | innerYAxisList,
141 | xDim: dimension[0],
142 | yDim: dimension[1],
143 | metrics,
144 | type
145 | })
146 | } else {
147 | chartData = getData({
148 | rows,
149 | xDim: dimension[0],
150 | yDim: dimension[1],
151 | metrics,
152 | type
153 | })
154 | }
155 | const metricsList = metrics ? rows.map(row => row[metrics]) : [0, 5]
156 | const innerMin = min || Math.min.apply(null, metricsList)
157 | const innerMax = max || Math.max.apply(null, metricsList)
158 |
159 | const xAxis = getAxis(innerXAxisList, xAxisName)
160 | const yAxis = getAxis(innerYAxisList, yAxisName)
161 | const visualMap = getVisualMap({ innerMin, innerMax, type, heatColor })
162 | const series = getSeries({ chartData })
163 | const tooltip = tooltipVisible && getTooltip({
164 | dataType,
165 | innerXAxisList,
166 | innerYAxisList,
167 | digit
168 | })
169 |
170 | const options = { visualMap, series }
171 | if (type === 'bmap') {
172 | Object.assign(options.series[0], { coordinateSystem: 'bmap', pointSize, blurSize })
173 |
174 | return getBmap(key).then(_ => {
175 | return Object.assign({ bmap }, options)
176 | })
177 | } else if (type === 'map') {
178 | options.series[0].coordinateSystem = 'geo'
179 |
180 | return getMapJSON(position, positionJsonLink).then(json => {
181 | const geoAttr = Object.assign({ map: position }, geo)
182 | if (beforeRegisterMap) json = beforeRegisterMap(json)
183 | echarts.registerMap(position, json)
184 | console.log(Object.assign({ geo: geoAttr }, options))
185 | return Object.assign({ geo: geoAttr }, options)
186 | })
187 | } else {
188 | return Object.assign({ xAxis, yAxis, tooltip }, options)
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/packages/histogram-mini/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { histogrammini } from '../bar-mini/main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeHistogramMini',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = histogrammini
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/histogram/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { histogram } from '../bar/main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeHistogram',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = histogram
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/index/index.js:
--------------------------------------------------------------------------------
1 | import VeBar from '../bar'
2 | import VeBarMini from '../bar-mini'
3 | import VeHistogram from '../histogram'
4 | import VeHistogramMini from '../histogram-mini'
5 | import VeLine from '../line'
6 | import VeLineMini from '../line-mini'
7 | import VePie from '../pie'
8 | import VeRing from '../ring'
9 | import VeWaterfall from '../waterfall'
10 | import VeFunnel from '../funnel'
11 | import VeRadar from '../radar'
12 | import VeChart from '../chart'
13 | import VeMap from '../map'
14 | import VeBmap from '../bmap'
15 | import VeSankey from '../sankey'
16 | import VeHeatmap from '../heatmap'
17 |
18 | import 'echarts/lib/chart/bar'
19 | import 'echarts/lib/chart/funnel'
20 | import 'echarts/lib/chart/line'
21 | import 'echarts/lib/chart/pie'
22 | import 'echarts/lib/chart/radar'
23 |
24 | const components = [
25 | VeBar,
26 | VeBarMini,
27 | VeHistogram,
28 | VeHistogramMini,
29 | VeLine,
30 | VeLineMini,
31 | VePie,
32 | VeRing,
33 | VeWaterfall,
34 | VeFunnel,
35 | VeRadar,
36 | VeChart,
37 | VeMap,
38 | VeBmap,
39 | VeSankey,
40 | VeHeatmap
41 | ]
42 |
43 | function install (Vue, _) {
44 | components.forEach(component => {
45 | Vue.component(component.name, component)
46 | })
47 | }
48 |
49 | if (typeof window !== 'undefined' && window.Vue) {
50 | install(window.Vue)
51 | }
52 |
53 | export default {
54 | VeBar,
55 | VeHistogram,
56 | VeRing,
57 | VeLine,
58 | VePie,
59 | VeWaterfall,
60 | VeFunnel,
61 | VeRadar,
62 | VeChart,
63 | VeMap,
64 | VeBmap,
65 | VeSankey,
66 | install
67 | }
68 |
--------------------------------------------------------------------------------
/src/packages/line-mini/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { linemini } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeLineMini',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = linemini
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/line-mini/main.js:
--------------------------------------------------------------------------------
1 | import { itemPoint } from '../../echarts-base'
2 | import { getFormated, getStackMap } from '../../utils'
3 | import 'echarts/lib/chart/line'
4 |
5 | function getLineXAxis (args) {
6 | const { dimension, rows, xAxisName, axisVisible, xAxisType } = args
7 | return dimension.map((item, index) => ({
8 | type: xAxisType,
9 | nameLocation: 'middle',
10 | nameGap: 22,
11 | boundaryGap: false,
12 | name: xAxisName[index] || '',
13 | axisTick: {
14 | show: false,
15 | lineStyle: {
16 | color: '#eee'
17 | },
18 | length: 7
19 | },
20 | axisLabel: {
21 | show: false,
22 | margin: 15,
23 | color: '#80848F'
24 | },
25 | axisLine: {
26 | show: false
27 | },
28 | data: rows.map(row => row[item]),
29 | show: axisVisible
30 | }))
31 | }
32 |
33 | function getLineSeries (args) {
34 | const {
35 | rows,
36 | axisSite,
37 | metrics,
38 | area,
39 | stack,
40 | nullAddZero,
41 | labelMap,
42 | label,
43 | itemStyle,
44 | lineStyle,
45 | areaStyle,
46 | xAxisType,
47 | dimension
48 | } = args
49 | let series = []
50 | const dataTemp = {}
51 | const stackMap = stack && getStackMap(stack)
52 | metrics.forEach(item => { dataTemp[item] = [] })
53 | rows.forEach(row => {
54 | metrics.forEach(item => {
55 | let value = null
56 | if (row[item] != null) {
57 | value = row[item]
58 | } else if (nullAddZero) {
59 | value = 0
60 | }
61 | const dataItem = xAxisType === 'category'
62 | ? value
63 | : [row[dimension[0]], value]
64 | dataTemp[item].push(dataItem)
65 | })
66 | })
67 | metrics.forEach(item => {
68 | let seriesItem = {
69 | name: labelMap[item] != null ? labelMap[item] : item,
70 | type: 'line',
71 | // 改变symbol
72 | showSymbol: false,
73 | symbolSize: 1,
74 | data: dataTemp[item]
75 | }
76 |
77 | if (area) seriesItem.areaStyle = { normal: {} }
78 | if (axisSite.right) {
79 | seriesItem.yAxisIndex = ~axisSite.right.indexOf(item) ? 1 : 0
80 | }
81 |
82 | if (stack && stackMap[item]) seriesItem.stack = stackMap[item]
83 |
84 | if (label) seriesItem.label = label
85 | if (itemStyle) seriesItem.itemStyle = itemStyle
86 | if (lineStyle) seriesItem.lineStyle = lineStyle
87 | if (areaStyle) seriesItem.areaStyle = areaStyle
88 |
89 | series.push(seriesItem)
90 | })
91 | return series.length ? series : false
92 | }
93 |
94 | function getLineYAxis (args) {
95 | const {
96 | yAxisName,
97 | yAxisType,
98 | axisVisible,
99 | scale,
100 | min,
101 | max,
102 | digit
103 | } = args
104 | const yAxisBase = {
105 | type: 'value',
106 | axisTick: {
107 | show: false
108 | },
109 | show: axisVisible
110 | }
111 | let yAxis = []
112 | for (let i = 0; i < 2; i++) {
113 | if (yAxisType[i]) {
114 | yAxis[i] = Object.assign({}, yAxisBase, {
115 | axisLabel: {
116 | formatter (val) {
117 | return getFormated(val, yAxisType[i], digit)
118 | }
119 | }
120 | })
121 | } else {
122 | yAxis[i] = Object.assign({}, yAxisBase)
123 | }
124 | yAxis[i].name = yAxisName[i] || ''
125 | yAxis[i].scale = scale[i] || false
126 | yAxis[i].min = min[i] || null
127 | yAxis[i].max = max[i] || null
128 | }
129 | return yAxis
130 | }
131 |
132 | function getLineTooltip (args) {
133 | const { axisSite, yAxisType, digit, labelMap, xAxisType } = args
134 | const rightItems = axisSite.right || []
135 | const rightList = labelMap
136 | ? rightItems.map(item => {
137 | return labelMap[item] === undefined ? item : labelMap[item]
138 | })
139 | : rightItems
140 | return {
141 | trigger: 'axis',
142 | // 空字符,图例标线
143 | axisPointer: {
144 | type: 'none'
145 | },
146 | formatter (items) {
147 | let tpl = []
148 | tpl.push(`${items[0].name}
`)
149 | items.forEach(item => {
150 | let showData = null
151 | const type = ~rightList.indexOf(item.seriesName)
152 | ? yAxisType[1]
153 | : yAxisType[0]
154 | const data = xAxisType === 'category'
155 | ? item.data
156 | : item.data[1]
157 | showData = getFormated(data, type, digit)
158 | tpl.push(itemPoint(item.color))
159 | tpl.push(`${item.seriesName}: ${showData}`)
160 | tpl.push('
')
161 | })
162 | return tpl.join('')
163 | }
164 | }
165 | }
166 |
167 | function getLegend (args) {
168 | const { metrics, legendName, labelMap } = args
169 | if (!legendName && !labelMap) return { data: metrics }
170 | const data = labelMap
171 | ? metrics.map(item => (labelMap[item] == null ? item : labelMap[item]))
172 | : metrics
173 | return {
174 | data,
175 | formatter (name) {
176 | return legendName[name] != null ? legendName[name] : name
177 | },
178 | icon: 'roundRect', // custome
179 | itemHeight: 15, // custome
180 | itemWidth: 18, // custome
181 | itemGap: 18, // custome
182 | right: '3.4%', // custome
183 | show: false
184 | }
185 | }
186 |
187 | function getGrid () {
188 | return {
189 | show: false,
190 | left: '0%',
191 | right: '10%',
192 | top: '0%',
193 | bottom: '0%',
194 | containLabel: false,
195 | padding: 0
196 | }
197 | }
198 |
199 | export const linemini = (columns, rows, settings, extra) => {
200 | const {
201 | axisSite = {},
202 | yAxisType = ['normal', 'normal'],
203 | xAxisType = 'category',
204 | yAxisName = [],
205 | dimension = [columns[0]],
206 | xAxisName = [],
207 | axisVisible = false,
208 | area,
209 | stack,
210 | scale = [false, false],
211 | min = [null, null],
212 | max = [null, null],
213 | nullAddZero = false,
214 | digit = 2,
215 | legendName = {},
216 | labelMap = {},
217 | label,
218 | itemStyle,
219 | lineStyle,
220 | areaStyle
221 | } = settings
222 | const { tooltipVisible, legendVisible } = extra
223 | let metrics = columns.slice()
224 |
225 | if (axisSite.left && axisSite.right) {
226 | metrics = axisSite.left.concat(axisSite.right)
227 | } else if (axisSite.left && !axisSite.right) {
228 | metrics = axisSite.left
229 | } else if (settings.metrics) {
230 | metrics = settings.metrics
231 | } else {
232 | metrics.splice(columns.indexOf(dimension[0]), 1)
233 | }
234 |
235 | const legend = legendVisible && getLegend({ metrics, legendName, labelMap })
236 | const tooltip = tooltipVisible && getLineTooltip({
237 | axisSite,
238 | yAxisType,
239 | digit,
240 | labelMap,
241 | xAxisType
242 | })
243 | const xAxis = getLineXAxis({
244 | dimension,
245 | rows,
246 | xAxisName,
247 | axisVisible,
248 | xAxisType
249 | })
250 | const yAxis = getLineYAxis({
251 | yAxisName,
252 | yAxisType,
253 | axisVisible,
254 | scale,
255 | min,
256 | max,
257 | digit
258 | })
259 | const series = getLineSeries({
260 | rows,
261 | axisSite,
262 | metrics,
263 | area,
264 | stack,
265 | nullAddZero,
266 | labelMap,
267 | label,
268 | itemStyle,
269 | lineStyle,
270 | areaStyle,
271 | xAxisType,
272 | dimension
273 | })
274 | const grid = getGrid()
275 | if (!xAxis || !series) return false
276 |
277 | let options = { legend, xAxis, series, yAxis, tooltip, grid }
278 | return options
279 | }
280 |
--------------------------------------------------------------------------------
/src/packages/line/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { line } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeLine',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = line
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/line/main.js:
--------------------------------------------------------------------------------
1 | import { itemPoint } from '../../echarts-base'
2 | import { getFormated, getStackMap } from '../../utils'
3 | import 'echarts/lib/chart/line'
4 |
5 | function getLineXAxis (args) {
6 | const { dimension, rows, xAxisName, axisVisible, xAxisType } = args
7 | return dimension.map((item, index) => ({
8 | type: xAxisType,
9 | nameLocation: 'middle',
10 | nameGap: 22,
11 | boundaryGap: false,
12 | name: xAxisName[index] || '',
13 | axisTick: {
14 | show: true,
15 | lineStyle: {
16 | color: '#eee'
17 | },
18 | length: 7
19 | },
20 | axisLabel: {
21 | margin: 15,
22 | color: '#80848F'
23 | },
24 | data: rows.map(row => row[item]),
25 | show: axisVisible
26 | }))
27 | }
28 |
29 | function getLineSeries (args) {
30 | const {
31 | rows,
32 | axisSite,
33 | metrics,
34 | area,
35 | stack,
36 | nullAddZero,
37 | labelMap,
38 | label,
39 | itemStyle,
40 | lineStyle,
41 | areaStyle,
42 | xAxisType,
43 | dimension
44 | } = args
45 | let series = []
46 | const dataTemp = {}
47 | const stackMap = stack && getStackMap(stack)
48 | metrics.forEach(item => { dataTemp[item] = [] })
49 | rows.forEach(row => {
50 | metrics.forEach(item => {
51 | let value = null
52 | if (row[item] != null) {
53 | value = row[item]
54 | } else if (nullAddZero) {
55 | value = 0
56 | }
57 | const dataItem = xAxisType === 'category'
58 | ? value
59 | : [row[dimension[0]], value]
60 | dataTemp[item].push(dataItem)
61 | })
62 | })
63 | metrics.forEach(item => {
64 | let seriesItem = {
65 | name: labelMap[item] != null ? labelMap[item] : item,
66 | type: 'line',
67 | data: dataTemp[item]
68 | }
69 |
70 | if (area) seriesItem.areaStyle = { normal: {} }
71 | if (axisSite.right) {
72 | seriesItem.yAxisIndex = ~axisSite.right.indexOf(item) ? 1 : 0
73 | }
74 |
75 | if (stack && stackMap[item]) seriesItem.stack = stackMap[item]
76 |
77 | if (label) seriesItem.label = label
78 | if (itemStyle) seriesItem.itemStyle = itemStyle
79 | if (lineStyle) seriesItem.lineStyle = lineStyle
80 | if (areaStyle) seriesItem.areaStyle = areaStyle
81 |
82 | series.push(seriesItem)
83 | })
84 | return series.length ? series : false
85 | }
86 |
87 | function getLineYAxis (args) {
88 | const {
89 | yAxisName,
90 | yAxisType,
91 | axisVisible,
92 | scale,
93 | min,
94 | max,
95 | digit
96 | } = args
97 | const yAxisBase = {
98 | type: 'value',
99 | axisTick: {
100 | show: false
101 | },
102 | show: axisVisible
103 | }
104 | let yAxis = []
105 | for (let i = 0; i < 2; i++) {
106 | if (yAxisType[i]) {
107 | yAxis[i] = Object.assign({}, yAxisBase, {
108 | axisLabel: {
109 | formatter (val) {
110 | return getFormated(val, yAxisType[i], digit)
111 | }
112 | }
113 | })
114 | } else {
115 | yAxis[i] = Object.assign({}, yAxisBase)
116 | }
117 | yAxis[i].name = yAxisName[i] || ''
118 | yAxis[i].scale = scale[i] || false
119 | yAxis[i].min = min[i] || null
120 | yAxis[i].max = max[i] || null
121 | }
122 | return yAxis
123 | }
124 |
125 | function getLineTooltip (args) {
126 | const { axisSite, yAxisType, digit, labelMap, xAxisType } = args
127 | const rightItems = axisSite.right || []
128 | const rightList = labelMap
129 | ? rightItems.map(item => {
130 | return labelMap[item] === undefined ? item : labelMap[item]
131 | })
132 | : rightItems
133 | return {
134 | trigger: 'axis',
135 | formatter (items) {
136 | let tpl = []
137 | tpl.push(`${items[0].name}
`)
138 | items.forEach(item => {
139 | let showData = null
140 | const type = ~rightList.indexOf(item.seriesName)
141 | ? yAxisType[1]
142 | : yAxisType[0]
143 | const data = xAxisType === 'category'
144 | ? item.data
145 | : item.data[1]
146 | showData = getFormated(data, type, digit)
147 | tpl.push(itemPoint(item.color))
148 | tpl.push(`${item.seriesName}: ${showData}`)
149 | tpl.push('
')
150 | })
151 | return tpl.join('')
152 | }
153 | }
154 | }
155 |
156 | function getLegend (args) {
157 | const { metrics, legendName, labelMap } = args
158 | if (!legendName && !labelMap) return { data: metrics }
159 | const data = labelMap
160 | ? metrics.map(item => (labelMap[item] == null ? item : labelMap[item]))
161 | : metrics
162 | return {
163 | data,
164 | formatter (name) {
165 | return legendName[name] != null ? legendName[name] : name
166 | },
167 | icon: 'roundRect', // custome
168 | itemHeight: 5, // custome
169 | itemWidth: 18, // custome
170 | itemGap: 18, // custome
171 | right: '3.4%' // custome
172 | }
173 | }
174 |
175 | export const line = (columns, rows, settings, extra) => {
176 | const {
177 | axisSite = {},
178 | yAxisType = ['normal', 'normal'],
179 | xAxisType = 'category',
180 | yAxisName = [],
181 | dimension = [columns[0]],
182 | xAxisName = [],
183 | axisVisible = true,
184 | area,
185 | stack,
186 | scale = [false, false],
187 | min = [null, null],
188 | max = [null, null],
189 | nullAddZero = false,
190 | digit = 2,
191 | legendName = {},
192 | labelMap = {},
193 | label,
194 | itemStyle,
195 | lineStyle,
196 | areaStyle
197 | } = settings
198 | const { tooltipVisible, legendVisible } = extra
199 | let metrics = columns.slice()
200 |
201 | if (axisSite.left && axisSite.right) {
202 | metrics = axisSite.left.concat(axisSite.right)
203 | } else if (axisSite.left && !axisSite.right) {
204 | metrics = axisSite.left
205 | } else if (settings.metrics) {
206 | metrics = settings.metrics
207 | } else {
208 | metrics.splice(columns.indexOf(dimension[0]), 1)
209 | }
210 |
211 | const legend = legendVisible && getLegend({ metrics, legendName, labelMap })
212 | const tooltip = tooltipVisible && getLineTooltip({
213 | axisSite,
214 | yAxisType,
215 | digit,
216 | labelMap,
217 | xAxisType
218 | })
219 | const xAxis = getLineXAxis({
220 | dimension,
221 | rows,
222 | xAxisName,
223 | axisVisible,
224 | xAxisType
225 | })
226 | const yAxis = getLineYAxis({
227 | yAxisName,
228 | yAxisType,
229 | axisVisible,
230 | scale,
231 | min,
232 | max,
233 | digit
234 | })
235 | const series = getLineSeries({
236 | rows,
237 | axisSite,
238 | metrics,
239 | area,
240 | stack,
241 | nullAddZero,
242 | labelMap,
243 | label,
244 | itemStyle,
245 | lineStyle,
246 | areaStyle,
247 | xAxisType,
248 | dimension
249 | })
250 | if (!xAxis || !series) return false
251 |
252 | let options = { legend, xAxis, series, yAxis, tooltip }
253 | return options
254 | }
255 |
--------------------------------------------------------------------------------
/src/packages/map/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { map } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeMap',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = map
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/map/main.js:
--------------------------------------------------------------------------------
1 | import { default as echarts, itemPoint } from '../../echarts-base'
2 | import { getMapJSON, getFormated } from '../../utils'
3 | import 'echarts/lib/chart/map'
4 |
5 | function getTooltip (dataType, digit, dataStore, metrics, color, labelMap) {
6 | return {
7 | formatter (item) {
8 | let tpl = []
9 | tpl.push(`${item.name}
`)
10 | metrics.forEach((label, index) => {
11 | let title = labelMap[label] != null ? labelMap[label] : label
12 | tpl.push(`${itemPoint(color[index])} ${title} : `)
13 | if (dataStore[item.name]) {
14 | tpl.push(getFormated(dataStore[item.name][label], dataType[label], digit))
15 | } else {
16 | tpl.push('-')
17 | }
18 | tpl.push('
')
19 | })
20 | return tpl.join(' ')
21 | }
22 | }
23 | }
24 |
25 | function getSeries (args) {
26 | const {
27 | position,
28 | selectData,
29 | dimension,
30 | metrics,
31 | rows,
32 | label,
33 | itemStyle,
34 | selectedMode,
35 | roam,
36 | center,
37 | aspectScale,
38 | boundingCoords,
39 | zoom,
40 | labelMap,
41 | scaleLimit,
42 | mapGrid
43 | } = args
44 | const result = []
45 | const mapBase = {
46 | type: 'map',
47 | mapType: position
48 | }
49 |
50 | metrics.forEach(itemName => {
51 | const itemResult = Object.assign({
52 | name: labelMap[itemName] != null ? labelMap[itemName] : itemName,
53 | data: [],
54 | selectedMode,
55 | roam,
56 | center,
57 | aspectScale,
58 | boundingCoords,
59 | zoom,
60 | scaleLimit
61 | }, mapBase)
62 |
63 | if (mapGrid) {
64 | Object.keys(mapGrid).forEach(key => {
65 | itemResult[key] = mapGrid[key]
66 | })
67 | }
68 |
69 | setGeoLabel(itemStyle, itemResult, 'itemStyle')
70 | setGeoLabel(label, itemResult, 'label')
71 |
72 | rows.forEach(row => {
73 | itemResult.data.push({
74 | name: row[dimension],
75 | value: row[itemName],
76 | selected: selectData
77 | })
78 | })
79 | result.push(itemResult)
80 | })
81 |
82 | return result
83 | }
84 |
85 | function setGeoLabel (value, target, label) {
86 | if (typeof value === 'object') {
87 | target[label] = value
88 | } else if (value) {
89 | target[label] = {
90 | normal: { show: true },
91 | emphasis: { show: true }
92 | }
93 | }
94 | }
95 |
96 | function getLegendMap (args) {
97 | const { metrics, legendName, labelMap } = args
98 | if (!legendName && !labelMap) return { data: metrics }
99 | const data = labelMap
100 | ? metrics.map(item => (labelMap[item] == null ? item : labelMap[item]))
101 | : metrics
102 | return {
103 | data,
104 | formatter (name) {
105 | return legendName[name] != null ? legendName[name] : name
106 | }
107 | }
108 | }
109 |
110 | export const map = (columns, rows, settings, extra) => {
111 | const {
112 | position = 'china',
113 | selectData = false,
114 | selectedMode,
115 | label = true,
116 | dataType = {},
117 | digit = 2,
118 | dimension = columns[0],
119 | roam,
120 | center,
121 | aspectScale,
122 | boundingCoords,
123 | zoom,
124 | scaleLimit,
125 | legendName = {},
126 | labelMap = {},
127 | mapGrid,
128 | itemStyle,
129 | positionJsonLink,
130 | beforeRegisterMap
131 | } = settings
132 | let metrics = columns.slice()
133 | if (settings.metrics) {
134 | metrics = settings.metrics
135 | } else {
136 | metrics.splice(columns.indexOf(dimension), 1)
137 | }
138 | const { tooltipVisible, legendVisible, color } = extra
139 | const dataStore = {}
140 | rows.forEach(row => { dataStore[row[dimension]] = row })
141 | const tooltip = tooltipVisible && getTooltip(dataType, digit, dataStore, metrics, color, labelMap)
142 | const legend = legendVisible && getLegendMap({ metrics, legendName, labelMap })
143 | const seriesParams = {
144 | position,
145 | selectData,
146 | label,
147 | itemStyle,
148 | dimension,
149 | metrics,
150 | rows,
151 | selectedMode,
152 | roam,
153 | center,
154 | aspectScale,
155 | boundingCoords,
156 | zoom,
157 | labelMap,
158 | scaleLimit,
159 | mapGrid
160 | }
161 | const series = getSeries(seriesParams)
162 |
163 | return getMapJSON(position, positionJsonLink).then(json => {
164 | if (beforeRegisterMap) json = beforeRegisterMap(json)
165 | echarts.registerMap(position, json)
166 | return { series, tooltip, legend }
167 | })
168 | }
169 |
--------------------------------------------------------------------------------
/src/packages/pie/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { pie } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VePie',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = pie
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/radar/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { radar } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeRadar',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = radar
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/radar/main.js:
--------------------------------------------------------------------------------
1 | import { itemPoint } from '../../echarts-base'
2 | import { getFormated } from '../../utils'
3 | import 'echarts/lib/chart/radar'
4 |
5 | function getRadarLegend (rows, dimension, legendName) {
6 | let legendData = rows.map(row => row[dimension])
7 | legendData = legendData.map(each => {
8 | return {
9 | 'name': each,
10 | 'icon': 'emptyCircle'
11 | }
12 | })
13 | return {
14 | data: legendData,
15 | orient: 'vertical',
16 | right: '5%',
17 | top: '10%',
18 | formatter (name) {
19 | return legendName[name] != null ? legendName[name] : name
20 | }
21 | }
22 | }
23 |
24 | function getRadarTooltip (dataType, radar, digit) {
25 | const typeTemp = []
26 | const nameTemp = []
27 | radar.indicator.map((item, index) => {
28 | typeTemp[index] = dataType[item.name]
29 | nameTemp[index] = item.name
30 | })
31 | return {
32 | formatter (item) {
33 | const tpl = []
34 | tpl.push(itemPoint(item.color))
35 | tpl.push(`${item.name}
`)
36 | item.data.value.forEach((val, index) => {
37 | tpl.push(`${nameTemp[index]}: `)
38 | tpl.push(`${getFormated(val, typeTemp[index], digit)}
`)
39 | })
40 | return tpl.join('')
41 | }
42 | }
43 | }
44 |
45 | function getRadarSetting (rows, metrics, labelMap) {
46 | const settingBase = {
47 | indicator: [],
48 | // shape: 'circle',
49 | splitNumber: 5
50 | }
51 | let indicatorTemp = {}
52 | rows.forEach(items => {
53 | metrics.forEach(item => {
54 | const key = labelMap[item] != null
55 | ? labelMap[item]
56 | : item
57 | if (!indicatorTemp[key]) {
58 | indicatorTemp[key] = [items[item]]
59 | } else {
60 | indicatorTemp[key].push(items[item])
61 | }
62 | })
63 | })
64 | settingBase.indicator = Object.keys(indicatorTemp).map(key => {
65 | return {
66 | name: key,
67 | max: Math.max.apply(null, indicatorTemp[key])
68 | }
69 | })
70 | return settingBase
71 | }
72 |
73 | function getRadarSeries (args) {
74 | const {
75 | rows,
76 | dimension,
77 | metrics,
78 | radar,
79 | label,
80 | itemStyle,
81 | lineStyle,
82 | labelMap,
83 | areaStyle
84 | } = args
85 | let radarIndexObj = {}
86 | radar.indicator.forEach((item, index) => {
87 | const name = item.name
88 | radarIndexObj[name] = index
89 | })
90 |
91 | const seriesData = rows.map(row => {
92 | const serieData = {
93 | value: [],
94 | name: row[dimension]
95 | }
96 | Object.keys(row).forEach(key => {
97 | if (~metrics.indexOf(key)) {
98 | let k = labelMap[key] != null
99 | ? radarIndexObj[labelMap[key]]
100 | : radarIndexObj[key]
101 | serieData.value[k] = row[key]
102 | }
103 | })
104 | return serieData
105 | })
106 | const result = {
107 | name: dimension,
108 | type: 'radar',
109 | data: seriesData
110 | }
111 | if (label) result.label = label
112 | if (itemStyle) result.itemStyle = itemStyle
113 | if (lineStyle) result.lineStyle = lineStyle
114 | if (areaStyle) result.areaStyle = areaStyle
115 | return [result]
116 | }
117 |
118 | export const radar = (columns, rows, settings, extra) => {
119 | const {
120 | dataType = {},
121 | legendName = {},
122 | labelMap = {},
123 | dimension = columns[0],
124 | digit = 2,
125 | label,
126 | itemStyle,
127 | lineStyle,
128 | areaStyle
129 | } = settings
130 | const { tooltipVisible, legendVisible } = extra
131 | let metrics = columns.slice()
132 | if (settings.metrics) {
133 | metrics = settings.metrics
134 | } else {
135 | metrics.splice(columns.indexOf(dimension), 1)
136 | }
137 | const legend = legendVisible && getRadarLegend(rows, dimension, legendName)
138 | const radar = getRadarSetting(rows, metrics, labelMap)
139 | const tooltip = tooltipVisible && getRadarTooltip(dataType, radar, digit)
140 | const series = getRadarSeries({
141 | rows,
142 | dimension,
143 | metrics,
144 | radar,
145 | label,
146 | itemStyle,
147 | lineStyle,
148 | labelMap,
149 | areaStyle
150 | })
151 | const options = { legend, tooltip, radar, series }
152 | return options
153 | }
154 |
--------------------------------------------------------------------------------
/src/packages/ring/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { ring } from '../pie/main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeRing',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = ring
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/sankey/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { sankey } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeSankey',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = sankey
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/sankey/main.js:
--------------------------------------------------------------------------------
1 | import { getFormated } from '../../utils'
2 | import { itemPoint } from '../../echarts-base'
3 | import 'echarts/lib/chart/sankey'
4 |
5 | function getTooltip (args) {
6 | const {
7 | itemDataType,
8 | linksDataType,
9 | digit
10 | } = args
11 | return {
12 | trigger: 'item',
13 | formatter (item) {
14 | const tpl = []
15 | const { name, data, value, color } = item
16 | tpl.push(itemPoint(color))
17 | tpl.push(`${name} : `)
18 | if (data && data.source) {
19 | tpl.push(`${getFormated(value, linksDataType, digit)}
`)
20 | } else {
21 | tpl.push(`${getFormated(value, itemDataType, digit)}
`)
22 | }
23 | return tpl.join('')
24 | }
25 | }
26 | }
27 |
28 | function getSeries (args) {
29 | const {
30 | rows,
31 | dimension,
32 | metrics,
33 | links,
34 | valueFull,
35 | useDataValue,
36 | label,
37 | itemStyle,
38 | lineStyle
39 | } = args
40 | const dataMap = {}
41 | const seriesData = rows.map(row => {
42 | dataMap[row[dimension]] = row[metrics]
43 | return { name: row[dimension], value: row[metrics] }
44 | })
45 | let innerLinks = null
46 | if (useDataValue) {
47 | innerLinks = links.map(link => {
48 | return Object.assign({}, link, { value: dataMap[link.target] })
49 | })
50 | } else if (!valueFull) {
51 | innerLinks = links.map(link => {
52 | return link.value == null
53 | ? Object.assign({}, link, { value: dataMap[link.target] })
54 | : link
55 | })
56 | } else {
57 | innerLinks = links
58 | }
59 |
60 | const result = {
61 | type: 'sankey',
62 | data: seriesData,
63 | links: innerLinks
64 | }
65 | if (label) result.label = label
66 | if (itemStyle) result.itemStyle = itemStyle
67 | if (lineStyle) result.lineStyle = lineStyle
68 | return [result]
69 | }
70 |
71 | export const sankey = (columns, rows, settings, extra) => {
72 | const {
73 | links,
74 | dimension = columns[0],
75 | metrics = columns[1],
76 | dataType = ['normal', 'normal'],
77 | digit = 2,
78 | valueFull = false,
79 | useDataValue = false,
80 | label,
81 | itemStyle,
82 | lineStyle
83 | } = settings
84 |
85 | if (!links) {
86 | console.warn('links is needed in settings!')
87 | return
88 | }
89 |
90 | const itemDataType = dataType[0]
91 | const linksDataType = dataType[1]
92 | const tooltip = getTooltip({
93 | itemDataType,
94 | linksDataType,
95 | digit
96 | })
97 | const series = getSeries({
98 | rows,
99 | dimension,
100 | metrics,
101 | links,
102 | valueFull,
103 | useDataValue,
104 | label,
105 | itemStyle,
106 | lineStyle
107 | })
108 | return { tooltip, series }
109 | }
110 |
--------------------------------------------------------------------------------
/src/packages/waterfall/index.js:
--------------------------------------------------------------------------------
1 | import echarts from '../../echarts-base'
2 | import { waterfall } from './main'
3 | import Core from '../../core'
4 | export default {
5 | name: 'VeWaterfall',
6 | mixins: [Core],
7 | created () {
8 | this.chartHandler = waterfall
9 | this.echartsLib = echarts
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/waterfall/main.js:
--------------------------------------------------------------------------------
1 | import { getFormated } from '../../utils'
2 | import 'echarts/lib/chart/bar'
3 |
4 | function getWaterfallTooltip (dataType, digit) {
5 | return {
6 | trigger: 'axis',
7 | axisPointer: { type: 'shadow' },
8 | formatter (items) {
9 | const item = items[1]
10 | return [
11 | `${item.name}
${item.seriesName} :`,
12 | `${getFormated(item.value, dataType, digit)}`
13 | ].join('')
14 | }
15 | }
16 | }
17 |
18 | function getWaterfallXAxis (args) {
19 | const {
20 | dimension,
21 | rows,
22 | remainStatus,
23 | totalName,
24 | remainName,
25 | labelMap,
26 | xAxisName,
27 | axisVisible
28 | } = args
29 | let xAxisData = [totalName].concat(rows.map(row => row[dimension]))
30 | if (remainStatus === 'have-remain') {
31 | xAxisData = xAxisData.concat([remainName])
32 | }
33 |
34 | return {
35 | type: 'category',
36 | name: labelMap && labelMap[xAxisName] || xAxisName,
37 | splitLine: { show: false },
38 | data: xAxisData,
39 | show: axisVisible
40 | }
41 | }
42 |
43 | function getWaterfallYAxis (args) {
44 | const { dataType, yAxisName, axisVisible, digit, labelMap } = args
45 | return {
46 | type: 'value',
47 | name: labelMap[yAxisName] != null ? labelMap[yAxisName] : yAxisName,
48 | axisTick: { show: false },
49 | axisLabel: {
50 | formatter (val) {
51 | return getFormated(val, dataType, digit)
52 | }
53 | },
54 | show: axisVisible
55 | }
56 | }
57 |
58 | function getWaterfallSeries (args) {
59 | const {
60 | dataType,
61 | rows,
62 | metrics,
63 | totalNum,
64 | remainStatus,
65 | dataSum,
66 | digit
67 | } = args
68 | const seriesBase = { type: 'bar', stack: '总量' }
69 | let dataSumTemp = dataSum
70 | let totalNumTemp = totalNum
71 | let assistData
72 | let mainData
73 | const rowData = rows.map(row => row[metrics])
74 |
75 | if (remainStatus === 'have-remain') {
76 | assistData = [0].concat(rows.map(row => {
77 | totalNumTemp -= row[metrics]
78 | return totalNumTemp
79 | })).concat([0])
80 | mainData = [totalNum].concat(rowData).concat([totalNum - dataSum])
81 | } else {
82 | assistData = [0].concat(rows.map(row => {
83 | dataSumTemp -= row[metrics]
84 | return dataSumTemp
85 | }))
86 | mainData = [dataSum].concat(rowData)
87 | }
88 | const series = []
89 |
90 | series.push(Object.assign({
91 | name: '辅助',
92 | itemStyle: {
93 | normal: { opacity: 0 },
94 | emphasis: { opacity: 0 }
95 | },
96 | data: assistData
97 | }, seriesBase))
98 |
99 | series.push(Object.assign({
100 | name: '数值',
101 | label: {
102 | normal: {
103 | show: true,
104 | position: 'top',
105 | formatter (item) {
106 | return getFormated(item.value, dataType, digit)
107 | }
108 | }
109 | },
110 | data: mainData
111 | }, seriesBase))
112 | return series
113 | }
114 |
115 | function getWaterfallRemainStatus (dataSum, totalNum) {
116 | if (!totalNum) return 'not-total'
117 | return totalNum > dataSum ? 'have-remain' : 'none-remain'
118 | }
119 |
120 | export const waterfall = (columns, rows, settings, extra) => {
121 | const {
122 | dataType = 'normal',
123 | dimension = columns[0],
124 | totalName = '总计',
125 | totalNum,
126 | remainName = '其他',
127 | xAxisName = dimension,
128 | labelMap = {},
129 | axisVisible = true,
130 | digit = 2
131 | } = settings
132 | const { tooltipVisible } = extra
133 | let metricsTemp = columns.slice()
134 | metricsTemp.splice(metricsTemp.indexOf(dimension), 1)
135 | const metrics = metricsTemp[0]
136 | const yAxisName = metrics
137 | const tooltip = tooltipVisible && getWaterfallTooltip(dataType, digit)
138 | const dataSum = parseFloat(rows.reduce((pre, cur) => {
139 | return pre + Number(cur[metrics])
140 | }, 0).toFixed(digit))
141 | const remainStatus = getWaterfallRemainStatus(dataSum, totalNum)
142 | const xAxisParams = {
143 | dimension,
144 | rows,
145 | remainStatus,
146 | totalName,
147 | remainName,
148 | xAxisName,
149 | labelMap,
150 | axisVisible
151 | }
152 | const xAxis = getWaterfallXAxis(xAxisParams)
153 | const yAxis = getWaterfallYAxis({ dataType, yAxisName, axisVisible, digit, labelMap })
154 | const seriesParams = {
155 | dataType,
156 | rows,
157 | dimension,
158 | metrics,
159 | totalNum,
160 | remainStatus,
161 | dataSum,
162 | digit
163 | }
164 | const series = getWaterfallSeries(seriesParams)
165 | const options = { tooltip, xAxis, yAxis, series }
166 | return options
167 | }
168 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | export const numberFormat = (val, digits = 2) => {
2 | if (isNaN(+val)) return val
3 |
4 | let symbolMap = [
5 | { value: 1E18, symbol: 'E' },
6 | { value: 1E15, symbol: 'P' },
7 | { value: 1E12, symbol: 'T' },
8 | { value: 1E9, symbol: 'B' },
9 | { value: 1E6, symbol: 'M' },
10 | { value: 1E3, symbol: 'k' }
11 | ]
12 |
13 | for (let i = 0; i < symbolMap.length; i++) {
14 | if (Math.abs(val) >= symbolMap[i].value) {
15 | return (val / symbolMap[i].value).toFixed(digits) + symbolMap[i].symbol
16 | }
17 | }
18 |
19 | return val.toString()
20 | }
21 |
22 | export const formatTausends = (num) => {
23 | return String(num).replace(/^(\s+|-)?\d+(?=.?\d*($|\s))/g, (m) => {
24 | return m.replace(/(?=(?!\b)(\d{3})+$)/g, ',')
25 | })
26 | }
27 |
28 | export const getFormated = (val, type, digit = 2, defaultVal = '-') => {
29 | if (val == null || isNaN(val)) return defaultVal
30 | switch (type) {
31 | case 'KMB': return numberFormat(val)
32 | case 'percent': return `${parseFloat((val * 100).toFixed(digit))}%`
33 | case 'normal': return formatTausends(val)
34 | default: return val
35 | }
36 | }
37 |
38 | export const getLineKB = (s, v) => {
39 | const result = []
40 | result[0] = (s[1] - s[0]) / (v[1] - v[0])
41 | result[1] = s[0] - result[0] * v[0]
42 | return result
43 | }
44 |
45 | export const getStackMap = (stack) => {
46 | const stackMap = {}
47 | Object.keys(stack).forEach(item => {
48 | stack[item].forEach(name => {
49 | stackMap[name] = item
50 | })
51 | })
52 | return stackMap
53 | }
54 |
55 | export const $get = (url) => {
56 | return new Promise((resolve, reject) => {
57 | const xhr = new XMLHttpRequest()
58 | xhr.open('GET', url)
59 | xhr.send(null)
60 | xhr.onload = () => {
61 | resolve(JSON.parse(xhr.responseText))
62 | }
63 | xhr.onerror = () => {
64 | reject(JSON.parse(xhr.responseText))
65 | }
66 | })
67 | }
68 |
69 | const MAP_URL_PREFIX = 'https://unpkg.com/echarts@3.6.2/map/json/'
70 |
71 | export const getMapJSON = (position, positionJsonLink) => {
72 | const link = positionJsonLink || `${MAP_URL_PREFIX}${position}.json`
73 | return $get(link)
74 | }
75 |
76 | let mapPromise = null
77 |
78 | export const getBmap = (key) => {
79 | if (!mapPromise) {
80 | mapPromise = new Promise((resolve, reject) => {
81 | const callbackName = `bmap${Date.now()}`
82 | window[callbackName] = resolve
83 | const script = document.createElement('script')
84 | script.src = [
85 | 'https://api.map.baidu.com/api?v=2.0',
86 | `ak=${key}`,
87 | `callback=${callbackName}`
88 | ].join('&')
89 |
90 | document.body.appendChild(script)
91 | })
92 | }
93 | return mapPromise
94 | }
95 |
96 | export const clone = (v) => JSON.parse(JSON.stringify(v))
97 |
98 | export const getType = (v) => {
99 | return Object.prototype.toString.call(v)
100 | }
101 |
102 | export const toKebab = (v) => v.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
103 |
104 | export const isArray = (v) => {
105 | return getType(v) === '[object Array]'
106 | }
107 |
108 | export const isObject = (v) => {
109 | return getType(v) === '[object Object]'
110 | }
111 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 | import Vue from 'vue'
3 | import chartData from '../examples/data/index.js'
4 | import 'echarts/lib/component/tooltip'
5 | import 'echarts/lib/component/legend'
6 |
7 | window.Promise = require('es6-promise').Promise
8 | import {
9 | VeLine,
10 | VeBar,
11 | VeHistogram,
12 | VePie,
13 | VeRing,
14 | VeFunnel,
15 | VeRadar,
16 | VeWaterfall,
17 | VeChart,
18 | VeMap,
19 | VeSankey,
20 | VeHeatmap
21 | } from '../lib/index.esm'
22 |
23 | const comps = {
24 | line: VeLine,
25 | bar: VeBar,
26 | histogram: VeHistogram,
27 | pie: VePie,
28 | ring: VeRing,
29 | funnel: VeFunnel,
30 | radar: VeRadar,
31 | waterfall: VeWaterfall,
32 | chart: VeChart,
33 | map: VeMap,
34 | sankey: VeSankey,
35 | heatmap: VeHeatmap
36 | }
37 | let box
38 | let vm = {}
39 | createBox()
40 |
41 | afterEach(() => {
42 | if (vm.$el) document.body.removeChild(vm.$el)
43 | createBox()
44 | })
45 |
46 | Object.keys(comps).forEach(type => {
47 | chartData[type].data.forEach(item => {
48 | describe(type + ': ', () => {
49 | testMount(type, comps[type], item)
50 | })
51 | })
52 | })
53 |
54 | function testMount (type, comp, item) {
55 | it(item.name, () => {
56 | const Ctor = Vue.extend(comp)
57 | const vm = new Ctor({
58 | propsData: { data: item.data, settings: item.settings }
59 | }).$mount(box)
60 | expect(vm.$el.classList.contains('ve-' + type)).toEqual(true)
61 | })
62 | }
63 |
64 | function createBox () {
65 | box = document.createElement('div')
66 | box.id = 'app'
67 | document.body.appendChild(box)
68 | }
69 |
--------------------------------------------------------------------------------
/test/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 | frameworks: ['jasmine'],
4 | files: [
5 | './index.js'
6 | ],
7 | browsers: ['PhantomJS'],
8 | reporters: ['spec'],
9 | preprocessors: {
10 | './index.js': ['webpack']
11 | },
12 | webpack: {
13 | devtool: 'inline-source-map',
14 | module: {
15 | loaders: [
16 | {
17 | test: /\.(js)$/,
18 | loader: 'babel-loader'
19 | }
20 | ]
21 | },
22 | resolve: {
23 | extensions: ['.js', '.vue']
24 | }
25 | },
26 | singleRun: true
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/test/load/cdn/all/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/load/cdn/bmap/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/test/load/cdn/heatmap/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/test/load/cdn/line/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test/load/webpack/all/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
24 |
--------------------------------------------------------------------------------
/test/load/webpack/all/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | import VeCharts from '../../../../lib/index.common'
5 |
6 | Vue.use(VeCharts)
7 | /* eslint-disable no-new */
8 | new Vue({
9 | el: '#app',
10 | render: h => h(App)
11 | })
12 |
--------------------------------------------------------------------------------
/test/load/webpack/all/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | module.exports = {
6 | entry: {
7 | app: './index.js'
8 | },
9 | output: {
10 | path: path.resolve(__dirname, '../dist'),
11 | filename: 'index.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.js', '.vue']
16 | },
17 | devServer: {
18 | port: '8180',
19 | hot: true,
20 | stats: 'errors-only'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.vue$/,
26 | loader: 'vue-loader'
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader'
31 | },
32 | {
33 | test: /\.css$/,
34 | use: ['style-loader', 'css-loader']
35 | }
36 | ]
37 | },
38 | plugins: [
39 | new webpack.DefinePlugin({
40 | 'process.env': {
41 | NODE_ENV: '"development"'
42 | }
43 | }),
44 | new webpack.HotModuleReplacementPlugin(),
45 | new HtmlWebpackPlugin({
46 | filename: 'index.html',
47 | template: '../index.html',
48 | inject: true
49 | })
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/test/load/webpack/css-part/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
28 |
--------------------------------------------------------------------------------
/test/load/webpack/css-part/index.js:
--------------------------------------------------------------------------------
1 |
2 | import Vue from 'vue'
3 | import App from './App'
4 |
5 | /* eslint-disable no-new */
6 | new Vue({
7 | el: '#app',
8 | render: h => h(App)
9 | })
10 |
--------------------------------------------------------------------------------
/test/load/webpack/css-part/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | module.exports = {
6 | entry: {
7 | app: './index.js'
8 | },
9 | output: {
10 | path: path.resolve(__dirname, '../dist'),
11 | filename: 'index.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.js', '.vue']
16 | },
17 | devServer: {
18 | port: '8180',
19 | hot: true,
20 | stats: 'errors-only'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.vue$/,
26 | loader: 'vue-loader'
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader',
31 | query: { compact: false }
32 | },
33 | {
34 | test: /\.css$/,
35 | use: ['style-loader', 'css-loader']
36 | }
37 | ]
38 | },
39 | plugins: [
40 | new webpack.DefinePlugin({
41 | 'process.env': {
42 | NODE_ENV: '"development"'
43 | }
44 | }),
45 | new webpack.HotModuleReplacementPlugin(),
46 | new HtmlWebpackPlugin({
47 | filename: 'index.html',
48 | template: '../index.html',
49 | inject: true
50 | })
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/test/load/webpack/esm/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
52 |
--------------------------------------------------------------------------------
/test/load/webpack/esm/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | /* eslint-disable no-new */
5 | new Vue({
6 | el: '#app',
7 | render: h => h(App)
8 | })
9 |
--------------------------------------------------------------------------------
/test/load/webpack/esm/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | module.exports = {
6 | entry: {
7 | app: './index.js'
8 | },
9 | output: {
10 | path: path.resolve(__dirname, '../dist'),
11 | filename: 'index.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.js', '.vue']
16 | },
17 | devServer: {
18 | port: '8180',
19 | hot: true,
20 | stats: 'errors-only'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.vue$/,
26 | loader: 'vue-loader'
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader',
31 | query: { compact: false }
32 | },
33 | {
34 | test: /\.css$/,
35 | use: ['style-loader', 'css-loader']
36 | }
37 | ]
38 | },
39 | plugins: [
40 | new webpack.DefinePlugin({
41 | 'process.env': {
42 | NODE_ENV: '"development"'
43 | }
44 | }),
45 | new webpack.HotModuleReplacementPlugin(),
46 | new HtmlWebpackPlugin({
47 | filename: 'index.html',
48 | template: '../index.html',
49 | inject: true
50 | })
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/test/load/webpack/heatmap/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
40 |
--------------------------------------------------------------------------------
/test/load/webpack/heatmap/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | /* eslint-disable no-new */
5 | new Vue({
6 | el: '#app',
7 | render: h => h(App)
8 | })
9 |
--------------------------------------------------------------------------------
/test/load/webpack/heatmap/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | module.exports = {
6 | entry: {
7 | app: './index.js'
8 | },
9 | output: {
10 | path: path.resolve(__dirname, '../dist'),
11 | filename: 'index.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.js', '.vue']
16 | },
17 | devServer: {
18 | port: '8180',
19 | hot: true,
20 | stats: 'errors-only'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.vue$/,
26 | loader: 'vue-loader'
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader'
31 | },
32 | {
33 | test: /\.css$/,
34 | use: ['style-loader', 'css-loader']
35 | }
36 | ]
37 | },
38 | plugins: [
39 | new webpack.DefinePlugin({
40 | 'process.env': {
41 | NODE_ENV: '"development"'
42 | }
43 | }),
44 | new webpack.HotModuleReplacementPlugin(),
45 | new HtmlWebpackPlugin({
46 | filename: 'index.html',
47 | template: '../index.html',
48 | inject: true
49 | })
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/test/load/webpack/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/load/webpack/line/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
27 |
--------------------------------------------------------------------------------
/test/load/webpack/line/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | /* eslint-disable no-new */
5 | new Vue({
6 | el: '#app',
7 | render: h => h(App)
8 | })
9 |
--------------------------------------------------------------------------------
/test/load/webpack/line/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | module.exports = {
6 | entry: {
7 | app: './index.js'
8 | },
9 | output: {
10 | path: path.resolve(__dirname, '../dist'),
11 | filename: 'index.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.js', '.vue']
16 | },
17 | devServer: {
18 | port: '8180',
19 | hot: true,
20 | stats: 'errors-only'
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: /\.vue$/,
26 | loader: 'vue-loader'
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader'
31 | },
32 | {
33 | test: /\.css$/,
34 | use: ['style-loader', 'css-loader']
35 | }
36 | ]
37 | },
38 | plugins: [
39 | new webpack.DefinePlugin({
40 | 'process.env': {
41 | NODE_ENV: '"development"'
42 | }
43 | }),
44 | new webpack.HotModuleReplacementPlugin(),
45 | new HtmlWebpackPlugin({
46 | filename: 'index.html',
47 | template: '../index.html',
48 | inject: true
49 | })
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------