正在显示
18 个修改的文件
包含
2774 行增加
和
28 行删除
... | ... | @@ -126,7 +126,8 @@ App({ |
126 | 126 | onshow_count: 0, |
127 | 127 | // baseUrl: "http://47.99.47.16:20000/", |
128 | 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 | 131 | OSSUrl: "",//"https://oss.workai.com.cn/", |
131 | 132 | userInfo: null, |
132 | 133 | hasLogin: false, |
... | ... |
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | |
48 | 48 | .text_333_28 { |
49 | 49 | font-family: PingFangSC-Regular; |
50 | - font-size: 26rpx; | |
50 | + font-size: 28rpx; | |
51 | 51 | color: #333; |
52 | 52 | text-align: right; |
53 | 53 | line-height: 80rpx; |
... | ... | @@ -57,6 +57,14 @@ |
57 | 57 | font-family: PingFangSC-Regular; |
58 | 58 | font-size: 30rpx; |
59 | 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 | 70 | .text_333_30_bold { |
... | ... | @@ -67,7 +75,7 @@ |
67 | 75 | |
68 | 76 | .text_999_28 { |
69 | 77 | font-family: PingFangSC-Regular; |
70 | - font-size: 26rpx; | |
78 | + font-size: 28rpx; | |
71 | 79 | color: #999; |
72 | 80 | text-align: right; |
73 | 81 | line-height: 80rpx; |
... | ... |
1 | 1 | <!--pages/main/advancepayment/home.wxml--> |
2 | 2 | <view class='page'> |
3 | - <scroll-view> | |
3 | + <scroll-view style='margin-bottom:40rpx'> | |
4 | 4 | <view style='padding:30rpx;background:#ffffff'> |
5 | 5 | <view> |
6 | 6 | <text class='text_gray_32'>当前选择月份</text> |
... | ... | @@ -45,16 +45,61 @@ |
45 | 45 | <text class='text_333_30_bold float_right'>32983000.00</text> |
46 | 46 | </view> |
47 | 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 | 49 | <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image> |
50 | 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 | 78 | </view> |
56 | - | |
57 | 79 | </view> |
58 | 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 | 104 | </scroll-view> |
60 | -</view> | |
\ No newline at end of file | ||
105 | + </view> | |
\ No newline at end of file | ||
... | ... |
1 | 1 | /* pages/main/advancepayment/home.wxss */ |
2 | -.page{ | |
2 | + | |
3 | +.page { | |
3 | 4 | background-color: #fcfcfc; |
4 | 5 | } |
5 | 6 | |
6 | 7 | .text_gray_32 { |
7 | 8 | font-size: 32rpx; |
8 | - color: #6C7596 ; | |
9 | + color: #6c7596; | |
9 | 10 | font-family: PingFangSC-Semibold; |
10 | 11 | line-height: 100rpx; |
11 | 12 | } |
... | ... | @@ -15,10 +16,52 @@ |
15 | 16 | width: 40rpx; |
16 | 17 | height: 40rpx; |
17 | 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 | 23 | width: 92%; |
23 | 24 | height: 312rpx; |
24 | -} | |
\ No newline at end of file | ||
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 | +}) | |
\ No newline at end of file | ||
... | ... |
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> | |
\ No newline at end of file | ||
... | ... |
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 | 1 | // pages/main/finalpayment/home.js |
2 | +var wxCharts = require('../../../utils/wxcharts.js'); | |
3 | +var app = getApp(); | |
4 | +var pieChart = null; | |
2 | 5 | Page({ |
3 | 6 | |
4 | 7 | /** |
... | ... | @@ -11,56 +14,99 @@ Page({ |
11 | 14 | /** |
12 | 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 | 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 | 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 | 79 | * Lifecycle function--Called when page hide |
34 | 80 | */ |
35 | - onHide: function () { | |
81 | + onHide: function() { | |
36 | 82 | |
37 | 83 | }, |
38 | 84 | |
39 | 85 | /** |
40 | 86 | * Lifecycle function--Called when page unload |
41 | 87 | */ |
42 | - onUnload: function () { | |
88 | + onUnload: function() { | |
43 | 89 | |
44 | 90 | }, |
45 | 91 | |
46 | 92 | /** |
47 | 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 | 100 | * Called when page reach bottom |
55 | 101 | */ |
56 | - onReachBottom: function () { | |
102 | + onReachBottom: function() { | |
57 | 103 | |
58 | 104 | }, |
59 | 105 | |
60 | 106 | /** |
61 | 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 | }) |
\ No newline at end of file | ||
... | ... |
1 | 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> | |
\ No newline at end of file | ||
... | ... |
1 | -/* pages/main/finalpayment/home.wxss */ | |
\ No newline at end of file | ||
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 | +} | |
\ No newline at end of file | ||
... | ... |
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 | +}) | |
\ No newline at end of file | ||
... | ... |
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> | |
\ No newline at end of file | ||
... | ... |
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 | +} | |
\ No newline at end of file | ||
... | ... |
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; | |
... | ... |
请
注册
或
登录
后发表评论