正在显示
18 个修改的文件
包含
2774 行增加
和
28 行删除
@@ -126,7 +126,8 @@ App({ | @@ -126,7 +126,8 @@ App({ | ||
126 | onshow_count: 0, | 126 | onshow_count: 0, |
127 | // baseUrl: "http://47.99.47.16:20000/", | 127 | // baseUrl: "http://47.99.47.16:20000/", |
128 | // baseUrl: "http://47.96.75.229:20000/", | 128 | // baseUrl: "http://47.96.75.229:20000/", |
129 | - baseUrl: "https://api.workai.com.cn/", | 129 | + baseUrl: "http://192.144.144.220:20000/", |
130 | + // baseUrl: "https://api.workai.com.cn/", | ||
130 | OSSUrl: "",//"https://oss.workai.com.cn/", | 131 | OSSUrl: "",//"https://oss.workai.com.cn/", |
131 | userInfo: null, | 132 | userInfo: null, |
132 | hasLogin: false, | 133 | hasLogin: false, |
@@ -14,6 +14,8 @@ | @@ -14,6 +14,8 @@ | ||
14 | "pages/main/advancepayment/home", | 14 | "pages/main/advancepayment/home", |
15 | 15 | ||
16 | "pages/main/finalpayment/home", | 16 | "pages/main/finalpayment/home", |
17 | + "pages/main/finalpayment/inputinfo/inputinfo", | ||
18 | + "pages/main/finalpayment/historydetail/historydetail", | ||
17 | "pages/login/login" | 19 | "pages/login/login" |
18 | ], | 20 | ], |
19 | "window": { | 21 | "window": { |
@@ -47,7 +47,7 @@ | @@ -47,7 +47,7 @@ | ||
47 | 47 | ||
48 | .text_333_28 { | 48 | .text_333_28 { |
49 | font-family: PingFangSC-Regular; | 49 | font-family: PingFangSC-Regular; |
50 | - font-size: 26rpx; | 50 | + font-size: 28rpx; |
51 | color: #333; | 51 | color: #333; |
52 | text-align: right; | 52 | text-align: right; |
53 | line-height: 80rpx; | 53 | line-height: 80rpx; |
@@ -57,6 +57,14 @@ | @@ -57,6 +57,14 @@ | ||
57 | font-family: PingFangSC-Regular; | 57 | font-family: PingFangSC-Regular; |
58 | font-size: 30rpx; | 58 | font-size: 30rpx; |
59 | color: #666; | 59 | color: #666; |
60 | + text-align: right; | ||
61 | +} | ||
62 | + | ||
63 | +.text_blue_28 { | ||
64 | + font-family: PingFangSC-Regular; | ||
65 | + font-size: 28rpx; | ||
66 | + color: #3795ff; | ||
67 | + text-align: right; | ||
60 | } | 68 | } |
61 | 69 | ||
62 | .text_333_30_bold { | 70 | .text_333_30_bold { |
@@ -67,7 +75,7 @@ | @@ -67,7 +75,7 @@ | ||
67 | 75 | ||
68 | .text_999_28 { | 76 | .text_999_28 { |
69 | font-family: PingFangSC-Regular; | 77 | font-family: PingFangSC-Regular; |
70 | - font-size: 26rpx; | 78 | + font-size: 28rpx; |
71 | color: #999; | 79 | color: #999; |
72 | text-align: right; | 80 | text-align: right; |
73 | line-height: 80rpx; | 81 | line-height: 80rpx; |
1 | <!--pages/main/advancepayment/home.wxml--> | 1 | <!--pages/main/advancepayment/home.wxml--> |
2 | <view class='page'> | 2 | <view class='page'> |
3 | - <scroll-view> | 3 | + <scroll-view style='margin-bottom:40rpx'> |
4 | <view style='padding:30rpx;background:#ffffff'> | 4 | <view style='padding:30rpx;background:#ffffff'> |
5 | <view> | 5 | <view> |
6 | <text class='text_gray_32'>当前选择月份</text> | 6 | <text class='text_gray_32'>当前选择月份</text> |
@@ -45,16 +45,61 @@ | @@ -45,16 +45,61 @@ | ||
45 | <text class='text_333_30_bold float_right'>32983000.00</text> | 45 | <text class='text_333_30_bold float_right'>32983000.00</text> |
46 | </view> | 46 | </view> |
47 | </view> | 47 | </view> |
48 | - <view style='padding:30rpx;positive:relative;width:92%;height:312rpx'> | 48 | + <view style='margin:30rpx;positive:relative;width:92%;height:312rpx'> |
49 | <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image> | 49 | <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image> |
50 | <view> | 50 | <view> |
51 | - <view style='position:absolute;z-index: 2'> | ||
52 | - <text >38382738</text> | ||
53 | - <!-- <text >38382739</text> | ||
54 | - <text >38382730</text> --> | 51 | + <view class='view_bg_wrap' style='margin-top: 44rpx;'> |
52 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
53 | + <text class='text_num_wrap'>3838.9</text> | ||
54 | + <text class='text_text_wrap'>本期应预扣预缴税额</text> | ||
55 | + </view> | ||
56 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
57 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
58 | + <text class='text_num_wrap'>10398.01</text> | ||
59 | + <text class='text_text_wrap'>已预扣预缴税额</text> | ||
60 | + </view> | ||
61 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
62 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
63 | + <text class='text_num_wrap'>133.09</text> | ||
64 | + <text class='text_text_wrap'>本期应预扣预缴税额</text> | ||
65 | + </view> | ||
66 | + </view> | ||
67 | + | ||
68 | + <view class='view_bg_wrap' style='margin-top: 180rpx;'> | ||
69 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
70 | + <text class='text_num_wrap'>30.8%</text> | ||
71 | + <text class='text_text_wrap'>使用税率</text> | ||
72 | + </view> | ||
73 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
74 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
75 | + <text class='text_num_wrap'>19106.91</text> | ||
76 | + <text class='text_text_wrap'>速算扣除数</text> | ||
77 | + </view> | ||
55 | </view> | 78 | </view> |
56 | - | ||
57 | </view> | 79 | </view> |
58 | </view> | 80 | </view> |
81 | + | ||
82 | + <view style='padding-left:30rpx;background:#ffffff'> | ||
83 | + <image class='icon_wrap' src="/images/rectangle_icon.png"></image> | ||
84 | + <text style='padding-left:20rpx' class='text_gray_32'>工资明细</text> | ||
85 | + </view> | ||
86 | + <view style='margin-top:2rpx;background:#ffffff;padding-bottom:30rpx'> | ||
87 | + <view style='padding:30rpx'> | ||
88 | + <text class='text_wrap_left'>公司名称</text> | ||
89 | + <text class='text_wrap_right'>400000.00</text> | ||
90 | + </view> | ||
91 | + <view style='padding:30rpx'> | ||
92 | + <text class='text_wrap_left'>计薪时间</text> | ||
93 | + <text class='text_wrap_right'>400000.00</text> | ||
94 | + </view> | ||
95 | + <view style='padding:30rpx'> | ||
96 | + <text class='text_wrap_left'>发薪时间</text> | ||
97 | + <text class='text_wrap_right'>400000.00</text> | ||
98 | + </view> | ||
99 | + <view style='padding:30rpx'> | ||
100 | + <text class='text_wrap_left'>实发工资</text> | ||
101 | + <text class='text_wrap_right'>400000.00</text> | ||
102 | + </view> | ||
103 | + </view> | ||
59 | </scroll-view> | 104 | </scroll-view> |
60 | -</view> | ||
105 | + </view> |
1 | /* pages/main/advancepayment/home.wxss */ | 1 | /* pages/main/advancepayment/home.wxss */ |
2 | -.page{ | 2 | + |
3 | +.page { | ||
3 | background-color: #fcfcfc; | 4 | background-color: #fcfcfc; |
4 | } | 5 | } |
5 | 6 | ||
6 | .text_gray_32 { | 7 | .text_gray_32 { |
7 | font-size: 32rpx; | 8 | font-size: 32rpx; |
8 | - color: #6C7596 ; | 9 | + color: #6c7596; |
9 | font-family: PingFangSC-Semibold; | 10 | font-family: PingFangSC-Semibold; |
10 | line-height: 100rpx; | 11 | line-height: 100rpx; |
11 | } | 12 | } |
@@ -15,10 +16,52 @@ | @@ -15,10 +16,52 @@ | ||
15 | width: 40rpx; | 16 | width: 40rpx; |
16 | height: 40rpx; | 17 | height: 40rpx; |
17 | margin-top: 30rpx; | 18 | margin-top: 30rpx; |
18 | - align-self: center | 19 | + align-self: center; |
19 | } | 20 | } |
20 | 21 | ||
21 | -.payment_img_bg{ | 22 | +.payment_img_bg { |
22 | width: 92%; | 23 | width: 92%; |
23 | height: 312rpx; | 24 | height: 312rpx; |
24 | -} | ||
25 | +} | ||
26 | + | ||
27 | +.icon_wrap { | ||
28 | + width: 8rpx; | ||
29 | + height: 28rpx; | ||
30 | +} | ||
31 | + | ||
32 | +.view_bg_wrap { | ||
33 | + position: absolute; | ||
34 | + z-index: 2; | ||
35 | + display: flex; | ||
36 | + width: 690rpx; | ||
37 | + flex-wrap: nowrap; | ||
38 | +} | ||
39 | + | ||
40 | +.text_num_wrap { | ||
41 | + font-family: PingFangSC-Semibold; | ||
42 | + font-size: 18px; | ||
43 | + color: #fff; | ||
44 | + text-align: center; | ||
45 | +} | ||
46 | + | ||
47 | +.text_text_wrap { | ||
48 | + font-family: PingFang-SC-Medium; | ||
49 | + font-size: 11px; | ||
50 | + color: #fff; | ||
51 | + text-align: center; | ||
52 | +} | ||
53 | + | ||
54 | +.text_wrap_left { | ||
55 | + font-family: PingFang-SC-Medium; | ||
56 | + font-size: 30rpx; | ||
57 | + color: #999; | ||
58 | + float: left | ||
59 | +} | ||
60 | + | ||
61 | +.text_wrap_right { | ||
62 | + font-family: PingFang-SC-Medium; | ||
63 | + font-size: 30rpx; | ||
64 | + color: #000; | ||
65 | + text-align: right; | ||
66 | + float: right | ||
67 | +} |
1 | +// pages/main/finalpayment/historydetail/historydetail.js | ||
2 | +var wxCharts = require('../../../../utils/wxcharts.js'); | ||
3 | +var app = getApp(); | ||
4 | +var pieChart = null; | ||
5 | +Page({ | ||
6 | + | ||
7 | + /** | ||
8 | + * Page initial data | ||
9 | + */ | ||
10 | + data: { | ||
11 | + | ||
12 | + }, | ||
13 | + | ||
14 | + /** | ||
15 | + * Lifecycle function--Called when page load | ||
16 | + */ | ||
17 | + onLoad: function (options) { | ||
18 | + var windowWidth = 320; | ||
19 | + try { | ||
20 | + var res = wx.getSystemInfoSync(); | ||
21 | + windowWidth = res.windowWidth; | ||
22 | + } catch (e) { | ||
23 | + console.error('getSystemInfoSync failed!'); | ||
24 | + } | ||
25 | + | ||
26 | + pieChart = new wxCharts({ | ||
27 | + animation: false, | ||
28 | + canvasId: 'pieCanvas', | ||
29 | + type: 'pie', | ||
30 | + series: [{ | ||
31 | + name: '成交量2', | ||
32 | + data: 35, | ||
33 | + }, { | ||
34 | + name: '成交量3', | ||
35 | + data: 78, | ||
36 | + }, { | ||
37 | + name: '成交量4', | ||
38 | + data: 63, | ||
39 | + }, { | ||
40 | + name: '成交量2', | ||
41 | + data: 35, | ||
42 | + }, { | ||
43 | + name: '成交量3', | ||
44 | + data: 78, | ||
45 | + }], | ||
46 | + width: windowWidth, | ||
47 | + height: 280, | ||
48 | + dataLabel: true, | ||
49 | + }); | ||
50 | + }, | ||
51 | + | ||
52 | + /** | ||
53 | + * Lifecycle function--Called when page is initially rendered | ||
54 | + */ | ||
55 | + onReady: function () { | ||
56 | + | ||
57 | + }, | ||
58 | + | ||
59 | + /** | ||
60 | + * Lifecycle function--Called when page show | ||
61 | + */ | ||
62 | + onShow: function () { | ||
63 | + | ||
64 | + }, | ||
65 | + | ||
66 | + /** | ||
67 | + * Lifecycle function--Called when page hide | ||
68 | + */ | ||
69 | + onHide: function () { | ||
70 | + | ||
71 | + }, | ||
72 | + | ||
73 | + /** | ||
74 | + * Lifecycle function--Called when page unload | ||
75 | + */ | ||
76 | + onUnload: function () { | ||
77 | + | ||
78 | + }, | ||
79 | + | ||
80 | + /** | ||
81 | + * Page event handler function--Called when user drop down | ||
82 | + */ | ||
83 | + onPullDownRefresh: function () { | ||
84 | + | ||
85 | + }, | ||
86 | + | ||
87 | + /** | ||
88 | + * Called when page reach bottom | ||
89 | + */ | ||
90 | + onReachBottom: function () { | ||
91 | + | ||
92 | + }, | ||
93 | + | ||
94 | + /** | ||
95 | + * Called when user click on the top right corner to share | ||
96 | + */ | ||
97 | + onShareAppMessage: function () { | ||
98 | + | ||
99 | + } | ||
100 | +}) |
1 | +<!--pages/main/finalpayment/historydetail/historydetail.wxml--> | ||
2 | +<view class='page'> | ||
3 | + <view style='padding:30rpx;'> | ||
4 | + <text class='text_gray_32'>当前选择月份</text> | ||
5 | + <view class='float_right'> | ||
6 | + <text class='text_gray_32'>2018年</text> | ||
7 | + <image class='arrow_wrap' style='margin-top: 8rpx' src='/images/arrow_right.png'></image> | ||
8 | + </view> | ||
9 | + </view> | ||
10 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
11 | + | ||
12 | + <view style='padding-left:30rpx;background:#ffffff;height:100rpx;'> | ||
13 | + <image class='icon_wrap' src="/images/rectangle_icon.png"></image> | ||
14 | + <text style='padding-left:20rpx;line-height:100rpx' class='text_gray_32'>专项附加扣除概览</text> | ||
15 | + </view> | ||
16 | + <view class='divide_line_f5f5f5'></view> | ||
17 | + | ||
18 | + <view class="container_wrap"> | ||
19 | + <canvas canvas-id="pieCanvas" class="canvas" style="height:560rpx" bindtouchstart="touchHandler"></canvas> | ||
20 | + </view> | ||
21 | + | ||
22 | + <view class='divide_line_f5f5f5'></view> | ||
23 | + | ||
24 | + <view style='display: flex;flex-wrap: nowrap;height:144rpx'> | ||
25 | + <view style='flex-grow: 1;justify-content:center;display: flex;flex-direction: column;'> | ||
26 | + <text class='text_num_wrap'>24138.2</text> | ||
27 | + <text class='text_text_wrap'>所得(元)</text> | ||
28 | + </view> | ||
29 | + <view style='width:2rpx;height:84rpx;background:#f5f5f5;'></view> | ||
30 | + <view style='flex-grow: 1;justify-content:center;display: flex;flex-direction: column;'> | ||
31 | + <text class='text_num_wrap'>5861.8</text> | ||
32 | + <text class='text_text_wrap'>应纳税额(元)</text> | ||
33 | + </view> | ||
34 | + </view> | ||
35 | + | ||
36 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
37 | + <view style='padding:0 30rpx;height:100rpx'> | ||
38 | + <text class='text_333_28_bold ' style='line-height:100rpx'>专项扣除</text> | ||
39 | + </view> | ||
40 | + | ||
41 | + <view> | ||
42 | + <view style='height:2rpx;width:94%;background:#f5f5f5;align-self:center'></view> | ||
43 | + <view style='padding:0 30rpx;height:80rpx'> | ||
44 | + <text class='text_333_28 float_left'>基本养老保险</text> | ||
45 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
46 | + </view> | ||
47 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
48 | + <view style='padding:0 30rpx;height:80rpx'> | ||
49 | + <text class='text_333_28 float_left'>基本失业保险</text> | ||
50 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
51 | + </view> | ||
52 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
53 | + <view style='padding:0 30rpx;height:80rpx'> | ||
54 | + <text class='text_333_28 float_left'>基本医疗保险</text> | ||
55 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
56 | + </view> | ||
57 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
58 | + <view style='padding:0 30rpx;height:80rpx'> | ||
59 | + <text class='text_333_28 float_left'>住房公积金</text> | ||
60 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
61 | + </view> | ||
62 | + </view> | ||
63 | + | ||
64 | +</view> |
1 | +/* pages/main/finalpayment/historydetail/historydetail.wxss */ | ||
2 | +.text_gray_32 { | ||
3 | + font-size: 32rpx; | ||
4 | + color: #6c7596; | ||
5 | + font-family: PingFangSC-Semibold; | ||
6 | +} | ||
7 | + | ||
8 | +.icon_wrap { | ||
9 | + width: 8rpx; | ||
10 | + height: 28rpx; | ||
11 | +} | ||
12 | + | ||
13 | +.text_num_wrap { | ||
14 | + font-family: PingFangSC-Semibold; | ||
15 | + font-size: 15px; | ||
16 | + color: #333; | ||
17 | + text-align: center; | ||
18 | +} | ||
19 | + | ||
20 | +.text_text_wrap { | ||
21 | + font-family: PingFang-SC-Medium; | ||
22 | + font-size: 11px; | ||
23 | + color: #333; | ||
24 | + text-align: center; | ||
25 | +} | ||
26 | + | ||
27 | +.container_wrap { | ||
28 | + height: 560rpx; | ||
29 | + display: flex; | ||
30 | + flex-direction: column; | ||
31 | + box-sizing: border-box; | ||
32 | + -webkit-text-size-adjust:none; | ||
33 | + -webkit-user-select: none; | ||
34 | + font-size: 24rpx; | ||
35 | + color: #6c7596; | ||
36 | + font-family: PingFang-SC-Medium; | ||
37 | +} | ||
38 | +.canvas { | ||
39 | + width: 100%; | ||
40 | + height: 280; | ||
41 | +} | ||
42 | + |
1 | // pages/main/finalpayment/home.js | 1 | // pages/main/finalpayment/home.js |
2 | +var wxCharts = require('../../../utils/wxcharts.js'); | ||
3 | +var app = getApp(); | ||
4 | +var pieChart = null; | ||
2 | Page({ | 5 | Page({ |
3 | 6 | ||
4 | /** | 7 | /** |
@@ -11,56 +14,99 @@ Page({ | @@ -11,56 +14,99 @@ Page({ | ||
11 | /** | 14 | /** |
12 | * Lifecycle function--Called when page load | 15 | * Lifecycle function--Called when page load |
13 | */ | 16 | */ |
14 | - onLoad: function (options) { | ||
15 | - | 17 | + onLoad: function(options) { |
18 | + var windowWidth = 320; | ||
19 | + try { | ||
20 | + var res = wx.getSystemInfoSync(); | ||
21 | + windowWidth = res.windowWidth; | ||
22 | + } catch (e) { | ||
23 | + console.error('getSystemInfoSync failed!'); | ||
24 | + } | ||
25 | + | ||
26 | + pieChart = new wxCharts({ | ||
27 | + animation: false, | ||
28 | + canvasId: 'pieCanvas', | ||
29 | + type: 'pie', | ||
30 | + series: [ { | ||
31 | + name: '成交量2', | ||
32 | + data: 35, | ||
33 | + }, { | ||
34 | + name: '成交量3', | ||
35 | + data: 78, | ||
36 | + }, { | ||
37 | + name: '成交量4', | ||
38 | + data: 63, | ||
39 | + }, { | ||
40 | + name: '成交量2', | ||
41 | + data: 35, | ||
42 | + }, { | ||
43 | + name: '成交量3', | ||
44 | + data: 78, | ||
45 | + }], | ||
46 | + width: windowWidth, | ||
47 | + height: 260, | ||
48 | + dataLabel: true, | ||
49 | + }); | ||
16 | }, | 50 | }, |
17 | 51 | ||
18 | /** | 52 | /** |
19 | * Lifecycle function--Called when page is initially rendered | 53 | * Lifecycle function--Called when page is initially rendered |
20 | */ | 54 | */ |
21 | - onReady: function () { | 55 | + onReady: function() { |
22 | 56 | ||
23 | }, | 57 | }, |
24 | 58 | ||
25 | /** | 59 | /** |
26 | * Lifecycle function--Called when page show | 60 | * Lifecycle function--Called when page show |
27 | */ | 61 | */ |
28 | - onShow: function () { | 62 | + onShow: function() { |
63 | + | ||
64 | + }, | ||
65 | + | ||
66 | + addinfo: function(e) { | ||
67 | + wx.navigateTo({ | ||
68 | + url: 'inputinfo/inputinfo', | ||
69 | + }) | ||
70 | + }, | ||
29 | 71 | ||
72 | + gohistory: function (e) { | ||
73 | + wx.navigateTo({ | ||
74 | + url: 'historydetail/historydetail', | ||
75 | + }) | ||
30 | }, | 76 | }, |
31 | 77 | ||
32 | /** | 78 | /** |
33 | * Lifecycle function--Called when page hide | 79 | * Lifecycle function--Called when page hide |
34 | */ | 80 | */ |
35 | - onHide: function () { | 81 | + onHide: function() { |
36 | 82 | ||
37 | }, | 83 | }, |
38 | 84 | ||
39 | /** | 85 | /** |
40 | * Lifecycle function--Called when page unload | 86 | * Lifecycle function--Called when page unload |
41 | */ | 87 | */ |
42 | - onUnload: function () { | 88 | + onUnload: function() { |
43 | 89 | ||
44 | }, | 90 | }, |
45 | 91 | ||
46 | /** | 92 | /** |
47 | * Page event handler function--Called when user drop down | 93 | * Page event handler function--Called when user drop down |
48 | */ | 94 | */ |
49 | - onPullDownRefresh: function () { | 95 | + onPullDownRefresh: function() { |
50 | 96 | ||
51 | }, | 97 | }, |
52 | 98 | ||
53 | /** | 99 | /** |
54 | * Called when page reach bottom | 100 | * Called when page reach bottom |
55 | */ | 101 | */ |
56 | - onReachBottom: function () { | 102 | + onReachBottom: function() { |
57 | 103 | ||
58 | }, | 104 | }, |
59 | 105 | ||
60 | /** | 106 | /** |
61 | * Called when user click on the top right corner to share | 107 | * Called when user click on the top right corner to share |
62 | */ | 108 | */ |
63 | - onShareAppMessage: function () { | 109 | + onShareAppMessage: function() { |
64 | 110 | ||
65 | } | 111 | } |
66 | }) | 112 | }) |
1 | <!--pages/main/finalpayment/home.wxml--> | 1 | <!--pages/main/finalpayment/home.wxml--> |
2 | -<text>pages/main/finalpayment/home.wxml</text> | 2 | +<view class='page'> |
3 | + <scroll-view style='margin-bottom:40rpx'> | ||
4 | + <view style='background:#ffffff'> | ||
5 | + <view style='padding:30rpx;'> | ||
6 | + <text class='text_gray_32'>当前选择月份</text> | ||
7 | + <view class='float_right'> | ||
8 | + <text class='text_gray_32'>2018年11月</text> | ||
9 | + <image class='arrow_wrap' src='/images/arrow_right.png'></image> | ||
10 | + </view> | ||
11 | + </view> | ||
12 | + <view class='divide_line_f5f5f5'></view> | ||
13 | + <view style='margin: 30rpx;positive:relative;width:92%;height:434rpx'> | ||
14 | + <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image> | ||
15 | + <view> | ||
16 | + <view class='view_bg_wrap' style='margin-top: 48rpx;'> | ||
17 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
18 | + <text class='text_num_wrap'>261609.90</text> | ||
19 | + <text class='text_text_wrap'>累计收入额</text> | ||
20 | + </view> | ||
21 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
22 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
23 | + <text class='text_num_wrap'>19106.91</text> | ||
24 | + <text class='text_text_wrap'>累计缴纳个税</text> | ||
25 | + </view> | ||
26 | + </view> | ||
27 | + <view class='view_bg_wrap' style='margin-top: 206rpx;'> | ||
28 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
29 | + <text class='text_num_wrap'>3838.9</text> | ||
30 | + <text class='text_text_wrap'>累计专项扣除</text> | ||
31 | + </view> | ||
32 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
33 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
34 | + <text class='text_num_wrap'>10398.01</text> | ||
35 | + <text class='text_text_wrap'>累计专项附加扣除</text> | ||
36 | + </view> | ||
37 | + <view style='width:2rpx;height:74rpx;background:#ffffff;'></view> | ||
38 | + <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> | ||
39 | + <text class='text_num_wrap'>133.09</text> | ||
40 | + <text class='text_text_wrap'>汇算补差</text> | ||
41 | + </view> | ||
42 | + </view> | ||
43 | + <view style='position: absolute;z-index: 2;display: flex;margin-top:370rpx;width:100%;justify-content: center;' bindtap='gohistory'> | ||
44 | + <text class='text_blue_wrap_28' style=''>查看历史缴税信息</text> | ||
45 | + </view> | ||
46 | + </view> | ||
47 | + </view> | ||
48 | + <view class='divide_line_f5f5f5'></view> | ||
49 | + <view style='padding-left:30rpx;background:#ffffff;height:100rpx;'> | ||
50 | + <image class='icon_wrap' src="/images/rectangle_icon.png"></image> | ||
51 | + <text style='padding-left:20rpx;line-height:100rpx' class='text_gray_32'>专项附加扣除概览</text> | ||
52 | + </view> | ||
53 | + </view> | ||
54 | + <view class="container_wrap"> | ||
55 | + <canvas canvas-id="pieCanvas" class="canvas" style="height:300px" bindtouchstart="touchHandler"></canvas> | ||
56 | + </view> | ||
57 | + </scroll-view> | ||
58 | + | ||
59 | + <view> | ||
60 | + <button class="btn_bottom" bindtap='addinfo'>录入信息</button> | ||
61 | + </view> | ||
62 | +</view> |
1 | -/* pages/main/finalpayment/home.wxss */ | ||
1 | +/* pages/main/finalpayment/home.wxss */ | ||
2 | +.arrow_wrap { | ||
3 | + position: relative; | ||
4 | + width: 40rpx; | ||
5 | + height: 40rpx; | ||
6 | + align-self: center; | ||
7 | + margin-top: 8rpx | ||
8 | +} | ||
9 | + | ||
10 | +.text_gray_32 { | ||
11 | + font-size: 32rpx; | ||
12 | + color: #6c7596; | ||
13 | + font-family: PingFangSC-Semibold; | ||
14 | +} | ||
15 | + | ||
16 | +.payment_img_bg { | ||
17 | + width: 92%; | ||
18 | + height: 360rpx; | ||
19 | +} | ||
20 | + | ||
21 | +.view_bg_wrap { | ||
22 | + position: absolute; | ||
23 | + z-index: 2; | ||
24 | + display: flex; | ||
25 | + width: 690rpx; | ||
26 | + flex-wrap: nowrap; | ||
27 | +} | ||
28 | + | ||
29 | +.text_num_wrap { | ||
30 | + font-family: PingFangSC-Semibold; | ||
31 | + font-size: 18px; | ||
32 | + color: #fff; | ||
33 | + text-align: center; | ||
34 | +} | ||
35 | + | ||
36 | +.text_text_wrap { | ||
37 | + font-family: PingFang-SC-Medium; | ||
38 | + font-size: 11px; | ||
39 | + color: #fff; | ||
40 | + text-align: center; | ||
41 | +} | ||
42 | + | ||
43 | +.text_blue_wrap_28{ | ||
44 | +font-size: 28rpx; | ||
45 | +color: #357AEB; | ||
46 | +letter-spacing: 0; | ||
47 | +} | ||
48 | + | ||
49 | +.icon_wrap { | ||
50 | + width: 8rpx; | ||
51 | + height: 28rpx; | ||
52 | +} | ||
53 | + | ||
54 | +.container_wrap { | ||
55 | + display: flex; | ||
56 | + flex-direction: column; | ||
57 | + box-sizing: border-box; | ||
58 | + -webkit-text-size-adjust:none; | ||
59 | + -webkit-user-select: none; | ||
60 | + font-size: 35rpx; | ||
61 | + color: #333; | ||
62 | + font-family: Helvetica,Arial,"Helvetica Neue","Droid Sans","Microsoft YaHei",sans-serif; | ||
63 | +} | ||
64 | +.canvas { | ||
65 | + width: 100%; | ||
66 | + height: 200px; | ||
67 | +} |
1 | +// pages/main/finalpayment/inputinfo/inputinfo.js | ||
2 | +Page({ | ||
3 | + | ||
4 | + /** | ||
5 | + * Page initial data | ||
6 | + */ | ||
7 | + data: { | ||
8 | + | ||
9 | + }, | ||
10 | + | ||
11 | + /** | ||
12 | + * Lifecycle function--Called when page load | ||
13 | + */ | ||
14 | + onLoad: function (options) { | ||
15 | + | ||
16 | + }, | ||
17 | + | ||
18 | + /** | ||
19 | + * Lifecycle function--Called when page is initially rendered | ||
20 | + */ | ||
21 | + onReady: function () { | ||
22 | + | ||
23 | + }, | ||
24 | + | ||
25 | + /** | ||
26 | + * Lifecycle function--Called when page show | ||
27 | + */ | ||
28 | + onShow: function () { | ||
29 | + | ||
30 | + }, | ||
31 | + | ||
32 | + /** | ||
33 | + * Lifecycle function--Called when page hide | ||
34 | + */ | ||
35 | + onHide: function () { | ||
36 | + | ||
37 | + }, | ||
38 | + | ||
39 | + /** | ||
40 | + * Lifecycle function--Called when page unload | ||
41 | + */ | ||
42 | + onUnload: function () { | ||
43 | + | ||
44 | + }, | ||
45 | + | ||
46 | + /** | ||
47 | + * Page event handler function--Called when user drop down | ||
48 | + */ | ||
49 | + onPullDownRefresh: function () { | ||
50 | + | ||
51 | + }, | ||
52 | + | ||
53 | + /** | ||
54 | + * Called when page reach bottom | ||
55 | + */ | ||
56 | + onReachBottom: function () { | ||
57 | + | ||
58 | + }, | ||
59 | + | ||
60 | + /** | ||
61 | + * Called when user click on the top right corner to share | ||
62 | + */ | ||
63 | + onShareAppMessage: function () { | ||
64 | + | ||
65 | + } | ||
66 | +}) |
1 | +<!--pages/main/finalpayment/inputinfo/inputinfo.wxml--> | ||
2 | +<view class='page'> | ||
3 | + <view style='padding:30rpx;'> | ||
4 | + <text class='text_gray_32'>当前选择月份</text> | ||
5 | + <view class='float_right'> | ||
6 | + <text class='text_gray_32'>2018年</text> | ||
7 | + <image class='arrow_wrap' style='margin-top: 8rpx'src='/images/arrow_right.png'></image> | ||
8 | + </view> | ||
9 | + </view> | ||
10 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
11 | + <view style='padding:0 30rpx;height:100rpx'> | ||
12 | + <text class='text_333_28_bold ' style='line-height:100rpx'>专项扣除</text> | ||
13 | + <text class='text_blue_28 float_right' style='line-height:100rpx'>编辑</text> | ||
14 | + </view> | ||
15 | + | ||
16 | + <view> | ||
17 | + <view style='height:2rpx;width:94%;background:#f5f5f5;align-self:center'></view> | ||
18 | + <view style='padding:0 30rpx;height:80rpx'> | ||
19 | + <text class='text_333_28 float_left'>基本养老保险</text> | ||
20 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
21 | + </view> | ||
22 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
23 | + <view style='padding:0 30rpx;height:80rpx'> | ||
24 | + <text class='text_333_28 float_left'>基本失业保险</text> | ||
25 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
26 | + </view> | ||
27 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
28 | + <view style='padding:0 30rpx;height:80rpx'> | ||
29 | + <text class='text_333_28 float_left'>基本医疗保险</text> | ||
30 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
31 | + </view> | ||
32 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
33 | + <view style='padding:0 30rpx;height:80rpx'> | ||
34 | + <text class='text_333_28 float_left'>住房公积金</text> | ||
35 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
36 | + </view> | ||
37 | + </view> | ||
38 | + | ||
39 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
40 | + <view style='padding:0 30rpx;height:100rpx'> | ||
41 | + <text class='text_333_28_bold ' style='line-height:100rpx'>法定扣除</text> | ||
42 | + <text class='text_blue_28 float_right' style='line-height:100rpx'>编辑</text> | ||
43 | + </view> | ||
44 | + <view> | ||
45 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
46 | + <view style='padding:0 30rpx;height:80rpx'> | ||
47 | + <text class='text_333_28 float_left'>捐赠</text> | ||
48 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
49 | + </view> | ||
50 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
51 | + <view style='padding:0 30rpx;height:80rpx'> | ||
52 | + <text class='text_333_28 float_left'>总额</text> | ||
53 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
54 | + </view> | ||
55 | + </view> | ||
56 | + | ||
57 | + | ||
58 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
59 | + <view style='padding:0 30rpx;height:100rpx'> | ||
60 | + <text class='text_333_28_bold ' style='line-height:100rpx'>专项附加扣除</text> | ||
61 | + <text class='text_blue_28 float_right' style='line-height:100rpx'>编辑</text> | ||
62 | + </view> | ||
63 | + <view> | ||
64 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
65 | + <view style='padding:0 30rpx;height:80rpx'> | ||
66 | + <text class='text_333_28 float_left'>继续教育</text> | ||
67 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
68 | + </view> | ||
69 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
70 | + <view style='padding:0 30rpx;height:80rpx'> | ||
71 | + <text class='text_333_28 float_left'>子女教育</text> | ||
72 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
73 | + </view> | ||
74 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
75 | + <view style='padding:0 30rpx;height:80rpx'> | ||
76 | + <text class='text_333_28 float_left'>大病医疗</text> | ||
77 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
78 | + </view> | ||
79 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
80 | + <view style='padding:0 30rpx;height:80rpx'> | ||
81 | + <text class='text_333_28 float_left'>住房租金</text> | ||
82 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
83 | + </view> | ||
84 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
85 | + <view style='padding:0 30rpx;height:80rpx'> | ||
86 | + <text class='text_333_28 float_left'>赡养老人</text> | ||
87 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
88 | + </view> | ||
89 | + </view> | ||
90 | + | ||
91 | + <view style='height:20rpx;width:100%;background:#f5f5f5'></view> | ||
92 | + <view style='padding:0 30rpx;height:100rpx'> | ||
93 | + <text class='text_333_28_bold ' style='line-height:100rpx'>收入及个税</text> | ||
94 | + <text class='text_blue_28 float_right' style='line-height:100rpx'>编辑</text> | ||
95 | + </view> | ||
96 | + <view> | ||
97 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
98 | + <view style='padding:0 30rpx;height:80rpx'> | ||
99 | + <text class='text_333_28 float_left'>收入类型</text> | ||
100 | + <image class='arrow_wrap' src='/images/arrow_right.png'></image> | ||
101 | + <text class='text_333_28 float_right'>工作</text> | ||
102 | + </view> | ||
103 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
104 | + <view style='padding:0 30rpx;height:80rpx'> | ||
105 | + <text class='text_333_28 float_left'>收入金额(含免税部分)</text> | ||
106 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
107 | + </view> | ||
108 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
109 | + <view style='padding:0 30rpx;height:80rpx'> | ||
110 | + <text class='text_333_28 float_left'>已申报个税</text> | ||
111 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
112 | + </view> | ||
113 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
114 | + <view style='padding:0 30rpx;height:80rpx'> | ||
115 | + <text class='text_333_28 float_left'>申报单位</text> | ||
116 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='北京小爱智能科技'> </input> | ||
117 | + </view> | ||
118 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
119 | + <view style='padding:0 30rpx;height:80rpx'> | ||
120 | + <text class='text_333_28 float_left'>申报地</text> | ||
121 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='北京 朝阳'> </input> | ||
122 | + </view> | ||
123 | + <view style='height:2rpx;width:94%;background:#f5f5f5'></view> | ||
124 | + <view style='padding:0 30rpx;height:80rpx'> | ||
125 | + <text class='text_333_28 float_left'>总额</text> | ||
126 | + <input class='text_999_28 float_right' style='margin-top:12rpx' value='500.00'> </input> | ||
127 | + </view> | ||
128 | + </view> | ||
129 | +</view> |
1 | +/* pages/main/finalpayment/inputinfo/inputinfo.wxss */ | ||
2 | +.text_gray_32 { | ||
3 | + font-size: 32rpx; | ||
4 | + color: #6c7596; | ||
5 | + font-family: PingFangSC-Semibold; | ||
6 | +} | ||
7 | + | ||
8 | +.text_333_28_bold { | ||
9 | + font-family: PingFangSC-Semibold; | ||
10 | + font-size: 28rpx; | ||
11 | + color: #333; | ||
12 | + text-align: left; | ||
13 | +} | ||
14 | + | ||
15 | +.arrow_wrap { | ||
16 | + position: relative; | ||
17 | + width: 40rpx; | ||
18 | + height: 40rpx; | ||
19 | + align-self: center; | ||
20 | +} |
utils/wxcharts.js
0 → 100755
1 | +/* | ||
2 | + * charts for WeChat small app v1.0 | ||
3 | + * | ||
4 | + * https://github.com/xiaolin3303/wx-charts | ||
5 | + * 2016-11-28 | ||
6 | + * | ||
7 | + * Designed and built with all the love of Web | ||
8 | + */ | ||
9 | + | ||
10 | +'use strict'; | ||
11 | + | ||
12 | +var config = { | ||
13 | + yAxisWidth: 15, | ||
14 | + yAxisSplit: 5, | ||
15 | + xAxisHeight: 15, | ||
16 | + xAxisLineHeight: 15, | ||
17 | + legendHeight: 15, | ||
18 | + yAxisTitleWidth: 15, | ||
19 | + padding: 12, | ||
20 | + columePadding: 3, | ||
21 | + fontSize: 10, | ||
22 | + dataPointShape: ['diamond', 'circle', 'triangle', 'rect'], | ||
23 | + colors: ['#7cb5ec', '#f7a35c', '#434348', '#90ed7d', '#f15c80', '#8085e9'], | ||
24 | + pieChartLinePadding: 25, | ||
25 | + pieChartTextPadding: 15, | ||
26 | + xAxisTextPadding: 3, | ||
27 | + titleColor: '#333333', | ||
28 | + titleFontSize: 20, | ||
29 | + subtitleColor: '#999999', | ||
30 | + subtitleFontSize: 15, | ||
31 | + toolTipPadding: 3, | ||
32 | + toolTipBackground: '#000000', | ||
33 | + toolTipOpacity: 0.7, | ||
34 | + toolTipLineHeight: 14, | ||
35 | + radarGridCount: 3, | ||
36 | + radarLabelTextMargin: 15 | ||
37 | +}; | ||
38 | + | ||
39 | +// Object.assign polyfill | ||
40 | +// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign | ||
41 | +function assign(target, varArgs) { | ||
42 | + if (target == null) { | ||
43 | + // TypeError if undefined or null | ||
44 | + throw new TypeError('Cannot convert undefined or null to object'); | ||
45 | + } | ||
46 | + | ||
47 | + var to = Object(target); | ||
48 | + | ||
49 | + for (var index = 1; index < arguments.length; index++) { | ||
50 | + var nextSource = arguments[index]; | ||
51 | + | ||
52 | + if (nextSource != null) { | ||
53 | + // Skip over if undefined or null | ||
54 | + for (var nextKey in nextSource) { | ||
55 | + // Avoid bugs when hasOwnProperty is shadowed | ||
56 | + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { | ||
57 | + to[nextKey] = nextSource[nextKey]; | ||
58 | + } | ||
59 | + } | ||
60 | + } | ||
61 | + } | ||
62 | + return to; | ||
63 | +} | ||
64 | + | ||
65 | +var util = { | ||
66 | + toFixed: function toFixed(num, limit) { | ||
67 | + limit = limit || 2; | ||
68 | + if (this.isFloat(num)) { | ||
69 | + num = num.toFixed(limit); | ||
70 | + } | ||
71 | + return num; | ||
72 | + }, | ||
73 | + isFloat: function isFloat(num) { | ||
74 | + return num % 1 !== 0; | ||
75 | + }, | ||
76 | + approximatelyEqual: function approximatelyEqual(num1, num2) { | ||
77 | + return Math.abs(num1 - num2) < 1e-10; | ||
78 | + }, | ||
79 | + isSameSign: function isSameSign(num1, num2) { | ||
80 | + return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2; | ||
81 | + }, | ||
82 | + isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) { | ||
83 | + return this.isSameSign(p1.x, p2.x); | ||
84 | + }, | ||
85 | + isCollision: function isCollision(obj1, obj2) { | ||
86 | + obj1.end = {}; | ||
87 | + obj1.end.x = obj1.start.x + obj1.width; | ||
88 | + obj1.end.y = obj1.start.y - obj1.height; | ||
89 | + obj2.end = {}; | ||
90 | + obj2.end.x = obj2.start.x + obj2.width; | ||
91 | + obj2.end.y = obj2.start.y - obj2.height; | ||
92 | + var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y < obj1.end.y; | ||
93 | + | ||
94 | + return !flag; | ||
95 | + } | ||
96 | +}; | ||
97 | + | ||
98 | +function findRange(num, type, limit) { | ||
99 | + if (isNaN(num)) { | ||
100 | + throw new Error('[wxCharts] unvalid series data!'); | ||
101 | + } | ||
102 | + limit = limit || 10; | ||
103 | + type = type ? type : 'upper'; | ||
104 | + var multiple = 1; | ||
105 | + while (limit < 1) { | ||
106 | + limit *= 10; | ||
107 | + multiple *= 10; | ||
108 | + } | ||
109 | + if (type === 'upper') { | ||
110 | + num = Math.ceil(num * multiple); | ||
111 | + } else { | ||
112 | + num = Math.floor(num * multiple); | ||
113 | + } | ||
114 | + while (num % limit !== 0) { | ||
115 | + if (type === 'upper') { | ||
116 | + num++; | ||
117 | + } else { | ||
118 | + num--; | ||
119 | + } | ||
120 | + } | ||
121 | + | ||
122 | + return num / multiple; | ||
123 | +} | ||
124 | + | ||
125 | +function calValidDistance(distance, chartData, config, opts) { | ||
126 | + | ||
127 | + var dataChartAreaWidth = opts.width - config.padding - chartData.xAxisPoints[0]; | ||
128 | + var dataChartWidth = chartData.eachSpacing * opts.categories.length; | ||
129 | + var validDistance = distance; | ||
130 | + if (distance >= 0) { | ||
131 | + validDistance = 0; | ||
132 | + } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) { | ||
133 | + validDistance = dataChartAreaWidth - dataChartWidth; | ||
134 | + } | ||
135 | + return validDistance; | ||
136 | +} | ||
137 | + | ||
138 | +function isInAngleRange(angle, startAngle, endAngle) { | ||
139 | + function adjust(angle) { | ||
140 | + while (angle < 0) { | ||
141 | + angle += 2 * Math.PI; | ||
142 | + } | ||
143 | + while (angle > 2 * Math.PI) { | ||
144 | + angle -= 2 * Math.PI; | ||
145 | + } | ||
146 | + | ||
147 | + return angle; | ||
148 | + } | ||
149 | + | ||
150 | + angle = adjust(angle); | ||
151 | + startAngle = adjust(startAngle); | ||
152 | + endAngle = adjust(endAngle); | ||
153 | + if (startAngle > endAngle) { | ||
154 | + endAngle += 2 * Math.PI; | ||
155 | + if (angle < startAngle) { | ||
156 | + angle += 2 * Math.PI; | ||
157 | + } | ||
158 | + } | ||
159 | + | ||
160 | + return angle >= startAngle && angle <= endAngle; | ||
161 | +} | ||
162 | + | ||
163 | +function calRotateTranslate(x, y, h) { | ||
164 | + var xv = x; | ||
165 | + var yv = h - y; | ||
166 | + | ||
167 | + var transX = xv + (h - yv - xv) / Math.sqrt(2); | ||
168 | + transX *= -1; | ||
169 | + | ||
170 | + var transY = (h - yv) * (Math.sqrt(2) - 1) - (h - yv - xv) / Math.sqrt(2); | ||
171 | + | ||
172 | + return { | ||
173 | + transX: transX, | ||
174 | + transY: transY | ||
175 | + }; | ||
176 | +} | ||
177 | + | ||
178 | +function createCurveControlPoints(points, i) { | ||
179 | + | ||
180 | + function isNotMiddlePoint(points, i) { | ||
181 | + if (points[i - 1] && points[i + 1]) { | ||
182 | + return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y, points[i + 1].y); | ||
183 | + } else { | ||
184 | + return false; | ||
185 | + } | ||
186 | + } | ||
187 | + | ||
188 | + var a = 0.2; | ||
189 | + var b = 0.2; | ||
190 | + var pAx = null; | ||
191 | + var pAy = null; | ||
192 | + var pBx = null; | ||
193 | + var pBy = null; | ||
194 | + if (i < 1) { | ||
195 | + pAx = points[0].x + (points[1].x - points[0].x) * a; | ||
196 | + pAy = points[0].y + (points[1].y - points[0].y) * a; | ||
197 | + } else { | ||
198 | + pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a; | ||
199 | + pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a; | ||
200 | + } | ||
201 | + | ||
202 | + if (i > points.length - 3) { | ||
203 | + var last = points.length - 1; | ||
204 | + pBx = points[last].x - (points[last].x - points[last - 1].x) * b; | ||
205 | + pBy = points[last].y - (points[last].y - points[last - 1].y) * b; | ||
206 | + } else { | ||
207 | + pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b; | ||
208 | + pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b; | ||
209 | + } | ||
210 | + | ||
211 | + // fix issue https://github.com/xiaolin3303/wx-charts/issues/79 | ||
212 | + if (isNotMiddlePoint(points, i + 1)) { | ||
213 | + pBy = points[i + 1].y; | ||
214 | + } | ||
215 | + if (isNotMiddlePoint(points, i)) { | ||
216 | + pAy = points[i].y; | ||
217 | + } | ||
218 | + | ||
219 | + return { | ||
220 | + ctrA: { x: pAx, y: pAy }, | ||
221 | + ctrB: { x: pBx, y: pBy } | ||
222 | + }; | ||
223 | +} | ||
224 | + | ||
225 | +function convertCoordinateOrigin(x, y, center) { | ||
226 | + return { | ||
227 | + x: center.x + x, | ||
228 | + y: center.y - y | ||
229 | + }; | ||
230 | +} | ||
231 | + | ||
232 | +function avoidCollision(obj, target) { | ||
233 | + if (target) { | ||
234 | + // is collision test | ||
235 | + while (util.isCollision(obj, target)) { | ||
236 | + if (obj.start.x > 0) { | ||
237 | + obj.start.y--; | ||
238 | + } else if (obj.start.x < 0) { | ||
239 | + obj.start.y++; | ||
240 | + } else { | ||
241 | + if (obj.start.y > 0) { | ||
242 | + obj.start.y++; | ||
243 | + } else { | ||
244 | + obj.start.y--; | ||
245 | + } | ||
246 | + } | ||
247 | + } | ||
248 | + } | ||
249 | + return obj; | ||
250 | +} | ||
251 | + | ||
252 | +function fillSeriesColor(series, config) { | ||
253 | + var index = 0; | ||
254 | + return series.map(function (item) { | ||
255 | + if (!item.color) { | ||
256 | + item.color = config.colors[index]; | ||
257 | + index = (index + 1) % config.colors.length; | ||
258 | + } | ||
259 | + return item; | ||
260 | + }); | ||
261 | +} | ||
262 | + | ||
263 | +function getDataRange(minData, maxData) { | ||
264 | + var limit = 0; | ||
265 | + var range = maxData - minData; | ||
266 | + if (range >= 10000) { | ||
267 | + limit = 1000; | ||
268 | + } else if (range >= 1000) { | ||
269 | + limit = 100; | ||
270 | + } else if (range >= 100) { | ||
271 | + limit = 10; | ||
272 | + } else if (range >= 10) { | ||
273 | + limit = 5; | ||
274 | + } else if (range >= 1) { | ||
275 | + limit = 1; | ||
276 | + } else if (range >= 0.1) { | ||
277 | + limit = 0.1; | ||
278 | + } else { | ||
279 | + limit = 0.01; | ||
280 | + } | ||
281 | + return { | ||
282 | + minRange: findRange(minData, 'lower', limit), | ||
283 | + maxRange: findRange(maxData, 'upper', limit) | ||
284 | + }; | ||
285 | +} | ||
286 | + | ||
287 | +function measureText(text) { | ||
288 | + var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; | ||
289 | + | ||
290 | + // wx canvas 未实现measureText方法, 此处自行实现 | ||
291 | + text = String(text); | ||
292 | + var text = text.split(''); | ||
293 | + var width = 0; | ||
294 | + text.forEach(function (item) { | ||
295 | + if (/[a-zA-Z]/.test(item)) { | ||
296 | + width += 7; | ||
297 | + } else if (/[0-9]/.test(item)) { | ||
298 | + width += 5.5; | ||
299 | + } else if (/\./.test(item)) { | ||
300 | + width += 2.7; | ||
301 | + } else if (/-/.test(item)) { | ||
302 | + width += 3.25; | ||
303 | + } else if (/[\u4e00-\u9fa5]/.test(item)) { | ||
304 | + width += 10; | ||
305 | + } else if (/\(|\)/.test(item)) { | ||
306 | + width += 3.73; | ||
307 | + } else if (/\s/.test(item)) { | ||
308 | + width += 2.5; | ||
309 | + } else if (/%/.test(item)) { | ||
310 | + width += 8; | ||
311 | + } else { | ||
312 | + width += 10; | ||
313 | + } | ||
314 | + }); | ||
315 | + return width * fontSize / 10; | ||
316 | +} | ||
317 | + | ||
318 | +function dataCombine(series) { | ||
319 | + return series.reduce(function (a, b) { | ||
320 | + return (a.data ? a.data : a).concat(b.data); | ||
321 | + }, []); | ||
322 | +} | ||
323 | + | ||
324 | +function getSeriesDataItem(series, index) { | ||
325 | + var data = []; | ||
326 | + series.forEach(function (item) { | ||
327 | + if (item.data[index] !== null && typeof item.data[index] !== 'undefinded') { | ||
328 | + var seriesItem = {}; | ||
329 | + seriesItem.color = item.color; | ||
330 | + seriesItem.name = item.name; | ||
331 | + seriesItem.data = item.format ? item.format(item.data[index]) : item.data[index]; | ||
332 | + data.push(seriesItem); | ||
333 | + } | ||
334 | + }); | ||
335 | + | ||
336 | + return data; | ||
337 | +} | ||
338 | + | ||
339 | + | ||
340 | + | ||
341 | +function getMaxTextListLength(list) { | ||
342 | + var lengthList = list.map(function (item) { | ||
343 | + return measureText(item); | ||
344 | + }); | ||
345 | + return Math.max.apply(null, lengthList); | ||
346 | +} | ||
347 | + | ||
348 | +function getRadarCoordinateSeries(length) { | ||
349 | + var eachAngle = 2 * Math.PI / length; | ||
350 | + var CoordinateSeries = []; | ||
351 | + for (var i = 0; i < length; i++) { | ||
352 | + CoordinateSeries.push(eachAngle * i); | ||
353 | + } | ||
354 | + | ||
355 | + return CoordinateSeries.map(function (item) { | ||
356 | + return -1 * item + Math.PI / 2; | ||
357 | + }); | ||
358 | +} | ||
359 | + | ||
360 | +function getToolTipData(seriesData, calPoints, index, categories) { | ||
361 | + var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; | ||
362 | + | ||
363 | + var textList = seriesData.map(function (item) { | ||
364 | + return { | ||
365 | + text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data, | ||
366 | + color: item.color | ||
367 | + }; | ||
368 | + }); | ||
369 | + var validCalPoints = []; | ||
370 | + var offset = { | ||
371 | + x: 0, | ||
372 | + y: 0 | ||
373 | + }; | ||
374 | + calPoints.forEach(function (points) { | ||
375 | + if (typeof points[index] !== 'undefinded' && points[index] !== null) { | ||
376 | + validCalPoints.push(points[index]); | ||
377 | + } | ||
378 | + }); | ||
379 | + validCalPoints.forEach(function (item) { | ||
380 | + offset.x = Math.round(item.x); | ||
381 | + offset.y += item.y; | ||
382 | + }); | ||
383 | + | ||
384 | + offset.y /= validCalPoints.length; | ||
385 | + return { textList: textList, offset: offset }; | ||
386 | +} | ||
387 | + | ||
388 | +function findCurrentIndex(currentPoints, xAxisPoints, opts, config) { | ||
389 | + var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; | ||
390 | + | ||
391 | + var currentIndex = -1; | ||
392 | + if (isInExactChartArea(currentPoints, opts, config)) { | ||
393 | + xAxisPoints.forEach(function (item, index) { | ||
394 | + if (currentPoints.x + offset > item) { | ||
395 | + currentIndex = index; | ||
396 | + } | ||
397 | + }); | ||
398 | + } | ||
399 | + | ||
400 | + return currentIndex; | ||
401 | +} | ||
402 | + | ||
403 | +function isInExactChartArea(currentPoints, opts, config) { | ||
404 | + return currentPoints.x < opts.width - config.padding && currentPoints.x > config.padding + config.yAxisWidth + config.yAxisTitleWidth && currentPoints.y > config.padding && currentPoints.y < opts.height - config.legendHeight - config.xAxisHeight - config.padding; | ||
405 | +} | ||
406 | + | ||
407 | +function findRadarChartCurrentIndex(currentPoints, radarData, count) { | ||
408 | + var eachAngleArea = 2 * Math.PI / count; | ||
409 | + var currentIndex = -1; | ||
410 | + if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) { | ||
411 | + var fixAngle = function fixAngle(angle) { | ||
412 | + if (angle < 0) { | ||
413 | + angle += 2 * Math.PI; | ||
414 | + } | ||
415 | + if (angle > 2 * Math.PI) { | ||
416 | + angle -= 2 * Math.PI; | ||
417 | + } | ||
418 | + return angle; | ||
419 | + }; | ||
420 | + | ||
421 | + var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x); | ||
422 | + angle = -1 * angle; | ||
423 | + if (angle < 0) { | ||
424 | + angle += 2 * Math.PI; | ||
425 | + } | ||
426 | + | ||
427 | + var angleList = radarData.angleList.map(function (item) { | ||
428 | + item = fixAngle(-1 * item); | ||
429 | + | ||
430 | + return item; | ||
431 | + }); | ||
432 | + | ||
433 | + angleList.forEach(function (item, index) { | ||
434 | + var rangeStart = fixAngle(item - eachAngleArea / 2); | ||
435 | + var rangeEnd = fixAngle(item + eachAngleArea / 2); | ||
436 | + if (rangeEnd < rangeStart) { | ||
437 | + rangeEnd += 2 * Math.PI; | ||
438 | + } | ||
439 | + if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <= rangeEnd) { | ||
440 | + currentIndex = index; | ||
441 | + } | ||
442 | + }); | ||
443 | + } | ||
444 | + | ||
445 | + return currentIndex; | ||
446 | +} | ||
447 | + | ||
448 | +function findPieChartCurrentIndex(currentPoints, pieData) { | ||
449 | + var currentIndex = -1; | ||
450 | + if (isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) { | ||
451 | + var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x); | ||
452 | + angle = -angle; | ||
453 | + for (var i = 0, len = pieData.series.length; i < len; i++) { | ||
454 | + var item = pieData.series[i]; | ||
455 | + if (isInAngleRange(angle, item._start_, item._start_ + item._proportion_ * 2 * Math.PI)) { | ||
456 | + currentIndex = i; | ||
457 | + break; | ||
458 | + } | ||
459 | + } | ||
460 | + } | ||
461 | + | ||
462 | + return currentIndex; | ||
463 | +} | ||
464 | + | ||
465 | +function isInExactPieChartArea(currentPoints, center, radius) { | ||
466 | + return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2); | ||
467 | +} | ||
468 | + | ||
469 | +function splitPoints(points) { | ||
470 | + var newPoints = []; | ||
471 | + var items = []; | ||
472 | + points.forEach(function (item, index) { | ||
473 | + if (item !== null) { | ||
474 | + items.push(item); | ||
475 | + } else { | ||
476 | + if (items.length) { | ||
477 | + newPoints.push(items); | ||
478 | + } | ||
479 | + items = []; | ||
480 | + } | ||
481 | + }); | ||
482 | + if (items.length) { | ||
483 | + newPoints.push(items); | ||
484 | + } | ||
485 | + | ||
486 | + return newPoints; | ||
487 | +} | ||
488 | + | ||
489 | +function calLegendData(series, opts, config) { | ||
490 | + if (opts.legend === false) { | ||
491 | + return { | ||
492 | + legendList: [], | ||
493 | + legendHeight: 0 | ||
494 | + }; | ||
495 | + } | ||
496 | + var padding = 5; | ||
497 | + var marginTop = 8; | ||
498 | + var shapeWidth = 15; | ||
499 | + var legendList = []; | ||
500 | + var widthCount = 0; | ||
501 | + var currentRow = []; | ||
502 | + series.forEach(function (item) { | ||
503 | + var itemWidth = 3 * padding + shapeWidth + measureText(item.name || 'undefinded'); | ||
504 | + if (widthCount + itemWidth > opts.width) { | ||
505 | + legendList.push(currentRow); | ||
506 | + widthCount = itemWidth; | ||
507 | + currentRow = [item]; | ||
508 | + } else { | ||
509 | + widthCount += itemWidth; | ||
510 | + currentRow.push(item); | ||
511 | + } | ||
512 | + }); | ||
513 | + if (currentRow.length) { | ||
514 | + legendList.push(currentRow); | ||
515 | + } | ||
516 | + | ||
517 | + return { | ||
518 | + legendList: legendList, | ||
519 | + legendHeight: legendList.length * (config.fontSize + marginTop) + padding | ||
520 | + }; | ||
521 | +} | ||
522 | + | ||
523 | +function calCategoriesData(categories, opts, config) { | ||
524 | + var result = { | ||
525 | + angle: 0, | ||
526 | + xAxisHeight: config.xAxisHeight | ||
527 | + }; | ||
528 | + | ||
529 | + var _getXAxisPoints = getXAxisPoints(categories, opts, config), | ||
530 | + eachSpacing = _getXAxisPoints.eachSpacing; | ||
531 | + | ||
532 | + // get max length of categories text | ||
533 | + | ||
534 | + | ||
535 | + var categoriesTextLenth = categories.map(function (item) { | ||
536 | + return measureText(item); | ||
537 | + }); | ||
538 | + | ||
539 | + var maxTextLength = Math.max.apply(this, categoriesTextLenth); | ||
540 | + | ||
541 | + if (maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) { | ||
542 | + result.angle = 45 * Math.PI / 180; | ||
543 | + result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle); | ||
544 | + } | ||
545 | + | ||
546 | + return result; | ||
547 | +} | ||
548 | + | ||
549 | +function getRadarDataPoints(angleList, center, radius, series, opts) { | ||
550 | + var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1; | ||
551 | + | ||
552 | + var radarOption = opts.extra.radar || {}; | ||
553 | + radarOption.max = radarOption.max || 0; | ||
554 | + var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series))); | ||
555 | + | ||
556 | + var data = []; | ||
557 | + series.forEach(function (each) { | ||
558 | + var listItem = {}; | ||
559 | + listItem.color = each.color; | ||
560 | + listItem.data = []; | ||
561 | + each.data.forEach(function (item, index) { | ||
562 | + var tmp = {}; | ||
563 | + tmp.angle = angleList[index]; | ||
564 | + | ||
565 | + tmp.proportion = item / maxData; | ||
566 | + tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion * process * Math.sin(tmp.angle), center); | ||
567 | + listItem.data.push(tmp); | ||
568 | + }); | ||
569 | + | ||
570 | + data.push(listItem); | ||
571 | + }); | ||
572 | + | ||
573 | + return data; | ||
574 | +} | ||
575 | + | ||
576 | +function getPieDataPoints(series) { | ||
577 | + var process = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; | ||
578 | + | ||
579 | + var count = 0; | ||
580 | + var _start_ = 0; | ||
581 | + series.forEach(function (item) { | ||
582 | + item.data = item.data === null ? 0 : item.data; | ||
583 | + count += item.data; | ||
584 | + }); | ||
585 | + series.forEach(function (item) { | ||
586 | + item.data = item.data === null ? 0 : item.data; | ||
587 | + item._proportion_ = item.data / count * process; | ||
588 | + }); | ||
589 | + series.forEach(function (item) { | ||
590 | + item._start_ = _start_; | ||
591 | + _start_ += 2 * item._proportion_ * Math.PI; | ||
592 | + }); | ||
593 | + | ||
594 | + return series; | ||
595 | +} | ||
596 | + | ||
597 | +function getPieTextMaxLength(series) { | ||
598 | + series = getPieDataPoints(series); | ||
599 | + var maxLength = 0; | ||
600 | + series.forEach(function (item) { | ||
601 | + var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%'; | ||
602 | + maxLength = Math.max(maxLength, measureText(text)); | ||
603 | + }); | ||
604 | + | ||
605 | + return maxLength; | ||
606 | +} | ||
607 | + | ||
608 | +function fixColumeData(points, eachSpacing, columnLen, index, config, opts) { | ||
609 | + return points.map(function (item) { | ||
610 | + if (item === null) { | ||
611 | + return null; | ||
612 | + } | ||
613 | + item.width = (eachSpacing - 2 * config.columePadding) / columnLen; | ||
614 | + | ||
615 | + if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) { | ||
616 | + // customer column width | ||
617 | + item.width = Math.min(item.width, +opts.extra.column.width); | ||
618 | + } else { | ||
619 | + // default width should less tran 25px | ||
620 | + // don't ask me why, I don't know | ||
621 | + item.width = Math.min(item.width, 25); | ||
622 | + } | ||
623 | + item.x += (index + 0.5 - columnLen / 2) * item.width; | ||
624 | + | ||
625 | + return item; | ||
626 | + }); | ||
627 | +} | ||
628 | + | ||
629 | +function getXAxisPoints(categories, opts, config) { | ||
630 | + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth; | ||
631 | + var spacingValid = opts.width - 2 * config.padding - yAxisTotalWidth; | ||
632 | + var dataCount = opts.enableScroll ? Math.min(5, categories.length) : categories.length; | ||
633 | + var eachSpacing = spacingValid / dataCount; | ||
634 | + | ||
635 | + var xAxisPoints = []; | ||
636 | + var startX = config.padding + yAxisTotalWidth; | ||
637 | + var endX = opts.width - config.padding; | ||
638 | + categories.forEach(function (item, index) { | ||
639 | + xAxisPoints.push(startX + index * eachSpacing); | ||
640 | + }); | ||
641 | + if (opts.enableScroll === true) { | ||
642 | + xAxisPoints.push(startX + categories.length * eachSpacing); | ||
643 | + } else { | ||
644 | + xAxisPoints.push(endX); | ||
645 | + } | ||
646 | + | ||
647 | + return { xAxisPoints: xAxisPoints, startX: startX, endX: endX, eachSpacing: eachSpacing }; | ||
648 | +} | ||
649 | + | ||
650 | +function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) { | ||
651 | + var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; | ||
652 | + | ||
653 | + var points = []; | ||
654 | + var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight; | ||
655 | + data.forEach(function (item, index) { | ||
656 | + if (item === null) { | ||
657 | + points.push(null); | ||
658 | + } else { | ||
659 | + var point = {}; | ||
660 | + point.x = xAxisPoints[index] + Math.round(eachSpacing / 2); | ||
661 | + var height = validHeight * (item - minRange) / (maxRange - minRange); | ||
662 | + height *= process; | ||
663 | + point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding; | ||
664 | + points.push(point); | ||
665 | + } | ||
666 | + }); | ||
667 | + | ||
668 | + return points; | ||
669 | +} | ||
670 | + | ||
671 | +function getYAxisTextList(series, opts, config) { | ||
672 | + var data = dataCombine(series); | ||
673 | + // remove null from data | ||
674 | + data = data.filter(function (item) { | ||
675 | + return item !== null; | ||
676 | + }); | ||
677 | + var minData = Math.min.apply(this, data); | ||
678 | + var maxData = Math.max.apply(this, data); | ||
679 | + if (typeof opts.yAxis.min === 'number') { | ||
680 | + minData = Math.min(opts.yAxis.min, minData); | ||
681 | + } | ||
682 | + if (typeof opts.yAxis.max === 'number') { | ||
683 | + maxData = Math.max(opts.yAxis.max, maxData); | ||
684 | + } | ||
685 | + | ||
686 | + // fix issue https://github.com/xiaolin3303/wx-charts/issues/9 | ||
687 | + if (minData === maxData) { | ||
688 | + var rangeSpan = maxData || 1; | ||
689 | + minData -= rangeSpan; | ||
690 | + maxData += rangeSpan; | ||
691 | + } | ||
692 | + | ||
693 | + var dataRange = getDataRange(minData, maxData); | ||
694 | + var minRange = dataRange.minRange; | ||
695 | + var maxRange = dataRange.maxRange; | ||
696 | + | ||
697 | + var range = []; | ||
698 | + var eachRange = (maxRange - minRange) / config.yAxisSplit; | ||
699 | + | ||
700 | + for (var i = 0; i <= config.yAxisSplit; i++) { | ||
701 | + range.push(minRange + eachRange * i); | ||
702 | + } | ||
703 | + return range.reverse(); | ||
704 | +} | ||
705 | + | ||
706 | +function calYAxisData(series, opts, config) { | ||
707 | + | ||
708 | + var ranges = getYAxisTextList(series, opts, config); | ||
709 | + var yAxisWidth = config.yAxisWidth; | ||
710 | + var rangesFormat = ranges.map(function (item) { | ||
711 | + item = util.toFixed(item, 2); | ||
712 | + item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item; | ||
713 | + yAxisWidth = Math.max(yAxisWidth, measureText(item) + 5); | ||
714 | + return item; | ||
715 | + }); | ||
716 | + if (opts.yAxis.disabled === true) { | ||
717 | + yAxisWidth = 0; | ||
718 | + } | ||
719 | + | ||
720 | + return { rangesFormat: rangesFormat, ranges: ranges, yAxisWidth: yAxisWidth }; | ||
721 | +} | ||
722 | + | ||
723 | +function drawPointShape(points, color, shape, context) { | ||
724 | + context.beginPath(); | ||
725 | + context.setStrokeStyle("#ffffff"); | ||
726 | + context.setLineWidth(1); | ||
727 | + context.setFillStyle(color); | ||
728 | + | ||
729 | + if (shape === 'diamond') { | ||
730 | + points.forEach(function (item, index) { | ||
731 | + if (item !== null) { | ||
732 | + context.moveTo(item.x, item.y - 4.5); | ||
733 | + context.lineTo(item.x - 4.5, item.y); | ||
734 | + context.lineTo(item.x, item.y + 4.5); | ||
735 | + context.lineTo(item.x + 4.5, item.y); | ||
736 | + context.lineTo(item.x, item.y - 4.5); | ||
737 | + } | ||
738 | + }); | ||
739 | + } else if (shape === 'circle') { | ||
740 | + points.forEach(function (item, index) { | ||
741 | + if (item !== null) { | ||
742 | + context.moveTo(item.x + 3.5, item.y); | ||
743 | + context.arc(item.x, item.y, 4, 0, 2 * Math.PI, false); | ||
744 | + } | ||
745 | + }); | ||
746 | + } else if (shape === 'rect') { | ||
747 | + points.forEach(function (item, index) { | ||
748 | + if (item !== null) { | ||
749 | + context.moveTo(item.x - 3.5, item.y - 3.5); | ||
750 | + context.rect(item.x - 3.5, item.y - 3.5, 7, 7); | ||
751 | + } | ||
752 | + }); | ||
753 | + } else if (shape === 'triangle') { | ||
754 | + points.forEach(function (item, index) { | ||
755 | + if (item !== null) { | ||
756 | + context.moveTo(item.x, item.y - 4.5); | ||
757 | + context.lineTo(item.x - 4.5, item.y + 4.5); | ||
758 | + context.lineTo(item.x + 4.5, item.y + 4.5); | ||
759 | + context.lineTo(item.x, item.y - 4.5); | ||
760 | + } | ||
761 | + }); | ||
762 | + } | ||
763 | + context.closePath(); | ||
764 | + context.fill(); | ||
765 | + context.stroke(); | ||
766 | +} | ||
767 | + | ||
768 | +function drawRingTitle(opts, config, context) { | ||
769 | + var titlefontSize = opts.title.fontSize || config.titleFontSize; | ||
770 | + var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize; | ||
771 | + var title = opts.title.name || ''; | ||
772 | + var subtitle = opts.subtitle.name || ''; | ||
773 | + var titleFontColor = opts.title.color || config.titleColor; | ||
774 | + var subtitleFontColor = opts.subtitle.color || config.subtitleColor; | ||
775 | + var titleHeight = title ? titlefontSize : 0; | ||
776 | + var subtitleHeight = subtitle ? subtitlefontSize : 0; | ||
777 | + var margin = 5; | ||
778 | + if (subtitle) { | ||
779 | + var textWidth = measureText(subtitle, subtitlefontSize); | ||
780 | + var startX = (opts.width - textWidth) / 2 + (opts.subtitle.offsetX || 0); | ||
781 | + var startY = (opts.height - config.legendHeight + subtitlefontSize) / 2; | ||
782 | + if (title) { | ||
783 | + startY -= (titleHeight + margin) / 2; | ||
784 | + } | ||
785 | + context.beginPath(); | ||
786 | + context.setFontSize(subtitlefontSize); | ||
787 | + context.setFillStyle(subtitleFontColor); | ||
788 | + context.fillText(subtitle, startX, startY); | ||
789 | + context.stroke(); | ||
790 | + context.closePath(); | ||
791 | + } | ||
792 | + if (title) { | ||
793 | + var _textWidth = measureText(title, titlefontSize); | ||
794 | + var _startX = (opts.width - _textWidth) / 2 + (opts.title.offsetX || 0); | ||
795 | + var _startY = (opts.height - config.legendHeight + titlefontSize) / 2; | ||
796 | + if (subtitle) { | ||
797 | + _startY += (subtitleHeight + margin) / 2; | ||
798 | + } | ||
799 | + context.beginPath(); | ||
800 | + context.setFontSize(titlefontSize); | ||
801 | + context.setFillStyle(titleFontColor); | ||
802 | + context.fillText(title, _startX, _startY); | ||
803 | + context.stroke(); | ||
804 | + context.closePath(); | ||
805 | + } | ||
806 | +} | ||
807 | + | ||
808 | +function drawPointText(points, series, config, context) { | ||
809 | + // 绘制数据文案 | ||
810 | + var data = series.data; | ||
811 | + | ||
812 | + context.beginPath(); | ||
813 | + context.setFontSize(config.fontSize); | ||
814 | + context.setFillStyle('#666666'); | ||
815 | + points.forEach(function (item, index) { | ||
816 | + if (item !== null) { | ||
817 | + var formatVal = series.format ? series.format(data[index]) : data[index]; | ||
818 | + context.fillText(formatVal, item.x - measureText(formatVal) / 2, item.y - 2); | ||
819 | + } | ||
820 | + }); | ||
821 | + context.closePath(); | ||
822 | + context.stroke(); | ||
823 | +} | ||
824 | + | ||
825 | +function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) { | ||
826 | + var radarOption = opts.extra.radar || {}; | ||
827 | + radius += config.radarLabelTextMargin; | ||
828 | + context.beginPath(); | ||
829 | + context.setFontSize(config.fontSize); | ||
830 | + context.setFillStyle(radarOption.labelColor || '#666666'); | ||
831 | + angleList.forEach(function (angle, index) { | ||
832 | + var pos = { | ||
833 | + x: radius * Math.cos(angle), | ||
834 | + y: radius * Math.sin(angle) | ||
835 | + }; | ||
836 | + var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition); | ||
837 | + var startX = posRelativeCanvas.x; | ||
838 | + var startY = posRelativeCanvas.y; | ||
839 | + if (util.approximatelyEqual(pos.x, 0)) { | ||
840 | + startX -= measureText(opts.categories[index] || '') / 2; | ||
841 | + } else if (pos.x < 0) { | ||
842 | + startX -= measureText(opts.categories[index] || ''); | ||
843 | + } | ||
844 | + context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2); | ||
845 | + }); | ||
846 | + context.stroke(); | ||
847 | + context.closePath(); | ||
848 | +} | ||
849 | + | ||
850 | +function drawPieText(series, opts, config, context, radius, center) { | ||
851 | + var lineRadius = radius + config.pieChartLinePadding; | ||
852 | + var textObjectCollection = []; | ||
853 | + var lastTextObject = null; | ||
854 | + | ||
855 | + var seriesConvert = series.map(function (item) { | ||
856 | + var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2); | ||
857 | + var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%'; | ||
858 | + var color = item.color; | ||
859 | + return { arc: arc, text: text, color: color }; | ||
860 | + }); | ||
861 | + seriesConvert.forEach(function (item) { | ||
862 | + // line end | ||
863 | + var orginX1 = Math.cos(item.arc) * lineRadius; | ||
864 | + var orginY1 = Math.sin(item.arc) * lineRadius; | ||
865 | + | ||
866 | + // line start | ||
867 | + var orginX2 = Math.cos(item.arc) * radius; | ||
868 | + var orginY2 = Math.sin(item.arc) * radius; | ||
869 | + | ||
870 | + // text start | ||
871 | + var orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding; | ||
872 | + var orginY3 = orginY1; | ||
873 | + | ||
874 | + var textWidth = measureText(item.text); | ||
875 | + var startY = orginY3; | ||
876 | + | ||
877 | + if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, { x: orginX3 })) { | ||
878 | + if (orginX3 > 0) { | ||
879 | + startY = Math.min(orginY3, lastTextObject.start.y); | ||
880 | + } else if (orginX1 < 0) { | ||
881 | + startY = Math.max(orginY3, lastTextObject.start.y); | ||
882 | + } else { | ||
883 | + if (orginY3 > 0) { | ||
884 | + startY = Math.max(orginY3, lastTextObject.start.y); | ||
885 | + } else { | ||
886 | + startY = Math.min(orginY3, lastTextObject.start.y); | ||
887 | + } | ||
888 | + } | ||
889 | + } | ||
890 | + | ||
891 | + if (orginX3 < 0) { | ||
892 | + orginX3 -= textWidth; | ||
893 | + } | ||
894 | + | ||
895 | + var textObject = { | ||
896 | + lineStart: { | ||
897 | + x: orginX2, | ||
898 | + y: orginY2 | ||
899 | + }, | ||
900 | + lineEnd: { | ||
901 | + x: orginX1, | ||
902 | + y: orginY1 | ||
903 | + }, | ||
904 | + start: { | ||
905 | + x: orginX3, | ||
906 | + y: startY | ||
907 | + }, | ||
908 | + width: textWidth, | ||
909 | + height: config.fontSize, | ||
910 | + text: item.text, | ||
911 | + color: item.color | ||
912 | + }; | ||
913 | + | ||
914 | + lastTextObject = avoidCollision(textObject, lastTextObject); | ||
915 | + textObjectCollection.push(lastTextObject); | ||
916 | + }); | ||
917 | + | ||
918 | + textObjectCollection.forEach(function (item) { | ||
919 | + var lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center); | ||
920 | + var lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center); | ||
921 | + var textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center); | ||
922 | + context.setLineWidth(1); | ||
923 | + context.setFontSize(config.fontSize); | ||
924 | + context.beginPath(); | ||
925 | + context.setStrokeStyle(item.color); | ||
926 | + context.setFillStyle(item.color); | ||
927 | + context.moveTo(lineStartPoistion.x, lineStartPoistion.y); | ||
928 | + var curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x; | ||
929 | + var textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5; | ||
930 | + context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y); | ||
931 | + context.moveTo(lineStartPoistion.x, lineStartPoistion.y); | ||
932 | + context.stroke(); | ||
933 | + context.closePath(); | ||
934 | + context.beginPath(); | ||
935 | + context.moveTo(textPosition.x + item.width, textPosition.y); | ||
936 | + context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI); | ||
937 | + context.closePath(); | ||
938 | + context.fill(); | ||
939 | + context.beginPath(); | ||
940 | + context.setFillStyle('#666666'); | ||
941 | + context.fillText(item.text, textStartX, textPosition.y + 3); | ||
942 | + context.closePath(); | ||
943 | + context.stroke(); | ||
944 | + | ||
945 | + context.closePath(); | ||
946 | + }); | ||
947 | +} | ||
948 | + | ||
949 | +function drawToolTipSplitLine(offsetX, opts, config, context) { | ||
950 | + var startY = config.padding; | ||
951 | + var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight; | ||
952 | + context.beginPath(); | ||
953 | + context.setStrokeStyle('#cccccc'); | ||
954 | + context.setLineWidth(1); | ||
955 | + context.moveTo(offsetX, startY); | ||
956 | + context.lineTo(offsetX, endY); | ||
957 | + context.stroke(); | ||
958 | + context.closePath(); | ||
959 | +} | ||
960 | + | ||
961 | +function drawToolTip(textList, offset, opts, config, context) { | ||
962 | + var legendWidth = 4; | ||
963 | + var legendMarginRight = 5; | ||
964 | + var arrowWidth = 8; | ||
965 | + var isOverRightBorder = false; | ||
966 | + offset = assign({ | ||
967 | + x: 0, | ||
968 | + y: 0 | ||
969 | + }, offset); | ||
970 | + offset.y -= 8; | ||
971 | + var textWidth = textList.map(function (item) { | ||
972 | + return measureText(item.text); | ||
973 | + }); | ||
974 | + | ||
975 | + var toolTipWidth = legendWidth + legendMarginRight + 4 * config.toolTipPadding + Math.max.apply(null, textWidth); | ||
976 | + var toolTipHeight = 2 * config.toolTipPadding + textList.length * config.toolTipLineHeight; | ||
977 | + | ||
978 | + // if beyond the right border | ||
979 | + if (offset.x - Math.abs(opts._scrollDistance_) + arrowWidth + toolTipWidth > opts.width) { | ||
980 | + isOverRightBorder = true; | ||
981 | + } | ||
982 | + | ||
983 | + // draw background rect | ||
984 | + context.beginPath(); | ||
985 | + context.setFillStyle(opts.tooltip.option.background || config.toolTipBackground); | ||
986 | + context.setGlobalAlpha(config.toolTipOpacity); | ||
987 | + if (isOverRightBorder) { | ||
988 | + context.moveTo(offset.x, offset.y + 10); | ||
989 | + context.lineTo(offset.x - arrowWidth, offset.y + 10 - 5); | ||
990 | + context.lineTo(offset.x - arrowWidth, offset.y + 10 + 5); | ||
991 | + context.moveTo(offset.x, offset.y + 10); | ||
992 | + context.fillRect(offset.x - toolTipWidth - arrowWidth, offset.y, toolTipWidth, toolTipHeight); | ||
993 | + } else { | ||
994 | + context.moveTo(offset.x, offset.y + 10); | ||
995 | + context.lineTo(offset.x + arrowWidth, offset.y + 10 - 5); | ||
996 | + context.lineTo(offset.x + arrowWidth, offset.y + 10 + 5); | ||
997 | + context.moveTo(offset.x, offset.y + 10); | ||
998 | + context.fillRect(offset.x + arrowWidth, offset.y, toolTipWidth, toolTipHeight); | ||
999 | + } | ||
1000 | + | ||
1001 | + context.closePath(); | ||
1002 | + context.fill(); | ||
1003 | + context.setGlobalAlpha(1); | ||
1004 | + | ||
1005 | + // draw legend | ||
1006 | + textList.forEach(function (item, index) { | ||
1007 | + context.beginPath(); | ||
1008 | + context.setFillStyle(item.color); | ||
1009 | + var startX = offset.x + arrowWidth + 2 * config.toolTipPadding; | ||
1010 | + var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding; | ||
1011 | + if (isOverRightBorder) { | ||
1012 | + startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding; | ||
1013 | + } | ||
1014 | + context.fillRect(startX, startY, legendWidth, config.fontSize); | ||
1015 | + context.closePath(); | ||
1016 | + }); | ||
1017 | + | ||
1018 | + // draw text list | ||
1019 | + context.beginPath(); | ||
1020 | + context.setFontSize(config.fontSize); | ||
1021 | + context.setFillStyle('#ffffff'); | ||
1022 | + textList.forEach(function (item, index) { | ||
1023 | + var startX = offset.x + arrowWidth + 2 * config.toolTipPadding + legendWidth + legendMarginRight; | ||
1024 | + if (isOverRightBorder) { | ||
1025 | + startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding + +legendWidth + legendMarginRight; | ||
1026 | + } | ||
1027 | + var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding; | ||
1028 | + context.fillText(item.text, startX, startY + config.fontSize); | ||
1029 | + }); | ||
1030 | + context.stroke(); | ||
1031 | + context.closePath(); | ||
1032 | +} | ||
1033 | + | ||
1034 | +function drawYAxisTitle(title, opts, config, context) { | ||
1035 | + var startX = config.xAxisHeight + (opts.height - config.xAxisHeight - measureText(title)) / 2; | ||
1036 | + context.save(); | ||
1037 | + context.beginPath(); | ||
1038 | + context.setFontSize(config.fontSize); | ||
1039 | + context.setFillStyle(opts.yAxis.titleFontColor || '#333333'); | ||
1040 | + context.translate(0, opts.height); | ||
1041 | + context.rotate(-90 * Math.PI / 180); | ||
1042 | + context.fillText(title, startX, config.padding + 0.5 * config.fontSize); | ||
1043 | + context.stroke(); | ||
1044 | + context.closePath(); | ||
1045 | + context.restore(); | ||
1046 | +} | ||
1047 | + | ||
1048 | +function drawColumnDataPoints(series, opts, config, context) { | ||
1049 | + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | ||
1050 | + | ||
1051 | + var _calYAxisData = calYAxisData(series, opts, config), | ||
1052 | + ranges = _calYAxisData.ranges; | ||
1053 | + | ||
1054 | + var _getXAxisPoints = getXAxisPoints(opts.categories, opts, config), | ||
1055 | + xAxisPoints = _getXAxisPoints.xAxisPoints, | ||
1056 | + eachSpacing = _getXAxisPoints.eachSpacing; | ||
1057 | + | ||
1058 | + var minRange = ranges.pop(); | ||
1059 | + var maxRange = ranges.shift(); | ||
1060 | + context.save(); | ||
1061 | + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { | ||
1062 | + context.translate(opts._scrollDistance_, 0); | ||
1063 | + } | ||
1064 | + | ||
1065 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1066 | + var data = eachSeries.data; | ||
1067 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1068 | + points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); | ||
1069 | + | ||
1070 | + // 绘制柱状数据图 | ||
1071 | + context.beginPath(); | ||
1072 | + context.setFillStyle(eachSeries.color); | ||
1073 | + points.forEach(function (item, index) { | ||
1074 | + if (item !== null) { | ||
1075 | + var startX = item.x - item.width / 2 + 1; | ||
1076 | + var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight; | ||
1077 | + context.moveTo(startX, item.y); | ||
1078 | + context.rect(startX, item.y, item.width - 2, height); | ||
1079 | + } | ||
1080 | + }); | ||
1081 | + context.closePath(); | ||
1082 | + context.fill(); | ||
1083 | + }); | ||
1084 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1085 | + var data = eachSeries.data; | ||
1086 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1087 | + points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); | ||
1088 | + if (opts.dataLabel !== false && process === 1) { | ||
1089 | + drawPointText(points, eachSeries, config, context); | ||
1090 | + } | ||
1091 | + }); | ||
1092 | + context.restore(); | ||
1093 | + return { | ||
1094 | + xAxisPoints: xAxisPoints, | ||
1095 | + eachSpacing: eachSpacing | ||
1096 | + }; | ||
1097 | +} | ||
1098 | + | ||
1099 | +function drawAreaDataPoints(series, opts, config, context) { | ||
1100 | + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | ||
1101 | + | ||
1102 | + var _calYAxisData2 = calYAxisData(series, opts, config), | ||
1103 | + ranges = _calYAxisData2.ranges; | ||
1104 | + | ||
1105 | + var _getXAxisPoints2 = getXAxisPoints(opts.categories, opts, config), | ||
1106 | + xAxisPoints = _getXAxisPoints2.xAxisPoints, | ||
1107 | + eachSpacing = _getXAxisPoints2.eachSpacing; | ||
1108 | + | ||
1109 | + var minRange = ranges.pop(); | ||
1110 | + var maxRange = ranges.shift(); | ||
1111 | + var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight; | ||
1112 | + var calPoints = []; | ||
1113 | + | ||
1114 | + context.save(); | ||
1115 | + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { | ||
1116 | + context.translate(opts._scrollDistance_, 0); | ||
1117 | + } | ||
1118 | + | ||
1119 | + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { | ||
1120 | + drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context); | ||
1121 | + } | ||
1122 | + | ||
1123 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1124 | + var data = eachSeries.data; | ||
1125 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1126 | + calPoints.push(points); | ||
1127 | + | ||
1128 | + var splitPointList = splitPoints(points); | ||
1129 | + | ||
1130 | + splitPointList.forEach(function (points) { | ||
1131 | + // 绘制区域数据 | ||
1132 | + context.beginPath(); | ||
1133 | + context.setStrokeStyle(eachSeries.color); | ||
1134 | + context.setFillStyle(eachSeries.color); | ||
1135 | + context.setGlobalAlpha(0.6); | ||
1136 | + context.setLineWidth(2); | ||
1137 | + if (points.length > 1) { | ||
1138 | + var firstPoint = points[0]; | ||
1139 | + var lastPoint = points[points.length - 1]; | ||
1140 | + | ||
1141 | + context.moveTo(firstPoint.x, firstPoint.y); | ||
1142 | + if (opts.extra.lineStyle === 'curve') { | ||
1143 | + points.forEach(function (item, index) { | ||
1144 | + if (index > 0) { | ||
1145 | + var ctrlPoint = createCurveControlPoints(points, index - 1); | ||
1146 | + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); | ||
1147 | + } | ||
1148 | + }); | ||
1149 | + } else { | ||
1150 | + points.forEach(function (item, index) { | ||
1151 | + if (index > 0) { | ||
1152 | + context.lineTo(item.x, item.y); | ||
1153 | + } | ||
1154 | + }); | ||
1155 | + } | ||
1156 | + | ||
1157 | + context.lineTo(lastPoint.x, endY); | ||
1158 | + context.lineTo(firstPoint.x, endY); | ||
1159 | + context.lineTo(firstPoint.x, firstPoint.y); | ||
1160 | + } else { | ||
1161 | + var item = points[0]; | ||
1162 | + context.moveTo(item.x - eachSpacing / 2, item.y); | ||
1163 | + context.lineTo(item.x + eachSpacing / 2, item.y); | ||
1164 | + context.lineTo(item.x + eachSpacing / 2, endY); | ||
1165 | + context.lineTo(item.x - eachSpacing / 2, endY); | ||
1166 | + context.moveTo(item.x - eachSpacing / 2, item.y); | ||
1167 | + } | ||
1168 | + context.closePath(); | ||
1169 | + context.fill(); | ||
1170 | + context.setGlobalAlpha(1); | ||
1171 | + }); | ||
1172 | + | ||
1173 | + if (opts.dataPointShape !== false) { | ||
1174 | + var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length]; | ||
1175 | + drawPointShape(points, eachSeries.color, shape, context); | ||
1176 | + } | ||
1177 | + }); | ||
1178 | + if (opts.dataLabel !== false && process === 1) { | ||
1179 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1180 | + var data = eachSeries.data; | ||
1181 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1182 | + drawPointText(points, eachSeries, config, context); | ||
1183 | + }); | ||
1184 | + } | ||
1185 | + | ||
1186 | + context.restore(); | ||
1187 | + | ||
1188 | + return { | ||
1189 | + xAxisPoints: xAxisPoints, | ||
1190 | + calPoints: calPoints, | ||
1191 | + eachSpacing: eachSpacing | ||
1192 | + }; | ||
1193 | +} | ||
1194 | + | ||
1195 | +function drawLineDataPoints(series, opts, config, context) { | ||
1196 | + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | ||
1197 | + | ||
1198 | + var _calYAxisData3 = calYAxisData(series, opts, config), | ||
1199 | + ranges = _calYAxisData3.ranges; | ||
1200 | + | ||
1201 | + var _getXAxisPoints3 = getXAxisPoints(opts.categories, opts, config), | ||
1202 | + xAxisPoints = _getXAxisPoints3.xAxisPoints, | ||
1203 | + eachSpacing = _getXAxisPoints3.eachSpacing; | ||
1204 | + | ||
1205 | + var minRange = ranges.pop(); | ||
1206 | + var maxRange = ranges.shift(); | ||
1207 | + var calPoints = []; | ||
1208 | + | ||
1209 | + context.save(); | ||
1210 | + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { | ||
1211 | + context.translate(opts._scrollDistance_, 0); | ||
1212 | + } | ||
1213 | + | ||
1214 | + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { | ||
1215 | + drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context); | ||
1216 | + } | ||
1217 | + | ||
1218 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1219 | + var data = eachSeries.data; | ||
1220 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1221 | + calPoints.push(points); | ||
1222 | + var splitPointList = splitPoints(points); | ||
1223 | + | ||
1224 | + splitPointList.forEach(function (points, index) { | ||
1225 | + context.beginPath(); | ||
1226 | + context.setStrokeStyle(eachSeries.color); | ||
1227 | + context.setLineWidth(2); | ||
1228 | + if (points.length === 1) { | ||
1229 | + context.moveTo(points[0].x, points[0].y); | ||
1230 | + context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); | ||
1231 | + } else { | ||
1232 | + context.moveTo(points[0].x, points[0].y); | ||
1233 | + if (opts.extra.lineStyle === 'curve') { | ||
1234 | + points.forEach(function (item, index) { | ||
1235 | + if (index > 0) { | ||
1236 | + var ctrlPoint = createCurveControlPoints(points, index - 1); | ||
1237 | + context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y); | ||
1238 | + } | ||
1239 | + }); | ||
1240 | + } else { | ||
1241 | + points.forEach(function (item, index) { | ||
1242 | + if (index > 0) { | ||
1243 | + context.lineTo(item.x, item.y); | ||
1244 | + } | ||
1245 | + }); | ||
1246 | + } | ||
1247 | + context.moveTo(points[0].x, points[0].y); | ||
1248 | + } | ||
1249 | + context.closePath(); | ||
1250 | + context.stroke(); | ||
1251 | + }); | ||
1252 | + | ||
1253 | + if (opts.dataPointShape !== false) { | ||
1254 | + var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length]; | ||
1255 | + drawPointShape(points, eachSeries.color, shape, context); | ||
1256 | + } | ||
1257 | + }); | ||
1258 | + if (opts.dataLabel !== false && process === 1) { | ||
1259 | + series.forEach(function (eachSeries, seriesIndex) { | ||
1260 | + var data = eachSeries.data; | ||
1261 | + var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); | ||
1262 | + drawPointText(points, eachSeries, config, context); | ||
1263 | + }); | ||
1264 | + } | ||
1265 | + | ||
1266 | + context.restore(); | ||
1267 | + | ||
1268 | + return { | ||
1269 | + xAxisPoints: xAxisPoints, | ||
1270 | + calPoints: calPoints, | ||
1271 | + eachSpacing: eachSpacing | ||
1272 | + }; | ||
1273 | +} | ||
1274 | + | ||
1275 | +function drawToolTipBridge(opts, config, context, process) { | ||
1276 | + context.save(); | ||
1277 | + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { | ||
1278 | + context.translate(opts._scrollDistance_, 0); | ||
1279 | + } | ||
1280 | + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) { | ||
1281 | + drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context); | ||
1282 | + } | ||
1283 | + context.restore(); | ||
1284 | +} | ||
1285 | + | ||
1286 | +function drawXAxis(categories, opts, config, context) { | ||
1287 | + var _getXAxisPoints4 = getXAxisPoints(categories, opts, config), | ||
1288 | + xAxisPoints = _getXAxisPoints4.xAxisPoints, | ||
1289 | + startX = _getXAxisPoints4.startX, | ||
1290 | + endX = _getXAxisPoints4.endX, | ||
1291 | + eachSpacing = _getXAxisPoints4.eachSpacing; | ||
1292 | + | ||
1293 | + var startY = opts.height - config.padding - config.xAxisHeight - config.legendHeight; | ||
1294 | + var endY = startY + config.xAxisLineHeight; | ||
1295 | + | ||
1296 | + context.save(); | ||
1297 | + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) { | ||
1298 | + context.translate(opts._scrollDistance_, 0); | ||
1299 | + } | ||
1300 | + | ||
1301 | + context.beginPath(); | ||
1302 | + context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc"); | ||
1303 | + | ||
1304 | + if (opts.xAxis.disableGrid !== true) { | ||
1305 | + if (opts.xAxis.type === 'calibration') { | ||
1306 | + xAxisPoints.forEach(function (item, index) { | ||
1307 | + if (index > 0) { | ||
1308 | + context.moveTo(item - eachSpacing / 2, startY); | ||
1309 | + context.lineTo(item - eachSpacing / 2, startY + 4); | ||
1310 | + } | ||
1311 | + }); | ||
1312 | + } else { | ||
1313 | + xAxisPoints.forEach(function (item, index) { | ||
1314 | + context.moveTo(item, startY); | ||
1315 | + context.lineTo(item, endY); | ||
1316 | + }); | ||
1317 | + } | ||
1318 | + } | ||
1319 | + context.closePath(); | ||
1320 | + context.stroke(); | ||
1321 | + | ||
1322 | + // 对X轴列表做抽稀处理 | ||
1323 | + var validWidth = opts.width - 2 * config.padding - config.yAxisWidth - config.yAxisTitleWidth; | ||
1324 | + var maxXAxisListLength = Math.min(categories.length, Math.ceil(validWidth / config.fontSize / 1.5)); | ||
1325 | + var ratio = Math.ceil(categories.length / maxXAxisListLength); | ||
1326 | + | ||
1327 | + categories = categories.map(function (item, index) { | ||
1328 | + return index % ratio !== 0 ? '' : item; | ||
1329 | + }); | ||
1330 | + | ||
1331 | + if (config._xAxisTextAngle_ === 0) { | ||
1332 | + context.beginPath(); | ||
1333 | + context.setFontSize(config.fontSize); | ||
1334 | + context.setFillStyle(opts.xAxis.fontColor || '#666666'); | ||
1335 | + categories.forEach(function (item, index) { | ||
1336 | + var offset = eachSpacing / 2 - measureText(item) / 2; | ||
1337 | + context.fillText(item, xAxisPoints[index] + offset, startY + config.fontSize + 5); | ||
1338 | + }); | ||
1339 | + context.closePath(); | ||
1340 | + context.stroke(); | ||
1341 | + } else { | ||
1342 | + categories.forEach(function (item, index) { | ||
1343 | + context.save(); | ||
1344 | + context.beginPath(); | ||
1345 | + context.setFontSize(config.fontSize); | ||
1346 | + context.setFillStyle(opts.xAxis.fontColor || '#666666'); | ||
1347 | + var textWidth = measureText(item); | ||
1348 | + var offset = eachSpacing / 2 - textWidth; | ||
1349 | + | ||
1350 | + var _calRotateTranslate = calRotateTranslate(xAxisPoints[index] + eachSpacing / 2, startY + config.fontSize / 2 + 5, opts.height), | ||
1351 | + transX = _calRotateTranslate.transX, | ||
1352 | + transY = _calRotateTranslate.transY; | ||
1353 | + | ||
1354 | + context.rotate(-1 * config._xAxisTextAngle_); | ||
1355 | + context.translate(transX, transY); | ||
1356 | + context.fillText(item, xAxisPoints[index] + offset, startY + config.fontSize + 5); | ||
1357 | + context.closePath(); | ||
1358 | + context.stroke(); | ||
1359 | + context.restore(); | ||
1360 | + }); | ||
1361 | + } | ||
1362 | + | ||
1363 | + context.restore(); | ||
1364 | +} | ||
1365 | + | ||
1366 | +function drawYAxisGrid(opts, config, context) { | ||
1367 | + var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight; | ||
1368 | + var eachSpacing = Math.floor(spacingValid / config.yAxisSplit); | ||
1369 | + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth; | ||
1370 | + var startX = config.padding + yAxisTotalWidth; | ||
1371 | + var endX = opts.width - config.padding; | ||
1372 | + | ||
1373 | + var points = []; | ||
1374 | + for (var i = 0; i < config.yAxisSplit; i++) { | ||
1375 | + points.push(config.padding + eachSpacing * i); | ||
1376 | + } | ||
1377 | + points.push(config.padding + eachSpacing * config.yAxisSplit + 2); | ||
1378 | + | ||
1379 | + context.beginPath(); | ||
1380 | + context.setStrokeStyle(opts.yAxis.gridColor || "#cccccc"); | ||
1381 | + context.setLineWidth(1); | ||
1382 | + points.forEach(function (item, index) { | ||
1383 | + context.moveTo(startX, item); | ||
1384 | + context.lineTo(endX, item); | ||
1385 | + }); | ||
1386 | + context.closePath(); | ||
1387 | + context.stroke(); | ||
1388 | +} | ||
1389 | + | ||
1390 | +function drawYAxis(series, opts, config, context) { | ||
1391 | + if (opts.yAxis.disabled === true) { | ||
1392 | + return; | ||
1393 | + } | ||
1394 | + | ||
1395 | + var _calYAxisData4 = calYAxisData(series, opts, config), | ||
1396 | + rangesFormat = _calYAxisData4.rangesFormat; | ||
1397 | + | ||
1398 | + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth; | ||
1399 | + | ||
1400 | + var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight; | ||
1401 | + var eachSpacing = Math.floor(spacingValid / config.yAxisSplit); | ||
1402 | + var startX = config.padding + yAxisTotalWidth; | ||
1403 | + var endX = opts.width - config.padding; | ||
1404 | + var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight; | ||
1405 | + | ||
1406 | + // set YAxis background | ||
1407 | + context.setFillStyle(opts.background || '#ffffff'); | ||
1408 | + if (opts._scrollDistance_ < 0) { | ||
1409 | + context.fillRect(0, 0, startX, endY + config.xAxisHeight + 5); | ||
1410 | + } | ||
1411 | + context.fillRect(endX, 0, opts.width, endY + config.xAxisHeight + 5); | ||
1412 | + | ||
1413 | + var points = []; | ||
1414 | + for (var i = 0; i <= config.yAxisSplit; i++) { | ||
1415 | + points.push(config.padding + eachSpacing * i); | ||
1416 | + } | ||
1417 | + | ||
1418 | + context.stroke(); | ||
1419 | + context.beginPath(); | ||
1420 | + context.setFontSize(config.fontSize); | ||
1421 | + context.setFillStyle(opts.yAxis.fontColor || '#666666'); | ||
1422 | + rangesFormat.forEach(function (item, index) { | ||
1423 | + var pos = points[index] ? points[index] : endY; | ||
1424 | + context.fillText(item, config.padding + config.yAxisTitleWidth, pos + config.fontSize / 2); | ||
1425 | + }); | ||
1426 | + context.closePath(); | ||
1427 | + context.stroke(); | ||
1428 | + | ||
1429 | + if (opts.yAxis.title) { | ||
1430 | + drawYAxisTitle(opts.yAxis.title, opts, config, context); | ||
1431 | + } | ||
1432 | +} | ||
1433 | + | ||
1434 | +function drawLegend(series, opts, config, context) { | ||
1435 | + if (!opts.legend) { | ||
1436 | + return; | ||
1437 | + } | ||
1438 | + // each legend shape width 15px | ||
1439 | + // the spacing between shape and text in each legend is the `padding` | ||
1440 | + // each legend spacing is the `padding` | ||
1441 | + // legend margin top `config.padding` | ||
1442 | + | ||
1443 | + var _calLegendData = calLegendData(series, opts, config), | ||
1444 | + legendList = _calLegendData.legendList; | ||
1445 | + | ||
1446 | + var padding = 5; | ||
1447 | + var marginTop = 8; | ||
1448 | + var shapeWidth = 15; | ||
1449 | + legendList.forEach(function (itemList, listIndex) { | ||
1450 | + var width = 0; | ||
1451 | + itemList.forEach(function (item) { | ||
1452 | + item.name = item.name || 'undefined'; | ||
1453 | + width += 3 * padding + measureText(item.name) + shapeWidth; | ||
1454 | + }); | ||
1455 | + var startX = (opts.width - width) / 2 + padding; | ||
1456 | + var startY = opts.height - config.padding - config.legendHeight + listIndex * (config.fontSize + marginTop) + padding + marginTop; | ||
1457 | + | ||
1458 | + context.setFontSize(config.fontSize); | ||
1459 | + itemList.forEach(function (item) { | ||
1460 | + switch (opts.type) { | ||
1461 | + case 'line': | ||
1462 | + context.beginPath(); | ||
1463 | + context.setLineWidth(1); | ||
1464 | + context.setStrokeStyle(item.color); | ||
1465 | + context.moveTo(startX - 2, startY + 5); | ||
1466 | + context.lineTo(startX + 17, startY + 5); | ||
1467 | + context.stroke(); | ||
1468 | + context.closePath(); | ||
1469 | + context.beginPath(); | ||
1470 | + context.setLineWidth(1); | ||
1471 | + context.setStrokeStyle('#ffffff'); | ||
1472 | + context.setFillStyle(item.color); | ||
1473 | + context.moveTo(startX + 7.5, startY + 5); | ||
1474 | + context.arc(startX + 7.5, startY + 5, 4, 0, 2 * Math.PI); | ||
1475 | + context.fill(); | ||
1476 | + context.stroke(); | ||
1477 | + context.closePath(); | ||
1478 | + break; | ||
1479 | + case 'pie': | ||
1480 | + case 'ring': | ||
1481 | + context.beginPath(); | ||
1482 | + context.setFillStyle(item.color); | ||
1483 | + context.moveTo(startX + 7.5, startY + 5); | ||
1484 | + context.arc(startX + 7.5, startY + 5, 7, 0, 2 * Math.PI); | ||
1485 | + context.closePath(); | ||
1486 | + context.fill(); | ||
1487 | + break; | ||
1488 | + default: | ||
1489 | + context.beginPath(); | ||
1490 | + context.setFillStyle(item.color); | ||
1491 | + context.moveTo(startX, startY); | ||
1492 | + context.rect(startX, startY, 15, 10); | ||
1493 | + context.closePath(); | ||
1494 | + context.fill(); | ||
1495 | + } | ||
1496 | + startX += padding + shapeWidth; | ||
1497 | + context.beginPath(); | ||
1498 | + context.setFillStyle(opts.extra.legendTextColor || '#333333'); | ||
1499 | + context.fillText(item.name, startX, startY + 9); | ||
1500 | + context.closePath(); | ||
1501 | + context.stroke(); | ||
1502 | + startX += measureText(item.name) + 2 * padding; | ||
1503 | + }); | ||
1504 | + }); | ||
1505 | +} | ||
1506 | +function drawPieDataPoints(series, opts, config, context) { | ||
1507 | + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | ||
1508 | + | ||
1509 | + var pieOption = opts.extra.pie || {}; | ||
1510 | + series = getPieDataPoints(series, process); | ||
1511 | + var centerPosition = { | ||
1512 | + x: opts.width / 2, | ||
1513 | + y: (opts.height - config.legendHeight) / 2 | ||
1514 | + }; | ||
1515 | + var radius = Math.min(centerPosition.x - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, centerPosition.y - config.pieChartLinePadding - config.pieChartTextPadding); | ||
1516 | + if (opts.dataLabel) { | ||
1517 | + radius -= 10; | ||
1518 | + } else { | ||
1519 | + radius -= 2 * config.padding; | ||
1520 | + } | ||
1521 | + series = series.map(function (eachSeries) { | ||
1522 | + eachSeries._start_ += (pieOption.offsetAngle || 0) * Math.PI / 180; | ||
1523 | + return eachSeries; | ||
1524 | + }); | ||
1525 | + series.forEach(function (eachSeries) { | ||
1526 | + context.beginPath(); | ||
1527 | + context.setLineWidth(2); | ||
1528 | + context.setStrokeStyle('#ffffff'); | ||
1529 | + context.setFillStyle(eachSeries.color); | ||
1530 | + context.moveTo(centerPosition.x, centerPosition.y); | ||
1531 | + context.arc(centerPosition.x, centerPosition.y, radius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI); | ||
1532 | + context.closePath(); | ||
1533 | + context.fill(); | ||
1534 | + if (opts.disablePieStroke !== true) { | ||
1535 | + context.stroke(); | ||
1536 | + } | ||
1537 | + }); | ||
1538 | + | ||
1539 | + if (opts.type === 'ring') { | ||
1540 | + var innerPieWidth = radius * 0.6; | ||
1541 | + if (typeof opts.extra.ringWidth === 'number' && opts.extra.ringWidth > 0) { | ||
1542 | + innerPieWidth = Math.max(0, radius - opts.extra.ringWidth); | ||
1543 | + } | ||
1544 | + context.beginPath(); | ||
1545 | + context.setFillStyle(opts.background || '#ffffff'); | ||
1546 | + context.moveTo(centerPosition.x, centerPosition.y); | ||
1547 | + context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI); | ||
1548 | + context.closePath(); | ||
1549 | + context.fill(); | ||
1550 | + } | ||
1551 | + | ||
1552 | + if (opts.dataLabel !== false && process === 1) { | ||
1553 | + // fix https://github.com/xiaolin3303/wx-charts/issues/132 | ||
1554 | + var valid = false; | ||
1555 | + for (var i = 0, len = series.length; i < len; i++) { | ||
1556 | + if (series[i].data > 0) { | ||
1557 | + valid = true; | ||
1558 | + break; | ||
1559 | + } | ||
1560 | + } | ||
1561 | + | ||
1562 | + if (valid) { | ||
1563 | + drawPieText(series, opts, config, context, radius, centerPosition); | ||
1564 | + } | ||
1565 | + } | ||
1566 | + | ||
1567 | + if (process === 1 && opts.type === 'ring') { | ||
1568 | + drawRingTitle(opts, config, context); | ||
1569 | + } | ||
1570 | + | ||
1571 | + return { | ||
1572 | + center: centerPosition, | ||
1573 | + radius: radius, | ||
1574 | + series: series | ||
1575 | + }; | ||
1576 | +} | ||
1577 | + | ||
1578 | +function drawRadarDataPoints(series, opts, config, context) { | ||
1579 | + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; | ||
1580 | + | ||
1581 | + var radarOption = opts.extra.radar || {}; | ||
1582 | + var coordinateAngle = getRadarCoordinateSeries(opts.categories.length); | ||
1583 | + var centerPosition = { | ||
1584 | + x: opts.width / 2, | ||
1585 | + y: (opts.height - config.legendHeight) / 2 | ||
1586 | + }; | ||
1587 | + | ||
1588 | + var radius = Math.min(centerPosition.x - (getMaxTextListLength(opts.categories) + config.radarLabelTextMargin), centerPosition.y - config.radarLabelTextMargin); | ||
1589 | + | ||
1590 | + radius -= config.padding; | ||
1591 | + | ||
1592 | + // draw grid | ||
1593 | + context.beginPath(); | ||
1594 | + context.setLineWidth(1); | ||
1595 | + context.setStrokeStyle(radarOption.gridColor || "#cccccc"); | ||
1596 | + coordinateAngle.forEach(function (angle) { | ||
1597 | + var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition); | ||
1598 | + context.moveTo(centerPosition.x, centerPosition.y); | ||
1599 | + context.lineTo(pos.x, pos.y); | ||
1600 | + }); | ||
1601 | + context.stroke(); | ||
1602 | + context.closePath(); | ||
1603 | + | ||
1604 | + // draw split line grid | ||
1605 | + | ||
1606 | + var _loop = function _loop(i) { | ||
1607 | + var startPos = {}; | ||
1608 | + context.beginPath(); | ||
1609 | + context.setLineWidth(1); | ||
1610 | + context.setStrokeStyle(radarOption.gridColor || "#cccccc"); | ||
1611 | + coordinateAngle.forEach(function (angle, index) { | ||
1612 | + var pos = convertCoordinateOrigin(radius / config.radarGridCount * i * Math.cos(angle), radius / config.radarGridCount * i * Math.sin(angle), centerPosition); | ||
1613 | + if (index === 0) { | ||
1614 | + startPos = pos; | ||
1615 | + context.moveTo(pos.x, pos.y); | ||
1616 | + } else { | ||
1617 | + context.lineTo(pos.x, pos.y); | ||
1618 | + } | ||
1619 | + }); | ||
1620 | + context.lineTo(startPos.x, startPos.y); | ||
1621 | + context.stroke(); | ||
1622 | + context.closePath(); | ||
1623 | + }; | ||
1624 | + | ||
1625 | + for (var i = 1; i <= config.radarGridCount; i++) { | ||
1626 | + _loop(i); | ||
1627 | + } | ||
1628 | + | ||
1629 | + var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process); | ||
1630 | + radarDataPoints.forEach(function (eachSeries, seriesIndex) { | ||
1631 | + // 绘制区域数据 | ||
1632 | + context.beginPath(); | ||
1633 | + context.setFillStyle(eachSeries.color); | ||
1634 | + context.setGlobalAlpha(0.6); | ||
1635 | + eachSeries.data.forEach(function (item, index) { | ||
1636 | + if (index === 0) { | ||
1637 | + context.moveTo(item.position.x, item.position.y); | ||
1638 | + } else { | ||
1639 | + context.lineTo(item.position.x, item.position.y); | ||
1640 | + } | ||
1641 | + }); | ||
1642 | + context.closePath(); | ||
1643 | + context.fill(); | ||
1644 | + context.setGlobalAlpha(1); | ||
1645 | + | ||
1646 | + if (opts.dataPointShape !== false) { | ||
1647 | + var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length]; | ||
1648 | + var points = eachSeries.data.map(function (item) { | ||
1649 | + return item.position; | ||
1650 | + }); | ||
1651 | + drawPointShape(points, eachSeries.color, shape, context); | ||
1652 | + } | ||
1653 | + }); | ||
1654 | + // draw label text | ||
1655 | + drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context); | ||
1656 | + | ||
1657 | + return { | ||
1658 | + center: centerPosition, | ||
1659 | + radius: radius, | ||
1660 | + angleList: coordinateAngle | ||
1661 | + }; | ||
1662 | +} | ||
1663 | + | ||
1664 | +function drawCanvas(opts, context) { | ||
1665 | + context.draw(); | ||
1666 | +} | ||
1667 | + | ||
1668 | +var Timing = { | ||
1669 | + easeIn: function easeIn(pos) { | ||
1670 | + return Math.pow(pos, 3); | ||
1671 | + }, | ||
1672 | + | ||
1673 | + easeOut: function easeOut(pos) { | ||
1674 | + return Math.pow(pos - 1, 3) + 1; | ||
1675 | + }, | ||
1676 | + | ||
1677 | + easeInOut: function easeInOut(pos) { | ||
1678 | + if ((pos /= 0.5) < 1) { | ||
1679 | + return 0.5 * Math.pow(pos, 3); | ||
1680 | + } else { | ||
1681 | + return 0.5 * (Math.pow(pos - 2, 3) + 2); | ||
1682 | + } | ||
1683 | + }, | ||
1684 | + | ||
1685 | + linear: function linear(pos) { | ||
1686 | + return pos; | ||
1687 | + } | ||
1688 | +}; | ||
1689 | + | ||
1690 | +function Animation(opts) { | ||
1691 | + this.isStop = false; | ||
1692 | + opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration; | ||
1693 | + opts.timing = opts.timing || 'linear'; | ||
1694 | + | ||
1695 | + var delay = 17; | ||
1696 | + | ||
1697 | + var createAnimationFrame = function createAnimationFrame() { | ||
1698 | + if (typeof requestAnimationFrame !== 'undefined') { | ||
1699 | + return requestAnimationFrame; | ||
1700 | + } else if (typeof setTimeout !== 'undefined') { | ||
1701 | + return function (step, delay) { | ||
1702 | + setTimeout(function () { | ||
1703 | + var timeStamp = +new Date(); | ||
1704 | + step(timeStamp); | ||
1705 | + }, delay); | ||
1706 | + }; | ||
1707 | + } else { | ||
1708 | + return function (step) { | ||
1709 | + step(null); | ||
1710 | + }; | ||
1711 | + } | ||
1712 | + }; | ||
1713 | + var animationFrame = createAnimationFrame(); | ||
1714 | + var startTimeStamp = null; | ||
1715 | + var _step = function step(timestamp) { | ||
1716 | + if (timestamp === null || this.isStop === true) { | ||
1717 | + opts.onProcess && opts.onProcess(1); | ||
1718 | + opts.onAnimationFinish && opts.onAnimationFinish(); | ||
1719 | + return; | ||
1720 | + } | ||
1721 | + if (startTimeStamp === null) { | ||
1722 | + startTimeStamp = timestamp; | ||
1723 | + } | ||
1724 | + if (timestamp - startTimeStamp < opts.duration) { | ||
1725 | + var process = (timestamp - startTimeStamp) / opts.duration; | ||
1726 | + var timingFunction = Timing[opts.timing]; | ||
1727 | + process = timingFunction(process); | ||
1728 | + opts.onProcess && opts.onProcess(process); | ||
1729 | + animationFrame(_step, delay); | ||
1730 | + } else { | ||
1731 | + opts.onProcess && opts.onProcess(1); | ||
1732 | + opts.onAnimationFinish && opts.onAnimationFinish(); | ||
1733 | + } | ||
1734 | + }; | ||
1735 | + _step = _step.bind(this); | ||
1736 | + | ||
1737 | + animationFrame(_step, delay); | ||
1738 | +} | ||
1739 | + | ||
1740 | +// stop animation immediately | ||
1741 | +// and tigger onAnimationFinish | ||
1742 | +Animation.prototype.stop = function () { | ||
1743 | + this.isStop = true; | ||
1744 | +}; | ||
1745 | + | ||
1746 | +function drawCharts(type, opts, config, context) { | ||
1747 | + var _this = this; | ||
1748 | + | ||
1749 | + var series = opts.series; | ||
1750 | + var categories = opts.categories; | ||
1751 | + series = fillSeriesColor(series, config); | ||
1752 | + | ||
1753 | + var _calLegendData = calLegendData(series, opts, config), | ||
1754 | + legendHeight = _calLegendData.legendHeight; | ||
1755 | + | ||
1756 | + config.legendHeight = legendHeight; | ||
1757 | + | ||
1758 | + var _calYAxisData = calYAxisData(series, opts, config), | ||
1759 | + yAxisWidth = _calYAxisData.yAxisWidth; | ||
1760 | + | ||
1761 | + config.yAxisWidth = yAxisWidth; | ||
1762 | + if (categories && categories.length) { | ||
1763 | + var _calCategoriesData = calCategoriesData(categories, opts, config), | ||
1764 | + xAxisHeight = _calCategoriesData.xAxisHeight, | ||
1765 | + angle = _calCategoriesData.angle; | ||
1766 | + | ||
1767 | + config.xAxisHeight = xAxisHeight; | ||
1768 | + config._xAxisTextAngle_ = angle; | ||
1769 | + } | ||
1770 | + if (type === 'pie' || type === 'ring') { | ||
1771 | + config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(series); | ||
1772 | + } | ||
1773 | + | ||
1774 | + var duration = opts.animation ? 1000 : 0; | ||
1775 | + this.animationInstance && this.animationInstance.stop(); | ||
1776 | + switch (type) { | ||
1777 | + case 'line': | ||
1778 | + this.animationInstance = new Animation({ | ||
1779 | + timing: 'easeIn', | ||
1780 | + duration: duration, | ||
1781 | + onProcess: function onProcess(process) { | ||
1782 | + drawYAxisGrid(opts, config, context); | ||
1783 | + | ||
1784 | + var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process), | ||
1785 | + xAxisPoints = _drawLineDataPoints.xAxisPoints, | ||
1786 | + calPoints = _drawLineDataPoints.calPoints, | ||
1787 | + eachSpacing = _drawLineDataPoints.eachSpacing; | ||
1788 | + | ||
1789 | + _this.chartData.xAxisPoints = xAxisPoints; | ||
1790 | + _this.chartData.calPoints = calPoints; | ||
1791 | + _this.chartData.eachSpacing = eachSpacing; | ||
1792 | + drawXAxis(categories, opts, config, context); | ||
1793 | + drawLegend(opts.series, opts, config, context); | ||
1794 | + drawYAxis(series, opts, config, context); | ||
1795 | + drawToolTipBridge(opts, config, context, process); | ||
1796 | + drawCanvas(opts, context); | ||
1797 | + }, | ||
1798 | + onAnimationFinish: function onAnimationFinish() { | ||
1799 | + _this.event.trigger('renderComplete'); | ||
1800 | + } | ||
1801 | + }); | ||
1802 | + break; | ||
1803 | + case 'column': | ||
1804 | + this.animationInstance = new Animation({ | ||
1805 | + timing: 'easeIn', | ||
1806 | + duration: duration, | ||
1807 | + onProcess: function onProcess(process) { | ||
1808 | + drawYAxisGrid(opts, config, context); | ||
1809 | + | ||
1810 | + var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process), | ||
1811 | + xAxisPoints = _drawColumnDataPoints.xAxisPoints, | ||
1812 | + eachSpacing = _drawColumnDataPoints.eachSpacing; | ||
1813 | + | ||
1814 | + _this.chartData.xAxisPoints = xAxisPoints; | ||
1815 | + _this.chartData.eachSpacing = eachSpacing; | ||
1816 | + drawXAxis(categories, opts, config, context); | ||
1817 | + drawLegend(opts.series, opts, config, context); | ||
1818 | + drawYAxis(series, opts, config, context); | ||
1819 | + drawCanvas(opts, context); | ||
1820 | + }, | ||
1821 | + onAnimationFinish: function onAnimationFinish() { | ||
1822 | + _this.event.trigger('renderComplete'); | ||
1823 | + } | ||
1824 | + }); | ||
1825 | + break; | ||
1826 | + case 'area': | ||
1827 | + this.animationInstance = new Animation({ | ||
1828 | + timing: 'easeIn', | ||
1829 | + duration: duration, | ||
1830 | + onProcess: function onProcess(process) { | ||
1831 | + drawYAxisGrid(opts, config, context); | ||
1832 | + | ||
1833 | + var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process), | ||
1834 | + xAxisPoints = _drawAreaDataPoints.xAxisPoints, | ||
1835 | + calPoints = _drawAreaDataPoints.calPoints, | ||
1836 | + eachSpacing = _drawAreaDataPoints.eachSpacing; | ||
1837 | + | ||
1838 | + _this.chartData.xAxisPoints = xAxisPoints; | ||
1839 | + _this.chartData.calPoints = calPoints; | ||
1840 | + _this.chartData.eachSpacing = eachSpacing; | ||
1841 | + drawXAxis(categories, opts, config, context); | ||
1842 | + drawLegend(opts.series, opts, config, context); | ||
1843 | + drawYAxis(series, opts, config, context); | ||
1844 | + drawToolTipBridge(opts, config, context, process); | ||
1845 | + drawCanvas(opts, context); | ||
1846 | + }, | ||
1847 | + onAnimationFinish: function onAnimationFinish() { | ||
1848 | + _this.event.trigger('renderComplete'); | ||
1849 | + } | ||
1850 | + }); | ||
1851 | + break; | ||
1852 | + case 'ring': | ||
1853 | + case 'pie': | ||
1854 | + this.animationInstance = new Animation({ | ||
1855 | + timing: 'easeInOut', | ||
1856 | + duration: duration, | ||
1857 | + onProcess: function onProcess(process) { | ||
1858 | + _this.chartData.pieData = drawPieDataPoints(series, opts, config, context, process); | ||
1859 | + drawLegend(opts.series, opts, config, context); | ||
1860 | + drawCanvas(opts, context); | ||
1861 | + }, | ||
1862 | + onAnimationFinish: function onAnimationFinish() { | ||
1863 | + _this.event.trigger('renderComplete'); | ||
1864 | + } | ||
1865 | + }); | ||
1866 | + break; | ||
1867 | + case 'radar': | ||
1868 | + this.animationInstance = new Animation({ | ||
1869 | + timing: 'easeInOut', | ||
1870 | + duration: duration, | ||
1871 | + onProcess: function onProcess(process) { | ||
1872 | + _this.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process); | ||
1873 | + drawLegend(opts.series, opts, config, context); | ||
1874 | + drawCanvas(opts, context); | ||
1875 | + }, | ||
1876 | + onAnimationFinish: function onAnimationFinish() { | ||
1877 | + _this.event.trigger('renderComplete'); | ||
1878 | + } | ||
1879 | + }); | ||
1880 | + break; | ||
1881 | + } | ||
1882 | +} | ||
1883 | + | ||
1884 | +// simple event implement | ||
1885 | + | ||
1886 | +function Event() { | ||
1887 | + this.events = {}; | ||
1888 | +} | ||
1889 | + | ||
1890 | +Event.prototype.addEventListener = function (type, listener) { | ||
1891 | + this.events[type] = this.events[type] || []; | ||
1892 | + this.events[type].push(listener); | ||
1893 | +}; | ||
1894 | + | ||
1895 | +Event.prototype.trigger = function () { | ||
1896 | + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
1897 | + args[_key] = arguments[_key]; | ||
1898 | + } | ||
1899 | + | ||
1900 | + var type = args[0]; | ||
1901 | + var params = args.slice(1); | ||
1902 | + if (!!this.events[type]) { | ||
1903 | + this.events[type].forEach(function (listener) { | ||
1904 | + try { | ||
1905 | + listener.apply(null, params); | ||
1906 | + } catch (e) { | ||
1907 | + console.error(e); | ||
1908 | + } | ||
1909 | + }); | ||
1910 | + } | ||
1911 | +}; | ||
1912 | + | ||
1913 | +var Charts = function Charts(opts) { | ||
1914 | + opts.title = opts.title || {}; | ||
1915 | + opts.subtitle = opts.subtitle || {}; | ||
1916 | + opts.yAxis = opts.yAxis || {}; | ||
1917 | + opts.xAxis = opts.xAxis || {}; | ||
1918 | + opts.extra = opts.extra || {}; | ||
1919 | + opts.legend = opts.legend === false ? false : true; | ||
1920 | + opts.animation = opts.animation === false ? false : true; | ||
1921 | + var config$$1 = assign({}, config); | ||
1922 | + config$$1.yAxisTitleWidth = opts.yAxis.disabled !== true && opts.yAxis.title ? config$$1.yAxisTitleWidth : 0; | ||
1923 | + config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : config$$1.pieChartLinePadding; | ||
1924 | + config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding; | ||
1925 | + | ||
1926 | + this.opts = opts; | ||
1927 | + this.config = config$$1; | ||
1928 | + this.context = wx.createCanvasContext(opts.canvasId); | ||
1929 | + // store calcuated chart data | ||
1930 | + // such as chart point coordinate | ||
1931 | + this.chartData = {}; | ||
1932 | + this.event = new Event(); | ||
1933 | + this.scrollOption = { | ||
1934 | + currentOffset: 0, | ||
1935 | + startTouchX: 0, | ||
1936 | + distance: 0 | ||
1937 | + }; | ||
1938 | + | ||
1939 | + drawCharts.call(this, opts.type, opts, config$$1, this.context); | ||
1940 | +}; | ||
1941 | + | ||
1942 | +Charts.prototype.updateData = function () { | ||
1943 | + var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
1944 | + | ||
1945 | + this.opts.series = data.series || this.opts.series; | ||
1946 | + this.opts.categories = data.categories || this.opts.categories; | ||
1947 | + | ||
1948 | + this.opts.title = assign({}, this.opts.title, data.title || {}); | ||
1949 | + this.opts.subtitle = assign({}, this.opts.subtitle, data.subtitle || {}); | ||
1950 | + | ||
1951 | + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context); | ||
1952 | +}; | ||
1953 | + | ||
1954 | +Charts.prototype.stopAnimation = function () { | ||
1955 | + this.animationInstance && this.animationInstance.stop(); | ||
1956 | +}; | ||
1957 | + | ||
1958 | +Charts.prototype.addEventListener = function (type, listener) { | ||
1959 | + this.event.addEventListener(type, listener); | ||
1960 | +}; | ||
1961 | + | ||
1962 | +Charts.prototype.getCurrentDataIndex = function (e) { | ||
1963 | + var touches = e.touches && e.touches.length ? e.touches : e.changedTouches; | ||
1964 | + if (touches && touches.length) { | ||
1965 | + var _touches$ = touches[0], | ||
1966 | + x = _touches$.x, | ||
1967 | + y = _touches$.y; | ||
1968 | + | ||
1969 | + if (this.opts.type === 'pie' || this.opts.type === 'ring') { | ||
1970 | + return findPieChartCurrentIndex({ x: x, y: y }, this.chartData.pieData); | ||
1971 | + } else if (this.opts.type === 'radar') { | ||
1972 | + return findRadarChartCurrentIndex({ x: x, y: y }, this.chartData.radarData, this.opts.categories.length); | ||
1973 | + } else { | ||
1974 | + return findCurrentIndex({ x: x, y: y }, this.chartData.xAxisPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset)); | ||
1975 | + } | ||
1976 | + } | ||
1977 | + return -1; | ||
1978 | +}; | ||
1979 | + | ||
1980 | +Charts.prototype.showToolTip = function (e) { | ||
1981 | + var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
1982 | + | ||
1983 | + if (this.opts.type === 'line' || this.opts.type === 'area') { | ||
1984 | + var index = this.getCurrentDataIndex(e); | ||
1985 | + var currentOffset = this.scrollOption.currentOffset; | ||
1986 | + | ||
1987 | + var opts = assign({}, this.opts, { | ||
1988 | + _scrollDistance_: currentOffset, | ||
1989 | + animation: false | ||
1990 | + }); | ||
1991 | + if (index > -1) { | ||
1992 | + var seriesData = getSeriesDataItem(this.opts.series, index); | ||
1993 | + if (seriesData.length === 0) { | ||
1994 | + drawCharts.call(this, opts.type, opts, this.config, this.context); | ||
1995 | + } else { | ||
1996 | + var _getToolTipData = getToolTipData(seriesData, this.chartData.calPoints, index, this.opts.categories, option), | ||
1997 | + textList = _getToolTipData.textList, | ||
1998 | + offset = _getToolTipData.offset; | ||
1999 | + | ||
2000 | + opts.tooltip = { | ||
2001 | + textList: textList, | ||
2002 | + offset: offset, | ||
2003 | + option: option | ||
2004 | + }; | ||
2005 | + drawCharts.call(this, opts.type, opts, this.config, this.context); | ||
2006 | + } | ||
2007 | + } else { | ||
2008 | + drawCharts.call(this, opts.type, opts, this.config, this.context); | ||
2009 | + } | ||
2010 | + } | ||
2011 | +}; | ||
2012 | + | ||
2013 | +Charts.prototype.scrollStart = function (e) { | ||
2014 | + if (e.touches[0] && this.opts.enableScroll === true) { | ||
2015 | + this.scrollOption.startTouchX = e.touches[0].x; | ||
2016 | + } | ||
2017 | +}; | ||
2018 | + | ||
2019 | +Charts.prototype.scroll = function (e) { | ||
2020 | + // TODO throtting... | ||
2021 | + if (e.touches[0] && this.opts.enableScroll === true) { | ||
2022 | + var _distance = e.touches[0].x - this.scrollOption.startTouchX; | ||
2023 | + var currentOffset = this.scrollOption.currentOffset; | ||
2024 | + | ||
2025 | + var validDistance = calValidDistance(currentOffset + _distance, this.chartData, this.config, this.opts); | ||
2026 | + | ||
2027 | + this.scrollOption.distance = _distance = validDistance - currentOffset; | ||
2028 | + var opts = assign({}, this.opts, { | ||
2029 | + _scrollDistance_: currentOffset + _distance, | ||
2030 | + animation: false | ||
2031 | + }); | ||
2032 | + | ||
2033 | + drawCharts.call(this, opts.type, opts, this.config, this.context); | ||
2034 | + } | ||
2035 | +}; | ||
2036 | + | ||
2037 | +Charts.prototype.scrollEnd = function (e) { | ||
2038 | + if (this.opts.enableScroll === true) { | ||
2039 | + var _scrollOption = this.scrollOption, | ||
2040 | + currentOffset = _scrollOption.currentOffset, | ||
2041 | + distance = _scrollOption.distance; | ||
2042 | + | ||
2043 | + this.scrollOption.currentOffset = currentOffset + distance; | ||
2044 | + this.scrollOption.distance = 0; | ||
2045 | + } | ||
2046 | +}; | ||
2047 | + | ||
2048 | +module.exports = Charts; |
请
注册
或
登录
后发表评论