提交 4ea54c3bdbdf12845badb1def105f19873355bbf

作者 wangyu
1 个父辈 f1b13b10

添加页面

@@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
18 <text wx:if="{{selected&&disabled}}" class="text_999_28 float_right">{{selected}}</text> 18 <text wx:if="{{selected&&disabled}}" class="text_999_28 float_right">{{selected}}</text>
19 <text wx:elif="{{selected}}" class="text_333_28 float_right ">{{selected}}</text> 19 <text wx:elif="{{selected}}" class="text_333_28 float_right ">{{selected}}</text>
20 <text wx:else class="text_999_28 float_right ">{{placeholder}}</text> 20 <text wx:else class="text_999_28 float_right ">{{placeholder}}</text>
21 -  
22 </picker> 21 </picker>
23 </view> 22 </view>
24 </view> 23 </view>
1 // pages/main/addtionalreduce/addextrainfo/addextrainfo.js 1 // pages/main/addtionalreduce/addextrainfo/addextrainfo.js
  2 +var OSSInit;
  3 +var baseUrl = getApp().globalData.baseUrl;
2 Page({ 4 Page({
3 5
4 /** 6 /**
@@ -8,7 +10,8 @@ Page({ @@ -8,7 +10,8 @@ Page({
8 lable:0, 10 lable:0,
9 title_arr: ["添加子女", "添加继续教育", "添加老人", "添加大病医疗", "添加住房贷款利息"], 11 title_arr: ["添加子女", "添加继续教育", "添加老人", "添加大病医疗", "添加住房贷款利息"],
10 extrainfo_arr: ["请上传子女出生证明、学籍信息凭证、学费凭证、本人结婚证和分摊协议", "请上传学历学籍凭证", "请上传出生证明或关系证明、独生子女证、分摊协议、其他法定赡养人赡养证明", "请上传诊断书和医疗费用收据", "请上传首套房证明、还款证明、不动产登记证、结婚证和夫妻约定抵扣协议"], 12 extrainfo_arr: ["请上传子女出生证明、学籍信息凭证、学费凭证、本人结婚证和分摊协议", "请上传学历学籍凭证", "请上传出生证明或关系证明、独生子女证、分摊协议、其他法定赡养人赡养证明", "请上传诊断书和医疗费用收据", "请上传首套房证明、还款证明、不动产登记证、结婚证和夫妻约定抵扣协议"],
11 - cur_index:0 13 + cur_index:0,
  14 + img_path:"/images/upload_img.png"
12 }, 15 },
13 16
14 /** 17 /**
@@ -22,6 +25,38 @@ Page({ @@ -22,6 +25,38 @@ Page({
22 wx.setNavigationBarTitle({ 25 wx.setNavigationBarTitle({
23 title: this.data.title_arr[this.data.cur_index] 26 title: this.data.title_arr[this.data.cur_index]
24 }) 27 })
  28 + this.initOSS()
  29 + },
  30 +
  31 + initOSS: function () {
  32 + var that = this
  33 + var Authorization = getApp().globalData.Authorization;
  34 + //OSS 上传前init
  35 + wx.showLoading()
  36 + wx.request({
  37 + url: baseUrl + "filemeta/v1/inits",
  38 + header: {
  39 + 'Authorization': Authorization
  40 + },
  41 + method: 'POST',
  42 + data: {
  43 + "access_type": "web_upload",
  44 + "action ": "put_object",
  45 + "instance_id": "",
  46 + "object_type": "wx_image"
  47 + },
  48 + success: function (result) {
  49 +
  50 + OSSInit = result.data
  51 + console.log(' OSS init 成功', OSSInit)
  52 + },
  53 + fail: function (res) {
  54 + console.log('OSS init 失败', res)
  55 + },
  56 + complete: function () {
  57 + wx.hideLoading()
  58 + }
  59 + })
25 }, 60 },
26 61
27 /** 62 /**
@@ -38,6 +73,84 @@ Page({ @@ -38,6 +73,84 @@ Page({
38 73
39 }, 74 },
40 75
  76 + gosave:function(){
  77 +
  78 + },
  79 +
  80 + goupload:function(e){
  81 + console.log(e)
  82 + var that = this
  83 + wx.chooseImage({
  84 + sourceType: ['camera', 'album'],
  85 + // sizeType: ['original'],
  86 + count: 1,
  87 + success: function (res) {
  88 + console.log('success', res)
  89 + that.setData({
  90 + img_path: res.tempFilePaths[0]
  91 + })
  92 + that.uploadImage(that.data.img_path)
  93 + }
  94 + })
  95 + },
  96 +
  97 + uploadImage: function (path) {
  98 + var that = this
  99 + wx.showLoading({
  100 + title: '上传图片中...',
  101 + })
  102 + console.log('key', 'imagepath_' + path.substring(path.length - 10, path.length))
  103 + wx.uploadFile({
  104 + url: getApp().globalData.OSSUrl,
  105 + filePath: path,
  106 + name: 'file',
  107 + formData: {
  108 + 'key': 'imagepath_' + path.substring(path.length - 15, path.length),
  109 + 'OSSAccessKeyId': OSSInit.access_key_id,
  110 + 'policy': OSSInit.policy,
  111 + 'signature': OSSInit.signature,
  112 + 'callback': OSSInit.callback_body,
  113 + 'x:access_token': OSSInit.callback_token,
  114 + 'success_action_status': '200',
  115 + },
  116 + success: function (res) {
  117 + console.log('uploadFile', res.data)
  118 + if (res.statusCode == 200) {
  119 + var data = JSON.parse(res.data)
  120 + console.log('上传成功', res)
  121 + that.oss_bucket = data.bucket
  122 +
  123 + } else {
  124 + var title = '图片上传失败,请重新上传'
  125 + if (res.statusCode == 413) {
  126 + title = '图片体积过大,请选择较小图片上传'
  127 + }
  128 + wx.showModal({
  129 + title: '上传失败',
  130 + content: title,
  131 + showCancel: false,
  132 + confirmColor: '#4E8FE7'
  133 + })
  134 + }
  135 + wx.hideLoading()
  136 + },
  137 + fail: function (err) {
  138 + console.log('fail', err)
  139 + wx.showModal({
  140 + title: '上传失败',
  141 + content: '图片上传失败,请重新上传',
  142 + showCancel: false,
  143 + confirmColor: '#4E8FE7'
  144 + })
  145 + wx.hideLoading()
  146 + },
  147 + complete(res) {
  148 + console.log('complete', res)
  149 + wx.hideLoading()
  150 + }
  151 + })
  152 + },
  153 +
41 /** 154 /**
42 * Lifecycle function--Called when page hide 155 * Lifecycle function--Called when page hide
43 */ 156 */
@@ -156,11 +156,11 @@ @@ -156,11 +156,11 @@
156 <view class='text_black_30 float_left'>上传材料</view> 156 <view class='text_black_30 float_left'>上传材料</view>
157 </view> 157 </view>
158 <view style='margin-bottom:140rpx'> 158 <view style='margin-bottom:140rpx'>
159 - <image src='/images/upload_img.png' style='width:100%;height:380rpx' bindtap='goupload'></image> 159 + <image src='{{img_path}}' style='width:100%;height:380rpx' bindtap='goupload'></image>
160 <view class='text_999_30' style='text-align:center;margin:20rpx 30rpx'>{{extrainfo_arr[cur_index]}}</view> 160 <view class='text_999_30' style='text-align:center;margin:20rpx 30rpx'>{{extrainfo_arr[cur_index]}}</view>
161 </view> 161 </view>
162 162
163 - <view class="btn_bottom"> 163 + <view class="btn_bottom" bindtap='gosave'>
164 <button class="btn_bottom"> 保存</button> 164 <button class="btn_bottom"> 保存</button>
165 </view> 165 </view>
166 </scroll-view> 166 </scroll-view>
@@ -29,6 +29,14 @@ Page({ @@ -29,6 +29,14 @@ Page({
29 }, { 29 }, {
30 sureid: false 30 sureid: false
31 }, ], 31 }, ],
  32 + unitData: {
  33 + label: '选择申报单位',
  34 + bindtype: 'unit',
  35 + selected: '',
  36 + values: ["北京小爱智能科技有限公司", "杭州蜗壳爱有限公司"],
  37 + placeholder: '请选择申报单位',
  38 + onChange: 'onPickerSelect'
  39 + },
32 40
33 }, 41 },
34 42
@@ -53,6 +61,15 @@ Page({ @@ -53,6 +61,15 @@ Page({
53 61
54 }, 62 },
55 63
  64 + onPickerSelect: function(e) {
  65 + console.log('picker发送选择改变,携带值为', e)
  66 + var unit_data = this.data.unitData
  67 + unit_data.selected = unit_data.values[e.detail.value]
  68 + this.setData({
  69 + unitData: unit_data
  70 + })
  71 + },
  72 +
56 selectRep: function(e) { 73 selectRep: function(e) {
57 let index = e.currentTarget.dataset.selectindex; //当前点击元素的自定义数据,这个很关键 74 let index = e.currentTarget.dataset.selectindex; //当前点击元素的自定义数据,这个很关键
58 let selectIndex = this.data.selectIndex; //取到data里的selectIndex 75 let selectIndex = this.data.selectIndex; //取到data里的selectIndex
@@ -63,8 +80,8 @@ Page({ @@ -63,8 +80,8 @@ Page({
63 }, 80 },
64 81
65 housing01: function(e) { 82 housing01: function(e) {
66 - this.setData ({  
67 - flag_housing01:!this.data.flag_housing01 83 + this.setData({
  84 + flag_housing01: !this.data.flag_housing01
68 }) 85 })
69 if (this.data.flag_housing02) { 86 if (this.data.flag_housing02) {
70 this.setData({ 87 this.setData({
@@ -75,7 +92,7 @@ Page({ @@ -75,7 +92,7 @@ Page({
75 92
76 housing02: function(e) { 93 housing02: function(e) {
77 this.setData({ 94 this.setData({
78 - flag_housing02:!this.data.flag_housing02 95 + flag_housing02: !this.data.flag_housing02
79 }) 96 })
80 if (this.data.flag_housing01) { 97 if (this.data.flag_housing01) {
81 this.setData({ 98 this.setData({
1 <!--pages/main/addtionalreduce/godeclare/godeclare.wxml--> 1 <!--pages/main/addtionalreduce/godeclare/godeclare.wxml-->
  2 +<import src="../../../common/picker_cell" />
  3 +
2 <view class='page'> 4 <view class='page'>
3 <view> 5 <view>
4 <view class='text_gray_30' style='padding:30rpx'>您新加入了一家单位,请选择在该单位申报的专项附加扣除项</view> 6 <view class='text_gray_30' style='padding:30rpx'>您新加入了一家单位,请选择在该单位申报的专项附加扣除项</view>
5 <view style='padding:0 30rpx'> 7 <view style='padding:0 30rpx'>
6 <view class='divide_line_f5f5f5'></view> 8 <view class='divide_line_f5f5f5'></view>
7 - <text class='text_black_30'>选择申报单位</text> 9 + <!-- <text class='text_black_30'>选择申报单位</text>
8 <view class='float_right'> 10 <view class='float_right'>
9 <text class='text_black_30'>请选择申报单位</text> 11 <text class='text_black_30'>请选择申报单位</text>
10 <image class='arrow_img_wrap' src='/images/arrow_right.png'></image> 12 <image class='arrow_img_wrap' src='/images/arrow_right.png'></image>
11 - </view> 13 + </view> -->
  14 + <template is="picker_cell_normal" data="{{...unitData}}" />
12 <view class='divide_line_f5f5f5'></view> 15 <view class='divide_line_f5f5f5'></view>
13 </view> 16 </view>
14 <text class='text_black_30' style='padding-left:30rpx'>选择专项附加扣除项</text> 17 <text class='text_black_30' style='padding-left:30rpx'>选择专项附加扣除项</text>
@@ -42,4 +42,12 @@ color: #1890FF; @@ -42,4 +42,12 @@ color: #1890FF;
42 .select_666_28{ 42 .select_666_28{
43 font-size: 28rpx; 43 font-size: 28rpx;
44 color: #666666; 44 color: #666666;
  45 +}
  46 +
  47 +.text_666_28 {
  48 + font-family: PingFangSC-Regular;
  49 + font-size: 28rpx;
  50 + color: #666;
  51 + text-align: right;
  52 + line-height: 80rpx;
45 } 53 }
@@ -29,6 +29,13 @@ Page({ @@ -29,6 +29,13 @@ Page({
29 29
30 }, 30 },
31 31
  32 + lookandadd:function(e){
  33 + console.log("e", e);
  34 + wx.navigateTo({
  35 + url: '../addextrainfo/addextrainfo?index=' + e.currentTarget.id,
  36 + })
  37 + },
  38 +
32 /** 39 /**
33 * Lifecycle function--Called when page hide 40 * Lifecycle function--Called when page hide
34 */ 41 */
1 -{}  
  1 +{
  2 + "navigationBarTitleText": "调整使用项"
  3 +}
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 <text class='text_gray_22 float_right'>剩余可抵扣额度:12810.00</text> 15 <text class='text_gray_22 float_right'>剩余可抵扣额度:12810.00</text>
16 </view> 16 </view>
17 <view class='divide_line_f5f5f5'></view> 17 <view class='divide_line_f5f5f5'></view>
18 - <view style='padding:20rpx 0'> 18 + <view style='padding:20rpx 0' bindtap='lookandadd' id='{{index}}'>
19 <text class='text_blue_28'>查看并调整</text> 19 <text class='text_blue_28'>查看并调整</text>
20 <image class='arrow_img_wrap' src='/images/arrow_right.png'></image> 20 <image class='arrow_img_wrap' src='/images/arrow_right.png'></image>
21 </view> 21 </view>
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <view class='card_rectangle_bg_column' style="margin-top:30rpx"> 6 <view class='card_rectangle_bg_column' style="margin-top:30rpx">
7 <view style='position:absolute' style='padding:44rpx 30rpx;'> 7 <view style='position:absolute' style='padding:44rpx 30rpx;'>
8 <view hidden='{{index!=0}}' style='float:left;margin-top:4rpx'> 8 <view hidden='{{index!=0}}' style='float:left;margin-top:4rpx'>
9 - <text class='text_999_32'>北京小爱科技北京小爱科小爱</text> 9 + <text class='text_999_32'>北京小爱科技北京小爱科</text>
10 </view> 10 </view>
11 <view hidden='{{index==0}}' style='float:left;margin-top:4rpx'> 11 <view hidden='{{index==0}}' style='float:left;margin-top:4rpx'>
12 <text class='text_black_32'>北京小爱科技北京小爱</text> 12 <text class='text_black_32'>北京小爱科技北京小爱</text>
1 // pages/main/finalpayment/historydetail/historydetail.js 1 // pages/main/finalpayment/historydetail/historydetail.js
2 -var wxCharts = require('../../../../utils/wxcharts.js'); 2 +var wxCharts = require('../../../../utils/wxcharts02.js');
3 var app = getApp(); 3 var app = getApp();
4 var pieChart = null; 4 var pieChart = null;
5 Page({ 5 Page({
@@ -14,12 +14,12 @@ @@ -14,12 +14,12 @@
14 <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image> 14 <image class=' payment_img_bg ' src='/images/payment_bg.png ' style='position:absolute;z-index: 1;'></image>
15 <view> 15 <view>
16 <view class='view_bg_wrap' style='margin-top: 48rpx;'> 16 <view class='view_bg_wrap' style='margin-top: 48rpx;'>
17 - <view style='flex-grow: 1;text-align:center;display: flex;flex-direction: column;'> 17 + <view style='flex: 1;text-align:center;display: flex;flex-direction: column;'>
18 <text class='text_num_wrap'>261609.90</text> 18 <text class='text_num_wrap'>261609.90</text>
19 <text class='text_text_wrap'>累计收入额</text> 19 <text class='text_text_wrap'>累计收入额</text>
20 </view> 20 </view>
21 <view style='width:2rpx;height:74rpx;background:#ffffff;'></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;'> 22 + <view style='flex: 1;text-align:center;display: flex;flex-direction: column;'>
23 <text class='text_num_wrap'>19106.91</text> 23 <text class='text_num_wrap'>19106.91</text>
24 <text class='text_text_wrap'>累计缴纳个税</text> 24 <text class='text_text_wrap'>累计缴纳个税</text>
25 </view> 25 </view>
@@ -20,16 +20,18 @@ @@ -20,16 +20,18 @@
20 } 20 }
21 21
22 .head_text_wrap1 { 22 .head_text_wrap1 {
23 - font-family: PingFangSC-Regular;  
24 - font-size: 12px;  
25 - color: #999;  
26 line-height: 70rpx; 23 line-height: 70rpx;
  24 + font-family: PingFangSC-Semibold;
  25 + font-size: 14px;
  26 + color: #333;
  27 + letter-spacing: 0;
  28 + text-align: left;
27 } 29 }
28 30
29 .head_text_wrap2 { 31 .head_text_wrap2 {
30 font-family: PingFang-SC-Medium; 32 font-family: PingFang-SC-Medium;
31 font-size: 12px; 33 font-size: 12px;
32 - color: #c9c9c9; 34 + color: #999;
33 letter-spacing: 0; 35 letter-spacing: 0;
34 text-align: left; 36 text-align: left;
35 } 37 }
@@ -18,16 +18,18 @@ @@ -18,16 +18,18 @@
18 } 18 }
19 19
20 .head_text_wrap1 { 20 .head_text_wrap1 {
21 - font-family: PingFangSC-Regular;  
22 - font-size: 12px;  
23 - color: #999;  
24 line-height: 70rpx; 21 line-height: 70rpx;
  22 + font-family: PingFangSC-Semibold;
  23 + font-size: 14px;
  24 + color: #333;
  25 + letter-spacing: 0;
  26 + text-align: left;
25 } 27 }
26 28
27 .head_text_wrap2 { 29 .head_text_wrap2 {
28 font-family: PingFang-SC-Medium; 30 font-family: PingFang-SC-Medium;
29 font-size: 12px; 31 font-size: 12px;
30 - color: #c9c9c9; 32 + color: #999;
31 letter-spacing: 0; 33 letter-spacing: 0;
32 text-align: left; 34 text-align: left;
33 } 35 }
@@ -34,7 +34,7 @@ var config = { @@ -34,7 +34,7 @@ var config = {
34 toolTipLineHeight: 14, 34 toolTipLineHeight: 14,
35 radarGridCount: 3, 35 radarGridCount: 3,
36 radarLabelTextMargin: 15 36 radarLabelTextMargin: 15
37 -}; 37 +};
38 38
39 // Object.assign polyfill 39 // Object.assign polyfill
40 // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 40 // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
  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: ['#6F39FF', '#FF76A5', '#EF344D', '#FFBB23', '#2092FF'],
  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 +};
  36 +
  37 +// Object.assign polyfill
  38 +// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
  39 +function assign(target, varArgs) {
  40 + if (target == null) {
  41 + // TypeError if undefined or null
  42 + throw new TypeError('Cannot convert undefined or null to object');
  43 + }
  44 +
  45 + var to = Object(target);
  46 +
  47 + for (var index = 1; index < arguments.length; index++) {
  48 + var nextSource = arguments[index];
  49 +
  50 + if (nextSource != null) {
  51 + // Skip over if undefined or null
  52 + for (var nextKey in nextSource) {
  53 + // Avoid bugs when hasOwnProperty is shadowed
  54 + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
  55 + to[nextKey] = nextSource[nextKey];
  56 + }
  57 + }
  58 + }
  59 + }
  60 + return to;
  61 +}
  62 +
  63 +var util = {
  64 + toFixed: function toFixed(num, limit) {
  65 + limit = limit || 2;
  66 + if (this.isFloat(num)) {
  67 + num = num.toFixed(limit);
  68 + }
  69 + return num;
  70 + },
  71 + isFloat: function isFloat(num) {
  72 + return num % 1 !== 0;
  73 + },
  74 + approximatelyEqual: function approximatelyEqual(num1, num2) {
  75 + return Math.abs(num1 - num2) < 1e-10;
  76 + },
  77 + isSameSign: function isSameSign(num1, num2) {
  78 + return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
  79 + },
  80 + isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
  81 + return this.isSameSign(p1.x, p2.x);
  82 + },
  83 + isCollision: function isCollision(obj1, obj2) {
  84 + obj1.end = {};
  85 + obj1.end.x = obj1.start.x + obj1.width;
  86 + obj1.end.y = obj1.start.y - obj1.height;
  87 + obj2.end = {};
  88 + obj2.end.x = obj2.start.x + obj2.width;
  89 + obj2.end.y = obj2.start.y - obj2.height;
  90 + 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;
  91 +
  92 + return !flag;
  93 + }
  94 +};
  95 +
  96 +function findRange(num, type, limit) {
  97 + if (isNaN(num)) {
  98 + throw new Error('[wxCharts] unvalid series data!');
  99 + }
  100 + limit = limit || 10;
  101 + type = type ? type : 'upper';
  102 + var multiple = 1;
  103 + while (limit < 1) {
  104 + limit *= 10;
  105 + multiple *= 10;
  106 + }
  107 + if (type === 'upper') {
  108 + num = Math.ceil(num * multiple);
  109 + } else {
  110 + num = Math.floor(num * multiple);
  111 + }
  112 + while (num % limit !== 0) {
  113 + if (type === 'upper') {
  114 + num++;
  115 + } else {
  116 + num--;
  117 + }
  118 + }
  119 +
  120 + return num / multiple;
  121 +}
  122 +
  123 +function calValidDistance(distance, chartData, config, opts) {
  124 +
  125 + var dataChartAreaWidth = opts.width - config.padding - chartData.xAxisPoints[0];
  126 + var dataChartWidth = chartData.eachSpacing * opts.categories.length;
  127 + var validDistance = distance;
  128 + if (distance >= 0) {
  129 + validDistance = 0;
  130 + } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
  131 + validDistance = dataChartAreaWidth - dataChartWidth;
  132 + }
  133 + return validDistance;
  134 +}
  135 +
  136 +function isInAngleRange(angle, startAngle, endAngle) {
  137 + function adjust(angle) {
  138 + while (angle < 0) {
  139 + angle += 2 * Math.PI;
  140 + }
  141 + while (angle > 2 * Math.PI) {
  142 + angle -= 2 * Math.PI;
  143 + }
  144 +
  145 + return angle;
  146 + }
  147 +
  148 + angle = adjust(angle);
  149 + startAngle = adjust(startAngle);
  150 + endAngle = adjust(endAngle);
  151 + if (startAngle > endAngle) {
  152 + endAngle += 2 * Math.PI;
  153 + if (angle < startAngle) {
  154 + angle += 2 * Math.PI;
  155 + }
  156 + }
  157 +
  158 + return angle >= startAngle && angle <= endAngle;
  159 +}
  160 +
  161 +function calRotateTranslate(x, y, h) {
  162 + var xv = x;
  163 + var yv = h - y;
  164 +
  165 + var transX = xv + (h - yv - xv) / Math.sqrt(2);
  166 + transX *= -1;
  167 +
  168 + var transY = (h - yv) * (Math.sqrt(2) - 1) - (h - yv - xv) / Math.sqrt(2);
  169 +
  170 + return {
  171 + transX: transX,
  172 + transY: transY
  173 + };
  174 +}
  175 +
  176 +function createCurveControlPoints(points, i) {
  177 +
  178 + function isNotMiddlePoint(points, i) {
  179 + if (points[i - 1] && points[i + 1]) {
  180 + 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);
  181 + } else {
  182 + return false;
  183 + }
  184 + }
  185 +
  186 + var a = 0.2;
  187 + var b = 0.2;
  188 + var pAx = null;
  189 + var pAy = null;
  190 + var pBx = null;
  191 + var pBy = null;
  192 + if (i < 1) {
  193 + pAx = points[0].x + (points[1].x - points[0].x) * a;
  194 + pAy = points[0].y + (points[1].y - points[0].y) * a;
  195 + } else {
  196 + pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
  197 + pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
  198 + }
  199 +
  200 + if (i > points.length - 3) {
  201 + var last = points.length - 1;
  202 + pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
  203 + pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
  204 + } else {
  205 + pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
  206 + pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
  207 + }
  208 +
  209 + // fix issue https://github.com/xiaolin3303/wx-charts/issues/79
  210 + if (isNotMiddlePoint(points, i + 1)) {
  211 + pBy = points[i + 1].y;
  212 + }
  213 + if (isNotMiddlePoint(points, i)) {
  214 + pAy = points[i].y;
  215 + }
  216 +
  217 + return {
  218 + ctrA: {
  219 + x: pAx,
  220 + y: pAy
  221 + },
  222 + ctrB: {
  223 + x: pBx,
  224 + y: pBy
  225 + }
  226 + };
  227 +}
  228 +
  229 +function convertCoordinateOrigin(x, y, center) {
  230 + return {
  231 + x: center.x + x,
  232 + y: center.y - y
  233 + };
  234 +}
  235 +
  236 +function avoidCollision(obj, target) {
  237 + if (target) {
  238 + // is collision test
  239 + while (util.isCollision(obj, target)) {
  240 + if (obj.start.x > 0) {
  241 + obj.start.y--;
  242 + } else if (obj.start.x < 0) {
  243 + obj.start.y++;
  244 + } else {
  245 + if (obj.start.y > 0) {
  246 + obj.start.y++;
  247 + } else {
  248 + obj.start.y--;
  249 + }
  250 + }
  251 + }
  252 + }
  253 + return obj;
  254 +}
  255 +
  256 +function fillSeriesColor(series, config) {
  257 + var index = 0;
  258 + return series.map(function(item) {
  259 + if (!item.color) {
  260 + item.color = config.colors[index];
  261 + index = (index + 1) % config.colors.length;
  262 + }
  263 + return item;
  264 + });
  265 +}
  266 +
  267 +function getDataRange(minData, maxData) {
  268 + var limit = 0;
  269 + var range = maxData - minData;
  270 + if (range >= 10000) {
  271 + limit = 1000;
  272 + } else if (range >= 1000) {
  273 + limit = 100;
  274 + } else if (range >= 100) {
  275 + limit = 10;
  276 + } else if (range >= 10) {
  277 + limit = 5;
  278 + } else if (range >= 1) {
  279 + limit = 1;
  280 + } else if (range >= 0.1) {
  281 + limit = 0.1;
  282 + } else {
  283 + limit = 0.01;
  284 + }
  285 + return {
  286 + minRange: findRange(minData, 'lower', limit),
  287 + maxRange: findRange(maxData, 'upper', limit)
  288 + };
  289 +}
  290 +
  291 +function measureText(text) {
  292 + var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
  293 +
  294 + // wx canvas 未实现measureText方法, 此处自行实现
  295 + text = String(text);
  296 + var text = text.split('');
  297 + var width = 0;
  298 + text.forEach(function(item) {
  299 + if (/[a-zA-Z]/.test(item)) {
  300 + width += 7;
  301 + } else if (/[0-9]/.test(item)) {
  302 + width += 5.5;
  303 + } else if (/\./.test(item)) {
  304 + width += 2.7;
  305 + } else if (/-/.test(item)) {
  306 + width += 3.25;
  307 + } else if (/[\u4e00-\u9fa5]/.test(item)) {
  308 + width += 10;
  309 + } else if (/\(|\)/.test(item)) {
  310 + width += 3.73;
  311 + } else if (/\s/.test(item)) {
  312 + width += 2.5;
  313 + } else if (/%/.test(item)) {
  314 + width += 8;
  315 + } else {
  316 + width += 10;
  317 + }
  318 + });
  319 + return width * fontSize / 10;
  320 +}
  321 +
  322 +function dataCombine(series) {
  323 + return series.reduce(function(a, b) {
  324 + return (a.data ? a.data : a).concat(b.data);
  325 + }, []);
  326 +}
  327 +
  328 +function getSeriesDataItem(series, index) {
  329 + var data = [];
  330 + series.forEach(function(item) {
  331 + if (item.data[index] !== null && typeof item.data[index] !== 'undefinded') {
  332 + var seriesItem = {};
  333 + seriesItem.color = item.color;
  334 + seriesItem.name = item.name;
  335 + seriesItem.data = item.format ? item.format(item.data[index]) : item.data[index];
  336 + data.push(seriesItem);
  337 + }
  338 + });
  339 +
  340 + return data;
  341 +}
  342 +
  343 +
  344 +
  345 +function getMaxTextListLength(list) {
  346 + var lengthList = list.map(function(item) {
  347 + return measureText(item);
  348 + });
  349 + return Math.max.apply(null, lengthList);
  350 +}
  351 +
  352 +function getToolTipData(seriesData, calPoints, index, categories) {
  353 + var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
  354 +
  355 + var textList = seriesData.map(function(item) {
  356 + return {
  357 + text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data,
  358 + color: item.color
  359 + };
  360 + });
  361 + var validCalPoints = [];
  362 + var offset = {
  363 + x: 0,
  364 + y: 0
  365 + };
  366 + calPoints.forEach(function(points) {
  367 + if (typeof points[index] !== 'undefinded' && points[index] !== null) {
  368 + validCalPoints.push(points[index]);
  369 + }
  370 + });
  371 + validCalPoints.forEach(function(item) {
  372 + offset.x = Math.round(item.x);
  373 + offset.y += item.y;
  374 + });
  375 +
  376 + offset.y /= validCalPoints.length;
  377 + return {
  378 + textList: textList,
  379 + offset: offset
  380 + };
  381 +}
  382 +
  383 +function findCurrentIndex(currentPoints, xAxisPoints, opts, config) {
  384 + var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
  385 +
  386 + var currentIndex = -1;
  387 + if (isInExactChartArea(currentPoints, opts, config)) {
  388 + xAxisPoints.forEach(function(item, index) {
  389 + if (currentPoints.x + offset > item) {
  390 + currentIndex = index;
  391 + }
  392 + });
  393 + }
  394 +
  395 + return currentIndex;
  396 +}
  397 +
  398 +function isInExactChartArea(currentPoints, opts, config) {
  399 + 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;
  400 +}
  401 +
  402 +function findPieChartCurrentIndex(currentPoints, pieData) {
  403 + var currentIndex = -1;
  404 + if (isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
  405 + var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
  406 + angle = -angle;
  407 + for (var i = 0, len = pieData.series.length; i < len; i++) {
  408 + var item = pieData.series[i];
  409 + if (isInAngleRange(angle, item._start_, item._start_ + item._proportion_ * 2 * Math.PI)) {
  410 + currentIndex = i;
  411 + break;
  412 + }
  413 + }
  414 + }
  415 +
  416 + return currentIndex;
  417 +}
  418 +
  419 +function isInExactPieChartArea(currentPoints, center, radius) {
  420 + return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
  421 +}
  422 +
  423 +function splitPoints(points) {
  424 + var newPoints = [];
  425 + var items = [];
  426 + points.forEach(function(item, index) {
  427 + if (item !== null) {
  428 + items.push(item);
  429 + } else {
  430 + if (items.length) {
  431 + newPoints.push(items);
  432 + }
  433 + items = [];
  434 + }
  435 + });
  436 + if (items.length) {
  437 + newPoints.push(items);
  438 + }
  439 +
  440 + return newPoints;
  441 +}
  442 +
  443 +function calLegendData(series, opts, config) {
  444 + if (opts.legend === false) {
  445 + return {
  446 + legendList: [],
  447 + legendHeight: 0
  448 + };
  449 + }
  450 + var padding = 5;
  451 + var marginTop = 8;
  452 + var shapeWidth = 15;
  453 + var legendList = [];
  454 + var widthCount = 0;
  455 + var currentRow = [];
  456 + series.forEach(function(item) {
  457 + var itemWidth = 3 * padding + shapeWidth + measureText(item.name || 'undefinded');
  458 + if (widthCount + itemWidth > opts.width) {
  459 + legendList.push(currentRow);
  460 + widthCount = itemWidth;
  461 + currentRow = [item];
  462 + } else {
  463 + widthCount += itemWidth;
  464 + currentRow.push(item);
  465 + }
  466 + });
  467 + if (currentRow.length) {
  468 + legendList.push(currentRow);
  469 + }
  470 +
  471 + return {
  472 + legendList: legendList,
  473 + legendHeight: legendList.length * (config.fontSize + marginTop) + padding
  474 + };
  475 +}
  476 +
  477 +function calCategoriesData(categories, opts, config) {
  478 + var result = {
  479 + angle: 0,
  480 + xAxisHeight: config.xAxisHeight
  481 + };
  482 +
  483 + var _getXAxisPoints = getXAxisPoints(categories, opts, config),
  484 + eachSpacing = _getXAxisPoints.eachSpacing;
  485 +
  486 + // get max length of categories text
  487 +
  488 +
  489 + var categoriesTextLenth = categories.map(function(item) {
  490 + return measureText(item);
  491 + });
  492 +
  493 + var maxTextLength = Math.max.apply(this, categoriesTextLenth);
  494 +
  495 + if (maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) {
  496 + result.angle = 45 * Math.PI / 180;
  497 + result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle);
  498 + }
  499 +
  500 + return result;
  501 +}
  502 +
  503 +function getPieDataPoints(series) {
  504 + var process = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  505 +
  506 + var count = 0;
  507 + var _start_ = 0;
  508 + series.forEach(function(item) {
  509 + item.data = item.data === null ? 0 : item.data;
  510 + count += item.data;
  511 + });
  512 + series.forEach(function(item) {
  513 + item.data = item.data === null ? 0 : item.data;
  514 + item._proportion_ = item.data / count * process;
  515 + });
  516 + series.forEach(function(item) {
  517 + item._start_ = _start_;
  518 + _start_ += 2 * item._proportion_ * Math.PI;
  519 + });
  520 +
  521 + return series;
  522 +}
  523 +
  524 +function getPieTextMaxLength(series) {
  525 + series = getPieDataPoints(series);
  526 + var maxLength = 0;
  527 + series.forEach(function(item) {
  528 + var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
  529 + maxLength = Math.max(maxLength, measureText(text));
  530 + });
  531 +
  532 + return maxLength;
  533 +}
  534 +
  535 +function fixColumeData(points, eachSpacing, columnLen, index, config, opts) {
  536 + return points.map(function(item) {
  537 + if (item === null) {
  538 + return null;
  539 + }
  540 + item.width = (eachSpacing - 2 * config.columePadding) / columnLen;
  541 +
  542 + if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
  543 + // customer column width
  544 + item.width = Math.min(item.width, +opts.extra.column.width);
  545 + } else {
  546 + // default width should less tran 25px
  547 + // don't ask me why, I don't know
  548 + item.width = Math.min(item.width, 25);
  549 + }
  550 + item.x += (index + 0.5 - columnLen / 2) * item.width;
  551 +
  552 + return item;
  553 + });
  554 +}
  555 +
  556 +function getXAxisPoints(categories, opts, config) {
  557 + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;
  558 + var spacingValid = opts.width - 2 * config.padding - yAxisTotalWidth;
  559 + var dataCount = opts.enableScroll ? Math.min(5, categories.length) : categories.length;
  560 + var eachSpacing = spacingValid / dataCount;
  561 +
  562 + var xAxisPoints = [];
  563 + var startX = config.padding + yAxisTotalWidth;
  564 + var endX = opts.width - config.padding;
  565 + categories.forEach(function(item, index) {
  566 + xAxisPoints.push(startX + index * eachSpacing);
  567 + });
  568 + if (opts.enableScroll === true) {
  569 + xAxisPoints.push(startX + categories.length * eachSpacing);
  570 + } else {
  571 + xAxisPoints.push(endX);
  572 + }
  573 +
  574 + return {
  575 + xAxisPoints: xAxisPoints,
  576 + startX: startX,
  577 + endX: endX,
  578 + eachSpacing: eachSpacing
  579 + };
  580 +}
  581 +
  582 +function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
  583 + var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
  584 +
  585 + var points = [];
  586 + var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
  587 + data.forEach(function(item, index) {
  588 + if (item === null) {
  589 + points.push(null);
  590 + } else {
  591 + var point = {};
  592 + point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
  593 + var height = validHeight * (item - minRange) / (maxRange - minRange);
  594 + height *= process;
  595 + point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding;
  596 + points.push(point);
  597 + }
  598 + });
  599 +
  600 + return points;
  601 +}
  602 +
  603 +function getYAxisTextList(series, opts, config) {
  604 + var data = dataCombine(series);
  605 + // remove null from data
  606 + data = data.filter(function(item) {
  607 + return item !== null;
  608 + });
  609 + var minData = Math.min.apply(this, data);
  610 + var maxData = Math.max.apply(this, data);
  611 + if (typeof opts.yAxis.min === 'number') {
  612 + minData = Math.min(opts.yAxis.min, minData);
  613 + }
  614 + if (typeof opts.yAxis.max === 'number') {
  615 + maxData = Math.max(opts.yAxis.max, maxData);
  616 + }
  617 +
  618 + // fix issue https://github.com/xiaolin3303/wx-charts/issues/9
  619 + if (minData === maxData) {
  620 + var rangeSpan = maxData || 1;
  621 + minData -= rangeSpan;
  622 + maxData += rangeSpan;
  623 + }
  624 +
  625 + var dataRange = getDataRange(minData, maxData);
  626 + var minRange = dataRange.minRange;
  627 + var maxRange = dataRange.maxRange;
  628 +
  629 + var range = [];
  630 + var eachRange = (maxRange - minRange) / config.yAxisSplit;
  631 +
  632 + for (var i = 0; i <= config.yAxisSplit; i++) {
  633 + range.push(minRange + eachRange * i);
  634 + }
  635 + return range.reverse();
  636 +}
  637 +
  638 +function calYAxisData(series, opts, config) {
  639 +
  640 + var ranges = getYAxisTextList(series, opts, config);
  641 + var yAxisWidth = config.yAxisWidth;
  642 + var rangesFormat = ranges.map(function(item) {
  643 + item = util.toFixed(item, 2);
  644 + item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item;
  645 + yAxisWidth = Math.max(yAxisWidth, measureText(item) + 5);
  646 + return item;
  647 + });
  648 + if (opts.yAxis.disabled === true) {
  649 + yAxisWidth = 0;
  650 + }
  651 +
  652 + return {
  653 + rangesFormat: rangesFormat,
  654 + ranges: ranges,
  655 + yAxisWidth: yAxisWidth
  656 + };
  657 +}
  658 +
  659 +function drawPointShape(points, color, shape, context) {
  660 + context.beginPath();
  661 + context.setStrokeStyle("#ffffff");
  662 + context.setLineWidth(1);
  663 + context.setFillStyle(color);
  664 +
  665 + if (shape === 'diamond') {
  666 + points.forEach(function(item, index) {
  667 + if (item !== null) {
  668 + context.moveTo(item.x, item.y - 4.5);
  669 + context.lineTo(item.x - 4.5, item.y);
  670 + context.lineTo(item.x, item.y + 4.5);
  671 + context.lineTo(item.x + 4.5, item.y);
  672 + context.lineTo(item.x, item.y - 4.5);
  673 + }
  674 + });
  675 + } else if (shape === 'circle') {
  676 + points.forEach(function(item, index) {
  677 + if (item !== null) {
  678 + context.moveTo(item.x + 3.5, item.y);
  679 + context.arc(item.x, item.y, 4, 0, 2 * Math.PI, false);
  680 + }
  681 + });
  682 + } else if (shape === 'rect') {
  683 + points.forEach(function(item, index) {
  684 + if (item !== null) {
  685 + context.moveTo(item.x - 3.5, item.y - 3.5);
  686 + context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
  687 + }
  688 + });
  689 + } else if (shape === 'triangle') {
  690 + points.forEach(function(item, index) {
  691 + if (item !== null) {
  692 + context.moveTo(item.x, item.y - 4.5);
  693 + context.lineTo(item.x - 4.5, item.y + 4.5);
  694 + context.lineTo(item.x + 4.5, item.y + 4.5);
  695 + context.lineTo(item.x, item.y - 4.5);
  696 + }
  697 + });
  698 + }
  699 + context.closePath();
  700 + context.fill();
  701 + context.stroke();
  702 +}
  703 +
  704 +
  705 +function drawPointText(points, series, config, context) {
  706 + // 绘制数据文案
  707 + var data = series.data;
  708 +
  709 + context.beginPath();
  710 + context.setFontSize(config.fontSize);
  711 + context.setFillStyle('#666666');
  712 + points.forEach(function(item, index) {
  713 + if (item !== null) {
  714 + var formatVal = series.format ? series.format(data[index]) : data[index];
  715 + context.fillText(formatVal, item.x - measureText(formatVal) / 2, item.y - 2);
  716 + }
  717 + });
  718 + context.closePath();
  719 + context.stroke();
  720 +}
  721 +
  722 +function drawPieText(series, opts, config, context, radius, center) {
  723 + var lineRadius = radius + config.pieChartLinePadding;
  724 + var textObjectCollection = [];
  725 + var lastTextObject = null;
  726 +
  727 + var seriesConvert = series.map(function(item) {
  728 + var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
  729 + // var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
  730 + var text = item.data.toFixed(2);
  731 + var color = item.color;
  732 + return {
  733 + arc: arc,
  734 + text: text ,
  735 + color: color
  736 + };
  737 + });
  738 + seriesConvert.forEach(function(item) {
  739 + // line end
  740 + var orginX1 = Math.cos(item.arc) * lineRadius;
  741 + var orginY1 = Math.sin(item.arc) * lineRadius;
  742 +
  743 + // line start
  744 + var orginX2 = Math.cos(item.arc) * radius;
  745 + var orginY2 = Math.sin(item.arc) * radius;
  746 +
  747 + // text start
  748 + var orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
  749 + var orginY3 = orginY1;
  750 +
  751 + var textWidth = measureText(item.text);
  752 + var startY = orginY3;
  753 +
  754 + if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, {
  755 + x: orginX3
  756 + })) {
  757 + if (orginX3 > 0) {
  758 + startY = Math.min(orginY3, lastTextObject.start.y);
  759 + } else if (orginX1 < 0) {
  760 + startY = Math.max(orginY3, lastTextObject.start.y);
  761 + } else {
  762 + if (orginY3 > 0) {
  763 + startY = Math.max(orginY3, lastTextObject.start.y);
  764 + } else {
  765 + startY = Math.min(orginY3, lastTextObject.start.y);
  766 + }
  767 + }
  768 + }
  769 +
  770 + if (orginX3 < 0) {
  771 + orginX3 -= textWidth;
  772 + }
  773 +
  774 + var textObject = {
  775 + lineStart: {
  776 + x: orginX2,
  777 + y: orginY2
  778 + },
  779 + lineEnd: {
  780 + x: orginX1,
  781 + y: orginY1
  782 + },
  783 + start: {
  784 + x: orginX3,
  785 + y: startY
  786 + },
  787 + width: textWidth,
  788 + height: config.fontSize,
  789 + text: item.text,
  790 + color: item.color
  791 + };
  792 +
  793 + lastTextObject = avoidCollision(textObject, lastTextObject);
  794 + textObjectCollection.push(lastTextObject);
  795 + });
  796 +
  797 + textObjectCollection.forEach(function(item) {
  798 + var lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
  799 + var lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
  800 + var textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
  801 + context.setLineWidth(1);
  802 + context.setFontSize(config.fontSize);
  803 + context.beginPath();
  804 + context.setStrokeStyle(item.color);
  805 + context.setFillStyle(item.color);
  806 + context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
  807 + var curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
  808 + var textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
  809 + context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
  810 + context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
  811 + context.stroke();
  812 + context.closePath();
  813 + context.beginPath();
  814 + context.moveTo(textPosition.x + item.width, textPosition.y);
  815 + context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI);
  816 + context.closePath();
  817 + context.fill();
  818 + context.beginPath();
  819 + context.setFillStyle('#666666');
  820 + context.fillText(item.text, textStartX, textPosition.y + 3);
  821 + context.closePath();
  822 + context.stroke();
  823 +
  824 + context.closePath();
  825 + });
  826 +}
  827 +
  828 +function drawToolTipSplitLine(offsetX, opts, config, context) {
  829 + var startY = config.padding;
  830 + var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
  831 + context.beginPath();
  832 + context.setStrokeStyle('#cccccc');
  833 + context.setLineWidth(1);
  834 + context.moveTo(offsetX, startY);
  835 + context.lineTo(offsetX, endY);
  836 + context.stroke();
  837 + context.closePath();
  838 +}
  839 +
  840 +function drawToolTip(textList, offset, opts, config, context) {
  841 + var legendWidth = 4;
  842 + var legendMarginRight = 5;
  843 + var arrowWidth = 8;
  844 + var isOverRightBorder = false;
  845 + offset = assign({
  846 + x: 0,
  847 + y: 0
  848 + }, offset);
  849 + offset.y -= 8;
  850 + var textWidth = textList.map(function(item) {
  851 + return measureText(item.text);
  852 + });
  853 +
  854 + var toolTipWidth = legendWidth + legendMarginRight + 4 * config.toolTipPadding + Math.max.apply(null, textWidth);
  855 + var toolTipHeight = 2 * config.toolTipPadding + textList.length * config.toolTipLineHeight;
  856 +
  857 + // if beyond the right border
  858 + if (offset.x - Math.abs(opts._scrollDistance_) + arrowWidth + toolTipWidth > opts.width) {
  859 + isOverRightBorder = true;
  860 + }
  861 +
  862 + // draw background rect
  863 + context.beginPath();
  864 + context.setFillStyle(opts.tooltip.option.background || config.toolTipBackground);
  865 + context.setGlobalAlpha(config.toolTipOpacity);
  866 + if (isOverRightBorder) {
  867 + context.moveTo(offset.x, offset.y + 10);
  868 + context.lineTo(offset.x - arrowWidth, offset.y + 10 - 5);
  869 + context.lineTo(offset.x - arrowWidth, offset.y + 10 + 5);
  870 + context.moveTo(offset.x, offset.y + 10);
  871 + context.fillRect(offset.x - toolTipWidth - arrowWidth, offset.y, toolTipWidth, toolTipHeight);
  872 + } else {
  873 + context.moveTo(offset.x, offset.y + 10);
  874 + context.lineTo(offset.x + arrowWidth, offset.y + 10 - 5);
  875 + context.lineTo(offset.x + arrowWidth, offset.y + 10 + 5);
  876 + context.moveTo(offset.x, offset.y + 10);
  877 + context.fillRect(offset.x + arrowWidth, offset.y, toolTipWidth, toolTipHeight);
  878 + }
  879 +
  880 + context.closePath();
  881 + context.fill();
  882 + context.setGlobalAlpha(1);
  883 +
  884 + // draw legend
  885 + textList.forEach(function(item, index) {
  886 + context.beginPath();
  887 + context.setFillStyle(item.color);
  888 + var startX = offset.x + arrowWidth + 2 * config.toolTipPadding;
  889 + var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding;
  890 + if (isOverRightBorder) {
  891 + startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding;
  892 + }
  893 + context.fillRect(startX, startY, legendWidth, config.fontSize);
  894 + context.closePath();
  895 + });
  896 +
  897 + // draw text list
  898 + context.beginPath();
  899 + context.setFontSize(config.fontSize);
  900 + context.setFillStyle('#ffffff');
  901 + textList.forEach(function(item, index) {
  902 + var startX = offset.x + arrowWidth + 2 * config.toolTipPadding + legendWidth + legendMarginRight;
  903 + if (isOverRightBorder) {
  904 + startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding + +legendWidth + legendMarginRight;
  905 + }
  906 + var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding;
  907 + context.fillText(item.text, startX, startY + config.fontSize);
  908 + });
  909 + context.stroke();
  910 + context.closePath();
  911 +}
  912 +
  913 +function drawYAxisTitle(title, opts, config, context) {
  914 + var startX = config.xAxisHeight + (opts.height - config.xAxisHeight - measureText(title)) / 2;
  915 + context.save();
  916 + context.beginPath();
  917 + context.setFontSize(config.fontSize);
  918 + context.setFillStyle(opts.yAxis.titleFontColor || '#333333');
  919 + context.translate(0, opts.height);
  920 + context.rotate(-90 * Math.PI / 180);
  921 + context.fillText(title, startX, config.padding + 0.5 * config.fontSize);
  922 + context.stroke();
  923 + context.closePath();
  924 + context.restore();
  925 +}
  926 +
  927 +function drawToolTipBridge(opts, config, context, process) {
  928 + context.save();
  929 + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
  930 + context.translate(opts._scrollDistance_, 0);
  931 + }
  932 + if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
  933 + drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context);
  934 + }
  935 + context.restore();
  936 +}
  937 +
  938 +function drawXAxis(categories, opts, config, context) {
  939 + var _getXAxisPoints4 = getXAxisPoints(categories, opts, config),
  940 + xAxisPoints = _getXAxisPoints4.xAxisPoints,
  941 + startX = _getXAxisPoints4.startX,
  942 + endX = _getXAxisPoints4.endX,
  943 + eachSpacing = _getXAxisPoints4.eachSpacing;
  944 +
  945 + var startY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
  946 + var endY = startY + config.xAxisLineHeight;
  947 +
  948 + context.save();
  949 + if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
  950 + context.translate(opts._scrollDistance_, 0);
  951 + }
  952 +
  953 + context.beginPath();
  954 + context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
  955 +
  956 + if (opts.xAxis.disableGrid !== true) {
  957 + if (opts.xAxis.type === 'calibration') {
  958 + xAxisPoints.forEach(function(item, index) {
  959 + if (index > 0) {
  960 + context.moveTo(item - eachSpacing / 2, startY);
  961 + context.lineTo(item - eachSpacing / 2, startY + 4);
  962 + }
  963 + });
  964 + } else {
  965 + xAxisPoints.forEach(function(item, index) {
  966 + context.moveTo(item, startY);
  967 + context.lineTo(item, endY);
  968 + });
  969 + }
  970 + }
  971 + context.closePath();
  972 + context.stroke();
  973 +
  974 + // 对X轴列表做抽稀处理
  975 + var validWidth = opts.width - 2 * config.padding - config.yAxisWidth - config.yAxisTitleWidth;
  976 + var maxXAxisListLength = Math.min(categories.length, Math.ceil(validWidth / config.fontSize / 1.5));
  977 + var ratio = Math.ceil(categories.length / maxXAxisListLength);
  978 +
  979 + categories = categories.map(function(item, index) {
  980 + return index % ratio !== 0 ? '' : item;
  981 + });
  982 +
  983 + if (config._xAxisTextAngle_ === 0) {
  984 + context.beginPath();
  985 + context.setFontSize(config.fontSize);
  986 + context.setFillStyle(opts.xAxis.fontColor || '#666666');
  987 + categories.forEach(function(item, index) {
  988 + var offset = eachSpacing / 2 - measureText(item) / 2;
  989 + context.fillText(item, xAxisPoints[index] + offset, startY + config.fontSize + 5);
  990 + });
  991 + context.closePath();
  992 + context.stroke();
  993 + } else {
  994 + categories.forEach(function(item, index) {
  995 + context.save();
  996 + context.beginPath();
  997 + context.setFontSize(config.fontSize);
  998 + context.setFillStyle(opts.xAxis.fontColor || '#666666');
  999 + var textWidth = measureText(item);
  1000 + var offset = eachSpacing / 2 - textWidth;
  1001 +
  1002 + var _calRotateTranslate = calRotateTranslate(xAxisPoints[index] + eachSpacing / 2, startY + config.fontSize / 2 + 5, opts.height),
  1003 + transX = _calRotateTranslate.transX,
  1004 + transY = _calRotateTranslate.transY;
  1005 +
  1006 + context.rotate(-1 * config._xAxisTextAngle_);
  1007 + context.translate(transX, transY);
  1008 + context.fillText(item, xAxisPoints[index] + offset, startY + config.fontSize + 5);
  1009 + context.closePath();
  1010 + context.stroke();
  1011 + context.restore();
  1012 + });
  1013 + }
  1014 +
  1015 + context.restore();
  1016 +}
  1017 +
  1018 +function drawYAxisGrid(opts, config, context) {
  1019 + var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
  1020 + var eachSpacing = Math.floor(spacingValid / config.yAxisSplit);
  1021 + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;
  1022 + var startX = config.padding + yAxisTotalWidth;
  1023 + var endX = opts.width - config.padding;
  1024 +
  1025 + var points = [];
  1026 + for (var i = 0; i < config.yAxisSplit; i++) {
  1027 + points.push(config.padding + eachSpacing * i);
  1028 + }
  1029 + points.push(config.padding + eachSpacing * config.yAxisSplit + 2);
  1030 +
  1031 + context.beginPath();
  1032 + context.setStrokeStyle(opts.yAxis.gridColor || "#cccccc");
  1033 + context.setLineWidth(1);
  1034 + points.forEach(function(item, index) {
  1035 + context.moveTo(startX, item);
  1036 + context.lineTo(endX, item);
  1037 + });
  1038 + context.closePath();
  1039 + context.stroke();
  1040 +}
  1041 +
  1042 +function drawYAxis(series, opts, config, context) {
  1043 + if (opts.yAxis.disabled === true) {
  1044 + return;
  1045 + }
  1046 +
  1047 + var _calYAxisData4 = calYAxisData(series, opts, config),
  1048 + rangesFormat = _calYAxisData4.rangesFormat;
  1049 +
  1050 + var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;
  1051 +
  1052 + var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
  1053 + var eachSpacing = Math.floor(spacingValid / config.yAxisSplit);
  1054 + var startX = config.padding + yAxisTotalWidth;
  1055 + var endX = opts.width - config.padding;
  1056 + var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
  1057 +
  1058 + // set YAxis background
  1059 + context.setFillStyle(opts.background || '#ffffff');
  1060 + if (opts._scrollDistance_ < 0) {
  1061 + context.fillRect(0, 0, startX, endY + config.xAxisHeight + 5);
  1062 + }
  1063 + context.fillRect(endX, 0, opts.width, endY + config.xAxisHeight + 5);
  1064 +
  1065 + var points = [];
  1066 + for (var i = 0; i <= config.yAxisSplit; i++) {
  1067 + points.push(config.padding + eachSpacing * i);
  1068 + }
  1069 +
  1070 + context.stroke();
  1071 + context.beginPath();
  1072 + context.setFontSize(config.fontSize);
  1073 + context.setFillStyle(opts.yAxis.fontColor || '#666666');
  1074 + rangesFormat.forEach(function(item, index) {
  1075 + var pos = points[index] ? points[index] : endY;
  1076 + context.fillText(item, config.padding + config.yAxisTitleWidth, pos + config.fontSize / 2);
  1077 + });
  1078 + context.closePath();
  1079 + context.stroke();
  1080 +
  1081 + if (opts.yAxis.title) {
  1082 + drawYAxisTitle(opts.yAxis.title, opts, config, context);
  1083 + }
  1084 +}
  1085 +
  1086 +function drawLegend(series, opts, config, context) {
  1087 + if (!opts.legend) {
  1088 + return;
  1089 + }
  1090 + // each legend shape width 15px
  1091 + // the spacing between shape and text in each legend is the `padding`
  1092 + // each legend spacing is the `padding`
  1093 + // legend margin top `config.padding`
  1094 +
  1095 + var _calLegendData = calLegendData(series, opts, config),
  1096 + legendList = _calLegendData.legendList;
  1097 +
  1098 + var padding = 5;
  1099 + var marginTop = 8;
  1100 + var shapeWidth = 15;
  1101 + legendList.forEach(function(itemList, listIndex) {
  1102 + var width = 0;
  1103 + itemList.forEach(function(item) {
  1104 + item.name = item.name || 'undefined';
  1105 + width += 3 * padding + measureText(item.name) + shapeWidth;
  1106 + });
  1107 + var startX = (opts.width - width) / 2 + padding;
  1108 + var startY = opts.height - config.padding - config.legendHeight + listIndex * (config.fontSize + marginTop) + padding + marginTop;
  1109 +
  1110 + context.setFontSize(config.fontSize);
  1111 + itemList.forEach(function(item) {
  1112 + switch (opts.type) {
  1113 + case 'line':
  1114 + context.beginPath();
  1115 + context.setLineWidth(1);
  1116 + context.setStrokeStyle(item.color);
  1117 + context.moveTo(startX - 2, startY + 5);
  1118 + context.lineTo(startX + 17, startY + 5);
  1119 + context.stroke();
  1120 + context.closePath();
  1121 + context.beginPath();
  1122 + context.setLineWidth(1);
  1123 + context.setStrokeStyle('#ffffff');
  1124 + context.setFillStyle(item.color);
  1125 + context.moveTo(startX + 7.5, startY + 5);
  1126 + context.arc(startX + 7.5, startY + 5, 4, 0, 2 * Math.PI);
  1127 + context.fill();
  1128 + context.stroke();
  1129 + context.closePath();
  1130 + break;
  1131 + case 'pie':
  1132 + case 'ring':
  1133 + context.beginPath();
  1134 + context.setFillStyle(item.color);
  1135 + context.moveTo(startX + 7.5, startY + 5);
  1136 + context.arc(startX + 7.5, startY + 5, 8, 0, 2 * Math.PI);
  1137 + context.closePath();
  1138 + context.fill();
  1139 + break;
  1140 + default:
  1141 + context.beginPath();
  1142 + context.setFillStyle(item.color);
  1143 + context.moveTo(startX, startY);
  1144 + context.rect(startX, startY, 15, 10);
  1145 + context.closePath();
  1146 + context.fill();
  1147 + }
  1148 + startX += padding + shapeWidth;
  1149 + context.beginPath();
  1150 + context.setFillStyle(opts.extra.legendTextColor || '#333333');
  1151 + context.fillText(item.name, startX, startY + 9);
  1152 + context.closePath();
  1153 + context.stroke();
  1154 + startX += measureText(item.name) + 2 * padding;
  1155 + });
  1156 + });
  1157 +}
  1158 +
  1159 +function drawPieDataPoints(series, opts, config, context) {
  1160 + var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
  1161 +
  1162 + var pieOption = opts.extra.pie || {};
  1163 + series = getPieDataPoints(series, process);
  1164 + var centerPosition = {
  1165 + x: opts.width / 2,
  1166 + y: (opts.height - config.legendHeight) / 2
  1167 + };
  1168 + var radius = Math.min(centerPosition.x - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, centerPosition.y - config.pieChartLinePadding - config.pieChartTextPadding);
  1169 + if (opts.dataLabel) {
  1170 + radius -= 10;
  1171 + } else {
  1172 + radius -= 2 * config.padding;
  1173 + }
  1174 + series = series.map(function(eachSeries) {
  1175 + eachSeries._start_ += (pieOption.offsetAngle || 0) * Math.PI / 180;
  1176 + return eachSeries;
  1177 + });
  1178 + series.forEach(function(eachSeries) {
  1179 + context.beginPath();
  1180 + context.setLineWidth(2);
  1181 + context.setStrokeStyle('#ffffff');
  1182 + context.setFillStyle(eachSeries.color);
  1183 + context.moveTo(centerPosition.x, centerPosition.y);
  1184 + context.arc(centerPosition.x, centerPosition.y, radius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
  1185 + context.closePath();
  1186 + context.fill();
  1187 + if (opts.disablePieStroke !== true) {
  1188 + context.stroke();
  1189 + }
  1190 + });
  1191 +
  1192 + if (opts.type === 'ring') {
  1193 + var innerPieWidth = radius * 0.6;
  1194 + if (typeof opts.extra.ringWidth === 'number' && opts.extra.ringWidth > 0) {
  1195 + innerPieWidth = Math.max(0, radius - opts.extra.ringWidth);
  1196 + }
  1197 + context.beginPath();
  1198 + context.setFillStyle(opts.background || '#ffffff');
  1199 + context.moveTo(centerPosition.x, centerPosition.y);
  1200 + context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI);
  1201 + context.closePath();
  1202 + context.fill();
  1203 + }
  1204 +
  1205 + if (opts.dataLabel !== false && process === 1) {
  1206 + // fix https://github.com/xiaolin3303/wx-charts/issues/132
  1207 + var valid = false;
  1208 + for (var i = 0, len = series.length; i < len; i++) {
  1209 + if (series[i].data > 0) {
  1210 + valid = true;
  1211 + break;
  1212 + }
  1213 + }
  1214 +
  1215 + if (valid) {
  1216 + drawPieText(series, opts, config, context, radius, centerPosition);
  1217 + }
  1218 + }
  1219 +
  1220 + if (process === 1 && opts.type === 'ring') {
  1221 + drawRingTitle(opts, config, context);
  1222 + }
  1223 +
  1224 + return {
  1225 + center: centerPosition,
  1226 + radius: radius,
  1227 + series: series
  1228 + };
  1229 +}
  1230 +
  1231 +function drawCanvas(opts, context) {
  1232 + context.draw();
  1233 +}
  1234 +
  1235 +var Timing = {
  1236 + easeIn: function easeIn(pos) {
  1237 + return Math.pow(pos, 3);
  1238 + },
  1239 +
  1240 + easeOut: function easeOut(pos) {
  1241 + return Math.pow(pos - 1, 3) + 1;
  1242 + },
  1243 +
  1244 + easeInOut: function easeInOut(pos) {
  1245 + if ((pos /= 0.5) < 1) {
  1246 + return 0.5 * Math.pow(pos, 3);
  1247 + } else {
  1248 + return 0.5 * (Math.pow(pos - 2, 3) + 2);
  1249 + }
  1250 + },
  1251 +
  1252 + linear: function linear(pos) {
  1253 + return pos;
  1254 + }
  1255 +};
  1256 +
  1257 +function Animation(opts) {
  1258 + this.isStop = false;
  1259 + opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
  1260 + opts.timing = opts.timing || 'linear';
  1261 +
  1262 + var delay = 17;
  1263 +
  1264 + var createAnimationFrame = function createAnimationFrame() {
  1265 + if (typeof requestAnimationFrame !== 'undefined') {
  1266 + return requestAnimationFrame;
  1267 + } else if (typeof setTimeout !== 'undefined') {
  1268 + return function(step, delay) {
  1269 + setTimeout(function() {
  1270 + var timeStamp = +new Date();
  1271 + step(timeStamp);
  1272 + }, delay);
  1273 + };
  1274 + } else {
  1275 + return function(step) {
  1276 + step(null);
  1277 + };
  1278 + }
  1279 + };
  1280 + var animationFrame = createAnimationFrame();
  1281 + var startTimeStamp = null;
  1282 + var _step = function step(timestamp) {
  1283 + if (timestamp === null || this.isStop === true) {
  1284 + opts.onProcess && opts.onProcess(1);
  1285 + opts.onAnimationFinish && opts.onAnimationFinish();
  1286 + return;
  1287 + }
  1288 + if (startTimeStamp === null) {
  1289 + startTimeStamp = timestamp;
  1290 + }
  1291 + if (timestamp - startTimeStamp < opts.duration) {
  1292 + var process = (timestamp - startTimeStamp) / opts.duration;
  1293 + var timingFunction = Timing[opts.timing];
  1294 + process = timingFunction(process);
  1295 + opts.onProcess && opts.onProcess(process);
  1296 + animationFrame(_step, delay);
  1297 + } else {
  1298 + opts.onProcess && opts.onProcess(1);
  1299 + opts.onAnimationFinish && opts.onAnimationFinish();
  1300 + }
  1301 + };
  1302 + _step = _step.bind(this);
  1303 +
  1304 + animationFrame(_step, delay);
  1305 +}
  1306 +
  1307 +// stop animation immediately
  1308 +// and tigger onAnimationFinish
  1309 +Animation.prototype.stop = function() {
  1310 + this.isStop = true;
  1311 +};
  1312 +
  1313 +function drawCharts(type, opts, config, context) {
  1314 + var _this = this;
  1315 +
  1316 + var series = opts.series;
  1317 + var categories = opts.categories;
  1318 + series = fillSeriesColor(series, config);
  1319 +
  1320 + var _calLegendData = calLegendData(series, opts, config),
  1321 + legendHeight = _calLegendData.legendHeight;
  1322 +
  1323 + config.legendHeight = legendHeight;
  1324 +
  1325 + var _calYAxisData = calYAxisData(series, opts, config),
  1326 + yAxisWidth = _calYAxisData.yAxisWidth;
  1327 +
  1328 + config.yAxisWidth = yAxisWidth;
  1329 + if (categories && categories.length) {
  1330 + var _calCategoriesData = calCategoriesData(categories, opts, config),
  1331 + xAxisHeight = _calCategoriesData.xAxisHeight,
  1332 + angle = _calCategoriesData.angle;
  1333 +
  1334 + config.xAxisHeight = xAxisHeight;
  1335 + config._xAxisTextAngle_ = angle;
  1336 + }
  1337 + if (type === 'pie' || type === 'ring') {
  1338 + config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(series);
  1339 + }
  1340 +
  1341 + var duration = opts.animation ? 1000 : 0;
  1342 + this.animationInstance && this.animationInstance.stop();
  1343 + switch (type) {
  1344 + case 'ring':
  1345 + case 'pie':
  1346 + this.animationInstance = new Animation({
  1347 + timing: 'easeInOut',
  1348 + duration: duration,
  1349 + onProcess: function onProcess(process) {
  1350 + _this.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
  1351 + drawLegend(opts.series, opts, config, context);
  1352 + drawCanvas(opts, context);
  1353 + },
  1354 + onAnimationFinish: function onAnimationFinish() {
  1355 + _this.event.trigger('renderComplete');
  1356 + }
  1357 + });
  1358 + break;
  1359 + case 'radar':
  1360 + // this.animationInstance = new Animation({
  1361 + // timing: 'easeInOut',
  1362 + // duration: duration,
  1363 + // onProcess: function onProcess(process) {
  1364 + // _this.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process);
  1365 + // drawLegend(opts.series, opts, config, context);
  1366 + // drawCanvas(opts, context);
  1367 + // },
  1368 + // onAnimationFinish: function onAnimationFinish() {
  1369 + // _this.event.trigger('renderComplete');
  1370 + // }
  1371 + // });
  1372 + break;
  1373 + }
  1374 +}
  1375 +
  1376 +// simple event implement
  1377 +
  1378 +function Event() {
  1379 + this.events = {};
  1380 +}
  1381 +
  1382 +Event.prototype.addEventListener = function(type, listener) {
  1383 + this.events[type] = this.events[type] || [];
  1384 + this.events[type].push(listener);
  1385 +};
  1386 +
  1387 +Event.prototype.trigger = function() {
  1388 + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  1389 + args[_key] = arguments[_key];
  1390 + }
  1391 +
  1392 + var type = args[0];
  1393 + var params = args.slice(1);
  1394 + if (!!this.events[type]) {
  1395 + this.events[type].forEach(function(listener) {
  1396 + try {
  1397 + listener.apply(null, params);
  1398 + } catch (e) {
  1399 + console.error(e);
  1400 + }
  1401 + });
  1402 + }
  1403 +};
  1404 +
  1405 +var Charts = function Charts(opts) {
  1406 + opts.title = opts.title || {};
  1407 + opts.subtitle = opts.subtitle || {};
  1408 + opts.yAxis = opts.yAxis || {};
  1409 + opts.xAxis = opts.xAxis || {};
  1410 + opts.extra = opts.extra || {};
  1411 + opts.legend = opts.legend === false ? false : true;
  1412 + opts.animation = opts.animation === false ? false : true;
  1413 + var config$$1 = assign({}, config);
  1414 + config$$1.yAxisTitleWidth = opts.yAxis.disabled !== true && opts.yAxis.title ? config$$1.yAxisTitleWidth : 0;
  1415 + config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : config$$1.pieChartLinePadding;
  1416 + config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding;
  1417 +
  1418 + this.opts = opts;
  1419 + this.config = config$$1;
  1420 + this.context = wx.createCanvasContext(opts.canvasId);
  1421 + // store calcuated chart data
  1422 + // such as chart point coordinate
  1423 + this.chartData = {};
  1424 + this.event = new Event();
  1425 + this.scrollOption = {
  1426 + currentOffset: 0,
  1427 + startTouchX: 0,
  1428 + distance: 0
  1429 + };
  1430 +
  1431 + drawCharts.call(this, opts.type, opts, config$$1, this.context);
  1432 +};
  1433 +
  1434 +Charts.prototype.updateData = function() {
  1435 + var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1436 +
  1437 + this.opts.series = data.series || this.opts.series;
  1438 + this.opts.categories = data.categories || this.opts.categories;
  1439 +
  1440 + this.opts.title = assign({}, this.opts.title, data.title || {});
  1441 + this.opts.subtitle = assign({}, this.opts.subtitle, data.subtitle || {});
  1442 +
  1443 + drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
  1444 +};
  1445 +
  1446 +Charts.prototype.stopAnimation = function() {
  1447 + this.animationInstance && this.animationInstance.stop();
  1448 +};
  1449 +
  1450 +Charts.prototype.addEventListener = function(type, listener) {
  1451 + this.event.addEventListener(type, listener);
  1452 +};
  1453 +
  1454 +Charts.prototype.getCurrentDataIndex = function(e) {
  1455 + var touches = e.touches && e.touches.length ? e.touches : e.changedTouches;
  1456 + if (touches && touches.length) {
  1457 + var _touches$ = touches[0],
  1458 + x = _touches$.x,
  1459 + y = _touches$.y;
  1460 +
  1461 + if (this.opts.type === 'pie' || this.opts.type === 'ring') {
  1462 + return findPieChartCurrentIndex({
  1463 + x: x,
  1464 + y: y
  1465 + }, this.chartData.pieData);
  1466 + } else if (this.opts.type === 'radar') {
  1467 + return findRadarChartCurrentIndex({
  1468 + x: x,
  1469 + y: y
  1470 + }, this.chartData.radarData, this.opts.categories.length);
  1471 + } else {
  1472 + return findCurrentIndex({
  1473 + x: x,
  1474 + y: y
  1475 + }, this.chartData.xAxisPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
  1476 + }
  1477 + }
  1478 + return -1;
  1479 +};
  1480 +
  1481 +Charts.prototype.showToolTip = function(e) {
  1482 + var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1483 +
  1484 + if (this.opts.type === 'line' || this.opts.type === 'area') {
  1485 + var index = this.getCurrentDataIndex(e);
  1486 + var currentOffset = this.scrollOption.currentOffset;
  1487 +
  1488 + var opts = assign({}, this.opts, {
  1489 + _scrollDistance_: currentOffset,
  1490 + animation: false
  1491 + });
  1492 + if (index > -1) {
  1493 + var seriesData = getSeriesDataItem(this.opts.series, index);
  1494 + if (seriesData.length === 0) {
  1495 + drawCharts.call(this, opts.type, opts, this.config, this.context);
  1496 + } else {
  1497 + var _getToolTipData = getToolTipData(seriesData, this.chartData.calPoints, index, this.opts.categories, option),
  1498 + textList = _getToolTipData.textList,
  1499 + offset = _getToolTipData.offset;
  1500 +
  1501 + opts.tooltip = {
  1502 + textList: textList,
  1503 + offset: offset,
  1504 + option: option
  1505 + };
  1506 + drawCharts.call(this, opts.type, opts, this.config, this.context);
  1507 + }
  1508 + } else {
  1509 + drawCharts.call(this, opts.type, opts, this.config, this.context);
  1510 + }
  1511 + }
  1512 +};
  1513 +
  1514 +Charts.prototype.scrollStart = function(e) {
  1515 + if (e.touches[0] && this.opts.enableScroll === true) {
  1516 + this.scrollOption.startTouchX = e.touches[0].x;
  1517 + }
  1518 +};
  1519 +
  1520 +Charts.prototype.scroll = function(e) {
  1521 + // TODO throtting...
  1522 + if (e.touches[0] && this.opts.enableScroll === true) {
  1523 + var _distance = e.touches[0].x - this.scrollOption.startTouchX;
  1524 + var currentOffset = this.scrollOption.currentOffset;
  1525 +
  1526 + var validDistance = calValidDistance(currentOffset + _distance, this.chartData, this.config, this.opts);
  1527 +
  1528 + this.scrollOption.distance = _distance = validDistance - currentOffset;
  1529 + var opts = assign({}, this.opts, {
  1530 + _scrollDistance_: currentOffset + _distance,
  1531 + animation: false
  1532 + });
  1533 +
  1534 + drawCharts.call(this, opts.type, opts, this.config, this.context);
  1535 + }
  1536 +};
  1537 +
  1538 +Charts.prototype.scrollEnd = function(e) {
  1539 + if (this.opts.enableScroll === true) {
  1540 + var _scrollOption = this.scrollOption,
  1541 + currentOffset = _scrollOption.currentOffset,
  1542 + distance = _scrollOption.distance;
  1543 +
  1544 + this.scrollOption.currentOffset = currentOffset + distance;
  1545 + this.scrollOption.distance = 0;
  1546 + }
  1547 +};
  1548 +
  1549 +module.exports = Charts;
注册登录 后发表评论