소스 검색

Signed-off-by: 李妹妹 <1639016684@qq.com>

李妹妹 1 개월 전
부모
커밋
decb472b46
100개의 변경된 파일24618개의 추가작업 그리고 78개의 파일을 삭제
  1. 14 1
      assets/css/common.less
  2. 1 16
      assets/css/commonTheme.css
  3. 3 2
      common/request.js
  4. 495 0
      components/pushangyuqi-calendar/pushangyuqi-calendar.vue
  5. 432 0
      components/ren-calendar/ren-calendar.vue
  6. 487 0
      components/sapling-vue-scale/sapling-vue-scale.vue
  7. 2 3
      main.js
  8. 5 0
      package-lock.json
  9. 256 0
      pages.json
  10. 16 12
      pages/user/index.vue
  11. 420 0
      pages_company/addSchedule.vue
  12. 484 0
      pages_company/clientDetail.vue
  13. 372 0
      pages_company/clientList.vue
  14. 425 0
      pages_company/executionRecord.vue
  15. 302 40
      pages_company/index.vue
  16. 377 0
      pages_company/returnRecord.vue
  17. 346 0
      pages_company/schedule.vue
  18. 429 0
      pages_company/testRecord.vue
  19. 386 0
      pages_company/todoList.vue
  20. 454 0
      pages_echarts/acid.vue
  21. 187 0
      pages_echarts/acidDetail.vue
  22. 405 0
      pages_echarts/acidList.vue
  23. 403 0
      pages_echarts/bloodPressure.vue
  24. 210 0
      pages_echarts/bloodPressureDetail.vue
  25. 405 0
      pages_echarts/bloodPressureList.vue
  26. 427 0
      pages_echarts/bloodSugar.vue
  27. 187 0
      pages_echarts/bloodSugarDetail.vue
  28. 405 0
      pages_echarts/bloodSugarList.vue
  29. 256 0
      pages_echarts/components/dateTimePicker/dateTimePicker.vue
  30. 190 0
      pages_echarts/components/myWeekPicker/myWeekPicker.vue
  31. 70 0
      pages_echarts/components/myWeekPicker/week.js
  32. 511 0
      pages_echarts/components/simpleScale/simpleScale.vue
  33. 378 0
      pages_echarts/hips.vue
  34. 378 0
      pages_echarts/waistLine.vue
  35. 411 0
      pages_health/addCompetitors.vue
  36. 494 0
      pages_health/addDoc.vue
  37. 433 0
      pages_health/addServe.vue
  38. 611 0
      pages_health/addUser.vue
  39. 474 0
      pages_health/buyOrder.vue
  40. 320 0
      pages_health/doc.vue
  41. 46 4
      pages_health/healthfiles.vue
  42. BIN
      static/images/company/add_blue_icon.png
  43. BIN
      static/images/company/add_icon.png
  44. BIN
      static/images/company/address_icon.png
  45. BIN
      static/images/company/appointed_task_icon.png
  46. BIN
      static/images/company/comparison_indicators_icon.png
  47. BIN
      static/images/company/consumables_mall_icon.png
  48. BIN
      static/images/company/customer_complaints_icon.png
  49. BIN
      static/images/company/customer_profile_icon.png
  50. BIN
      static/images/company/deenergize_icon.png
  51. BIN
      static/images/company/edit_add_icon.png
  52. BIN
      static/images/company/evaluation_record_icon.png
  53. BIN
      static/images/company/execution_record_icon.png
  54. BIN
      static/images/company/follow_up_records_icon.png
  55. BIN
      static/images/company/health_records_icon.png
  56. BIN
      static/images/company/list_matters_icon.png
  57. BIN
      static/images/company/make_phone_call_icon.png
  58. BIN
      static/images/company/manager_examine_icon.png
  59. BIN
      static/images/company/my_promotion_icon.png
  60. BIN
      static/images/company/phone_icon.png
  61. BIN
      static/images/company/phone_icon16.png
  62. BIN
      static/images/company/physical_examination_icon.png
  63. BIN
      static/images/company/return_records_icon.png
  64. BIN
      static/images/company/right_arrow_black_icon24.png
  65. BIN
      static/images/company/right_arrow_right_icon.png
  66. BIN
      static/images/company/sales_management_top_bg.png
  67. BIN
      static/images/company/send_SMS_icon.png
  68. BIN
      static/images/company/time_arrow_blue_icon.png
  69. BIN
      static/images/company/time_arrow_down_icon.png
  70. BIN
      static/images/company/time_arrow_icon.png
  71. BIN
      static/images/company/to_do_list_icon.png
  72. BIN
      static/images/company/work_item_icon.png
  73. BIN
      static/images/health/arrow_down.png
  74. BIN
      static/images/health/arrow_time_no_icon.png
  75. BIN
      static/images/health/arrow_time_yes_icon.png
  76. BIN
      static/images/health/blood_pressure_top_bg.png
  77. BIN
      static/images/health/blood_sugar_top_bg.png
  78. BIN
      static/images/health/hip_circumference_tab_switch_bg.png
  79. BIN
      static/images/health/hips_top_bg.png
  80. BIN
      static/images/health/nav_add_icon24.png
  81. BIN
      static/images/health/note_icon.png
  82. BIN
      static/images/health/qw_arrow_icon.png
  83. BIN
      static/images/health/right_arrow_right_icon24.png
  84. BIN
      static/images/health/uric_acid_top_bg.png
  85. BIN
      static/images/health/waist_circumference_top_bg.png
  86. BIN
      static/images/health/yz_arrow_icon.png
  87. BIN
      static/images/health/zc_arrow_icon.png
  88. 320 0
      uni_modules/qiun-data-charts/changelog.md
  89. 1618 0
      uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue
  90. 42 0
      uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue
  91. 162 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue
  92. 170 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue
  93. 173 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue
  94. 222 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue
  95. 229 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue
  96. 36 0
      uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue
  97. 422 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js
  98. 606 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js
  99. 5 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md
  100. 7706 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js

+ 14 - 1
assets/css/common.less

@@ -183,7 +183,7 @@ radio .wx-radio-input{
 }
 /* 选中后的 背景样式  */
 radio .wx-radio-input.wx-radio-input-checked{
-	background: linear-gradient(135deg, #66b2ef  0%, #0bb3f2 100%);
+	background: linear-gradient(135deg, #66b2ef  0%, #008FD3 100%);
 	border: 1px solid #0bb3f2;
 }
 /* 选中后的 对勾样式 (白色对勾) */
@@ -260,3 +260,16 @@ checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
 		transform: translate(-50%,-50%);
 	}
 }
+/* tab颜色 */
+.tab-orange {
+	background: #FF5039;
+}
+.tab-gree{
+	background: #2CAE5C;
+}
+.tab-purple {
+	background: #7A73E0;
+}
+.tab-blue {
+	background: #4585F8;
+}

+ 1 - 16
assets/css/commonTheme.css

@@ -154,20 +154,12 @@
 .color-orange {
 	color: #FC581C;
 }
-
 .color-red {
 	color: #F22513;
 }
-<<<<<<< HEAD
-.color-white{
-	color: #fff;
-=======
-
 .color-yellow {
 	color: #FE9000;
->>>>>>> b7c4a5ef5dca83cf636cd2e6c01d1e9e72751095
 }
-
 .color-pink {
 	color: #FF4545;
 }
@@ -207,17 +199,10 @@
 .bg-purple {
 	background-color: #7A73E0;
 }
-<<<<<<< HEAD
+
 .bg-white{
 	background-color:#fff;
 }
 .bg-light{
 	background-color:#F5F7FA;
 }
-=======
-
-
-.bg-white {
-	background-color: #fff;
-}
->>>>>>> b7c4a5ef5dca83cf636cd2e6c01d1e9e72751095

+ 3 - 2
common/request.js

@@ -3,8 +3,9 @@ export default class Request {
 	http(router, data = {}, method,contentType) {
 		let that = this;
 		// let path = 'http://localhost:7014';
-		//let path = 'https://api.qinggetai.com'; 
-		//let path = "http://n8288269.natappfree.cc/store"
+		let path = 'https://api.qinggetai.com'; 
+		//let path = "http://d7zwsx.natappfree.cc"
+		//let path = "http://taf8642b.natappfree.cc/store"
 		uni.setStorageSync('requestPath',path)
 		// uni.showLoading({
 		// 	title: '加载中'

+ 495 - 0
components/pushangyuqi-calendar/pushangyuqi-calendar.vue

@@ -0,0 +1,495 @@
+<template>
+	<view class="calendar">
+		<view class="table">
+			<view class="chose-head">
+				<view class="chose-item">
+					<view class="btn" @click="yearsub">
+						<u-icon name="arrow-left" color="#008FD3" size="14"></u-icon>
+					</view>
+					<view class="year-td">
+						<picker mode="selector" :range="years" @change="yearchange" :value="y">
+							<view class="text">{{years[y]}}年</view>
+						</picker>
+					</view>
+					<view class="btn" @click="yearadd">
+						<u-icon name="arrow-right" color="#008FD3" size="14"></u-icon>
+					</view>
+				</view>
+				
+				<view class="chose-item">
+					<view class="btn" @click="monthsub">
+						<u-icon name="arrow-left" color="#008FD3" size="14"></u-icon>
+					</view>
+					<view class="month-td">
+						<picker mode="selector" :range="months" @change="monthchange" :value="m">
+							<view class="text">{{months[m]}}月</view>
+						</picker>
+					</view>
+					<view class="btn" @click="monthadd">
+						<u-icon name="arrow-right" color="#008FD3" size="14"></u-icon>
+					</view>
+				</view>
+			</view>
+
+			<view class="week">
+				<view class="item">日</view>
+				<view class="item">一</view>
+				<view class="item">二</view>
+				<view class="item">三</view>
+				<view class="item">四</view>
+				<view class="item">五</view>
+				<view class="item">六</view>
+			</view>
+
+
+			<view class="date-tr" v-for="(i,index) in dates" :key="index">
+				<view v-for="(j,k) in i" :key="k" :style="{color:j[0]}" :class="j[2]=='#008FD3'?'td active':'td'" @click="itemChose(j,index,k)">{{j[1]}}</view>
+			</view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="submit()">
+					确定
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import config from '../../uni_modules/uview-ui/libs/config/config';
+
+	export default {
+		data() {
+			return {
+				year: 2022,
+				month: 12,
+				date: 19,
+				/* 年月是当天的日期,日是这个月日历的第一天,
+				其实就是上个月的最后一个周日,这里是随便定义的,
+				后面在mounted里面根据当前日期赋值 */
+				years: [], //存放1900到2100共200年
+				months: [], //存放1到12月
+				y: 0,
+				m: 0, //picker的迭代器
+				dates: [
+					[],
+					[],
+					[],
+					[],
+					[],
+					[]
+				], //外层括号表示一个月,内层括号表示一周,每个元素是一天
+				activeDateStr: '', // 当前选中的时间
+			}
+		},
+		
+		mounted() {
+			for (let i = 1900; i <= 2100; i++) {
+				this.years.push(i);
+			}
+			for (let i = 1; i <= 12; i++) {
+				this.months.push(i);
+			}
+		
+			//获取当前时间和月份
+			var date = new Date();
+			this.year = date.getFullYear();
+			this.month = date.getMonth() + 1;
+			let dayNum = date.getDate();
+		
+			for (let i = 0; i < 200; i++) {
+				if (this.years[i] == this.year) {
+					this.y = i;
+					break;
+				}
+			}
+			for (let i = 0; i < 12; i++) {
+				if (this.months[i] == this.month) {
+					this.m = i;
+					break;
+				}
+			}
+		
+			//当前月份的天数和上个月的天数
+			var maxdays = this.maxdformat();
+			var maxday = maxdays[0];
+			var premaxday = maxdays[1];
+		
+			//通过当月一号的星期来计算上个月的最后一个星期日时几号
+			date.setDate(1);
+			var weekday = date.getDay();
+			this.date = premaxday - weekday + 1;
+		     // console.log(this.date,'this.date')
+			//编排这个月的日历
+			this.datesformat(maxday, premaxday);
+			
+			let mothnum = this.months[this.m]
+			if(mothnum<10) {
+				mothnum = '0'+mothnum
+			}
+			if(dayNum<10) {
+				dayNum = '0'+dayNum
+			}
+			this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
+		},
+		methods: {
+			//编排日历
+			datesformat(maxday, premaxday) {
+				//获取当前日期,用来突出显示当前日期
+				var date = new Date();
+				var y = date.getFullYear();
+				var m = date.getMonth() + 1;
+				var d = date.getDate();
+				var i = 0,
+					j = 0;
+				for (i; i < 3; i++) {
+					for (j = 0; j < 7; j++) {
+						let cache = ['#222222', '', '#fff']; //第一个元素用来定义字体颜色,第二个是日期,第三个元素是背景色,用来突出显示当前日期
+						if (this.date > 21 && this.date <= premaxday) {
+							cache[0] = '#BBBBBB';
+						}
+						/* 上个月的日期显示为灰色,只能判断前半个月,
+						   因为如果到这个月的21号之后的话造成这个月的日期也变为灰色,
+						   选21是因为前3周不可能到21号(1号在周日的话会放在第二周),
+						   并且上个月的最后一个星期日必然是21号之后 */
+						else if (this.year == y && this.month == m && this.date == d) {
+							cache[2] = '#008FD3'; // 当前日期背景颜色
+							cache[0] = '#fff'; // 当前日期文字颜色
+						}
+						if (this.date <= premaxday) {
+							cache[1] = this.date++;
+						} else {
+							this.date = 1;
+							cache[1] = this.date++; //日期递增,如果超过上个月的最后一天的话重新从1号开始
+						}
+						this.dates[i].push(cache);
+					}
+				}
+				for (i; i < 6; i++) {
+					for (j = 0; j < 7; j++) {
+						let cache = ['#222222', '', "#fff"]
+						if (this.date < 14 || this.date == maxday + 1) {
+							cache[0] = '#BBBBBB'
+						} else if (this.year == y && this.month == m && this.date == d) {
+							cache[2] = '#008FD3'
+							cache[0] = '#fff'; // 当前日期文字颜色
+						}
+						if (this.date <= maxday) {
+							cache[1] = this.date++;
+						} else {
+							this.date = 1;
+							cache[1] = this.date++;
+						}
+						this.dates[i].push(cache);
+						/* 基本与上半月相似,下个月的日期显示为灰色,
+						   选14是因为第4周的第一天最早是15号(1号在周日并放在第二周的情况),
+						   并且下个月出现最多日期的情况(2月1号是周一)也不会有14天 */
+						
+					}
+				}
+			},
+
+			//计算当月的天数和上个月的天数
+			maxdformat() {
+				var maxday = 30;
+				var premaxday = 30; //都定义为30天,这样小月就不用判断了
+				if (this.month == 2) {
+					if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) { //二月判断平闰年
+						maxday = 29;
+					} else {
+						maxday = 28;
+					}
+				} else if (this.month == 1 || this.month == 3 || this.month == 5 || this.month == 7 ||
+					this.month == 8 || this.month == 10 || this.month == 12) { //给大月赋值
+					maxday = 31;
+				}
+
+				//计算上个月的天数,月份+1直接用上面的
+				if (this.month == 3) {
+					if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) {
+						premaxday = 29;
+					} else {
+						premaxday = 28;
+					}
+				} else if (this.month == 2 || this.month == 4 || this.month == 6 || this.month == 8 ||
+					this.month == 9 || this.month == 11 || this.month == 1) {
+					premaxday = 31;
+				}
+				return [maxday, premaxday];
+			},
+
+			//下一个月
+			monthadd() {
+				//月份加一,十二月下一个月是一月
+				if (this.month == 12) {
+					this.y++;
+					this.year++;
+					this.m = 0;
+					this.month = 1;
+				} else {
+					this.m++;
+					this.month++;
+				}
+
+				var maxdays = this.maxdformat();
+				var maxday = maxdays[0];
+				var premaxday = maxdays[1];
+
+				//这个月的最后一个周日,就是下个月日历的第一天
+				if (this.dates[5][0][1] > 14) {
+					this.date = this.dates[5][0][1];
+				} else {
+					this.date = this.dates[4][0][1];
+				}
+				this.dates = [
+					[],
+					[],
+					[],
+					[],
+					[],
+					[]
+				]; //日历初始化
+				this.datesformat(maxday, premaxday); //编排下个月的日历
+			},
+
+			//上一个月
+			monthsub() {
+				if (this.month == 1) {
+					this.m = 11;
+					this.month = 12;
+					this.y--;
+					this.year--;
+				} else {
+					this.m--;
+					this.month--;
+				}
+				var maxdays = this.maxdformat();
+				var maxday = maxdays[0];
+				var premaxday = maxdays[1];
+
+				//根据上个月的最后一个周日,计算上个月日历的第一天
+				if (this.dates[0][0][1] <= 28) {
+					this.date = premaxday + this.dates[0][0][1] - 28;
+				} else {
+					this.date = premaxday + this.dates[0][0][1] - 35;
+				}
+				this.dates = [
+					[],
+					[],
+					[],
+					[],
+					[],
+					[]
+				];
+
+				this.datesformat(maxday, premaxday)
+			},
+
+			//下一年,就是把下一个月运行12次
+			yearadd() {
+				for (let c = 0; c < 12; c++) {
+					this.monthadd();
+				}
+			},
+
+			//上一年,就是把上一个月运行12次
+			yearsub() {
+				for (let c = 0; c < 12; c++) {
+					this.monthsub();
+				}
+			},
+
+			//picker直接选择年份,计算中间差几年,然后运行几次上一年或下一年
+			yearchange(e) {
+				this.y = e.target.value
+				let d = this.year - this.years[this.y];
+				if (d > 0) {
+					for (let i = 0; i < d; i++) {
+						this.yearsub();
+					}
+				} else {
+					for (let i = 0; i < 0 - d; i++) {
+						this.yearadd();
+					}
+				}
+				this.y += d;
+			},
+
+			//picker直接选择月份
+			monthchange(e) {
+				this.m = e.target.value
+				let d = this.month - this.months[this.m];
+				if (d > 0) {
+					for (let i = 0; i < d; i++) {
+						this.monthsub();
+					}
+				} else {
+					for (let i = 0; i < 0 - d; i++) {
+						this.monthadd();
+					}
+				}
+				this.m += d;
+			},
+			// 日期选择
+			itemChose(day,w,k) {
+				if(day[0] == '#222222'){ // 取消所有选中数据
+					for(let i=0;i<6;i++) {
+						for(let j=0;j<7;j++) {
+							if(this.dates[i][j][0] != '#BBBBBB' && this.dates[i][j][2] == '#008FD3') {
+								this.dates[i][j][2] = '#fff'
+								this.dates[i][j][0] = '#222222'
+							}
+						}
+					}
+					this.dates[w][k][2] = '#008FD3'
+					this.dates[w][k][0] = '#fff'
+					let newValue = ['#fff', day[1], "#008FD3"]
+					this.$set(this.dates[w], k, newValue)
+				}
+				let mothnum = this.months[this.m]
+				if(mothnum<10) {
+					mothnum = '0'+mothnum
+				}
+				let dayNum = day[1]
+				if(dayNum<10) {
+					dayNum = '0'+dayNum
+				}
+				this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
+			},
+			submit(){
+				console.log(this.activeDateStr,'===')
+				this.$emit('onDayClick', this.activeDateStr);
+			}
+		},
+	}
+</script>
+
+<style scoped lang="scss">
+	.calendar{
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		.chose-head{
+			width: 100%;
+			height: 88upx;
+			border-bottom: 2upx solid #ECECEC;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			// padding: 0 97upx 0 67upx;
+			.chose-item{
+				display: flex;
+				align-items: center;
+				.btn{
+					width: 48upx;
+					height: 48upx;
+					background: #EFF3F7;
+					border-radius: 8upx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					image{
+						width: 11upx;
+						height: 18upx;
+					}
+				}
+				.year-td{
+					width: 160upx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					.text{
+						font-size: 28upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+					}
+				}
+				.month-td{
+					width: 100upx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					.text{
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+					}
+				}
+			}
+		}
+		.table{
+			width: 100%;
+			.week{
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0 20upx;
+				border-bottom: 2upx solid #ECECEC;
+				.item{
+					width: 10%;
+					height: 60upx;
+					line-height: 60upx;
+					margin: 12upx 0;
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 400;
+					color: #222222;
+					text-align: center;
+					// &:first-child{
+					// 	color: #FF7700;
+					// }
+					// &:last-child{
+					// 	color: #FF7700;
+					// }
+				}
+			}
+			.date-tr{
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0 20upx;
+				.td{
+					width: 10%;
+					height: 56upx;
+					line-height: 56upx;
+					margin: 12upx 0;
+					font-size: 28upx;
+					text-align: center;
+					font-family: PingFang SC;
+					font-weight: 600;
+					color: #222222;
+					border-radius: 8upx;
+					&.active{
+						background-color: #008FD3;
+					}
+				}
+			}
+			.btn-box {
+				// height: 120upx;
+				padding-top: 30rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				.sub-btn {
+					width: 480upx;
+					height: 88upx;
+					line-height: 88upx;
+					text-align: center;
+					font-size: 32upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FFFFFF;
+					background: #008FD3 ;
+					border-radius: 44upx;
+					// margin-bottom: 40upx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
+	}
+	
+</style>

+ 432 - 0
components/ren-calendar/ren-calendar.vue

@@ -0,0 +1,432 @@
+<template>
+    <view class="calendar-wrapper">
+		<view class="fs28 left">{{y+'年'+m+'月'}}</view>
+        <view class="header" v-if="headerBar">
+            <view class="pre" @click="changeMonth('pre')">上个月</view>
+            <view>{{y+'年'+formatNum(m)+'月'}}</view>
+            <view class="next" @click="changeMonth('next')">下个月</view>
+        </view>
+        <view class="week">
+            <view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
+        </view>
+        <view :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
+            <view :style="{ top: positionTop + 'rpx' }" class="days">
+                <view class="item" v-for="(item, index) in dates" :key="index">
+                    <view
+                        class="day"
+                        @click="selectOne(item, $event)"
+                        :class="{
+                            choose: choose == `${item.year}-${item.month}-${item.date}`&&item.isCurM,
+                            nolm: !item.isCurM,
+                            today: isToday(item.year, item.month, item.date),
+                            isWorkDay: isWorkDay(item.year, item.month, item.date)
+                        }"
+                    >
+                        {{ Number(item.date) }}
+                    </view>
+                   <!-- <view class="markDay" v-if="isMarkDay(item.year, item.month, item.date)&&item.isCurM"></view> -->
+                    <!-- <view class="today-text" v-if="isToday(item.year, item.month, item.date)">今</view> -->
+                </view>
+            </view>
+        </view>
+        <image src="@/static/images/company/time_arrow_down_icon.png" mode="scaleToFill" v-if="collapsible" @click="toggle" class="weektoggle" :class="{ down: monthOpen }"></image>
+    </view>
+</template>
+
+<script>
+export default {
+    name: 'ren-calendar',
+    props: {
+        // 星期几为第一天(0为星期日)
+        weekstart: {
+            type: Number,
+            default: 0
+        },
+        // 标记的日期
+        markDays: {
+            type: Array,
+            default: ()=>{
+                return [];
+            }
+        },
+        //是否展示月份切换按钮
+        headerBar:{
+            type: Boolean,
+            default: true
+        },
+        // 是否展开
+        open: {
+            type: Boolean,
+            default: true
+        },
+        //是否可收缩
+        collapsible:{
+            type: Boolean,
+            default: true
+        },
+        //未来日期是否不可点击
+        disabledAfter: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            weektext: ['日', '一', '二', '三', '四', '五', '六'],
+            y: new Date().getFullYear(), // 年
+            m: new Date().getMonth() + 1, // 月
+            dates: [], // 当前月的日期数据
+            positionTop: 0,
+            monthOpen: true,
+            choose: ''
+        };
+    },
+    created() {
+        this.dates = this.monthDay(this.y, this.m);
+        !this.open && this.toggle();
+    },
+    mounted() {
+        this.choose = this.getToday().date;
+    },
+    computed: {
+        // 顶部星期栏
+        weekDay() {
+            return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
+        },
+        height() {
+            return (this.dates.length / 7) * 80 + 'rpx';
+        }
+    },
+    methods: {
+        formatNum(num) {
+            let res = Number(num);
+            return res < 10 ? '0' + res : res;
+        },
+        getToday() {
+            let date = new Date();
+            let y = date.getFullYear();
+            let m = date.getMonth();
+            let d = date.getDate();
+            let week = new Date().getDay();
+            let weekText = ['日', '一', '二', '三', '四', '五', '六'];
+            let formatWeek = '星期' + weekText[week];
+            let today = {
+                date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
+                week: formatWeek
+            };
+            return today;
+        },
+        // 获取当前月份数据
+        monthDay(y, month) {
+            let dates = [];
+            let m = Number(month);
+            let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
+            let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
+            let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天
+            let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
+            let startDay = (() => {
+                // 周初有几天是上个月的
+                if (firstDayOfMonth == weekstart) {
+                    return 0;
+                } else if (firstDayOfMonth > weekstart) {
+                    return firstDayOfMonth - weekstart;
+                } else {
+                    return 7 - weekstart + firstDayOfMonth;
+                }
+            })();
+            let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
+            for (let i = 1; i <= startDay; i++) {
+                dates.push({
+                    date: this.formatNum(lastDayOfLastMonth - startDay + i),
+                    day: weekstart + i - 1 || 7,
+                    month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
+                    year: m - 1 >= 0 ? y : y - 1
+                });
+            }
+            for (let j = 1; j <= lastDateOfMonth; j++) {
+                dates.push({
+                    date: this.formatNum(j),
+                    day: (j % 7) + firstDayOfMonth - 1 || 7,
+                    month: this.formatNum(m),
+                    year: y,
+                    isCurM: true //是否当前月份
+                });
+            }
+            for (let k = 1; k <= endDay; k++) {
+                dates.push({
+                    date: this.formatNum(k),
+                    day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
+                    month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
+                    year: m + 1 <= 11 ? y : y + 1
+                });
+            }
+            // console.log(dates);
+            return dates;
+        },
+        isWorkDay(y, m, d) {
+            //是否工作日
+            let ymd = `${y}/${m}/${d}`;
+            let formatDY = new Date(ymd.replace(/-/g, '/'));
+            let week = formatDY.getDay();
+            if (week == 0 || week == 6) {
+                return false;
+            } else {
+                return true;
+            }
+        },
+        isFutureDay(y, m, d) {
+            //是否未来日期
+            let ymd = `${y}/${m}/${d}`;
+            let formatDY = new Date(ymd.replace(/-/g, '/'));
+            let showTime = formatDY.getTime();
+            let curTime = new Date().getTime();
+            if (showTime > curTime) {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        // 标记日期
+        isMarkDay(y, m, d) {
+            let flag = false;
+            for (let i = 0; i < this.markDays.length; i++) {
+                let dy = `${y}-${m}-${d}`;
+                if (this.markDays[i] == dy) {
+                    flag = true;
+                    break;
+                }
+            }
+            return flag;
+        },
+        isToday(y, m, d) {
+            let checkD = y + '-' + m + '-' + d;
+            let today = this.getToday().date;
+            if (checkD == today) {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        // 展开收起
+        toggle() {
+            this.monthOpen = !this.monthOpen;
+            if (this.monthOpen) {
+                this.positionTop = 0;
+            } else {
+                let index = -1;
+                this.dates.forEach((i, x) => {
+                    this.isToday(i.year, i.month, i.date) && (index = x);
+                });
+                this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80;
+            }
+        },
+        // 点击回调
+        selectOne(i, event) {
+            let date = `${i.year}-${i.month}-${i.date}`;
+            let selectD = new Date(date).getTime();
+            let curTime = new Date().getTime();
+            let week = new Date(date).getDay();
+            let weekText = ['日', '一', '二', '三', '四', '五', '六'];
+            let formatWeek = '星期' + weekText[week];
+            let response = {
+                date: date,
+                week: formatWeek
+            };
+            if (!i.isCurM) {
+                // console.log('不在当前月范围内');
+                return false;
+            }
+            if (selectD > curTime) {
+                if (this.disabledAfter) {
+                    console.log('未来日期不可选');
+                    return false;
+                } else {
+                    this.choose = date;
+                    this.$emit('onDayClick', response);
+                }
+            } else {
+                this.choose = date;
+                this.$emit('onDayClick', response);
+            }
+            console.log(response);
+        },
+        //改变年月
+        changYearMonth(y, m) {
+            this.dates = this.monthDay(y, m);
+            this.y = y;
+            this.m = m;
+        },
+        changeMonth(type){
+            if(type=='pre'){
+               if (this.m + 1 == 2) {
+                   this.m = 12;
+                   this.y = this.y - 1;
+               } else {
+                   this.m = this.m - 1;
+               } 
+            }else{
+                if (this.m + 1 == 13) {
+                    this.m = 1;
+                    this.y = this.y + 1;
+                } else {
+                    this.m = this.m + 1;
+                }
+            }
+            this.dates = this.monthDay(this.y, this.m);
+        }
+    }
+};
+</script>
+
+<style lang="scss" scoped>
+.calendar-wrapper {
+    color: #fff;
+    font-size: 28rpx;
+    text-align: center;
+    background-color: #008FD3;
+    padding-bottom: 10rpx;
+	.left{
+		font-weight: 500;
+		font-size: 28rpx;
+		color: #FFFFFF;
+		text-align: left;
+		padding: 10rpx 36rpx;
+	}
+    .header{
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 88rpx;
+        color: #42464A;
+        font-size: 32rpx;
+        font-weight: bold;
+        border-bottom: 2rpx solid #f2f2f2;
+        .pre,.next{
+              color: #4d7df9;
+              font-size: 28rpx;
+              font-weight: normal;
+              padding: 8rpx 15rpx;
+              border-radius: 10rpx;
+              border: 2rpx solid #dcdfe6;
+        }
+        .pre{
+            margin-right: 30rpx;
+        }
+        .next{
+            margin-left: 30rpx;
+        }
+    }
+
+    .week {
+        display: flex;
+        align-items: center;
+        height: 80rpx;
+        line-height: 80rpx;
+        border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
+
+        view {
+            flex: 1;
+        }
+    }
+
+    .content {
+        position: relative;
+        overflow: hidden;
+        transition: height 0.4s ease;
+
+        .days {
+            transition: top 0.3s;
+            display: flex;
+            align-items: center;
+            flex-wrap: wrap;
+            position: relative;
+
+            .item {
+                position: relative;
+                display: block;
+                height: 80rpx;
+                line-height: 80rpx;
+                width: calc(100% / 7);
+
+                .day {
+                    font-style: normal;
+                    display: inline-block;
+                    vertical-align: middle;
+                    width: 60rpx;
+                    height: 60rpx;
+                    line-height: 60rpx;
+                    overflow: hidden;
+                    border-radius: 8rpx;
+
+                    &.choose {
+                        background-color: #fff;
+                        color: #008FD3;
+                    }
+
+                    &.nolm {
+                        color: #fff;
+                        opacity: 0.5;
+                    }
+                }
+                .isWorkDay {
+                    color: #fff;
+					font-weight: 600;
+                }
+
+                .notSigned {
+                    font-style: normal;
+                    width: 8rpx;
+                    height: 8rpx;
+                    background: #fa7268;
+                    border-radius: 10rpx;
+                    position: absolute;
+                    left: 50%;
+                    bottom: 0;
+                    pointer-events: none;
+                }
+                .today {
+                    color: #fff;
+                    background-color: #a8c0ff;
+                }
+                .workDay {
+                    font-style: normal;
+                    width: 8rpx;
+                    height: 8rpx;
+                    background: #4d7df9;
+                    border-radius: 10rpx;
+                    position: absolute;
+                    left: 50%;
+                    bottom: 0;
+                    pointer-events: none;
+                }
+                .markDay{
+                    font-style: normal;
+                    width: 8rpx;
+                    height: 8rpx;
+                    background: #fc7a64;
+                    border-radius: 10rpx;
+                    position: absolute;
+                    left: 50%;
+                    bottom: 0;
+                    pointer-events: none;
+                }
+            }
+        }
+    }
+
+    .hide {
+        height: 80rpx !important;
+    }
+
+    .weektoggle {
+        width: 48rpx;
+        height: 48rpx;
+        position: relative;
+        // bottom: -42rpx;
+        &.down {
+            transform: rotate(180deg);
+            bottom: 0;
+        }
+    }
+}
+</style>

+ 487 - 0
components/sapling-vue-scale/sapling-vue-scale.vue

@@ -0,0 +1,487 @@
+
+<template>
+  <div>
+    <!-- 横向 -->
+    <view class='wrapper horizontal-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-if="direction=== 'horizontal'">
+      <view class='scale-mask' v-if="!scroll"/>
+      <!-- 选中的横条  -->
+      <view class='zz' :style="{backgroundColor: stylesObj.lineSelect}"/>
+      <scroll-view
+        class='scroll-view'
+        :scroll-x="true"
+        :scroll-left="centerNum"
+        :scroll-with-animation="true"
+        @scroll="bindscroll"
+        :show-scrollbar="false"
+        :enhanced="true"
+      >
+
+        <view class='scroll-wrapper'>
+          <!-- 左补白 -->
+          <view class='seat' :style="{width: windowWidth/2 + 'px'}"/>
+
+          <!-- 标尺容器 -->
+          <view  class='scale-container'>
+            <view class='scale-wrapper'>
+              <view class='scale-grip'
+                    v-for="(item, index) in grid"
+                    :key="index"
+                    :style="{height:h + 'px', borderColor: stylesObj.line }">
+                <view class='scale-grip-item'
+                      v-for="(it, idx) in 10"
+                      :key="idx"
+                      :style="{width: single + 'px', height: idx===4?'80':'60' + '%', borderColor: stylesObj.line}"
+                />
+              </view>
+            </view>
+            <!-- 标尺数显示,长度:每格长度*个数 -->
+            <view class='scale-vaule-wrapper' :style="{width: single*10*grid + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
+              <view class='scale-value first-scale-value' :style="{width: single*10 + 'px'}">{{min}}</view>
+              <view v-if="int" style="display: flex;">
+                <view
+                  class='scale-vaule'
+                  v-for="(item, index) in grid"
+                  :key="index"
+                  :style="{width:single*10 + 'px'}">{{min+10*(index+1)}}
+                </view>
+              </view>
+              <view v-else style="display: flex;">
+                <view
+                  class='scale-vaule'
+                  v-for="(it, index) in grid"
+                  :key="index"
+                  :style="{width: single*10 + 'px'}">{{min+(index+1)}}
+                </view>
+              </view>
+            </view>
+          </view>
+
+          <!-- 右补白 -->
+          <view class='seat' :style="{width: windowWidth/2 + 'px'}"/>
+        </view>
+      </scroll-view>
+    </view>
+
+    <!-- 竖向 -->
+    <view class='wrapper vertical-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-else-if="direction === 'vertical'">
+      <view class='scale-mask' v-if="!scroll"/>
+      <view class='zz' :style="{backgroundColor: stylesObj.lineSelect}"/>
+      <scroll-view
+        class='scroll-view'
+        style="height: 600rpx;"
+        :scroll-y="true"
+        :scroll-top="centerNum"
+        :scroll-with-animation='true'
+        @scroll="bindscroll"
+        :show-scrollbar="false"
+        :enhanced="true">
+
+        <view class='scroll-wrapper'>
+          <!-- 左补白 -->
+          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>
+
+          <!-- 标尺容器 -->
+          <view  class='scale-container'>
+            <view class='scale-wrapper' :style="{height: single*10*grid + 'px', paddingTop: single*10/2 + 'px'}">
+              <view class='scale-grip'
+                    v-for="(item, index) in grid"
+                    :key="index"
+                    :style="{borderColor: stylesObj.line}">
+                <view class='scale-grip-item'
+                      v-for="(it, idx) in 10"
+                      :key="idx"
+                      :style="{height: single + 'px', width: (idx==4||idx==9) ? '80':'60' + '%', borderColor: stylesObj.line}"
+                />
+              </view>
+            </view>
+            <!-- 标尺数显示,长度:每格长度*个数 -->
+            <view class='scale-vaule-wrapper'
+                  :style="{height: single*10*(grid+1) + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
+              <view class='scale-value' :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min}}</view>
+              <view v-if="int">
+                <view class='scale-vaule'
+                      v-for="(item, index) in grid"
+                      :key="index"
+                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+10*(index+1)}}
+                </view>
+              </view>
+              <view v-else>
+                <view class='scale-vaule'
+                      v-for="(it, index) in grid"
+                      :key="index"
+                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+(index+1)}}
+                </view>
+              </view>
+            </view>
+          </view>
+
+          <!-- 右补白 -->
+          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>
+        </view>
+      </scroll-view>
+    </view>
+  </div>
+</template>
+
+<script>
+/**
+ min[number] 默认值 0, // 最小值
+ max[number] 默认值 100, // 最大值
+ int[boolean] 默认值 true, // 是否开启整数模式 ,false为小数模式  true 整数模式
+ single[number] 默认值 10, // 单个格子的实际长度(单位rpx)
+ h[number] 默认值 0,// 自定义高度 初始值为80
+ active[null] 默认值 center ,// 自定义选中位置  (三个值 min, max ,center , 范围内合法数值)
+ styles[object]  // 自定义卡尺样式
+ */
+
+export default {
+  name: '',
+  components: {},
+  props: {
+    // 最小值
+    min: {
+      type: Number,
+      default: 0,
+    },
+    // 最大值
+    max: {
+      type: Number,
+      default: 100,
+    },
+    // 是否开启整数模式
+    int: {
+      type: Boolean,
+      default: false,
+    },
+    // 每个格子的实际行度 (单位px ,相对默认值)
+    single: {
+      type: Number,
+      default: 10,
+    },
+    // 高度
+    h: {
+      type: Number,
+      default: 80,
+    },
+    // 是否禁止滚动
+    scroll: {
+      type: Boolean,
+      default: true,
+    },
+    // 方向
+    direction: {
+      type: String,
+      default: 'horizontal',
+    },
+    // 当前选中
+    active: {
+      type: null,
+      default: '0',
+    },
+    styles: {
+      type: Object,
+      default: () => {},
+    },
+
+  },
+  data() {
+    return {
+      defaultStyles: {
+        line: '#CCCCCC', // 刻度颜色
+        bginner: '#fbfbfb', // 前景色颜色
+        bgoutside: '#dbdbdb', // 背景色颜色
+        lineSelect: '#FF5030', // 选中线颜色
+        fontColor: '#404040', // 刻度数字颜色
+        fontSize: 16, // 字体大小
+      },
+      rul: {},
+      windowHeight: 0,
+      windowWidth: '',
+      horizontalTime: null,
+      verticalTime: null,
+      grid: '',
+      centerNum: '',
+      stylesObj: {},
+    };
+  },
+  computed: {},
+  watch: {},
+  onReady() {
+    const min = parseInt(this.min, 10) || 0;
+    const max = parseInt(this.max, 10) || 100;
+    this.min = min;
+    this.max = max;
+    this.init();
+  },
+  created() {
+  },
+  mounted() {
+  },
+  methods: {
+    // 初始化
+    init() {
+      // 设置默认值
+      const min = this.min || 0;
+      const max = this.max || 0;
+      /**
+       * grid 外层的刻度尺,里面有10个小刻度尺(10个小刻度尺直接拿10遍历出来)
+       * 整数:
+       *  需要除以10,此时里面的一个小刻度尺代表1
+       *  例如:30-80 此时需要5个外层刻度尺。
+       * 小数:
+       *  不需要除以10,此时里面的一个小刻度尺代表0.1
+       *  例如:30-80 此时需要50个外层刻度尺。
+       *
+       */
+      let grid;
+      if (this.int) {
+        grid = (max - min) / 10;
+      } else {
+        grid = (max - min);
+      }
+      this.stylesObj = Object.assign(this.defaultStyles, this.styles);
+      this.grid = grid;
+
+      // 当前选中的 active
+      let activeVal = this.selectActiveVal();
+      if (activeVal < min || activeVal > max) { // 默认数字不合理
+        activeVal = (min + max) / 2;
+      }
+      if (this.int) {
+        let diff = (activeVal - min) / 10; // 移动diff格
+        /* eslint-disable-next-line */
+        if (diff < 0 || isNaN(diff) || !diff) diff = 0;
+        // this.single 每个小格子长度
+        const centerNum = diff * this.single * 10;
+        setTimeout(() => { this.centerNum = centerNum; }, 200);
+      } else {
+        const diff1 = (activeVal - min) * 10; // 移动diff格
+        const centerNum = diff1 * this.single;
+        setTimeout(() => { this.centerNum = centerNum; }, 200);
+      }
+      //  获取节点信息,获取节点宽度
+      const query = this.createSelectorQuery().in(this);
+      query.select('#scale-wrapper').boundingClientRect(() => {
+        // res.top; // 这个组件内 #the-id 节点的上边界坐标
+      }).exec((e) => {
+        this.windowWidth = e[0].width;
+        this.windowHeight = e[0].height;
+      });
+    },
+    // 给定的选中默认值
+    selectActiveVal() {
+      // 当前选中位置设置
+      let activeVal;
+      if (this.active === 'min') {
+        activeVal = this.min;
+      } else if (this.active === 'max') {
+        activeVal = this.max;
+      } else if (this.active === 'center') {
+        activeVal = (this.min + this.max) / 2;
+      } else {
+        activeVal = this.active ? this.active : this.min;
+      }
+      return activeVal;
+    },
+    // 滚动
+    bindscroll(e) {
+      // 移动的距离
+      let offset = 0;
+      if (this.direction === 'vertical') {
+        offset = e.detail.scrollTop;
+      } else {
+        offset = e.detail.scrollLeft;
+      }
+      // 选中的值
+      let value;
+      if (this.int) {
+        value = this.min + (offset / this.single);
+        value = Math.round(value);
+        if (value > this.max) value = this.max;
+        this.$emit('value', value);
+        const centerNum = (value - this.min) * this.single + Math.random() ** 10;
+        clearTimeout(this.horizontalTime);
+        this.horizontalTime = setTimeout(() => {
+          this.centerNum = centerNum;
+          this.$emit('value', value);
+        }, 100);
+      } else {
+        value = this.min + ((offset / this.single) / 10);
+        value = value.toFixed(1);
+        if (value > this.max) value = this.max;
+        this.$emit('value', value);
+        const centerNum = (value - this.min) * this.single * 10 + Math.random() ** 10;
+        clearTimeout(this.verticalTime);
+        this.verticalTime = setTimeout(() => {
+          this.centerNum = centerNum;
+          this.$emit('value', value);
+        }, 100);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+  view,text {
+    box-sizing: border-box;
+  }
+  .wrapper {
+    position: relative;
+  }
+  .scale-mask {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    z-index: 100;
+  }
+  .horizontal-box {
+    // padding-top: 7%;
+    .scroll-wrapper {
+      position: relative;
+      display: flex;
+    }
+    .zz {
+      position: absolute;
+      left: 50%;
+      top: 0;
+      transform: translate(-50%);
+      height: 100%;
+      width: 2rpx;
+      background-color: #FF5030;
+      z-index: 10;
+	  &::before{
+	  		  display:block;
+	  		     content:'';
+	  		     border-width:16rpx 16rpx 16rpx 16rpx;
+	  		     border-style:solid;
+	  		     border-color:#FF5030 transparent transparent transparent;
+	  		  
+	  		     /* 定位 */
+	  		     position:absolute;
+	  		    left: -16rpx;
+	  		    top: 0;
+	  }
+    }
+    .scale-wrapper {
+      display: flex;
+      border-top: 1px solid #dddddd;
+    }
+    .scale-grip {
+      position: relative;
+      height: 100rpx;
+      display: flex;
+      &::before {
+        content: "";
+        position: absolute;
+        top: 0;
+        border-width: 1px;
+        border-color: inherit;
+        border-style: solid;
+        height: 100%;
+        transform: translateX(-50%);
+        left: 0rpx;
+      }
+      &:last-child {
+        &::after {
+          content: "";
+          position: absolute;
+          top: 0;
+          right: 0;
+          border-width: 1px;
+          border-color: inherit;
+          border-style: solid;
+          height: 100%;
+        }
+      }
+    }
+    .scale-grip-item {
+      height: 60%;
+      padding-top: 10rpx;
+	  &:nth-child(5n){
+		  height: 80%;
+	  }
+      &:not(:last-child) {
+        border-right: 1px solid #000000;
+      }
+    }
+    .scale-vaule-wrapper {
+      position: relative;
+      display: flex;
+      text-align: center;
+    }
+    .scale-vaule {
+      padding: 30rpx 0;
+      transform: translateX(50%);
+    }
+    .first-scale-value {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      padding: 20rpx 0;
+      transform: translateX(-50%);
+    }
+    .seat {
+      flex-shrink: 0;
+      box-sizing: border-box;
+      border-top: 1px solid #ddd;
+    }
+  }
+  /* .scale-container{
+    display: flex;
+  } */
+  .vertical-box {
+    height: 100%;
+    .scroll-wrapper {
+      position: relative;
+    }
+    .scroll-view {
+      height: 100%;
+    }
+    .zz {
+      position: absolute;
+      top: 50%;
+      left: 0;
+      transform: translate(-50%);
+      width: 40%;
+      height: 2px;
+      background-color: #FF5030;
+      z-index: 10;
+    }
+    .scale-container {
+      display: flex;
+      width: 100%;
+    }
+    .scale-wrapper {
+      flex: 1;
+    }
+    .scale-grip {
+      position: relative;
+      border-left: 1px solid #000000;
+      &:first-child {
+        &::before {
+          content: "";
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 80%;
+          height: 0;
+          border-top: 1px solid #dbdbdb;
+        }
+      }
+    }
+    .scale-grip-item {
+      height: 60%;
+      padding-top: 10rpx;
+      border-bottom: 1px solid #000000;
+    }
+    .scale-vaule-wrapper {
+      position: relative;
+      text-align: left;
+      flex: 1;
+    }
+    .scale-vaule {
+    }
+  }
+
+</style>

+ 2 - 3
main.js

@@ -3,7 +3,7 @@ import App from './App'
 
 Vue.config.productionTip = false
 
-import uView from 'uview-ui'
+import uView from '@/uni_modules/uview-ui'
 Vue.use(uView)
 // uni.$u.config.unit = 'rpx'
   
@@ -12,8 +12,7 @@ Vue.prototype.utils = utils;
  
 import {setData} from './utils/common.js'
 Vue.prototype.setData = setData;
- 
- 
+
 App.mpType = 'app'
 const app = new Vue({
     ...App

+ 5 - 0
package-lock.json

@@ -4,6 +4,11 @@
     "lockfileVersion": 1,
     "requires": true,
     "dependencies": {
+        "@qiun/ucharts": {
+            "version": "2.5.0-20230101",
+            "resolved": "https://registry.npmjs.org/@qiun/ucharts/-/ucharts-2.5.0-20230101.tgz",
+            "integrity": "sha512-C7ccBgfPuGF6dxTRuMW0NPPMSCf1k/kh3I9zkRVBc5PaivudX/rPL+jd2Wty6gn5ya5L3Ob+YmYe09V5xw66Cw=="
+        },
         "animate.css": {
             "version": "3.7.2",
             "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-3.7.2.tgz",

+ 256 - 0
pages.json

@@ -861,6 +861,85 @@
 					"path": "index",
 					"style": {
 						"navigationBarTitleText": "销售管理首页",
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "clientList",
+					"style": {
+						"navigationBarTitleText": "我的下级",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "todoList",
+					"style": {
+						"navigationBarTitleText": "待办事项",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "clientDetail",
+					"style": {
+						"navigationBarTitleText": "客户详情",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "executionRecord",
+					"style": {
+						"navigationBarTitleText": "执行记录",
+						"navigationBarBackgroundColor": "#008FD3",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "returnRecord",
+					"style": {
+						"navigationBarTitleText": "回访记录",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "testRecord",
+					"style": {
+						"navigationBarTitleText": "测评记录",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "schedule",
+					"style": {
+						"navigationBarTitleText": "日程",
+						"navigationBarBackgroundColor": "#008FD3",
+				        "navigationBarTextStyle": "white",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "addSchedule",
+					"style": {
+						"navigationBarTitleText": "添加日程",
+						"navigationBarBackgroundColor": "#008FD3",
+				        "navigationBarTextStyle": "white",
 						"app-plus": {
 							"titleNView": false
 						}
@@ -1149,6 +1228,183 @@
 							"titleNView": false
 						}
 					}
+				},
+				{
+					"path": "doc",
+					"style": {
+						"navigationBarTitleText": "添加用户信息",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "addDoc",
+					"style": {
+						"navigationBarTitleText": "健康档案",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},{
+					"path": "addUser",
+					"style": {
+						"navigationBarTitleText": "用户信息",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "buyOrder",
+					"style": {
+						"navigationBarTitleText": "购买信息",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "addServe",
+					"style": {
+						"navigationBarTitleText": "商品信息",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "addCompetitors",
+					"style": {
+						"navigationBarTitleText": "竞品信息",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				}
+			]
+		},{
+			"root": "pages_echarts",
+			"pages": [
+				{
+					"path": "bloodSugar",
+					"style": {
+						"navigationBarTitleText": "血糖检测",
+						"enablePullDownRefresh": false,
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "bloodSugarList",
+					"style": {
+						"navigationBarTitleText": "血糖数据",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "bloodSugarDetail",
+					"style": {
+						"navigationBarTitleText": "血糖详情",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "bloodPressure",
+					"style": {
+						"navigationBarTitleText": "血压检测",
+						"enablePullDownRefresh": false,
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "bloodPressureList",
+					"style": {
+						"navigationBarTitleText": "血压数据",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "bloodPressureDetail",
+					"style": {
+						"navigationBarTitleText": "血压详情",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "acid",
+					"style": {
+						"navigationBarTitleText": "尿酸检测",
+						"enablePullDownRefresh": false,
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "acidList",
+					"style": {
+						"navigationBarTitleText": "尿酸数据",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "acidDetail",
+					"style": {
+						"navigationBarTitleText": "尿酸详情",
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},{
+					"path": "waistLine",
+					"style": {
+						"navigationBarTitleText": "腰围",
+						"enablePullDownRefresh": false,
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
+				},
+				{
+					"path": "hips",
+					"style": {
+						"navigationBarTitleText": "臀围",
+						"enablePullDownRefresh": false,
+						"navigationStyle": "custom",
+						"app-plus": {
+							"titleNView": false
+						}
+					}
 				}
 			]
 		}

+ 16 - 12
pages/user/index.vue

@@ -195,8 +195,8 @@
 		},
 		onShow() {
 			console.log("onshow")
-			this.getUserInfo();
-			this.getOrderCount();
+			// this.getUserInfo();
+			// this.getOrderCount();
 		},
 		onReachBottom() {
 			console.log("onReachBottom")
@@ -229,16 +229,20 @@
 				);
 			},
 			toManager(){
-				if(this.utils.checkCompanyUserLoginState()){
-					uni.navigateTo({
-						url: '/pages_company/index'
-					})
-				}
-				else{
-					uni.navigateTo({
-						url: '/pages_company/auth/login'
-					})
-				}
+				console.log('---')
+				uni.navigateTo({
+					url: '/pages_company/index'
+				})
+				// if(this.utils.checkCompanyUserLoginState()){
+				// 	uni.navigateTo({
+				// 		url: '/pages_company/index'
+				// 	})
+				// }
+				// else{
+				// 	uni.navigateTo({
+				// 		url: '/pages_company/auth/login'
+				// 	})
+				// }
 				
 			},
 			openH5(url){

+ 420 - 0
pages_company/addSchedule.vue

@@ -0,0 +1,420 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="time-box">
+				<view class="time">2025年7月15日</view>
+				<view class="txt">今日待办</view>
+				<view class="num">10</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">开始时间</text>
+				<view class="form-item">
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+						<input type="text" :value="form.birthday" placeholder="请选择日程开始时间" placeholder-class="form-input" disabled="disabled" />
+						</view>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+					</picker>
+				</view>
+				<text class="form-title">日程安排</text>
+				<view class="form-item">
+					<textarea maxlength="200" class="form-textarea" v-model="form.remark" placeholder="请输入您的日程安排"  placeholder-class="form-input" />
+				</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="submit()">
+				添加
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				array:['是','否'],
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			sexChange(type) {
+				this.form.sex = type
+			},
+			radioClick(item) {
+			        this.checked=item.id
+			      },
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			onChooseAvatar(e){
+				let {
+					avatarUrl
+				} = e.detail;
+				uni.uploadFile({
+					url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+					filePath: avatarUrl,
+					name: 'file',
+					formData: {
+						'user': 'test'  // 上传附带参数
+					},
+					success: (uploadFileRes) => {
+						this.user.avatar =JSON.parse(uploadFileRes.data).url
+					}
+				});
+			},
+			submit() {
+				// if (this.form.userName == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "姓名不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.idCard == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "身份证号不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.sex == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "性别不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.birthday == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "出生年月不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.type == "add") {
+				// 	this.addDoc()
+				// } else if (this.type == "edit") {
+				// 	this.editDoc()
+				// }
+                uni.navigateTo({
+                	url: '/pages_health/doc?type=edit&docId='
+                })
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			// padding: 20upx;
+background: #008FD3;
+.time-box{
+	padding: 30rpx;
+	text-align: left;
+	.time{
+		font-family: PingFang SC;
+		font-weight: 500;
+		font-size: 28rpx;
+		color: #FFFFFF;
+		padding-bottom: 25rpx;
+	}
+	.txt{
+		font-weight: 500;
+		font-size: 24rpx;
+		color: rgba(255,255,255,0.5);
+		padding-bottom: 12rpx;
+	}
+	.num{
+		font-family: Roboto, Roboto;
+		font-weight: 500;
+		font-size: 64rpx;
+		color: #FFFFFF;
+	}
+}
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 32upx;
+				margin-bottom: -40upx;
+
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 600;
+					font-size: 36rpx;
+					color: #222426;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: flex-start;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+        
+					.label {
+						width: 300upx;
+						text-align: left;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+
+					input {
+						text-align:left;
+					}
+               
+					.form-input {
+						font-size: 30upx;
+						font-family: PingFang SC;
+						// font-weight: 500;
+						color: #B2B2B2;
+						text-align: left;
+					}
+
+					.form-item-tag{
+						margin-right: 16rpx;
+						.tag{
+							border-radius: 8rpx 8rpx 8rpx 8rpx;
+							border: 2rpx solid #ECECEC;
+							display: flex;
+							align-items: center;
+							padding: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							&.active{
+								background: #F0FAFF;
+								border: 2rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+						
+						
+					}
+					.right{
+						display: flex;
+						align-items: center;
+					}
+					.sex-box{
+						flex:1;
+						display: flex;
+						align-items: center;
+						justify-content: flex-end;
+						.sex-item{
+							width: 146rpx;
+							height: 64rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							background: #F5F7FA;
+							border-radius: 32rpx 32rpx 32rpx 32rpx;
+							margin-left: 16rpx;
+							.u-icon__icon{
+								margin: 0;
+							}
+							text{
+								// font-family: PingFang SC, PingFang SC;
+								font-weight: 400;
+								font-size: 28rpx;
+								color: #898E91;
+								margin-left: 12rpx;
+							}
+							&.active{
+								background: #FCF0E7;
+								text{
+									color:#FF5030
+								}
+							}
+						}
+					}
+					.form-textarea{
+						font-size: 30upx;
+						color: #999999;
+						height: 100upx;
+						padding: 4upx 0;
+					}
+					 
+					.birth-picker {
+						width: 100%;
+						.right-box{
+							width: 100%;
+							display: flex;
+							align-items: center;
+							justify-content: space-between;
+							.input-box{
+								flex: 1;
+								// width: 470upx;
+							}
+							.arrow{
+								width: 13upx;
+								height: 23upx;
+								margin-left: 20upx;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3 ;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+	}
+</style>

+ 484 - 0
pages_company/clientDetail.vue

@@ -0,0 +1,484 @@
+<template>
+		<view class="content">
+			<view class="user-info2">
+				<view class="align-center justify-between">
+				<view class="left">
+					<view class="head-img">
+						<image :src="user.avatar==null?'../static/images/health/my_heads.png':user.avatar" mode="aspectFill"></image>
+					</view>
+					<view class="name-phone">
+						<view class="name">{{user.nickName}}</view>
+						<view class="phone-box" v-if="user!=null">
+							<image class="w32 h32" src="../static/images/company/address_icon.png" mode=""></image>
+							<view class="address">
+								重庆
+							</view>
+							<view class="phone">
+								{{utils.parsePhone(user.phonenumber)}}
+							</view>
+						</view>
+					</view>
+				</view>
+					<image class="w80 h80" src="../static/images/company/phone_icon.png" mode=""></image>
+				</view>
+				<view class="tag-box">
+					<view class="align-center justify-between mb32">
+						<view class="title">他的标签</view>
+						<view class="title2">编辑标签</view>
+					</view>
+					<view class="align-center">
+						<view class="tag">高血压</view>
+						<view class="tag">高血压</view>
+						<view class="add-tag">
+							<image class="w24 h24" src="../static/images/company/add_blue_icon.png" mode=""></image>
+							<view>添加标签</view>
+						</view>
+					</view>
+				</view>
+				<view class="demands">
+					<view class="title">健康诉求</view>
+					<view class="text">希望能够调理好糖尿病</view>
+				</view>
+				
+			</view>
+			<view class="used-tools2">
+				<view class="title">管理</view>
+				<view class="tools-list">
+					<view class="item" @click="navgetTo('/pages_user/user/userTui')">
+						<image src="../static/images/company/health_records_icon.png" mode=""></image>
+						<text class="text">健康档案</text>
+					</view>
+					<view class="item" @click="navgetTo('')">
+						<image src="../static/images/company/physical_examination_icon.png" mode=""></image>
+						<text class="text">体检信息</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_company/executionRecord')">
+						<image src="../static/images/company/execution_record_icon.png" mode=""></image>
+						<text class="text">执行记录</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_company/returnRecord')">
+						<image src="../static/images/company/return_records_icon.png" mode=""></image>
+						<text class="text">回访记录</text>
+					</view>
+					<view class="item" @click="navgetTo('')">
+						<image src="../static/images/company/consumables_mall_icon.png" mode=""></image>
+						<text class="text">购买信息</text>
+					</view>
+					 <view class="item" @click="navgetTo('')">
+					 	<image src="../static/images/company/comparison_indicators_icon.png" mode=""></image>
+					 	<text class="text">指标对比</text>
+					 </view>
+					 <view class="item" @click="navgetTo('/pages_company/testRecord')">
+					 	<image src="../static/images/company/evaluation_record_icon.png" mode=""></image>
+					 	<text class="text">测评记录</text>
+					 </view>
+					 <view class="item" @click="navgetTo('')">
+					 	<image src="../static/images/company/follow_up_records_icon.png" mode=""></image>
+					 	<text class="text">跟进记录</text>
+					 </view>
+				</view>
+			</view>
+			<view class="used-tools2">
+				<view class="title">备注信息</view>
+				<view class="tools-list">
+					<view class="remark">暂无</view>
+				</view>
+		     </view>
+		</view>
+</template>
+
+<script>
+	import {getUserInfo,getQrImg} from '@/api/companyUser'
+	export default {
+		data() {
+			return {
+				statusBarHeight:'',
+				top:0,
+				user:{
+					nickName:'健康管家小左',
+					phonenumber:'13996660261',
+					deptName:'测试企业',
+					avatar:null
+				},
+				 // user:null,
+			};
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			console.log("onload")
+		},
+		onShow() {
+			console.log("onshow")
+			// this.getUserInfo()
+		},
+		methods: {
+			alipay(){
+				// var url="http://alipay.yjf.runtzh.com/#/?companyId="+this.user.companyId+"&companyUserId="+this.user.userId
+				// uni.setClipboardData({
+				// 	data:url,
+				// 	success:()=>{
+				// 		uni.showToast({
+				// 			title:'收款地址已复制到剪切板',
+				// 			icon:'none'
+				// 		})
+						
+				// 	}
+				// });
+				
+				uni.navigateTo({
+					url:'/pages_company/alipayImg'
+				})
+			},
+			toCard(){
+				uni.navigateTo({
+					url:'/pages_company/card?cardId='+this.user.cardId
+				})
+			},
+			toCreateOrder(){
+				uni.navigateTo({
+					url:'/pages_company/order/productList'
+				})
+			},
+			toPay(){
+				uni.navigateTo({
+					url:'/pages_user/user/pay?companyId='+this.user.companyId+"&companyUserId="+this.user.userId
+				})
+			},
+			toOrder(){
+				uni.navigateTo({
+					url:'/pages_company/storeOrder?companyId='+this.user.companyId+"&companyUserId="+this.user.userId
+				})
+			},
+			toPackage(){
+				uni.navigateTo({
+					url:'/pages_company/storeProductPackage?companyId='+this.user.companyId+"&companyUserId="+this.user.userId
+				})
+			},
+			toCoupon(){
+				uni.navigateTo({
+					url:'/pages_company/coupon'
+				})
+			},
+			toCreateCoupon(){
+				uni.navigateTo({
+					url:'/pages_company/order/coupon'
+				})
+			},
+			toCreateOrderCoupon(){
+				uni.navigateTo({
+					url:'/pages_company/order/coupon'
+				})
+			},
+			getUserInfo(){
+				var data={token:uni.getStorageSync('CompanyUserToken')}
+				getUserInfo(data).then(
+					res => {
+						if(res.code==200){
+							  this.user=res.data;
+						}
+						else if(res.code==403){
+							uni.setStorageSync('CompanyUserToken',null);
+							uni.navigateBack({
+								delta:-1
+							})			
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			logout(){
+			 	uni.showModal({
+			 		title:"提示",
+			 		content:"确认退出登录吗?",
+			 		showCancel:true,
+			 		cancelText:'取消',
+			 		confirmText:'确定',
+			 		success:res=>{
+			 			if(res.confirm){
+			 				uni.setStorageSync('CompanyUserToken',null);
+			 				uni.navigateBack({
+			 					delta:-1
+			 				})							
+			 			}else{
+			 			}
+			 		}
+			 	})
+			 },
+			 
+			// 跳转页面
+			navgetTo(url) {
+				// this.utils.isLogin().then(res => {
+				// 	if(res){
+						uni.navigateTo({
+							url: url
+						})
+				// 	}
+				// })
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.bg {
+		width: 100%;
+		height: 380rpx;
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: -1;
+	}
+	.content{
+		padding:20upx;
+		background: linear-gradient( 180deg, #008FD3 0%, #EFF3F7 24%, #EFF3F7 100%);
+		height: 100vh;
+		    box-sizing: border-box;
+			padding-top: 32rpx;
+		.user-info2{
+			box-sizing: border-box;
+			background: #FFFFFF;
+			border-radius: 16upx;
+			padding: 40upx 30upx;
+			margin-bottom: 20rpx;
+			.left{
+				position: relative;
+				display: flex;
+				.head-img{
+					width: 112upx;
+					height: 112upx;
+					border-radius: 50%;
+					overflow: hidden;
+					margin-right: 30upx;
+					image{
+						width: 100%;
+						height: 100%;
+					}
+				}
+				.name-phone{
+					// padding-top: 15upx;
+					display: flex;
+					flex-direction: column;
+					justify-content:center;
+					.name{
+						font-size: 36upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #111111;
+						// line-height: 1;
+					}
+					.phone-box{
+						display: flex;
+						align-items: center;
+						margin-top: 14rpx;
+						.phone{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #626468;
+							line-height: 36rpx;
+						}
+						.address{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #626468;
+							margin-left:8rpx;
+							margin-right: 30rpx;
+						}
+					}
+					
+				}
+			}
+			.tag-box{
+				padding-top: 40rpx;
+				padding-bottom: 40rpx;
+				border-bottom: 1rpx solid #ECECEC;
+				.title{
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #222426;
+				}
+				.title2{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+				}
+				.tag{
+					margin-right: 16rpx;
+					width: 112rpx;
+					height: 56rpx;
+					line-height: 56rpx;
+					text-align: center;
+					background: #F0FAFF;
+					border-radius: 8rpx 8rpx 8rpx 8rpx;
+					font-size: 24rpx;
+					color: #008FD3;
+				}
+				.add-tag{
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					width: 160rpx;
+					height: 56rpx;
+					background: #FFFFFF;
+					border-radius: 8rpx 8rpx 8rpx 8rpx;
+					border: 1rpx solid #008FD3;
+					font-size: 22rpx;
+					color: #008FD3;
+					image{
+						margin-right: 8rpx;
+					}
+				}
+			}
+			.demands{
+				.title{
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #222426;
+					padding:28rpx 0;
+				}
+				.text{
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #898E91;
+				}
+			}
+			.msg-box{
+				width: 144rpx;
+				height: 56rpx;
+				line-height: 56rpx;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #FFFFFF;
+				text-align: center;
+				background: linear-gradient( 90deg, #FEA501 0%, #FECB8A 100%);
+				border-radius: 28rpx 28rpx 28rpx 28rpx;
+				border: 1rpx solid #FEDDB9;
+			}
+		}
+		.used-tools2{
+			box-sizing: border-box;
+			background: #FFFFFF;
+			border-radius: 16upx;
+			padding: 40upx 30upx;
+			margin-bottom: 20rpx;
+			.title{
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #222222;
+				line-height: 1;
+			}
+			.tools-list{
+				margin-top: 50upx;
+				display: flex;
+				flex-wrap: wrap;
+				width: 100%;
+				.item{
+					box-sizing: border-box;
+					width: 25%;
+					display: flex;
+					flex-direction: column;
+					align-items: center;
+					justify-content: center;
+					margin-bottom: 50upx;
+					position: relative;
+					image{
+						width: 44upx;
+						height: 44upx;
+					}
+					.text{
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #111111;
+						line-height: 1;
+						margin-top: 20upx;
+					}
+					.contact-btn{
+						display: inline-block;
+						position: absolute;
+						top: 0;
+						left: 0;
+						width: 100%;
+						height: 100%;
+						opacity: 0;
+					}
+				}
+				.remark{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #898E91;
+					text-align: left;
+				}
+			}
+			.index-box{
+				margin-top: 30rpx;
+				display: flex;
+				    align-items: center;
+				    justify-content: space-between;
+				.box-title{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+					margin: 0 14rpx;
+				}
+				.prop{
+					font-family: Roboto Slab;
+					font-weight: 500;
+					font-size: 48rpx;
+					color: #222426;
+				}
+				.task{
+					width: 311rpx;
+					height: 142rpx;
+					background: #EBF8FF;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+					display: flex;
+					    flex-direction: column;
+					    justify-content: center;
+					    align-items: center;
+				}
+				.work{
+					width: 311rpx;
+					height: 142rpx;
+					background: #FFF3DE;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+					display: flex;
+					    flex-direction: column;
+					    justify-content: center;
+					    align-items: center;
+				}
+			}
+		}
+		.log-out{
+			height: 80upx;
+			line-height: 80upx;
+			text-align: center;
+			font-size: 28upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+			background: #FFFFFF;
+			border-radius: 16upx;
+			margin-top: 20upx;
+		}
+	}
+</style>

+ 372 - 0
pages_company/clientList.vue

@@ -0,0 +1,372 @@
+<template>
+	<view class="content">
+		<view class="top-bg">
+				<view class="top-title">我的下级人数</view>
+				<view class="num">285</view>
+		</view>
+		<view class="search-cont">
+			<view class="inner">
+				<image class="icon-search" src="/static/images/search.png" mode=""></image>
+				<input type="text" value="" placeholder="搜索名称或编号" confirm-type="搜索"   placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+			</view>
+			<view class="btn-serach" @click="goSearch" >搜索</view>
+		</view>
+		<view class="top-title">下级列表</view>
+		<!-- 订单列表 -->
+		<mescroll-body ref="mescrollRef" :up="upOption">
+			<view class="client-list">
+				<view v-for="(item,index) in dataList" :key="index" class="item"  @click="showDetail()">
+					<view class="top-box">
+						<image :src="item.img==null?'../static/images/health/my_heads.png':item.img" mode="aspectFill"></image>
+						<view class="right">
+							<view class="name">{{item.name}}</view>
+							<view class="align-end">
+								<view class="proxy">
+									<view class="title">代理价格</view>
+									<view class="price">¥{{item.proxyPrice.toFixed(2)}}</view>
+								</view>
+								<view class="sale">
+									<view class="title">销售价格</view>
+									<view class="price">¥{{item.salePrice.toFixed(2)}}</view>
+								</view>
+							</view>
+							<view class="phone">手机号:{{item.phone}}</view>
+							<view class="time">注册时间:{{item.createTime}}</view>
+						</view>
+					</view>
+					<view class="btn-box">
+						<view  class="btn-proxy" @click.stop="showDetail(item)">
+							设置代理价格
+						</view>
+						<view  class="btn-sale" @click.stop="showDetail(item)">
+							设置销售价格
+						</view>
+					</view>
+				</view>
+			</view>
+		</mescroll-body>
+	</view>
+</template>
+
+<script>
+	import {getCompanyStoreOrderList} from '@/api/storeOrder'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				searchKey:"",
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{name:'西航宇',phone:'18056647845',proxyPrice:0.8,salePrice:0.6,createTime:'2025-06-10 14:20',img:'/static/images/health/my_heads.png'},
+					{name:'蓝西',phone:'18056647845',proxyPrice:1.0,salePrice:0.8,createTime:'2025-07-10 14:20',img:'/static/images/health/female_profile.png'}
+				],
+			};
+		},
+		onLoad(options) {
+			var that=this;
+			// uni.$on('refreshOrder', () => {
+			// 	that.mescroll.resetUpScroll()
+			// })
+			this.companyId=options.companyId;
+			this.companyUserId=options.companyUserId;
+		},
+		methods: {
+			goSearch(e) {
+				this.searchKey=e.detail.value;
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					keyword:this.searchKey,
+					companyId:this.companyId,
+					companyUserId:this.companyUserId,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getCompanyStoreOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item) {
+				uni.navigateTo({
+					url: './clientDetail?id=' 
+				})
+			},
+			// cancel(item){
+			// 	var that=this;
+			// 	uni.showModal({
+			// 	    title: '提示',
+			// 	    content: '确定取消订单吗',
+			// 	    success: function (res) {
+			// 	        if (res.confirm) {
+			// 				var data = {
+			// 					orderId:item.id
+			// 				};
+			// 				cancelOrder(data).then(res => {
+			// 					if(res.code==200){
+			// 						uni.showToast({
+			// 							icon:'success',
+			// 							title: "操作成功",
+			// 						});
+			// 						 that.mescroll.resetUpScroll()
+			// 					}else{
+			// 						uni.showToast({
+			// 							icon:'none',
+			// 							title: res.msg,
+			// 						});
+			// 					}
+			// 				});
+			// 	        } 
+			// 			else if (res.cancel) {
+			// 	        }
+			// 	    }
+			// 	});
+			// },
+			// pay(item) {
+			// 	 uni.navigateTo({
+			// 	 	url: '../shopping/paymentOrder?orderId='+item.id
+			// 	 })
+			// },
+			// 查看物流
+			// showDelivery(item) {
+			// 	uni.navigateTo({
+			// 		url: './storeOrderDelivery?orderId='+item.id
+			// 	})
+			// }
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding:20upx;
+	}
+	.top-bg{
+		background: linear-gradient( 266deg, #FEA603 0%, #E83924 100%);
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		padding: 30rpx;
+		margin-bottom: 30rpx;
+		.top-title{
+			font-family: PingFang SC;
+			font-weight: 500;
+			font-size: 28rpx;
+			color: #FFFFFF;
+			text-align: left;
+		}
+		.num{
+			font-family: Roboto;
+			font-weight: 500;
+			font-size: 64rpx;
+			color: #FFFFFF;
+			text-align: left;
+		}
+	}
+	.search-cont{
+		// padding: 16upx 30upx;
+		// background-color: #FFFFFF;
+		display: flex;
+		align-items: center;
+		justify-content:space-between;
+		.inner{
+			box-sizing: border-box;
+			width: 80%;
+			height: 64rpx;
+			background: #fff;
+			border-radius: 32upx;
+			display: flex;
+			align-items: center;
+			padding: 0 30upx;
+			.icon-search{
+				width: 28upx;
+				height: 28upx;
+				margin-right: 20upx;
+			}
+			input{
+				height: 60upx;
+				line-height: 60upx;
+				flex: 1;
+			}
+		}
+		.btn-serach{
+			width: 112rpx;
+			height: 64rpx;
+			line-height: 64rpx;
+			text-align: center;
+			font-weight: 600;
+			font-size: 24rpx;
+			color: #fff;
+			background: #008FD3;
+			border-radius: 34rpx 34rpx 34rpx 34rpx;
+		}
+	}
+	.top-title{
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 600;
+		font-size: 36rpx;
+		color: #222426;
+		text-align: left;
+		padding:22rpx ;
+	}
+	.client-list{
+		.item{
+			background: #fff;
+			border-radius: 0rpx 0rpx 0rpx 0rpx;
+			padding: 30rpx;
+			margin-bottom: 20rpx;
+			.top-box{
+				padding-bottom: 30rpx;
+				display: flex;
+				align-items: flex-start;
+				border-bottom: 1rpx solid #ECECEC;
+				image{
+					width: 112rpx;
+					height: 112rpx;
+					background: #EAEAEA;
+					border-radius:50%;
+					margin-right: 22rpx;
+				}
+				.right{
+					display: flex;
+					flex-direction: column;
+					justify-content: space-between;
+					.name{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 32rpx;
+						color: #222426;
+						text-align: left;
+						margin-bottom: 10rpx;
+					}
+					.proxy{
+						// width: 166rpx;
+						// height: 36rpx;
+						border-radius: 4rpx 4rpx 4rpx 4rpx;
+						border: 1rpx solid #008FD3;
+						display: flex;
+						    align-items: center;
+							margin-right: 16rpx;
+						.title{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 20rpx;
+							color: #FFFFFF;
+							background: #008FD3;
+							padding: 8rpx;
+						}
+						.price{
+							font-weight: 500;
+							font-size: 20rpx;
+							color: #008FD3;
+							padding: 4rpx 12rpx;
+						}
+					}
+					.sale{
+						// width: 166rpx;
+						// height: 36rpx;
+						border-radius: 4rpx 4rpx 4rpx 4rpx;
+						border: 1rpx solid #FF5030;
+						display: flex;
+						    align-items: center;
+						.title{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 20rpx;
+							color: #FFFFFF;
+							background: #FF5030;
+							padding: 8rpx;
+						}
+						.price{
+							font-weight: 500;
+							font-size: 20rpx;
+							color: #FF5030;
+							padding: 4rpx 12rpx;
+						}
+					}
+					.phone,.time{
+						font-family: PingFang SC;
+						font-weight: 400;
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						margin-top: 16rpx;
+					}
+				}
+				
+			}
+			.btn-box{
+				padding-top: 30rpx;
+				display: flex;
+				align-items: center;
+				justify-content: flex-end;
+				.btn-proxy{
+					width: 224rpx;
+					height: 60rpx;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #FFFFFF;
+	                text-align: center;
+					line-height:60rpx;
+					background: #008FD3;
+					border-radius: 30rpx 30rpx 30rpx 30rpx;
+					margin-right: 16rpx;
+				}
+				.btn-sale{
+					width: 224rpx;
+					height: 60rpx;
+					font-weight: 400;
+					font-size: 24rpx;
+					text-align: center;
+					line-height:60rpx;
+					color: #FFFFFF;
+					background: #FF5030;
+					border-radius: 30rpx 30rpx 30rpx 30rpx;
+				}
+			}
+		}
+	}
+	
+</style>

+ 425 - 0
pages_company/executionRecord.vue

@@ -0,0 +1,425 @@
+<template>
+	<view class="content">
+		<ren-calendar ref='ren' :markDays='markDays' :headerBar='false' :open="false" @onDayClick='onDayClick'></ren-calendar>
+		<view class="inner">
+			<view class="title-box align-center justify-between">
+				<text>用药情况</text>
+				<view class="select-box" @click="navgetTo()">
+					<text>打卡 (0/2)</text>
+					<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+				</view>
+			</view>
+			<view class="form-box">
+				<view class="form-item">
+					<view class="left">
+						<text class="label">阿仑单抗 1.0mg</text>
+						<text class="time">11:30</text>
+					</view>
+					<view class="check">
+						<u-icon name="checkmark-circle-fill" color="#008FD3" size="18"></u-icon>
+						<text>已用药</text>
+					</view>
+				</view>
+			</view>
+			<view class="title-box">
+				健康数据
+			</view>
+			<view class="form-box">
+				<view class="form-item">
+					<text class="label">腰围</text>
+					<view class="num">
+						<text>70cm</text>
+						<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">臀围</text>
+					<view class="num">
+						<text>70cm</text>
+						<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">血糖</text>
+					<view class="num">
+						<text>4.0</text>
+						<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">血压</text>
+					<view class="num">
+						<text>--</text>
+						<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">尿酸</text>
+					<view class="num">
+						<text>正常</text>
+						<image class="w48 h48" src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</view>
+			<view class="title-box align-center justify-between">
+				<text class="left">指标信息</text>
+				<view class="select-box2">
+					<image class="w24 h24" src="@/static/images/company/edit_add_icon.png"></image>
+					<text>选择指标项</text>
+				</view>
+			</view>
+			<view class="form-box">
+				<view class="form-item">
+					<text class="label">促甲状腺素受体抗体(A-TSHR)</text>
+					<view class="num">
+						<text>2.12 1U/L</text>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">低密度脂蛋白胆固醇(LDL)</text>
+					<view class="num">
+						<text>3.00 mmol/L</text>
+					</view>
+				</view>
+			</view>
+			<view class="title-box">
+				其他
+			</view>
+			<view class="form-box mb20">
+				<view class="form-item">
+					<text class="label">口感舌燥,恶心</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import RenCalendar from '@/components/ren-calendar/ren-calendar.vue'
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		components:{
+		            RenCalendar
+		        },
+		data() {
+			return {
+				curDate:'',
+				markDays:[],
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			let today = this.$refs.ren.getToday().date;
+			            this.curDate = today;
+			            this.markDays.push(today);
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			//日历
+			onDayClick(data){
+			                this.curDate = data.date;
+			            },
+			navgetTo(){
+				uni.navigateTo({
+					url:'/pages_company/schedule'
+				})
+			},
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			submit() {
+				if (this.form.userName == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "姓名不能为空",
+					});
+					return;
+				}
+				if (this.form.idCard == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "身份证号不能为空",
+					});
+					return;
+				}
+				if (this.form.sex == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "性别不能为空",
+					});
+					return;
+				}
+				if (this.form.birthday == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "出生年月不能为空",
+					});
+					return;
+				}
+				if (this.type == "add") {
+					this.addDoc()
+				} else if (this.type == "edit") {
+					this.editDoc()
+				}
+
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding:0 20upx;
+            .title-box{
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 500;
+				font-size: 32rpx;
+				color: #626468;
+				padding: 24rpx 0;
+               .select-box{
+               	display: flex;
+               	align-items: center;
+				justify-content: center;
+               	text{
+               		font-family: PingFang SC;
+               		font-weight: 400;
+               		font-size: 24rpx;
+               		color: #626468;
+               		margin-left: 8rpx;
+               	}
+               }
+			   .select-box2{
+			   	width: 216rpx;
+			   	height: 64rpx;
+			   	background: #FFFFFF;
+			   	border-radius: 32rpx 32rpx 32rpx 32rpx;
+			   	display: flex;
+			   	align-items: center;
+			   				justify-content: center;
+			   	text{
+			   		font-family: PingFang SC;
+			   		font-weight: 400;
+			   		font-size: 24rpx;
+			   		color: #626468;
+			   		margin-left: 5rpx;
+			   	}
+			   }
+				
+			}
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				// margin-bottom: 20upx;
+                
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #626468;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+                    .left{
+						display: flex;
+						flex-direction: column;
+						align-items: flex-start;
+						.time{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 28rpx;
+							color: #898E91;
+							text-align: left;
+						}
+					}
+					.check{
+						
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						text{
+							// font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #008FD3;
+							margin-left: 16rpx;
+						}
+					}
+					.label {
+						// width: 150upx;
+						text-align: left;
+						font-weight: 500;
+						font-size: 32rpx;
+						color: #222426;
+						text-align: left;
+					}
+                    .num{
+						font-family: PingFang SC;
+						font-weight: 400;
+						font-size: 32rpx;
+						color: #222426;
+						line-height: 34rpx;
+						display: flex;
+						align-items: center;
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			// position: fixed;
+			// width: 90%;
+			// bottom: 0;
+			// left: 50%;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+	}
+</style>

+ 302 - 40
pages_company/index.vue

@@ -1,7 +1,12 @@
 <template>
 	<view class="top-cont">
+		<image class="bg" src="/static/images/company/sales_management_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="销售管理" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
 		<view class="content">
-			<view class="user-info">
+			<!-- <view class="user-info">
 				<view class="left">
 					<view class="name-phone">
 						<view class="name">{{user.nickName}}</view>
@@ -11,9 +16,9 @@
 				<view class="msg-box"  >
 					 {{user.deptName}}
 				</view>
-			</view>
+			</view> -->
 			<!-- 常用工具 -->
-			<view class="used-tools">
+		<!-- 	<view class="used-tools">
 				<view class="title">常用工具</view>
 				<view class="tools-list">
 					<view class="item" @click="toCreateOrder()">
@@ -45,6 +50,75 @@
 						<text class="text">套餐优惠券</text>
 					</view>
 					 
+				</view>
+			</view> -->
+			<view class="user-info2">
+				<view class="left">
+					<view class="head-img">
+						<image :src="user.avatar==null?'../static/images/health/my_heads.png':user.avatar" mode="aspectFill"></image>
+					</view>
+					<view class="name-phone">
+						<view class="align-end">
+							<view class="name">{{user.nickName}}</view>
+							<image class="w48 h48" src="../static/images/company/right_arrow_black_icon24.png" mode=""></image>
+						</view>
+						<view class="phone-box" v-if="user!=null">
+							<image class="w32 h32" src="../static/images/company/phone_icon16.png" mode=""></image>
+							<view class="phone">
+								{{utils.parsePhone(user.phonenumber)}}
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="msg-box">
+					 {{user.deptName}}
+				</view>
+			</view>
+			<view class="used-tools2">
+				<view class="title">指标汇总</view>
+				<view class="index-box">
+					<view class="task">
+						<view class="align-center">
+							<image class="w48 h48" src="../static/images/company/appointed_task_icon.png" mode=""></image>
+							<view class="box-title">指派任务</view>
+							<image class="w24 h24" src="../static/images/company/right_arrow_right_icon.png" mode=""></image>
+						</view>
+						<view class="prop">80%</view>
+					</view>
+					<view class="work">
+						<view class="align-center" @click="navgetTo('/pages_company/addSchedule')">
+							<image class="w48 h48" src="../static/images/company/work_item_icon.png" mode=""></image>
+							<view class="box-title">工作事项</view>
+						<image class="w24 h24" src="../static/images/company/right_arrow_right_icon.png" mode=""></image>
+						</view>
+						<view class="prop">30%</view>
+					</view>
+				</view>
+			</view>
+			<view class="used-tools2">
+				<view class="title">常用工具</view>
+				<view class="tools-list">
+					<view class="item" @click="navgetTo('/pages_user/user/userTui')">
+						<image src="../static/images/company/my_promotion_icon.png" mode=""></image>
+						<text class="text">我的推广</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_company/todoList')">
+						<image src="../static/images/company/to_do_list_icon.png" mode=""></image>
+						<text class="text">待办事项</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_company/clientList')">
+						<image src="../static/images/company/customer_profile_icon.png" mode=""></image>
+						<text class="text">客户档案</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_user/user/userTui')">
+						<image src="../static/images/company/manager_examine_icon.png" mode=""></image>
+						<text class="text">管理师考核</text>
+					</view>
+					<view class="item" @click="navgetTo('/pages_user/user/userTui')">
+						<image src="../static/images/company/customer_complaints_icon.png" mode=""></image>
+						<text class="text">客户投诉</text>
+					</view>
+					 
 				</view>
 			</view>
 			<!-- 退出登录按钮 -->
@@ -59,18 +133,37 @@
 	export default {
 		data() {
 			return {
-				 user:null,
+				statusBarHeight:'',
+				top:0,
+				user:{
+					nickName:'健康管家小左',
+					phonenumber:'13996660261',
+					deptName:'测试企业',
+					avatar:null
+				},
+				 // user:null,
 			};
 		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
 		onLoad() {
 			console.log("onload")
 		},
 		onShow() {
 			console.log("onshow")
-			this.getUserInfo()
+			// this.getUserInfo()
 		},
 		methods: {
-			
+			navgetTo(url){
+				uni.navigateTo({
+					url:url
+				})
+			},
 			alipay(){
 				// var url="http://alipay.yjf.runtzh.com/#/?companyId="+this.user.companyId+"&companyUserId="+this.user.userId
 				// uni.setClipboardData({
@@ -170,34 +263,148 @@
 			 },
 			 
 			// 跳转页面
-			navgetTo(url) {
-				this.utils.isLogin().then(res => {
-					if(res){
-						uni.navigateTo({
-							url: url
-						})
-					}
-				})
-			},
+			// navgetTo(url) {
+			// 	this.utils.isLogin().then(res => {
+			// 		if(res){
+			// 			uni.navigateTo({
+			// 				url: url
+			// 			})
+			// 		}
+			// 	})
+			// },
 		}
 	}
 </script>
 
 <style lang="scss">
+	.bg {
+		width: 100%;
+		height: 380rpx;
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: -1;
+	}
 	.content{
+		padding-top: calc(var(--status-bar-height) + 140rpx) !important;
 		margin: 20upx 0upx;
-		padding: 0 20upx;
-		.user-info{
-			padding: 30upx;
+		padding:20upx;
+		// .user-info{
+		// 	padding: 30upx;
+		// 	display: flex;
+		// 	align-items: center;
+		// 	justify-content: space-between;
+		// 	.left{
+		// 		position: relative;
+		// 		display: flex;
+		// 		.head-img{
+		// 			width: 120upx;
+		// 			height: 120upx;
+		// 			border-radius: 50%;
+		// 			overflow: hidden;
+		// 			margin-right: 30upx;
+		// 			border: 4upx solid #FFFFFF;
+		// 			box-shadow: 0px 5px 15px 2px rgba(0,0,0,0.1);
+		// 			image{
+		// 				width: 100%;
+		// 				height: 100%;
+		// 			}
+		// 		}
+		// 		.name-phone{
+		// 			padding-top: 15upx;
+		// 			.name{
+		// 				font-size: 36upx;
+		// 				font-family: PingFang SC;
+		// 				font-weight: bold;
+		// 				color: #111111;
+		// 				line-height: 1;
+		// 			}
+		// 			.phone{
+		// 				font-size: 28upx;
+		// 				font-family: PingFang SC;
+		// 				font-weight: 500;
+		// 				color: #666666;
+		// 				line-height: 1;
+		// 				margin-top: 30upx;
+		// 			}
+		// 		}
+		// 	}
+		// 	.msg-box{
+		// 		padding: 5rpx 15upx;
+		// 		height: 30upx;
+		// 		line-height: 30upx;
+		// 		font-size: 22upx;
+		// 		font-family: PingFang SC;
+		// 		font-weight: 500;
+		// 		color: #FFFFFF;
+		// 		border-radius: 8rpx;
+		// 		background-color: #0bb3f2;
+		// 	}
+		// }
+		// .used-tools{
+		// 	box-sizing: border-box;
+		// 	background: #FFFFFF;
+		// 	border-radius: 16upx;
+		// 	padding: 40upx 30upx;
+			
+		// 	.title{
+		// 		font-size: 32upx;
+		// 		font-family: PingFang SC;
+		// 		font-weight: bold;
+		// 		color: #222222;
+		// 		line-height: 1;
+		// 	}
+		// 	.tools-list{
+		// 		margin-top: 50upx;
+		// 		display: flex;
+		// 		flex-wrap: wrap;
+		// 		width: 100%;
+		// 		.item{
+		// 			box-sizing: border-box;
+		// 			width: 25%;
+		// 			display: flex;
+		// 			flex-direction: column;
+		// 			align-items: center;
+		// 			justify-content: center;
+		// 			margin-bottom: 50upx;
+		// 			position: relative;
+		// 			image{
+		// 				width: 44upx;
+		// 				height: 44upx;
+		// 			}
+		// 			.text{
+		// 				font-size: 24upx;
+		// 				font-family: PingFang SC;
+		// 				font-weight: 500;
+		// 				color: #111111;
+		// 				line-height: 1;
+		// 				margin-top: 20upx;
+		// 			}
+		// 			.contact-btn{
+		// 				display: inline-block;
+		// 				position: absolute;
+		// 				top: 0;
+		// 				left: 0;
+		// 				width: 100%;
+		// 				height: 100%;
+		// 				opacity: 0;
+		// 			}
+		// 		}
+		// 	}
+		// }
+		.user-info2{
+			// padding: 30upx;
+			margin-bottom: 30rpx;
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
+			margin-bottom: 20rpx;
 			.left{
 				position: relative;
 				display: flex;
 				.head-img{
-					width: 120upx;
-					height: 120upx;
+					width: 128upx;
+					height: 128upx;
 					border-radius: 50%;
 					overflow: hidden;
 					margin-right: 30upx;
@@ -209,42 +416,58 @@
 					}
 				}
 				.name-phone{
-					padding-top: 15upx;
+					// padding-top: 15upx;
+					display: flex;
+					flex-direction: column;
+					justify-content:center;
 					.name{
-						font-size: 36upx;
+						font-size: 40upx;
 						font-family: PingFang SC;
 						font-weight: bold;
 						color: #111111;
-						line-height: 1;
+						// line-height: 1;
 					}
-					.phone{
-						font-size: 28upx;
-						font-family: PingFang SC;
-						font-weight: 500;
-						color: #666666;
-						line-height: 1;
-						margin-top: 30upx;
+					.phone-box{
+						width: 220rpx;
+						height: 48rpx;
+						background: #008FD3;
+						border-radius: 24rpx 24rpx 24rpx 24rpx;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						margin-top: 14rpx;
+						.phone{
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #FFFFFF;
+							line-height: 36rpx;
+							margin-left: 6rpx;
+						}
 					}
+					
 				}
 			}
 			.msg-box{
-				padding: 5rpx 15upx;
-				height: 30upx;
-				line-height: 30upx;
-				font-size: 22upx;
+				width: 144rpx;
+				height: 56rpx;
+				line-height: 56rpx;
 				font-family: PingFang SC;
-				font-weight: 500;
+				font-weight: 400;
+				font-size: 24rpx;
 				color: #FFFFFF;
-				border-radius: 8rpx;
-				background-color: #0bb3f2;
+				text-align: center;
+				background: linear-gradient( 90deg, #FEA501 0%, #FECB8A 100%);
+				border-radius: 28rpx 28rpx 28rpx 28rpx;
+				border: 1rpx solid #FEDDB9;
 			}
 		}
-		.used-tools{
+		.used-tools2{
 			box-sizing: border-box;
 			background: #FFFFFF;
 			border-radius: 16upx;
 			padding: 40upx 30upx;
-			
+			margin-bottom: 20rpx;
 			.title{
 				font-size: 32upx;
 				font-family: PingFang SC;
@@ -289,12 +512,51 @@
 					}
 				}
 			}
+			.index-box{
+				margin-top: 30rpx;
+				display: flex;
+				    align-items: center;
+				    justify-content: space-between;
+				.box-title{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+					margin: 0 14rpx;
+				}
+				.prop{
+					font-family: Roboto Slab;
+					font-weight: 500;
+					font-size: 48rpx;
+					color: #222426;
+				}
+				.task{
+					width: 311rpx;
+					height: 142rpx;
+					background: #EBF8FF;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+					display: flex;
+					    flex-direction: column;
+					    justify-content: center;
+					    align-items: center;
+				}
+				.work{
+					width: 311rpx;
+					height: 142rpx;
+					background: #FFF3DE;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+					display: flex;
+					    flex-direction: column;
+					    justify-content: center;
+					    align-items: center;
+				}
+			}
 		}
 		.log-out{
 			height: 80upx;
 			line-height: 80upx;
 			text-align: center;
-			font-size: 26upx;
+			font-size: 28upx;
 			font-family: PingFang SC;
 			font-weight: 500;
 			color: #666666;

+ 377 - 0
pages_company/returnRecord.vue

@@ -0,0 +1,377 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view 
+						v-for="(item,index) in orderStatus" 
+						:key="index"
+						:class="item.val == showType?'item active':'item'"
+						@click="orderStatusChange(item)"
+					>
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+			<mescroll-body top="88upx" ref="mescrollRef">
+				<view class="phone-list" v-if="showType==1">
+				<view v-for="(item,index) in dataList" :key="index" class="item" >
+					<image src="/static/images/company/deenergize_icon.png" class="w32 h32"></image>
+				    <view class="phone-name">
+						 <view class="justify-between align-center" style="width: 100%;">
+							 <view class="name">{{item.name}}</view>
+							 <view class="type">去电</view>
+						 </view>
+						 <view class="time">{{item.time}}</view>
+					 </view>
+				</view>
+				</view>
+				<view class="sms-list" v-if="showType==2">
+				<view v-for="(item,index) in dataList2" :key="index" class="item" >
+					<view class="title">{{item.content}}</view>
+				    <view class="box">
+						 <view class="time">{{item.time}}</view>
+						 <view class="state">{{item.state}}</view>
+					 </view>
+				</view>
+				</view>
+			</mescroll-body>
+		<view class="btn-box2">
+			<view v-if="showType==1" class="sub-btn" @click="navgetTo(orderStatusValue)">
+				<image src="/static/images/company/make_phone_call_icon.png" class="w48 h48"></image>
+				<text>拨打电话</text>
+			</view>
+			<view v-if="showType==2" class="sub-btn" @click="navgetTo(orderStatusValue)">
+				<image src="/static/images/company/send_SMS_icon.png" class="w48 h48"></image>
+				<text>发送短信</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				orderStatus:[
+					{name:"电话记录",val:1},
+					{name:"短信记录",val:2},
+				],
+				showType:1,
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{orderId:1, name:'今日 11:22',time:'4分16秒'},
+					{orderId:2, name:'昨天 09:16',time:'4分16秒'},
+					{orderId:3, name:'1月12 13:06',time:'4分16秒'}
+				],
+				dataList2: [
+					{orderId:1,content:'服用胰岛素口服液 规格20mg*20 每次1片1日一次 用法口服',state:'已送达',time:'2025-2-20 10:29',},
+					{orderId:2,content:'服用胰岛素口服液 规格20mg*20 每次1片1日一次 用法口服',state:'已送达',time:'2025-2-20 10:29',},
+					{orderId:3,content:'服用胰岛素口服液 规格20mg*20 每次1片1日一次 用法口服',state:'已送达',time:'2025-2-20 10:29',}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			pay(item){
+				uni.navigateTo({
+					url: '/pages_/doctor/paymentOrder?orderId='+item.orderId
+				})
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.showType = item.val
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.showType,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item) {
+				if(item.orderType==1){
+					uni.navigateTo({
+						url: '/pages_doctor/doctorOrderIM?orderId='+item.orderId
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 40upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				overflow-x: auto;
+			}
+			.item{
+				flex:1;
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #626468;
+				// margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color:#008FD3;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.btn-box2{
+			z-index: 9999;
+			width: 100%;
+			padding: 30upx;
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			box-sizing: border-box;
+			// background: #FFFFFF;
+			
+			 
+			.sub-btn{
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+	   .phone-list{
+		   padding: 30rpx;
+		   background: #FFFFFF;
+		   border-radius: 16rpx 16rpx 16rpx 16rpx;
+		   .item{
+			   display: flex;
+			   align-items: flex-start;
+			   border-bottom: 1rpx solid #ECECEC;
+			   padding-bottom: 30rpx;
+			   margin-bottom: 30rpx;
+			   &:last-child{
+				   border-bottom: 0;
+				    margin-bottom: 0;
+					padding-bottom: 0;
+			   }
+			   .phone-name{
+				   display: flex;
+				   flex-direction: column;
+				   align-items: flex-start;
+				   justify-content: flex-start;
+				   padding-left: 24rpx;
+				       flex: 1;
+				   .name{
+				   				   font-family: PingFang SC;
+				   				   font-weight: 500;
+				   				   font-size: 32rpx;
+				   				   color: #222426;
+				   				   text-align: left;
+				   }
+				   .type{
+					   font-family: PingFang SC;
+					   font-weight: 400;
+					   font-size: 28rpx;
+					   color: #626468;
+					   text-align: right;
+				   }
+				   .time{
+					   font-family: PingFang SC;
+					   font-weight: 400;
+					   font-size: 28rpx;
+					   color: #898E91;
+					   text-align: left;
+					   margin-top: 14rpx;
+				   }
+			   }
+			   
+		   }
+	   }
+	   .sms-list{
+		   .item{
+			   padding: 30rpx;
+			   background: #FFFFFF;
+			   border-radius: 16rpx 16rpx 16rpx 16rpx;
+			   margin-bottom: 20rpx;
+			   .title{
+				   font-family: PingFang SC;
+				   font-weight: 500;
+				   font-size: 32rpx;
+				   color: #222426;
+				   text-align: left;
+			   }
+			   .box{
+				   display: flex;
+				   align-items: center;
+				   justify-content: space-between;
+				   padding-top: 22rpx;
+				   .time{
+					   font-family: PingFang SC;
+					   font-weight: 400;
+					   font-size: 24rpx;
+					   color: #898E91;
+					   text-align: left;
+				   }
+				   .state{
+					   font-family: PingFang SC;
+					   font-weight: 400;
+					   font-size: 24rpx;
+					   color: #2CAE5C;
+					   text-align: right;
+				   }
+			   }
+		   }
+	   }
+		
+	}
+</style>

+ 346 - 0
pages_company/schedule.vue

@@ -0,0 +1,346 @@
+<template>
+	<view class="content">
+		<ren-calendar ref='ren' :markDays='markDays' :headerBar='false'  @onDayClick='onDayClick'></ren-calendar>
+		<view class="inner">
+			<view class="title-box align-center">
+				<text>我的行程</text>
+				<view class="num">(3)</view>
+			</view>
+			<view class="form-box">
+				<u-swipe-action>
+					<view class="form-swipe mb20" v-for="(item,index) in dataList" :key="index">
+				        <u-swipe-action-item :options="options"  @click="action()"> 
+				         <view class="form-item">
+				         	<view class="left">
+				         		<text class="label">已开始</text>
+				         		<text class="time">{{item.time}}</text>
+				         	</view>
+				         	<view class="right">
+				         		<view>{{item.content}}</view>
+				         	</view>
+				         </view>
+				        </u-swipe-action-item>
+						</view>
+				      </u-swipe-action>
+				
+			</view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="addSchedule()">
+					<image class="w32 h32" src="@/static/images/company/add_icon.png"></image>
+					<text>添加日程</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import RenCalendar from '@/components/ren-calendar/ren-calendar.vue'
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		components:{
+		            RenCalendar
+		        },
+		data() {
+			return {
+				 options: [{
+				                    text: '修改',
+				                    style: {
+				                        backgroundColor: '#008FD3'
+				                    }
+				                }, {
+				                    text: '删除',
+				                    style: {
+				                        backgroundColor: '#FF5030'
+				                    }
+				                }],
+				curDate:'',
+				markDays:[],
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				dataList:[{id:1,time:'09:00',content:'酒店登记入驻,记得检查马桶卫生和柏子是否干净'},
+				{id:2,time:'09:00',content:'收拾好行李,准备去医院'},
+				{id:3,time:'16:30',content:'酒店登记入驻,记得检查马桶卫生和柏子是否干净'},
+				],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			let today = this.$refs.ren.getToday().date;
+			            this.curDate = today;
+			            this.markDays.push(today);
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			//日历
+			onDayClick(data){
+			                this.curDate = data.date;
+			            },
+			action(e){
+				console.log(e,'--')
+			},
+			addSchedule(){
+				uni.navigateTo({
+					url: '/pages_company/addSchedule'
+				})
+			},
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			submit() {
+				if (this.form.userName == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "姓名不能为空",
+					});
+					return;
+				}
+				if (this.form.idCard == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "身份证号不能为空",
+					});
+					return;
+				}
+				if (this.form.sex == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "性别不能为空",
+					});
+					return;
+				}
+				if (this.form.birthday == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "出生年月不能为空",
+					});
+					return;
+				}
+				if (this.type == "add") {
+					this.addDoc()
+				} else if (this.type == "edit") {
+					this.editDoc()
+				}
+
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+		background: #FFFFFF;
+	}
+.u-swipe-action-item__right__button__wrapper__text{
+	font-size: 28rpx !important;
+	line-height: 28rpx !important;
+}
+	.content {
+		height: 100%;
+		// display: flex;
+		// flex-direction: column;
+		// justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding:30upx;
+			background: #FFFFFF;
+			border-radius:16rpx  16rpx  16rpx  16rpx;
+			margin-top:-20rpx;
+			position: relative;
+            .title-box{
+				text{
+					font-family: PingFang SC, PingFang SC;
+					font-weight: 600;
+					font-size: 36rpx;
+					color: #222426;
+					padding: 24rpx 0;
+					
+				}
+				.num{
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #898E91;
+				}
+               
+               }
+			   .select-box2{
+			   	width: 216rpx;
+			   	height: 64rpx;
+			   	background: #FFFFFF;
+			   	border-radius: 32rpx 32rpx 32rpx 32rpx;
+			   	display: flex;
+			   	align-items: center;
+			   				justify-content: center;
+			   	text{
+			   		font-family: PingFang SC;
+			   		font-weight: 400;
+			   		font-size: 24rpx;
+			   		color: #626468;
+			   		margin-left: 5rpx;
+			   	}
+			   }
+				
+			}
+			.form-box {
+				// padding:30upx;
+				// background: #FFFFFF;
+				// border-radius: 16upx;
+				.form-swipe{
+					overflow: hidden;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+				}
+				.form-item {
+					padding: 30upx;
+					display: flex;
+					align-items: center;
+					// justify-content: space-between;
+					background: #F5F7FA;
+					
+                    .left{
+						display: flex;
+						flex-direction: column;
+						align-items: center;
+						padding-right: 30rpx;
+						border-right: 1px solid #CCCCCC;
+						.label{
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #626468;
+						}
+						.time{
+							font-family: PingFang SC;
+							font-weight: 500;
+							font-size: 48rpx;
+						}
+						
+					}
+					.right{
+						padding-left: 30rpx;
+						view{
+							font-weight: 400;
+							font-size: 24rpx;
+							color: #222426;
+							text-align: left;
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			// display: flex;
+			// align-items: center;
+			// justify-content: center;
+
+			position: fixed;
+			right: 20rpx;
+			bottom: 20%;
+			z-index: 999;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				width: 192rpx;
+				height: 80rpx;
+				background: #008FD3;
+				box-shadow: 0rpx 6rpx 10rpx 0rpx rgba(0,143,211,0.2);
+				border-radius: 40rpx 40rpx 40rpx 40rpx;
+				text{
+					color: #fff;
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #FFFFFF;
+				}
+			}
+		}
+	}
+</style>

+ 429 - 0
pages_company/testRecord.vue

@@ -0,0 +1,429 @@
+<template>
+	<view class="content">
+		<view class="consu-list">
+			<mescroll-body  ref="mescrollRef">
+				<view v-for="(item,index) in dataList" :key="index" class="item" >
+					<view class="item-top">
+						<image src="@/static/images/71014b69fdcc4b56ae2a84bdc28f11c3.png" mode="aspectFill" class="w208 h128 radius12"></image>
+						<view class="item-title">
+							<view class="ask-text">{{item.name}}</view>
+							<view class="ask-time">{{item.time}}</view>
+						</view>
+					</view>
+					<view class="bottom-box">
+						<view class="btn-box">
+							<view class="btn cancel" @click="shareQr()">分享</view>
+							<view class="btn pay" @click="showDetail(item)">结果</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-body>
+		</view>
+		<!-- <view class="btn-box2">
+			<view class="sub-btn" @click="navgetTo(orderStatusValue)">
+				<image src="/static/images/health/nav_add_icon24.png" class="w48 h48"></image>
+				<text>新增</text>
+			</view>
+		</view> -->
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{orderId:1, name:'极诺泰1',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:2, name:'极诺泰2',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:3, name:'极诺泰3',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,}
+				],
+				dataList2: [
+					{orderId:1, name:'竞品1',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:2, name:'竞品2',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:3, name:'竞品3',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			pay(item){
+				uni.navigateTo({
+					url: '/pages_/doctor/paymentOrder?orderId='+item.orderId
+				})
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			//分享
+			shareQr(){
+				wx.downloadFile({
+				    url: this.url,
+				    success: (res) => {
+				      wx.showShareImageMenu({
+				        path: res.tempFilePath
+				      })
+				    }
+				})
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.orderStatusValue = item.val
+				if(item.val==1){
+					this.dataList=this.dataList2
+				}
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.orderStatusValue,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item) {
+				if(item.orderType==1){
+					uni.navigateTo({
+						url: '/pages_doctor/doctorOrderIM?orderId='+item.orderId
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 40upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				overflow-x: auto;
+			}
+			.item{
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color: #333333;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.btn-box2{
+			z-index: 9999;
+			width: 100%;
+			padding: 30upx;
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			box-sizing: border-box;
+			// background: #FFFFFF;
+			
+			 
+			.sub-btn{
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+		.consu-list{
+			.item{
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 30rpx;
+				position: relative;
+				margin-bottom: 20upx;
+				.item-top{
+					padding-bottom:30rpx ;
+					border-bottom: 1px solid #ECECEC;
+					display: flex;
+					align-items: flex-start;
+					.item-title{
+						display: flex;
+						flex-direction: column;
+						align-items: flex-start;
+						margin-left: 24rpx;
+						
+					}
+					.ask-text{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 32rpx;
+						color: #222426;
+						text-align: left;
+					}
+					.ask-time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						margin-top: 20rpx;
+					}
+				}
+				.ordersn-box{
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding: 0upx 0 20upx;
+					.num{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						line-height: 1;
+					}
+					.status-box{
+						display: flex;
+						align-items: center;
+						.recom-box{
+							width: 108upx;
+							height: 30upx;
+							line-height: 30upx;
+							text-align: left;
+							padding-left: 8upx;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #FFFFFF;
+							// background-image: url(../../static/images/recom.png);
+							background-repeat: no-repeat;
+							background-size: 100% 100%;
+							margin-right: 8upx;
+						}
+						.text{
+							font-size: 28upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							line-height: 1;
+							&.success{
+								color: #0bb3f2;
+							}
+							&.black{
+								color: #111111;
+							}
+							&.info{
+								color: #999999;
+							}
+						}
+					}
+				}
+				.patient-text{
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					margin-bottom: 24upx;
+				}
+			
+				.bottom-box{
+					height: 80upx;
+					display: flex;
+					align-items: center;
+					justify-content: flex-end;
+					margin-top: 20rpx;
+					.amount-paid{
+						display: flex;
+						align-items: center;
+						.label{
+							font-size: 24upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 1;
+						}
+						.price-box{
+							display: flex;
+							align-items: flex-end;
+							.unit{
+								font-size: 24upx;
+								font-family: PingFang SC;
+								font-weight: 600;
+								color: #FF5030;
+								line-height: 1.2;
+								margin-right: 4upx;
+							}
+							.num{
+								font-size: 36upx;
+								font-family: PingFang SC;
+								font-weight: bold;
+								color: #FF5030;
+								line-height: 1;
+							}
+						}
+					}
+					.btn-box{
+						box-sizing: border-box;
+						display: flex;
+						align-items: center;
+						.btn{
+						   width: 128rpx;
+						    height: 60rpx;
+							line-height: 60upx;
+							font-size: 24upx;
+							font-family: PingFang SC;
+							text-align: center;
+							border-radius: 32upx;
+							margin-left: 16upx;
+							&:first-child{
+								margin-left: 0;
+							}
+							&.cancel{
+								border: 1px solid #B2B2B2;
+								color: #666666;
+							}
+							&.pay{
+								border: 1px solid #008FD3;
+								color: #008FD3;
+							}
+						}
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 386 - 0
pages_company/todoList.vue

@@ -0,0 +1,386 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- 事项列表 -->
+			<view class="filter">
+				<view :class="isShow==false?'time-box':'time-box active'"  @tap="openCalendar()">
+					<view class="title">选择日期</view>
+					<image :src="isShow==false?'/static/images/company/time_arrow_icon.png':'/static/images/company/time_arrow_blue_icon.png'" class="w24 h24"></image>
+				</view>
+				<view class="list-box">
+					<image src="/static/images/company/list_matters_icon.png" class="w32 h32"></image>
+					<view class="title">事项列表</view>
+				</view>
+			</view>
+			</view>
+			<view class="top-fixed2">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view v-for="(item,index) in taskType" :key="index"
+						:class="item.val == showType?'item active':'item'" @click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+			<u-popup :show="isShow" mode="top" :round="12"  customStyle="top: 110rpx;">
+				<view class="calendar-box">
+			           <pushangyuqi-calendar @onDayClick="onDayClick"></pushangyuqi-calendar>
+				</view>
+			</u-popup>
+		<mescroll-body top="200upx" ref="mescrollRef">
+			<view class="sms-list">
+				<view v-for="(item,index) in dataList" :key="index" class="item">
+					<view class="justify-between align-center">
+						<view class="title">{{item.content}}</view>
+						<view class="state" :style="{'color':item.status==0?'#FF5030':'#2CAE5C'}">
+							{{item.status==0?"未完成":"已完成"}}</view>
+					</view>
+					<view class="personnel">
+						{{item.personnel}}
+					</view>
+				</view>
+			</view>
+		</mescroll-body>
+	</view>
+</template>
+
+<script>
+	import pushangyuqiCalendar from '../components/pushangyuqi-calendar/pushangyuqi-calendar.vue'
+	import {
+		getMyDoctorOrderList,
+		cancelOrder
+	} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin],
+		components:{
+		           pushangyuqiCalendar
+		        },
+		data() {
+			return {
+				taskType: [{
+						name: "全部",
+						val: 0
+					},
+					{
+						name: "固定任务",
+						val: 1
+					},
+					{
+						name: "工作计划",
+						val: 2
+					},
+				],
+				isShow:false,
+				showType: 0,
+				mescroll: null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll: true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon: '/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				dataList: [{
+						orderId: 1,
+						content: '发送20条营销短信',
+						status: 0,
+						personnel: '管理员张三分配'
+					},
+					{
+						orderId: 2,
+						content: '发送20条营销短信',
+						status: 1,
+						personnel: '管理员张三分配'
+					},
+					{
+						orderId: 3,
+						content: '发送20条营销短信',
+						status: 0,
+						personnel: '管理员张三分配'
+					}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			//时间筛选
+			openCalendar(){
+				this.isShow=!this.isShow
+			},
+			//日历
+			onDayClick(data){
+			                this.curDate = data;
+							 this.isShow = false
+			            },
+			navgetTo(index) {
+				uni.navigateTo({
+					url: index == 0 ? '/pages_health/addServe' : '/pages_health/addCompetitors'
+				})
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.showType = item.val
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status: this.showType,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item) {
+				if (item.orderType == 1) {
+					uni.navigateTo({
+						url: '/pages_doctor/doctorOrderIM?orderId=' + item.orderId
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color:#EFF3F7;
+		background: #EFF3F7;
+	}
+	.calendar-box{
+		padding:0 30rpx;
+	}
+	.content {
+		padding: 20upx;
+
+		.top-fixed {
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index:10076;
+		}
+		.top-fixed2 {
+			width: 100%;
+			position: fixed;
+			top: 110rpx;
+			left: 0;
+			z-index: 10;
+		}
+        .filter{
+			background: #FFFFFF;
+			padding: 20rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			.time-box{
+				display: flex;
+				align-items: center;
+				padding:16rpx 48rpx;
+				background: #F5F7FA;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				.title{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #626468;
+					text-align: center;
+					padding-right: 20rpx;
+				}
+				&.active{
+					background: #F0FAFF;
+					.title{
+						color:#008FD3
+					}
+				}
+			}
+			.list-box{
+				display: flex;
+				align-items: center;
+				.title{
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #222426;
+					text-align: center;
+					padding-left: 16rpx;
+				}
+			}
+		}
+		.pub-tab-box {
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 20upx;
+		    background-color: #EFF3F7;
+
+			.tab-inner {
+				height: 110upx;
+				line-height: 110upx;
+				display: flex;
+				align-items: center;
+				// justify-content: space-between;
+				overflow-x: auto;
+			}
+
+			.item {
+				// flex: 1;
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 400;
+				color: #222426;
+				margin-right: 16upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+                background: #FFFFFF;
+                border-radius: 36rpx 36rpx 36rpx 36rpx;
+				padding:16rpx 48rpx;
+				&:last-child {
+					margin-right: 0;
+				}
+
+				&.active {
+					font-weight: bold;
+					color: #fff;
+                    background: linear-gradient(120deg, #31A1FE 0%, #008FD3 100%);
+				}
+
+				.text {
+					position: relative;
+					z-index: 1;
+				}
+
+				.tab-bg {
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+
+		.btn-box2 {
+			z-index: 9999;
+			width: 100%;
+			padding: 30upx;
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			box-sizing: border-box;
+			// background: #FFFFFF;
+
+
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+
+				image {
+					margin-right: 16rpx;
+				}
+			}
+		}
+
+		.sms-list {
+			.item {
+				padding: 30rpx;
+				background: #FFFFFF;
+				border-radius: 16rpx 16rpx 16rpx 16rpx;
+				margin-bottom: 20rpx;
+
+				.title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #222426;
+					text-align: left;
+				}
+
+				.title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #222426;
+					text-align: left;
+				}
+
+				.state {
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 26rpx;
+					text-align: right;
+				}
+
+				.personnel {
+					font-family: PingFang SC;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #898E91;
+					text-align: left;
+					margin-top: 16rpx;
+				}
+
+			}
+		}
+
+	}
+</style>

+ 454 - 0
pages_echarts/acid.vue

@@ -0,0 +1,454 @@
+<template>
+	<view class="hb column hidden container">
+		<image class="bg" src="/static/images/health/uric_acid_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="尿酸监测" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
+		
+		<view class="top-fixed">
+			<dateTimePicker @onChange="onChangeTime" :tabColor="'blue'"/>
+		</view>
+		<scroll-view class="content" :scroll-y="true">
+			<view class="content-box">
+				<view class="tltle">尿酸趋势</view>
+				<view class="subtitle">单位:μmol/L</view>
+				<view class="charts-box">
+					<qiun-data-charts type="column" :opts="opts" :chartData="chartData" />
+				</view>
+			</view>
+			<view class="content-box">
+				<view class="align-center justify-between">
+					<view class="tltle">尿酸异常记录</view>
+					<view class="more" @click="navgetTo()">
+						<text>查看更多</text>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="type-box">
+					<view class="box bg3">
+						<view class="fs32 mb12">高风险</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/yz_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg2">
+						<view class="fs32 mb12">不良</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/qw_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg1">
+						<view class="fs32 mb12">正常</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/zc_arrow_icon.png"></image>
+						</view>
+					</view>
+				</view>
+				<view class="content-bottom">
+					<view class="align-center">
+						<image class="w48 h48" src="/static/images/health/note_icon.png"></image>
+						<view class="title">尿酸
+							<text>最新标准</text>
+						</view>
+					</view>
+					<view class="bottom-box">
+						<view>男性正常值:150~416umol/L</view>
+						<view>女性正常值:89~357μmol/L</view>
+					</view>
+				</view>
+			</view>
+			<view class="h20"></view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="navgetTo()">记录</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import dateTimePicker from "@/pages_echarts/components/dateTimePicker/dateTimePicker.vue"
+	export default {
+		components: {
+			dateTimePicker
+		},
+		data() {
+			return {
+				statusBarHeight: '',
+				top: 0,
+				aIndex: 0,
+				times: [{
+						name: "每日",
+						val: 0
+					},
+					{
+						name: "每周",
+						val: 1
+					},
+					{
+						name: "每月",
+						val: 2
+					}
+				],
+				indexInfo: [],
+				chartData: {},
+			opts: {
+				padding: [15, 0, 15, 0],
+				enableScroll: false,
+				dataLabel: false,
+				legend: {
+					show: false
+				},
+				xAxis: {
+					disableGrid: true,
+					fontSize: 12,
+					axisLine: false,
+					fontColor: '#ccc',
+					labelCount: 7,
+					format: "formatterTime",
+				},
+				yAxis: {
+					gridType: "dash",
+					dashLength: 2,
+					data: [{
+						fontColor: '#ccc',
+						min: 0,
+						// max: 100,
+						axisLine: false,
+						fontSize: 12,
+					}]
+				},
+				extra: {
+					tooltip: {
+						gridType: "dash",
+						showArrow: false,
+						legendShow: true,
+						legendShape: "circle"
+					},
+					column: {
+						type: "group",
+						width: 12,
+						barBorderRadius: [4, 4, 0, 0],
+					}
+				}
+			}
+			}
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			// 获取系统信息
+			const sys = uni.getSystemInfoSync()
+			this.statusBarHeight = sys.statusBarHeight + 'px'
+			this.getServerData();
+		},
+		onUnload() { //普通页面在 onUnload 生命周期中执行
+			uni.$emit('stop')
+		},
+		onHide() { //tabBar页面在onHide生命周期中执行
+			uni.$emit('stop')
+		},
+		onPageScroll(e) {
+			//console.log(e)
+			this.top = e.scrollTop;
+		},
+		methods: {
+			// tab切换
+			orderStatusChange(item) {
+				this.aIndex = item.val
+			},
+			onChangeTime(time) {
+				const param = {
+					startTime: this.utils.timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
+					endTime: this.utils.timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
+					deviceId: ''
+				}
+				// this.queryParam = param
+				// this.getServerData(param)
+				// this.getAbnormalInfo(param)
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: ["00:00", "06:00", "12:00", "18:00", "23:59"],
+						series: [{
+							name: "尿酸",
+							data:[{
+								value:23,
+								color:'#FDBD27',
+							},{
+								value:123,
+								color:'#FF5558',
+								
+							},
+							{
+								value:90,
+								color:'#52D087',
+							},
+							{
+								value:23,
+								color:'#FDBD27',
+							},
+							{
+								value:90,
+								color:'#52D087',
+							}
+							]
+							// data: res.data.map(item => ({
+							// 	value: item.val,
+							// 	color: item.status === 1 ? "#FDBD27" : item.status ===
+							// 		2 ? "#FF5558" : "#52D087"
+							// }))
+						}
+
+						]
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+			navgetTo(index) {
+				uni.navigateTo({
+					url: '/pages_echarts/acidList'
+				})
+			},
+			goToUser() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		position: relative;
+
+		.bg {
+			width: 100%;
+			height: 380rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+	}
+
+	.top-fixed {
+		width: 100%;
+		position: fixed;
+		top: calc(var(--status-bar-height) + 140rpx);
+		left: 0;
+		z-index: 10;
+	}
+
+	.pub-tab-box {
+		box-sizing: border-box;
+		width: 400rpx;
+		// padding: 0 60rpx;
+		margin: 0 auto;
+
+		// background-color: #FFFFFF;
+		.tab-inner {
+			height: 88upx;
+			line-height: 88upx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			overflow-x: auto;
+		}
+
+		.item {
+			font-family: PingFang SC;
+			font-weight: 400;
+			font-size: 30rpx;
+			color: #626468;
+			line-height: 64rpx;
+			text-align: center;
+
+			&:last-child {
+				margin-right: 0;
+			}
+
+			&.active {
+				font-weight: 500;
+				width: 124rpx;
+				height: 64rpx;
+				background: #4585F8;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				color: #fff;
+			}
+
+			.text {
+				position: relative;
+				z-index: 1;
+			}
+
+			.tab-bg {
+				width: 72upx;
+				height: 28upx;
+				position: absolute;
+				top: 17upx;
+				left: 50%;
+				transform: translateX(-36upx);
+				z-index: -1;
+			}
+		}
+	}
+
+	.content {
+		padding-top: calc(var(--status-bar-height) + 320rpx) !important;
+		height: 100vh;
+		box-sizing: border-box;
+		width: 100%;
+		padding: 20rpx;
+overflow: hidden;
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.sub-btn {
+				width: 388rpx;
+				height: 72rpx;
+				line-height: 72upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #4585F8;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+
+		.content-box {
+			// width: 100%;
+			background: #FFFFFF;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+			padding: 24rpx;
+			margin-bottom: 20rpx;
+
+			.tltle {
+				font-family: PingFang SC;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #222426;
+				text-align: left;
+				margin-bottom: 16rpx;
+			}
+
+			.subtitle {
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+				text-align: left;
+
+			}
+
+			/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
+			.charts-box {
+				// width: 100%;
+				height: 500rpx;
+				margin-top: 30rpx;
+			}
+
+			.more {
+				display: flex;
+				align-items: center;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+			}
+
+			.type-box {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				margin-top: 20rpx;
+
+				.box {
+					padding: 24rpx;
+					width: 158rpx;
+					// height: 144rpx;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+
+					&.bg1 {
+						background: #FAFFFC;
+						border: 2rpx solid #EBFFF3;
+					}
+
+					&.bg2 {
+						background: #FEFAF8;
+						border: 2rpx solid #FDF7F3;
+					}
+
+					&.bg3 {
+						background: #FFFCFC;
+						border: 2rpx solid #FCF4F4;
+					}
+				}
+			}
+
+			.content-bottom {
+				padding: 24rpx;
+				background: #F5F7FA;
+				border-radius: 16rpx 16rpx 16rpx 16rpx;
+				margin-top: 32rpx;
+
+				.title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #222426;
+					text-align: left;
+					margin-left: 14rpx;
+
+					text {
+						color: #FF5030;
+					}
+				}
+
+				.bottom-box {
+					postion: relative;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+					text-align: left;
+					line-height: 40rpx;
+					padding-top: 24rpx;
+					padding-left: 24rpx;
+
+					view {
+						position: relative;
+					}
+
+					view::before {
+						content: "";
+						width: 8rpx;
+						height: 8rpx;
+						background: rgba(255, 80, 48, 0.2);
+						position: absolute;
+						left: -22rpx;
+						top: 20rpx;
+						border-radius: 50%;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 187 - 0
pages_echarts/acidDetail.vue

@@ -0,0 +1,187 @@
+<template>
+	<view class="container">
+		<view class="datebox">
+			<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
+				<view class="datebox-item border-line flex-bt">
+					<view>日期</view>
+					<view class="datebox-item-right">
+						<text :class="date ? '':'default'">{{date ? date : "请选择日期"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+			<picker mode="time" :value="time" @change="bindTimeChange">
+				<view class="datebox-item flex-bt">
+					<view>测量时间</view>
+					<view class="datebox-item-right">
+						<text :class="time ? '':'default'">{{time ? time : "请选择测量时间"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+		</view>
+		<view class="datebox-detail">
+			<view class="datebox-detail-header flex-bt">
+				<view>尿酸</view>
+				<view class="datebox-detail-header-right">
+					<text class="num">{{active}}</text>
+					<text>μmol/L</text>
+				</view>
+			</view>
+			<view class="scale">
+				<simpleScale ref="simpleScale" :minVal="0" :maxVal="33" :int="false" :single="10" :h="h" :active="active" :scroll="false" :style="style"
+					@value="getScroll" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import simpleScale from "@/pages_echarts/components/simpleScale/simpleScale.vue"
+	// import { bgInfo } from "@/api/pages_watch/healthMonitoring.js"
+	export default {
+		components: {
+			simpleScale
+		},
+		data() {
+			return {
+				// 表示有效日期范围的开始,字符串格式为"YYYY-MM-DD"
+				startDate: "2020-01-01",
+				// 表示有效日期范围的结束,字符串格式为"YYYY-MM-DD"
+				endDate: this.utils.timeFormat(new Date()),
+				date: "2024-01-01",
+				time: "17:12",
+				active: "6",
+				loading: false,
+				style: {
+					line: '#ccc',
+					bginner: '#fbfbfb',
+					bgoutside: '#ffffff',
+					fontColor: '#333',
+					fontSize: 16
+				},
+				h: uni.upx2px(88)
+			}
+		},
+		onLoad(option) {
+			// const param = JSON.parse(option.param)
+			// this.date = param.createTime && param.createTime.split(' ')[0]
+			// this.time = param.createTime && param.createTime.substring(11, 16)
+			// this.active = String(param.num || 0)
+			this.$nextTick(()=>{
+				this.$refs.simpleScale.init()
+			})
+		},
+		methods: {
+			bindDateChange(e) {
+				this.date = e.detail.value
+				this.getList()
+			},
+			bindTimeChange(e) {
+				this.time = e.detail.value
+				this.getList()
+			},
+			getScroll(e) {
+				this.active = e
+			},
+			// 查询数据
+			getList() {
+				this.loading = true
+				const param = {
+					startTime: this.date.replace(/-/g, '/') +" " +this.time + ":00",
+					endTime: this.date.replace(/-/g, '/') +" " + this.time + ":59",
+					deviceId: uni.getStorageSync("deviceId"),
+				}
+				bgInfo(param).then(res => {
+					this.loading = false
+					if (res.code == 200) {
+						if(res.data && res.data.length > 0) {
+							this.date = res.data[0].createTime && res.data[0].createTime.split(' ')[0]
+							this.time = res.data[0].createTime && res.data[0].createTime.substring(11, 16)
+							this.active = String(res.data[0].bloodGlucose || 0)
+						} else {
+							this.active = "0"
+						}
+						
+					} else {
+						this.active = "0"
+					}
+					this.$nextTick(()=>{
+						this.$refs.simpleScale.init()
+					})
+				}).catch(() => {
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@mixin u-flex($flexD, $alignI, $justifyC) {
+		display: flex;
+		flex-direction: $flexD;
+		align-items: $alignI;
+		justify-content: $justifyC;
+	}
+	.flex-bt {
+		@include u-flex(row, center, space-between);
+	}
+	.default {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #999999;
+	}
+	.container {
+		padding: 20rpx 24rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #333333;
+	}
+	.datebox {
+		padding: 0 32rpx;
+		margin-bottom: 20rpx;
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		&-item {
+			height: 120rpx;
+			&-right {
+				font-weight: 400;
+				font-size: 32rpx;
+				@include u-flex(row, center, flex-start);
+				image {
+					width: 48rpx;
+					height: 48rpx;
+				}
+			}
+		}
+	}
+	.datebox-detail {
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		padding: 40rpx 32rpx;
+		&-header-right {
+			flex-shrink: 0;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #999999;
+			.num {
+				font-size: 48rpx;
+				color: #333333;
+				margin-right: 14rpx;
+			}
+		}
+	}
+	.scale {
+		height: 176rpx;
+		margin-top: 36rpx;
+		overflow: hidden;
+		background: #FFFFFF;
+		box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(170,170,170,0.1);
+		border-radius: 0rpx 0rpx 0rpx 0rpx;
+		border: 2rpx solid #ECECEC;
+		// width: 200rpx;
+		// height: 600rpx;
+	}
+</style>

+ 405 - 0
pages_echarts/acidList.vue

@@ -0,0 +1,405 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view 
+						v-for="(item,index) in orderStatus" 
+						:key="index"
+						:class="item.val == orderStatusValue?'item active':'item'"
+						@click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="consu-list">
+			<view class="tab-time">
+				<picker class="birth-picker" mode="date"  fields="month"  @change="bindDateChange">
+					<view class="left-box">
+						<view>{{day}}</view>
+						<image class="w48 h48" src="../static/images/health/arrow_down.png"></image>
+					</view>
+				</picker>
+			</view>
+			<mescroll-body top="176upx" ref="mescrollRef">
+				<view v-for="(item,index) in dataList" :key="index" class="item">
+					<view class="item-top">
+						{{item.date}}
+					</view>
+					<view class="bottom-box" v-for="(it,idx) in item.list" :key="idx" @click="showDetail(it)">
+						<view class="amount-paid">
+							<view :class="'title bg'+it.type">{{it.typeName}}</view>
+							<view class="data">{{it.data}} μmol/L</view>
+						</view>
+						<view class="time">{{utils.timeFormat(it.createTime, "hh:MM")}}</view>
+					</view>
+				</view>
+			</mescroll-body>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				day:this.utils.timeFormat(new Date(),'yyyy年mm月'),
+				orderStatus:[
+					{name:"全部",val:""},
+					{name:"正常",val:"0"},
+					{name:"不良",val:"1"},
+					{name:"高风险",val:"2"},
+				],
+				orderStatusValue:'',
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-06-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'不良',
+								data:10.9,
+								createTime:'2025-06-25 22:39:55'
+							},
+							{
+								type:3,
+								typeName:'高风险',
+								data:10.9,
+								createTime:'2025-06-25 17:39:55'
+							}
+						],
+						date:'2025-06-25',
+						id:1
+					},
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-02-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'轻微',
+								data:10.9,
+								createTime:'2025-02-25 20:39:55'
+							}
+						],
+						date:'2025-02-25',
+						id:2
+					}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			// 时间选择
+			bindDateChange: function(e) {
+				this.day = this.utils.timeFormat(new Date(e.target.value),'yyyy年mm月')
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.orderStatusValue = item.val
+				if(item.val==1){
+					this.dataList=this.dataList2
+				}
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.orderStatusValue,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item){
+				console.log(item,'pp')
+				uni.navigateTo({
+					url: '/pages_echarts/acidDetail'
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 60upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content:space-between;
+				overflow-x: auto;
+			}
+			.item{
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				// margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color: #333333;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.tab-time{
+			padding: 32rpx 24rpx;
+			    font-size: 30rpx;
+			    color: #222426;
+			    text-align: left;
+				position: fixed;
+				top:88upx;
+				z-index:10;
+			.birth-picker {
+				flex: 1;
+				display: flex;
+				align-items: center;
+				
+				.left-box{
+					width: 100%;
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #222426;
+					display: flex;
+					align-items: center;
+					.input-box{
+						// width: 470upx;
+					}
+					.arrow{
+						width: 13upx;
+						height: 23upx;
+						margin-left: 20upx;
+					}
+				}
+			}
+		}
+		.consu-list{
+			.item{
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 24rpx;
+				position: relative;
+				margin-bottom: 20upx;
+				.item-top{
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #626468;
+					text-align: left;
+					padding:16rpx 0;
+					.item-title{
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+						margin-bottom: 12rpx;
+						
+					}
+					.ask-text{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 36rpx;
+						color: #222426;
+						text-align: left;
+					}
+					.ask-time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						line-height: 40rpx;
+					}
+				}
+				.bottom-box{
+					// height: 80upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding:32rpx 0;
+					border-bottom: 1px solid #ECECEC;
+					&:last-child{
+						border-bottom: 0;
+					}
+					.amount-paid{
+						display: flex;
+						align-items: center;
+				        .title{
+							width: 72rpx;
+							height: 72rpx;
+							line-height: 72rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							font-size: 24rpx;
+							color: #FFFFFF;
+							text-align: center;
+							margin-right: 18rpx;
+							border-radius:50%;
+						}
+						.bg1{
+							background: #52D087;
+						}
+						.bg2{
+							background: #FFB992;
+						}
+						.bg3{
+							background: #FF5558;
+						}
+						.data{
+							font-weight: 500;
+							font-size: 30rpx;
+							color: #222426;
+							text-align: left;
+						}
+					}
+				    .time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: right;
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 403 - 0
pages_echarts/bloodPressure.vue

@@ -0,0 +1,403 @@
+<template>
+	<view class="hb column hidden container">
+		<image class="bg" src="/static/images/health/blood_pressure_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="血压检测" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
+		<view class="top-fixed">
+			<!-- tab切换 -->
+		<dateTimePicker @onChange="onChangeTime" :tab-color="'orange'"/>
+		</view>
+		<scroll-view class="content" :scroll-y="true">
+			<view class="content-box">
+				<view class="tltle">血压趋势</view>
+				<view class="subtitle">单位:mmhg</view>
+				<view class="charts-box">
+					<qiun-data-charts type="area" :opts="opts" :chartData="chartData" />
+				</view>
+			</view>
+			<view class="content-box">
+				<view class="align-center justify-between">
+					<view class="tltle">血压异常记录</view>
+					<view class="more" @click="navgetTo()">
+						<text>查看更多</text>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="type-box">
+					<view class="box bg1">
+						<view class="fs32 mb12">正常</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/zc_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg2">
+						<view class="fs32 mb12">轻微</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/qw_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg3">
+						<view class="fs32 mb12">严重</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/yz_arrow_icon.png"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="h20"></view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="navgetTo()">记录</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import dateTimePicker from "@/pages_echarts/components/dateTimePicker/dateTimePicker.vue"
+	export default {
+		components: {
+			dateTimePicker
+		},
+		data() {
+			return {
+				statusBarHeight: '',
+				top: 0,
+				aIndex:0,
+				times:[	{name:"每日",val:0},
+					{name:"每周",val:1},
+					{name:"每月",val:2}],
+				indexInfo: [],
+				chartData: {},
+				opts: {
+					padding: [25, 10, 0, 0],
+					enableScroll: false,
+					dataLabel: false,
+					dataPointShapeType: "hollow",
+					legend: {
+						show: false
+					},
+					xAxis: {
+						disableGrid: true,
+						fontSize: 12,
+						axisLine: false,
+						fontColor: '#ccc',
+						labelCount: 7,
+						format: "formatterTime",
+					},
+					yAxis: {
+						gridType: "dash",
+						dashLength: 2,
+						data: [{
+							fontColor: '#ccc',
+							min: 0,
+							axisLine: false,
+							fontSize: 12,
+						}]
+					},
+					extra: {
+						tooltip: {
+							gridType: "dash",
+							showArrow: false,
+							legendShow: true,
+							legendShape: "circle"
+						},
+						area: {
+							type: "straight",
+							opacity: 0.2,
+							addLine: true,
+							width: 2,
+							gradient: true,
+							activeType: "solid"
+						}
+					}
+				}
+			}
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			// 获取系统信息
+			const sys = uni.getSystemInfoSync()
+			this.statusBarHeight = sys.statusBarHeight + 'px'
+			this.getServerData();
+		},
+		onUnload() { //普通页面在 onUnload 生命周期中执行
+			uni.$emit('stop')
+		},
+		onHide() { //tabBar页面在onHide生命周期中执行
+			uni.$emit('stop')
+		},
+		onPageScroll(e) {
+			//console.log(e)
+			this.top = e.scrollTop;
+		},
+		methods: {
+			// tab切换
+			orderStatusChange(item) {
+				this.aIndex = item.val
+			},
+			onChangeTime(time) {
+				const param = {
+					startTime: this.utils.timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
+					endTime: this.utils.timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
+					deviceId: ''
+				}
+				// this.queryParam = param
+				// this.getServerData(param)
+				// this.getAbnormalInfo(param)
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: ["1", "2", "3", "4", "5"],
+						series: [{
+							name: "收缩压",
+							color: "#FF5030",
+							data: [35, 180, 125, 307, 40]
+						},
+						{
+							name: "舒张压",
+							color: "#008FD3",
+							data: [135, 18, 125, 370, 40]
+						}
+						],
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+			navgetTo(index) {
+				uni.navigateTo({
+					url: '/pages_echarts/bloodPressureList'
+				})
+			},
+			goToUser() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		position: relative;
+
+		.bg {
+			width: 100%;
+			height: 380rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+	}
+.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: calc(var(--status-bar-height) + 140rpx);
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			    width: 400rpx;
+			    // padding: 0 60rpx;
+			    margin: 0 auto;
+			// background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content:space-between;
+				overflow-x: auto;
+			}
+			.item{
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 30rpx;
+				color: #626468;
+				line-height: 64rpx;
+				text-align: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: 500;
+					width: 124rpx;
+					height: 64rpx;
+					background: #FF5039;
+					border-radius: 32rpx 32rpx 32rpx 32rpx;
+					color: #fff;
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+	.content {
+		padding-top: calc(var(--status-bar-height) + 320rpx) !important;
+		height: 100vh;
+		box-sizing: border-box;
+		width: 100%;
+		padding: 20rpx;
+overflow: hidden;
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.sub-btn {
+				width: 388rpx;
+				height: 72rpx;
+				line-height: 72upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #FF5039;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+
+		.content-box {
+			// width: 100%;
+			background: #FFFFFF;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+			padding: 24rpx;
+			margin-bottom: 20rpx;
+
+			.tltle {
+				font-family: PingFang SC;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #222426;
+				text-align: left;
+				margin-bottom: 16rpx;
+			}
+
+			.subtitle {
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+				text-align: left;
+
+			}
+
+			/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
+			.charts-box {
+				// width: 100%;
+				height: 500rpx;
+				margin-top: 30rpx;
+			}
+
+			.more {
+				display: flex;
+				align-items: center;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+			}
+
+			.type-box {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				margin-top: 20rpx;
+
+				.box {
+					padding: 24rpx;
+					width: 158rpx;
+					// height: 144rpx;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+
+					&.bg1 {
+						background: #FAFFFC;
+						border: 2rpx solid #EBFFF3;
+					}
+
+					&.bg2 {
+						background: #FEFAF8;
+						border: 2rpx solid #FDF7F3;
+					}
+
+					&.bg3 {
+						background: #FFFCFC;
+						border: 2rpx solid #FCF4F4;
+					}
+				}
+			}
+
+			.content-bottom {
+				padding: 24rpx;
+				background: #F5F7FA;
+				border-radius: 16rpx 16rpx 16rpx 16rpx;
+				margin-top: 32rpx;
+               
+				.title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #222426;
+					text-align: left;
+					margin-left: 14rpx;
+
+					text {
+						color: #FF5030;
+					}
+				}
+				.bottom-box {
+                   postion:relative;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+					text-align: left;
+					line-height: 40rpx;
+					padding-top: 24rpx;
+                    padding-left: 24rpx;
+					view{
+						position: relative;
+					}
+					view::before {
+						content: "";
+						width: 8rpx;
+						height: 8rpx;
+						background: rgba(255,80,48,0.2);
+						position: absolute;
+						left:-22rpx;
+						top: 20rpx;
+						border-radius: 50%;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 210 - 0
pages_echarts/bloodPressureDetail.vue

@@ -0,0 +1,210 @@
+<template>
+	<view class="container">
+		<view class="datebox">
+			<picker mode="date" fields="day" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
+				<view class="datebox-item border-line flex-bt">
+					<view>日期</view>
+					<view class="datebox-item-right">
+						<text :class="date ? '':'default'">{{date ? date : "请选择日期"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+			<picker mode="time" :value="time" @change="bindTimeChange">
+				<view class="datebox-item flex-bt">
+					<view>测量时间</view>
+					<view class="datebox-item-right">
+						<text :class="time ? '':'default'">{{time ? time : "请选择测量时间"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+		</view>
+		<view class="datebox-detail">
+			<view class="datebox-detail-header flex-bt">
+				<view>收缩压</view>
+				<view class="datebox-detail-header-right">
+					<text class="num">{{sbp}}</text>
+					<text>mmHg</text>
+				</view>
+			</view>
+			<view class="scale">
+				<simpleScale ref="simpleSBPScale" :minVal="0" :maxVal="300" :int="true" :single="10" :h="h" :active="sbp" :scroll="false" :style="style"
+					@value="getSBPScroll" />
+			</view> 
+			<view class="datebox-detail-header flex-bt" style="margin-top: 48rpx;">
+				<view>舒张压</view>
+				<view class="datebox-detail-header-right">
+					<text class="num">{{dbp}}</text>
+					<text>mmHg</text>
+				</view>
+			</view>
+			<view class="scale">
+				<simpleScale ref="simpleDBPScale" :minVal="0" :maxVal="300" :int="true" :single="10" :h="h" :active="dbp" :scroll="false" :style="style"
+					@value="getDBPScroll" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import simpleScale from "@/pages_echarts/components/simpleScale/simpleScale.vue"
+	// import { bpInfo } from "@/api/pages_watch/healthMonitoring.js"
+	export default {
+		components: {
+			simpleScale
+		},
+		data() {
+			return {
+				// 表示有效日期范围的开始,字符串格式为"YYYY-MM-DD"
+				startDate: "2020-01-01",
+				// 表示有效日期范围的结束,字符串格式为"YYYY-MM-DD"
+				endDate: this.utils.timeFormat(new Date()),
+				date: "2024-01-01",
+				time: "17:12",
+				// 收缩压
+				sbp: "0",
+				// 舒张压
+				dbp: "0",
+				loading: false,
+				style: {
+					line: '#ccc',
+					bginner: '#fbfbfb',
+					bgoutside: '#ffffff',
+					fontColor: '#333',
+					fontSize: 16
+				},
+				h: uni.upx2px(88)
+			}
+		},
+		onLoad(option) {
+			const param = JSON.parse(option.param)
+			// this.date = param.createTime && param.createTime.split(' ')[0]
+			// this.time = param.createTime && param.createTime.substring(11, 16)
+			// this.sbp = String(param.sbp || 0)
+			// this.dbp = String(param.dbp || 0)
+			this.$nextTick(()=>{
+				this.$refs.simpleSBPScale.init()
+				this.$refs.simpleDBPScale.init()
+			})
+		},
+		methods: {
+			bindDateChange(e) {
+				this.date = e.detail.value
+				this.getList()
+			},
+			bindTimeChange(e) {
+				this.time = e.detail.value
+				this.getList()
+			},
+			getSBPScroll(e) {
+				this.sbp = e
+			},
+			getDBPScroll(e) {
+				this.dbp = e
+			},
+			// 查询数据
+			getList() {
+				this.loading = true
+				const param = {
+					startTime: this.date.replace(/-/g, '/') +" " +this.time + ":00",
+					endTime: this.date.replace(/-/g, '/') +" " + this.time + ":59",
+					deviceId: uni.getStorageSync("deviceId"),
+				}
+				bpInfo(param).then(res => {
+					this.loading = false
+					if (res.code == 200) {
+						if(res.data && res.data.length > 0) {
+							this.date = res.data[0].createTime && res.data[0].createTime.split(' ')[0]
+							this.time = res.data[0].createTime && res.data[0].createTime.substring(11, 16)
+							this.sbp = String(res.data[0].sbp || 0)
+							this.dbp = String(res.data[0].dbp || 0)
+							console.log(this.sbp,this.dbp)
+						} else {
+							this.sbp = "0"
+							this.dbp = "0"
+						}
+					} else {
+						this.sbp = "0"
+						this.dbp = "0"
+					}
+					this.$nextTick(()=>{
+						this.$refs.simpleSBPScale.init()
+						this.$refs.simpleDBPScale.init()
+					})
+				}).catch(() => {
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@mixin u-flex($flexD, $alignI, $justifyC) {
+		display: flex;
+		flex-direction: $flexD;
+		align-items: $alignI;
+		justify-content: $justifyC;
+	}
+	.flex-bt {
+		@include u-flex(row, center, space-between);
+	}
+	.default {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #999999;
+	}
+	.container {
+		padding: 20rpx 24rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #333333;
+	}
+	.datebox {
+		padding: 0 32rpx;
+		margin-bottom: 20rpx;
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		&-item {
+			height: 120rpx;
+			&-right {
+				font-weight: 400;
+				font-size: 32rpx;
+				@include u-flex(row, center, flex-start);
+				image {
+					width: 48rpx;
+					height: 48rpx;
+				}
+			}
+		}
+	}
+	.datebox-detail {
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		padding: 40rpx 32rpx;
+		&-header-right {
+			flex-shrink: 0;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #999999;
+			.num {
+				font-size: 48rpx;
+				color: #333333;
+				margin-right: 14rpx;
+			}
+		}
+	}
+	.scale {
+		height: 176rpx;
+		margin-top: 36rpx;
+		overflow: hidden;
+		background: #FFFFFF;
+		box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(170,170,170,0.1);
+		border-radius: 0rpx 0rpx 0rpx 0rpx;
+		border: 2rpx solid #ECECEC;
+		// width: 200rpx;
+		// height: 600rpx;
+	}
+</style>

+ 405 - 0
pages_echarts/bloodPressureList.vue

@@ -0,0 +1,405 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view 
+						v-for="(item,index) in orderStatus" 
+						:key="index"
+						:class="item.val == orderStatusValue?'item active':'item'"
+						@click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="consu-list">
+			<view class="tab-time">
+				<picker class="birth-picker" mode="date"  fields="month"  @change="bindDateChange">
+					<view class="left-box">
+						<view>{{day}}</view>
+						<image class="w48 h48" src="../static/images/health/arrow_down.png"></image>
+					</view>
+				</picker>
+			</view>
+			<mescroll-body top="176upx" ref="mescrollRef">
+				<view v-for="(item,index) in dataList" :key="index" class="item">
+					<view class="item-top">
+						{{item.date}}
+					</view>
+					<view class="bottom-box" v-for="(it,idx) in item.list" :key="idx" @click="showDetail(it)">
+						<view class="amount-paid">
+							<view :class="'title bg'+it.type">{{it.typeName}}</view>
+							<view class="data">{{it.data}} mmHg</view>
+						</view>
+						<view class="time">{{utils.formatDate(it.createTime)}}</view>
+					</view>
+				</view>
+			</mescroll-body>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				day:this.utils.timeFormat(new Date(),'yyyy年mm月'),
+				orderStatus:[
+					{name:"全部",val:""},
+					{name:"正常",val:"0"},
+					{name:"轻微",val:"1"},
+					{name:"严重",val:"2"},
+				],
+				orderStatusValue:'',
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-06-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'轻微',
+								data:10.9,
+								createTime:'2025-06-25 22:39:55'
+							},
+							{
+								type:3,
+								typeName:'严重',
+								data:10.9,
+								createTime:'2025-06-25 17:39:55'
+							}
+						],
+						date:'2025-06-25',
+						id:1
+					},
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-02-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'轻微',
+								data:10.9,
+								createTime:'2025-02-25 20:39:55'
+							}
+						],
+						date:'2025-02-25',
+						id:2
+					}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			// 时间选择
+			bindDateChange: function(e) {
+				this.day = this.utils.timeFormat(new Date(e.target.value),'yyyy年mm月')
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.orderStatusValue = item.val
+				if(item.val==1){
+					this.dataList=this.dataList2
+				}
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.orderStatusValue,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item){
+				console.log(item,'pp')
+				uni.navigateTo({
+					url: '/pages_echarts/bloodPressureDetail'
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 60upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content:space-between;
+				overflow-x: auto;
+			}
+			.item{
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				// margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color: #333333;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.tab-time{
+			padding: 32rpx 24rpx;
+			    font-size: 30rpx;
+			    color: #222426;
+			    text-align: left;
+				position: fixed;
+				top:88upx;
+				z-index:10;
+			.birth-picker {
+				flex: 1;
+				display: flex;
+				align-items: center;
+				
+				.left-box{
+					width: 100%;
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #222426;
+					display: flex;
+					align-items: center;
+					.input-box{
+						// width: 470upx;
+					}
+					.arrow{
+						width: 13upx;
+						height: 23upx;
+						margin-left: 20upx;
+					}
+				}
+			}
+		}
+		.consu-list{
+			.item{
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 24rpx;
+				position: relative;
+				margin-bottom: 20upx;
+				.item-top{
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #626468;
+					text-align: left;
+					padding:16rpx 0;
+					.item-title{
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+						margin-bottom: 12rpx;
+						
+					}
+					.ask-text{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 36rpx;
+						color: #222426;
+						text-align: left;
+					}
+					.ask-time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						line-height: 40rpx;
+					}
+				}
+				.bottom-box{
+					// height: 80upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding:32rpx 0;
+					border-bottom: 1px solid #ECECEC;
+					&:last-child{
+						border-bottom: 0;
+					}
+					.amount-paid{
+						display: flex;
+						align-items: center;
+				        .title{
+							width: 72rpx;
+							height: 72rpx;
+							line-height: 72rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							font-size: 24rpx;
+							color: #FFFFFF;
+							text-align: center;
+							margin-right: 18rpx;
+							border-radius:50%;
+						}
+						.bg1{
+							background: #52D087;
+						}
+						.bg2{
+							background: #FFB992;
+						}
+						.bg3{
+							background: #FF5558;
+						}
+						.data{
+							font-weight: 500;
+							font-size: 30rpx;
+							color: #222426;
+							text-align: left;
+						}
+					}
+				    .time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: right;
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 427 - 0
pages_echarts/bloodSugar.vue

@@ -0,0 +1,427 @@
+<template>
+	<view class="hb column hidden container">
+		<image class="bg" src="/static/images/health/blood_sugar_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="血糖检测" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<dateTimePicker @onChange="onChangeTime" :tab-color="'gree'"/>
+		</view>
+		<scroll-view class="content" :scroll-y="true">
+			<view class="content-box">
+				<view class="tltle">血糖趋势</view>
+				<view class="subtitle">单位:mmol/L</view>
+				<view class="charts-box">
+					<qiun-data-charts type="area" :opts="opts" :chartData="chartData" />
+				</view>
+			</view>
+			<view class="content-box">
+				<view class="align-center justify-between">
+					<view class="tltle">血糖异常记录</view>
+					<view class="more" @click="navgetTo()">
+						<text>查看更多</text>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+				<view class="type-box">
+					<view class="box bg1">
+						<view class="fs32 mb12">正常</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/zc_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg2">
+						<view class="fs32 mb12">轻微</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/qw_arrow_icon.png"></image>
+						</view>
+					</view>
+					<view class="box bg3">
+						<view class="fs32 mb12">严重</view>
+						<view class="align-center justify-between">
+							<text class="subtitle">4次</text>
+							<image class="w24 h24" src="/static/images/health/yz_arrow_icon.png"></image>
+						</view>
+					</view>
+				</view>
+				<view class="content-bottom">
+					<view class="align-center">
+						<image class="w48 h48" src="/static/images/health/note_icon.png"></image>
+						<view class="title">血糖
+							<text>最新标准</text>
+						</view>
+					</view>
+					<view class="bottom-box">
+						<view>空腹血糖正常值为4.1-6.1mmol/L</view>
+						<view>餐后1小时血糖正常值为6.7-9.4mmol/L</view>
+						<view>餐后2小时血糖正常值为{{'<=' + 7.8}}mmol /L</view>
+						<!-- <view>餐后2小时血糖正常值为<=7.8mmol/L</view> -->
+					</view>
+				</view>
+			</view>
+			<view class="h20"></view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="navgetTo()">记录</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+import dateTimePicker from "@/pages_echarts/components/dateTimePicker/dateTimePicker.vue"
+	export default {
+		components: {
+			dateTimePicker
+		},
+		data() {
+			return {
+				color:'#2CAE5C',
+				statusBarHeight: '',
+				top: 0,
+				aIndex:0,
+				times:[	{name:"每日",val:0},
+					{name:"每周",val:1},
+					{name:"每月",val:2}],
+				indexInfo: [],
+				healthRecordsList: [{
+					title: '疾病史',
+					type: "healthHistory",
+					desc: '',
+					bgicon: "/static/images/health/jbs_icon.png",
+				}, {
+					title: '症状史',
+					type: "symptomHistory",
+					desc: '',
+					bgicon: "/static/images/health/zzs_icon.png",
+				}],
+				chartData: {},
+				opts: {
+					color: ["#FF5030"],
+					padding: [20, 0, 15, 0],
+					enableScroll: false,
+					dataLabel:false,
+					dataPointShapeType: "hollow",
+					legend: {
+						show: false,
+					},
+					xAxis: {
+						disableGrid: true,
+						fontSize: 12,
+						axisLine:false,
+						fontColor: '#ccc',
+						// 横坐标最多展示几个
+						labelCount: 7,
+						// 自定义横坐标展示(在/u-charts/config-ucharts中有配置)
+						format: "formatterTime",
+					},
+					yAxis: {
+						gridType: "dash",
+						dashLength: 2,
+						// splitNumber: 6,
+						data: [{
+							fontColor: '#ccc',
+							min: 0,
+							// max: 33,
+							axisLine:false,
+							fontSize: 12,
+						}]
+					},
+					extra: {
+						tooltip: {
+							gridType: "dash",
+							showArrow: false,
+							legendShow: true,
+							legendShape: "circle"
+						},
+						area: {
+							type: "straight",
+							opacity: 0.2,
+							addLine: true,
+							width: 2,
+							gradient: true,
+							activeType: "solid"
+						}
+					}
+				}
+			}
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			// 获取系统信息
+			const sys = uni.getSystemInfoSync()
+			this.statusBarHeight = sys.statusBarHeight + 'px'
+			this.getServerData();
+		},
+		onUnload() { //普通页面在 onUnload 生命周期中执行
+			uni.$emit('stop')
+		},
+		onHide() { //tabBar页面在onHide生命周期中执行
+			uni.$emit('stop')
+		},
+		onPageScroll(e) {
+			//console.log(e)
+			this.top = e.scrollTop;
+		},
+		methods: {
+			// tab切换
+			orderStatusChange(item) {
+				this.aIndex = item.val
+			},
+			onChangeTime(time) {
+				const param = {
+					startTime: this.utils.timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
+					endTime: this.utils.timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
+					deviceId: ''
+				}
+				// this.queryParam = param
+				// this.getServerData(param)
+				// this.getAbnormalInfo(param)
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: ["00:00", "06:00", "12:00", "18:00", "23:59"],
+						series: [{
+							name: "血糖",
+							data: [35, 8, 25, 37, 4]
+						}]
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+			navgetTo(index) {
+				uni.navigateTo({
+					url: '/pages_echarts/bloodSugarList'
+				})
+			},
+			goToUser() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		position: relative;
+
+		.bg {
+			width: 100%;
+			height: 380rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+	}
+.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: calc(var(--status-bar-height) + 140rpx);
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			    width: 400rpx;
+			    // padding: 0 60rpx;
+			    margin: 0 auto;
+			// background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content:space-between;
+				overflow-x: auto;
+			}
+			.item{
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 30rpx;
+				color: #626468;
+				line-height: 64rpx;
+				text-align: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: 500;
+					width: 124rpx;
+					height: 64rpx;
+					background: #2CAE5C;
+					border-radius: 32rpx 32rpx 32rpx 32rpx;
+					color: #fff;
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+	.content {
+		padding-top: calc(var(--status-bar-height) + 320rpx) !important;
+		height: 100vh;
+		box-sizing: border-box;
+		width: 100%;
+		padding: 20rpx;
+overflow: hidden;
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.sub-btn {
+				width: 388rpx;
+				height: 72rpx;
+				line-height: 72upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #2CAE5C;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+
+		.content-box {
+			// width: 100%;
+			background: #FFFFFF;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+			padding: 24rpx;
+			margin-bottom: 20rpx;
+
+			.tltle {
+				font-family: PingFang SC;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #222426;
+				text-align: left;
+				margin-bottom: 16rpx;
+			}
+
+			.subtitle {
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+				text-align: left;
+
+			}
+
+			/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
+			.charts-box {
+				// width: 100%;
+				height: 500rpx;
+				margin-top: 30rpx;
+			}
+
+			.more {
+				display: flex;
+				align-items: center;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+			}
+
+			.type-box {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				margin-top: 20rpx;
+
+				.box {
+					padding: 24rpx;
+					width: 158rpx;
+					// height: 144rpx;
+					border-radius: 16rpx 16rpx 16rpx 16rpx;
+
+					&.bg1 {
+						background: #FAFFFC;
+						border: 2rpx solid #EBFFF3;
+					}
+
+					&.bg2 {
+						background: #FEFAF8;
+						border: 2rpx solid #FDF7F3;
+					}
+
+					&.bg3 {
+						background: #FFFCFC;
+						border: 2rpx solid #FCF4F4;
+					}
+				}
+			}
+
+			.content-bottom {
+				padding: 24rpx;
+				background: #F5F7FA;
+				border-radius: 16rpx 16rpx 16rpx 16rpx;
+				margin-top: 32rpx;
+               
+				.title {
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #222426;
+					text-align: left;
+					margin-left: 14rpx;
+
+					text {
+						color: #FF5030;
+					}
+				}
+				.bottom-box {
+                   postion:relative;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #626468;
+					text-align: left;
+					line-height: 40rpx;
+					padding-top: 24rpx;
+                    padding-left: 24rpx;
+					view{
+						position: relative;
+					}
+					view::before {
+						content: "";
+						width: 8rpx;
+						height: 8rpx;
+						background: rgba(255,80,48,0.2);
+						position: absolute;
+						left:-22rpx;
+						top: 20rpx;
+						border-radius: 50%;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 187 - 0
pages_echarts/bloodSugarDetail.vue

@@ -0,0 +1,187 @@
+<template>
+	<view class="container">
+		<view class="datebox">
+			<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
+				<view class="datebox-item border-line flex-bt">
+					<view>日期</view>
+					<view class="datebox-item-right">
+						<text :class="date ? '':'default'">{{date ? date : "请选择日期"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+			<picker mode="time" :value="time" @change="bindTimeChange">
+				<view class="datebox-item flex-bt">
+					<view>测量时间</view>
+					<view class="datebox-item-right">
+						<text :class="time ? '':'default'">{{time ? time : "请选择测量时间"}}</text>
+						<image src="@/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</view>
+			</picker>
+		</view>
+		<view class="datebox-detail">
+			<view class="datebox-detail-header flex-bt">
+				<view>血糖</view>
+				<view class="datebox-detail-header-right">
+					<text class="num">{{active}}</text>
+					<text>mmol/L</text>
+				</view>
+			</view>
+			<view class="scale">
+				<simpleScale ref="simpleScale" :minVal="0" :maxVal="33" :int="false" :single="10" :h="h" :active="active" :scroll="false" :style="style"
+					@value="getScroll" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import simpleScale from "@/pages_echarts/components/simpleScale/simpleScale.vue"
+	// import { bgInfo } from "@/api/pages_watch/healthMonitoring.js"
+	export default {
+		components: {
+			simpleScale
+		},
+		data() {
+			return {
+				// 表示有效日期范围的开始,字符串格式为"YYYY-MM-DD"
+				startDate: "2020-01-01",
+				// 表示有效日期范围的结束,字符串格式为"YYYY-MM-DD"
+				endDate: this.utils.timeFormat(new Date()),
+				date: "2024-01-01",
+				time: "17:12",
+				active: "6",
+				loading: false,
+				style: {
+					line: '#ccc',
+					bginner: '#fbfbfb',
+					bgoutside: '#ffffff',
+					fontColor: '#333',
+					fontSize: 16
+				},
+				h: uni.upx2px(88)
+			}
+		},
+		onLoad(option) {
+			// const param = JSON.parse(option.param)
+			// this.date = param.createTime && param.createTime.split(' ')[0]
+			// this.time = param.createTime && param.createTime.substring(11, 16)
+			// this.active = String(param.num || 0)
+			this.$nextTick(()=>{
+				this.$refs.simpleScale.init()
+			})
+		},
+		methods: {
+			bindDateChange(e) {
+				this.date = e.detail.value
+				this.getList()
+			},
+			bindTimeChange(e) {
+				this.time = e.detail.value
+				this.getList()
+			},
+			getScroll(e) {
+				this.active = e
+			},
+			// 查询数据
+			getList() {
+				this.loading = true
+				const param = {
+					startTime: this.date.replace(/-/g, '/') +" " +this.time + ":00",
+					endTime: this.date.replace(/-/g, '/') +" " + this.time + ":59",
+					deviceId: uni.getStorageSync("deviceId"),
+				}
+				bgInfo(param).then(res => {
+					this.loading = false
+					if (res.code == 200) {
+						if(res.data && res.data.length > 0) {
+							this.date = res.data[0].createTime && res.data[0].createTime.split(' ')[0]
+							this.time = res.data[0].createTime && res.data[0].createTime.substring(11, 16)
+							this.active = String(res.data[0].bloodGlucose || 0)
+						} else {
+							this.active = "0"
+						}
+						
+					} else {
+						this.active = "0"
+					}
+					this.$nextTick(()=>{
+						this.$refs.simpleScale.init()
+					})
+				}).catch(() => {
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@mixin u-flex($flexD, $alignI, $justifyC) {
+		display: flex;
+		flex-direction: $flexD;
+		align-items: $alignI;
+		justify-content: $justifyC;
+	}
+	.flex-bt {
+		@include u-flex(row, center, space-between);
+	}
+	.default {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #999999;
+	}
+	.container {
+		padding: 20rpx 24rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #333333;
+	}
+	.datebox {
+		padding: 0 32rpx;
+		margin-bottom: 20rpx;
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		&-item {
+			height: 120rpx;
+			&-right {
+				font-weight: 400;
+				font-size: 32rpx;
+				@include u-flex(row, center, flex-start);
+				image {
+					width: 48rpx;
+					height: 48rpx;
+				}
+			}
+		}
+	}
+	.datebox-detail {
+		background: #FFFFFF;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		padding: 40rpx 32rpx;
+		&-header-right {
+			flex-shrink: 0;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #999999;
+			.num {
+				font-size: 48rpx;
+				color: #333333;
+				margin-right: 14rpx;
+			}
+		}
+	}
+	.scale {
+		height: 176rpx;
+		margin-top: 36rpx;
+		overflow: hidden;
+		background: #FFFFFF;
+		box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(170,170,170,0.1);
+		border-radius: 0rpx 0rpx 0rpx 0rpx;
+		border: 2rpx solid #ECECEC;
+		// width: 200rpx;
+		// height: 600rpx;
+	}
+</style>

+ 405 - 0
pages_echarts/bloodSugarList.vue

@@ -0,0 +1,405 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view 
+						v-for="(item,index) in orderStatus" 
+						:key="index"
+						:class="item.val == orderStatusValue?'item active':'item'"
+						@click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="consu-list">
+			<view class="tab-time">
+				<picker class="birth-picker" mode="date"  fields="month"  @change="bindDateChange">
+					<view class="left-box">
+						<view>{{day}}</view>
+						<image class="w48 h48" src="../static/images/health/arrow_down.png"></image>
+					</view>
+				</picker>
+			</view>
+			<mescroll-body top="176upx" ref="mescrollRef">
+				<view v-for="(item,index) in dataList" :key="index" class="item">
+					<view class="item-top">
+						{{item.date}}
+					</view>
+					<view class="bottom-box" v-for="(it,idx) in item.list" :key="idx" @click="showDetail(it)">
+						<view class="amount-paid">
+							<view :class="'title bg'+it.type">{{it.typeName}}</view>
+							<view class="data">{{it.data}} mmol/L</view>
+						</view>
+						<view class="time">{{utils.formatDate(it.createTime)}}</view>
+					</view>
+				</view>
+			</mescroll-body>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				day:this.utils.timeFormat(new Date(),'yyyy年mm月'),
+				orderStatus:[
+					{name:"全部",val:""},
+					{name:"正常",val:"0"},
+					{name:"轻微",val:"1"},
+					{name:"严重",val:"2"},
+				],
+				orderStatusValue:'',
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-06-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'轻微',
+								data:10.9,
+								createTime:'2025-06-25 22:39:55'
+							},
+							{
+								type:3,
+								typeName:'严重',
+								data:10.9,
+								createTime:'2025-06-25 17:39:55'
+							}
+						],
+						date:'2025-06-25',
+						id:1
+					},
+					{
+					 list:[
+							{
+								type:1,
+								typeName:'正常',
+								data:10.9,
+								createTime:'2025-02-25 12:39:55'
+							},
+							{
+								type:2,
+								typeName:'轻微',
+								data:10.9,
+								createTime:'2025-02-25 20:39:55'
+							}
+						],
+						date:'2025-02-25',
+						id:2
+					}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			// 时间选择
+			bindDateChange: function(e) {
+				this.day = this.utils.timeFormat(new Date(e.target.value),'yyyy年mm月')
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.orderStatusValue = item.val
+				if(item.val==1){
+					this.dataList=this.dataList2
+				}
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.orderStatusValue,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item){
+				console.log(item,'pp')
+				uni.navigateTo({
+					url: '/pages_echarts/bloodSugarDetail'
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 60upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content:space-between;
+				overflow-x: auto;
+			}
+			.item{
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				// margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color: #333333;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.tab-time{
+			padding: 32rpx 24rpx;
+			    font-size: 30rpx;
+			    color: #222426;
+			    text-align: left;
+				position: fixed;
+				top:88upx;
+				z-index:10;
+			.birth-picker {
+				flex: 1;
+				display: flex;
+				align-items: center;
+				
+				.left-box{
+					width: 100%;
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #222426;
+					display: flex;
+					align-items: center;
+					.input-box{
+						// width: 470upx;
+					}
+					.arrow{
+						width: 13upx;
+						height: 23upx;
+						margin-left: 20upx;
+					}
+				}
+			}
+		}
+		.consu-list{
+			.item{
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 24rpx;
+				position: relative;
+				margin-bottom: 20upx;
+				.item-top{
+					font-family: PingFang SC;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #626468;
+					text-align: left;
+					padding:16rpx 0;
+					.item-title{
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+						margin-bottom: 12rpx;
+						
+					}
+					.ask-text{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 36rpx;
+						color: #222426;
+						text-align: left;
+					}
+					.ask-time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						line-height: 40rpx;
+					}
+				}
+				.bottom-box{
+					// height: 80upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding:32rpx 0;
+					border-bottom: 1px solid #ECECEC;
+					&:last-child{
+						border-bottom: 0;
+					}
+					.amount-paid{
+						display: flex;
+						align-items: center;
+				        .title{
+							width: 72rpx;
+							height: 72rpx;
+							line-height: 72rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							font-size: 24rpx;
+							color: #FFFFFF;
+							text-align: center;
+							margin-right: 18rpx;
+							border-radius:50%;
+						}
+						.bg1{
+							background: #52D087;
+						}
+						.bg2{
+							background: #FFB992;
+						}
+						.bg3{
+							background: #FF5558;
+						}
+						.data{
+							font-weight: 500;
+							font-size: 30rpx;
+							color: #222426;
+							text-align: left;
+						}
+					}
+				    .time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: right;
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 256 - 0
pages_echarts/components/dateTimePicker/dateTimePicker.vue

@@ -0,0 +1,256 @@
+<template>
+	<view class="pickebox">
+		<view class="pickebox-typebox" v-if="showType">
+			<view :class="activeTab == index ? 'type-active tab-'+tabColor:''"  v-for="(item,index) in tabs" :key="index" @click="handleTab(item,index)">{{item.label}}</view>
+		</view>
+		<view class="pickebox-picker">
+			<view class="pickebox-pickerbtn prev" @click="handlePrev">
+				<image src="@/static/images/health/arrow_time_yes_icon.png"></image>
+				<!-- <image src="@/static/images/pages_watch/icons/arrow_time_no_icon.png"></image> -->
+			</view>
+			<view v-if="activeTab == 1" @click="openWeek">{{weekValue}}</view>
+			<template v-else>
+				<picker mode="date" :fields="fields" :value="value" style="display:inline-block;" @change="bindPickerChange">
+					<view>{{_date}}</view>
+				</picker>
+			</template>
+			<view class="pickebox-pickerbtn next" @click="handleNext">
+				<image src="@/static/images/health/arrow_time_yes_icon.png"></image>
+				<!-- <image src="@/static/images/pages_watch/icons/arrow_time_no_icon.png"></image> -->
+			</view>
+		</view>
+		<!-- 周 -->
+		<u-popup :show="show" mode="bottom">
+		    <myWeekPicker :value="value" @change="getWeeks"></myWeekPicker>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+	
+	import myWeekPicker from "@/pages_echarts/components/myWeekPicker/myWeekPicker.vue"
+	import weekjs from '../myWeekPicker/week.js';
+	export default {
+		name:"dateTimePicker",
+		components: {
+			myWeekPicker
+		},
+		props: {
+			showType: {
+				type: Boolean,
+				default: true
+			},
+			// 0: yyyy-mm-dd
+			// 1: yyyy年mm月dd日
+			formatType: {
+				type: Number,
+				default: 0
+			},
+			from: {
+				type: String,
+				default: ""
+			},
+			tabColor:{
+				type: String,
+				default: ""
+			}
+		},
+		data() {
+			return {
+				show:false,
+				tabs: [{
+					label: '每日',
+					value: 'day'
+				},{
+					label: '每周',
+					value: 'week'
+				},{
+					label: '每月',
+					value: 'month'
+				}],
+				activeTab: 0,
+				//  year、month、day,表示选择器的粒度,默认为 day
+				fields: 'day',
+				value: this.utils.timeFormat(),
+				weekValue: "",
+				startTime: "",
+				endTime: ""
+			}
+		},
+		computed: {
+			_date() {
+				if(this.formatType == 1 && this.value) {
+					console.log(this.fields)
+					if(this.fields == 'month') {
+						return this.utils.timeFormat(new Date(this.value),'yyyy年mm月')
+					} else {
+						return this.utils.timeFormat(new Date(this.value),'yyyy年mm月dd日')
+					}
+				} else {
+					return this.value
+				}
+			}
+		},
+		created() {
+			console.log(this.tabColor,'---')
+			if(this.from == "report") {
+				this.activeTab = 2
+				this.fields = 'month'
+				this.value = this.utils.timeFormat(new Date(), 'yyyy-mm')
+			} else if(this.from == "sports") {
+				this.tabs = [{
+					label: '每日',
+					value: 'day'
+				},{
+					label: '每周',
+					value: 'week'
+				}]
+			}
+			this.resetTime()
+		},
+		methods: {
+			handleTab(item,index) {
+				this.activeTab = index
+				this.fields = item.value == 'week' ? 'day' : item.value
+				if(this.activeTab == 0) { // 每日
+					this.value = this.utils.timeFormat()
+				} else if(this.activeTab == 1) { // 每周
+					this.value = this.utils.timeFormat()
+				} else if(this.activeTab == 2) { // 每月
+					this.value = this.utils.timeFormat(new Date(), 'yyyy-mm')
+				}
+				this.resetTime()
+			},
+			bindPickerChange(e) {
+				this.value = e.detail.value
+				this.resetTime()
+			},
+			handlePrev() {
+				// 前一天
+				const yesterday = new Date(this.value).setDate(new Date(this.value).getDate() - 1);
+				// 前一个月
+				let day = this.value
+				if(this.activeTab == 2) {
+					day = day + '-01'
+				}
+				const prevMonths = new Date(day).setMonth(new Date(day).getMonth() - 1);
+				// 7天前日期
+				const weekday = new Date(this.value).setDate(new Date(this.value).getDate() - 7);
+				
+				if(this.activeTab == 0) { // 每日
+					this.value = this.utils.timeFormat(yesterday)
+				} else if(this.activeTab == 1) { // 每周
+					this.value = this.utils.timeFormat(weekday)
+				} else if(this.activeTab == 2) { // 每月
+					this.value = this.utils.timeFormat(prevMonths, 'yyyy-mm')
+				}
+				this.resetTime()
+			},
+			handleNext() {
+				// 下一天
+				const yesterday = new Date(this.value).setDate(new Date(this.value).getDate() + 1);
+				// 下一个月
+				let day = this.value
+				if(this.activeTab == 2) {
+					day = day + '-01'
+				}
+				const prevMonths = new Date(day).setMonth(new Date(day).getMonth() + 1);
+				// 7天后日期
+				const weekday = new Date(this.value).setDate(new Date(this.value).getDate() + 7);
+				
+				if(this.activeTab == 0) { // 每日
+					this.value = this.utils.timeFormat(yesterday)
+				} else if(this.activeTab == 1) { // 每周
+					this.value = this.utils.timeFormat(weekday)
+				} else if(this.activeTab == 2) { // 每月
+					this.value = this.utils.timeFormat(prevMonths, 'yyyy-mm')
+				}
+				this.resetTime()
+			},
+			resetTime() {
+				if(this.activeTab == 0) { // 每日
+					this.startTime = this.value + " 00:00:00"
+					this.endTime = this.value + " 23:59:59"
+				} else if(this.activeTab == 1) { // 每周
+					let y = this.value.split('-')[0];
+					let m = this.value.split('-')[1];
+					let res =  weekjs.getWeeksByMonth(y, m,this.value,0); 
+					this.weekValue = res.week.formatVal
+					this.startTime = this.weekValue.split('至')[0] + " 00:00:00"
+					this.endTime = this.weekValue.split('至')[1] + " 23:59:59"
+				} else if(this.activeTab == 2) { // 每月
+					this.startTime = this.utils.timeFormat(this.value, 'yyyy-mm-dd') + " 00:00:00"
+					const currentYear = this.value.split('-')[0]
+					const currentMonth = this.value.split('-')[1]
+					const lastday = new Date(currentYear, currentMonth, 0)
+					this.endTime = this.utils.timeFormat(lastday, 'yyyy-mm-dd') + " 23:59:59"
+				}
+				this.$emit("onChange",[this.startTime,this.endTime,this.value,this.activeTab])
+			},
+			getWeeks(res) {
+			    if (res) { 
+					this.value = res.week.val
+			        this.weekValue = res.week.formatVal
+					this.resetTime()
+			    }
+			    this.show=false
+			},
+			openWeek() {
+			    this.show=true
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@mixin u-flex($flexD, $alignI, $justifyC) {
+		display: flex;
+		flex-direction: $flexD;
+		align-items: $alignI;
+		justify-content: $justifyC;
+	}
+	.pickebox {
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #333333;
+		.type-active {
+			font-weight: 500;
+			font-size: 30rpx;
+			color: #FFFFFF;
+		}
+		&-typebox {
+			height: 88rpx;
+			@include u-flex(row, center, center);
+			// gap: 16rpx;
+			view {
+				width: 124rpx;
+				height: 64rpx;
+				margin: 8rpx;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				color: #757575;
+				line-height: 64rpx;
+				text-align: center;
+			}
+		}
+		&-picker {
+			height: 88rpx;
+			margin: 20rpx 0;
+			@include u-flex(row, center, center);
+			// gap: 32rpx;
+		}
+		&-pickerbtn {
+			margin: 0 32rpx;
+			image {
+				width: 48rpx;
+				height: 48rpx;
+				background: #FFFFFF;
+				border-radius: 50%;
+				overflow: hidden;
+			}
+		}
+		.next image{
+			transform: rotateZ(180deg);
+		}
+	}
+</style>

+ 190 - 0
pages_echarts/components/myWeekPicker/myWeekPicker.vue

@@ -0,0 +1,190 @@
+<template>
+	<view class="my-week-picker">
+		<view class="my-week-popup_header">
+			<text class="my-week-popup-text cancel" @click="onCancel">取消</text>
+			<text class="my-week-popup-text sure" @click="onSure">确定</text>
+		</view>
+		<picker-view :value="pickerValue" @change="bindChange" class="my-week-picker_view"
+			:indicatorStyle="'height:'+height+'px'">
+			<picker-view-column class="my-week-picker_item years">
+				<view class="my-week-picker_item_view" :style="{'height':height+'px'}" v-for="(item,index) in years"
+					:key="index">{{item}}</view>
+			</picker-view-column>
+			<picker-view-column class="my-week-picker_item months">
+				<view class="my-week-picker_item_view" :style="{'height':height+'px'}" v-for="(item,index) in months"
+					:key="index">{{index+1}}</view>
+			</picker-view-column>
+			<picker-view-column class="my-week-picker_item weeks">
+				<view class="my-week-picker_item_view" :style="{'height':height+'px'}" v-for="(item,index) in weeks"
+					:key="index">{{item.text}}</view>
+			</picker-view-column>
+		</picker-view>
+	</view>
+</template>
+
+<script>
+	import dayjs from 'dayjs';
+	import weekjs from './week.js'
+	export default {
+		name: "myWeekPicker",
+		props: {
+			value: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 格式化
+			 * 0:  2021-06-01
+			 * 1:  2021年06月01日
+			 */
+			formatType: {
+				type: Number,
+				default: 0
+			},
+			// 列的高度
+			height: {
+				type: [Number, String],
+				default: 50
+			},
+
+		},
+		data() {
+			return {
+				years: [],
+				months: 12,
+				weeks: [],
+				pickerValue: [0, 0, 0],
+				result: {
+					week: ''
+				}
+			};
+		},
+		computed: {
+			val() {
+				return this.value || dayjs().format('YYYY-MM-DD')
+			}
+		},
+		created() {
+			this.dateInit();
+		},
+		methods: {
+			async dateInit() {
+				let v = this.val.split('-');
+				
+				let s = Number(v[0]) - 50;
+				let e = Number(v[0]) + 50;
+				let y = Number(v[0]),
+					y_index;
+				let m = Number(v[1]);
+
+				// 年
+				for (var i = s; i <= e; i++) {
+					if (i == y) {
+						//所选年的index 
+						y = i;
+						y_index = e - s - (e - y)
+					}
+					this.years.push(i)
+				}
+				// 月
+				for (var i = 1; i <= 12; i++) {
+					if (i == Number(m)) { //所选月的index
+						m = i;
+						break;
+					}
+				}
+				// 周
+				let res = await weekjs.getWeeksByMonth(y, m,this.val,this.formatType); 
+				this.weeks =  res.arr;
+				this.$set(this.pickerValue, 2, await res.weekIndex - 1)
+				this.$set(this.pickerValue, 0, y_index)
+				this.$set(this.pickerValue, 1, m - 1)
+				this.result = {
+					week: res.week
+				}
+			},
+			// picker change
+			bindChange(e) {
+				let v = e.detail.value;
+				this.pickerValue = v;
+				let y = this.years[v[0]];
+				let m = v[1] + 1;
+				let w = v[2];
+				this.weeks = weekjs.getWeeksByMonth(y, m,this.val,this.formatType).arr;
+				this.result = {
+					week: this.weeks[w]
+				}
+			},
+			onCancel() {
+				this.$emit('change');
+			},
+			onSure() {
+				this.$emit('change', this.result);
+			}
+		}
+
+	}
+</script>
+
+<style lang="scss" scoped>
+	.my-week-picker {
+		background-color: #FFFFFF;
+		border-top: 1px solid #e3e3e3;
+	}
+
+	.my-week-popup_header {
+		box-sizing: border-box;
+		width: 100%;
+		height: 40px;
+		padding: 0 30rpx;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		background-color: #FFFFFF;
+		border-bottom: 1px solid #e3e3e3;
+	}
+
+	.my-week-popup-text {
+		font-size: 16px;
+
+		&.cancel {
+			color: #999;
+		}
+
+		&.sure {
+			color: #007AFF;
+		}
+	}
+
+	.my-week-picker_view {
+		width: 100%;
+		height: 450rpx;
+	}
+
+	.my-week-picker_item {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+
+		&.years {
+			flex: 1;
+		}
+
+		&.months {
+			flex: 1;
+		}
+
+		&.weeks {
+			flex: 3;
+		}
+	}
+
+	.my-week-picker_item_view {
+		font-size: 14px;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		text-align: center;
+	}
+</style>

+ 70 - 0
pages_echarts/components/myWeekPicker/week.js

@@ -0,0 +1,70 @@
+import dayjs from 'dayjs';
+import weekday from 'dayjs/plugin/weekday';
+import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
+import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
+dayjs.extend(weekday)
+dayjs.extend(isSameOrAfter)
+dayjs.extend(isSameOrBefore)
+// 解决苹果电脑本地语言配置
+// require('dayjs/locale/en');
+import 'dayjs/locale/en'
+dayjs.locale('en')
+
+/**
+ * 根据年月份得到周数据
+ * @param {String} y 年
+ * @param {String} m 月
+ * @param {String} v 当前日期
+ * @param {Number} t 格式化类型
+ */
+function getWeeksByMonth(y, m, v, t) {
+    // 2021-12-1是11月的第5周(对这种情况进行判断)
+    if(dayjs(v).date() < dayjs(v).day()){
+        m = m-1
+    }
+    let len = dayjs(`${y}-${m}`).daysInMonth();
+    let arr = [],
+        weekIndex, week;
+    [...Array(len)].forEach((c, i) => {
+        let date = dayjs(`${y}-${m}-${i+1}`);
+        if (date.day() == 1) {
+            let date_start = date.weekday(1);
+            let date_end = date.weekday(7);
+            let index = arr.length + 1;
+            let start = t ? date_start.format('MM月DD日') : date_start.format('MM-DD');
+            let end = t ? date_end.format('MM月DD日') : date_end.format('MM-DD');
+            let obj = {
+                text: `第${index}周(${start}至${end})`,
+                year: y,
+                month: m,
+                val: `${dayjs(date_start).format('YYYY-MM-DD')}`,
+                // start: start + '(周一)',
+                // end: end + '(周日)',
+				start: start,
+				end: end,
+                index: index ,//1:该月第一周   2:该月第二周
+				formatVal: t ? `${y}年${start}至${y}年${end}` : `${y}-${start}至${y}-${end}`
+            }
+            arr.push(obj)
+            // week = obj
+            if (dayjs(v).isSameOrAfter(date_start, 'date') && dayjs(v).isSameOrBefore(
+                    date_end, 'date')) {
+                        week = obj
+                weekIndex = index;
+            }
+        }
+    })
+
+    return {
+        arr,
+        weekIndex,
+        week
+    }
+}
+
+// module.exports = {
+//     getWeeksByMonth
+// }
+export default {
+	getWeeksByMonth
+}

+ 511 - 0
pages_echarts/components/simpleScale/simpleScale.vue

@@ -0,0 +1,511 @@
+
+<template>
+  <view>
+    <!-- 横向 -->
+    <view class='wrapper horizontal-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-if="direction=== 'horizontal'">
+      <view class='scale-mask' v-if="!scroll"/>
+      <!-- 选中的横条  -->
+      <view class='zz triangle' :style="{backgroundColor: stylesObj.lineSelect}"></view>
+      <scroll-view
+        class='scroll-view'
+        :scroll-x="true"
+        :scroll-left="centerNum"
+        :scroll-with-animation="true"
+        @scroll="bindscroll"
+        show-scrollbar="false"
+      >
+
+        <view class='scroll-wrapper'>
+          <!-- 左补白 -->
+          <view class='seat' :style="{width: windowWidth/2 + 'px'}"></view>
+
+          <!-- 标尺容器 -->
+          <view  class='scale-container'>
+            <view class='scale-wrapper'>
+              <view class='scale-grip'
+                    v-for="(item, index) in grid"
+                    :key="index"
+                    :style="{height:h + 'px', borderColor: stylesObj.line}">
+                <view class='scale-grip-item'
+                      v-for="(it, idx) in 10"
+                      :key="idx"
+                      :style="{width: single + 'px', height: idx===4?'86%':'50%', borderColor: stylesObj.line}"
+                />
+              </view>
+            </view>
+            <!-- 标尺数显示,长度:每格长度*个数 -->
+            <view class='scale-vaule-wrapper' :style="{width: single*10*grid + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
+              <view class='scale-value first-scale-value' :style="{width: single*10 + 'px'}">{{min}}</view>
+              <view v-if="int" style="display: flex;">
+                <view
+                  class='scale-vaule'
+                  v-for="(item, index) in grid"
+                  :key="index"
+                  :style="{width:single*10 + 'px'}">{{min+10*(index+1)}}
+                </view>
+              </view>
+              <view v-else style="display: flex;">
+                <view
+                  class='scale-vaule'
+                  v-for="(it, index) in grid"
+                  :key="index"
+                  :style="{width: single*10 + 'px'}">{{min+(index+1)}}
+                </view>
+              </view>
+            </view>
+          </view>
+
+          <!-- 右补白 -->
+          <view class='seat' :style="{width: windowWidth/2 + 'px'}"/>
+        </view>
+      </scroll-view>
+    </view>
+
+    <!-- 竖向 -->
+    <view class='wrapper vertical-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-else-if="direction === 'vertical'">
+      <view class='scale-mask' v-if="!scroll"/>
+      <view class='zz' :style="{backgroundColor: stylesObj.lineSelect}"/>
+      <scroll-view
+        class='scroll-view'
+        style="height: 600rpx;"
+        :scroll-y="true"
+        :scroll-top="centerNum"
+        :scroll-with-animation='true'
+        @scroll="bindscroll"
+        :show-scrollbar="false"
+        :enhanced="true">
+
+        <view class='scroll-wrapper'>
+          <!-- 左补白 -->
+          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>
+
+          <!-- 标尺容器 -->
+          <view  class='scale-container'>
+            <view class='scale-wrapper' :style="{height: single*10*grid + 'px', paddingTop: single*10/2 + 'px'}">
+              <view class='scale-grip'
+                    v-for="(item, index) in grid"
+                    :key="index"
+                    :style="{borderColor: stylesObj.line}">
+                <view class='scale-grip-item'
+                      v-for="(it, idx) in 10"
+                      :key="idx"
+                      :style="{height: single + 'px', width: (idx==4||idx==9) ? '80':'60' + '%', borderColor: stylesObj.line}"
+                />
+              </view>
+            </view>
+            <!-- 标尺数显示,长度:每格长度*个数 -->
+            <view class='scale-vaule-wrapper'
+                  :style="{height: single*10*(grid+1) + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
+              <view class='scale-value' :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min}}</view>
+              <view v-if="int">
+                <view class='scale-vaule'
+                      v-for="(item, index) in grid"
+                      :key="index"
+                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+10*(index+1)}}
+                </view>
+              </view>
+              <view v-else>
+                <view class='scale-vaule'
+                      v-for="(it, index) in grid"
+                      :key="index"
+                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+(index+1)}}
+                </view>
+              </view>
+            </view>
+          </view>
+
+          <!-- 右补白 -->
+          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>
+        </view>
+      </scroll-view>
+    </view>
+  </view>
+</template>
+
+<script>
+/**
+ minVal[number] 默认值 0, // 最小值
+ maxVal[number] 默认值 100, // 最大值
+ int[boolean] 默认值 true, // 是否开启整数模式 ,false为小数模式  true 整数模式
+ single[number] 默认值 10, // 单个格子的实际长度(单位rpx)
+ h[number] 默认值 0,// 自定义高度 初始值为80
+ active[null] 默认值 center ,// 自定义选中位置  (三个值 minVal, maxVal ,center , 范围内合法数值)
+ styles[object]  // 自定义卡尺样式
+ */
+
+export default {
+  name: '',
+  components: {},
+  props: {
+    // 最小值
+    minVal: {
+      type: Number,
+      default: 0,
+    },
+    // 最大值
+    maxVal: {
+      type: Number,
+      default: 100,
+    },
+    // 是否开启整数模式
+    int: {
+      type: Boolean,
+      default: false,
+    },
+    // 每个格子的实际行度 (单位px ,相对默认值)
+    single: {
+      type: Number,
+      default: 10,
+    },
+    // 高度
+    h: {
+      type: Number,
+      default: 40,
+    },
+    // 是否禁止滚动
+    scroll: {
+      type: Boolean,
+      default: true,
+    },
+    // 方向
+    direction: {
+      type: String,
+      default: 'horizontal',
+    },
+    // 当前选中
+    active: {
+      type: null,
+      default: '0',
+    },
+    styles: {
+      type: Object,
+      default:()=> {},
+    },
+
+  },
+  data() {
+    return {
+      defaultStyles: {
+        line: '#dbdbdb', // 刻度颜色
+        bginner: '#fbfbfb', // 前景色颜色
+        bgoutside: '#ffffff', // 背景色颜色
+        lineSelect: '#FF7700', // 选中线颜色
+        fontColor: '#404040', // 刻度数字颜色
+        fontSize: 16, // 字体大小
+      },
+      rul: {},
+      windowHeight: 0,
+      windowWidth: '',
+      horizontalTime: null,
+      verticalTime: null,
+      grid: '',
+      centerNum: '',
+      stylesObj: {},
+	  min: 0,
+	  max: 100,
+    };
+  },
+  computed: {},
+  watch: {},
+  onReady() {
+    // const min = parseInt(this.min, 10) || 0;
+    // const max = parseInt(this.max, 10) || 100;
+    // this.min = min;
+    // this.max = max;
+    // this.init();
+  },
+  created() {
+  },
+  mounted() {
+	  // this.init();
+  },
+  methods: {
+    // 初始化
+    init() {
+      // 设置默认值
+      // const min = this.min || 0;
+      // const max = this.max || 0;
+	  const min = parseInt(this.minVal, 10) || 0;
+	  const max = parseInt(this.maxVal, 10) || 100;
+	  this.min = min;
+	  this.max = max;
+      /**
+       * grid 外层的刻度尺,里面有10个小刻度尺(10个小刻度尺直接拿10遍历出来)
+       * 整数:
+       *  需要除以10,此时里面的一个小刻度尺代表1
+       *  例如:30-80 此时需要5个外层刻度尺。
+       * 小数:
+       *  不需要除以10,此时里面的一个小刻度尺代表0.1
+       *  例如:30-80 此时需要50个外层刻度尺。
+       *
+       */
+      let grid;
+      if (this.int) {
+        grid = (max - min) / 10;
+      } else {
+        grid = (max - min);
+      }
+      this.stylesObj = Object.assign(this.defaultStyles, this.styles);
+      this.grid = grid;
+
+      // 当前选中的 active
+      let activeVal = this.selectActiveVal();
+      if (activeVal < min || activeVal > max) { // 默认数字不合理
+        activeVal = (min + max) / 2;
+      }
+      if (this.int) {
+        let diff = (activeVal - min) / 10; // 移动diff格
+        /* eslint-disable-next-line */
+        if (diff < 0 || isNaN(diff) || !diff) diff = 0;
+        // this.single 每个小格子长度
+        const centerNum = diff * this.single * 10;
+        setTimeout(() => { this.centerNum = centerNum; }, 200);
+      } else {
+        const diff1 = (activeVal - min) * 10; // 移动diff格
+        const centerNum = diff1 * this.single;
+        setTimeout(() => { this.centerNum = centerNum; }, 200);
+      }
+      //  获取节点信息,获取节点宽度
+      const query = uni.createSelectorQuery().in(this);
+      query.select('#scale-wrapper').boundingClientRect(() => {
+        // res.top; // 这个组件内 #the-id 节点的上边界坐标
+      }).exec((e) => {
+        this.windowWidth = e[0].width;
+        this.windowHeight = e[0].height;
+      });
+    },
+    // 给定的选中默认值
+    selectActiveVal() {
+      // 当前选中位置设置
+      let activeVal;
+      if (this.active === 'min') {
+        activeVal = this.min;
+      } else if (this.active === 'max') {
+        activeVal = this.max;
+      } else if (this.active === 'center') {
+        activeVal = (this.min + this.max) / 2;
+      } else {
+        activeVal = this.active ? this.active : this.min;
+      }
+      return activeVal;
+    },
+    // 滚动
+    bindscroll(e) {
+      // 移动的距离
+      let offset = 0;
+      if (this.direction === 'vertical') {
+        offset = e.detail.scrollTop;
+      } else {
+        offset = e.detail.scrollLeft;
+      }
+      // 选中的值
+      let value;
+      if (this.int) {
+        value = this.min + (offset / this.single);
+        value = Math.round(value);
+        if (value > this.max) value = this.max;
+        this.$emit('value', value);
+        const centerNum = (value - this.min) * this.single + Math.random() ** 10;
+        clearTimeout(this.horizontalTime);
+        this.horizontalTime = setTimeout(() => {
+          this.centerNum = centerNum;
+          this.$emit('value', value);
+        }, 100);
+      } else {
+        value = this.min + ((offset / this.single) / 10);
+        value = value.toFixed(1);
+        if (value > this.max) value = this.max;
+        this.$emit('value', value);
+        const centerNum = (value - this.min) * this.single * 10 + Math.random() ** 10;
+        clearTimeout(this.verticalTime);
+        this.verticalTime = setTimeout(() => {
+          this.centerNum = centerNum;
+          this.$emit('value', value);
+        }, 100);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+  view,text {
+    box-sizing: border-box;
+  }
+  .wrapper {
+    position: relative;
+  }
+  .scale-mask {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    z-index: 100;
+  }
+  .horizontal-box {
+    // padding-top: 7%;
+    .scroll-wrapper {
+      position: relative;
+      display: flex;
+    }
+    .zz {
+      position: absolute;
+      left: 50%;
+      top: 0;
+      transform: translate(-50%);
+      height: 100%;
+      width: 2rpx;
+      background-color: #FF7700;
+      z-index: 10;
+    }
+	.triangle::after {
+		position: absolute;
+		left: 50%;
+		top: 0;
+		transform: translateX(-50%);
+		content: "";
+		height: 0;
+		border-top: 16rpx solid #FF7700;
+		border-bottom: 16rpx solid transparent;
+		border-left: 10rpx solid transparent;
+		border-right: 10rpx solid transparent;
+	}
+    .scale-wrapper {
+      display: flex;
+      border-top: 1px solid #dddddd;
+    }
+    .scale-grip {
+      position: relative;
+      height: 100rpx;
+      display: flex;
+      &::before {
+        content: "";
+        position: absolute;
+        top: 0;
+        border-width: 1px;
+        border-color: inherit;
+        border-style: solid;
+        height: 100%;
+        transform: translateX(-50%);
+        left: 0rpx;
+      }
+      &:last-child {
+        &::after {
+          content: "";
+          position: absolute;
+          top: 0;
+          right: 0;
+          border-width: 1px;
+          border-color: inherit;
+          border-style: solid;
+          height: 100%;
+        }
+      }
+    }
+    .scale-grip-item {
+      height: 50%;
+      padding-top: 10rpx;
+      &:not(:last-child) {
+        border-right: 1px solid #000000;
+      }
+    }
+    .scale-vaule-wrapper {
+      position: relative;
+      display: flex;
+      text-align: center;
+    }
+    .scale-vaule {
+      padding: 30rpx 0;
+      transform: translateX(50%);
+    }
+    .first-scale-value {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      padding: 20rpx 0;
+      transform: translateX(-50%);
+    }
+    .seat {
+      flex-shrink: 0;
+      box-sizing: border-box;
+      border-top: 1px solid #ddd;
+    }
+  }
+  /* .scale-container{
+    display: flex;
+  } */
+  .vertical-box {
+    height: 100%;
+    .scroll-wrapper {
+      position: relative;
+    }
+    .scroll-view {
+      height: 100%;
+    }
+    .zz {
+      position: absolute;
+      top: 50%;
+      left: 0;
+      transform: translate(-50%);
+      width: 40%;
+      height: 2px;
+      background-color: #FF7700;
+      z-index: 10;
+    }
+    .scale-container {
+      display: flex;
+      width: 100%;
+    }
+    .scale-wrapper {
+      flex: 1;
+    }
+    .scale-grip {
+      position: relative;
+      border-left: 1px solid #000000;
+      &:first-child {
+        &::before {
+          content: "";
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 80%;
+          height: 0;
+          border-top: 1px solid #dbdbdb;
+        }
+      }
+    }
+    .scale-grip-item {
+      height: 60%;
+      padding-top: 10rpx;
+      border-bottom: 1px solid #000000;
+    }
+    .scale-vaule-wrapper {
+      position: relative;
+      text-align: left;
+      flex: 1;
+    }
+    .scale-vaule {
+    }
+  }
+  /* .vertical-box .scale-grip:last-child::after{
+    content: "";
+    position: absolute;
+    top: 0;
+    left:0;
+    border-width: 1px;
+    border-color: inherit;
+    border-style: solid;
+    width: 100%;
+  } */
+  /* .vertical-box .first-scale-value{
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    padding: 20rpx 0;
+    transform: translateX(-50%);
+  } */
+  /* .vertical-box .seat {
+    flex-shrink: 0;
+    box-sizing: border-box;
+  } */
+
+</style>

+ 378 - 0
pages_echarts/hips.vue

@@ -0,0 +1,378 @@
+<template>
+	<view class="hb column hidden container">
+		<image class="bg" src="/static/images/health/hips_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="臀围" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<!-- <view class="pub-tab-box">
+				<view class="tab-inner">
+					<view v-for="(item,index) in times" :key="index" :class="item.val == aIndex?'item active':'item'"
+						@click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view> -->
+			<dateTimePicker @onChange="onChangeTime" :tab-color="'purple'"/>
+		</view>
+		<scroll-view class="content" :scroll-y="true">
+			<view class="content-box">
+				<view class="box-tab">
+					<view class="item active">图表</view>
+					<view class="item">列表</view>
+				</view>
+				<view class="h40"></view>
+				<view class="subtitle">单位:CM</view>
+				<view class="charts-box">
+					<qiun-data-charts type="line" :opts="opts" :chartData="chartData" />
+				</view>
+			</view>
+			<view class="h40"></view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="navgetTo()">记录</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import dateTimePicker from "@/pages_echarts/components/dateTimePicker/dateTimePicker.vue"
+	export default {
+		components: {
+			dateTimePicker
+		},	
+		data() {
+			return {
+				statusBarHeight: '',
+				top: 0,
+				aIndex: 0,
+				times: [{
+						name: "每日",
+						val: 0
+					},
+					{
+						name: "每周",
+						val: 1
+					},
+					{
+						name: "每月",
+						val: 2
+					}
+				],
+				indexInfo: [],
+				chartData: {},
+				opts: {
+					color: ["#FDBD27", "#FF5030"],
+					padding: [15, 10, 10, 15],
+					enableScroll: false,
+					dataLabel: false,
+					dataPointShapeType: 'hollow',
+					tapLegend: false,
+					legend: {
+
+					},
+					xAxis: {
+						// disableGrid: true
+						axisLine: false,
+						fontColor: '#CCCCCC'
+					},
+					yAxis: {
+						// showTitle:true,
+						// title:"单位:mmol/L",
+
+						gridType: "dash",
+						dashLength: 2,
+						data: [{
+							axisLine: false,
+							fontColor: '#CCCCCC'
+						}]
+						// fontColor:'#CCCCCC'
+					},
+					extra: {
+						  line: {
+						             type: "straight",
+						             width: 2,
+						             activeType: "hollow"
+						           }
+					}
+				}
+			}
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			// 获取系统信息
+			const sys = uni.getSystemInfoSync()
+			this.statusBarHeight = sys.statusBarHeight + 'px'
+			this.getServerData();
+		},
+		onUnload() { //普通页面在 onUnload 生命周期中执行
+			uni.$emit('stop')
+		},
+		onHide() { //tabBar页面在onHide生命周期中执行
+			uni.$emit('stop')
+		},
+		onPageScroll(e) {
+			//console.log(e)
+			this.top = e.scrollTop;
+		},
+		methods: {
+			// tab切换
+			orderStatusChange(item) {
+				this.aIndex = item.val
+			},
+			onChangeTime(time) {
+				const param = {
+					startTime: this.utils.timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
+					endTime: this.utils.timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
+					deviceId: ''
+				}
+				// this.queryParam = param
+				// this.getServerData(param)
+				// this.getAbnormalInfo(param)
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: ["周一", "周二", "周三", "周四", "周五"],
+						series: [{
+							name: "测量值",
+							data:[0,100,0,0,0]
+						}
+
+						]
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+			navgetTo(index) {
+				uni.navigateTo({
+					url: '/pages_echarts/acidList'
+				})
+			},
+			goToUser() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		position: relative;
+
+		.bg {
+			width: 100%;
+			height: 380rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+	}
+
+	.top-fixed {
+		width: 100%;
+		position: fixed;
+		top: calc(var(--status-bar-height) + 140rpx);
+		left: 0;
+		z-index: 10;
+	}
+
+	.pub-tab-box {
+		box-sizing: border-box;
+		width: 400rpx;
+		// padding: 0 60rpx;
+		margin: 0 auto;
+
+		// background-color: #FFFFFF;
+		.tab-inner {
+			height: 88upx;
+			line-height: 88upx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			overflow-x: auto;
+		}
+
+		.item {
+			font-family: PingFang SC;
+			font-weight: 400;
+			font-size: 30rpx;
+			color: #626468;
+			line-height: 64rpx;
+			text-align: center;
+
+			&:last-child {
+				margin-right: 0;
+			}
+
+			&.active {
+				font-weight: 500;
+				width: 124rpx;
+				height: 64rpx;
+				background: #7A73E0;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				color: #fff;
+			}
+
+			.text {
+				position: relative;
+				z-index: 1;
+			}
+
+			.tab-bg {
+				width: 72upx;
+				height: 28upx;
+				position: absolute;
+				top: 17upx;
+				left: 50%;
+				transform: translateX(-36upx);
+				z-index: -1;
+			}
+		}
+	}
+
+	.content {
+		padding-top: calc(var(--status-bar-height) + 320rpx) !important;
+		height: 100vh;
+		box-sizing: border-box;
+		width: 100%;
+		// padding: 0 24rpx 24rpx 24rpx;
+		overflow: hidden;
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.sub-btn {
+				width: 388rpx;
+				height: 72rpx;
+				line-height: 72upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #7A73E0;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+
+		.content-box {
+			// width: 100%;
+			background: #FFFFFF;
+			border-radius: 40rpx 40rpx 16rpx 16rpx;
+			// padding: 24rpx;
+			margin: auto 10px;
+			overflow: hidden;
+			// padding-bottom: 20rpx;
+
+			.tltle {
+				font-family: PingFang SC;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #222426;
+				text-align: left;
+				margin-bottom: 16rpx;
+			}
+
+			.subtitle {
+				padding-left: 24rpx;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+				text-align: left;
+
+			}
+
+			/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
+			.charts-box {
+				padding: 24rpx;
+				// width: 100%;
+				height: 500rpx;
+				margin-top: 30rpx;
+			}
+
+			.more {
+				display: flex;
+				align-items: center;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+			}
+          .box-tab{
+			  display: flex;
+			  align-items: center;
+			  height: 100rpx;
+			  line-height: 100rpx;
+			  background: linear-gradient( 360deg, #EFE9FA 0%, #D4D1FF 100%);
+			  // background: url(@/static/images/health/hip_circumference_tab_switch_bg.png) no-repeat  center center / cover;
+				  .item {
+				  	font-family: PingFang SC;
+				  	font-weight: 400;
+				  	font-size: 36rpx;
+				  	color: #626468;
+				  	flex:1;
+				  	text-align: center;
+					display: flex;
+					    align-items: flex-end;
+					    justify-content: center;
+				  	&.active {
+				  		background: #fff;
+				  		color: #7A73E0;
+						font-weight: bold;
+						border-radius: 40rpx 40rpx 0 0;
+						// box-shadow: 5rpx 0px 15rpx rgba(0, 0, 0, 0.1);
+						&::after {
+							content: "";
+							width: 36rpx;
+							height: 8rpx;
+							background: #7A73E0;
+							border-radius: 4rpx 4rpx 4rpx 4rpx;
+							position: absolute;
+							// bottom: 0;
+						}
+						
+				  	}
+				  
+				  	.text {
+				  		position: relative;
+				  		z-index: 1;
+				  	}
+				  
+				  	.tab-bg {
+				  		width: 72upx;
+				  		height: 28upx;
+				  		position: absolute;
+				  		top: 17upx;
+				  		left: 50%;
+				  		transform: translateX(-36upx);
+				  		z-index: -1;
+				  	}
+				  }
+		  }
+		
+
+			
+		}
+	}
+</style>

+ 378 - 0
pages_echarts/waistLine.vue

@@ -0,0 +1,378 @@
+<template>
+	<view class="hb column hidden container">
+		<image class="bg" src="/static/images/health/waist_circumference_top_bg.png" mode="widthFix"></image>
+		<view :style="{height: statusBarHeight,background: bgColor }"></view>
+		<u-navbar title="腰围" titleStyle="font-weight: bold;" @rightClick="rightClick" :autoBack="true"
+			:bg-color="bgColor">
+		</u-navbar>
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<!-- <view class="pub-tab-box">
+				<view class="tab-inner">
+					<view v-for="(item,index) in times" :key="index" :class="item.val == aIndex?'item active':'item'"
+						@click="orderStatusChange(item)">
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view> -->
+			<dateTimePicker @onChange="onChangeTime" :tab-color="'orange'"/>
+		</view>
+		<scroll-view class="content" :scroll-y="true">
+			<view class="content-box">
+				<view class="box-tab">
+					<view class="item active">图表</view>
+					<view class="item">列表</view>
+				</view>
+				<view class="h40"></view>
+				<view class="subtitle">单位:CM</view>
+				<view class="charts-box">
+					<qiun-data-charts type="line" :opts="opts" :chartData="chartData" />
+				</view>
+			</view>
+			<view class="h40"></view>
+			<view class="btn-box">
+				<view class="sub-btn" @click="navgetTo()">记录</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import dateTimePicker from "@/pages_echarts/components/dateTimePicker/dateTimePicker.vue"
+	export default {
+		components: {
+			dateTimePicker
+		},
+		data() {
+			return {
+				statusBarHeight: '',
+				top: 0,
+				aIndex: 0,
+				times: [{
+						name: "每日",
+						val: 0
+					},
+					{
+						name: "每周",
+						val: 1
+					},
+					{
+						name: "每月",
+						val: 2
+					}
+				],
+				indexInfo: [],
+				chartData: {},
+				opts: {
+					color: ["#FDBD27", "#FF5030"],
+					padding: [15, 10, 10, 15],
+					enableScroll: false,
+					dataLabel: false,
+					dataPointShapeType: 'hollow',
+					tapLegend: false,
+					legend: {
+
+					},
+					xAxis: {
+						// disableGrid: true
+						axisLine: false,
+						fontColor: '#CCCCCC'
+					},
+					yAxis: {
+						// showTitle:true,
+						// title:"单位:mmol/L",
+
+						gridType: "dash",
+						dashLength: 2,
+						data: [{
+							axisLine: false,
+							fontColor: '#CCCCCC'
+						}]
+						// fontColor:'#CCCCCC'
+					},
+					extra: {
+						  line: {
+						             type: "straight",
+						             width: 2,
+						             activeType: "hollow"
+						           }
+					}
+				}
+			}
+		},
+		computed: {
+			// 计算属性的 getter
+			bgColor: function() {
+				var top = this.top / 30;
+				return 'rgba(11,179,242, ' + top + ')';
+			},
+		},
+		onLoad() {
+			// 获取系统信息
+			const sys = uni.getSystemInfoSync()
+			this.statusBarHeight = sys.statusBarHeight + 'px'
+			this.getServerData();
+		},
+		onUnload() { //普通页面在 onUnload 生命周期中执行
+			uni.$emit('stop')
+		},
+		onHide() { //tabBar页面在onHide生命周期中执行
+			uni.$emit('stop')
+		},
+		onPageScroll(e) {
+			//console.log(e)
+			this.top = e.scrollTop;
+		},
+		methods: {
+			// tab切换
+			orderStatusChange(item) {
+				this.aIndex = item.val
+			},
+			onChangeTime(time) {
+				const param = {
+					startTime: this.utils.timeFormat(time[0],'yyyy/mm/dd hh:MM:ss'),
+					endTime: this.utils.timeFormat(time[1],'yyyy/mm/dd hh:MM:ss'),
+					deviceId: ''
+				}
+				// this.queryParam = param
+				// this.getServerData(param)
+				// this.getAbnormalInfo(param)
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: ["周一", "周二", "周三", "周四", "周五"],
+						series: [{
+							name: "测量值",
+							data:[0,100,0,0,0]
+						}
+
+						]
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+			navgetTo(index) {
+				uni.navigateTo({
+					url: '/pages_echarts/acidList'
+				})
+			},
+			goToUser() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		position: relative;
+
+		.bg {
+			width: 100%;
+			height: 380rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+	}
+
+	.top-fixed {
+		width: 100%;
+		position: fixed;
+		top: calc(var(--status-bar-height) + 140rpx);
+		left: 0;
+		z-index: 10;
+	}
+
+	.pub-tab-box {
+		box-sizing: border-box;
+		width: 400rpx;
+		// padding: 0 60rpx;
+		margin: 0 auto;
+
+		// background-color: #FFFFFF;
+		.tab-inner {
+			height: 88upx;
+			line-height: 88upx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			overflow-x: auto;
+		}
+
+		.item {
+			font-family: PingFang SC;
+			font-weight: 400;
+			font-size: 30rpx;
+			color: #626468;
+			line-height: 64rpx;
+			text-align: center;
+
+			&:last-child {
+				margin-right: 0;
+			}
+
+			&.active {
+				font-weight: 500;
+				width: 124rpx;
+				height: 64rpx;
+				background: #FF5039;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				color: #fff;
+			}
+
+			.text {
+				position: relative;
+				z-index: 1;
+			}
+
+			.tab-bg {
+				width: 72upx;
+				height: 28upx;
+				position: absolute;
+				top: 17upx;
+				left: 50%;
+				transform: translateX(-36upx);
+				z-index: -1;
+			}
+		}
+	}
+
+	.content {
+		padding-top: calc(var(--status-bar-height) + 320rpx) !important;
+		height: 100vh;
+		box-sizing: border-box;
+		width: 100%;
+		// padding: 0 24rpx 24rpx 24rpx;
+		overflow: hidden;
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.sub-btn {
+				width: 388rpx;
+				height: 72rpx;
+				line-height: 72upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #FF5039;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+
+		.content-box {
+			// width: 100%;
+			background: #FFFFFF;
+			border-radius: 40rpx 40rpx 16rpx 16rpx;
+			// padding: 24rpx;
+			margin: auto 10px;
+			overflow: hidden;
+			// padding-bottom: 20rpx;
+
+			.tltle {
+				font-family: PingFang SC;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #222426;
+				text-align: left;
+				margin-bottom: 16rpx;
+			}
+
+			.subtitle {
+				padding-left: 24rpx;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+				text-align: left;
+
+			}
+
+			/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
+			.charts-box {
+				padding: 24rpx;
+				// width: 100%;
+				height: 500rpx;
+				margin-top: 30rpx;
+			}
+
+			.more {
+				display: flex;
+				align-items: center;
+				font-family: PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #898E91;
+			}
+          .box-tab{
+			  display: flex;
+			  align-items: center;
+			  height: 100rpx;
+			  line-height: 100rpx;
+			  background: linear-gradient( 360deg, #F9EDEC 0%, #FFD6D2 100%);
+			  // background: url(@/static/images/health/hip_circumference_tab_switch_bg.png) no-repeat  center center / cover;
+				  .item {
+				  	font-family: PingFang SC;
+				  	font-weight: 400;
+				  	font-size: 36rpx;
+				  	color: #626468;
+				  	flex:1;
+				  	text-align: center;
+					display: flex;
+					    align-items: flex-end;
+					    justify-content: center;
+				  	&.active {
+				  		background: #fff;
+				  		color: #FF5039;
+						font-weight: bold;
+						border-radius: 40rpx 40rpx 0 0;
+						// box-shadow: 5rpx 0px 15rpx rgba(0, 0, 0, 0.1);
+						&::after {
+							content: "";
+							width: 36rpx;
+							height: 8rpx;
+							background: #FF5039;
+							border-radius: 4rpx 4rpx 4rpx 4rpx;
+							position: absolute;
+							// bottom: 0;
+						}
+						
+				  	}
+				  
+				  	.text {
+				  		position: relative;
+				  		z-index: 1;
+				  	}
+				  
+				  	.tab-bg {
+				  		width: 72upx;
+				  		height: 28upx;
+				  		position: absolute;
+				  		top: 17upx;
+				  		left: 50%;
+				  		transform: translateX(-36upx);
+				  		z-index: -1;
+				  	}
+				  }
+		  }
+		
+
+			
+		}
+	}
+</style>

+ 411 - 0
pages_health/addCompetitors.vue

@@ -0,0 +1,411 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="form-box">
+				<view class="form-item">
+					<text class="label">竞品公司</text>
+					<input  class="input-width" type="text" v-model="form.userName" placeholder="请输入竞品公司"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">产品</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入产品"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">价格</text>
+					<input  class="input-width" type="text" v-model="form.userName" placeholder="请输入价格"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">服务</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入竞品公司服务方式"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">免费服务次数</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入服务次数"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="submit()">
+				<image src="/static/images/health/nav_add_icon24.png" class="w48 h48"></image>
+				<text>新增竞品信息</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				array:['是','否'],
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			sexChange(type) {
+				this.form.sex = type
+			},
+			radioClick(item) {
+			        this.checked=item.id
+			      },
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			onChooseAvatar(e){
+				let {
+					avatarUrl
+				} = e.detail;
+				uni.uploadFile({
+					url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+					filePath: avatarUrl,
+					name: 'file',
+					formData: {
+						'user': 'test'  // 上传附带参数
+					},
+					success: (uploadFileRes) => {
+						this.user.avatar =JSON.parse(uploadFileRes.data).url
+					}
+				});
+			},
+			submit() {
+				// if (this.form.userName == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "姓名不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.idCard == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "身份证号不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.sex == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "性别不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.birthday == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "出生年月不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.type == "add") {
+				// 	this.addDoc()
+				// } else if (this.type == "edit") {
+				// 	this.editDoc()
+				// }
+                uni.navigateTo({
+                	url: '/pages_health/doc?type=edit&docId='
+                })
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding: 20upx;
+
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-bottom: 20upx;
+
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 600;
+					font-size: 40rpx;
+					color: #222426;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: flex-start;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+        
+					.label {
+						width: 300upx;
+						text-align: left;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+
+					input {
+						text-align: right;
+					}
+               
+					.form-input {
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						text-align: right;
+					}
+
+					.form-item-tag{
+						margin-right: 16rpx;
+						.tag{
+							border-radius: 8rpx 8rpx 8rpx 8rpx;
+							border: 2rpx solid #ECECEC;
+							display: flex;
+							align-items: center;
+							padding: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							&.active{
+								background: #F0FAFF;
+								border: 2rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+						
+						
+					}
+					.right{
+						display: flex;
+						align-items: center;
+					}
+					.sex-box{
+						flex:1;
+						display: flex;
+						align-items: center;
+						justify-content: flex-end;
+						.sex-item{
+							width: 146rpx;
+							height: 64rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							background: #F5F7FA;
+							border-radius: 32rpx 32rpx 32rpx 32rpx;
+							margin-left: 16rpx;
+							.u-icon__icon{
+								margin: 0;
+							}
+							text{
+								// font-family: PingFang SC, PingFang SC;
+								font-weight: 400;
+								font-size: 28rpx;
+								color: #898E91;
+								margin-left: 12rpx;
+							}
+							&.active{
+								background: #FCF0E7;
+								text{
+									color:#FF5030
+								}
+							}
+						}
+					}
+					.form-textarea{
+						font-size: 30upx;
+						color: #999999;
+						height: 100upx;
+						padding: 4upx 0;
+					}
+					 
+					.birth-picker {
+						flex: 1;
+						display: flex;
+						align-items: center;
+						
+						.right-box{
+							width: 100%;
+							display: flex;
+							align-items: center;
+							.input-box{
+								// width: 470upx;
+							}
+							.arrow{
+								width: 13upx;
+								height: 23upx;
+								margin-left: 20upx;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			// position: fixed;
+			// width: 90%;
+			// bottom: 0;
+			// left: 50%;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3 ;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+	}
+</style>

+ 494 - 0
pages_health/addDoc.vue

@@ -0,0 +1,494 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="form-box">
+				<text class="form-title">身体信息</text>
+				<view class="form-item">
+					<text class="label">身高</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入身高"
+						placeholder-class="form-input" />
+					<text class="unit">cm</text>
+				</view>
+				<view class="form-item">
+					<text class="label">体重</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入体重"
+						placeholder-class="form-input" />
+					<text class="unit">kg</text>
+				</view>
+				<view class="form-item">
+					<text class="label">腰围</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入腰围"
+						placeholder-class="form-input" />
+					<text class="unit">cm</text>
+				</view>
+				<view class="form-item">
+					<text class="label">臀围</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入臀围"
+						placeholder-class="form-input" />
+					<text class="unit">cm</text>
+				</view>
+
+
+			</view>
+			<view class="form-box">
+				<text class="form-title">疾病史</text>
+				<view class="form-item">
+					<text class="label">高血糖</text>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(1)" value="1" :checked="form.sex===1"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">无</text>
+						</label>
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(2)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">轻微</text>
+						</label>
+						<label>
+							<radio @click="sexChange(3)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">严重</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="form-item">
+					<text class="label">测量值</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入测量值"
+						placeholder-class="form-input" />
+					<text class="unit">mmol/L</text>
+				</view>
+				<view class="form-item">
+					<text class="label">高血压</text>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(1)" value="1" :checked="form.sex===1"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">无</text>
+						</label>
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(2)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">轻微</text>
+						</label>
+						<label>
+							<radio @click="sexChange(3)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">严重</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="form-item">
+					<text class="label">收缩压</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入测量值"
+						placeholder-class="form-input" />
+					<text class="unit">mmHg</text>
+				</view>
+				<view class="form-item">
+					<text class="label">舒张压</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入测量值"
+						placeholder-class="form-input" />
+					<text class="unit">mmHg</text>
+				</view>
+				<view class="form-item">
+					<text class="label">高血脂</text>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(1)" value="1" :checked="form.sex===1"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">无</text>
+						</label>
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(2)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">轻微</text>
+						</label>
+						<label>
+							<radio @click="sexChange(3)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">严重</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="form-item">
+					<text class="label">高尿酸</text>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(1)" value="1" :checked="form.sex===1"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">无</text>
+						</label>
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(2)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">轻微</text>
+						</label>
+						<label>
+							<radio @click="sexChange(3)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">严重</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="form-item">
+					<text class="label">测量值</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入测量值"
+						placeholder-class="form-input" />
+					<text class="unit">μmol/L</text>
+				</view>
+				<view class="form-item">
+					<text class="label">高体重</text>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(1)" value="1" :checked="form.sex===1"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">正常</text>
+						</label>
+						<label style="margin-right: 50upx;">
+							<radio @click="sexChange(2)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">偏瘦</text>
+						</label>
+						<label>
+							<radio @click="sexChange(3)" value="2" :checked="form.sex===2"
+								style="margin-right: 16upx;" />
+							<text class="sex-text">偏重</text>
+						</label>
+					</radio-group>
+				</view>
+
+			</view>
+			<view class="form-box">
+				<text class="form-title">其他病史</text>
+				<view class="form-item wrap">
+					<view class="form-item-tag" v-for="(item, index) in tags" :key="index" @click="radioClick(item)">
+					<view :class="checked==item.id?'tag active':'tag'">
+						{{item.name}}
+					</view>
+					</view>
+					<view class="form-item-tag mt16">
+						<view class="tag">
+							+ 其他
+						</view>
+						
+					</view>
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">症状史</text>
+				<view class="form-item wrap">
+					<view class="form-item-tag" v-for="(item, index) in tags" :key="index" @click="radioClick(item)">
+						<view :class="checked==item.id?'tag active':'tag'">
+							{{item.name}}
+						</view>
+					</view>
+					<view class="form-item-tag mt16">
+						<view class="tag">
+							+ 其他
+						</view>
+						
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="submit()">保存</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			sexChange(type) {
+				this.form.sex = type
+			},
+			radioClick(item) {
+			        this.checked=item.id
+			      },
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			submit() {
+				if (this.form.userName == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "姓名不能为空",
+					});
+					return;
+				}
+				if (this.form.idCard == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "身份证号不能为空",
+					});
+					return;
+				}
+				if (this.form.sex == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "性别不能为空",
+					});
+					return;
+				}
+				if (this.form.birthday == null) {
+					uni.showToast({
+						icon: 'none',
+						title: "出生年月不能为空",
+					});
+					return;
+				}
+				if (this.type == "add") {
+					this.addDoc()
+				} else if (this.type == "edit") {
+					this.editDoc()
+				}
+
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding: 20upx;
+
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-bottom: 20upx;
+
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 600;
+					font-size: 40rpx;
+					color: #222426;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: flex-start;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+        
+					.label {
+						width: 150upx;
+						text-align: left;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+
+					input {
+						text-align: left;
+					}
+
+					.unit {
+						width: 150upx;
+						text-align: right;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+               
+					.form-input {
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						text-align: left;
+					}
+
+					.form-item-tag{
+						margin-right: 16rpx;
+						.tag{
+							border-radius: 8rpx 8rpx 8rpx 8rpx;
+							border: 2rpx solid #ECECEC;
+							display: flex;
+							align-items: center;
+							padding: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							&.active{
+								background: #F0FAFF;
+								border: 2rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+						
+						
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			// position: fixed;
+			// width: 90%;
+			// bottom: 0;
+			// left: 50%;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+	}
+</style>

+ 433 - 0
pages_health/addServe.vue

@@ -0,0 +1,433 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="form-box">
+				<view class="form-item">
+					<text class="label">商品名称</text>
+					<input  class="input-width" type="text" v-model="form.userName" placeholder="请输入商品名称"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">出生年月</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择出生年月" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="form-item">
+					<text class="label">金额</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入金额"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">预计用完时间</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择时间" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="form-item">
+					<text class="label">购买次数</text>
+					<input  class="input-width" type="text" v-model="form.userName" placeholder="请输入购买次数"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">剩余次数</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入剩余次数"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">会员情况</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入会员情况"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="submit()">
+				<image src="/static/images/health/nav_add_icon24.png" class="w48 h48"></image>
+				<text>新增商品信息</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				array:['是','否'],
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			sexChange(type) {
+				this.form.sex = type
+			},
+			radioClick(item) {
+			        this.checked=item.id
+			      },
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			onChooseAvatar(e){
+				let {
+					avatarUrl
+				} = e.detail;
+				uni.uploadFile({
+					url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+					filePath: avatarUrl,
+					name: 'file',
+					formData: {
+						'user': 'test'  // 上传附带参数
+					},
+					success: (uploadFileRes) => {
+						this.user.avatar =JSON.parse(uploadFileRes.data).url
+					}
+				});
+			},
+			submit() {
+				// if (this.form.userName == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "姓名不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.idCard == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "身份证号不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.sex == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "性别不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.birthday == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "出生年月不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.type == "add") {
+				// 	this.addDoc()
+				// } else if (this.type == "edit") {
+				// 	this.editDoc()
+				// }
+                uni.navigateTo({
+                	url: '/pages_health/doc?type=edit&docId='
+                })
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding: 20upx;
+
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-bottom: 20upx;
+
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 600;
+					font-size: 40rpx;
+					color: #222426;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: flex-start;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+        
+					.label {
+						width: 300upx;
+						text-align: left;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+
+					input {
+						text-align: right;
+					}
+               
+					.form-input {
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						text-align: right;
+					}
+
+					.form-item-tag{
+						margin-right: 16rpx;
+						.tag{
+							border-radius: 8rpx 8rpx 8rpx 8rpx;
+							border: 2rpx solid #ECECEC;
+							display: flex;
+							align-items: center;
+							padding: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							&.active{
+								background: #F0FAFF;
+								border: 2rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+						
+						
+					}
+					.right{
+						display: flex;
+						align-items: center;
+					}
+					.sex-box{
+						flex:1;
+						display: flex;
+						align-items: center;
+						justify-content: flex-end;
+						.sex-item{
+							width: 146rpx;
+							height: 64rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							background: #F5F7FA;
+							border-radius: 32rpx 32rpx 32rpx 32rpx;
+							margin-left: 16rpx;
+							.u-icon__icon{
+								margin: 0;
+							}
+							text{
+								// font-family: PingFang SC, PingFang SC;
+								font-weight: 400;
+								font-size: 28rpx;
+								color: #898E91;
+								margin-left: 12rpx;
+							}
+							&.active{
+								background: #FCF0E7;
+								text{
+									color:#FF5030
+								}
+							}
+						}
+					}
+					.form-textarea{
+						font-size: 30upx;
+						color: #999999;
+						height: 100upx;
+						padding: 4upx 0;
+					}
+					 
+					.birth-picker {
+						flex: 1;
+						display: flex;
+						align-items: center;
+						
+						.right-box{
+							width: 100%;
+							display: flex;
+							align-items: center;
+							.input-box{
+								// width: 470upx;
+							}
+							.arrow{
+								width: 13upx;
+								height: 23upx;
+								margin-left: 20upx;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			// position: fixed;
+			// width: 90%;
+			// bottom: 0;
+			// left: 50%;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3 ;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+	}
+</style>

+ 611 - 0
pages_health/addUser.vue

@@ -0,0 +1,611 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="form-box">
+				<text class="form-title">基本信息</text>
+				<view class="form-item justify-between">
+					<text class="label">头像</text>
+					<view class="right">
+						<image :src="maleurl" class="w90 h90"></image>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						<!-- <button class="wx-head" type="balanced" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
+						</button> -->
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">性别</text>
+					<view class="sex-box">
+						<view :class="form.sex===1?'sex-item active':'sex-item'"  @click="sexChange(1)" >
+							<u-icon name="man" :color="form.sex===1?'#FF5030':'#898E91'" size="20"></u-icon>
+							<text>男</text>
+						</view>
+						<view :class="form.sex===2?'sex-item active':'sex-item'"  @click="sexChange(2)" >
+							<u-icon name="woman" :color="form.sex===2?'#FF5030':'#898E91'" size="20"></u-icon>
+							<text>女</text>
+						</view>
+					</view>
+				</view>
+				<view class="form-item">
+					<text class="label">出生年月</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择出生年月" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="form-item">
+					<text class="label">手机号</text>
+					<input maxlength="11" class="input-width" type="idcard" v-model="form.idCard" placeholder="请输入手机号" placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">身份证号</text>
+					<input maxlength="18" class="input-width" type="idcard" v-model="form.idCard" placeholder="请如实填写身份证号" placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">退休前工作单位</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入工作单位"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">可支配收入</text>
+					<input  class="input-width" type="text" v-model="form.userName" placeholder="请输入支配收入"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">实际消费</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入实际消费"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">家庭地址及居住情况</text>
+				
+				<view class="form-item">
+					<text class="label">市区</text>
+					<picker class="birth-picker" mode="region"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择市区" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+					
+				</view>
+				<view class="form-item">
+					<text class="label">小区名称</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入小区名称"
+						placeholder-class="form-input" />
+				
+				</view>
+				<view class="form-item">
+					<text class="label">门牌</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入门牌号"
+						placeholder-class="form-input" />
+				
+				</view>
+				
+				
+				<view class="form-item">
+					<text class="label">面积</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入面积"
+						placeholder-class="form-input" />
+				</view>
+				
+                 <view class="form-item">
+					<text class="label">楼层</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入楼层"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">家庭情况</text>
+				<view class="form-item">
+					<text class="label">伴侣</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入伴侣姓名"
+						placeholder-class="form-input" />
+				
+				</view>
+				<view class="form-item">
+					<text class="label">伴侣年龄</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入伴侣年龄"
+						placeholder-class="form-input" />
+				
+				</view>
+				
+				
+				<view class="form-item">
+					<text class="label">子辈单位</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入子辈工作单位"
+						placeholder-class="form-input" />
+				</view>
+				
+				 <view class="form-item">
+					<text class="label">孙辈学校</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入所在学校"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">会员情况</text>
+				<view class="form-item">
+					<text class="label">是否是会员</text>
+				<picker class="birth-picker" mode="selector"  @change="bindDateChange" :range="array">
+					<view class="right-box">
+						<view class="input-box">
+							<input type="text" :value="form.birthday" placeholder="请选择是否是会员" placeholder-class="form-input" disabled="disabled" />
+						</view>
+						<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+					</view>
+				</picker>
+				
+				</view>
+				<view class="form-item">
+					<text class="label">会员分类</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择会员分类" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				
+				</view>
+				
+				
+				<view class="form-item">
+					<text class="label">加入时间</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择加入时间" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+				
+				 <view class="form-item">
+					<text class="label">到期时间</text>
+					<picker class="birth-picker" mode="date"   @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择到期时间" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="form-item">
+					<text class="label">管理月份</text>
+					<picker class="birth-picker" mode="date" fields="month" @change="bindDateChange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" :value="form.birthday" placeholder="请选择管理月份" placeholder-class="form-input" disabled="disabled" />
+							</view>
+							<image class="w48 h48" src="/static/images/health/right_arrow_right_icon24.png"></image>
+						</view>
+					</picker>
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">特殊情况</text>
+				<view class="form-item">
+					<text class="label">职位</text>
+					<input class="input-width" type="text" v-model="form.userName" placeholder="请输入职位"
+						placeholder-class="form-input" />
+				
+				</view>
+				<view class="form-item">
+					<text class="label">癖好</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入癖好"
+						placeholder-class="form-input" />
+				
+				</view>
+				
+				
+				<view class="form-item">
+					<text class="label">平日喜好</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入平日喜好"
+						placeholder-class="form-input" />
+				</view>
+				
+				 <view class="form-item">
+					<text class="label">信仰</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入信仰"
+						placeholder-class="form-input" />
+				</view>
+				<view class="form-item">
+					<text class="label">担忧</text>
+					<input maxlength="10" class="input-width" type="text" v-model="form.userName" placeholder="请输入信仰"
+						placeholder-class="form-input" />
+				</view>
+			</view>
+			<view class="form-box">
+				<text class="form-title">其他</text>
+				<view class="form-item">
+				<!-- 	<text class="label">备注</text> -->
+					<textarea maxlength="200" class="form-textarea" v-model="form.remark" placeholder="请输入用户想解决的问题"   />
+				</view>
+				<view class="form-item">
+					<!-- <text class="label">备注</text> -->
+					<textarea maxlength="200" class="form-textarea" v-model="form.remark" placeholder="请输入健康管理师对用户的建议"   />
+				</view>
+			</view>
+		
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="submit()">保存</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDocDetails,
+		addDoc,
+		editDoc
+	} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				type: null,
+				patientId: null,
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				checked:1,
+				array:['是','否'],
+				tags: [{
+					name: '心脏病',
+					checked:true,
+					id: 1
+				},
+				{
+					name: '脑梗死',
+						checked:false,
+					id: 2
+				},{
+					name: '肾病',
+						checked:false,
+					id: 3
+				},{
+					name: '脂肪肝',
+						checked:false,
+					id: 4
+				}],
+				form: {
+					userName: null,
+					idCard: null,
+					sex: null,
+					birthday: null,
+					remark: null,
+				}
+			};
+		},
+		onLoad(option) {
+			this.type = option.type;
+			console.log(this.type)
+			if (this.type == 'edit') {
+				this.docId = option.docId;
+				// this.getDocDetails();
+			}
+		},
+		methods: {
+			sexChange(type) {
+				this.form.sex = type
+			},
+			radioClick(item) {
+			        this.checked=item.id
+			      },
+			getDocDetails() {
+				var data = {
+					docId: this.docId
+				};
+				getDocDetails(data).then(
+					res => {
+						if (res.code == 200) {
+							this.form = res.data;
+
+						} else {
+							uni.showToast({
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			onChooseAvatar(e){
+				let {
+					avatarUrl
+				} = e.detail;
+				uni.uploadFile({
+					url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+					filePath: avatarUrl,
+					name: 'file',
+					formData: {
+						'user': 'test'  // 上传附带参数
+					},
+					success: (uploadFileRes) => {
+						this.user.avatar =JSON.parse(uploadFileRes.data).url
+					}
+				});
+			},
+			submit() {
+				// if (this.form.userName == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "姓名不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.idCard == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "身份证号不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.sex == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "性别不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.form.birthday == null) {
+				// 	uni.showToast({
+				// 		icon: 'none',
+				// 		title: "出生年月不能为空",
+				// 	});
+				// 	return;
+				// }
+				// if (this.type == "add") {
+				// 	this.addDoc()
+				// } else if (this.type == "edit") {
+				// 	this.editDoc()
+				// }
+                uni.navigateTo({
+                	url: '/pages_health/doc?type=edit&docId='
+                })
+			},
+			editDoc() {
+				editDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				addDoc(this.form).then(
+					res => {
+						if (res.code == 200) {
+							uni.showToast({
+								icon: 'success',
+								title: "操作成功",
+							});
+							setTimeout(function() {
+								uni.$emit('refreshDoc');
+								uni.navigateBack({
+									delta: 1
+								})
+							}, 500);
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			// 出生日期选择
+			bindDateChange: function(e) {
+				this.form.birthday = e.target.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			// height: calc(100% - 120upx);
+			padding: 20upx;
+
+			.form-box {
+				padding: 0 30upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-bottom: 20upx;
+
+				.form-title {
+					font-family: PingFang SC;
+					font-weight: 600;
+					font-size: 40rpx;
+					color: #222426;
+					text-align: left;
+					padding: 30rpx 0;
+					display: block;
+				}
+
+				.form-item {
+					padding: 30upx 0;
+					display: flex;
+					align-items: flex-start;
+					border-bottom: 1px solid #F1F1F1;
+
+					&:last-child {
+						border-bottom: none;
+					}
+        
+					.label {
+						width: 300upx;
+						text-align: left;
+						font-size: 32upx;
+						line-height: 44upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						flex-shrink: 0;
+					}
+
+					input {
+						text-align: right;
+					}
+               
+					.form-input {
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						text-align: right;
+					}
+
+					.form-item-tag{
+						margin-right: 16rpx;
+						.tag{
+							border-radius: 8rpx 8rpx 8rpx 8rpx;
+							border: 2rpx solid #ECECEC;
+							display: flex;
+							align-items: center;
+							padding: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 400;
+							font-size: 24rpx;
+							&.active{
+								background: #F0FAFF;
+								border: 2rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+						
+						
+					}
+					.right{
+						display: flex;
+						align-items: center;
+					}
+					.sex-box{
+						flex:1;
+						display: flex;
+						align-items: center;
+						justify-content: flex-end;
+						.sex-item{
+							width: 146rpx;
+							height: 64rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							background: #F5F7FA;
+							border-radius: 32rpx 32rpx 32rpx 32rpx;
+							margin-left: 16rpx;
+							.u-icon__icon{
+								margin: 0;
+							}
+							text{
+								// font-family: PingFang SC, PingFang SC;
+								font-weight: 400;
+								font-size: 28rpx;
+								color: #898E91;
+								margin-left: 12rpx;
+							}
+							&.active{
+								background: #FCF0E7;
+								text{
+									color:#FF5030
+								}
+							}
+						}
+					}
+					.form-textarea{
+						font-size: 30upx;
+						color: #999999;
+						height: 100upx;
+						padding: 4upx 0;
+					}
+					 
+					.birth-picker {
+						flex: 1;
+						display: flex;
+						align-items: center;
+						
+						.right-box{
+							width: 100%;
+							display: flex;
+							align-items: center;
+							.input-box{
+								// width: 470upx;
+							}
+							.arrow{
+								width: 13upx;
+								height: 23upx;
+								margin-left: 20upx;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		.btn-box {
+			height: 120upx;
+			padding: 0 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			// position: fixed;
+			// width: 90%;
+			// bottom: 0;
+			// left: 50%;
+			// transform: translate(-50%,-50%);
+			// background: #FFFFFF;
+			.sub-btn {
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 32upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3 ;
+				border-radius: 44upx;
+				margin-bottom: 40upx;
+			}
+		}
+	}
+</style>

+ 474 - 0
pages_health/buyOrder.vue

@@ -0,0 +1,474 @@
+<template>
+	<view class="content">
+		<view class="top-fixed">
+			<!-- tab切换 -->
+			<view class="pub-tab-box">
+				<view class="tab-inner">
+					<view 
+						v-for="(item,index) in orderStatus" 
+						:key="index"
+						:class="item.val == orderStatusValue?'item active':'item'"
+						@click="orderStatusChange(item)"
+					>
+						<view class="text">
+							{{ item.name }}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="consu-list">
+			<mescroll-body top="88upx" ref="mescrollRef">
+				<view v-for="(item,index) in dataList" :key="index" class="item" >
+					<view class="item-top">
+						<view class="item-title">
+							<view class="ask-text">{{item.name}}</view>
+							<view class="fs28">X {{item.num}}</view>
+						</view>
+						<view class="ask-time">购买次数:{{item.num}}</view>
+						<view class="ask-time">购买时间:{{item.time}}</view>
+						<view class="ask-time">备注:{{item.remark}}</view>
+					</view>
+					<view class="bottom-box">
+						<view class="amount-paid">
+							<text class="label">订单金额:</text>
+							<view class="price-box">
+								<view class="unit">¥</view>
+								<view class="num">{{item.amount.toFixed(2)}}</view>
+							</view>
+						</view>
+						<view class="btn-box">
+							<view class="btn cancel" @click="cancel(item)">删除</view>
+							<view class="btn pay" @click="showDetail(item)">编辑</view>
+						</view>
+					</view>
+				</view>
+			</mescroll-body>
+		</view>
+		<view class="btn-box2">
+			<view class="sub-btn" @click="navgetTo(orderStatusValue)">
+				<image src="/static/images/health/nav_add_icon24.png" class="w48 h48"></image>
+				<text>新增</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDoctorOrderList,cancelOrder} from '@/api/doctorOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		data() {
+			return {
+				orderStatus:[
+					{name:"购买服务信息",val:"0"},
+					{name:"购买服务信息",val:"1"},
+				],
+				orderStatusValue:0,
+				mescroll:null,
+				// 上拉加载的配置
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'/static/images/no_data.png',
+						tip: '暂无数据'
+					}
+				},
+				// 列表数据
+				dataList: [
+					{orderId:1, name:'极诺泰1',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:2, name:'极诺泰2',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:3, name:'极诺泰3',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,}
+				],
+				dataList2: [
+					{orderId:1, name:'竞品1',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:2, name:'竞品2',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,},
+					{orderId:3, name:'竞品3',num:12,time:'2025-2-20 10:29',remark:'请尽快发货',amount:340.00,}
+				]
+			}
+		},
+		onLoad() {
+			// uni.$on('refreshDoctorOrder', () => {
+			// 	this.mescroll.resetUpScroll()
+			// })
+		},
+		methods: {
+			pay(item){
+				uni.navigateTo({
+					url: '/pages_/doctor/paymentOrder?orderId='+item.orderId
+				})
+			},
+			navgetTo(index){
+				uni.navigateTo({
+					url: index==0?'/pages_health/addServe':'/pages_health/addCompetitors'
+				})
+			},
+			cancel(item){
+				var that=this;
+				uni.showModal({
+				    title: '提示',
+				    content: '确定取消订单吗',
+				    success: function (res) {
+				        if (res.confirm) {
+							var data = {
+								orderId:item.orderId
+							};
+							cancelOrder(data).then(res => {
+								if(res.code==200){
+									uni.showToast({
+										icon:'success',
+										title: '订单已取消',
+									});
+									 that.mescroll.resetUpScroll()
+								}else{
+									uni.showToast({
+										icon:'none',
+										title: res.msg,
+									});
+								}
+							});
+				        } 
+						else if (res.cancel) {
+				        }
+				    }
+				});
+			},
+			// tab切换
+			orderStatusChange(item) {
+				this.orderStatusValue = item.val
+				if(item.val==1){
+					this.dataList=this.dataList2
+				}
+				this.mescroll.resetUpScroll()
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			/*下拉刷新的回调 */
+			downCallback(mescroll) {
+				mescroll.resetUpScroll()
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					status:this.orderStatusValue,
+					page: page.num,
+					pageSize: page.size
+				};
+				// getMyDoctorOrderList(data).then(res => {
+				// 	if(res.code==200){
+				// 		//设置列表数据
+				// 		if (page.num == 1) {
+				// 			that.dataList = res.data.list; 
+							
+				// 		} else {
+				// 			that.dataList = that.dataList.concat(res.data.list);
+							 
+				// 		}
+				// 		that.mescroll.endBySize(res.data.list.length, res.data.total);
+						
+				// 	}else{
+				// 		uni.showToast({
+				// 			icon:'none',
+				// 			title: "请求失败",
+				// 		});
+				// 		that.dataList = null;
+				// 		that.mescroll.endErr();
+				// 	}
+				// });
+			},
+			showDetail(item) {
+				if(item.orderType==1){
+					uni.navigateTo({
+						url: '/pages_doctor/doctorOrderIM?orderId='+item.orderId
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		padding: 20upx;
+		.top-fixed{
+			width: 100%;
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 10;
+		}
+		.pub-tab-box{
+			box-sizing: border-box;
+			width: 100%;
+			padding: 0 40upx;
+			background-color: #FFFFFF;
+			.tab-inner{
+				height: 88upx;
+				line-height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				overflow-x: auto;
+			}
+			.item{
+				font-size: 28upx;
+				white-space: nowrap;
+				line-height: 1;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				margin-right: 60upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				&:last-child{
+					margin-right: 0;
+				}
+				&.active{
+					font-weight: bold;
+					color: #333333;
+					&::after {
+						content: "";
+						width: 48rpx;
+						height: 8rpx;
+						background: linear-gradient(120deg, #31A1FE  0%, #008FD3 100%);
+						position: absolute;
+						bottom: 0;
+						border-radius: 6upx 6upx 0upx 0;
+					}
+				}
+				.text{
+					position: relative;
+					z-index: 1;
+				}
+				.tab-bg{
+					width: 72upx;
+					height: 28upx;
+					position: absolute;
+					top: 17upx;
+					left: 50%;
+					transform: translateX(-36upx);
+					z-index: -1;
+				}
+			}
+		}
+		.btn-box2{
+			z-index: 9999;
+			width: 100%;
+			padding: 30upx;
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			box-sizing: border-box;
+			// background: #FFFFFF;
+			
+			 
+			.sub-btn{
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+		.consu-list{
+			.item{
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 32rpx;
+				position: relative;
+				margin-bottom: 20upx;
+				.item-top{
+					padding-bottom:40rpx ;
+					border-bottom: 1px solid #ECECEC;
+					.item-title{
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+						margin-bottom: 12rpx;
+						
+					}
+					.ask-text{
+						font-family: PingFang SC;
+						font-weight: 500;
+						font-size: 36rpx;
+						color: #222426;
+						text-align: left;
+					}
+					.ask-time{
+						font-size: 24rpx;
+						color: #898E91;
+						text-align: left;
+						line-height: 40rpx;
+					}
+				}
+				.ordersn-box{
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					padding: 0upx 0 20upx;
+					.num{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						line-height: 1;
+					}
+					.status-box{
+						display: flex;
+						align-items: center;
+						.recom-box{
+							width: 108upx;
+							height: 30upx;
+							line-height: 30upx;
+							text-align: left;
+							padding-left: 8upx;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #FFFFFF;
+							// background-image: url(../../static/images/recom.png);
+							background-repeat: no-repeat;
+							background-size: 100% 100%;
+							margin-right: 8upx;
+						}
+						.text{
+							font-size: 28upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							line-height: 1;
+							&.success{
+								color: #0bb3f2;
+							}
+							&.black{
+								color: #111111;
+							}
+							&.info{
+								color: #999999;
+							}
+						}
+					}
+				}
+				.doctor-info{
+					display: flex;
+					align-items: center;
+					.img-box{
+						width: 80upx;
+						height: 80upx;
+						background: #E0FFF8;
+						border-radius: 50%;
+						overflow: hidden;
+						margin-right: 20upx;
+						image{
+							width: 100%;
+							height: 100%;
+						}
+					}
+					.name{
+						font-size: 28upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 48upx;
+						text{
+							margin-right: 10upx;
+						}
+					}
+				}
+				
+				.patient-text{
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					margin-bottom: 24upx;
+				}
+			
+				.bottom-box{
+					height: 80upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					margin-top: 20rpx;
+					.amount-paid{
+						display: flex;
+						align-items: center;
+						.label{
+							font-size: 24upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 1;
+						}
+						.price-box{
+							display: flex;
+							align-items: flex-end;
+							.unit{
+								font-size: 24upx;
+								font-family: PingFang SC;
+								font-weight: 600;
+								color: #FF5030;
+								line-height: 1.2;
+								margin-right: 4upx;
+							}
+							.num{
+								font-size: 36upx;
+								font-family: PingFang SC;
+								font-weight: bold;
+								color: #FF5030;
+								line-height: 1;
+							}
+						}
+					}
+					.btn-box{
+						box-sizing: border-box;
+						display: flex;
+						align-items: center;
+						.btn{
+						   width: 128rpx;
+						    height: 60rpx;
+							line-height: 60upx;
+							font-size: 24upx;
+							font-family: PingFang SC;
+							text-align: center;
+							border-radius: 32upx;
+							margin-left: 15upx;
+							&:first-child{
+								margin-left: 0;
+							}
+							&.cancel{
+								border: 1px solid #B2B2B2;
+								color: #666666;
+							}
+							&.pay{
+								border: 1px solid #008FD3;
+								color: #008FD3;
+							}
+						}
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 320 - 0
pages_health/doc.vue

@@ -0,0 +1,320 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view v-for="(item,index) in docs" :key="index" class="item" @click="showDetail(item)">
+				<view class="user-info">
+					<view class="user-top">
+						<view class="user-left">
+							<image :src="maleurl" class="w112 h112"></image>
+							<view class="ml32">
+								<view class="name">{{item.userName}}</view>
+								<view class="age-box"  :style="{'background-color':item.sex==1?'#EBF8FF':'#FCF0E7'}">
+									<u-icon :color="item.sex==1?'#008FD3':'#FF5030'" :name="item.sex==1?'man':'woman'"></u-icon>
+									<view class="age">{{utils.getAge(item.birthday)}}岁</view>
+								</view>
+							</view>
+							
+						</view>
+						<view class="user-phone">{{utils.parsePhone(item.phone)}}</view>
+					</view>
+					<view class="user-bottom">
+						<view class="btn" @click="navgetTo('/pages_health/buyOrder?type=add')">购买信息</view>
+						<view class="btn" @click="navgetTo('/pages_health/addUser?type=add')">基本信息</view>
+						<view class="btn" @click="navgetTo('/pages_health/addDoc?type=add')">健康档案</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="docs.length == 0" class="no-data-box" @click="getMyDocList()">
+				<image src="../../static/images/no_data.png" mode="aspectFit"></image>
+				<view class="empty-title">暂无数据</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="sub-btn" @click="addDoc">
+				<image src="/static/images/health/nav_add_icon24.png" class="w48 h48"></image>
+				<text>创建用户信息</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyDocList,delDoc} from '@/api/doc.js'
+	export default {
+		data() {
+			return {
+				famaleurl:"/static/images/health/female_profile.png",
+				maleurl:"/static/images/health/my_heads.png",
+				docs:[
+					{userName:'西航宇',sex:1,birthday:'1990-01-01',phone:'16666666666'},
+					{userName:'蓝西',sex:2,birthday:'1990-06-01',phone:'1888888888'},
+					{userName:'西航宇',sex:1,birthday:'1993-01-01',phone:'16666666666'},
+					{userName:'蓝西',sex:2,birthday:'1994-06-01',phone:'1888888888'},
+					{userName:'蓝西',sex:2,birthday:'1994-06-01',phone:'1888888888'}
+				],
+			}
+		},
+		onLoad() {
+			// this.getMyDocList()
+			// uni.$on('refreshDoc', () => {
+			// 	this.getMyDocList()
+			// })
+		},
+		methods: {
+			navgetTo(url){
+				uni.navigateTo({
+					url: url
+				})
+			},
+			showDetail(item){
+				uni.navigateTo({
+					url: './docDetail?docId='+item.docId
+				})
+			},
+			editDoc(item){
+				uni.navigateTo({
+					url: './addDoc?type=edit&docId='+item.docId
+				})
+			},
+			delDoc(item){
+				uni.showModal({
+					title:"提示",
+					content:"确认删除吗?",
+					showCancel:true,
+					cancelText:'取消',
+					confirmText:'确定',
+					success:res=>{
+						if(res.confirm){
+							// 用户点击确定
+							var data={docId:item.docId}
+							delDoc(data).then(
+								res => {
+									if(res.code==200){
+										 uni.showToast({
+										 	icon:'success',
+										 	title: "操作成功",
+										 });
+										 this.getMyDocList()
+									}else{
+										uni.showToast({
+											icon:'none',
+											title: "请求失败",
+										});
+									}
+								},
+								rej => {}
+							);
+														
+						}else{
+							// 否则点击了取消  
+						}
+					}
+				})
+			},
+			getMyDocList(){
+				uni.showLoading({
+					title:"正在加载中"
+				})
+				getMyDocList().then(
+					res => {
+						uni.hideLoading()
+						if(res.code==200){
+							this.docs=res.data;
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: "请求失败",
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			addDoc() {
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=add'
+				})
+			}
+			 
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		height: 100%;
+	}
+	.content{
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.inner{
+			flex: 1;
+			padding: 20upx 20upx 160upx;
+			.item{
+				background: #FFFFFF;
+				border-radius: 20upx;
+				margin-bottom: 20upx;
+				// padding: 40upx 30upx;
+				padding: 32rpx;
+				&:last-child{
+					margin-bottom: 0;
+				}
+				.user-info{
+					.user-top{
+						display: flex;
+						align-items: flex-start;
+						justify-content: space-between;
+						border-bottom: 1px solid #ECECEC;
+						padding-bottom: 40rpx;
+						.user-left{
+							display: flex;
+							align-items: center;
+							justify-content: flex-start;
+							.name{
+								font-family: PingFang SC;
+								font-weight: 500;
+								font-size: 36rpx;
+								color: #222426;
+								text-align: left;
+							}
+							.age-box{
+								display: flex;
+								align-items: center;
+								justify-content: center;
+								border-radius: 24rpx 24rpx 24rpx 24rpx;
+								margin-top: 16rpx;
+								width: 114rpx;
+								    height: 40rpx;
+								.age{
+									font-weight: 400;
+									font-size: 22rpx;
+									color: #626468;
+									line-height: 22rpx;
+									text-align: left;
+								}
+							}
+							
+						}
+						.user-phone{
+							font-family: PingFang SC;
+							font-weight: 500;
+							font-size: 28rpx;
+							color: #222426;
+							text-align: right;
+						}
+					}
+					.user-bottom{
+						display: flex;
+						align-items: center;
+						justify-content: flex-end;
+						padding-top: 20rpx;
+						.btn{
+							width: 176rpx;
+							height: 60rpx;
+							border-radius: 30rpx 30rpx 30rpx 30rpx;
+							border: 1rpx solid #B2B2B2;
+							font-size: 24rpx;
+							color: #222426;
+							line-height: 60rpx;
+							text-align: center;
+							margin-left:16rpx ;
+							&:last-child{
+								border: 1rpx solid #008FD3;
+								color: #008FD3;
+							}
+						}
+						
+					}
+					.gray-tag{
+						height: 46upx;
+						line-height: 46upx;
+						padding: 0 16upx;
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #333333;
+						background: #F7F7F7;
+						border-radius: 8upx;
+						margin-right: 10upx;
+					}
+					.blue-tag{
+						height: 46upx;
+						line-height: 46upx;
+						padding: 0 16upx;
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #4BC9B1;
+						background: #E2F6F2;
+						border-radius: 8upx;
+					}
+				}
+				.stage-box{
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					margin-top: 34upx;
+					.stage{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #111111;
+						line-height: 1;
+					}
+					.stage-text{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 1;
+					}
+				}
+				.progress-box{
+					margin-top: 18upx;
+				}
+				.period{
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1;
+					margin-top: 40upx;
+				}
+			}
+			 
+		}
+		.btn-box{
+			z-index: 9999;
+			width: 100%;
+			padding: 30upx;
+			position: fixed;
+			bottom: 0;
+			left: 0;
+			box-sizing: border-box;
+			// background: #FFFFFF;
+			
+	 
+			.sub-btn{
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #008FD3;
+				border-radius: 44upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				image{
+					margin-right: 16rpx;
+				}
+			}
+		}
+		 
+	}
+</style>

+ 46 - 4
pages_health/healthfiles.vue

@@ -21,12 +21,12 @@
 						</view>
 					</view>
 				</view>
-				<u-icon name="arrow-right"></u-icon>
+				<u-icon name="arrow-right" @click="goToUser"></u-icon>
 			</view>
 			<view class="fs36 bold mt20">健康数据</view>
 			<view class="health-monitoring">
 				<view class="health-monitoring-item" v-for="(item,index) in indexInfo" :key="index"
-					@tap="handleMonitoring(item)">
+					@tap="handleMonitoring(item,index)">
 					<view class="health-monitoring-title">
 						<view>
 							<view class="health-monitoring-maintitle bold">{{item.type.type}}</view>
@@ -161,6 +161,9 @@
 		    // 获取系统信息
 		    const sys = uni.getSystemInfoSync()
 		    this.statusBarHeight = sys.statusBarHeight+'px'
+			// uni.navigateTo({
+			// 	url: '/pages_health/doc?type=edit&docId='
+			// })
 		},
 		onUnload() { //普通页面在 onUnload 生命周期中执行
 		    uni.$emit('stop')
@@ -173,7 +176,45 @@
 		  	this.top=e.scrollTop;
 		},
 		methods: {
-			
+			handleMonitoring(item,index){
+				switch (index) {
+				case 0:
+				uni.navigateTo({
+					url: '/pages_health/addDoc?type=edit&docId='
+				})
+				break;
+				case 1:
+				uni.navigateTo({
+					url: '/pages_echarts/waistLine?type=edit&docId='
+				})
+				break;
+				case 2:
+				uni.navigateTo({
+					url: '/pages_echarts/hips?type=edit&docId='
+				})
+				break;
+				case 3:
+				uni.navigateTo({
+					url: '/pages_echarts/bloodSugar'
+				})
+				break;
+				case 4:
+				uni.navigateTo({
+					url: '/pages_echarts/bloodPressure?type=edit&docId='
+				})
+				break;
+				default:
+				uni.navigateTo({
+					url: '/pages_echarts/acid?type=edit&docId='
+				})
+				break;
+				}
+			},
+			goToUser(){
+				uni.navigateTo({
+					url: '/pages_health/addUser?type=edit&docId='
+				})
+			}
 		}
 	}
 </script>
@@ -181,13 +222,14 @@
 <style lang="scss" scoped>
 .container{
 	position: relative;
+	    background: #EFF3F7;
 	.bg{
 		width: 100%;
 		height: 380rpx;
 		position: absolute;
 		top: 0;
 		left: 0;
-		z-index: -1;
+		z-index:0;
 	}
 }
 .content{

BIN
static/images/company/add_blue_icon.png


BIN
static/images/company/add_icon.png


BIN
static/images/company/address_icon.png


BIN
static/images/company/appointed_task_icon.png


BIN
static/images/company/comparison_indicators_icon.png


BIN
static/images/company/consumables_mall_icon.png


BIN
static/images/company/customer_complaints_icon.png


BIN
static/images/company/customer_profile_icon.png


BIN
static/images/company/deenergize_icon.png


BIN
static/images/company/edit_add_icon.png


BIN
static/images/company/evaluation_record_icon.png


BIN
static/images/company/execution_record_icon.png


BIN
static/images/company/follow_up_records_icon.png


BIN
static/images/company/health_records_icon.png


BIN
static/images/company/list_matters_icon.png


BIN
static/images/company/make_phone_call_icon.png


BIN
static/images/company/manager_examine_icon.png


BIN
static/images/company/my_promotion_icon.png


BIN
static/images/company/phone_icon.png


BIN
static/images/company/phone_icon16.png


BIN
static/images/company/physical_examination_icon.png


BIN
static/images/company/return_records_icon.png


BIN
static/images/company/right_arrow_black_icon24.png


BIN
static/images/company/right_arrow_right_icon.png


BIN
static/images/company/sales_management_top_bg.png


BIN
static/images/company/send_SMS_icon.png


BIN
static/images/company/time_arrow_blue_icon.png


BIN
static/images/company/time_arrow_down_icon.png


BIN
static/images/company/time_arrow_icon.png


BIN
static/images/company/to_do_list_icon.png


BIN
static/images/company/work_item_icon.png


BIN
static/images/health/arrow_down.png


BIN
static/images/health/arrow_time_no_icon.png


BIN
static/images/health/arrow_time_yes_icon.png


BIN
static/images/health/blood_pressure_top_bg.png


BIN
static/images/health/blood_sugar_top_bg.png


BIN
static/images/health/hip_circumference_tab_switch_bg.png


BIN
static/images/health/hips_top_bg.png


BIN
static/images/health/nav_add_icon24.png


BIN
static/images/health/note_icon.png


BIN
static/images/health/qw_arrow_icon.png


BIN
static/images/health/right_arrow_right_icon24.png


BIN
static/images/health/uric_acid_top_bg.png


BIN
static/images/health/waist_circumference_top_bg.png


BIN
static/images/health/yz_arrow_icon.png


BIN
static/images/health/zc_arrow_icon.png


+ 320 - 0
uni_modules/qiun-data-charts/changelog.md

@@ -0,0 +1,320 @@
+## 2.5.0-20230101(2023-01-01)
+- 秋云图表组件 修改条件编译顺序,确保uniapp的cli方式的项目依赖不完整时可以正常显示
+- 秋云图表组件 恢复props属性directory的使用,以修复vue3项目中,开启echarts后,echarts目录识别错误的bug
+- uCharts.js 修复区域图、混合图只有一个数据时图表显示不正确的bug
+- uCharts.js 修复折线图、区域图中时间轴类别图表tooltip指示点显示不正确的bug
+- uCharts.js 修复x轴使用labelCount时,并且boundaryGap = 'justify' 并且关闭Y轴显示的时候,最后一个坐标值不显示的bug
+- uCharts.js 修复折线图只有一组数据时 ios16 渲染颜色不正确的bug
+- uCharts.js 修复玫瑰图半径显示不正确的bug
+- uCharts.js 柱状图、山峰图增加正负图功能,y轴网格如果需要显示0轴则由 min max 及 splitNumber 确定,后续版本优化自动显示0轴
+- uCharts.js 柱状图column增加 opts.extra.column.labelPosition,数据标签位置,有效值为 outside外部, insideTop内顶部, center内中间, bottom内底部
+- uCharts.js 雷达图radar增加 opts.extra.radar.labelShow,否显示各项标识文案是,默认true
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.boxPadding,提示窗边框填充距离,默认3px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.fontSize,提示窗字体大小配置,默认13px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.lineHeight,提示窗文字行高,默认20px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShow,是否显示左侧图例,默认true
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShape,图例形状,图例标识样式,有效值为 auto自动跟随图例, diamond◆, circle●, triangle▲, square■, rect▬, line-
+- uCharts.js 标记线markLine增加 opts.extra.markLine.labelFontSize,字体大小配置,默认13px
+- uCharts.js 标记线markLine增加 opts.extra.markLine.labelPadding,标签边框内填充距离,默认6px
+- uCharts.js 折线图line增加 opts.extra.line.linearType,渐变色类型,可选值 none关闭渐变色,custom 自定义渐变色。使用自定义渐变色时请赋值serie.linearColor作为颜色值
+- uCharts.js 折线图line增加 serie.linearColor,渐变色数组,格式为2维数组[起始位置,颜色值],例如[[0,'#0EE2F8'],[0.3,'#2BDCA8'],[0.6,'#1890FF'],[1,'#9A60B4']]
+- uCharts.js 折线图line增加 opts.extra.line.onShadow,是否开启折线阴影,开启后请赋值serie.setShadow阴影设置
+- uCharts.js 折线图line增加 serie.setShadow,阴影配置,格式为4位数组:[offsetX,offsetY,blur,color]
+- uCharts.js 折线图line增加 opts.extra.line.animation,动画效果方向,可选值为vertical 垂直动画效果,horizontal 水平动画效果
+- uCharts.js X轴xAxis增加 opts.xAxis.lineHeight,X轴字体行高,默认20px
+- uCharts.js X轴xAxis增加 opts.xAxis.marginTop,X轴文字距离轴线的距离,默认0px
+- uCharts.js X轴xAxis增加 opts.xAxis.title,当前X轴标题
+- uCharts.js X轴xAxis增加 opts.xAxis.titleFontSize,标题字体大小,默认13px
+- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetY,标题纵向偏移距离,负数为向上偏移,正数向下偏移
+- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetX,标题横向偏移距离,负数为向左偏移,正数向右偏移
+- uCharts.js X轴xAxis增加 opts.xAxis.titleFontColor,标题字体颜色,默认#666666
+
+## 报错TypeError: Cannot read properties of undefined (reading 'length')
+- 如果是uni-modules版本组件,请先登录HBuilderX账号;
+- 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行;
+- 如果是cli项目请使用码云上的非uniCloud版本组件;
+- 或者添加uniCloud的依赖;
+- 或者使用原生uCharts;
+## 2.4.5-20221130(2022-11-30)
+- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画
+- uCharts.js 折线图修复特殊情况下只有单点数据,并改变线宽后点变为圆形的bug
+- uCharts.js 修复Y轴disabled启用后无效并报错的bug
+- uCharts.js 修复仪表盘起始结束角度特殊情况下显示不正确的bug
+- uCharts.js 雷达图新增参数 opts.extra.radar.radius , 自定义雷达图半径
+- uCharts.js 折线图、区域图增加tooltip指示点,opts.extra.line.activeType/opts.extra.area.activeType,可选值"none"不启用激活指示点,"hollow"空心点模式,"solid"实心点模式
+## 2.4.4-20221102(2022-11-02)
+- 秋云图表组件 修复使用echarts时reload、reshow无法调用重新渲染的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/40)
+- 秋云图表组件 修复使用echarts时,初始化时宽高不正确的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/42)
+- 秋云图表组件 修复uniapp的h5使用history模式时,无法加载echarts的bug
+- 秋云图表组件 小程序端@complete、@scrollLeft、@scrollRight、@getTouchStart、@getTouchMove、@getTouchEnd事件增加opts参数传出,方便一些特殊需求的交互获取数据。
+
+- uCharts.js 修复calTooltipYAxisData方法内formatter格式化方法未与y轴方法同步的问题,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/43)
+- uCharts.js 地图新增参数opts.series[i].fillOpacity,以透明度方式来设置颜色过度效果,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/38)
+- uCharts.js 地图新增参数opts.extra.map.active,是否启用点击激活变色
+- uCharts.js 地图新增参数opts.extra.map.activeTextColor,是否启用点击激活变色
+- uCharts.js 地图新增渲染完成事件renderComplete
+- uCharts.js 漏斗图修复当部分数据相同时tooltip提示窗点击错误的bug
+- uCharts.js 漏斗图新增参数series.data[i].centerText 居中标签文案
+- uCharts.js 漏斗图新增参数series.data[i].centerTextSize 居中标签文案字体大小,默认opts.fontSize
+- uCharts.js 漏斗图新增参数series.data[i].centerTextColor 居中标签文案字体颜色,默认#FFFFFF
+- uCharts.js 漏斗图新增参数opts.extra.funnel.minSize 最小值的最小宽度,默认0
+- uCharts.js 进度条新增参数opts.extra.arcbar.direction,动画方向,可选值为cw顺时针、ccw逆时针
+- uCharts.js 混合图新增参数opts.extra.mix.line.width,折线的宽度,默认2
+- uCharts.js 修复tooltip开启horizentalLine水平横线标注时,图表显示错位的bug
+- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画
+- uCharts.js 修复开启滚动条后X轴文字超出绘图区域后的隐藏逻辑
+- uCharts.js 柱状图、条状图修复堆叠模式不能通过{value,color}赋值单个柱子颜色的问题
+- uCharts.js 气泡图修复不识别series.textSize和series.textColor的bug
+
+## 报错TypeError: Cannot read properties of undefined (reading 'length')
+1. 如果是uni-modules版本组件,请先登录HBuilderX账号;
+2. 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行;
+3. 如果是cli项目请使用码云上的非uniCloud版本组件;
+4. 或者添加uniCloud的依赖;
+5. 或者使用原生uCharts;
+## 2.4.3-20220505(2022-05-05)
+- 秋云图表组件 修复开启canvas2d后将series赋值为空数组显示加载图标时,再次赋值后画布闪动的bug
+- 秋云图表组件 修复升级hbx最新版后ECharts的highlight方法报错的bug
+- uCharts.js 雷达图新增参数opts.extra.radar.gridEval,数据点位网格抽希,默认1
+- uCharts.js 雷达图新增参数opts.extra.radar.axisLabel,	是否显示刻度点值,默认false
+- uCharts.js 雷达图新增参数opts.extra.radar.axisLabelTofix,刻度点值小数位数,默认0
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointShow,是否显示末端刻度圆点,默认false
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointRadius,刻度圆点的半径,默认3
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointColor,刻度圆点的颜色,默认#cccccc
+- uCharts.js 雷达图新增参数opts.extra.radar.linearType,渐变色类型,可选值"none"关闭渐变,"custom"开启渐变
+- uCharts.js 雷达图新增参数opts.extra.radar.customColor,自定义渐变颜色,数组类型对应series的数组长度以匹配不同series颜色的不同配色方案,例如["#FA7D8D", "#EB88E2"]
+- uCharts.js 雷达图优化支持series.textColor、series.textSize属性
+- uCharts.js 柱状图中温度计式图标,优化支持全圆角类型,修复边框有缝隙的bug,详见官网【演示】中的温度计图表
+- uCharts.js 柱状图新增参数opts.extra.column.activeWidth,当前点击柱状图的背景宽度,默认一个单元格单位
+- uCharts.js 混合图增加opts.extra.mix.area.gradient 区域图是否开启渐变色
+- uCharts.js 混合图增加opts.extra.mix.area.opacity 区域图透明度,默认0.2
+- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelText,自定义标签文字,避免formatter格式化的繁琐,详见官网【演示】中的饼图
+- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelShow,自定义是否显示某一个指示标签,避免因饼图类别太多导致标签重复或者居多导致图形变形的问题,详见官网【演示】中的饼图
+- uCharts.js 增加opts.series[i].legendText/opts.series[0].data[i].legendText(与series.name同级)自定义图例显示文字的方法
+- uCharts.js 优化X轴、Y轴formatter格式化方法增加形参,统一为fromatter:function(value,index,opts){}
+- uCharts.js 修复横屏模式下无法使用双指缩放方法的bug
+- uCharts.js 修复当只有一条数据或者多条数据值相等的时候Y轴自动计算的最大值错误的bug
+- 【官网模板】增加外部自定义图例与图表交互的例子,[点击跳转](https://www.ucharts.cn/v2/#/layout/info?id=2)
+
+## 注意:非unimodules 版本如因更新 hbx 至 3.4.7 导致报错如下,请到码云更新非 unimodules 版本组件,[点击跳转](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6)
+> Error in callback for immediate watcher "uchartsOpts": "SyntaxError: Unexpected token u in JSON at position 0"
+## 2.4.2-20220421(2022-04-21)
+- 秋云图表组件 修复HBX升级3.4.6.20220420版本后echarts报错的问题
+## 2.4.2-20220420(2022-04-20)
+## 重要!此版本uCharts新增了很多功能,修复了诸多已知问题
+- 秋云图表组件 新增onzoom开启双指缩放功能(仅uCharts),前提需要直角坐标系类图表类型,并且ontouch为true、opts.enableScroll为true,详见实例项目K线图
+- 秋云图表组件 新增optsWatch是否监听opts变化,关闭optsWatch后,动态修改opts不会触发图表重绘
+- 秋云图表组件 修复开启canvas2d功能后,动态更新数据后画布闪动的bug
+- 秋云图表组件 去除directory属性,改为自动获取echarts.min.js路径(升级不受影响)
+- 秋云图表组件 增加getImage()方法及@getImage事件,通过ref调用getImage()方法获,触发@getImage事件获取当前画布的base64图片文件流。
+- 秋云图表组件 支付宝、字节跳动、飞书、快手小程序支持开启canvas2d同层渲染设置。
+- 秋云图表组件 新增加【非uniCloud】版本组件,避免有些不需要uniCloud的使用组件发布至小程序需要提交隐私声明问题,请到码云[【非uniCloud版本】](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6),或npm[【非uniCloud版本】](https://www.npmjs.com/package/@qiun/uni-ucharts)下载使用。
+- uCharts.js 新增dobuleZoom双指缩放功能
+- uCharts.js 新增山峰图type="mount",数据格式为饼图类格式,不需要传入categories,具体详见新版官网在线演示
+- uCharts.js 修复折线图当数据中存在null时tooltip报错的bug
+- uCharts.js 修复饼图类当画布比较小时自动计算的半径是负数报错的bug
+- uCharts.js 统一各图表类型的series.formatter格式化方法的形参为(val, index, series, opts),方便格式化时有更多参数可用
+- uCharts.js 标记线功能增加labelText自定义显示文字,增加labelAlign标签显示位置(左侧或右侧),增加标签显示位置微调labelOffsetX、labelOffsetY
+- uCharts.js 修复条状图当数值很小时开启圆角后样式错误的bug
+- uCharts.js 修复X轴开启disabled后,X轴仍占用空间的bug
+- uCharts.js 修复X轴开启滚动条并且开启rotateLabel后,X轴文字与滚动条重叠的bug
+- uCharts.js 增加X轴rotateAngle文字旋转自定义角度,取值范围(-90至90)
+- uCharts.js 修复地图文字标签层级显示不正确的bug
+- uCharts.js 修复饼图、圆环图、玫瑰图当数据全部为0的时候不显示数据标签的bug
+- uCharts.js 修复当opts.padding上边距为0时,Y轴顶部刻度标签位置不正确的bug
+
+## 另外我们还开发了各大原生小程序组件,已发布至码云和npm
+[https://gitee.com/uCharts/uCharts](https://gitee.com/uCharts/uCharts)
+[https://www.npmjs.com/~qiun](https://www.npmjs.com/~qiun)
+
+## 对于原生uCharts文档我们已上线新版官方网站,详情点击下面链接进入官网
+[https://www.uCharts.cn/v2/](https://www.ucharts.cn/v2/)
+## 2.3.7-20220122(2022-01-22)
+## 重要!使用vue3编译,请使用cli模式并升级至最新依赖,HbuilderX编译需要使用3.3.8以上版本
+- uCharts.js 修复uni-app平台组件模式使用vue3编译到小程序报错的bug。
+## 2.3.7-20220118(2022-01-18)
+## 注意,使用vue3的前提是需要3.3.8.20220114-alpha版本的HBuilder!
+## 2.3.67-20220118(2022-01-18)
+- 秋云图表组件 组件初步支持vue3,全端编译会有些问题,具体详见下面修改:
+1. 小程序端运行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new uni_modules_qiunDataCharts_js_sdk_uCharts_uCharts.uCharts,将.uCharts去掉。
+2. 小程序端发行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new e.uCharts,将.uCharts去掉,变为 new e。
+3. 如果觉得上述步骤比较麻烦,如果您的项目只编译到小程序端,可以修改u-charts.js最后一行导出方式,将 export default uCharts;变更为 export default { uCharts: uCharts }; 这样变更后,H5和App端的renderjs会有问题,请开发者自行选择。(此问题非组件问题,请等待DC官方修复Vue3的小程序端)
+## 2.3.6-20220111(2022-01-11)
+- 秋云图表组件 修改组件 props 属性中的 background 默认值为 rgba(0,0,0,0)
+## 2.3.6-20211201(2021-12-01)
+- uCharts.js 修复bar条状图开启圆角模式时,值很小时圆角渲染错误的bug
+## 2.3.5-20211014(2021-10-15)
+- uCharts.js 增加vue3的编译支持(仅原生uCharts,qiun-data-charts组件后续会支持,请关注更新)
+## 2.3.4-20211012(2021-10-12)
+- 秋云图表组件 修复 mac os x 系统 mouseover 事件丢失的 bug
+## 2.3.3-20210706(2021-07-06)
+- uCharts.js 增加雷达图开启数据点值(opts.dataLabel)的显示
+## 2.3.2-20210627(2021-06-27)
+- 秋云图表组件 修复tooltipCustom个别情况下传值不正确报错TypeError: Cannot read property 'name' of undefined的bug
+## 2.3.1-20210616(2021-06-16)
+- uCharts.js 修复圆角柱状图使用4角圆角时,当数值过大时不正确的bug
+## 2.3.0-20210612(2021-06-12)
+- uCharts.js 【重要】uCharts增加nvue兼容,可在nvue项目中使用gcanvas组件渲染uCharts,[详见码云uCharts-demo-nvue](https://gitee.com/uCharts/uCharts)
+- 秋云图表组件 增加tapLegend属性,是否开启图例点击交互事件
+- 秋云图表组件 getIndex事件中增加返回uCharts实例中的opts参数,以便在页面中调用参数
+- 示例项目 pages/other/other.vue增加app端自定义tooltip的方法,详见showOptsTooltip方法
+## 2.2.1-20210603(2021-06-03)
+- uCharts.js 修复饼图、圆环图、玫瑰图,当起始角度不为0时,tooltip位置不准确的bug
+- uCharts.js 增加温度计式柱状图开启顶部半圆形的配置
+## 2.2.0-20210529(2021-05-29)
+- uCharts.js 增加条状图type="bar"
+- 示例项目 pages/ucharts/ucharts.vue增加条状图的demo
+## 2.1.7-20210524(2021-05-24)
+- uCharts.js 修复大数据量模式下曲线图不平滑的bug
+## 2.1.6-20210523(2021-05-23)
+- 秋云图表组件 修复小程序端开启滚动条更新数据后滚动条位置不符合预期的bug
+## 2.1.5-2021051702(2021-05-17)
+- uCharts.js 修复自定义Y轴min和max值为0时不能正确显示的bug
+## 2.1.5-20210517(2021-05-17)
+- uCharts.js 修复Y轴自定义min和max时,未按指定的最大值最小值显示坐标轴刻度的bug
+## 2.1.4-20210516(2021-05-16)
+- 秋云图表组件 优化onWindowResize防抖方法
+- 秋云图表组件 修复APP端uCharts更新数据时,清空series显示loading图标后再显示图表,图表抖动的bug
+- uCharts.js 修复开启canvas2d后,x轴、y轴、series自定义字体大小未按比例缩放的bug
+- 示例项目 修复format-e.vue拼写错误导致app端使用uCharts渲染图表
+## 2.1.3-20210513(2021-05-13)
+- 秋云图表组件 修改uCharts变更chartData数据为updateData方法,支持带滚动条的数据动态打点
+- 秋云图表组件 增加onWindowResize防抖方法 fix by ど誓言,如尘般染指流年づ 
+- 秋云图表组件 H5或者APP变更chartData数据显示loading图表时,原数据闪现的bug
+- 秋云图表组件 props增加errorReload禁用错误点击重新加载的方法
+- uCharts.js 增加tooltip显示category(x轴对应点位)标题的功能,opts.extra.tooltip.showCategory,默认为false
+- uCharts.js 修复mix混合图只有柱状图时,tooltip的分割线显示位置不正确的bug
+- uCharts.js 修复开启滚动条,图表在拖动中动态打点,滚动条位置不正确的bug
+- uCharts.js 修复饼图类数据格式为echarts数据格式,series为空数组报错的bug
+- 示例项目 修改uCharts.js更新到v2.1.2版本后,@getIndex方法获取索引值变更为e.currentIndex.index
+- 示例项目 pages/updata/updata.vue增加滚动条拖动更新(数据动态打点)的demo
+- 示例项目 pages/other/other.vue增加errorReload禁用错误点击重新加载的demo
+## 2.1.2-20210509(2021-05-09)
+秋云图表组件 修复APP端初始化时就传入chartData或lacaldata不显示图表的bug
+## 2.1.1-20210509(2021-05-09)
+- 秋云图表组件 变更ECharts的eopts配置在renderjs内执行,支持在config-echarts.js配置文件内写function配置。
+- 秋云图表组件 修复APP端报错Prop being mutated: "onmouse"错误的bug。
+- 秋云图表组件 修复APP端报错Error: Not Found:Page[6][-1,27] at view.umd.min.js:1的bug。
+## 2.1.0-20210507(2021-05-07)
+- 秋云图表组件 修复初始化时就有数据或者数据更新的时候loading加载动画闪动的bug
+- uCharts.js 修复x轴format方法categories为字符串类型时返回NaN的bug
+- uCharts.js 修复series.textColor、legend.fontColor未执行全局默认颜色的bug
+## 2.1.0-20210506(2021-05-06)
+- 秋云图表组件 修复极个别情况下报错item.properties undefined的bug
+- 秋云图表组件 修复极个别情况下关闭加载动画reshow不起作用,无法显示图表的bug
+- 示例项目 pages/ucharts/ucharts.vue 增加时间轴折线图(type="tline")、时间轴区域图(type="tarea")、散点图(type="scatter")、气泡图demo(type="bubble")、倒三角形漏斗图(opts.extra.funnel.type="triangle")、金字塔形漏斗图(opts.extra.funnel.type="pyramid")
+- 示例项目 pages/format-u/format-u.vue 增加X轴format格式化示例
+- uCharts.js 升级至v2.1.0版本
+- uCharts.js 修复 玫瑰图面积模式点击tooltip位置不正确的bug
+- uCharts.js 修复 玫瑰图点击图例,只剩一个类别显示空白的bug
+- uCharts.js 修复 饼图类图点击图例,其他图表tooltip位置某些情况下不准的bug
+- uCharts.js 修复 x轴为矢量轴(时间轴)情况下,点击tooltip位置不正确的bug
+- uCharts.js 修复 词云图获取点击索引偶尔不准的bug
+- uCharts.js 增加 直角坐标系图表X轴format格式化方法(原生uCharts.js用法请使用formatter)
+- uCharts.js 增加 漏斗图扩展配置,倒三角形(opts.extra.funnel.type="triangle"),金字塔形(opts.extra.funnel.type="pyramid")
+- uCharts.js 增加 散点图(opts.type="scatter")、气泡图(opts.type="bubble")
+- 后期计划 完善散点图、气泡图,增加markPoints标记点,增加横向条状图。
+## 2.0.0-20210502(2021-05-02)
+- uCharts.js 修复词云图获取点击索引不正确的bug
+## 2.0.0-20210501(2021-05-01)
+- 秋云图表组件 修复QQ小程序、百度小程序在关闭动画效果情况下,v-for循环使用图表,显示不正确的bug
+## 2.0.0-20210426(2021-04-26)
+- 秋云图表组件 修复QQ小程序不支持canvas2d的bug
+- 秋云图表组件 修复钉钉小程序某些情况点击坐标计算错误的bug
+- uCharts.js 增加 extra.column.categoryGap 参数,柱状图类每个category点位(X轴点)柱子组之间的间距
+- uCharts.js 增加 yAxis.data[i].titleOffsetY 参数,标题纵向偏移距离,负数为向上偏移,正数向下偏移
+- uCharts.js 增加 yAxis.data[i].titleOffsetX 参数,标题横向偏移距离,负数为向左偏移,正数向右偏移
+- uCharts.js 增加 extra.gauge.labelOffset 参数,仪表盘标签文字径向便宜距离,默认13px
+## 2.0.0-20210422-2(2021-04-22)
+秋云图表组件 修复 formatterAssign 未判断 args[key] == null 的情况导致栈溢出的 bug
+## 2.0.0-20210422(2021-04-22)
+- 秋云图表组件 修复H5、APP、支付宝小程序、微信小程序canvas2d模式下横屏模式的bug
+## 2.0.0-20210421(2021-04-21)
+- uCharts.js 修复多行图例的情况下,图例在上方或者下方时,图例float为左侧或者右侧时,第二行及以后的图例对齐方式不正确的bug
+## 2.0.0-20210420(2021-04-20)
+- 秋云图表组件 修复微信小程序开启canvas2d模式后,windows版微信小程序不支持canvas2d模式的bug
+- 秋云图表组件 修改非uni_modules版本为v2.0版本qiun-data-charts组件
+## 2.0.0-20210419(2021-04-19)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 修复混合图中柱状图单独设置颜色不生效的bug
+- uCharts.js 修复多Y轴单独设置fontSize时,开启canvas2d后,未对应放大字体的bug
+## 2.0.0-20210418(2021-04-18)
+- 秋云图表组件 增加directory配置,修复H5端history模式下如果发布到二级目录无法正确加载echarts.min.js的bug
+## 2.0.0-20210416(2021-04-16)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复APP端某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员
+- 示例项目 修复APP端v-for循环某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员
+- uCharts.js 修复非直角坐标系tooltip提示窗右侧超出未变换方向显示的bug
+## 2.0.0-20210415(2021-04-15)
+- 秋云图表组件 修复H5端发布到二级目录下echarts无法加载的bug
+- 秋云图表组件 修复某些情况下echarts.off('finished')移除监听事件报错的bug
+## 2.0.0-20210414(2021-04-14)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复H5端在cli项目下ECharts引用地址错误的bug
+- 示例项目 增加ECharts的formatter用法的示例(详见示例项目format-e.vue)
+- uCharts.js 增加圆环图中心背景色的配置extra.ring.centerColor
+- uCharts.js 修复微信小程序安卓端柱状图开启透明色后显示不正确的bug
+## 2.0.0-20210413(2021-04-13)
+- 秋云图表组件 修复百度小程序多个图表真机未能正确获取根元素dom尺寸的bug
+- 秋云图表组件 修复百度小程序横屏模式方向不正确的bug
+- 秋云图表组件 修改ontouch时,@getTouchStart@getTouchMove@getTouchEnd的触发条件
+- uCharts.js 修复饼图类数据格式series属性不生效的bug
+- uCharts.js 增加时序区域图 详见示例项目中ucharts.vue
+## 2.0.0-20210412-2(2021-04-12)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX。如仍不好用,请重启电脑,此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复uCharts在APP端横屏模式下不能正确渲染的bug
+- 示例项目 增加ECharts柱状图渐变色、圆角柱状图、横向柱状图(条状图)的示例
+## 2.0.0-20210412(2021-04-12)
+- 秋云图表组件 修复created中判断echarts导致APP端无法识别,改回mounted中判断echarts初始化
+- uCharts.js 修复2d模式下series.textOffset未乘像素比的bug
+## 2.0.0-20210411(2021-04-11)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX,并清空小程序开发者工具缓存。
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 折线图区域图增加connectNulls断点续连的功能,详见示例项目中ucharts.vue
+- 秋云图表组件 变更初始化方法为created,变更type2d默认值为true,优化2d模式下组件初始化后dom获取不到的bug
+- 秋云图表组件 修复左右布局时,右侧图表点击坐标错误的bug,修复tooltip柱状图自定义颜色显示object的bug
+## 2.0.0-20210410(2021-04-10)
+- 修复左右布局时,右侧图表点击坐标错误的bug,修复柱状图自定义颜色tooltip显示object的bug
+- 增加标记线及柱状图自定义颜色的demo
+## 2.0.0-20210409(2021-04-08)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
+## 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 修复钉钉小程序百度小程序measureText不准确的bug,修复2d模式下饼图类activeRadius为按比例放大的bug
+- 修复组件在支付宝小程序端点击位置不准确的bug
+## 2.0.0-20210408(2021-04-07)
+- 修复组件在支付宝小程序端不能显示的bug(目前支付宝小程不能点击交互,后续修复)
+- uCharts.js 修复高分屏下柱状图类,圆弧进度条 自定义宽度不能按比例放大的bug
+## 2.0.0-20210407(2021-04-06)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
+## 增加 通过tofix和unit快速格式化y轴的demo add by `howcode`
+## 增加 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+## 2.0.0-20210406(2021-04-05)
+# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页
+## 2.0.0(2021-04-05)
+# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页

+ 1618 - 0
uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue

@@ -0,0 +1,1618 @@
+<!-- 
+ * qiun-data-charts 秋云高性能跨全端图表组件
+ * Copyright (c) 2021 QIUN® 秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 为方便更多开发者使用,如有更好的建议请提交码云 Pull Requests !
+ *
+ * uCharts®官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ -->
+<template>
+  <view class="chartsview" :id="'ChartBoxId'+cid">
+    <view v-if="mixinDatacomLoading">
+      <!-- 自定义加载状态,请改这里 -->
+      <qiun-loading :loadingType="loadingType" />
+    </view>
+    <view v-if="mixinDatacomErrorMessage && errorShow" @tap="reloading">
+      <!-- 自定义错误提示,请改这里 -->
+      <qiun-error :errorMessage="errorMessage" />
+    </view>
+    <!-- APP和H5采用renderjs渲染图表 -->
+    <!-- #ifdef APP-VUE || H5 -->
+    <block v-if="echarts">
+      <view
+        :style="{ background: background }"
+        style="width: 100%;height: 100%;"
+        :data-directory="directory"
+        :id="'EC'+cid" 
+        :prop="echartsOpts" 
+        :change:prop="rdcharts.ecinit" 
+        :resize="echartsResize"
+        :change:resize="rdcharts.ecresize"
+        v-show="showchart"
+      />
+    </block>
+    <block v-else>
+      <view
+        v-on:tap="rdcharts.tap"
+        v-on:mousemove="rdcharts.mouseMove"
+        v-on:mousedown="rdcharts.mouseDown"
+        v-on:mouseup="rdcharts.mouseUp"
+        v-on:touchstart="rdcharts.touchStart"
+        v-on:touchmove="rdcharts.touchMove"
+        v-on:touchend="rdcharts.touchEnd"
+        :id="'UC'+cid"
+        :prop="uchartsOpts"
+        :change:prop="rdcharts.ucinit"
+      >
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          :disable-scroll="disableScroll"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+    </block>
+    <!-- #endif -->
+    <!-- 支付宝小程序 -->
+    <!-- #ifdef MP-ALIPAY -->
+    <block v-if="ontouch">
+      <canvas
+        :id="cid"
+        :canvasId="cid"
+        :width="cWidth * pixel"
+        :height="cHeight * pixel"
+        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+        :disable-scroll="disScroll"
+        @tap="_tap"
+        @touchstart="_touchStart"
+        @touchmove="_touchMove"
+        @touchend="_touchEnd"
+        @error="_error"
+        v-show="showchart"
+      />
+    </block>
+    <block v-if="!ontouch">
+      <canvas
+        :id="cid"
+        :canvasId="cid"
+        :width="cWidth * pixel"
+        :height="cHeight * pixel"
+        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+        :disable-scroll="disScroll"
+        @tap="_tap"
+        @error="_error"
+        v-show="showchart"
+      />
+    </block>
+    <!-- #endif -->
+    <!-- 其他小程序通过vue渲染图表 -->
+    <!-- #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO || MP-KUAISHOU || MP-LARK || MP-JD || MP-360 -->
+    <block v-if="type2d">
+      <view v-if="ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          type="2d"
+          :disable-scroll="disScroll"
+          @touchstart="_touchStart"
+          @touchmove="_touchMove"
+          @touchend="_touchEnd"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+      <view v-if="!ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          type="2d"
+          :disable-scroll="disScroll"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+    </block>
+    <block v-if="!type2d">
+      <view v-if="ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          @touchstart="_touchStart"
+          @touchmove="_touchMove"
+          @touchend="_touchEnd"
+          :disable-scroll="disScroll"
+          @error="_error"
+          v-if="showchart"
+        />
+      </view>
+      <view v-if="!ontouch" >
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          :disable-scroll="disScroll"
+          @tap="_tap"
+          @error="_error"
+          v-if="showchart"
+        />
+      </view>
+    </block>
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+import uCharts from '../../js_sdk/u-charts/u-charts.js';
+import cfu from '../../js_sdk/u-charts/config-ucharts.js';
+// #ifdef APP-VUE || H5
+import cfe from '../../js_sdk/u-charts/config-echarts.js';
+// #endif
+
+function deepCloneAssign(origin = {}, ...args) {
+  for (let i in args) {
+    for (let key in args[i]) {
+      if (args[i].hasOwnProperty(key)) {
+        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? deepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
+      }
+    }
+  }
+  return origin;
+}
+
+function formatterAssign(args,formatter) {
+  for (let key in args) {
+    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
+      formatterAssign(args[key],formatter)
+    }else if(key === 'format' && typeof args[key] === 'string'){
+      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
+    }
+  }
+  return args;
+}
+
+// 时间转换函数,为了匹配uniClinetDB读取出的时间与categories不同
+function getFormatDate(date) {
+	var seperator = "-";
+	var year = date.getFullYear();
+	var month = date.getMonth() + 1;
+	var strDate = date.getDate();
+	if (month >= 1 && month <= 9) {
+			month = "0" + month;
+	}
+	if (strDate >= 0 && strDate <= 9) {
+			strDate = "0" + strDate;
+	}
+	var currentdate = year + seperator + month + seperator + strDate;
+	return currentdate;
+}
+
+var lastMoveTime = null;
+/**
+ * 防抖
+ *
+ * @param { Function } fn 要执行的方法
+ * @param { Number } wait  防抖多少毫秒
+ *
+ * 在 vue 中使用(注意:不能使用箭头函数,否则this指向不对,并且不能再次封装如:
+ * move(){  // 错误调用方式
+ *   debounce(function () {
+ *   console.log(this.title);
+ * }, 1000)});
+ * 应该直接使用:// 正确调用方式
+ * move: debounce(function () {
+ *   console.log(this.title);
+ * }, 1000)
+ */
+function debounce(fn, wait) {
+  let timer = false;
+  return function() {
+    clearTimeout(timer);
+    timer && clearTimeout(timer);
+    timer = setTimeout(() => {
+      timer = false;
+      fn.apply(this, arguments); // 把参数传进去
+    }, wait);
+  };
+}
+
+export default {
+  name: 'qiun-data-charts',
+  mixins: [uniCloud.mixinDatacom],
+  props: {
+    type: {
+      type: String,
+      default: null
+    },
+    canvasId: {
+      type: String,
+      default: 'uchartsid'
+    },
+    canvas2d: {
+      type: Boolean,
+      default: false
+    },
+    background: {
+      type: String,
+      default: 'rgba(0,0,0,0)'
+    },
+    animation: {
+      type: Boolean,
+      default: true
+    },
+    chartData: {
+      type: Object,
+      default() {
+        return {
+          categories: [],
+          series: []
+        };
+      }
+    },
+    opts: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    eopts: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    loadingType: {
+      type: Number,
+      default: 2
+    },
+    errorShow: {
+      type: Boolean,
+      default: true
+    },
+    errorReload: {
+      type: Boolean,
+      default: true
+    },
+    errorMessage: {
+      type: String,
+      default: null
+    },
+    inScrollView: {
+      type: Boolean,
+      default: false
+    },
+    reshow: {
+      type: Boolean,
+      default: false
+    },
+    reload: {
+      type: Boolean,
+      default: false
+    },
+    disableScroll: {
+      type: Boolean,
+      default: false
+    },
+    optsWatch: {
+      type: Boolean,
+      default: true
+    },
+    onzoom: {
+      type: Boolean,
+      default: false
+    },
+    ontap: {
+      type: Boolean,
+      default: true
+    },
+    ontouch: {
+      type: Boolean,
+      default: false
+    },
+    onmouse: {
+      type: Boolean,
+      default: true
+    },
+    onmovetip: {
+      type: Boolean,
+      default: false
+    },
+    echartsH5: {
+      type: Boolean,
+      default: false
+    },
+    echartsApp: {
+      type: Boolean,
+      default: false
+    },
+    tooltipShow: {
+      type: Boolean,
+      default: true
+    },
+    tooltipFormat: {
+      type: String,
+      default: undefined
+    },
+    tooltipCustom: {
+      type: Object,
+      default: undefined
+    },
+    startDate: {
+      type: String,
+      default: undefined
+    },
+    endDate: {
+      type: String,
+      default: undefined
+    },
+    textEnum: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    groupEnum: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    pageScrollTop: {
+      type: Number,
+      default: 0
+    },
+    directory: {
+      type: String,
+      default: '/'
+    },
+    tapLegend: {
+      type: Boolean,
+      default: true
+    },
+    menus: {
+      type: Array,
+      default () {
+        return []
+      }
+    }
+  },
+  data() {
+    return {
+      cid: 'uchartsid',
+      inWx: false,
+      inAli: false,
+      inTt: false,
+      inBd: false,
+      inH5: false,
+      inApp: false,
+      inWin: false,
+      type2d: true,
+      disScroll: false,
+      openmouse: false,
+      pixel: 1,
+      cWidth: 375,
+      cHeight: 250,
+      showchart: false,
+      echarts: false,
+      echartsResize:{
+        state:false
+      },
+      uchartsOpts: {},
+      echartsOpts: {},
+      drawData:{},
+      lastDrawTime:null,
+    };
+  },
+  created(){
+    this.cid = this.canvasId
+    if (this.canvasId == 'uchartsid' || this.canvasId == '') {
+      let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
+      let len = t.length
+      let id = ''
+      for (let i = 0; i < 32; i++) {
+        id += t.charAt(Math.floor(Math.random() * len))
+      }
+      this.cid = id
+    }
+    const systemInfo = uni.getSystemInfoSync()
+    if(systemInfo.platform === 'windows' || systemInfo.platform === 'mac'){
+      this.inWin = true;
+    }
+    // #ifdef MP-WEIXIN
+    this.inWx = true;
+    if (this.canvas2d === false || systemInfo.platform === 'windows' || systemInfo.platform === 'mac') {
+      this.type2d = false;
+    }else{
+      this.type2d = true;
+      this.pixel = systemInfo.pixelRatio;
+    }
+    // #endif
+    //非微信小程序端强制关闭canvas2d模式
+    // #ifndef MP-WEIXIN
+    this.type2d = false;
+    // #endif
+    // #ifdef  MP-TOUTIAO || MP-LARK || MP-ALIPAY
+    this.type2d = this.canvas2d;
+    // #endif
+    // #ifdef MP-ALIPAY
+    this.inAli = true;
+    this.pixel = systemInfo.pixelRatio;
+    // #endif
+    // #ifdef MP-BAIDU
+    this.inBd = true;
+    // #endif
+    // #ifdef MP-TOUTIAO
+    this.inTt = true;
+    // #endif
+    this.disScroll = this.disableScroll;
+  },
+  mounted() {
+    // #ifdef APP-VUE
+    this.inApp = true;
+    if (this.echartsApp === true) {
+      this.echarts = true;
+      this.openmouse = false;
+    }
+    // #endif
+    // #ifdef APP-NVUE
+    this.inApp = true;
+    this.mixinDatacomLoading = false
+    this.mixinDatacomErrorMessage = "暂不支持NVUE"
+    // #endif
+    // #ifdef H5
+    this.inH5 = true;
+    if(this.inWin === true){
+      this.openmouse = this.onmouse;
+    }
+    if (this.echartsH5 === true) {
+      this.echarts = true;
+    }
+    // #endif
+    this.$nextTick(()=>{
+      this.beforeInit();
+    })
+    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || APP-VUE
+    const time = this.inH5 ? 500 : 200;
+    const _this = this;
+    uni.onWindowResize(
+      debounce(function(res) {
+        if (_this.mixinDatacomLoading == true) {
+          return;
+        }
+        let errmsg = _this.mixinDatacomErrorMessage;
+        if (errmsg !== null && errmsg !== 'null' && errmsg !== '') {
+          return;
+        }
+        if (_this.echarts) {
+          _this.echartsResize.state = !_this.echartsResize.state;
+        } else {
+          _this.resizeHandler();
+        }
+      }, time)
+    );
+    // #endif
+  },
+  destroyed(){
+    if(this.echarts === true){
+      delete cfe.option[this.cid]
+      delete cfe.instance[this.cid]
+    }else{
+      delete cfu.option[this.cid]
+      delete cfu.instance[this.cid]
+    }
+    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
+    uni.offWindowResize(()=>{})
+    // #endif
+  },
+  watch: {
+    chartDataProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval)) {
+            this._clearChart();
+            if (val.series && val.series.length > 0) {
+              this.beforeInit();
+            }else{
+              this.mixinDatacomLoading = true;
+              this.showchart = false;
+              this.mixinDatacomErrorMessage = null;
+            }
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this._clearChart();
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:chartData数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    localdata:{
+      handler(val, oldval) {
+        if (JSON.stringify(val) !== JSON.stringify(oldval)) {
+          if (val.length > 0) {
+            this.beforeInit();
+          }else{
+            this.mixinDatacomLoading = true;
+            this._clearChart();
+            this.showchart = false;
+            this.mixinDatacomErrorMessage = null;
+          }
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    optsProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === false && this.optsWatch == true) {
+            this.checkData(this.drawData);
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this._clearChart();
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:opts数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    eoptsProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === true) {
+            this.checkData(this.drawData);
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:eopts数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    reshow(val, oldval) {
+      if (val === true && this.mixinDatacomLoading === false) {
+        setTimeout(() => {
+          this.mixinDatacomErrorMessage = null;
+          this.echartsResize.state = !this.echartsResize.state;
+          this.checkData(this.drawData);
+        }, 200);
+      }
+    },
+    reload(val, oldval) {
+      if (val === true) {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this.reloading();
+      }
+    },
+    mixinDatacomErrorMessage(val, oldval) {
+      if (val) {
+        this.emitMsg({name: 'error', params: {type:"error", errorShow: this.errorShow, msg: val, id: this.cid}});
+        if(this.errorShow){
+          console.log('[秋云图表组件]' + val);
+        }
+      }
+    },
+    errorMessage(val, oldval) {
+      if (val && this.errorShow && val !== null && val !== 'null' && val !== '') {
+        this.showchart = false;
+        this.mixinDatacomLoading = false;
+        this.mixinDatacomErrorMessage = val;
+      } else {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this.reloading();
+      }
+    }
+  },
+  computed: {
+    optsProps() {
+      return JSON.parse(JSON.stringify(this.opts));
+    },
+    eoptsProps() {
+      return JSON.parse(JSON.stringify(this.eopts));
+    },
+    chartDataProps() {
+      return JSON.parse(JSON.stringify(this.chartData));
+    },
+  },
+  methods: {
+    beforeInit(){
+      this.mixinDatacomErrorMessage = null;
+      if (typeof this.chartData === 'object' && this.chartData != null && this.chartData.series !== undefined && this.chartData.series.length > 0) {
+        //拷贝一下chartData,为了opts变更后统一数据来源
+        this.drawData = deepCloneAssign({}, this.chartData);
+        this.mixinDatacomLoading = false;
+        this.showchart = true;
+        this.checkData(this.chartData);
+      }else if(this.localdata.length>0){
+        this.mixinDatacomLoading = false;
+        this.showchart = true;
+        this.localdataInit(this.localdata);
+      }else if(this.collection !== ''){
+        this.mixinDatacomLoading = false;
+        this.getCloudData();
+      }else{
+        this.mixinDatacomLoading = true;
+      }
+    },
+    localdataInit(resdata){
+      //替换enum类型为正确的描述
+      if(this.groupEnum.length>0){
+        for (let i = 0; i < resdata.length; i++) {
+          for (let j = 0; j < this.groupEnum.length; j++) {
+            if(resdata[i].group === this.groupEnum[j].value){
+              resdata[i].group = this.groupEnum[j].text
+            }
+          }
+        }
+      }
+      if(this.textEnum.length>0){
+        for (let i = 0; i < resdata.length; i++) {
+          for (let j = 0; j < this.textEnum.length; j++) {
+            if(resdata[i].text === this.textEnum[j].value){
+              resdata[i].text = this.textEnum[j].text
+            }
+          }
+        }
+      }
+      let needCategories = false;
+      let tmpData = {categories:[], series:[]}
+      let tmpcategories = []
+      let tmpseries = [];
+      //拼接categories
+      if(this.echarts === true){
+        needCategories = cfe.categories.includes(this.type)
+      }else{
+        needCategories = cfu.categories.includes(this.type)
+      }
+      if(needCategories === true){
+        //如果props中的chartData带有categories,则优先使用chartData的categories
+        if(this.chartData && this.chartData.categories && this.chartData.categories.length>0){
+          tmpcategories = this.chartData.categories
+        }else{
+          //如果是日期类型的数据,不管是本地数据还是云数据,都按起止日期自动拼接categories
+          if(this.startDate && this.endDate){
+            let idate = new Date(this.startDate)
+            let edate = new Date(this.endDate)
+            while (idate <= edate) {
+            	tmpcategories.push(getFormatDate(idate))
+            	idate = idate.setDate(idate.getDate() + 1)
+            	idate = new Date(idate)
+            }
+          //否则从结果中去重并拼接categories
+          }else{
+            let tempckey = {};
+            resdata.map(function(item, index) {
+              if (item.text != undefined && !tempckey[item.text]) {
+                tmpcategories.push(item.text)
+                tempckey[item.text] = true
+              }
+            });
+          }
+        }
+        tmpData.categories = tmpcategories
+      }
+      //拼接series
+      let tempskey = {};
+      resdata.map(function(item, index) {
+        if (item.group != undefined && !tempskey[item.group]) {
+          tmpseries.push({ name: item.group, data: [] });
+          tempskey[item.group] = true;
+        }
+      });
+      //如果没有获取到分组名称(可能是带categories的数据,也可能是不带的饼图类)
+      if (tmpseries.length == 0) {
+        tmpseries = [{ name: '默认分组', data: [] }];
+        //如果是需要categories的图表类型
+        if(needCategories === true){
+          for (let j = 0; j < tmpcategories.length; j++) {
+            let seriesdata = 0;
+            for (let i = 0; i < resdata.length; i++) {
+              if (resdata[i].text == tmpcategories[j]) {
+                seriesdata = resdata[i].value;
+              }
+            }
+            tmpseries[0].data.push(seriesdata);
+          }
+        //如果是饼图类的图表类型
+        }else{
+          for (let i = 0; i < resdata.length; i++) {
+            tmpseries[0].data.push({"name": resdata[i].text,"value": resdata[i].value});
+          }
+        }
+      //如果有分组名
+      } else {
+        for (let k = 0; k < tmpseries.length; k++) {
+          //如果有categories
+          if (tmpcategories.length > 0) {
+            for (let j = 0; j < tmpcategories.length; j++) {
+              let seriesdata = 0;
+              for (let i = 0; i < resdata.length; i++) {
+                if (tmpseries[k].name == resdata[i].group && resdata[i].text == tmpcategories[j]) {
+                  seriesdata = resdata[i].value;
+                }
+              }
+              tmpseries[k].data.push(seriesdata);
+            }
+          //如果传了group而没有传text,即没有categories(正常情况下这种数据是不符合数据要求规范的)
+          } else {
+            for (let i = 0; i < resdata.length; i++) {
+              if (tmpseries[k].name == resdata[i].group) {
+                tmpseries[k].data.push(resdata[i].value);
+              }
+            }
+          }
+        }
+      }
+      tmpData.series = tmpseries
+      //拷贝一下chartData,为了opts变更后统一数据来源
+      this.drawData = deepCloneAssign({}, tmpData);
+      this.checkData(tmpData)
+    },
+    reloading() {
+      if(this.errorReload === false){
+        return;
+      }
+      this.showchart = false;
+      this.mixinDatacomErrorMessage = null;
+      if (this.collection !== '') {
+        this.mixinDatacomLoading = false;
+        this.onMixinDatacomPropsChange(true);
+      } else {
+        this.beforeInit();
+      }
+    },
+    checkData(anyData) {
+      let cid = this.cid
+      //复位opts或eopts
+      if(this.echarts === true){
+        cfe.option[cid] = deepCloneAssign({}, this.eopts);
+        cfe.option[cid].id = cid;
+        cfe.option[cid].type = this.type;
+      }else{
+        if (this.type && cfu.type.includes(this.type)) {
+          cfu.option[cid] = deepCloneAssign({}, cfu[this.type], this.opts);
+          cfu.option[cid].canvasId = cid;
+        } else {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:props参数中type类型不正确';
+        }
+      }
+      //挂载categories和series
+      let newData = deepCloneAssign({}, anyData);
+      if (newData.series !== undefined && newData.series.length > 0) {
+        this.mixinDatacomErrorMessage = null;
+        if (this.echarts === true) {
+          cfe.option[cid].chartData = newData;
+          this.$nextTick(()=>{
+            this.init()
+          })
+        }else{
+          cfu.option[cid].categories = newData.categories;
+          cfu.option[cid].series = newData.series;
+          this.$nextTick(()=>{
+            this.init()
+          })
+        }
+      }
+    },
+    resizeHandler() {
+      //渲染防抖
+      let currTime = Date.now();
+      let lastDrawTime = this.lastDrawTime?this.lastDrawTime:currTime-3000;
+      let duration = currTime - lastDrawTime;
+      if (duration < 1000) return;
+      let chartdom = uni
+        .createSelectorQuery()
+        // #ifndef MP-ALIPAY
+        .in(this)
+        // #endif
+        .select('#ChartBoxId'+this.cid)
+        .boundingClientRect(data => {
+          this.showchart = true;
+          if (data.width > 0 && data.height > 0) {
+            if (data.width !== this.cWidth || data.height !== this.cHeight) {
+              this.checkData(this.drawData)
+            }
+          }
+        })
+        .exec();
+    },
+    getCloudData() {
+      if (this.mixinDatacomLoading == true) {
+        return;
+      }
+      this.mixinDatacomLoading = true;
+      this.mixinDatacomGet()
+        .then(res => {
+          this.mixinDatacomResData = res.result.data;
+          this.localdataInit(this.mixinDatacomResData);
+        })
+        .catch(err => {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '请求错误:' + err;
+        });
+    },
+    onMixinDatacomPropsChange(needReset, changed) {
+      if (needReset == true && this.collection !== '') {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this._clearChart();
+        this.getCloudData();
+      }
+    },
+    _clearChart() {
+      let cid = this.cid
+      if (this.echarts !== true && cfu.option[cid] && cfu.option[cid].context) {
+        const ctx = cfu.option[cid].context;
+        if(typeof ctx === "object" && !!!cfu.option[cid].update){
+          ctx.clearRect(0, 0, this.cWidth*this.pixel, this.cHeight*this.pixel);
+          ctx.draw();
+        }
+      }
+    },
+    init() {
+      let cid = this.cid
+      let chartdom = uni
+        .createSelectorQuery()
+        // #ifndef MP-ALIPAY
+        .in(this)
+        // #endif
+        .select('#ChartBoxId'+cid)
+        .boundingClientRect(data => {
+          if (data.width > 0 && data.height > 0) {
+            this.mixinDatacomLoading = false;
+            this.showchart = true;
+            this.lastDrawTime = Date.now();
+            this.cWidth = data.width;
+            this.cHeight = data.height;
+            if(this.echarts !== true){
+              cfu.option[cid].background = this.background == 'rgba(0,0,0,0)' ? '#FFFFFF' : this.background;
+              cfu.option[cid].canvas2d = this.type2d;
+              cfu.option[cid].pixelRatio = this.pixel;
+              cfu.option[cid].animation = this.animation;
+              cfu.option[cid].width = data.width * this.pixel;
+              cfu.option[cid].height = data.height * this.pixel;
+              cfu.option[cid].onzoom = this.onzoom;
+              cfu.option[cid].ontap = this.ontap;
+              cfu.option[cid].ontouch = this.ontouch;
+              cfu.option[cid].onmouse = this.openmouse;
+              cfu.option[cid].onmovetip = this.onmovetip;
+              cfu.option[cid].tooltipShow = this.tooltipShow;
+              cfu.option[cid].tooltipFormat = this.tooltipFormat;
+              cfu.option[cid].tooltipCustom = this.tooltipCustom;
+              cfu.option[cid].inScrollView = this.inScrollView;
+              cfu.option[cid].lastDrawTime = this.lastDrawTime;
+              cfu.option[cid].tapLegend = this.tapLegend;
+            }
+            //如果是H5或者App端,采用renderjs渲染图表
+            if (this.inH5 || this.inApp) {
+              if (this.echarts == true) {
+                cfe.option[cid].ontap = this.ontap;
+                cfe.option[cid].onmouse = this.openmouse;
+                cfe.option[cid].tooltipShow = this.tooltipShow;
+                cfe.option[cid].tooltipFormat = this.tooltipFormat;
+                cfe.option[cid].tooltipCustom = this.tooltipCustom;
+                cfe.option[cid].lastDrawTime = this.lastDrawTime;
+                this.echartsOpts = deepCloneAssign({}, cfe.option[cid]);
+              } else {
+                cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                this.uchartsOpts = deepCloneAssign({}, cfu.option[cid]);
+              }
+            //如果是小程序端,采用uCharts渲染
+            } else {
+              cfu.option[cid] = formatterAssign(cfu.option[cid],cfu.formatter)
+              this.mixinDatacomErrorMessage = null;
+              this.mixinDatacomLoading = false;
+              this.showchart = true;
+              this.$nextTick(()=>{
+                if (this.type2d === true) {
+                  const query = uni.createSelectorQuery().in(this)
+                  query
+                    .select('#' + cid)
+                    .fields({ node: true, size: true })
+                    .exec(res => {
+                      if (res[0]) {
+                        const canvas = res[0].node;
+                        const ctx = canvas.getContext('2d');
+                        cfu.option[cid].context = ctx;
+                        cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+                          this._updataUChart(cid)
+                        }else{
+                          canvas.width = data.width * this.pixel;
+                          canvas.height = data.height * this.pixel;
+                          canvas._width = data.width * this.pixel;
+                          canvas._height = data.height * this.pixel;
+                          setTimeout(()=>{
+                            cfu.option[cid].context.restore();
+                            cfu.option[cid].context.save();
+                            this._newChart(cid)
+                          },100)
+                        }
+                      } else {
+                        this.showchart = false;
+                        this.mixinDatacomErrorMessage = '参数错误:开启2d模式后,未获取到dom节点,canvas-id:' + cid;
+                      }
+                    });
+                } else {
+                  if(this.inAli){
+                    cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                  }
+                  cfu.option[cid].context = uni.createCanvasContext(cid, this);
+                  if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+                    this._updataUChart(cid)
+                  }else{
+                    setTimeout(()=>{
+                      cfu.option[cid].context.restore();
+                      cfu.option[cid].context.save();
+                      this._newChart(cid)
+                    },100)
+                  }
+                }
+              })
+            }
+          } else {
+            this.mixinDatacomLoading = false;
+            this.showchart = false;
+            if (this.reshow == true) {
+              this.mixinDatacomErrorMessage = '布局错误:未获取到父元素宽高尺寸!canvas-id:' + cid;
+            }
+          }
+        })
+        .exec();
+    },
+    saveImage(){
+    	uni.canvasToTempFilePath({
+    	  canvasId: this.cid,
+    	  success: res=>{
+    	    //#ifdef H5
+    			var a = document.createElement("a");
+    			a.href = res.tempFilePath;
+    			a.download = this.cid;
+    			a.target = '_blank'
+    			a.click();
+    	    //#endif
+    	    //#ifndef H5
+    	      uni.saveImageToPhotosAlbum({
+              filePath: res.tempFilePath,
+              success: function () {
+                uni.showToast({
+                  title: '保存成功',
+                  duration: 2000
+                });
+              }
+    	      });
+    	    //#endif
+    	  } 
+    	},this);
+    },
+    getImage(){
+      if(this.type2d == false){
+        uni.canvasToTempFilePath({
+          canvasId: this.cid,
+          success: res=>{
+            this.emitMsg({name: 'getImage', params: {type:"getImage", base64: res.tempFilePath}});
+          }
+        },this);
+      }else{
+        const query = uni.createSelectorQuery().in(this)
+        query
+          .select('#' + this.cid)
+          .fields({ node: true, size: true })
+          .exec(res => {
+            if (res[0]) {
+              const canvas = res[0].node;
+              this.emitMsg({name: 'getImage', params: {type:"getImage", base64: canvas.toDataURL('image/png')}});
+            }
+          });
+      }
+    },
+    // #ifndef APP-VUE || H5
+    _newChart(cid) {
+      if (this.mixinDatacomLoading == true) {
+        return;
+      }
+      this.showchart = true;
+      cfu.instance[cid] = new uCharts(cfu.option[cid]);
+      cfu.instance[cid].addEventListener('renderComplete', () => {
+        this.emitMsg({name: 'complete', params: {type:"complete", complete: true, id: cid, opts: cfu.instance[cid].opts}});
+        cfu.instance[cid].delEventListener('renderComplete')
+      });
+      cfu.instance[cid].addEventListener('scrollLeft', () => {
+        this.emitMsg({name: 'scrollLeft', params: {type:"scrollLeft", scrollLeft: true, id: cid, opts: cfu.instance[cid].opts}});
+      });
+      cfu.instance[cid].addEventListener('scrollRight', () => {
+        this.emitMsg({name: 'scrollRight', params: {type:"scrollRight", scrollRight: true, id: cid, opts: cfu.instance[cid].opts}});
+      });
+    },
+    _updataUChart(cid) {
+      cfu.instance[cid].updateData(cfu.option[cid])
+    },
+    _tooltipDefault(item, category, index, opts) {
+      if (category) {
+        let data = item.data
+        if(typeof item.data === "object"){
+          data = item.data.value
+        }
+        return category + ' ' + item.name + ':' + data;
+      } else {
+        if (item.properties && item.properties.name) {
+          return item.properties.name;
+        } else {
+          return item.name + ':' + item.data;
+        }
+      }
+    },
+    _showTooltip(e) {
+      let cid = this.cid
+      let tc = cfu.option[cid].tooltipCustom
+      if (tc && tc !== undefined && tc !== null) {
+        let offset = undefined;
+        if (tc.x >= 0 && tc.y >= 0) {
+          offset = { x: tc.x, y: tc.y + 10 };
+        }
+        cfu.instance[cid].showToolTip(e, {
+          index: tc.index,
+          offset: offset,
+          textList: tc.textList,
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this._tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      } else {
+        cfu.instance[cid].showToolTip(e, {
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this._tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      }
+    },
+    _tap(e,move) {
+      let cid = this.cid
+      let currentIndex = null;
+      let legendIndex = null;
+      if (this.inScrollView === true || this.inAli) {
+        let chartdom = uni
+          .createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this)
+          .select('#ChartBoxId'+cid)
+          // #endif
+          // #ifdef MP-ALIPAY
+          .select('#'+this.cid)
+          // #endif
+          .boundingClientRect(data => {
+            e.changedTouches=[];
+            if (this.inAli) {
+              e.changedTouches.unshift({ x: e.detail.clientX - data.left, y: e.detail.clientY - data.top});
+            }else{
+              e.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top - this.pageScrollTop});
+            }
+            if(move){
+              if (this.tooltipShow === true) {
+                this._showTooltip(e);
+              }
+            }else{
+              currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
+              legendIndex = cfu.instance[cid].getLegendDataIndex(e);
+              if(this.tapLegend === true){
+                cfu.instance[cid].touchLegend(e);
+              }
+              if (this.tooltipShow === true) {
+                this._showTooltip(e);
+              }
+              this.emitMsg({name: 'getIndex', params: { type:"getIndex", event:{ x: e.detail.x - data.left, y: e.detail.y - data.top }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
+            }
+          })
+          .exec();
+      } else {
+        if(move){
+          if (this.tooltipShow === true) {
+            this._showTooltip(e);
+          }
+        }else{
+          e.changedTouches=[];
+          e.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop });
+          currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
+          legendIndex = cfu.instance[cid].getLegendDataIndex(e);
+          if(this.tapLegend === true){
+            cfu.instance[cid].touchLegend(e);
+          }
+          if (this.tooltipShow === true) {
+            this._showTooltip(e);
+          }
+          this.emitMsg({name: 'getIndex', params: {type:"getIndex", event:{ x: e.detail.x, y: e.detail.y - e.currentTarget.offsetTop }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
+        }
+      }
+    },
+    _touchStart(e) {
+      let cid = this.cid
+      lastMoveTime=Date.now();
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
+        cfu.instance[cid].scrollStart(e);
+      }
+      this.emitMsg({name:'getTouchStart', params:{type:"touchStart", event:e.changedTouches[0], id:cid, opts: cfu.instance[cid].opts}});
+    },
+    _touchMove(e) {
+      let cid = this.cid
+      let currMoveTime = Date.now();
+      let duration = currMoveTime - lastMoveTime;
+      let touchMoveLimit = cfu.option[cid].touchMoveLimit || 24;
+      if (duration < Math.floor(1000 / touchMoveLimit)) return;//每秒60帧
+      lastMoveTime = currMoveTime;
+      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
+        cfu.instance[cid].scroll(e);
+      }
+      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
+        this._tap(e,true)
+      }
+      if(this.ontouch === true && cfu.option[cid].enableScroll === true && this.onzoom === true && e.changedTouches.length == 2){
+        cfu.instance[cid].dobuleZoom(e);
+      }
+      this.emitMsg({name: 'getTouchMove', params: {type:"touchMove", event:e.changedTouches[0], id: cid, opts: cfu.instance[cid].opts}});
+    },
+    _touchEnd(e) {
+      let cid = this.cid
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
+        cfu.instance[cid].scrollEnd(e);
+      }
+      this.emitMsg({name:'getTouchEnd', params:{type:"touchEnd", event:e.changedTouches[0], id:cid, opts: cfu.instance[cid].opts}});
+      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
+        this._tap(e,true)
+      }
+    },
+    // #endif
+    _error(e) {
+      this.mixinDatacomErrorMessage = e.detail.errMsg;
+    },
+    emitMsg(msg) {
+      this.$emit(msg.name, msg.params);
+    },
+    getRenderType() {
+      //防止如果开启echarts且父元素为v-if的情况renderjs监听不到prop变化的问题
+      if(this.echarts===true && this.mixinDatacomLoading===false){
+        this.beforeInit()
+      }
+    },
+    toJSON(){
+      return this
+    }
+  }
+};
+</script>
+
+<!-- #ifdef APP-VUE || H5 -->
+<script module="rdcharts" lang="renderjs">
+import uChartsRD from '../../js_sdk/u-charts/u-charts.js';
+import cfu from '../../js_sdk/u-charts/config-ucharts.js';
+import cfe from '../../js_sdk/u-charts/config-echarts.js';
+
+var that = {};
+var rootdom = null;
+
+function rddeepCloneAssign(origin = {}, ...args) {
+  for (let i in args) {
+    for (let key in args[i]) {
+      if (args[i].hasOwnProperty(key)) {
+        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? rddeepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
+      }
+    }
+  }
+  return origin;
+}
+
+function rdformatterAssign(args,formatter) {
+  for (let key in args) {
+    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
+      rdformatterAssign(args[key],formatter)
+    }else if(key === 'format' && typeof args[key] === 'string'){
+      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
+    }
+  }
+  return args;
+}
+
+export default {
+  data() {
+    return {
+      rid:null
+    }
+  },
+  mounted() {
+    rootdom = {top:0,left:0}
+    // #ifdef H5
+    let dm = document.querySelectorAll('uni-main')[0]
+    if(dm === undefined){
+      dm = document.querySelectorAll('uni-page-wrapper')[0]
+    }
+    rootdom = {top:dm.offsetTop,left:dm.offsetLeft}
+    // #endif
+    setTimeout(()=>{
+      if(this.rid === null){
+        this.$ownerInstance && this.$ownerInstance.callMethod('getRenderType')
+      }
+    },200)
+  },
+  destroyed(){
+    delete cfu.option[this.rid]
+    delete cfu.instance[this.rid]
+    delete cfe.option[this.rid]
+    delete cfe.instance[this.rid]
+  },
+  methods: {
+    //==============以下是ECharts的方法====================
+    ecinit(newVal, oldVal, owner, instance){
+      let cid = JSON.stringify(newVal.id)
+      this.rid = cid
+      that[cid] = this.$ownerInstance || instance
+      let eopts = JSON.parse(JSON.stringify(newVal))
+      let type = eopts.type;
+      //载入并覆盖默认配置
+      if (type && cfe.type.includes(type)) {
+        cfe.option[cid] = rddeepCloneAssign({}, cfe[type], eopts);
+      }else{
+        cfe.option[cid] = rddeepCloneAssign({}, eopts);
+      }
+      let newData = eopts.chartData;
+      if(newData){
+        //挂载categories和series
+        if(cfe.option[cid].xAxis && cfe.option[cid].xAxis.type && cfe.option[cid].xAxis.type === 'category'){
+          cfe.option[cid].xAxis.data = newData.categories
+        }
+        if(cfe.option[cid].yAxis && cfe.option[cid].yAxis.type && cfe.option[cid].yAxis.type === 'category'){
+          cfe.option[cid].yAxis.data = newData.categories
+        }
+        cfe.option[cid].series = []
+        for (var i = 0; i < newData.series.length; i++) {
+          cfe.option[cid].seriesTemplate = cfe.option[cid].seriesTemplate ? cfe.option[cid].seriesTemplate : {}
+          let Template = rddeepCloneAssign({},cfe.option[cid].seriesTemplate,newData.series[i])
+          cfe.option[cid].series.push(Template)
+        }
+      }
+      
+      if (typeof window.echarts === 'object') {
+          this.newEChart()
+      }else{
+        const script = document.createElement('script')
+        // #ifdef APP-VUE
+        script.src = './uni_modules/qiun-data-charts/static/app-plus/echarts.min.js'
+        // #endif
+        // #ifdef H5
+        const rooturl = window.location.origin
+        const directory = instance.getDataset().directory
+        script.src = rooturl + directory + 'uni_modules/qiun-data-charts/static/h5/echarts.min.js'
+        // #endif
+        script.onload = this.newEChart
+        document.head.appendChild(script)
+      }
+    },
+    ecresize(newVal, oldVal, owner, instance){
+      if(cfe.instance[this.rid]){
+        cfe.instance[this.rid].resize()
+      }
+    },
+    newEChart(){
+      let cid = this.rid
+      if(cfe.instance[cid] === undefined){
+        cfe.instance[cid] = echarts.init(that[cid].$el.children[0])
+        //ontap开启后才触发click事件
+        if(cfe.option[cid].ontap === true){
+          cfe.instance[cid].on('click', resdata => {
+            let event = JSON.parse(JSON.stringify({
+              x:resdata.event.offsetX,y:resdata.event.offsetY
+            }))
+            that[cid].callMethod('emitMsg',{name:"getIndex", params:{type:"getIndex", event:event, currentIndex:resdata.dataIndex, value:resdata.data, seriesName: resdata.seriesName,id:cid}})
+          })
+          // 增加ECharts的highlight消息,实现按下移动返回索引功能。add by onefish 创建于 2021-12-11 09:50
+          cfe.instance[cid].on('highlight', resdata => {
+            that[cid].callMethod('emitMsg',{name:"getHighlight", params:{type:"highlight", res:resdata, id:cid}})
+          })
+        }
+        this.updataEChart(cid,cfe.option[cid])
+      }else{
+        this.updataEChart(cid,cfe.option[cid])
+      }
+    },
+    updataEChart(cid,option){
+      //替换option内format属性为formatter的预定义方法
+      option = rdformatterAssign(option,cfe.formatter)
+      if(option.tooltip){
+        option.tooltip.show = option.tooltipShow?true:false;
+        option.tooltip.position = this.tooltipPosition()
+        //tooltipFormat方法,替换组件的tooltipFormat为config-echarts.js内对应的方法
+        if (typeof option.tooltipFormat === 'string' && cfe.formatter[option.tooltipFormat]) {
+          option.tooltip.formatter = option.tooltip.formatter ? option.tooltip.formatter : cfe.formatter[option.tooltipFormat]
+        }
+      }
+      // 颜色渐变添加的方法
+      if (option.series) {
+      	for (let i in option.series) {
+      		let linearGradient = option.series[i].linearGradient
+      		if (linearGradient) {
+      			option.series[i].color = new echarts.graphic.LinearGradient(linearGradient[0],linearGradient[1],linearGradient[2],linearGradient[3],linearGradient[4])
+      		}
+      	}
+      }
+      cfe.instance[cid].setOption(option, option.notMerge)
+      cfe.instance[cid].on('finished', function(){
+        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
+        if(cfe.instance[cid]){
+          cfe.instance[cid].off('finished')
+        }
+      });
+
+      //修复init初始化实例获取宽高不正确问题
+      if(
+        typeof that[cid].$el.children[0].clientWidth != 'undefined' &&
+          (
+            Math.abs( that[cid].$el.children[0].clientWidth - cfe.instance[cid].getWidth() )>3 ||
+            Math.abs( that[cid].$el.children[0].clientHeight - cfe.instance[cid].getHeight() )>3
+          )
+      ){this.ecresize();}
+    },
+    tooltipPosition(){
+      return (point, params, dom, rect, size) => {
+      	let x = point[0]
+      	let y = point[1]
+      	let viewWidth = size.viewSize[0]
+      	let viewHeight = size.viewSize[1]
+      	let boxWidth = size.contentSize[0]
+      	let boxHeight = size.contentSize[1]
+      	let posX = x + 30 
+      	let posY = y + 30 
+      	if (posX + boxWidth > viewWidth) { 
+      		posX = x - boxWidth - 30
+      	}
+      	if (posY + boxHeight > viewHeight) {
+      		posY = y - boxHeight - 30
+      	}
+      	return [posX, posY]
+      }
+    },
+    //==============以下是uCharts的方法====================
+    ucinit(newVal, oldVal, owner, instance){
+      if(JSON.stringify(newVal) == JSON.stringify(oldVal)){
+        return;
+      }
+      if(!newVal.canvasId){
+        return;
+      }
+      let cid = JSON.parse(JSON.stringify(newVal.canvasId))
+      this.rid = cid
+      that[cid] = this.$ownerInstance || instance
+      cfu.option[cid] = JSON.parse(JSON.stringify(newVal))
+      cfu.option[cid] = rdformatterAssign(cfu.option[cid],cfu.formatter)
+      let canvasdom = document.getElementById(cid)
+      if(canvasdom && canvasdom.children[0]){
+        cfu.option[cid].context = canvasdom.children[0].getContext("2d")
+        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+          this.updataUChart()
+        }else{
+          setTimeout(()=>{
+            cfu.option[cid].context.restore();
+            cfu.option[cid].context.save();
+            this.newUChart()
+          },100)
+        }
+      }
+    },
+    newUChart() {
+      let cid = this.rid
+      cfu.instance[cid] = new uChartsRD(cfu.option[cid])
+      cfu.instance[cid].addEventListener('renderComplete', () => {
+        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid, opts: cfu.instance[cid].opts}})
+        cfu.instance[cid].delEventListener('renderComplete')
+      });
+      cfu.instance[cid].addEventListener('scrollLeft', () => {
+        that[cid].callMethod('emitMsg',{name:"scrollLeft",params:{type:"scrollLeft",scrollLeft:true,id:cid, opts: cfu.instance[cid].opts}})
+      });
+      cfu.instance[cid].addEventListener('scrollRight', () => {
+        that[cid].callMethod('emitMsg',{name:"scrollRight",params:{type:"scrollRight",scrollRight:true,id:cid, opts: cfu.instance[cid].opts}})
+      });
+    },
+    updataUChart() {
+      let cid = this.rid
+      cfu.instance[cid].updateData(cfu.option[cid])
+    },
+    tooltipDefault(item, category, index, opts) {
+      if (category) {
+        let data = item.data
+        if(typeof item.data === "object"){
+          data = item.data.value
+        }
+        return category + ' ' + item.name + ':' + data;
+      } else {
+        if (item.properties && item.properties.name) {
+          return item.properties.name ;
+        } else {
+          return item.name + ':' + item.data;
+        }
+      }
+    },
+    showTooltip(e,cid) {
+      let tc = cfu.option[cid].tooltipCustom
+      if (tc && tc !== undefined && tc !== null) {
+        let offset = undefined;
+        if (tc.x >= 0 && tc.y >= 0) {
+          offset = { x: tc.x, y: tc.y + 10 };
+        }
+        cfu.instance[cid].showToolTip(e, {
+          index: tc.index,
+          offset: offset,
+          textList: tc.textList,
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this.tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      } else {
+        cfu.instance[cid].showToolTip(e, {
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this.tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      }
+    },
+    tap(e) {
+      let cid = this.rid
+      let ontap = cfu.option[cid].ontap
+      let tooltipShow = cfu.option[cid].tooltipShow
+      let tapLegend = cfu.option[cid].tapLegend
+      if(ontap == false) return;
+      let currentIndex=null
+      let legendIndex=null
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      if(e.detail.x){//tap或者click的事件
+        tmpe = { x: e.detail.x - rchartdom.left, y:e.detail.y - rchartdom.top + rootdom.top}
+      }else{//mouse的事件
+        tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      }
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      currentIndex=cfu.instance[cid].getCurrentDataIndex(e)
+      legendIndex=cfu.instance[cid].getLegendDataIndex(e)
+      if(tapLegend === true){
+        cfu.instance[cid].touchLegend(e);
+      }
+      if(tooltipShow==true){
+        this.showTooltip(e,cid)
+      }
+      that[cid].callMethod('emitMsg',{name:"getIndex",params:{type:"getIndex",event:tmpe,currentIndex:currentIndex,legendIndex:legendIndex,id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchStart(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
+        cfu.instance[cid].scrollStart(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"touchStart",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchMove(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
+        cfu.instance[cid].scroll(e);
+      }
+      if(cfu.option[cid].ontap === true && cfu.option[cid].enableScroll === false && cfu.option[cid].onmovetip === true){
+        let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+        let tmpe = { x: e.changedTouches[0].clientX - rchartdom.left, y:e.changedTouches[0].clientY - rchartdom.top + rootdom.top}
+        e.changedTouches.unshift(tmpe)
+        if(cfu.option[cid].tooltipShow === true){
+          this.showTooltip(e,cid)
+        }
+      }
+      if(ontouch === true && cfu.option[cid].enableScroll === true && cfu.option[cid].onzoom === true && e.changedTouches.length == 2){
+        cfu.instance[cid].dobuleZoom(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"touchMove",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchEnd(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
+        cfu.instance[cid].scrollEnd(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"touchEnd",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    mouseDown(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      cfu.instance[cid].scrollStart(e)
+      cfu.option[cid].mousedown=true;
+      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"mouseDown",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+    },
+    mouseMove(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      let tooltipShow = cfu.option[cid].tooltipShow
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      if(cfu.option[cid].mousedown){
+        cfu.instance[cid].scroll(e)
+        that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"mouseMove",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+      }else if(cfu.instance[cid]){
+        if(tooltipShow==true){
+          this.showTooltip(e,cid)
+        }
+      }
+    },
+    mouseUp(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      cfu.instance[cid].scrollEnd(e)
+      cfu.option[cid].mousedown=false;
+      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"mouseUp",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+    },
+  }
+}
+</script>
+<!-- #endif -->
+
+<style scoped>
+.chartsview {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex: 1;
+  justify-content: center;
+  align-items: center;
+}
+</style>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 42 - 0
uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue


+ 162 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue

@@ -0,0 +1,162 @@
+<template>
+	 <view class="container loading1">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading1',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+.container.loading1 {
+  -webkit-transform: rotate(45deg);
+          transform: rotate(45deg);
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading1 .shape1 {
+  -webkit-animation: animation1shape1 0.5s ease 0s infinite alternate;
+          animation: animation1shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, 16px);
+            transform: translate(16px, 16px);
+  }
+}
+
+@keyframes animation1shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, 16px);
+            transform: translate(16px, 16px);
+  }
+}
+.loading1 .shape2 {
+  -webkit-animation: animation1shape2 0.5s ease 0s infinite alternate;
+          animation: animation1shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, 16px);
+            transform: translate(-16px, 16px);
+  }
+}
+
+@keyframes animation1shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, 16px);
+            transform: translate(-16px, 16px);
+  }
+}
+.loading1 .shape3 {
+  -webkit-animation: animation1shape3 0.5s ease 0s infinite alternate;
+          animation: animation1shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, -16px);
+            transform: translate(16px, -16px);
+  }
+}
+
+@keyframes animation1shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, -16px);
+            transform: translate(16px, -16px);
+  }
+}
+.loading1 .shape4 {
+  -webkit-animation: animation1shape4 0.5s ease 0s infinite alternate;
+          animation: animation1shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, -16px);
+            transform: translate(-16px, -16px);
+  }
+}
+
+@keyframes animation1shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, -16px);
+            transform: translate(-16px, -16px);
+  }
+}
+
+
+</style>

+ 170 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue

@@ -0,0 +1,170 @@
+<template>
+	 <view class="container loading2">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading2',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading2 {
+  -webkit-transform: rotate(10deg);
+          transform: rotate(10deg);
+}
+.container.loading2 .shape {
+  border-radius: 5px;
+}
+.container.loading2{
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+
+.loading2 .shape1 {
+  -webkit-animation: animation2shape1 0.5s ease 0s infinite alternate;
+          animation: animation2shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, 20px);
+            transform: translate(20px, 20px);
+  }
+}
+
+@keyframes animation2shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, 20px);
+            transform: translate(20px, 20px);
+  }
+}
+.loading2 .shape2 {
+  -webkit-animation: animation2shape2 0.5s ease 0s infinite alternate;
+          animation: animation2shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, 20px);
+            transform: translate(-20px, 20px);
+  }
+}
+
+@keyframes animation2shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, 20px);
+            transform: translate(-20px, 20px);
+  }
+}
+.loading2 .shape3 {
+  -webkit-animation: animation2shape3 0.5s ease 0s infinite alternate;
+          animation: animation2shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, -20px);
+            transform: translate(20px, -20px);
+  }
+}
+
+@keyframes animation2shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, -20px);
+            transform: translate(20px, -20px);
+  }
+}
+.loading2 .shape4 {
+  -webkit-animation: animation2shape4 0.5s ease 0s infinite alternate;
+          animation: animation2shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, -20px);
+            transform: translate(-20px, -20px);
+  }
+}
+
+@keyframes animation2shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, -20px);
+            transform: translate(-20px, -20px);
+  }
+}
+
+</style>

+ 173 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue

@@ -0,0 +1,173 @@
+<template>
+	 <view class="container loading3">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading3',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+ .container.loading3 {
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+.container.loading3 .shape1 {
+  border-top-left-radius: 10px;
+}
+.container.loading3 .shape2 {
+  border-top-right-radius: 10px;
+}
+.container.loading3 .shape3 {
+  border-bottom-left-radius: 10px;
+}
+.container.loading3 .shape4 {
+  border-bottom-right-radius: 10px;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading3 .shape1 {
+  -webkit-animation: animation3shape1 0.5s ease 0s infinite alternate;
+          animation: animation3shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, 5px);
+            transform: translate(5px, 5px);
+  }
+}
+
+@keyframes animation3shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, 5px);
+            transform: translate(5px, 5px);
+  }
+}
+.loading3 .shape2 {
+  -webkit-animation: animation3shape2 0.5s ease 0s infinite alternate;
+          animation: animation3shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, 5px);
+            transform: translate(-5px, 5px);
+  }
+}
+
+@keyframes animation3shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, 5px);
+            transform: translate(-5px, 5px);
+  }
+}
+.loading3 .shape3 {
+  -webkit-animation: animation3shape3 0.5s ease 0s infinite alternate;
+          animation: animation3shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, -5px);
+            transform: translate(5px, -5px);
+  }
+}
+
+@keyframes animation3shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, -5px);
+            transform: translate(5px, -5px);
+  }
+}
+.loading3 .shape4 {
+  -webkit-animation: animation3shape4 0.5s ease 0s infinite alternate;
+          animation: animation3shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, -5px);
+            transform: translate(-5px, -5px);
+  }
+}
+
+@keyframes animation3shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, -5px);
+            transform: translate(-5px, -5px);
+  }
+}
+</style>

+ 222 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue

@@ -0,0 +1,222 @@
+<template>
+	 <view class="container loading5">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading5',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading5 .shape {
+  width: 15px;
+  height: 15px;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading5 .shape1 {
+  animation: animation5shape1 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+  50% {
+    -webkit-transform: translate(15px, 15px);
+            transform: translate(15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+}
+
+@keyframes animation5shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+  50% {
+    -webkit-transform: translate(15px, 15px);
+            transform: translate(15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+}
+.loading5 .shape2 {
+  animation: animation5shape2 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-15px, 15px);
+            transform: translate(-15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+}
+
+@keyframes animation5shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-15px, 15px);
+            transform: translate(-15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+}
+.loading5 .shape3 {
+  animation: animation5shape3 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(15px, -15px);
+            transform: translate(15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+}
+
+@keyframes animation5shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(15px, -15px);
+            transform: translate(15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+}
+.loading5 .shape4 {
+  animation: animation5shape4 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+  50% {
+    -webkit-transform: translate(-15px, -15px);
+            transform: translate(-15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+}
+
+@keyframes animation5shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+  50% {
+    -webkit-transform: translate(-15px, -15px);
+            transform: translate(-15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+}
+
+</style>

+ 229 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue

@@ -0,0 +1,229 @@
+<template>
+	 <view class="container loading6">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading6',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading6 {
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+.container.loading6 .shape {
+  width: 12px;
+  height: 12px;
+  border-radius: 2px;
+}
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+
+.loading6 .shape1 {
+  -webkit-animation: animation6shape1 2s linear 0s infinite normal;
+          animation: animation6shape1 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+  50% {
+    -webkit-transform: translate(18px, 18px);
+            transform: translate(18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+}
+
+@keyframes animation6shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+  50% {
+    -webkit-transform: translate(18px, 18px);
+            transform: translate(18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+}
+.loading6 .shape2 {
+  -webkit-animation: animation6shape2 2s linear 0s infinite normal;
+          animation: animation6shape2 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-18px, 18px);
+            transform: translate(-18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+}
+
+@keyframes animation6shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-18px, 18px);
+            transform: translate(-18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+}
+.loading6 .shape3 {
+  -webkit-animation: animation6shape3 2s linear 0s infinite normal;
+          animation: animation6shape3 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(18px, -18px);
+            transform: translate(18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+}
+
+@keyframes animation6shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(18px, -18px);
+            transform: translate(18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+}
+.loading6 .shape4 {
+  -webkit-animation: animation6shape4 2s linear 0s infinite normal;
+          animation: animation6shape4 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+  50% {
+    -webkit-transform: translate(-18px, -18px);
+            transform: translate(-18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+}
+
+@keyframes animation6shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+  50% {
+    -webkit-transform: translate(-18px, -18px);
+            transform: translate(-18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+}
+</style>

+ 36 - 0
uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue

@@ -0,0 +1,36 @@
+<template>
+	<view>
+	 <Loading1 v-if="loadingType==1"/>
+	 <Loading2 v-if="loadingType==2"/>
+	 <Loading3 v-if="loadingType==3"/>
+	 <Loading4 v-if="loadingType==4"/>
+	 <Loading5 v-if="loadingType==5"/>
+	</view>
+</template>
+
+<script>
+	import Loading1 from "./loading1.vue";
+	import Loading2 from "./loading2.vue";
+	import Loading3 from "./loading3.vue";
+	import Loading4 from "./loading4.vue";
+	import Loading5 from "./loading5.vue";
+	export default {
+		components:{Loading1,Loading2,Loading3,Loading4,Loading5},
+		name: 'qiun-loading',
+		props: {
+			loadingType: {
+				type: Number,
+				default: 2
+			},
+		},
+		data() {
+			return {
+				
+			};
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 422 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js

@@ -0,0 +1,422 @@
+/*
+ * uCharts®
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
+ * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 
+ * uCharts®官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+
+// 通用配置项
+
+// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
+const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
+
+const cfe = {
+  //demotype为自定义图表类型
+	"type": ["pie", "ring", "rose", "funnel", "line", "column", "area", "radar", "gauge","candle","demotype"],
+  //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型例如最后的"demotype"
+	"categories": ["line", "column", "area", "radar", "gauge", "candle","demotype"],
+  //instance为实例变量承载属性,option为eopts承载属性,不要删除
+	"instance": {},
+	"option": {},
+  //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
+  "formatter":{
+    "tooltipDemo1":function(res){
+      let result = ''
+      for (let i in res) {
+      	if (i == 0) {
+      		result += res[i].axisValueLabel + '年销售额'
+      	}
+      	let value = '--'
+      	if (res[i].data !== null) {
+      		value = res[i].data
+      	}
+      	// #ifdef H5
+      	result += '\n' + res[i].seriesName + ':' + value + ' 万元'
+      	// #endif
+      	
+      	// #ifdef APP-PLUS
+      	result += '<br/>' + res[i].marker + res[i].seriesName + ':' + value + ' 万元'
+      	// #endif
+      }
+      return result;
+    },
+    legendFormat:function(name){
+      return "自定义图例+"+name;
+    },
+    yAxisFormatDemo:function (value, index) {
+      return value + '元';
+    },
+    seriesFormatDemo:function(res){
+      return res.name + '年' + res.value + '元';
+    }
+  },
+  //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在eopts参数,会将demotype与eopts中option合并后渲染图表。
+  "demotype":{
+    "color": color,
+    //在这里填写echarts的option即可
+    
+  },
+  //下面是自定义配置,请添加项目所需的通用配置
+	"column": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'bar',
+			"data": [],
+			"barwidth": 20,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"line": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'line',
+			"data": [],
+			"barwidth": 20,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"area": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'line',
+			"data": [],
+			"areaStyle": {},
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"pie": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"grid": {
+			"top": 40,
+			"bottom": 30,
+			"right": 15,
+			"left": 15
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": '50%',
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"ring": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"grid": {
+			"top": 40,
+			"bottom": 30,
+			"right": 15,
+			"left": 15
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": ['40%', '70%'],
+			"avoidLabelOverlap": false,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+			"labelLine": {
+				"show": true
+			},
+		},
+	},
+	"rose": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"legend": {
+			"top": 'bottom'
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": "55%",
+			"center": ['50%', '50%'],
+			"roseType": 'area',
+		},
+	},
+	"funnel": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item',
+			"formatter": "{b} : {c}%"
+		},
+		"legend": {
+			"top": 'bottom'
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'funnel',
+			"left": '10%',
+			"top": 60,
+			"bottom": 60,
+			"width": '80%',
+			"min": 0,
+			"max": 100,
+			"minSize": '0%',
+			"maxSize": '100%',
+			"sort": 'descending',
+			"gap": 2,
+			"label": {
+				"show": true,
+				"position": 'inside'
+			},
+			"labelLine": {
+				"length": 10,
+				"lineStyle": {
+					"width": 1,
+					"type": 'solid'
+				}
+			},
+			"itemStyle": {
+				"bordercolor": '#fff',
+				"borderwidth": 1
+			},
+			"emphasis": {
+				"label": {
+					"fontSize": 20
+				}
+			},
+			"data": [],
+		},
+	},
+	"gauge": {
+		"color": color,
+		"tooltip": {
+        "formatter": '{a} <br/>{b} : {c}%'
+    },
+		"seriesTemplate": {
+			"name": '业务指标',
+      "type": 'gauge',
+      "detail": {"formatter": '{value}%'},
+      "data": [{"value": 50, "name": '完成率'}]
+		},
+	},
+	"candle": {
+		"xAxis": {
+			"data": []
+		},
+		"yAxis": {},
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"dataZoom": [{
+				"type": 'inside',
+				"xAxisIndex": [0, 1],
+				"start": 10,
+				"end": 100
+			},
+			{
+				"show": true,
+				"xAxisIndex": [0, 1],
+				"type": 'slider',
+				"bottom": 10,
+				"start": 10,
+				"end": 100
+			}
+		],
+		"seriesTemplate": {
+			"name": '',
+			"type": 'k',
+			"data": [],
+		},
+	}
+}
+
+export default cfe;

+ 606 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js

@@ -0,0 +1,606 @@
+/*
+ * uCharts®
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
+ * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 
+ * uCharts®官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+
+// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
+const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
+
+//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改
+const formatDateTime = (timeStamp, returnType)=>{
+  var date = new Date();
+  date.setTime(timeStamp * 1000);
+  var y = date.getFullYear();
+  var m = date.getMonth() + 1;
+  m = m < 10 ? ('0' + m) : m;
+  var d = date.getDate();
+  d = d < 10 ? ('0' + d) : d;
+  var h = date.getHours();
+  h = h < 10 ? ('0' + h) : h;
+  var minute = date.getMinutes();
+  var second = date.getSeconds();
+  minute = minute < 10 ? ('0' + minute) : minute;
+  second = second < 10 ? ('0' + second) : second;
+  if(returnType == 'full'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;}
+  if(returnType == 'y-m-d'){return y + '-' + m + '-' + d;}
+  if(returnType == 'h:m'){return  h +':' + minute;}
+  if(returnType == 'h:m:s'){return  h +':' + minute +':' + second;}
+  return [y, m, d, h, minute, second];
+}
+
+const cfu = {
+  //demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
+	"type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","bar","area","radar","gauge","candle","mix","tline","tarea","scatter","bubble","demotype"],
+	"range":["饼状图","圆环图","玫瑰图","词云图","漏斗图","地图","圆弧进度条","折线图","柱状图","山峰图","条状图","区域图","雷达图","仪表盘","K线图","混合图","时间轴折线","时间轴区域","散点图","气泡图","自定义类型"],
+  //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype"
+  //自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories
+	"categories":["line","column","mount","bar","area","radar","gauge","candle","mix","demotype"],
+  //instance为实例变量承载属性,不要删除
+  "instance":{},
+  //option为opts及eopts承载属性,不要删除
+  "option":{},
+  //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
+  "formatter":{
+    "yAxisDemo1":function(val, index, opts){return val+'元'},
+    "yAxisDemo2":function(val, index, opts){return val.toFixed(2)},
+    "xAxisDemo1":function(val, index, opts){return val+'年';},
+    "xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')},
+    "seriesDemo1":function(val, index, series, opts){return val+'元'},
+    "tooltipDemo1":function(item, category, index, opts){
+      if(index==0){
+      	return '随便用'+item.data+'年'
+      }else{
+      	return '其他我没改'+item.data+'天'
+      }
+    },
+    "pieDemo":function(val, index, series, opts){
+      if(index !== undefined){
+        return series[index].name+':'+series[index].data+'元'
+      }
+    },
+  },
+  //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
+  "demotype":{
+    //我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
+    "type": "line",
+    "color": color,
+    "padding": [15,10,0,15],
+    "xAxis": {
+      "disableGrid": true,
+    },
+    "yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+    },
+    "legend": {
+    },
+    "extra": {
+    	"line": {
+    		"type": "curve",
+    		"width": 2
+    	},
+    }
+  },
+  //下面是自定义配置,请添加项目所需的通用配置
+	"pie":{
+		"type": "pie",
+    "color": color,
+		"padding": [5,5,5,5],
+		"extra": {
+			"pie": {
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": true,
+				"borderWidth": 3,
+				"borderColor": "#FFFFFF"
+			},
+		}
+	},
+	"ring":{
+		"type": "ring",
+    "color": color,
+		"padding": [5,5,5,5],
+		"rotate": false,
+		"dataLabel": true,
+		"legend": {
+			"show": true,
+			"position": "right",
+      "lineHeight": 25,
+		},
+		"title": {
+			"name": "收益率",
+			"fontSize": 15,
+			"color": "#666666"
+		},
+		"subtitle": {
+			"name": "70%",
+			"fontSize": 25,
+			"color": "#7cb5ec"
+		},
+		"extra": {
+			"ring": {
+				"ringWidth":30,
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": true,
+				"borderWidth": 3,
+				"borderColor": "#FFFFFF"
+			},
+		},
+	},
+	"rose":{
+		"type": "rose",
+    "color": color,
+		"padding": [5,5,5,5],
+		"legend": {
+			"show": true,
+			"position": "left",
+      "lineHeight": 25,
+		},
+		"extra": {
+			"rose": {
+				"type": "area",
+				"minRadius": 50,
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": false,
+				"borderWidth": 2,
+				"borderColor": "#FFFFFF"
+			},
+		}
+	},
+	"word":{
+		"type": "word",
+    "color": color,
+		"extra": {
+			"word": {
+				"type": "normal",
+				"autoColors": false
+			}
+		}
+	},
+	"funnel":{
+		"type": "funnel",
+    "color": color,
+		"padding": [15,15,0,15],
+		"extra": {
+			"funnel": {
+				"activeOpacity": 0.3,
+				"activeWidth": 10,
+				"border": true,
+				"borderWidth": 2,
+				"borderColor": "#FFFFFF",
+				"fillOpacity": 1,
+				"labelAlign": "right"
+			},
+		}
+	},
+	"map":{
+		"type": "map",
+    "color": color,
+		"padding": [0,0,0,0],
+    "dataLabel": true,
+		"extra": {
+			"map": {
+				"border": true,
+				"borderWidth": 1,
+				"borderColor": "#666666",
+				"fillOpacity": 0.6,
+				"activeBorderColor": "#F04864",
+				"activeFillColor": "#FACC14",
+				"activeFillOpacity": 1
+			},
+		}
+	},
+	"arcbar":{
+		"type": "arcbar",
+    "color": color,
+		"title": {
+			"name": "百分比",
+			"fontSize": 25,
+			"color": "#00FF00"
+		},
+		"subtitle": {
+			"name": "默认标题",
+			"fontSize": 15,
+			"color": "#666666"
+		},
+		"extra": {
+			"arcbar": {
+				"type": "default",
+				"width": 12,
+				"backgroundColor": "#E9E9E9",
+				"startAngle": 0.75,
+				"endAngle": 0.25,
+				"gap": 2
+			}
+		}
+	},
+	"line":{
+		"type": "line",
+    "color": color,
+		"padding": [15,10,0,15],
+		"xAxis": {
+      "disableGrid": true,
+		},
+		"yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+		},
+		"legend": {
+		},
+		"extra": {
+			"line": {
+				"type": "straight",
+				"width": 2,
+        "activeType": "hollow"
+			},
+		}
+	},
+  "tline":{
+  	"type": "line",
+    "color": color,
+  	"padding": [15,10,0,15],
+  	"xAxis": {
+      "disableGrid": false,
+      "boundaryGap":"justify",
+  	},
+  	"yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+      "data":[
+        {
+          "min":0,
+          "max":80
+        }
+      ]
+  	},
+  	"legend": {
+  	},
+  	"extra": {
+  		"line": {
+  			"type": "curve",
+  			"width": 2,
+        "activeType": "hollow"
+  		},
+  	}
+  },
+  "tarea":{
+  	"type": "area",
+    "color": color,
+  	"padding": [15,10,0,15],
+  	"xAxis": {
+      "disableGrid": true,
+      "boundaryGap":"justify",
+  	},
+  	"yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+      "data":[
+        {
+          "min":0,
+          "max":80
+        }
+      ]
+  	},
+  	"legend": {
+  	},
+  	"extra": {
+  		"area": {
+  			"type": "curve",
+  			"opacity": 0.2,
+  			"addLine": true,
+  			"width": 2,
+  			"gradient": true,
+        "activeType": "hollow"
+  		},
+  	}
+  },
+	"column":{
+		"type": "column",
+    "color": color,
+		"padding": [15,15,0,5],
+		"xAxis": {
+      "disableGrid": true,
+		},
+		"yAxis": {
+      "data":[{"min":0}]
+		},
+		"legend": {
+		},
+		"extra": {
+			"column": {
+				"type": "group",
+				"width": 30,
+				"activeBgColor": "#000000",
+				"activeBgOpacity": 0.08
+			},
+		}
+	},
+  "mount":{
+  	"type": "mount",
+    "color": color,
+  	"padding": [15,15,0,5],
+  	"xAxis": {
+      "disableGrid": true,
+  	},
+  	"yAxis": {
+      "data":[{"min":0}]
+  	},
+  	"legend": {
+  	},
+  	"extra": {
+  		"mount": {
+  			"type": "mount",
+  			"widthRatio": 1.5,
+  		},
+  	}
+  },
+  "bar":{
+  	"type": "bar",
+    "color": color,
+  	"padding": [15,30,0,5],
+  	"xAxis": {
+      "boundaryGap":"justify",
+      "disableGrid":false,
+      "min":0,
+      "axisLine":false
+  	},
+  	"yAxis": {
+  	},
+  	"legend": {
+  	},
+  	"extra": {
+  		"bar": {
+  			"type": "group",
+  			"width": 30,
+  			"meterBorde": 1,
+  			"meterFillColor": "#FFFFFF",
+  			"activeBgColor": "#000000",
+  			"activeBgOpacity": 0.08
+  		},
+  	}
+  },
+	"area":{
+		"type": "area",
+		"color": color,
+		"padding": [15,15,0,15],
+		"xAxis": {
+      "disableGrid": true,
+		},
+		"yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+		},
+		"legend": {
+		},
+		"extra": {
+			"area": {
+				"type": "straight",
+				"opacity": 0.2,
+				"addLine": true,
+				"width": 2,
+				"gradient": false,
+        "activeType": "hollow"
+			},
+		}
+	},
+	"radar":{
+		"type": "radar",
+		"color": color,
+		"padding": [5,5,5,5],
+    "dataLabel": false,
+		"legend": {
+			"show": true,
+			"position": "right",
+      "lineHeight": 25,
+		},
+		"extra": {
+			"radar": {
+				"gridType": "radar",
+				"gridColor": "#CCCCCC",
+				"gridCount": 3,
+				"opacity": 0.2,
+				"max": 200,
+				"labelShow": true
+			},
+		}
+	},
+	"gauge":{
+		"type": "gauge",
+		"color": color,
+		"title": {
+			"name": "66Km/H",
+			"fontSize": 25,
+			"color": "#2fc25b",
+			"offsetY": 50
+		},
+		"subtitle": {
+			"name": "实时速度",
+			"fontSize": 15,
+			"color": "#1890ff",
+			"offsetY": -50
+		},
+		"extra": {
+			"gauge": {
+				"type": "default",
+				"width": 30,
+				"labelColor": "#666666",
+				"startAngle": 0.75,
+				"endAngle": 0.25,
+				"startNumber": 0,
+				"endNumber": 100,
+				"labelFormat": "",
+				"splitLine": {
+					"fixRadius": 0,
+					"splitNumber": 10,
+					"width": 30,
+					"color": "#FFFFFF",
+					"childNumber": 5,
+					"childWidth": 12
+				},
+				"pointer": {
+					"width": 24,
+					"color": "auto"
+				}
+			}
+		}
+	},
+	"candle":{
+		"type": "candle",
+		"color": color,
+		"padding": [15,15,0,15],
+		"enableScroll": true,
+		"enableMarkLine": true,
+		"dataLabel": false,
+		"xAxis": {
+			"labelCount": 4,
+			"itemCount": 40,
+			"disableGrid": true,
+			"gridColor": "#CCCCCC",
+			"gridType": "solid",
+			"dashLength": 4,
+			"scrollShow": true,
+			"scrollAlign": "left",
+			"scrollColor": "#A6A6A6",
+			"scrollBackgroundColor": "#EFEBEF"
+		},
+		"yAxis": {
+		},
+		"legend": {
+		},
+		"extra": {
+			"candle": {
+				"color": {
+					"upLine": "#f04864",
+					"upFill": "#f04864",
+					"downLine": "#2fc25b",
+					"downFill": "#2fc25b"
+				},
+				"average": {
+					"show": true,
+					"name": ["MA5","MA10","MA30"],
+					"day": [5,10,20],
+					"color": ["#1890ff","#2fc25b","#facc14"]
+				}
+			},
+			"markLine": {
+				"type": "dash",
+				"dashLength": 5,
+				"data": [
+					{
+						"value": 2150,
+						"lineColor": "#f04864",
+						"showLabel": true
+					},
+					{
+						"value": 2350,
+						"lineColor": "#f04864",
+						"showLabel": true
+					}
+				]
+			}
+		}
+	},
+	"mix":{
+		"type": "mix",
+		"color": color,
+		"padding": [15,15,0,15],
+		"xAxis": {
+      "disableGrid": true,
+		},
+		"yAxis": {
+			"disabled": false,
+			"disableGrid": false,
+			"splitNumber": 5,
+			"gridType": "dash",
+			"dashLength": 4,
+			"gridColor": "#CCCCCC",
+			"padding": 10,
+			"showTitle": true,
+			"data": []
+		},
+		"legend": {
+		},
+		"extra": {
+			"mix": {
+				"column": {
+					"width": 20
+				}
+			},
+		}
+	},
+	"scatter":{
+		"type": "scatter",
+		"color":color,
+		"padding":[15,15,0,15],
+    "dataLabel":false,
+    "xAxis": {
+      "disableGrid": false,
+      "gridType":"dash",
+      "splitNumber":5,
+      "boundaryGap":"justify",
+      "min":0
+    },
+    "yAxis": {
+      "disableGrid": false,
+      "gridType":"dash",
+    },
+    "legend": {
+    },
+    "extra": {
+    	"scatter": {
+    	},
+    }
+	},
+	"bubble":{
+		"type": "bubble",
+		"color":color,
+		"padding":[15,15,0,15],
+    "xAxis": {
+      "disableGrid": false,
+      "gridType":"dash",
+      "splitNumber":5,
+      "boundaryGap":"justify",
+      "min":0,
+      "max":250
+    },
+    "yAxis": {
+      "disableGrid": false,
+      "gridType":"dash",
+      "data":[{
+        "min":0,
+        "max":150
+      }]
+    },
+    "legend": {
+    },
+    "extra": {
+    	"bubble": {
+        "border":2,
+        "opacity": 0.5,
+    	},
+    }
+	}
+}
+
+export default cfu;

+ 5 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md

@@ -0,0 +1,5 @@
+# uCharts JSSDK说明
+1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`120kb`。
+2、如果120kb的体积仍需压缩,请手到uCharts官网通过在线定制选择您需要的图表。
+3、config-ucharts.js为uCharts组件的用户配置文件,升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。
+4、config-echarts.js为ECharts组件的用户配置文件,升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。

+ 7706 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js

@@ -0,0 +1,7706 @@
+/*
+ * uCharts (R)
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台
+ * Copyright (C) 2018-2022 QIUN (R) 秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 
+ * uCharts (R) 官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+
+'use strict';
+
+var config = {
+  version: 'v2.5.0-20230101',
+  yAxisWidth: 15,
+  xAxisHeight: 22,
+  padding: [10, 10, 10, 10],
+  rotate: false,
+  fontSize: 13,
+  fontColor: '#666666',
+  dataPointShape: ['circle', 'circle', 'circle', 'circle'],
+  color: ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'],
+  linearColor: ['#0EE2F8', '#2BDCA8', '#FA7D8D', '#EB88E2', '#2AE3A0', '#0EE2F8', '#EB88E2', '#6773E3', '#F78A85'],
+  pieChartLinePadding: 15,
+  pieChartTextPadding: 5,
+  titleFontSize: 20,
+  subtitleFontSize: 15,
+  radarLabelTextMargin: 13,
+};
+
+var assign = function(target, ...varArgs) {
+  if (target == null) {
+    throw new TypeError('[uCharts] Cannot convert undefined or null to object');
+  }
+  if (!varArgs || varArgs.length <= 0) {
+    return target;
+  }
+  // 深度合并对象
+  function deepAssign(obj1, obj2) {
+    for (let key in obj2) {
+      obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
+        deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key];
+    }
+    return obj1;
+  }
+  varArgs.forEach(val => {
+    target = deepAssign(target, val);
+  });
+  return target;
+};
+
+var util = {
+  toFixed: function toFixed(num, limit) {
+    limit = limit || 2;
+    if (this.isFloat(num)) {
+      num = num.toFixed(limit);
+    }
+    return num;
+  },
+  isFloat: function isFloat(num) {
+    return num % 1 !== 0;
+  },
+  approximatelyEqual: function approximatelyEqual(num1, num2) {
+    return Math.abs(num1 - num2) < 1e-10;
+  },
+  isSameSign: function isSameSign(num1, num2) {
+    return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
+  },
+  isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
+    return this.isSameSign(p1.x, p2.x);
+  },
+  isCollision: function isCollision(obj1, obj2) {
+    obj1.end = {};
+    obj1.end.x = obj1.start.x + obj1.width;
+    obj1.end.y = obj1.start.y - obj1.height;
+    obj2.end = {};
+    obj2.end.x = obj2.start.x + obj2.width;
+    obj2.end.y = obj2.start.y - obj2.height;
+    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;
+    return !flag;
+  }
+};
+
+//兼容H5点击事件
+function getH5Offset(e) {
+  e.mp = {
+    changedTouches: []
+  };
+  e.mp.changedTouches.push({
+    x: e.offsetX,
+    y: e.offsetY
+  });
+  return e;
+}
+
+// hex 转 rgba
+function hexToRgb(hexValue, opc) {
+  var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+  var hex = hexValue.replace(rgx, function(m, r, g, b) {
+    return r + r + g + g + b + b;
+  });
+  var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+  var r = parseInt(rgb[1], 16);
+  var g = parseInt(rgb[2], 16);
+  var b = parseInt(rgb[3], 16);
+  return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')';
+}
+
+function findRange(num, type, limit) {
+  if (isNaN(num)) {
+    throw new Error('[uCharts] series数据需为Number格式');
+  }
+  limit = limit || 10;
+  type = type ? type : 'upper';
+  var multiple = 1;
+  while (limit < 1) {
+    limit *= 10;
+    multiple *= 10;
+  }
+  if (type === 'upper') {
+    num = Math.ceil(num * multiple);
+  } else {
+    num = Math.floor(num * multiple);
+  }
+  while (num % limit !== 0) {
+    if (type === 'upper') {
+      if (num == num + 1) { //修复数据值过大num++无效的bug by 向日葵 @xrk_jy
+        break;
+      }
+      num++;
+    } else {
+      num--;
+    }
+  }
+  return num / multiple;
+}
+
+function calCandleMA(dayArr, nameArr, colorArr, kdata) {
+  let seriesTemp = [];
+  for (let k = 0; k < dayArr.length; k++) {
+    let seriesItem = {
+      data: [],
+      name: nameArr[k],
+      color: colorArr[k]
+    };
+    for (let i = 0, len = kdata.length; i < len; i++) {
+      if (i < dayArr[k]) {
+        seriesItem.data.push(null);
+        continue;
+      }
+      let sum = 0;
+      for (let j = 0; j < dayArr[k]; j++) {
+        sum += kdata[i - j][1];
+      }
+      seriesItem.data.push(+(sum / dayArr[k]).toFixed(3));
+    }
+    seriesTemp.push(seriesItem);
+  }
+  return seriesTemp;
+}
+
+function calValidDistance(self, distance, chartData, config, opts) {
+  var dataChartAreaWidth = opts.width - opts.area[1] - opts.area[3];
+  var dataChartWidth = chartData.eachSpacing * (opts.chartData.xAxisData.xAxisPoints.length - 1);
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    dataChartWidth += (opts.extra.mount.widthRatio - 1)*chartData.eachSpacing;
+  }
+  var validDistance = distance;
+  if (distance >= 0) {
+    validDistance = 0;
+    self.uevent.trigger('scrollLeft');
+    self.scrollOption.position = 'left'
+    opts.xAxis.scrollPosition = 'left';
+  } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
+    validDistance = dataChartAreaWidth - dataChartWidth;
+    self.uevent.trigger('scrollRight');
+    self.scrollOption.position = 'right'
+    opts.xAxis.scrollPosition = 'right';
+  } else {
+    self.scrollOption.position = distance
+    opts.xAxis.scrollPosition = distance;
+  }
+  return validDistance;
+}
+
+function isInAngleRange(angle, startAngle, endAngle) {
+  function adjust(angle) {
+    while (angle < 0) {
+      angle += 2 * Math.PI;
+    }
+    while (angle > 2 * Math.PI) {
+      angle -= 2 * Math.PI;
+    }
+    return angle;
+  }
+  angle = adjust(angle);
+  startAngle = adjust(startAngle);
+  endAngle = adjust(endAngle);
+  if (startAngle > endAngle) {
+    endAngle += 2 * Math.PI;
+    if (angle < startAngle) {
+      angle += 2 * Math.PI;
+    }
+  }
+  return angle >= startAngle && angle <= endAngle;
+}
+
+function createCurveControlPoints(points, i) {
+  function isNotMiddlePoint(points, i) {
+    if (points[i - 1] && points[i + 1]) {
+      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);
+    } else {
+      return false;
+    }
+  }
+  function isNotMiddlePointX(points, i) {
+    if (points[i - 1] && points[i + 1]) {
+      return points[i].x >= Math.max(points[i - 1].x, points[i + 1].x) || points[i].x <= Math.min(points[i - 1].x,
+        points[i + 1].x);
+    } else {
+      return false;
+    }
+  }
+  var a = 0.2;
+  var b = 0.2;
+  var pAx = null;
+  var pAy = null;
+  var pBx = null;
+  var pBy = null;
+  if (i < 1) {
+    pAx = points[0].x + (points[1].x - points[0].x) * a;
+    pAy = points[0].y + (points[1].y - points[0].y) * a;
+  } else {
+    pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
+    pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
+  }
+
+  if (i > points.length - 3) {
+    var last = points.length - 1;
+    pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
+    pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
+  } else {
+    pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
+    pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
+  }
+  if (isNotMiddlePoint(points, i + 1)) {
+    pBy = points[i + 1].y;
+  }
+  if (isNotMiddlePoint(points, i)) {
+    pAy = points[i].y;
+  }
+  if (isNotMiddlePointX(points, i + 1)) {
+    pBx = points[i + 1].x;
+  }
+  if (isNotMiddlePointX(points, i)) {
+    pAx = points[i].x;
+  }
+  if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) {
+    pAy = points[i].y;
+  }
+  if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) {
+    pBy = points[i + 1].y;
+  }
+  if (pAx >= Math.max(points[i].x, points[i + 1].x) || pAx <= Math.min(points[i].x, points[i + 1].x)) {
+    pAx = points[i].x;
+  }
+  if (pBx >= Math.max(points[i].x, points[i + 1].x) || pBx <= Math.min(points[i].x, points[i + 1].x)) {
+    pBx = points[i + 1].x;
+  }
+  return {
+    ctrA: {
+      x: pAx,
+      y: pAy
+    },
+    ctrB: {
+      x: pBx,
+      y: pBy
+    }
+  };
+}
+
+
+function convertCoordinateOrigin(x, y, center) {
+  return {
+    x: center.x + x,
+    y: center.y - y
+  };
+}
+
+function avoidCollision(obj, target) {
+  if (target) {
+    // is collision test
+    while (util.isCollision(obj, target)) {
+      if (obj.start.x > 0) {
+        obj.start.y--;
+      } else if (obj.start.x < 0) {
+        obj.start.y++;
+      } else {
+        if (obj.start.y > 0) {
+          obj.start.y++;
+        } else {
+          obj.start.y--;
+        }
+      }
+    }
+  }
+  return obj;
+}
+
+function fixPieSeries(series, opts, config){
+  let pieSeriesArr = [];
+  if(series.length>0 && series[0].data.constructor.toString().indexOf('Array') > -1){
+    opts._pieSeries_ = series;
+    let oldseries = series[0].data;
+    for (var i = 0; i < oldseries.length; i++) {
+      oldseries[i].formatter = series[0].formatter;
+      oldseries[i].data = oldseries[i].value;
+      pieSeriesArr.push(oldseries[i]);
+    }
+    opts.series = pieSeriesArr;
+  }else{
+    pieSeriesArr = series;
+  }
+  return pieSeriesArr;
+}
+
+function fillSeries(series, opts, config) {
+  var index = 0;
+  for (var i = 0; i < series.length; i++) {
+    let item = series[i];
+    if (!item.color) {
+      item.color = config.color[index];
+      index = (index + 1) % config.color.length;
+    }
+    if (!item.linearIndex) {
+      item.linearIndex = i;
+    }
+    if (!item.index) {
+      item.index = 0;
+    }
+    if (!item.type) {
+      item.type = opts.type;
+    }
+    if (typeof item.show == "undefined") {
+      item.show = true;
+    }
+    if (!item.type) {
+      item.type = opts.type;
+    }
+    if (!item.pointShape) {
+      item.pointShape = "circle";
+    }
+    if (!item.legendShape) {
+      switch (item.type) {
+        case 'line':
+          item.legendShape = "line";
+          break;
+        case 'column':
+        case 'bar':
+          item.legendShape = "rect";
+          break;
+        case 'area':
+        case 'mount':
+          item.legendShape = "triangle";
+          break;
+        default:
+          item.legendShape = "circle";
+      }
+    }
+  }
+  return series;
+}
+
+function fillCustomColor(linearType, customColor, series, config) {
+  var newcolor = customColor || [];
+  if (linearType == 'custom' && newcolor.length == 0 ) {
+    newcolor = config.linearColor;
+  }
+  if (linearType == 'custom' && newcolor.length < series.length) {
+    let chazhi = series.length - newcolor.length;
+    for (var i = 0; i < chazhi; i++) {
+      newcolor.push(config.linearColor[(i + 1) % config.linearColor.length]);
+    }
+  }
+  return newcolor;
+}
+
+function getDataRange(minData, maxData) {
+  var limit = 0;
+  var range = maxData - minData;
+  if (range >= 10000) {
+    limit = 1000;
+  } else if (range >= 1000) {
+    limit = 100;
+  } else if (range >= 100) {
+    limit = 10;
+  } else if (range >= 10) {
+    limit = 5;
+  } else if (range >= 1) {
+    limit = 1;
+  } else if (range >= 0.1) {
+    limit = 0.1;
+  } else if (range >= 0.01) {
+    limit = 0.01;
+  } else if (range >= 0.001) {
+    limit = 0.001;
+  } else if (range >= 0.0001) {
+    limit = 0.0001;
+  } else if (range >= 0.00001) {
+    limit = 0.00001;
+  } else {
+    limit = 0.000001;
+  }
+  return {
+    minRange: findRange(minData, 'lower', limit),
+    maxRange: findRange(maxData, 'upper', limit)
+  };
+}
+
+function measureText(text, fontSize, context) {
+  var width = 0;
+  text = String(text);
+  // #ifdef MP-ALIPAY || MP-BAIDU || APP-NVUE
+  context = false;
+  // #endif
+  if (context !== false && context !== undefined && context.setFontSize && context.measureText) {
+    context.setFontSize(fontSize);
+    return context.measureText(text).width;
+  } else {
+    var text = text.split('');
+    for (let i = 0; i < text.length; i++) {
+      let item = text[i];
+      if (/[a-zA-Z]/.test(item)) {
+        width += 7;
+      } else if (/[0-9]/.test(item)) {
+        width += 5.5;
+      } else if (/\./.test(item)) {
+        width += 2.7;
+      } else if (/-/.test(item)) {
+        width += 3.25;
+      } else if (/:/.test(item)) {
+        width += 2.5;
+      } else if (/[\u4e00-\u9fa5]/.test(item)) {
+        width += 10;
+      } else if (/\(|\)/.test(item)) {
+        width += 3.73;
+      } else if (/\s/.test(item)) {
+        width += 2.5;
+      } else if (/%/.test(item)) {
+        width += 8;
+      } else {
+        width += 10;
+      }
+    }
+    return width * fontSize / 10;
+  }
+}
+
+function dataCombine(series) {
+  return series.reduce(function(a, b) {
+    return (a.data ? a.data : a).concat(b.data);
+  }, []);
+}
+
+function dataCombineStack(series, len) {
+  var sum = new Array(len);
+  for (var j = 0; j < sum.length; j++) {
+    sum[j] = 0;
+  }
+  for (var i = 0; i < series.length; i++) {
+    for (var j = 0; j < sum.length; j++) {
+      sum[j] += series[i].data[j];
+    }
+  }
+  return series.reduce(function(a, b) {
+    return (a.data ? a.data : a).concat(b.data).concat(sum);
+  }, []);
+}
+
+function getTouches(touches, opts, e) {
+  let x, y;
+  if (touches.clientX) {
+    if (opts.rotate) {
+      y = opts.height - touches.clientX * opts.pix;
+      x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
+    } else {
+      x = touches.clientX * opts.pix;
+      y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
+    }
+  } else {
+    if (opts.rotate) {
+      y = opts.height - touches.x * opts.pix;
+      x = touches.y * opts.pix;
+    } else {
+      x = touches.x * opts.pix;
+      y = touches.y * opts.pix;
+    }
+  }
+  return {
+    x: x,
+    y: y
+  }
+}
+
+function getSeriesDataItem(series, index, group) {
+  var data = [];
+  var newSeries = [];
+  var indexIsArr = index.constructor.toString().indexOf('Array') > -1;
+  if(indexIsArr){
+    let tempSeries = filterSeries(series);
+    for (var i = 0; i < group.length; i++) {
+      newSeries.push(tempSeries[group[i]]);
+    }
+  }else{
+    newSeries = series;
+  };
+  for (let i = 0; i < newSeries.length; i++) {
+    let item = newSeries[i];
+    let tmpindex = -1;
+    if(indexIsArr){
+      tmpindex = index[i];
+    }else{
+      tmpindex = index;
+    }
+    if (item.data[tmpindex] !== null && typeof item.data[tmpindex] !== 'undefined' && item.show) {
+      let seriesItem = {};
+      seriesItem.color = item.color;
+      seriesItem.type = item.type;
+      seriesItem.style = item.style;
+      seriesItem.pointShape = item.pointShape;
+      seriesItem.disableLegend = item.disableLegend;
+      seriesItem.legendShape = item.legendShape;
+      seriesItem.name = item.name;
+      seriesItem.show = item.show;
+      seriesItem.data = item.formatter ? item.formatter(item.data[tmpindex]) : item.data[tmpindex];
+      data.push(seriesItem);
+    }
+  }
+  return data;
+}
+
+function getMaxTextListLength(list, fontSize, context) {
+  var lengthList = list.map(function(item) {
+    return measureText(item, fontSize, context);
+  });
+  return Math.max.apply(null, lengthList);
+}
+
+function getRadarCoordinateSeries(length) {
+  var eachAngle = 2 * Math.PI / length;
+  var CoordinateSeries = [];
+  for (var i = 0; i < length; i++) {
+    CoordinateSeries.push(eachAngle * i);
+  }
+  return CoordinateSeries.map(function(item) {
+    return -1 * item + Math.PI / 2;
+  });
+}
+
+function getToolTipData(seriesData, opts, index, group, categories) {
+  var option = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
+  var calPoints = opts.chartData.calPoints?opts.chartData.calPoints:[];
+  let points = {};
+  if(group.length > 0){
+    let filterPoints = [];
+    for (let i = 0; i < group.length; i++) {
+      filterPoints.push(calPoints[group[i]])
+    }
+    points = filterPoints[0][index[0]];
+  }else{
+    for (let i = 0; i < calPoints.length; i++) {
+      if(calPoints[i][index]){
+        points = calPoints[i][index];
+        break;
+      }
+    }
+  };
+  var textList = seriesData.map(function(item) {
+    let titleText = null;
+    if (opts.categories && opts.categories.length>0) {
+      titleText = categories[index];
+    };
+    return {
+      text: option.formatter ? option.formatter(item, titleText, index, opts) : item.name + ': ' + item.data,
+      color: item.color,
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+  });
+  var offset = {
+    x: Math.round(points.x),
+    y: Math.round(points.y)
+  };
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function getMixToolTipData(seriesData, opts, index, categories) {
+  var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+  var points = opts.chartData.xAxisPoints[index] + opts.chartData.eachSpacing / 2;
+  var textList = seriesData.map(function(item) {
+    return {
+      text: option.formatter ? option.formatter(item, categories[index], index, opts) : item.name + ': ' + item.data,
+      color: item.color,
+      disableLegend: item.disableLegend ? true : false,
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+  });
+  textList = textList.filter(function(item) {
+    if (item.disableLegend !== true) {
+      return item;
+    }
+  });
+  var offset = {
+    x: Math.round(points),
+    y: 0
+  };
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function getCandleToolTipData(series, seriesData, opts, index, categories, extra) {
+  var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
+  var calPoints = opts.chartData.calPoints;
+  let upColor = extra.color.upFill;
+  let downColor = extra.color.downFill;
+  //颜色顺序为开盘,收盘,最低,最高
+  let color = [upColor, upColor, downColor, upColor];
+  var textList = [];
+  seriesData.map(function(item) {
+    if (index == 0) {
+      if (item.data[1] - item.data[0] < 0) {
+        color[1] = downColor;
+      } else {
+        color[1] = upColor;
+      }
+    } else {
+      if (item.data[0] < series[index - 1][1]) {
+        color[0] = downColor;
+      }
+      if (item.data[1] < item.data[0]) {
+        color[1] = downColor;
+      }
+      if (item.data[2] > series[index - 1][1]) {
+        color[2] = upColor;
+      }
+      if (item.data[3] < series[index - 1][1]) {
+        color[3] = downColor;
+      }
+    }
+    let text1 = {
+      text: '开盘:' + item.data[0],
+      color: color[0],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text2 = {
+      text: '收盘:' + item.data[1],
+      color: color[1],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text3 = {
+      text: '最低:' + item.data[2],
+      color: color[2],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text4 = {
+      text: '最高:' + item.data[3],
+      color: color[3],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    textList.push(text1, text2, text3, text4);
+  });
+  var validCalPoints = [];
+  var offset = {
+    x: 0,
+    y: 0
+  };
+  for (let i = 0; i < calPoints.length; i++) {
+    let points = calPoints[i];
+    if (typeof points[index] !== 'undefined' && points[index] !== null) {
+      validCalPoints.push(points[index]);
+    }
+  }
+  offset.x = Math.round(validCalPoints[0][0].x);
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function filterSeries(series) {
+  let tempSeries = [];
+  for (let i = 0; i < series.length; i++) {
+    if (series[i].show == true) {
+      tempSeries.push(series[i])
+    }
+  }
+  return tempSeries;
+}
+
+function findCurrentIndex(currentPoints, calPoints, opts, config) {
+  var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+  var current={ index:-1, group:[] };
+  var spacing = opts.chartData.eachSpacing / 2;
+  let xAxisPoints = [];
+  if (calPoints && calPoints.length > 0) {
+    if (!opts.categories) {
+      spacing = 0;
+    }else{
+      for (let i = 1; i < opts.chartData.xAxisPoints.length; i++) {
+        xAxisPoints.push(opts.chartData.xAxisPoints[i] - spacing);
+      }
+      if ((opts.type == 'line' || opts.type == 'area') && opts.xAxis.boundaryGap == 'justify') {
+        xAxisPoints = opts.chartData.xAxisPoints;
+      }
+    }
+    if (isInExactChartArea(currentPoints, opts, config)) {
+      if (!opts.categories) {
+        let timePoints = Array(calPoints.length);
+        for (let i = 0; i < calPoints.length; i++) {
+          timePoints[i] = Array(calPoints[i].length)
+          for (let j = 0; j < calPoints[i].length; j++) {
+            timePoints[i][j] = (Math.abs(calPoints[i][j].x - currentPoints.x));
+          }
+        };
+        let pointValue =  Array(timePoints.length);
+        let pointIndex =  Array(timePoints.length);
+        for (let i = 0; i < timePoints.length; i++) {
+          pointValue[i] = Math.min.apply(null, timePoints[i]);
+          pointIndex[i] = timePoints[i].indexOf(pointValue[i]);
+        }
+        let minValue = Math.min.apply(null, pointValue);
+        current.index = [];
+        for (let i = 0; i < pointValue.length; i++) {
+          if(pointValue[i] == minValue){
+            current.group.push(i);
+            current.index.push(pointIndex[i]);
+          }
+        };
+      }else{
+        xAxisPoints.forEach(function(item, index) {
+          if (currentPoints.x + offset + spacing > item) {
+            current.index = index;
+          }
+        });
+      }
+    }
+  }
+  return current;
+}
+
+function findBarChartCurrentIndex(currentPoints, calPoints, opts, config) {
+  var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+  var current={ index:-1, group:[] };
+  var spacing = opts.chartData.eachSpacing / 2;
+  let yAxisPoints = opts.chartData.yAxisPoints;
+  if (calPoints && calPoints.length > 0) {
+    if (isInExactChartArea(currentPoints, opts, config)) {
+      yAxisPoints.forEach(function(item, index) {
+        if (currentPoints.y + offset + spacing > item) {
+          current.index = index;
+        }
+      });
+    }
+  }
+  return current;
+}
+
+function findLegendIndex(currentPoints, legendData, opts) {
+  let currentIndex = -1;
+  let gap = 0;
+  if (isInExactLegendArea(currentPoints, legendData.area)) {
+    let points = legendData.points;
+    let index = -1;
+    for (let i = 0, len = points.length; i < len; i++) {
+      let item = points[i];
+      for (let j = 0; j < item.length; j++) {
+        index += 1;
+        let area = item[j]['area'];
+        if (area && currentPoints.x > area[0] - gap && currentPoints.x < area[2] + gap && currentPoints.y > area[1] - gap && currentPoints.y < area[3] + gap) {
+          currentIndex = index;
+          break;
+        }
+      }
+    }
+    return currentIndex;
+  }
+  return currentIndex;
+}
+
+function isInExactLegendArea(currentPoints, area) {
+  return currentPoints.x > area.start.x && currentPoints.x < area.end.x && currentPoints.y > area.start.y && currentPoints.y < area.end.y;
+}
+
+function isInExactChartArea(currentPoints, opts, config) {
+  return currentPoints.x <= opts.width - opts.area[1] + 10 && currentPoints.x >= opts.area[3] - 10 && currentPoints.y >= opts.area[0] && currentPoints.y <= opts.height - opts.area[2];
+}
+
+function findRadarChartCurrentIndex(currentPoints, radarData, count) {
+  var eachAngleArea = 2 * Math.PI / count;
+  var currentIndex = -1;
+  if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) {
+    var fixAngle = function fixAngle(angle) {
+      if (angle < 0) {
+        angle += 2 * Math.PI;
+      }
+      if (angle > 2 * Math.PI) {
+        angle -= 2 * Math.PI;
+      }
+      return angle;
+    };
+    var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x);
+    angle = -1 * angle;
+    if (angle < 0) {
+      angle += 2 * Math.PI;
+    }
+    var angleList = radarData.angleList.map(function(item) {
+      item = fixAngle(-1 * item);
+      return item;
+    });
+    angleList.forEach(function(item, index) {
+      var rangeStart = fixAngle(item - eachAngleArea / 2);
+      var rangeEnd = fixAngle(item + eachAngleArea / 2);
+      if (rangeEnd < rangeStart) {
+        rangeEnd += 2 * Math.PI;
+      }
+      if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <= rangeEnd) {
+        currentIndex = index;
+      }
+    });
+  }
+  return currentIndex;
+}
+
+function findFunnelChartCurrentIndex(currentPoints, funnelData) {
+  var currentIndex = -1;
+  for (var i = 0, len = funnelData.series.length; i < len; i++) {
+    var item = funnelData.series[i];
+    if (currentPoints.x > item.funnelArea[0] && currentPoints.x < item.funnelArea[2] && currentPoints.y > item.funnelArea[1] && currentPoints.y < item.funnelArea[3]) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findWordChartCurrentIndex(currentPoints, wordData) {
+  var currentIndex = -1;
+  for (var i = 0, len = wordData.length; i < len; i++) {
+    var item = wordData[i];
+    if (currentPoints.x > item.area[0] && currentPoints.x < item.area[2] && currentPoints.y > item.area[1] && currentPoints.y < item.area[3]) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findMapChartCurrentIndex(currentPoints, opts) {
+  var currentIndex = -1;
+  var cData = opts.chartData.mapData;
+  var data = opts.series;
+  var tmp = pointToCoordinate(currentPoints.y, currentPoints.x, cData.bounds, cData.scale, cData.xoffset, cData.yoffset);
+  var poi = [tmp.x, tmp.y];
+  for (var i = 0, len = data.length; i < len; i++) {
+    var item = data[i].geometry.coordinates;
+    if (isPoiWithinPoly(poi, item, opts.chartData.mapData.mercator)) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findRoseChartCurrentIndex(currentPoints, pieData, opts) {
+  var currentIndex = -1;
+  var series = getRoseDataPoints(opts._series_, opts.extra.rose.type, pieData.radius, pieData.radius);
+  if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
+    var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
+    angle = -angle;
+    if(opts.extra.rose && opts.extra.rose.offsetAngle){
+      angle = angle - opts.extra.rose.offsetAngle * Math.PI / 180;
+    }
+    for (var i = 0, len = series.length; i < len; i++) {
+      if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._rose_proportion_ * 2 * Math.PI)) {
+        currentIndex = i;
+        break;
+      }
+    }
+  }
+  return currentIndex;
+}
+
+function findPieChartCurrentIndex(currentPoints, pieData, opts) {
+  var currentIndex = -1;
+  var series = getPieDataPoints(pieData.series);
+  if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
+    var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
+    angle = -angle;
+    if(opts.extra.pie && opts.extra.pie.offsetAngle){
+      angle = angle - opts.extra.pie.offsetAngle * Math.PI / 180;
+    }
+    if(opts.extra.ring && opts.extra.ring.offsetAngle){
+      angle = angle - opts.extra.ring.offsetAngle * Math.PI / 180;
+    }
+    for (var i = 0, len = series.length; i < len; i++) {
+      if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._proportion_ * 2 * Math.PI)) {
+        currentIndex = i;
+        break;
+      }
+    }
+  }
+  return currentIndex;
+}
+
+function isInExactPieChartArea(currentPoints, center, radius) {
+  return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
+}
+
+
+function splitPoints(points,eachSeries) {
+  var newPoints = [];
+  var items = [];
+  points.forEach(function(item, index) {
+    if(eachSeries.connectNulls){
+      if (item !== null) {
+        items.push(item);
+      }
+    }else{
+      if (item !== null) {
+        items.push(item);
+      } else {
+        if (items.length) {
+          newPoints.push(items);
+        }
+        items = [];
+      }
+    }
+    
+  });
+  if (items.length) {
+    newPoints.push(items);
+  }
+  return newPoints;
+}
+
+
+function calLegendData(series, opts, config, chartData, context) {
+  let legendData = {
+    area: {
+      start: {
+        x: 0,
+        y: 0
+      },
+      end: {
+        x: 0,
+        y: 0
+      },
+      width: 0,
+      height: 0,
+      wholeWidth: 0,
+      wholeHeight: 0
+    },
+    points: [],
+    widthArr: [],
+    heightArr: []
+  };
+  if (opts.legend.show === false) {
+    chartData.legendData = legendData;
+    return legendData;
+  }
+  let padding = opts.legend.padding * opts.pix;
+  let margin = opts.legend.margin * opts.pix;
+  let fontSize = opts.legend.fontSize ? opts.legend.fontSize * opts.pix : config.fontSize;
+  let shapeWidth = 15 * opts.pix;
+  let shapeRight = 5 * opts.pix;
+  let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize);
+  if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+    let legendList = [];
+    let widthCount = 0;
+    let widthCountArr = [];
+    let currentRow = [];
+    for (let i = 0; i < series.length; i++) {
+      let item = series[i];
+      const legendText = item.legendText ? item.legendText : item.name;
+      let itemWidth = shapeWidth + shapeRight + measureText(legendText || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix;
+      if (widthCount + itemWidth > opts.width - opts.area[1] - opts.area[3]) {
+        legendList.push(currentRow);
+        widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
+        widthCount = itemWidth;
+        currentRow = [item];
+      } else {
+        widthCount += itemWidth;
+        currentRow.push(item);
+      }
+    }
+    if (currentRow.length) {
+      legendList.push(currentRow);
+      widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
+      legendData.widthArr = widthCountArr;
+      let legendWidth = Math.max.apply(null, widthCountArr);
+      switch (opts.legend.float) {
+        case 'left':
+          legendData.area.start.x = opts.area[3];
+          legendData.area.end.x = opts.area[3] + legendWidth + 2 * padding;
+          break;
+        case 'right':
+          legendData.area.start.x = opts.width - opts.area[1] - legendWidth - 2 * padding;
+          legendData.area.end.x = opts.width - opts.area[1];
+          break;
+        default:
+          legendData.area.start.x = (opts.width - legendWidth) / 2 - padding;
+          legendData.area.end.x = (opts.width + legendWidth) / 2 + padding;
+      }
+      legendData.area.width = legendWidth + 2 * padding;
+      legendData.area.wholeWidth = legendWidth + 2 * padding;
+      legendData.area.height = legendList.length * lineHeight + 2 * padding;
+      legendData.area.wholeHeight = legendList.length * lineHeight + 2 * padding + 2 * margin;
+      legendData.points = legendList;
+    }
+  } else {
+    let len = series.length;
+    let maxHeight = opts.height - opts.area[0] - opts.area[2] - 2 * margin - 2 * padding;
+    let maxLength = Math.min(Math.floor(maxHeight / lineHeight), len);
+    legendData.area.height = maxLength * lineHeight + padding * 2;
+    legendData.area.wholeHeight = maxLength * lineHeight + padding * 2;
+    switch (opts.legend.float) {
+      case 'top':
+        legendData.area.start.y = opts.area[0] + margin;
+        legendData.area.end.y = opts.area[0] + margin + legendData.area.height;
+        break;
+      case 'bottom':
+        legendData.area.start.y = opts.height - opts.area[2] - margin - legendData.area.height;
+        legendData.area.end.y = opts.height - opts.area[2] - margin;
+        break;
+      default:
+        legendData.area.start.y = (opts.height - legendData.area.height) / 2;
+        legendData.area.end.y = (opts.height + legendData.area.height) / 2;
+    }
+    let lineNum = len % maxLength === 0 ? len / maxLength : Math.floor((len / maxLength) + 1);
+    let currentRow = [];
+    for (let i = 0; i < lineNum; i++) {
+      let temp = series.slice(i * maxLength, i * maxLength + maxLength);
+      currentRow.push(temp);
+    }
+    legendData.points = currentRow;
+    if (currentRow.length) {
+      for (let i = 0; i < currentRow.length; i++) {
+        let item = currentRow[i];
+        let maxWidth = 0;
+        for (let j = 0; j < item.length; j++) {
+          let itemWidth = shapeWidth + shapeRight + measureText(item[j].name || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix;
+          if (itemWidth > maxWidth) {
+            maxWidth = itemWidth;
+          }
+        }
+        legendData.widthArr.push(maxWidth);
+        legendData.heightArr.push(item.length * lineHeight + padding * 2);
+      }
+      let legendWidth = 0
+      for (let i = 0; i < legendData.widthArr.length; i++) {
+        legendWidth += legendData.widthArr[i];
+      }
+      legendData.area.width = legendWidth - opts.legend.itemGap * opts.pix + 2 * padding;
+      legendData.area.wholeWidth = legendData.area.width + padding;
+    }
+  }
+  switch (opts.legend.position) {
+    case 'top':
+      legendData.area.start.y = opts.area[0] + margin;
+      legendData.area.end.y = opts.area[0] + margin + legendData.area.height;
+      break;
+    case 'bottom':
+      legendData.area.start.y = opts.height - opts.area[2] - legendData.area.height - margin;
+      legendData.area.end.y = opts.height - opts.area[2] - margin;
+      break;
+    case 'left':
+      legendData.area.start.x = opts.area[3];
+      legendData.area.end.x = opts.area[3] + legendData.area.width;
+      break;
+    case 'right':
+      legendData.area.start.x = opts.width - opts.area[1] - legendData.area.width;
+      legendData.area.end.x = opts.width - opts.area[1];
+      break;
+  }
+  chartData.legendData = legendData;
+  return legendData;
+}
+
+function calCategoriesData(categories, opts, config, eachSpacing, context) {
+  var result = {
+    angle: 0,
+    xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix
+  };
+  var fontSize = opts.xAxis.fontSize * opts.pix;
+  var categoriesTextLenth = categories.map(function(item,index) {
+    var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item;
+    return measureText(String(xitem), fontSize, context);
+  });
+  var maxTextLength = Math.max.apply(this, categoriesTextLenth);
+  if (opts.xAxis.rotateLabel == true) {
+    result.angle = opts.xAxis.rotateAngle * Math.PI / 180;
+    let tempHeight = opts.xAxis.marginTop * opts.pix * 2 +  Math.abs(maxTextLength * Math.sin(result.angle))
+    tempHeight = tempHeight < fontSize + opts.xAxis.marginTop * opts.pix * 2 ? tempHeight + opts.xAxis.marginTop * opts.pix * 2 : tempHeight;
+    result.xAxisHeight = tempHeight;
+  }
+  if (opts.enableScroll && opts.xAxis.scrollShow) {
+    result.xAxisHeight += 6 * opts.pix;
+  }
+  if (opts.xAxis.disabled){
+    result.xAxisHeight = 0;
+  }
+  return result;
+}
+
+function getXAxisTextList(series, opts, config, stack) {
+  var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;
+  var data;
+  if (stack == 'stack') {
+    data = dataCombineStack(series, opts.categories.length);
+  } else {
+    data = dataCombine(series);
+  }
+  var sorted = [];
+  // remove null from data
+  data = data.filter(function(item) {
+    //return item !== null;
+    if (typeof item === 'object' && item !== null) {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        return item !== null;
+      } else {
+        return item.value !== null;
+      }
+    } else {
+      return item !== null;
+    }
+  });
+  data.map(function(item) {
+    if (typeof item === 'object') {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        if (opts.type == 'candle') {
+          item.map(function(subitem) {
+            sorted.push(subitem);
+          })
+        } else {
+          sorted.push(item[0]);
+        }
+      } else {
+        sorted.push(item.value);
+      }
+    } else {
+      sorted.push(item);
+    }
+  })
+
+  var minData = 0;
+  var maxData = 0;
+  if (sorted.length > 0) {
+    minData = Math.min.apply(this, sorted);
+    maxData = Math.max.apply(this, sorted);
+  }
+  //为了兼容v1.9.0之前的项目
+  if (index > -1) {
+    if (typeof opts.xAxis.data[index].min === 'number') {
+      minData = Math.min(opts.xAxis.data[index].min, minData);
+    }
+    if (typeof opts.xAxis.data[index].max === 'number') {
+      maxData = Math.max(opts.xAxis.data[index].max, maxData);
+    }
+  } else {
+    if (typeof opts.xAxis.min === 'number') {
+      minData = Math.min(opts.xAxis.min, minData);
+    }
+    if (typeof opts.xAxis.max === 'number') {
+      maxData = Math.max(opts.xAxis.max, maxData);
+    }
+  }
+  if (minData === maxData) {
+    var rangeSpan = maxData || 10;
+    maxData += rangeSpan;
+  }
+  //var dataRange = getDataRange(minData, maxData);
+  var minRange = minData;
+  var maxRange = maxData;
+  var range = [];
+  var eachRange = (maxRange - minRange) / opts.xAxis.splitNumber;
+  for (var i = 0; i <= opts.xAxis.splitNumber; i++) {
+    range.push(minRange + eachRange * i);
+  }
+  return range;
+}
+
+function calXAxisData(series, opts, config, context) {
+  //堆叠图重算Y轴
+  var columnstyle = assign({}, {
+    type: ""
+  }, opts.extra.bar);
+  var result = {
+    angle: 0,
+    xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix
+  };
+  result.ranges = getXAxisTextList(series, opts, config, columnstyle.type);
+  result.rangesFormat = result.ranges.map(function(item) {
+    //item = opts.xAxis.formatter ? opts.xAxis.formatter(item) : util.toFixed(item, 2);
+    item = util.toFixed(item, 2);
+    return item;
+  });
+  var xAxisScaleValues = result.ranges.map(function(item) {
+    // 如果刻度值是浮点数,则保留两位小数
+    item = util.toFixed(item, 2);
+    // 若有自定义格式则调用自定义的格式化函数
+    //item = opts.xAxis.formatter ? opts.xAxis.formatter(Number(item)) : item;
+    return item;
+  });
+  result = Object.assign(result, getXAxisPoints(xAxisScaleValues, opts, config));
+  // 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长
+  var eachSpacing = result.eachSpacing;
+  var textLength = xAxisScaleValues.map(function(item) {
+    return measureText(item, opts.xAxis.fontSize * opts.pix, context);
+  });
+  if (opts.xAxis.disabled === true) {
+    result.xAxisHeight = 0;
+  }
+  return result;
+}
+
+function getRadarDataPoints(angleList, center, radius, series, opts) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var radarOption = opts.extra.radar || {};
+  radarOption.max = radarOption.max || 0;
+  var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
+  var data = [];
+  for (let i = 0; i < series.length; i++) {
+    let each = series[i];
+    let listItem = {};
+    listItem.color = each.color;
+    listItem.legendShape = each.legendShape;
+    listItem.pointShape = each.pointShape;
+    listItem.data = [];
+    each.data.forEach(function(item, index) {
+      let tmp = {};
+      tmp.angle = angleList[index];
+      tmp.proportion = item / maxData;
+      tmp.value = item;
+      tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion * process * Math.sin(tmp.angle), center);
+      listItem.data.push(tmp);
+    });
+    data.push(listItem);
+  }
+  return data;
+}
+
+function getPieDataPoints(series, radius) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  var count = 0;
+  var _start_ = 0;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    count += item.data;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (count === 0) {
+      item._proportion_ = 1 / series.length * process;
+    } else {
+      item._proportion_ = item.data / count * process;
+    }
+    item._radius_ = radius;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item._start_ = _start_;
+    _start_ += 2 * item._proportion_ * Math.PI;
+  }
+  return series;
+}
+
+function getFunnelDataPoints(series, radius, option, eachSpacing) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  for (let i = 0; i < series.length; i++) {
+    if(option.type == 'funnel'){
+      series[i].radius = series[i].data / series[0].data * radius * process;
+    }else{
+      series[i].radius =  (eachSpacing * (series.length - i)) / (eachSpacing * series.length) * radius * process;
+    }
+    series[i]._proportion_ = series[i].data / series[0].data;
+  }
+  // if(option.type !== 'pyramid'){
+  //   series.reverse();
+  // }
+  return series;
+}
+
+function getRoseDataPoints(series, type, minRadius, radius) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var count = 0;
+  var _start_ = 0;
+  var dataArr = [];
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    count += item.data;
+    dataArr.push(item.data);
+  }
+  var minData = Math.min.apply(null, dataArr);
+  var maxData = Math.max.apply(null, dataArr);
+  var radiusLength = radius - minRadius;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (count === 0) {
+      item._proportion_ = 1 / series.length * process;
+      item._rose_proportion_ = 1 / series.length * process;
+    } else {
+      item._proportion_ = item.data / count * process;
+      if(type == 'area'){
+        item._rose_proportion_ = 1 / series.length * process;
+      }else{
+        item._rose_proportion_ = item.data / count * process;
+      }
+    }
+    item._radius_ = minRadius + radiusLength * ((item.data - minData) / (maxData - minData)) || radius;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item._start_ = _start_;
+    _start_ += 2 * item._rose_proportion_ * Math.PI;
+  }
+  return series;
+}
+
+function getArcbarDataPoints(series, arcbarOption) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  if (process == 1) {
+    process = 0.999999;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    let totalAngle;
+    if (arcbarOption.type == 'circle') {
+      totalAngle = 2;
+    } else {
+      if(arcbarOption.direction == 'ccw'){
+        if (arcbarOption.startAngle < arcbarOption.endAngle) {
+          totalAngle = 2 + arcbarOption.startAngle - arcbarOption.endAngle;
+        } else {
+          totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+        }
+      }else{
+        if (arcbarOption.endAngle < arcbarOption.startAngle) {
+          totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle;
+        } else {
+          totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+        }
+      }
+    }
+    item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
+    if(arcbarOption.direction == 'ccw'){
+      item._proportion_ = arcbarOption.startAngle - totalAngle * item.data * process ;
+    }
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getGaugeArcbarDataPoints(series, arcbarOption) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  if (process == 1) {
+    process = 0.999999;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    let totalAngle;
+    if (arcbarOption.type == 'circle') {
+      totalAngle = 2;
+    } else {
+      if (arcbarOption.endAngle < arcbarOption.startAngle) {
+        totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle;
+      } else {
+        totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+      }
+    }
+    item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getGaugeAxisPoints(categories, startAngle, endAngle) {
+  let totalAngle;
+  if (endAngle < startAngle) {
+    totalAngle = 2 + endAngle - startAngle;
+  } else {
+    totalAngle = startAngle - endAngle;
+  }
+  let tempStartAngle = startAngle;
+  for (let i = 0; i < categories.length; i++) {
+    categories[i].value = categories[i].value === null ? 0 : categories[i].value;
+    categories[i]._startAngle_ = tempStartAngle;
+    categories[i]._endAngle_ = totalAngle * categories[i].value + startAngle;
+    if (categories[i]._endAngle_ >= 2) {
+      categories[i]._endAngle_ = categories[i]._endAngle_ % 2;
+    }
+    tempStartAngle = categories[i]._endAngle_;
+  }
+  return categories;
+}
+
+function getGaugeDataPoints(series, categories, gaugeOption) {
+  let process = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (gaugeOption.pointer.color == 'auto') {
+      for (let i = 0; i < categories.length; i++) {
+        if (item.data <= categories[i].value) {
+          item.color = categories[i].color;
+          break;
+        }
+      }
+    } else {
+      item.color = gaugeOption.pointer.color;
+    }
+    let totalAngle;
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle;
+    item._oldAngle_ = gaugeOption.oldAngle;
+    if (gaugeOption.oldAngle < gaugeOption.endAngle) {
+      item._oldAngle_ += 2;
+    }
+    if (item.data >= gaugeOption.oldData) {
+      item._proportion_ = (item._endAngle_ - item._oldAngle_) * process + gaugeOption.oldAngle;
+    } else {
+      item._proportion_ = item._oldAngle_ - (item._oldAngle_ - item._endAngle_) * process;
+    }
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getPieTextMaxLength(series, config, context, opts) {
+  series = getPieDataPoints(series);
+  let maxLength = 0;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    let text = item.formatter ? item.formatter(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
+    maxLength = Math.max(maxLength, measureText(text, item.textSize * opts.pix || config.fontSize, context));
+  }
+  return maxLength;
+}
+
+function fixColumeData(points, eachSpacing, columnLen, index, config, opts) {
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    var seriesGap = 0;
+    var categoryGap = 0;
+    if (opts.type == 'mix') {
+      seriesGap = opts.extra.mix.column.seriesGap * opts.pix || 0;
+      categoryGap = opts.extra.mix.column.categoryGap * opts.pix || 0;
+    } else {
+      seriesGap = opts.extra.column.seriesGap * opts.pix || 0;
+      categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+    }
+    seriesGap =  Math.min(seriesGap, eachSpacing / columnLen)
+    categoryGap =  Math.min(categoryGap, eachSpacing / columnLen)
+    item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen);
+    if (opts.extra.mix && opts.extra.mix.column.width && +opts.extra.mix.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.mix.column.width * opts.pix);
+    }
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    item.x += (index + 0.5 - columnLen / 2) * (item.width + seriesGap);
+    return item;
+  });
+}
+
+function fixBarData(points, eachSpacing, columnLen, index, config, opts) {
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    var seriesGap = 0;
+    var categoryGap = 0;
+    seriesGap = opts.extra.bar.seriesGap * opts.pix || 0;
+    categoryGap = opts.extra.bar.categoryGap * opts.pix || 0;
+    seriesGap =  Math.min(seriesGap, eachSpacing / columnLen)
+    categoryGap =  Math.min(categoryGap, eachSpacing / columnLen)
+    item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen);
+    if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    item.y += (index + 0.5 - columnLen / 2) * (item.width + seriesGap);
+    return item;
+  });
+}
+
+function fixColumeMeterData(points, eachSpacing, columnLen, index, config, opts, border) {
+  var categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    item.width = eachSpacing - 2 * categoryGap;
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (index > 0) {
+      item.width -= border;
+    }
+    return item;
+  });
+}
+
+function fixColumeStackData(points, eachSpacing, columnLen, index, config, opts, series) {
+  var categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+  return points.map(function(item, indexn) {
+    if (item === null) {
+      return null;
+    }
+    item.width = Math.ceil(eachSpacing - 2 * categoryGap);
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    return item;
+  });
+}
+
+function fixBarStackData(points, eachSpacing, columnLen, index, config, opts, series) {
+  var categoryGap = opts.extra.bar.categoryGap * opts.pix || 0;
+  return points.map(function(item, indexn) {
+    if (item === null) {
+      return null;
+    }
+    item.width = Math.ceil(eachSpacing - 2 * categoryGap);
+    if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    return item;
+  });
+}
+
+function getXAxisPoints(categories, opts, config) {
+  var spacingValid = opts.width - opts.area[1] - opts.area[3];
+  var dataCount = opts.enableScroll ? Math.min(opts.xAxis.itemCount, categories.length) : categories.length;
+  if ((opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' || opts.type == 'bar') && dataCount > 1 && opts.xAxis.boundaryGap == 'justify') {
+    dataCount -= 1;
+  }
+  var widthRatio = 0;
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    widthRatio = opts.extra.mount.widthRatio - 1;
+    dataCount += widthRatio;
+  }
+  var eachSpacing = spacingValid / dataCount;
+  var xAxisPoints = [];
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  categories.forEach(function(item, index) {
+    xAxisPoints.push(startX + widthRatio / 2 * eachSpacing + index * eachSpacing);
+  });
+  if (opts.xAxis.boundaryGap !== 'justify') {
+    if (opts.enableScroll === true) {
+      xAxisPoints.push(startX + widthRatio * eachSpacing + categories.length * eachSpacing);
+    } else {
+      xAxisPoints.push(endX);
+    }
+  }
+  return {
+    xAxisPoints: xAxisPoints,
+    startX: startX,
+    endX: endX,
+    eachSpacing: eachSpacing
+  };
+}
+
+function getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var cPoints = [];
+      item.forEach(function(items, indexs) {
+        var point = {};
+        point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+        var value = items.value || items;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        height *= process;
+        point.y = opts.height - Math.round(height) - opts.area[2];
+        cPoints.push(point);
+      });
+      points.push(cPoints);
+    }
+  });
+  return points;
+}
+
+function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var boundaryGap = 'center';
+  if (opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' ) {
+    boundaryGap = opts.xAxis.boundaryGap;
+  }
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        if (item.constructor.toString().indexOf('Array') > -1) {
+          let xranges, xminRange, xmaxRange;
+          xranges = [].concat(opts.chartData.xAxisData.ranges);
+          xminRange = xranges.shift();
+          xmaxRange = xranges.pop();
+          value = item[1];
+          point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+          if(opts.type == 'bubble'){
+            point.r = item[2];
+            point.t = item[3];
+          }
+        } else {
+          value = item.value;
+        }
+      }
+      if (boundaryGap == 'center') {
+        point.x += eachSpacing / 2;
+      }
+      var height = validHeight * (value - minRange) / (maxRange - minRange);
+      height *= process;
+      point.y = opts.height - height - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process){
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var boundaryGap = opts.xAxis.boundaryGap;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      if(lineOption.animation == 'vertical'){
+        point.x = xAxisPoints[index];
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          if (item.constructor.toString().indexOf('Array') > -1) {
+            let xranges, xminRange, xmaxRange;
+            xranges = [].concat(opts.chartData.xAxisData.ranges);
+            xminRange = xranges.shift();
+            xmaxRange = xranges.pop();
+            value = item[1];
+            point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+          } else {
+            value = item.value;
+          }
+        }
+        if (boundaryGap == 'center') {
+          point.x += eachSpacing / 2;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        height *= process;
+        point.y = opts.height - height - opts.area[2];
+        points.push(point);
+      }else{
+        point.x = xAxisPoints[0] + eachSpacing * index * process;
+        var value = item;
+        if (boundaryGap == 'center') {
+          point.x += eachSpacing / 2;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        point.y = opts.height - height - opts.area[2];
+        points.push(point);
+      }
+    }
+  });
+  return points;
+}
+
+function getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process){
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        if (item.constructor.toString().indexOf('Array') > -1) {
+          let xranges, xminRange, xmaxRange;
+          xranges = [].concat(opts.chartData.xAxisData.ranges);
+          xminRange = xranges.shift();
+          xmaxRange = xranges.pop();
+          value = item[1];
+          point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+        } else {
+          value = item.value;
+        }
+      }
+      point.x += eachSpacing / 2;
+      var height = validHeight * (value * process - minRange) / (maxRange - minRange);
+      point.y = opts.height - height - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints) {
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  var mountWidth = eachSpacing * mountOption.widthRatio;
+  series.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      point.x += eachSpacing / 2;
+      var value = item.data;
+      var height = validHeight * (value * process - minRange) / (maxRange - minRange);
+      point.y = opts.height - height - opts.area[2];
+      point.value = value;
+      point.width = mountWidth;
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.y = yAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        value = item.value;
+      }
+      var height = validWidth * (value - minRange) / (maxRange - minRange);
+      height *= process;
+      point.height = height;
+      point.value = value;
+      point.x = height + opts.area[3];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
+  var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+
+      if (seriesIndex > 0) {
+        var value = 0;
+        for (let i = 0; i <= seriesIndex; i++) {
+          value += stackSeries[i].data[index];
+        }
+        var value0 = value - item;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
+      } else {
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          value = item.value;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = 0;
+      }
+      var heightc = height0;
+      height *= process;
+      heightc *= process;
+      point.y = opts.height - Math.round(height) - opts.area[2];
+      point.y0 = opts.height - Math.round(heightc) - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
+  var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
+  var points = [];
+  var validHeight = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.y = yAxisPoints[index];
+      if (seriesIndex > 0) {
+        var value = 0;
+        for (let i = 0; i <= seriesIndex; i++) {
+          value += stackSeries[i].data[index];
+        }
+        var value0 = value - item;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
+      } else {
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          value = item.value;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = 0;
+      }
+      var heightc = height0;
+      height *= process;
+      heightc *= process;
+      point.height = height - heightc;
+      point.x = opts.area[3] + height;
+      point.x0 = opts.area[3] + heightc;
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getYAxisTextList(series, opts, config, stack, yData) {
+  var index = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : -1;
+  var data;
+  if (stack == 'stack') {
+    data = dataCombineStack(series, opts.categories.length);
+  } else {
+    data = dataCombine(series);
+  }
+  var sorted = [];
+  // remove null from data
+  data = data.filter(function(item) {
+    //return item !== null;
+    if (typeof item === 'object' && item !== null) {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        return item !== null;
+      } else {
+        return item.value !== null;
+      }
+    } else {
+      return item !== null;
+    }
+  });
+  data.map(function(item) {
+    if (typeof item === 'object') {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        if (opts.type == 'candle') {
+          item.map(function(subitem) {
+            sorted.push(subitem);
+          })
+        } else {
+          sorted.push(item[1]);
+        }
+      } else {
+        sorted.push(item.value);
+      }
+    } else {
+      sorted.push(item);
+    }
+  })
+  var minData = yData.min || 0;
+  var maxData = yData.max || 0;
+  if (sorted.length > 0) {
+    minData = Math.min.apply(this, sorted);
+    maxData = Math.max.apply(this, sorted);
+  }
+  if (minData === maxData) {
+    if(maxData == 0){
+      maxData = 10;
+    }else{
+      minData = 0;
+    }
+  }
+  var dataRange = getDataRange(minData, maxData);
+  var minRange = (yData.min === undefined || yData.min === null) ? dataRange.minRange : yData.min;
+  var maxRange = (yData.max === undefined || yData.max === null) ? dataRange.maxRange : yData.max;
+  var eachRange = (maxRange - minRange) / opts.yAxis.splitNumber;
+  var range = [];
+  for (var i = 0; i <= opts.yAxis.splitNumber; i++) {
+    range.push(minRange + eachRange * i);
+  }
+  return range.reverse();
+}
+
+function calYAxisData(series, opts, config, context) {
+  //堆叠图重算Y轴
+  var columnstyle = assign({}, {
+    type: ""
+  }, opts.extra.column);
+  //如果是多Y轴,重新计算
+  var YLength = opts.yAxis.data.length;
+  var newSeries = new Array(YLength);
+  if (YLength > 0) {
+    for (let i = 0; i < YLength; i++) {
+      newSeries[i] = [];
+      for (let j = 0; j < series.length; j++) {
+        if (series[j].index == i) {
+          newSeries[i].push(series[j]);
+        }
+      }
+    }
+    var rangesArr = new Array(YLength);
+    var rangesFormatArr = new Array(YLength);
+    var yAxisWidthArr = new Array(YLength);
+
+    for (let i = 0; i < YLength; i++) {
+      let yData = opts.yAxis.data[i];
+      //如果总开关不显示,强制每个Y轴为不显示
+      if (opts.yAxis.disabled == true) {
+        yData.disabled = true;
+      }
+      if(yData.type === 'categories'){
+        if(!yData.formatter){
+          yData.formatter = (val,index,opts) => {return val + (yData.unit || '')};
+        }
+        yData.categories = yData.categories || opts.categories;
+        rangesArr[i] = yData.categories;
+      }else{
+        if(!yData.formatter){
+          yData.formatter = (val,index,opts) => {return util.toFixed(val, yData.tofix || 0) + (yData.unit || '')};
+        }
+        rangesArr[i] = getYAxisTextList(newSeries[i], opts, config, columnstyle.type, yData, i);
+      }
+      let yAxisFontSizes = yData.fontSize * opts.pix || config.fontSize;
+      yAxisWidthArr[i] = {
+        position: yData.position ? yData.position : 'left',
+        width: 0
+      };
+      rangesFormatArr[i] = rangesArr[i].map(function(items,index) {
+        items = yData.formatter(items,index,opts);
+        yAxisWidthArr[i].width = Math.max(yAxisWidthArr[i].width, measureText(items, yAxisFontSizes, context) + 5);
+        return items;
+      });
+      let calibration = yData.calibration ? 4 * opts.pix : 0;
+      yAxisWidthArr[i].width += calibration + 3 * opts.pix;
+      if (yData.disabled === true) {
+        yAxisWidthArr[i].width = 0;
+      }
+    }
+  } else {
+    var rangesArr = new Array(1);
+    var rangesFormatArr = new Array(1);
+    var yAxisWidthArr = new Array(1);
+    if(opts.type === 'bar'){
+      rangesArr[0] = opts.categories;
+      if(!opts.yAxis.formatter){
+        opts.yAxis.formatter = (val,index,opts) => {return val + (opts.yAxis.unit || '')}
+      }
+    }else{
+      if(!opts.yAxis.formatter){
+        opts.yAxis.formatter = (val,index,opts) => {return val.toFixed(opts.yAxis.tofix ) + (opts.yAxis.unit || '')}
+      }
+      rangesArr[0] = getYAxisTextList(series, opts, config, columnstyle.type, {});
+    }
+    yAxisWidthArr[0] = {
+      position: 'left',
+      width: 0
+    };
+    var yAxisFontSize = opts.yAxis.fontSize * opts.pix || config.fontSize;
+    rangesFormatArr[0] = rangesArr[0].map(function(item,index) {
+      item = opts.yAxis.formatter(item,index,opts);
+      yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize, context) + 5);
+      return item;
+    });
+    yAxisWidthArr[0].width += 3 * opts.pix;
+    if (opts.yAxis.disabled === true) {
+      yAxisWidthArr[0] = {
+        position: 'left',
+        width: 0
+      };
+      opts.yAxis.data[0] = {
+        disabled: true
+      };
+    } else {
+      opts.yAxis.data[0] = {
+        disabled: false,
+        position: 'left',
+        max: opts.yAxis.max,
+        min: opts.yAxis.min,
+        formatter: opts.yAxis.formatter
+      };
+      if(opts.type === 'bar'){
+        opts.yAxis.data[0].categories = opts.categories;
+        opts.yAxis.data[0].type = 'categories';
+      }
+    }
+  }
+  return {
+    rangesFormat: rangesFormatArr,
+    ranges: rangesArr,
+    yAxisWidth: yAxisWidthArr
+  };
+}
+
+function calTooltipYAxisData(point, series, opts, config, eachSpacing) {
+  let ranges = [].concat(opts.chartData.yAxisData.ranges);
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  let minAxis = opts.area[0];
+  let items = [];
+  for (let i = 0; i < ranges.length; i++) {
+    let maxVal = Math.max.apply(this, ranges[i]);
+    let minVal = Math.min.apply(this, ranges[i]);
+    let item = maxVal - (maxVal - minVal) * (point - minAxis) / spacingValid;
+    item = opts.yAxis.data && opts.yAxis.data[i].formatter ? opts.yAxis.data[i].formatter(item, i, opts) : item.toFixed(0);
+    items.push(String(item))
+  }
+  return items;
+}
+
+function calMarkLineData(points, opts) {
+  let minRange, maxRange;
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  for (let i = 0; i < points.length; i++) {
+    points[i].yAxisIndex = points[i].yAxisIndex ? points[i].yAxisIndex : 0;
+    let range = [].concat(opts.chartData.yAxisData.ranges[points[i].yAxisIndex]);
+    minRange = range.pop();
+    maxRange = range.shift();
+    let height = spacingValid * (points[i].value - minRange) / (maxRange - minRange);
+    points[i].y = opts.height - Math.round(height) - opts.area[2];
+  }
+  return points;
+}
+
+function contextRotate(context, opts) {
+  if (opts.rotateLock !== true) {
+    context.translate(opts.height, 0);
+    context.rotate(90 * Math.PI / 180);
+  } else if (opts._rotate_ !== true) {
+    context.translate(opts.height, 0);
+    context.rotate(90 * Math.PI / 180);
+    opts._rotate_ = true;
+  }
+}
+
+function drawPointShape(points, color, shape, context, opts) {
+  context.beginPath();
+  if (opts.dataPointShapeType == 'hollow') {
+    context.setStrokeStyle(color);
+    context.setFillStyle(opts.background);
+    context.setLineWidth(2 * opts.pix);
+  } else {
+    context.setStrokeStyle("#ffffff");
+    context.setFillStyle(color);
+    context.setLineWidth(1 * opts.pix);
+  }
+  if (shape === 'diamond') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y);
+        context.lineTo(item.x, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'circle') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x + 2.5 * opts.pix, item.y);
+        context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+      }
+    });
+  } else if (shape === 'square') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x - 3.5, item.y - 3.5);
+        context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+      }
+    });
+  } else if (shape === 'triangle') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y + 4.5);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'none') {
+    return;
+  }
+  context.closePath();
+  context.fill();
+  context.stroke();
+}
+
+function drawActivePoint(points, color, shape, context, opts, option, seriesIndex) {
+  if(!opts.tooltip){
+    return
+  }
+  if(opts.tooltip.group.length>0 && opts.tooltip.group.includes(seriesIndex) == false){
+    return
+  }
+  var pointIndex = typeof opts.tooltip.index === 'number' ? opts.tooltip.index : opts.tooltip.index[opts.tooltip.group.indexOf(seriesIndex)];
+  context.beginPath();
+  if (option.activeType == 'hollow') {
+    context.setStrokeStyle(color);
+    context.setFillStyle(opts.background);
+    context.setLineWidth(2 * opts.pix);
+  } else {
+    context.setStrokeStyle("#ffffff");
+    context.setFillStyle(color);
+    context.setLineWidth(1 * opts.pix);
+  }
+  if (shape === 'diamond') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index ) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y);
+        context.lineTo(item.x, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'circle') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x + 2.5 * opts.pix, item.y);
+        context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+      }
+    });
+  } else if (shape === 'square') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x - 3.5, item.y - 3.5);
+        context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+      }
+    });
+  } else if (shape === 'triangle') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y + 4.5);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'none') {
+    return;
+  }
+  context.closePath();
+  context.fill();
+  context.stroke();
+}
+
+function drawRingTitle(opts, config, context, center) {
+  var titlefontSize = opts.title.fontSize || config.titleFontSize;
+  var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize;
+  var title = opts.title.name || '';
+  var subtitle = opts.subtitle.name || '';
+  var titleFontColor = opts.title.color || opts.fontColor;
+  var subtitleFontColor = opts.subtitle.color || opts.fontColor;
+  var titleHeight = title ? titlefontSize : 0;
+  var subtitleHeight = subtitle ? subtitlefontSize : 0;
+  var margin = 5;
+  if (subtitle) {
+    var textWidth = measureText(subtitle, subtitlefontSize * opts.pix, context);
+    var startX = center.x - textWidth / 2 + (opts.subtitle.offsetX|| 0) * opts.pix ;
+    var startY = center.y + subtitlefontSize * opts.pix / 2 + (opts.subtitle.offsetY || 0) * opts.pix;
+    if (title) {
+      startY += (titleHeight * opts.pix + margin) / 2;
+    }
+    context.beginPath();
+    context.setFontSize(subtitlefontSize * opts.pix);
+    context.setFillStyle(subtitleFontColor);
+    context.fillText(subtitle, startX, startY);
+    context.closePath();
+    context.stroke();
+  }
+  if (title) {
+    var _textWidth = measureText(title, titlefontSize * opts.pix, context);
+    var _startX = center.x - _textWidth / 2 + (opts.title.offsetX || 0);
+    var _startY = center.y + titlefontSize * opts.pix / 2 + (opts.title.offsetY || 0) * opts.pix;
+    if (subtitle) {
+      _startY -= (subtitleHeight * opts.pix + margin) / 2;
+    }
+    context.beginPath();
+    context.setFontSize(titlefontSize * opts.pix);
+    context.setFillStyle(titleFontColor);
+    context.fillText(title, _startX, _startY);
+    context.closePath();
+    context.stroke();
+  }
+}
+
+function drawPointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        if (data[index].constructor.toString().indexOf('Array')>-1) {
+          value = data[index][1];
+        } else {
+          value = data[index].value
+        }
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      context.fillText(String(formatVal), item.x, item.y - 4 + textOffset * opts.pix);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawColumePointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  var Position = opts.extra.column.labelPosition;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        if (data[index].constructor.toString().indexOf('Array')>-1) {
+          value = data[index][1];
+        } else {
+          value = data[index].value
+        }
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      var startY = item.y - 4 * opts.pix + textOffset * opts.pix;
+      if(item.y > series.zeroPoints){
+        startY = item.y + textOffset * opts.pix + fontSize;
+      }
+      if(Position == 'insideTop'){
+        startY = item.y + fontSize + textOffset * opts.pix;
+        if(item.y > series.zeroPoints){
+          startY = item.y - textOffset * opts.pix - 4 * opts.pix;
+        }
+      }
+      if(Position == 'center'){
+        startY = item.y + textOffset * opts.pix + (opts.height - opts.area[2] - item.y + fontSize)/2;
+        if(series.zeroPoints < opts.height - opts.area[2]){
+          startY = item.y + textOffset * opts.pix + (series.zeroPoints - item.y + fontSize)/2;
+        }
+        if(item.y > series.zeroPoints){
+          startY = item.y - textOffset * opts.pix - (item.y - series.zeroPoints - fontSize)/2;
+        }
+        if(opts.extra.column.type == 'stack'){
+          startY = item.y + textOffset * opts.pix + (item.y0 - item.y + fontSize)/2;
+        }
+      }
+      if(Position == 'bottom'){
+        startY = opts.height - opts.area[2] + textOffset * opts.pix - 4 * opts.pix;
+        if(series.zeroPoints < opts.height - opts.area[2]){
+          startY = series.zeroPoints + textOffset * opts.pix - 4 * opts.pix;
+        }
+        if(item.y > series.zeroPoints){
+          startY = series.zeroPoints - textOffset * opts.pix + fontSize + 2 * opts.pix;
+        }
+        if(opts.extra.column.type == 'stack'){
+          startY = item.y0 + textOffset * opts.pix - 4 * opts.pix;
+        }
+      }
+      context.fillText(String(formatVal), item.x, startY);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawMountPointText(points, series, config, context, opts, zeroPoints) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  var Position = opts.extra.mount.labelPosition;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series[index].textSize ? series[index].textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series[index].textColor || opts.fontColor);
+      var value = item.value
+      var formatVal = series[index].formatter ? series[index].formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      var startY = item.y - 4 * opts.pix + textOffset * opts.pix;
+      if(item.y > zeroPoints){
+        startY = item.y + textOffset * opts.pix + fontSize;
+      }
+      context.fillText(String(formatVal), item.x, startY);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawBarPointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        value = data[index].value ;
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('left');
+      context.fillText(String(formatVal), item.x + 4 * opts.pix , item.y + fontSize / 2 - 3 );
+      context.closePath();
+      context.stroke();
+    }
+  });
+}
+
+function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) {
+  radius -= gaugeOption.width / 2 + gaugeOption.labelOffset * opts.pix;
+  radius = radius < 10 ? 10 : radius;
+  let totalAngle;
+  if (gaugeOption.endAngle < gaugeOption.startAngle) {
+    totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+  } else {
+    totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+  }
+  let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+  let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber;
+  let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber;
+  let nowAngle = gaugeOption.startAngle;
+  let nowNumber = gaugeOption.startNumber;
+  for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+    var pos = {
+      x: radius * Math.cos(nowAngle * Math.PI),
+      y: radius * Math.sin(nowAngle * Math.PI)
+    };
+    var labelText = gaugeOption.formatter ? gaugeOption.formatter(nowNumber,i,opts) : nowNumber;
+    pos.x += centerPosition.x - measureText(labelText, config.fontSize, context) / 2;
+    pos.y += centerPosition.y;
+    var startX = pos.x;
+    var startY = pos.y;
+    context.beginPath();
+    context.setFontSize(config.fontSize);
+    context.setFillStyle(gaugeOption.labelColor || opts.fontColor);
+    context.fillText(labelText, startX, startY + config.fontSize / 2);
+    context.closePath();
+    context.stroke();
+    nowAngle += splitAngle;
+    if (nowAngle >= 2) {
+      nowAngle = nowAngle % 2;
+    }
+    nowNumber += splitNumber;
+  }
+}
+
+function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) {
+  var radarOption = opts.extra.radar || {};
+  angleList.forEach(function(angle, index) {
+    if(radarOption.labelPointShow === true && opts.categories[index] !== ''){
+      var posPoint = {
+        x: radius * Math.cos(angle),
+        y: radius * Math.sin(angle)
+      };
+      var posPointAxis = convertCoordinateOrigin(posPoint.x, posPoint.y, centerPosition);
+      context.setFillStyle(radarOption.labelPointColor);
+      context.beginPath();
+      context.arc(posPointAxis.x, posPointAxis.y, radarOption.labelPointRadius * opts.pix, 0, 2 * Math.PI, false);
+      context.closePath();
+      context.fill();
+    }
+    if(radarOption.labelShow === true){
+      var pos = {
+        x: (radius + config.radarLabelTextMargin * opts.pix) * Math.cos(angle),
+        y: (radius + config.radarLabelTextMargin * opts.pix) * Math.sin(angle)
+      };
+      var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition);
+      var startX = posRelativeCanvas.x;
+      var startY = posRelativeCanvas.y;
+      if (util.approximatelyEqual(pos.x, 0)) {
+        startX -= measureText(opts.categories[index] || '', config.fontSize, context) / 2;
+      } else if (pos.x < 0) {
+        startX -= measureText(opts.categories[index] || '', config.fontSize, context);
+      }
+      context.beginPath();
+      context.setFontSize(config.fontSize);
+      context.setFillStyle(radarOption.labelColor || opts.fontColor);
+      context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2);
+      context.closePath();
+      context.stroke();
+    }
+  });
+
+}
+
+function drawPieText(series, opts, config, context, radius, center) {
+  var lineRadius = config.pieChartLinePadding;
+  var textObjectCollection = [];
+  var lastTextObject = null;
+  var seriesConvert = series.map(function(item,index) {
+    var text = item.formatter ? item.formatter(item,index,series,opts) : util.toFixed(item._proportion_.toFixed(4) * 100) + '%';
+    text = item.labelText ? item.labelText : text;
+    var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
+    if (item._rose_proportion_) {
+      arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._rose_proportion_ / 2);
+    }
+    var color = item.color;
+    var radius = item._radius_;
+    return {
+      arc: arc,
+      text: text,
+      color: color,
+      radius: radius,
+      textColor: item.textColor,
+      textSize: item.textSize,
+      labelShow: item.labelShow
+    };
+  });
+  for (let i = 0; i < seriesConvert.length; i++) {
+    let item = seriesConvert[i];
+    // line end
+    let orginX1 = Math.cos(item.arc) * (item.radius + lineRadius);
+    let orginY1 = Math.sin(item.arc) * (item.radius + lineRadius);
+    // line start
+    let orginX2 = Math.cos(item.arc) * item.radius;
+    let orginY2 = Math.sin(item.arc) * item.radius;
+    // text start
+    let orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
+    let orginY3 = orginY1;
+    let textWidth = measureText(item.text, item.textSize * opts.pix || config.fontSize, context);
+    let startY = orginY3;
+    if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, {
+        x: orginX3
+      })) {
+      if (orginX3 > 0) {
+        startY = Math.min(orginY3, lastTextObject.start.y);
+      } else if (orginX1 < 0) {
+        startY = Math.max(orginY3, lastTextObject.start.y);
+      } else {
+        if (orginY3 > 0) {
+          startY = Math.max(orginY3, lastTextObject.start.y);
+        } else {
+          startY = Math.min(orginY3, lastTextObject.start.y);
+        }
+      }
+    }
+    if (orginX3 < 0) {
+      orginX3 -= textWidth;
+    }
+    let textObject = {
+      lineStart: {
+        x: orginX2,
+        y: orginY2
+      },
+      lineEnd: {
+        x: orginX1,
+        y: orginY1
+      },
+      start: {
+        x: orginX3,
+        y: startY
+      },
+      width: textWidth,
+      height: config.fontSize,
+      text: item.text,
+      color: item.color,
+      textColor: item.textColor,
+      textSize: item.textSize
+    };
+    lastTextObject = avoidCollision(textObject, lastTextObject);
+    textObjectCollection.push(lastTextObject);
+  }
+  for (let i = 0; i < textObjectCollection.length; i++) {
+    if(seriesConvert[i].labelShow === false){
+      continue;
+    }
+    let item = textObjectCollection[i];
+    let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
+    let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
+    let textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
+    context.setLineWidth(1 * opts.pix);
+    context.setFontSize(item.textSize * opts.pix || config.fontSize);
+    context.beginPath();
+    context.setStrokeStyle(item.color);
+    context.setFillStyle(item.color);
+    context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+    let curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
+    let textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
+    context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
+    context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+    context.stroke();
+    context.closePath();
+    context.beginPath();
+    context.moveTo(textPosition.x + item.width, textPosition.y);
+    context.arc(curveStartX, textPosition.y, 2 * opts.pix, 0, 2 * Math.PI);
+    context.closePath();
+    context.fill();
+    context.beginPath();
+    context.setFontSize(item.textSize * opts.pix || config.fontSize);
+    context.setFillStyle(item.textColor || opts.fontColor);
+    context.fillText(item.text, textStartX, textPosition.y + 3);
+    context.closePath();
+    context.stroke();
+    context.closePath();
+  }
+}
+
+function drawToolTipSplitLine(offsetX, opts, config, context) {
+  var toolTipOption = opts.extra.tooltip || {};
+  toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType;
+  toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength;
+  var startY = opts.area[0];
+  var endY = opts.height - opts.area[2];
+  if (toolTipOption.gridType == 'dash') {
+    context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+  }
+  context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+  context.setLineWidth(1 * opts.pix);
+  context.beginPath();
+  context.moveTo(offsetX, startY);
+  context.lineTo(offsetX, endY);
+  context.stroke();
+  context.setLineDash([]);
+  if (toolTipOption.xAxisLabel) {
+    let labelText = opts.categories[opts.tooltip.index];
+    context.setFontSize(config.fontSize);
+    let textWidth = measureText(labelText, config.fontSize, context);
+    let textX = offsetX - 0.5 * textWidth;
+    let textY = endY + 2 * opts.pix;
+    context.beginPath();
+    context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity));
+    context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+    context.setLineWidth(1 * opts.pix);
+    context.rect(textX - toolTipOption.boxPadding * opts.pix, textY, textWidth + 2 * toolTipOption.boxPadding * opts.pix, config.fontSize + 2 * toolTipOption.boxPadding * opts.pix);
+    context.closePath();
+    context.stroke();
+    context.fill();
+    context.beginPath();
+    context.setFontSize(config.fontSize);
+    context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor);
+    context.fillText(String(labelText), textX, textY + toolTipOption.boxPadding * opts.pix + config.fontSize);
+    context.closePath();
+    context.stroke();
+  }
+}
+
+function drawMarkLine(opts, config, context) {
+  let markLineOption = assign({}, {
+    type: 'solid',
+    dashLength: 4,
+    data: []
+  }, opts.extra.markLine);
+  let startX = opts.area[3];
+  let endX = opts.width - opts.area[1];
+  let points = calMarkLineData(markLineOption.data, opts);
+  for (let i = 0; i < points.length; i++) {
+    let item = assign({}, {
+      lineColor: '#DE4A42',
+      showLabel: false,
+      labelFontSize: 13,
+      labelPadding: 6,
+      labelFontColor: '#666666',
+      labelBgColor: '#DFE8FF',
+      labelBgOpacity: 0.8,
+      labelAlign: 'left',
+      labelOffsetX: 0,
+      labelOffsetY: 0,
+    }, points[i]);
+    if (markLineOption.type == 'dash') {
+      context.setLineDash([markLineOption.dashLength, markLineOption.dashLength]);
+    }
+    context.setStrokeStyle(item.lineColor);
+    context.setLineWidth(1 * opts.pix);
+    context.beginPath();
+    context.moveTo(startX, item.y);
+    context.lineTo(endX, item.y);
+    context.stroke();
+    context.setLineDash([]);
+    if (item.showLabel) {
+      let fontSize = item.labelFontSize * opts.pix;
+      let labelText = item.labelText ? item.labelText : item.value;
+      context.setFontSize(fontSize);
+      let textWidth = measureText(labelText, fontSize, context);
+      let bgWidth = textWidth + item.labelPadding * opts.pix * 2;
+      let bgStartX = item.labelAlign == 'left' ? opts.area[3] - bgWidth : opts.width - opts.area[1];
+      bgStartX += item.labelOffsetX;
+      let bgStartY = item.y - 0.5 * fontSize - item.labelPadding * opts.pix;
+      bgStartY += item.labelOffsetY;
+      let textX = bgStartX + item.labelPadding * opts.pix;
+      let textY = item.y;
+      context.setFillStyle(hexToRgb(item.labelBgColor, item.labelBgOpacity));
+      context.setStrokeStyle(item.labelBgColor);
+      context.setLineWidth(1 * opts.pix);
+      context.beginPath();
+      context.rect(bgStartX, bgStartY, bgWidth, fontSize + 2 * item.labelPadding * opts.pix);
+      context.closePath();
+      context.stroke();
+      context.fill();
+      context.setFontSize(fontSize);
+      context.setTextAlign('left');
+      context.setFillStyle(item.labelFontColor);
+      context.fillText(String(labelText), textX, bgStartY + fontSize + item.labelPadding * opts.pix/2);
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  }
+}
+
+function drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) {
+  var toolTipOption = assign({}, {
+    gridType: 'solid',
+    dashLength: 4
+  }, opts.extra.tooltip);
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  if (toolTipOption.gridType == 'dash') {
+    context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+  }
+  context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+  context.setLineWidth(1 * opts.pix);
+  context.beginPath();
+  context.moveTo(startX, opts.tooltip.offset.y);
+  context.lineTo(endX, opts.tooltip.offset.y);
+  context.stroke();
+  context.setLineDash([]);
+  if (toolTipOption.yAxisLabel) {
+    let boxPadding = toolTipOption.boxPadding * opts.pix;
+    let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing);
+    let widthArr = opts.chartData.yAxisData.yAxisWidth;
+    let tStartLeft = opts.area[3];
+    let tStartRight = opts.width - opts.area[1];
+    for (let i = 0; i < labelText.length; i++) {
+      context.setFontSize(toolTipOption.fontSize * opts.pix);
+      let textWidth = measureText(labelText[i], toolTipOption.fontSize * opts.pix, context);
+      let bgStartX, bgEndX, bgWidth;
+      if (widthArr[i].position == 'left') {
+        bgStartX = tStartLeft - (textWidth + boxPadding * 2) - 2 * opts.pix;
+        bgEndX = Math.max(bgStartX, bgStartX + textWidth + boxPadding * 2);
+      } else {
+        bgStartX = tStartRight + 2 * opts.pix;
+        bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + boxPadding * 2);
+      }
+      bgWidth = bgEndX - bgStartX;
+      let textX = bgStartX + (bgWidth - textWidth) / 2;
+      let textY = opts.tooltip.offset.y;
+      context.beginPath();
+      context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity));
+      context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+      context.setLineWidth(1 * opts.pix);
+      context.rect(bgStartX, textY - 0.5 * config.fontSize - boxPadding, bgWidth, config.fontSize + 2 * boxPadding);
+      context.closePath();
+      context.stroke();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(config.fontSize);
+      context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor);
+      context.fillText(labelText[i], textX, textY + 0.5 * config.fontSize);
+      context.closePath();
+      context.stroke();
+      if (widthArr[i].position == 'left') {
+        tStartLeft -= (widthArr[i].width + opts.yAxis.padding * opts.pix);
+      } else {
+        tStartRight += widthArr[i].width + opts.yAxis.padding * opts.pix;
+      }
+    }
+  }
+}
+
+function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
+  var toolTipOption = assign({}, {
+    activeBgColor: '#000000',
+    activeBgOpacity: 0.08,
+    activeWidth: eachSpacing
+  }, opts.extra.column);
+  toolTipOption.activeWidth = toolTipOption.activeWidth > eachSpacing ? eachSpacing : toolTipOption.activeWidth;
+  var startY = opts.area[0];
+  var endY = opts.height - opts.area[2];
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
+  context.rect(offsetX - toolTipOption.activeWidth / 2, startY, toolTipOption.activeWidth, endY - startY);
+  context.closePath();
+  context.fill();
+  context.setFillStyle("#FFFFFF");
+}
+
+function drawBarToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
+  var toolTipOption = assign({}, {
+    activeBgColor: '#000000',
+    activeBgOpacity: 0.08
+  }, opts.extra.bar);
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
+  context.rect( startX ,offsetX - eachSpacing / 2 ,  endX - startX,eachSpacing);
+  context.closePath();
+  context.fill();
+  context.setFillStyle("#FFFFFF");
+}
+
+
+function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) {
+  var toolTipOption = assign({}, {
+    showBox: true,
+    showArrow: true,
+    showCategory: false,
+    bgColor: '#000000',
+    bgOpacity: 0.7,
+    borderColor: '#000000',
+    borderWidth: 0,
+    borderRadius: 0,
+    borderOpacity: 0.7,
+    boxPadding: 3,
+    fontColor: '#FFFFFF',
+    fontSize: 13,
+    lineHeight: 20,
+    legendShow: true,
+    legendShape: 'auto',
+    splitLine: true,
+  }, opts.extra.tooltip);
+  if(toolTipOption.showCategory==true && opts.categories){
+    textList.unshift({text:opts.categories[opts.tooltip.index],color:null})
+  }
+  var fontSize = toolTipOption.fontSize * opts.pix;
+  var lineHeight = toolTipOption.lineHeight * opts.pix;
+  var boxPadding = toolTipOption.boxPadding * opts.pix;
+  var legendWidth = fontSize;
+  var legendMarginRight = 5 * opts.pix;
+  if(toolTipOption.legendShow == false){
+    legendWidth = 0;
+    legendMarginRight = 0;
+  }
+  var arrowWidth = toolTipOption.showArrow ? 8 * opts.pix : 0;
+  var isOverRightBorder = false;
+  if (opts.type == 'line' || opts.type == 'mount' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') {
+    if (toolTipOption.splitLine == true) {
+      drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
+    }
+  }
+  offset = assign({
+    x: 0,
+    y: 0
+  }, offset);
+  offset.y -= 8 * opts.pix;
+  var textWidth = textList.map(function(item) {
+    return measureText(item.text, fontSize, context);
+  });
+  var toolTipWidth = legendWidth + legendMarginRight + 4 * boxPadding + Math.max.apply(null, textWidth);
+  var toolTipHeight = 2 * boxPadding + textList.length * lineHeight;
+  if (toolTipOption.showBox == false) {
+    return
+  }
+  // if beyond the right border
+  if (offset.x - Math.abs(opts._scrollDistance_ || 0) + arrowWidth + toolTipWidth > opts.width) {
+    isOverRightBorder = true;
+  }
+  if (toolTipHeight + offset.y > opts.height) {
+    offset.y = opts.height - toolTipHeight;
+  }
+  // draw background rect
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.bgColor, toolTipOption.bgOpacity));
+  context.setLineWidth(toolTipOption.borderWidth * opts.pix);
+  context.setStrokeStyle(hexToRgb(toolTipOption.borderColor, toolTipOption.borderOpacity));
+  var radius = toolTipOption.borderRadius;
+  if (isOverRightBorder) {
+    // 增加左侧仍然超出的判断
+    if(toolTipWidth + arrowWidth > opts.width){
+      offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width)
+    }
+    if(toolTipWidth > offset.x){
+      offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width)
+    }
+    if (toolTipOption.showArrow) {
+      context.moveTo(offset.x, offset.y + 10 * opts.pix);
+      context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix);
+    }
+    context.arc(offset.x - arrowWidth - radius, offset.y + toolTipHeight - radius, radius, 0, Math.PI / 2, false);
+    context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + toolTipHeight - radius, radius,
+      Math.PI / 2, Math.PI, false);
+    context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false);
+    context.arc(offset.x - arrowWidth - radius, offset.y + radius, radius, -Math.PI / 2, 0, false);
+    if (toolTipOption.showArrow) {
+      context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix);
+      context.lineTo(offset.x, offset.y + 10 * opts.pix);
+    }
+  } else {
+    if (toolTipOption.showArrow) {
+      context.moveTo(offset.x, offset.y + 10 * opts.pix);
+      context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix);
+    }
+    context.arc(offset.x + arrowWidth + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false);
+    context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + radius, radius, -Math.PI / 2, 0,
+      false);
+    context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + toolTipHeight - radius, radius, 0,
+      Math.PI / 2, false);
+    context.arc(offset.x + arrowWidth + radius, offset.y + toolTipHeight - radius, radius, Math.PI / 2, Math.PI, false);
+    if (toolTipOption.showArrow) {
+      context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix);
+      context.lineTo(offset.x, offset.y + 10 * opts.pix);
+    }
+  }
+  context.closePath();
+  context.fill();
+  if (toolTipOption.borderWidth > 0) {
+    context.stroke();
+  }
+  // draw legend
+  if(toolTipOption.legendShow){
+    textList.forEach(function(item, index) {
+      if (item.color !== null) {
+        context.beginPath();
+        context.setFillStyle(item.color);
+        var startX = offset.x + arrowWidth + 2 * boxPadding;
+        var startY = offset.y + (lineHeight - fontSize) / 2 + lineHeight * index + boxPadding + 1;
+        if (isOverRightBorder) {
+          startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding;
+        }
+        switch (item.legendShape) {
+          case 'line':
+            context.moveTo(startX, startY + 0.5 * legendWidth - 2 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 2 * opts.pix, legendWidth, 4 * opts.pix);
+            break;
+          case 'triangle':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            break;
+          case 'diamond':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            break;
+          case 'circle':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.arc(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth, 5 * opts.pix, 0, 2 * Math.PI);
+            break;
+          case 'rect':
+            context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+            break;
+          case 'square':
+            context.moveTo(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix);
+            break;
+          default:
+            context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+        }
+        context.closePath();
+        context.fill();
+      }
+    });
+  }
+  
+  // draw text list
+  textList.forEach(function(item, index) {
+    var startX = offset.x + arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight;
+    if (isOverRightBorder) {
+      startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight;
+    }
+    var startY = offset.y + lineHeight * index + (lineHeight - fontSize)/2 - 1 + boxPadding + fontSize;
+    context.beginPath();
+    context.setFontSize(fontSize);
+    context.setTextBaseline('normal');
+    context.setFillStyle(toolTipOption.fontColor);
+    context.fillText(item.text, startX, startY);
+    context.closePath();
+    context.stroke();
+  });
+}
+
+function drawColumnDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let columnOption = assign({}, {
+    type: 'group',
+    width: eachSpacing / 2,
+    meterBorder: 4,
+    meterFillColor: '#FFFFFF',
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+    labelPosition: 'outside'
+  }, opts.extra.column);
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+  }
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawToolTipSplitArea(opts.tooltip.offset.x, opts, config, context, eachSpacing);
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    
+    // 计算0轴坐标
+    let spacingValid = opts.height - opts.area[0] - opts.area[2];
+    let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange);
+    let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2];
+    eachSeries.zeroPoints = zeroPoints;
+    var data = eachSeries.data;
+    switch (columnOption.type) {
+      case 'group':
+        var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process);
+        var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(tooltipPoints);
+        points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          //fix issues/I27B1N yyoinge & Joeshu
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - item.width / 2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color
+            var strokeColor = item.color || eachSeries.color
+            if (columnOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (columnOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+                grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+              const left = startX;
+              const top = item.y > zeroPoints ? zeroPoints : item.y;
+              const width = item.width;
+              const height = Math.abs(zeroPoints - item.y);
+              if (columnOption.barBorderCircle) {
+                columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              if(item.y > zeroPoints){
+                columnOption.barBorderRadius = [0, 0,width / 2, width / 2];
+              }
+              let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+              context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+              context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+              context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, item.y);
+              context.lineTo(startX + item.width, item.y);
+              context.lineTo(startX + item.width, zeroPoints);
+              context.lineTo(startX, zeroPoints);
+              context.lineTo(startX, item.y);
+              context.setLineWidth(1)
+              context.setStrokeStyle(strokeColor);
+            }
+            context.setFillStyle(fillColor);
+            context.closePath();
+            //context.stroke();
+            context.fill();
+          }
+        };
+        break;
+      case 'stack':
+        // 绘制堆叠数据图
+        var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(points);
+        points = fixColumeStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color;
+            var startX = item.x - item.width / 2 + 1;
+            var height = opts.height - item.y - opts.area[2];
+            var height0 = opts.height - item.y0 - opts.area[2];
+            if (seriesIndex > 0) {
+              height -= height0;
+            }
+            context.setFillStyle(fillColor);
+            context.moveTo(startX, item.y);
+            context.fillRect(startX, item.y, item.width, height);
+            context.closePath();
+            context.fill();
+          }
+        };
+        break;
+      case 'meter':
+        // 绘制温度计数据图
+        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+        calPoints.push(points);
+        points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meterBorder);
+          for (let i = 0; i < points.length; i++) {
+            let item = points[i];
+            if (item !== null && i > leftNum && i < rightNum) {
+              //画背景颜色
+              context.beginPath();
+              if (seriesIndex == 0 && columnOption.meterBorder > 0) {
+                context.setStrokeStyle(eachSeries.color);
+                context.setLineWidth(columnOption.meterBorder * opts.pix);
+              }
+              if(seriesIndex == 0){
+                context.setFillStyle(columnOption.meterFillColor);
+              }else{
+                context.setFillStyle(item.color || eachSeries.color);
+              }
+              var startX = item.x - item.width / 2;
+              var height = opts.height - item.y - opts.area[2];
+              if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+                const left = startX;
+                const top = item.y;
+                const width = item.width;
+                const height = zeroPoints - item.y;
+                if (columnOption.barBorderCircle) {
+                  columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+                }
+                let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+                let minRadius = Math.min(width/2,height/2);
+                r0 = r0 > minRadius ? minRadius : r0;
+                r1 = r1 > minRadius ? minRadius : r1;
+                r2 = r2 > minRadius ? minRadius : r2;
+                r3 = r3 > minRadius ? minRadius : r3;
+                r0 = r0 < 0 ? 0 : r0;
+                r1 = r1 < 0 ? 0 : r1;
+                r2 = r2 < 0 ? 0 : r2;
+                r3 = r3 < 0 ? 0 : r3;
+                context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+                context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+                context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+                context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+                context.fill();
+              }else{
+                context.moveTo(startX, item.y);
+                context.lineTo(startX + item.width, item.y);
+                context.lineTo(startX + item.width, zeroPoints);
+                context.lineTo(startX, zeroPoints);
+                context.lineTo(startX, item.y);
+                context.fill();
+              }
+              if (seriesIndex == 0 && columnOption.meterBorder > 0) {
+                context.closePath();
+                context.stroke();
+              }
+            }
+          }
+        break;
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      switch (columnOption.type) {
+        case 'group':
+          var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+          points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+        case 'stack':
+          var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+        case 'meter':
+          var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+      }
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawMountDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let mountOption = assign({}, {
+    type: 'mount',
+    widthRatio: 1,
+    borderWidth: 1,
+    barBorderCircle: false,
+    barBorderRadius: [],
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.mount);
+  mountOption.widthRatio = mountOption.widthRatio <= 0 ? 0 : mountOption.widthRatio;
+  mountOption.widthRatio = mountOption.widthRatio >= 2 ? 2 : mountOption.widthRatio;
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+  }
+  mountOption.customColor = fillCustomColor(mountOption.linearType, mountOption.customColor, series, config);
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[0]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    
+    // 计算0轴坐标
+    let spacingValid = opts.height - opts.area[0] - opts.area[2];
+    let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange);
+    let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2];
+    
+    var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process);
+    switch (mountOption.type) {
+      case 'bar':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((mountOption.barBorderRadius && mountOption.barBorderRadius.length === 4) || mountOption.barBorderCircle === true) {
+              const left = startX;
+              const top = item.y > zeroPoints ? zeroPoints : item.y;
+              const width = item.width;
+              const height = Math.abs(zeroPoints - item.y);
+              if (mountOption.barBorderCircle) {
+                mountOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              if(item.y > zeroPoints){
+                mountOption.barBorderRadius = [0, 0,width / 2, width / 2];
+              }
+              let [r0, r1, r2, r3] = mountOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+              context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+              context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+              context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, item.y);
+              context.lineTo(startX + item.width, item.y);
+              context.lineTo(startX + item.width, zeroPoints);
+              context.lineTo(startX, zeroPoints);
+              context.lineTo(startX, item.y);
+            }
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.closePath();
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'triangle':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.lineTo(item.x, item.y);
+            context.lineTo(startX + item.width, zeroPoints);
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'mount':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.bezierCurveTo(item.x - item.width/4, zeroPoints, item.x - item.width/4, item.y, item.x, item.y);
+            context.bezierCurveTo(item.x + item.width/4, item.y, item.x + item.width/4, zeroPoints, startX + item.width, zeroPoints);
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'sharp':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.quadraticCurveTo(item.x - 0, zeroPoints - height/4, item.x, item.y);
+            context.quadraticCurveTo(item.x + 0, zeroPoints - height/4, startX + item.width, zeroPoints)
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+    }
+
+  if (opts.dataLabel !== false && process === 1) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[0]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process);
+    drawMountPointText(points, series, config, context, opts, zeroPoints);
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: points,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawBarDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let yAxisPoints = [];
+  let eachSpacing = (opts.height - opts.area[0] - opts.area[2])/opts.categories.length;
+  for (let i = 0; i < opts.categories.length; i++) {
+    yAxisPoints.push(opts.area[0] + eachSpacing / 2 + eachSpacing * i);
+  }
+  let columnOption = assign({}, {
+    type: 'group',
+    width: eachSpacing / 2,
+    meterBorder: 4,
+    meterFillColor: '#FFFFFF',
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.bar);
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = yAxisPoints.length + 2;
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawBarToolTipSplitArea(opts.tooltip.offset.y, opts, config, context, eachSpacing);
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.xAxisData.ranges);
+    maxRange = ranges.pop();
+    minRange = ranges.shift();
+    var data = eachSeries.data;
+    switch (columnOption.type) {
+      case 'group':
+        var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process);
+        var tooltipPoints = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(tooltipPoints);
+        points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          //fix issues/I27B1N yyoinge & Joeshu
+          if (item !== null && i > leftNum && i < rightNum) {
+            //var startX = item.x - item.width / 2;
+            var startX = opts.area[3];
+            var startY = item.y - item.width / 2;
+            var height = item.height;
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color
+            var strokeColor = item.color || eachSeries.color
+            if (columnOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, item.x, item.y);
+              //透明渐变
+              if (columnOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+                grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+              const left = startX;
+              const width = item.width;
+              const top = item.y - item.width / 2;
+              const height = item.height;
+              if (columnOption.barBorderCircle) {
+                columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              
+              context.arc(left + r3, top + r3, r3, -Math.PI, -Math.PI / 2);
+              context.arc(item.x - r0, top + r0, r0, -Math.PI / 2, 0);
+              context.arc(item.x - r1, top + width - r1, r1, 0, Math.PI / 2);
+              context.arc(left + r2, top + width - r2, r2, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, startY);
+              context.lineTo(item.x, startY);
+              context.lineTo(item.x, startY + item.width);
+              context.lineTo(startX, startY + item.width);
+              context.lineTo(startX, startY);
+              context.setLineWidth(1)
+              context.setStrokeStyle(strokeColor);
+            }
+            context.setFillStyle(fillColor);
+            context.closePath();
+            //context.stroke();
+            context.fill();
+          }
+        };
+        break;
+      case 'stack':
+        // 绘制堆叠数据图
+        var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(points);
+        points = fixBarStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color;
+            var startX = item.x0;
+            context.setFillStyle(fillColor);
+            context.moveTo(startX, item.y - item.width/2);
+            context.fillRect(startX, item.y - item.width/2, item.height , item.width);
+            context.closePath();
+            context.fill();
+          }
+        };
+        break;
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.xAxisData.ranges);
+      maxRange = ranges.pop();
+      minRange = ranges.shift();
+      var data = eachSeries.data;
+      switch (columnOption.type) {
+        case 'group':
+          var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process);
+          points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts);
+          drawBarPointText(points, eachSeries, config, context, opts);
+          break;
+        case 'stack':
+          var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+          drawBarPointText(points, eachSeries, config, context, opts);
+          break;
+      }
+    });
+  }
+  return {
+    yAxisPoints: yAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawCandleDataPoints(series, seriesMA, opts, config, context) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var candleOption = assign({}, {
+    color: {},
+    average: {}
+  }, opts.extra.candle);
+  candleOption.color = assign({}, {
+    upLine: '#f04864',
+    upFill: '#f04864',
+    downLine: '#2fc25b',
+    downFill: '#2fc25b'
+  }, candleOption.color);
+  candleOption.average = assign({}, {
+    show: false,
+    name: [],
+    day: [],
+    color: config.color
+  }, candleOption.average);
+  opts.extra.candle = candleOption;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  //画均线
+  if (candleOption.average.show || seriesMA) { //Merge pull request !12 from 邱贵翔
+    seriesMA.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      var splitPointList = splitPoints(points,eachSeries);
+      for (let i = 0; i < splitPointList.length; i++) {
+        let points = splitPointList[i];
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(1);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              var ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x,
+                item.y);
+            }
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.closePath();
+        context.stroke();
+      }
+    });
+  }
+  //画K线
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    var splitPointList = splitPoints(points,eachSeries);
+    for (let i = 0; i < splitPointList[0].length; i++) {
+      if (i > leftNum && i < rightNum) {
+        let item = splitPointList[0][i];
+        context.beginPath();
+        //如果上涨
+        if (data[i][1] - data[i][0] > 0) {
+          context.setStrokeStyle(candleOption.color.upLine);
+          context.setFillStyle(candleOption.color.upFill);
+          context.setLineWidth(1 * opts.pix);
+          context.moveTo(item[3].x, item[3].y); //顶点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+          context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[2].x, item[2].y); //底点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+          context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.moveTo(item[3].x, item[3].y); //顶点
+        } else {
+          context.setStrokeStyle(candleOption.color.downLine);
+          context.setFillStyle(candleOption.color.downFill);
+          context.setLineWidth(1 * opts.pix);
+          context.moveTo(item[3].x, item[3].y); //顶点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+          context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[2].x, item[2].y); //底点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+          context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.moveTo(item[3].x, item[3].y); //顶点
+        }
+        context.closePath();
+        context.fill();
+        context.stroke();
+      }
+    }
+  });
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawAreaDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var areaOption = assign({}, {
+    type: 'straight',
+    opacity: 0.2,
+    addLine: false,
+    width: 2,
+    gradient: false,
+    activeType: 'none'
+  }, opts.extra.area);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let endY = opts.height - opts.area[2];
+  let calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    let data = eachSeries.data;
+    let points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    let splitPointList = splitPoints(points,eachSeries);
+    for (let i = 0; i < splitPointList.length; i++) {
+      let points = splitPointList[i];
+      // 绘制区域数
+      context.beginPath();
+      context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+      if (areaOption.gradient) {
+        let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]);
+        gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity));
+        gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+        context.setFillStyle(gradient);
+      } else {
+        context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+      }
+      context.setLineWidth(areaOption.width * opts.pix);
+      if (points.length > 1) {
+        let firstPoint = points[0];
+        let lastPoint = points[points.length - 1];
+        context.moveTo(firstPoint.x, firstPoint.y);
+        let startPoint = 0;
+        if (areaOption.type === 'curve') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              let ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+            }
+          };
+        } 
+        if (areaOption.type === 'straight') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        if (areaOption.type === 'step') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, points[j - 1].y);
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        context.lineTo(lastPoint.x, endY);
+        context.lineTo(firstPoint.x, endY);
+        context.lineTo(firstPoint.x, firstPoint.y);
+      } else {
+        let item = points[0];
+        context.moveTo(item.x - eachSpacing / 2, item.y);
+        // context.lineTo(item.x + eachSpacing / 2, item.y);
+        // context.lineTo(item.x + eachSpacing / 2, endY);
+        // context.lineTo(item.x - eachSpacing / 2, endY);
+        // context.moveTo(item.x - eachSpacing / 2, item.y);
+      }
+      context.closePath();
+      context.fill();
+      //画连线
+      if (areaOption.addLine) {
+        if (eachSeries.lineType == 'dash') {
+          let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+          dashLength *= opts.pix;
+          context.setLineDash([dashLength, dashLength]);
+        }
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(areaOption.width * opts.pix);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          if (areaOption.type === 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                let ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+              }
+            };
+          }
+          if (areaOption.type === 'straight') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          if (areaOption.type === 'step') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, points[j - 1].y);
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.stroke();
+        context.setLineDash([]);
+      }
+    }
+    //画点
+    if (opts.dataPointShape !== false) {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+    drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, areaOption,seriesIndex);
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawScatterDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var scatterOption = assign({}, {
+    type: 'circle'
+  }, opts.extra.scatter);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.setFillStyle(eachSeries.color);
+    context.setLineWidth(1 * opts.pix);
+    var shape = eachSeries.pointShape;
+    if (shape === 'diamond') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x, item.y - 4.5);
+          context.lineTo(item.x - 4.5, item.y);
+          context.lineTo(item.x, item.y + 4.5);
+          context.lineTo(item.x + 4.5, item.y);
+          context.lineTo(item.x, item.y - 4.5);
+        }
+      });
+    } else if (shape === 'circle') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x + 2.5 * opts.pix, item.y);
+          context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+        }
+      });
+    } else if (shape === 'square') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x - 3.5, item.y - 3.5);
+          context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+        }
+      });
+    } else if (shape === 'triangle') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x, item.y - 4.5);
+          context.lineTo(item.x - 4.5, item.y + 4.5);
+          context.lineTo(item.x + 4.5, item.y + 4.5);
+          context.lineTo(item.x, item.y - 4.5);
+        }
+      });
+    } else if (shape === 'triangle') {
+      return;
+    }
+    context.closePath();
+    context.fill();
+    context.stroke();
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawBubbleDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var bubbleOption = assign({}, {
+    opacity: 1,
+    border:2
+  }, opts.extra.bubble);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.setLineWidth(bubbleOption.border * opts.pix);
+    context.setFillStyle(hexToRgb(eachSeries.color, bubbleOption.opacity));
+    points.forEach(function(item, index) {
+      context.moveTo(item.x + item.r, item.y);
+      context.arc(item.x, item.y, item.r * opts.pix, 0, 2 * Math.PI, false);
+    });
+    context.closePath();
+    context.fill();
+    context.stroke();
+    
+    if (opts.dataLabel !== false && process === 1) {
+      points.forEach(function(item, index) {
+        context.beginPath();
+        var fontSize = eachSeries.textSize * opts.pix || config.fontSize;
+        context.setFontSize(fontSize);
+        context.setFillStyle(eachSeries.textColor || "#FFFFFF");
+        context.setTextAlign('center');
+        context.fillText(String(item.t), item.x, item.y + fontSize/2);
+        context.closePath();
+        context.stroke();
+        context.setTextAlign('left');
+      });
+    }
+  });
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawLineDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var lineOption = assign({}, {
+    type: 'straight',
+    width: 2,
+    activeType: 'none',
+    linearType: 'none',
+    onShadow: false,
+    animation: 'vertical',
+  }, opts.extra.line);
+  lineOption.width *= opts.pix;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    // 这段很神奇的代码用于解决ios16的setStrokeStyle失效的bug
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.moveTo(-10000, -10000);
+    context.lineTo(-10001, -10001);
+    context.stroke();
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process);
+    calPoints.push(points);
+    var splitPointList = splitPoints(points,eachSeries);
+    if (eachSeries.lineType == 'dash') {
+      let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+      dashLength *= opts.pix;
+      context.setLineDash([dashLength, dashLength]);
+    }
+    context.beginPath();
+    var strokeColor = eachSeries.color;
+    if (lineOption.linearType !== 'none' && eachSeries.linearColor && eachSeries.linearColor.length > 0) {
+      var grd = context.createLinearGradient(opts.chartData.xAxisData.startX, opts.height/2, opts.chartData.xAxisData.endX, opts.height/2);
+      for (var i = 0; i < eachSeries.linearColor.length; i++) {
+        grd.addColorStop(eachSeries.linearColor[i][0], hexToRgb(eachSeries.linearColor[i][1], 1));
+      }
+      strokeColor = grd
+    }
+    context.setStrokeStyle(strokeColor);
+    if (lineOption.onShadow == true && eachSeries.setShadow && eachSeries.setShadow.length > 0) {
+      context.setShadow(eachSeries.setShadow[0], eachSeries.setShadow[1], eachSeries.setShadow[2], eachSeries.setShadow[3]);
+    }else{
+      context.setShadow(0, 0, 0, 'rgba(0,0,0,0)');
+    }
+    context.setLineWidth(lineOption.width);
+    splitPointList.forEach(function(points, index) {
+      if (points.length === 1) {
+        context.moveTo(points[0].x, points[0].y);
+        // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+      } else {
+        context.moveTo(points[0].x, points[0].y);
+        let startPoint = 0;
+        if (lineOption.type === 'curve') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              var ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+            }
+          };
+        }
+        if (lineOption.type === 'straight') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        if (lineOption.type === 'step') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, points[j - 1].y);
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        context.moveTo(points[0].x, points[0].y);
+      }
+    });
+    context.stroke();
+    context.setLineDash([]);
+    if (opts.dataPointShape !== false) {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+    drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, lineOption);
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawMixDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let columnOption = assign({}, {
+    width: eachSpacing / 2,
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.mix.column);
+  let areaOption = assign({}, {
+    opacity: 0.2,
+    gradient: false
+  }, opts.extra.mix.area);
+  let lineOption = assign({}, {
+    width: 2
+  }, opts.extra.mix.line);
+  let endY = opts.height - opts.area[2];
+  let calPoints = [];
+  var columnIndex = 0;
+  var columnLength = 0;
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (eachSeries.type == 'column') {
+      columnLength += 1;
+    }
+  });
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    // 绘制柱状数据图
+    if (eachSeries.type == 'column') {
+      points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+      for (let i = 0; i < points.length; i++) {
+        let item = points[i];
+        if (item !== null && i > leftNum && i < rightNum) {
+          var startX = item.x - item.width / 2;
+          var height = opts.height - item.y - opts.area[2];
+          context.beginPath();
+          var fillColor = item.color || eachSeries.color
+          var strokeColor = item.color || eachSeries.color
+          if (columnOption.linearType !== 'none') {
+            var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]);
+            //透明渐变
+            if (columnOption.linearType == 'opacity') {
+              grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+              grd.addColorStop(1, hexToRgb(fillColor, 1));
+            } else {
+              grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+              grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+              grd.addColorStop(1, hexToRgb(fillColor, 1));
+            }
+            fillColor = grd
+          }
+          // 圆角边框
+          if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle) {
+            const left = startX;
+            const top = item.y;
+            const width = item.width;
+            const height = opts.height - opts.area[2] - item.y;
+            if (columnOption.barBorderCircle) {
+              columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+            }
+            let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+            let minRadius = Math.min(width/2,height/2);
+            r0 = r0 > minRadius ? minRadius : r0;
+            r1 = r1 > minRadius ? minRadius : r1;
+            r2 = r2 > minRadius ? minRadius : r2;
+            r3 = r3 > minRadius ? minRadius : r3;
+            r0 = r0 < 0 ? 0 : r0;
+            r1 = r1 < 0 ? 0 : r1;
+            r2 = r2 < 0 ? 0 : r2;
+            r3 = r3 < 0 ? 0 : r3;
+            context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+            context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+            context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+            context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+          } else {
+            context.moveTo(startX, item.y);
+            context.lineTo(startX + item.width, item.y);
+            context.lineTo(startX + item.width, opts.height - opts.area[2]);
+            context.lineTo(startX, opts.height - opts.area[2]);
+            context.lineTo(startX, item.y);
+            context.setLineWidth(1)
+            context.setStrokeStyle(strokeColor);
+          }
+          context.setFillStyle(fillColor);
+          context.closePath();
+          context.fill();
+        }
+      }
+      columnIndex += 1;
+    }
+    //绘制区域图数据
+    if (eachSeries.type == 'area') {
+      let splitPointList = splitPoints(points,eachSeries);
+      for (let i = 0; i < splitPointList.length; i++) {
+        let points = splitPointList[i];
+        // 绘制区域数据
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+        if (areaOption.gradient) {
+          let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]);
+          gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity));
+          gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+          context.setFillStyle(gradient);
+        } else {
+          context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+        }
+        context.setLineWidth(2 * opts.pix);
+        if (points.length > 1) {
+          var firstPoint = points[0];
+          let lastPoint = points[points.length - 1];
+          context.moveTo(firstPoint.x, firstPoint.y);
+          let startPoint = 0;
+          if (eachSeries.style === 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                var ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+              }
+            };
+          } else {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          context.lineTo(lastPoint.x, endY);
+          context.lineTo(firstPoint.x, endY);
+          context.lineTo(firstPoint.x, firstPoint.y);
+        } else {
+          let item = points[0];
+          context.moveTo(item.x - eachSpacing / 2, item.y);
+          // context.lineTo(item.x + eachSpacing / 2, item.y);
+          // context.lineTo(item.x + eachSpacing / 2, endY);
+          // context.lineTo(item.x - eachSpacing / 2, endY);
+          // context.moveTo(item.x - eachSpacing / 2, item.y);
+        }
+        context.closePath();
+        context.fill();
+      }
+    }
+    // 绘制折线数据图
+    if (eachSeries.type == 'line') {
+      var splitPointList = splitPoints(points,eachSeries);
+      splitPointList.forEach(function(points, index) {
+        if (eachSeries.lineType == 'dash') {
+          let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+          dashLength *= opts.pix;
+          context.setLineDash([dashLength, dashLength]);
+        }
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(lineOption.width * opts.pix);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          if (eachSeries.style == 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                var ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y,
+                  item.x, item.y);
+              }
+            }
+          } else {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            }
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.stroke();
+        context.setLineDash([]);
+      });
+    }
+    // 绘制点数据图
+    if (eachSeries.type == 'point') {
+      eachSeries.addPoint = true;
+    }
+    if (eachSeries.addPoint == true && eachSeries.type !== 'column') {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    var columnIndex = 0;
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      if (eachSeries.type !== 'column') {
+        drawPointText(points, eachSeries, config, context, opts);
+      } else {
+        points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+        drawPointText(points, eachSeries, config, context, opts);
+        columnIndex += 1;
+      }
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing,
+  }
+}
+
+
+function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) {
+  var toolTipOption = opts.extra.tooltip || {};
+  if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' || opts.type == 'column' || opts.type == 'mount' || opts.type == 'candle' || opts.type == 'mix')) {
+    drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints)
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context, eachSpacing, xAxisPoints);
+  }
+  context.restore();
+
+}
+
+function drawXAxis(categories, opts, config, context) {
+
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    startX = xAxisData.startX,
+    endX = xAxisData.endX,
+    eachSpacing = xAxisData.eachSpacing;
+  var boundaryGap = 'center';
+  if (opts.type == 'bar' || opts.type == 'line' || opts.type == 'area'|| opts.type == 'scatter' || opts.type == 'bubble') {
+    boundaryGap = opts.xAxis.boundaryGap;
+  }
+  var startY = opts.height - opts.area[2];
+  var endY = opts.area[0];
+
+  //绘制滚动条
+  if (opts.enableScroll && opts.xAxis.scrollShow) {
+    var scrollY = opts.height - opts.area[2] + config.xAxisHeight;
+    var scrollScreenWidth = endX - startX;
+    var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1);
+    if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+      if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+      scrollTotalWidth += (opts.extra.mount.widthRatio - 1)*eachSpacing;
+    }
+    var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth;
+    var scrollLeft = 0;
+    if (opts._scrollDistance_) {
+      scrollLeft = -opts._scrollDistance_ * (scrollScreenWidth) / scrollTotalWidth;
+    }
+    context.beginPath();
+    context.setLineCap('round');
+    context.setLineWidth(6 * opts.pix);
+    context.setStrokeStyle(opts.xAxis.scrollBackgroundColor || "#EFEBEF");
+    context.moveTo(startX, scrollY);
+    context.lineTo(endX, scrollY);
+    context.stroke();
+    context.closePath();
+    context.beginPath();
+    context.setLineCap('round');
+    context.setLineWidth(6 * opts.pix);
+    context.setStrokeStyle(opts.xAxis.scrollColor || "#A6A6A6");
+    context.moveTo(startX + scrollLeft, scrollY);
+    context.lineTo(startX + scrollLeft + scrollWidth, scrollY);
+    context.stroke();
+    context.closePath();
+    context.setLineCap('butt');
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  //绘制X轴刻度线
+  if (opts.xAxis.calibration === true) {
+    context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+    context.setLineCap('butt');
+    context.setLineWidth(1 * opts.pix);
+    xAxisPoints.forEach(function(item, index) {
+      if (index > 0) {
+        context.beginPath();
+        context.moveTo(item - eachSpacing / 2, startY);
+        context.lineTo(item - eachSpacing / 2, startY + 3 * opts.pix);
+        context.closePath();
+        context.stroke();
+      }
+    });
+  }
+  //绘制X轴网格
+  if (opts.xAxis.disableGrid !== true) {
+    context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+    context.setLineCap('butt');
+    context.setLineWidth(1 * opts.pix);
+    if (opts.xAxis.gridType == 'dash') {
+      context.setLineDash([opts.xAxis.dashLength * opts.pix, opts.xAxis.dashLength * opts.pix]);
+    }
+    opts.xAxis.gridEval = opts.xAxis.gridEval || 1;
+    xAxisPoints.forEach(function(item, index) {
+      if (index % opts.xAxis.gridEval == 0) {
+        context.beginPath();
+        context.moveTo(item, startY);
+        context.lineTo(item, endY);
+        context.stroke();
+      }
+    });
+    context.setLineDash([]);
+  }
+  //绘制X轴文案
+  if (opts.xAxis.disabled !== true) {
+    // 对X轴列表做抽稀处理
+    //默认全部显示X轴标签
+    let maxXAxisListLength = categories.length;
+    //如果设置了X轴单屏数量
+    if (opts.xAxis.labelCount) {
+      //如果设置X轴密度
+      if (opts.xAxis.itemCount) {
+        maxXAxisListLength = Math.ceil(categories.length / opts.xAxis.itemCount * opts.xAxis.labelCount);
+      } else {
+        maxXAxisListLength = opts.xAxis.labelCount;
+      }
+      maxXAxisListLength -= 1;
+    }
+
+    let ratio = Math.ceil(categories.length / maxXAxisListLength);
+
+    let newCategories = [];
+    let cgLength = categories.length;
+    for (let i = 0; i < cgLength; i++) {
+      if (i % ratio !== 0) {
+        newCategories.push("");
+      } else {
+        newCategories.push(categories[i]);
+      }
+    }
+    newCategories[cgLength - 1] = categories[cgLength - 1];
+    var xAxisFontSize = opts.xAxis.fontSize * opts.pix || config.fontSize;
+    if (config._xAxisTextAngle_ === 0) {
+      newCategories.forEach(function(item, index) {
+        var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item;
+        var offset = -measureText(String(xitem), xAxisFontSize, context) / 2;
+        if (boundaryGap == 'center') {
+          offset += eachSpacing / 2;
+        }
+        var scrollHeight = 0;
+        if (opts.xAxis.scrollShow) {
+          scrollHeight = 6 * opts.pix;
+        }
+        // 如果在主视图区域内
+        var _scrollDistance_ = opts._scrollDistance_ || 0;
+        var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index];
+        if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){
+          context.beginPath();
+          context.setFontSize(xAxisFontSize);
+          context.setFillStyle(opts.xAxis.fontColor || opts.fontColor);
+          context.fillText(String(xitem), xAxisPoints[index] + offset, startY + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.fontSize) * opts.pix / 2 + opts.xAxis.fontSize * opts.pix);
+          context.closePath();
+          context.stroke();
+        }
+      });
+    } else {
+      newCategories.forEach(function(item, index) {
+        var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item) : item;
+        // 如果在主视图区域内
+        var _scrollDistance_ = opts._scrollDistance_ || 0;
+        var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index];
+        if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){
+          context.save();
+          context.beginPath();
+          context.setFontSize(xAxisFontSize);
+          context.setFillStyle(opts.xAxis.fontColor || opts.fontColor);
+          var textWidth = measureText(String(xitem), xAxisFontSize, context);
+          var offsetX = xAxisPoints[index];
+          if (boundaryGap == 'center') {
+            offsetX = xAxisPoints[index] + eachSpacing / 2;
+          }
+          var scrollHeight = 0;
+          if (opts.xAxis.scrollShow) {
+            scrollHeight = 6 * opts.pix;
+          }
+          var offsetY = startY + opts.xAxis.marginTop * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_));
+          if(opts.xAxis.rotateAngle < 0){
+            offsetX -= xAxisFontSize / 2;
+            textWidth = 0;
+          }else{
+            offsetX += xAxisFontSize / 2;
+            textWidth = -textWidth;
+          }
+          context.translate(offsetX, offsetY);
+          context.rotate(-1 * config._xAxisTextAngle_);
+          context.fillText(String(xitem), textWidth , 0 );
+          context.closePath();
+          context.stroke();
+          context.restore();
+        }
+      });
+    }
+  }
+  context.restore();
+  
+  //画X轴标题
+  if (opts.xAxis.title) {
+    context.beginPath();
+    context.setFontSize(opts.xAxis.titleFontSize * opts.pix);
+    context.setFillStyle(opts.xAxis.titleFontColor);
+    context.fillText(String(opts.xAxis.title), opts.width - opts.area[1] + opts.xAxis.titleOffsetX * opts.pix,opts.height - opts.area[2] + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.titleFontSize) * opts.pix / 2 + (opts.xAxis.titleFontSize + opts.xAxis.titleOffsetY) * opts.pix);
+    context.closePath();
+    context.stroke();
+  }
+  
+  //绘制X轴轴线
+  if (opts.xAxis.axisLine) {
+    context.beginPath();
+    context.setStrokeStyle(opts.xAxis.axisLineColor);
+    context.setLineWidth(1 * opts.pix);
+    context.moveTo(startX, opts.height - opts.area[2]);
+    context.lineTo(endX, opts.height - opts.area[2]);
+    context.stroke();
+  }
+}
+
+function drawYAxisGrid(categories, opts, config, context) {
+  if (opts.yAxis.disableGrid === true) {
+    return;
+  }
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  let eachSpacing = spacingValid / opts.yAxis.splitNumber;
+  let startX = opts.area[3];
+  let xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+    xAxiseachSpacing = opts.chartData.xAxisData.eachSpacing;
+  let TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1);
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1 ){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    TotalWidth += (opts.extra.mount.widthRatio - 1) * xAxiseachSpacing;
+  }
+  let endX = startX + TotalWidth;
+  let points = [];
+  let startY = 1
+  if (opts.xAxis.axisLine === false) {
+    startY = 0
+  }
+  for (let i = startY; i < opts.yAxis.splitNumber + 1; i++) {
+    points.push(opts.height - opts.area[2] - eachSpacing * i);
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  if (opts.yAxis.gridType == 'dash') {
+    context.setLineDash([opts.yAxis.dashLength * opts.pix, opts.yAxis.dashLength * opts.pix]);
+  }
+  context.setStrokeStyle(opts.yAxis.gridColor);
+  context.setLineWidth(1 * opts.pix);
+  points.forEach(function(item, index) {
+    context.beginPath();
+    context.moveTo(startX, item);
+    context.lineTo(endX, item);
+    context.stroke();
+  });
+  context.setLineDash([]);
+  context.restore();
+}
+
+function drawYAxis(series, opts, config, context) {
+  if (opts.yAxis.disabled === true) {
+    return;
+  }
+  var spacingValid = opts.height - opts.area[0] - opts.area[2];
+  var eachSpacing = spacingValid / opts.yAxis.splitNumber;
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  var endY = opts.height - opts.area[2];
+  // set YAxis background
+  context.beginPath();
+  context.setFillStyle(opts.background);
+  if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'left') {
+    context.fillRect(0, 0, startX, endY + 2 * opts.pix);
+  }
+  if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'right') {
+    context.fillRect(endX, 0, opts.width, endY + 2 * opts.pix);
+  }
+  context.closePath();
+  context.stroke();
+  
+  let tStartLeft = opts.area[3];
+  let tStartRight = opts.width - opts.area[1];
+  let tStartCenter = opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2;
+  if (opts.yAxis.data) {
+    for (let i = 0; i < opts.yAxis.data.length; i++) {
+      let yData = opts.yAxis.data[i];
+      var points = [];
+      if(yData.type === 'categories'){
+        for (let i = 0; i <= yData.categories.length; i++) {
+          points.push(opts.area[0] + spacingValid / yData.categories.length / 2 + spacingValid / yData.categories.length * i);
+        }
+      }else{
+        for (let i = 0; i <= opts.yAxis.splitNumber; i++) {
+          points.push(opts.area[0] + eachSpacing * i);
+        }
+      }
+      if (yData.disabled !== true) {
+        let rangesFormat = opts.chartData.yAxisData.rangesFormat[i];
+        let yAxisFontSize = yData.fontSize ? yData.fontSize * opts.pix : config.fontSize;
+        let yAxisWidth = opts.chartData.yAxisData.yAxisWidth[i];
+        let textAlign = yData.textAlign || "right";
+        //画Y轴刻度及文案
+        rangesFormat.forEach(function(item, index) {
+          var pos = points[index];
+          context.beginPath();
+          context.setFontSize(yAxisFontSize);
+          context.setLineWidth(1 * opts.pix);
+          context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+          context.setFillStyle(yData.fontColor || opts.fontColor);
+          let tmpstrat = 0;
+          let gapwidth = 4 * opts.pix;
+          if (yAxisWidth.position == 'left') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartLeft, pos);
+              context.lineTo(tStartLeft - 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            //画文字
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartLeft - yAxisWidth.width
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartLeft - gapwidth
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartLeft - yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+
+          } else if (yAxisWidth.position == 'right') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartRight, pos);
+              context.lineTo(tStartRight + 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartRight + gapwidth
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartRight + yAxisWidth.width
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartRight + yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+          } else if (yAxisWidth.position == 'center') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartCenter, pos);
+              context.lineTo(tStartCenter - 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            //画文字
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartCenter - yAxisWidth.width
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartCenter - gapwidth
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartCenter - yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+          }
+          context.closePath();
+          context.stroke();
+          context.setTextAlign('left');
+        });
+        //画Y轴轴线
+        if (yData.axisLine !== false) {
+          context.beginPath();
+          context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+          context.setLineWidth(1 * opts.pix);
+          if (yAxisWidth.position == 'left') {
+            context.moveTo(tStartLeft, opts.height - opts.area[2]);
+            context.lineTo(tStartLeft, opts.area[0]);
+          } else if (yAxisWidth.position == 'right') {
+            context.moveTo(tStartRight, opts.height - opts.area[2]);
+            context.lineTo(tStartRight, opts.area[0]);
+          } else if (yAxisWidth.position == 'center') {
+            context.moveTo(tStartCenter, opts.height - opts.area[2]);
+            context.lineTo(tStartCenter, opts.area[0]);
+          }
+          context.stroke();
+        }
+        //画Y轴标题
+        if (opts.yAxis.showTitle) {
+          let titleFontSize = yData.titleFontSize * opts.pix || config.fontSize;
+          let title = yData.title;
+          context.beginPath();
+          context.setFontSize(titleFontSize);
+          context.setFillStyle(yData.titleFontColor || opts.fontColor);
+          if (yAxisWidth.position == 'left') {
+            context.fillText(title, tStartLeft - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          } else if (yAxisWidth.position == 'right') {
+            context.fillText(title, tStartRight - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          } else if (yAxisWidth.position == 'center') {
+            context.fillText(title, tStartCenter - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          }
+          context.closePath();
+          context.stroke();
+        }
+        if (yAxisWidth.position == 'left') {
+          tStartLeft -= (yAxisWidth.width + opts.yAxis.padding * opts.pix);
+        } else {
+          tStartRight += yAxisWidth.width + opts.yAxis.padding * opts.pix;
+        }
+      }
+    }
+  }
+
+}
+
+function drawLegend(series, opts, config, context, chartData) {
+  if (opts.legend.show === false) {
+    return;
+  }
+  let legendData = chartData.legendData;
+  let legendList = legendData.points;
+  let legendArea = legendData.area;
+  let padding = opts.legend.padding * opts.pix;
+  let fontSize = opts.legend.fontSize * opts.pix;
+  let shapeWidth = 15 * opts.pix;
+  let shapeRight = 5 * opts.pix;
+  let itemGap = opts.legend.itemGap * opts.pix;
+  let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize);
+  //画背景及边框
+  context.beginPath();
+  context.setLineWidth(opts.legend.borderWidth * opts.pix);
+  context.setStrokeStyle(opts.legend.borderColor);
+  context.setFillStyle(opts.legend.backgroundColor);
+  context.moveTo(legendArea.start.x, legendArea.start.y);
+  context.rect(legendArea.start.x, legendArea.start.y, legendArea.width, legendArea.height);
+  context.closePath();
+  context.fill();
+  context.stroke();
+  legendList.forEach(function(itemList, listIndex) {
+    let width = 0;
+    let height = 0;
+    width = legendData.widthArr[listIndex];
+    height = legendData.heightArr[listIndex];
+    let startX = 0;
+    let startY = 0;
+    if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+      switch (opts.legend.float) {
+        case 'left':
+          startX = legendArea.start.x + padding;
+        break;
+        case 'right':
+          startX = legendArea.start.x + legendArea.width - width;
+        break;
+        default:
+        startX = legendArea.start.x + (legendArea.width - width) / 2;
+      }
+      startY = legendArea.start.y + padding + listIndex * lineHeight;
+    } else {
+      if (listIndex == 0) {
+        width = 0;
+      } else {
+        width = legendData.widthArr[listIndex - 1];
+      }
+      startX = legendArea.start.x + padding + width;
+      startY = legendArea.start.y + padding + (legendArea.height - height) / 2;
+    }
+    context.setFontSize(config.fontSize);
+    for (let i = 0; i < itemList.length; i++) {
+      let item = itemList[i];
+      item.area = [0, 0, 0, 0];
+      item.area[0] = startX;
+      item.area[1] = startY;
+      item.area[3] = startY + lineHeight;
+      context.beginPath();
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.show ? item.color : opts.legend.hiddenColor);
+      context.setFillStyle(item.show ? item.color : opts.legend.hiddenColor);
+      switch (item.legendShape) {
+        case 'line':
+          context.moveTo(startX, startY + 0.5 * lineHeight - 2 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 2 * opts.pix, 15 * opts.pix, 4 * opts.pix);
+          break;
+        case 'triangle':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          break;
+        case 'diamond':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          break;
+        case 'circle':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.arc(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight, 5 * opts.pix, 0, 2 * Math.PI);
+          break;
+        case 'rect':
+          context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+          break;
+        case 'square':
+          context.moveTo(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix);
+          break;
+        case 'none':
+          break;
+        default:
+          context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+      }
+      context.closePath();
+      context.fill();
+      context.stroke();
+      startX += shapeWidth + shapeRight;
+      let fontTrans = 0.5 * lineHeight + 0.5 * fontSize - 2;
+      const legendText = item.legendText ? item.legendText : item.name;
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.show ? opts.legend.fontColor : opts.legend.hiddenColor);
+      context.fillText(legendText, startX, startY + fontTrans);
+      context.closePath();
+      context.stroke();
+      if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+        startX += measureText(legendText, fontSize, context) + itemGap;
+        item.area[2] = startX;
+      } else {
+        item.area[2] = startX + measureText(legendText, fontSize, context) + itemGap;;
+        startX -= shapeWidth + shapeRight;
+        startY += lineHeight;
+      }
+    }
+  });
+}
+
+function drawPieDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var pieOption = assign({}, {
+    activeOpacity: 0.5,
+    activeRadius: 10,
+    offsetAngle: 0,
+    labelWidth: 15,
+    ringWidth: 30,
+    customRadius: 0,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    centerColor: '#FFFFFF',
+    linearType: 'none',
+    customColor: [],
+  }, opts.type == "pie" ? opts.extra.pie : opts.extra.ring);
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  if (config.pieChartLinePadding == 0) {
+    config.pieChartLinePadding = pieOption.activeRadius * opts.pix;
+  }
+
+  var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding);
+  radius = radius < 10 ? 10 : radius;
+  if (pieOption.customRadius > 0) {
+    radius = pieOption.customRadius * opts.pix;
+  }
+  series = getPieDataPoints(series, radius, process);
+  var activeRadius = pieOption.activeRadius * opts.pix;
+  pieOption.customColor = fillCustomColor(pieOption.linearType, pieOption.customColor, series, config);
+  series = series.map(function(eachSeries) {
+    eachSeries._start_ += (pieOption.offsetAngle) * Math.PI / 180;
+    return eachSeries;
+  });
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (opts.tooltip) {
+      if (opts.tooltip.index == seriesIndex) {
+        context.beginPath();
+        context.setFillStyle(hexToRgb(eachSeries.color, pieOption.activeOpacity || 0.5));
+        context.moveTo(centerPosition.x, centerPosition.y);
+        context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_ + activeRadius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
+        context.closePath();
+        context.fill();
+      }
+    }
+    context.beginPath();
+    context.setLineWidth(pieOption.borderWidth * opts.pix);
+    context.lineJoin = "round";
+    context.setStrokeStyle(pieOption.borderColor);
+    var fillcolor = eachSeries.color;
+    if (pieOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }
+      grd.addColorStop(0, hexToRgb(pieOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, 1))
+      fillcolor = grd
+    }
+    context.setFillStyle(fillcolor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
+    context.closePath();
+    context.fill();
+    if (pieOption.border == true) {
+      context.stroke();
+    }
+  });
+  if (opts.type === 'ring') {
+    var innerPieWidth = radius * 0.6;
+    if (typeof pieOption.ringWidth === 'number' && pieOption.ringWidth > 0) {
+      innerPieWidth = Math.max(0, radius - pieOption.ringWidth * opts.pix);
+    }
+    context.beginPath();
+    context.setFillStyle(pieOption.centerColor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI);
+    context.closePath();
+    context.fill();
+  }
+  if (opts.dataLabel !== false && process === 1) {
+    drawPieText(series, opts, config, context, radius, centerPosition);
+  }
+  if (process === 1 && opts.type === 'ring') {
+    drawRingTitle(opts, config, context, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawRoseDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var roseOption = assign({}, {
+    type: 'area',
+    activeOpacity: 0.5,
+    activeRadius: 10,
+    offsetAngle: 0,
+    labelWidth: 15,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.rose);
+  if (config.pieChartLinePadding == 0) {
+    config.pieChartLinePadding = roseOption.activeRadius * opts.pix;
+  }
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding);
+  radius = radius < 10 ? 10 : radius;
+  var minRadius = roseOption.minRadius || radius * 0.5;
+  if(radius < minRadius){
+    radius = minRadius + 10;
+  }
+  series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process);
+  var activeRadius = roseOption.activeRadius * opts.pix;
+  roseOption.customColor = fillCustomColor(roseOption.linearType, roseOption.customColor, series, config);
+  series = series.map(function(eachSeries) {
+    eachSeries._start_ += (roseOption.offsetAngle || 0) * Math.PI / 180;
+    return eachSeries;
+  });
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (opts.tooltip) {
+      if (opts.tooltip.index == seriesIndex) {
+        context.beginPath();
+        context.setFillStyle(hexToRgb(eachSeries.color, roseOption.activeOpacity || 0.5));
+        context.moveTo(centerPosition.x, centerPosition.y);
+        context.arc(centerPosition.x, centerPosition.y, activeRadius + eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI);
+        context.closePath();
+        context.fill();
+      }
+    }
+    context.beginPath();
+    context.setLineWidth(roseOption.borderWidth * opts.pix);
+    context.lineJoin = "round";
+    context.setStrokeStyle(roseOption.borderColor);
+    var fillcolor = eachSeries.color;
+    if (roseOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }
+      grd.addColorStop(0, hexToRgb(roseOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, 1))
+      fillcolor = grd
+    }
+    context.setFillStyle(fillcolor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI);
+    context.closePath();
+    context.fill();
+    if (roseOption.border == true) {
+      context.stroke();
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    drawPieText(series, opts, config, context, radius, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawArcbarDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var arcbarOption = assign({}, {
+    startAngle: 0.75,
+    endAngle: 0.25,
+    type: 'default',
+    direction: 'cw',
+    lineCap: 'round',
+    width: 12 ,
+    gap: 2 ,
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.arcbar);
+  series = getArcbarDataPoints(series, arcbarOption, process);
+  var centerPosition;
+  if (arcbarOption.centerX || arcbarOption.centerY) {
+    centerPosition = {
+      x: arcbarOption.centerX ? arcbarOption.centerX : opts.width / 2,
+      y: arcbarOption.centerY ? arcbarOption.centerY : opts.height / 2
+    };
+  } else {
+    centerPosition = {
+      x: opts.width / 2,
+      y: opts.height / 2
+    };
+  }
+  var radius;
+  if (arcbarOption.radius) {
+    radius = arcbarOption.radius;
+  } else {
+    radius = Math.min(centerPosition.x, centerPosition.y);
+    radius -= 5 * opts.pix;
+    radius -= arcbarOption.width / 2;
+  }
+  radius = radius < 10 ? 10 : radius;
+  arcbarOption.customColor = fillCustomColor(arcbarOption.linearType, arcbarOption.customColor, series, config);
+  
+  for (let i = 0; i < series.length; i++) {
+    let eachSeries = series[i];
+    //背景颜色
+    context.setLineWidth(arcbarOption.width * opts.pix);
+    context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9');
+    context.setLineCap(arcbarOption.lineCap);
+    context.beginPath();
+    if (arcbarOption.type == 'default') {
+      context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, arcbarOption.direction == 'ccw');
+    } else {
+      context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, 0, 2 * Math.PI, arcbarOption.direction == 'ccw');
+    }
+    context.stroke();
+    //进度条
+    var fillColor = eachSeries.color
+    if(arcbarOption.linearType == 'custom'){
+      var grd = context.createLinearGradient(centerPosition.x - radius, centerPosition.y, centerPosition.x + radius, centerPosition.y);
+      grd.addColorStop(1, hexToRgb(arcbarOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(0, hexToRgb(eachSeries.color, 1))
+      fillColor = grd;
+    }
+    context.setLineWidth(arcbarOption.width * opts.pix);
+    context.setStrokeStyle(fillColor);
+    context.setLineCap(arcbarOption.lineCap);
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, arcbarOption.direction == 'ccw');
+    context.stroke();
+  }
+  drawRingTitle(opts, config, context, centerPosition);
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawGaugeDataPoints(categories, series, opts, config, context) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var gaugeOption = assign({}, {
+    type: 'default',
+    startAngle: 0.75,
+    endAngle: 0.25,
+    width: 15,
+    labelOffset:13,
+    splitLine: {
+      fixRadius: 0,
+      splitNumber: 10,
+      width: 15,
+      color: '#FFFFFF',
+      childNumber: 5,
+      childWidth: 5
+    },
+    pointer: {
+      width: 15,
+      color: 'auto'
+    }
+  }, opts.extra.gauge);
+  if (gaugeOption.oldAngle == undefined) {
+    gaugeOption.oldAngle = gaugeOption.startAngle;
+  }
+  if (gaugeOption.oldData == undefined) {
+    gaugeOption.oldData = 0;
+  }
+  categories = getGaugeAxisPoints(categories, gaugeOption.startAngle, gaugeOption.endAngle);
+  var centerPosition = {
+    x: opts.width / 2,
+    y: opts.height / 2
+  };
+  var radius = Math.min(centerPosition.x, centerPosition.y);
+  radius -= 5 * opts.pix;
+  radius -= gaugeOption.width / 2;
+  radius = radius < 10 ? 10 : radius;
+  var innerRadius = radius - gaugeOption.width;
+  var totalAngle = 0;
+  //判断仪表盘的样式:default百度样式,progress新样式
+  if (gaugeOption.type == 'progress') {
+    //## 第一步画中心圆形背景和进度条背景
+    //中心圆形背景
+    var pieRadius = radius - gaugeOption.width * 3;
+    context.beginPath();
+    let gradient = context.createLinearGradient(centerPosition.x, centerPosition.y - pieRadius, centerPosition.x, centerPosition.y + pieRadius);
+    //配置渐变填充(起点:中心点向上减半径;结束点中心点向下加半径)
+    gradient.addColorStop('0', hexToRgb(series[0].color, 0.3));
+    gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+    context.setFillStyle(gradient);
+    context.arc(centerPosition.x, centerPosition.y, pieRadius, 0, 2 * Math.PI, false);
+    context.fill();
+    //画进度条背景
+    context.setLineWidth(gaugeOption.width);
+    context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+    context.setLineCap('round');
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, gaugeOption.endAngle * Math.PI, false);
+    context.stroke();
+    //## 第二步画刻度线
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+    let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+    let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+    let endX = -radius - gaugeOption.width - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    let len = gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1;
+    let proc = series[0].data * process;
+    for (let i = 0; i < len; i++) {
+      context.beginPath();
+      //刻度线随进度变色
+      if (proc > (i / len)) {
+        context.setStrokeStyle(hexToRgb(series[0].color, 1));
+      } else {
+        context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+      }
+      context.setLineWidth(3 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(endX, 0);
+      context.stroke();
+      context.rotate(childAngle * Math.PI);
+    }
+    context.restore();
+    //## 第三步画进度条
+    series = getGaugeArcbarDataPoints(series, gaugeOption, process);
+    context.setLineWidth(gaugeOption.width);
+    context.setStrokeStyle(series[0].color);
+    context.setLineCap('round');
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, series[0]._proportion_ * Math.PI, false);
+    context.stroke();
+    //## 第四步画指针
+    let pointerRadius = radius - gaugeOption.width * 2.5;
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((series[0]._proportion_ - 1) * Math.PI);
+    context.beginPath();
+    context.setLineWidth(gaugeOption.width / 3);
+    let gradient3 = context.createLinearGradient(0, -pointerRadius * 0.6, 0, pointerRadius * 0.6);
+    gradient3.addColorStop('0', hexToRgb('#FFFFFF', 0));
+    gradient3.addColorStop('0.5', hexToRgb(series[0].color, 1));
+    gradient3.addColorStop('1.0', hexToRgb('#FFFFFF', 0));
+    context.setStrokeStyle(gradient3);
+    context.arc(0, 0, pointerRadius, 0.85 * Math.PI, 1.15 * Math.PI, false);
+    context.stroke();
+    context.beginPath();
+    context.setLineWidth(1);
+    context.setStrokeStyle(series[0].color);
+    context.setFillStyle(series[0].color);
+    context.moveTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2 - 4, 0);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, 4);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+    context.stroke();
+    context.fill();
+    context.restore();
+    //default百度样式
+  } else {
+    //画背景
+    context.setLineWidth(gaugeOption.width);
+    context.setLineCap('butt');
+    for (let i = 0; i < categories.length; i++) {
+      let eachCategories = categories[i];
+      context.beginPath();
+      context.setStrokeStyle(eachCategories.color);
+      context.arc(centerPosition.x, centerPosition.y, radius, eachCategories._startAngle_ * Math.PI, eachCategories._endAngle_ * Math.PI, false);
+      context.stroke();
+    }
+    context.save();
+    //画刻度线
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+    let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+    let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+    let endX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+    let childendX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.childWidth;
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+      context.beginPath();
+      context.setStrokeStyle(gaugeOption.splitLine.color);
+      context.setLineWidth(2 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(endX, 0);
+      context.stroke();
+      context.rotate(splitAngle * Math.PI);
+    }
+    context.restore();
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    for (let i = 0; i < gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; i++) {
+      context.beginPath();
+      context.setStrokeStyle(gaugeOption.splitLine.color);
+      context.setLineWidth(1 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(childendX, 0);
+      context.stroke();
+      context.rotate(childAngle * Math.PI);
+    }
+    context.restore();
+    //画指针
+    series = getGaugeDataPoints(series, categories, gaugeOption, process);
+    for (let i = 0; i < series.length; i++) {
+      let eachSeries = series[i];
+      context.save();
+      context.translate(centerPosition.x, centerPosition.y);
+      context.rotate((eachSeries._proportion_ - 1) * Math.PI);
+      context.beginPath();
+      context.setFillStyle(eachSeries.color);
+      context.moveTo(gaugeOption.pointer.width, 0);
+      context.lineTo(0, -gaugeOption.pointer.width / 2);
+      context.lineTo(-innerRadius, 0);
+      context.lineTo(0, gaugeOption.pointer.width / 2);
+      context.lineTo(gaugeOption.pointer.width, 0);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFillStyle('#FFFFFF');
+      context.arc(0, 0, gaugeOption.pointer.width / 6, 0, 2 * Math.PI, false);
+      context.fill();
+      context.restore();
+    }
+    if (opts.dataLabel !== false) {
+      drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context);
+    }
+  }
+  //画仪表盘标题,副标题
+  drawRingTitle(opts, config, context, centerPosition);
+  if (process === 1 && opts.type === 'gauge') {
+    opts.extra.gauge.oldAngle = series[0]._proportion_;
+    opts.extra.gauge.oldData = series[0].data;
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    innerRadius: innerRadius,
+    categories: categories,
+    totalAngle: totalAngle
+  };
+}
+
+function drawRadarDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var radarOption = assign({}, {
+    gridColor: '#cccccc',
+    gridType: 'radar',
+    gridEval:1,
+    axisLabel:false,
+    axisLabelTofix:0,
+    labelShow:true,
+    labelColor:'#666666',
+    labelPointShow:false,
+    labelPointRadius:3,
+    labelPointColor:'#cccccc',
+    opacity: 0.2,
+    gridCount: 3,
+    border:false,
+    borderWidth:2,
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.radar);
+  var coordinateAngle = getRadarCoordinateSeries(opts.categories.length);
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  var xr = (opts.width - opts.area[1] - opts.area[3]) / 2
+  var yr = (opts.height - opts.area[0] - opts.area[2]) / 2
+  var radius = Math.min(xr - (getMaxTextListLength(opts.categories, config.fontSize, context) + config.radarLabelTextMargin), yr - config.radarLabelTextMargin);
+  radius -= config.radarLabelTextMargin * opts.pix;
+  radius = radius < 10 ? 10 : radius;
+  radius = radarOption.radius ? radarOption.radius : radius;
+  // 画分割线
+  context.beginPath();
+  context.setLineWidth(1 * opts.pix);
+  context.setStrokeStyle(radarOption.gridColor);
+  coordinateAngle.forEach(function(angle,index) {
+    var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    if (index % radarOption.gridEval == 0) {
+      context.lineTo(pos.x, pos.y);
+    }
+  });
+  context.stroke();
+  context.closePath();
+  
+  // 画背景网格
+  var _loop = function _loop(i) {
+    var startPos = {};
+    context.beginPath();
+    context.setLineWidth(1 * opts.pix);
+    context.setStrokeStyle(radarOption.gridColor);
+    if (radarOption.gridType == 'radar') {
+      coordinateAngle.forEach(function(angle, index) {
+        var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(angle), radius /
+          radarOption.gridCount * i * Math.sin(angle), centerPosition);
+        if (index === 0) {
+          startPos = pos;
+          context.moveTo(pos.x, pos.y);
+        } else {
+          context.lineTo(pos.x, pos.y);
+        }
+      });
+      context.lineTo(startPos.x, startPos.y);
+    } else {
+      var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(1.5), radius / radarOption.gridCount * i * Math.sin(1.5), centerPosition);
+      context.arc(centerPosition.x, centerPosition.y, centerPosition.y - pos.y, 0, 2 * Math.PI, false);
+    }
+    context.stroke();
+    context.closePath();
+  };
+  for (var i = 1; i <= radarOption.gridCount; i++) {
+    _loop(i);
+  }
+  radarOption.customColor = fillCustomColor(radarOption.linearType, radarOption.customColor, series, config);
+  var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process);
+  radarDataPoints.forEach(function(eachSeries, seriesIndex) {
+    // 绘制区域数据
+    context.beginPath();
+    context.setLineWidth(radarOption.borderWidth * opts.pix);
+    context.setStrokeStyle(eachSeries.color);
+    
+    var fillcolor = hexToRgb(eachSeries.color, radarOption.opacity);
+    if (radarOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, radius)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, radius)
+      }
+      grd.addColorStop(0, hexToRgb(radarOption.customColor[series[seriesIndex].linearIndex], radarOption.opacity))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, radarOption.opacity))
+      fillcolor = grd
+    }
+    
+    context.setFillStyle(fillcolor);
+    eachSeries.data.forEach(function(item, index) {
+      if (index === 0) {
+        context.moveTo(item.position.x, item.position.y);
+      } else {
+        context.lineTo(item.position.x, item.position.y);
+      }
+    });
+    context.closePath();
+    context.fill();
+    if(radarOption.border === true){
+      context.stroke();
+    }
+    context.closePath();
+    if (opts.dataPointShape !== false) {
+      var points = eachSeries.data.map(function(item) {
+        return item.position;
+      });
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+  });
+  // 画刻度值
+  if(radarOption.axisLabel === true){
+    const maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
+    const stepLength = radius / radarOption.gridCount;
+    const fontSize = opts.fontSize * opts.pix;
+    context.setFontSize(fontSize);
+    context.setFillStyle(opts.fontColor);
+    context.setTextAlign('left');
+    for (var i = 0; i < radarOption.gridCount + 1; i++) {
+      let label = i * maxData / radarOption.gridCount;
+      label = label.toFixed(radarOption.axisLabelTofix);
+      context.fillText(String(label), centerPosition.x + 3 * opts.pix, centerPosition.y - i * stepLength + fontSize / 2);
+    }
+  }
+  
+  // draw label text
+  drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context);
+  
+  // draw dataLabel
+  if (opts.dataLabel !== false && process === 1) {
+    radarDataPoints.forEach(function(eachSeries, seriesIndex) {
+      context.beginPath();
+      var fontSize = eachSeries.textSize * opts.pix || config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(eachSeries.textColor || opts.fontColor);
+      eachSeries.data.forEach(function(item, index) {
+        //如果是中心点垂直的上下点位
+        if(Math.abs(item.position.x - centerPosition.x)<2){
+          //如果在上面
+          if(item.position.y < centerPosition.y){
+            context.setTextAlign('center');
+            context.fillText(item.value, item.position.x, item.position.y - 4);
+          }else{
+            context.setTextAlign('center');
+            context.fillText(item.value, item.position.x, item.position.y + fontSize + 2);
+          }
+        }else{
+          //如果在左侧
+          if(item.position.x < centerPosition.x){
+            context.setTextAlign('right');
+            context.fillText(item.value, item.position.x - 4, item.position.y + fontSize / 2 - 2);
+          }else{
+            context.setTextAlign('left');
+            context.fillText(item.value, item.position.x + 4, item.position.y + fontSize / 2 - 2);
+          }
+        }
+      });
+      context.closePath();
+      context.stroke();
+    });
+    context.setTextAlign('left');
+  }
+  
+  return {
+    center: centerPosition,
+    radius: radius,
+    angleList: coordinateAngle
+  };
+}
+
+// 经纬度转墨卡托
+function lonlat2mercator(longitude, latitude) {
+  var mercator = Array(2);
+  var x = longitude * 20037508.34 / 180;
+  var y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180);
+  y = y * 20037508.34 / 180;
+  mercator[0] = x;
+  mercator[1] = y;
+  return mercator;
+}
+
+// 墨卡托转经纬度
+function mercator2lonlat(longitude, latitude) {
+  var lonlat = Array(2)
+  var x = longitude / 20037508.34 * 180;
+  var y = latitude / 20037508.34 * 180;
+  y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
+  lonlat[0] = x;
+  lonlat[1] = y;
+  return lonlat;
+}
+
+function getBoundingBox(data) {
+  var bounds = {},coords;
+  bounds.xMin = 180;
+  bounds.xMax = 0;
+  bounds.yMin = 90;
+  bounds.yMax = 0
+  for (var i = 0; i < data.length; i++) {
+    var coorda = data[i].geometry.coordinates
+    for (var k = 0; k < coorda.length; k++) {
+      coords = coorda[k];
+      if (coords.length == 1) {
+        coords = coords[0]
+      }
+      for (var j = 0; j < coords.length; j++) {
+        var longitude = coords[j][0];
+        var latitude = coords[j][1];
+        var point = {
+          x: longitude,
+          y: latitude
+        }
+        bounds.xMin = bounds.xMin < point.x ? bounds.xMin : point.x;
+        bounds.xMax = bounds.xMax > point.x ? bounds.xMax : point.x;
+        bounds.yMin = bounds.yMin < point.y ? bounds.yMin : point.y;
+        bounds.yMax = bounds.yMax > point.y ? bounds.yMax : point.y;
+      }
+    }
+  }
+  return bounds;
+}
+
+function coordinateToPoint(latitude, longitude, bounds, scale, xoffset, yoffset) {
+  return {
+    x: (longitude - bounds.xMin) * scale + xoffset,
+    y: (bounds.yMax - latitude) * scale + yoffset
+  };
+}
+
+function pointToCoordinate(pointY, pointX, bounds, scale, xoffset, yoffset) {
+  return {
+    x: (pointX - xoffset) / scale + bounds.xMin,
+    y: bounds.yMax - (pointY - yoffset) / scale
+  };
+}
+
+function isRayIntersectsSegment(poi, s_poi, e_poi) {
+  if (s_poi[1] == e_poi[1]) {
+    return false;
+  }
+  if (s_poi[1] > poi[1] && e_poi[1] > poi[1]) {
+    return false;
+  }
+  if (s_poi[1] < poi[1] && e_poi[1] < poi[1]) {
+    return false;
+  }
+  if (s_poi[1] == poi[1] && e_poi[1] > poi[1]) {
+    return false;
+  }
+  if (e_poi[1] == poi[1] && s_poi[1] > poi[1]) {
+    return false;
+  }
+  if (s_poi[0] < poi[0] && e_poi[1] < poi[1]) {
+    return false;
+  }
+  let xseg = e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]);
+  if (xseg < poi[0]) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+function isPoiWithinPoly(poi, poly, mercator) {
+  let sinsc = 0;
+  for (let i = 0; i < poly.length; i++) {
+    let epoly = poly[i][0];
+    if (poly.length == 1) {
+      epoly = poly[i][0]
+    }
+    for (let j = 0; j < epoly.length - 1; j++) {
+      let s_poi = epoly[j];
+      let e_poi = epoly[j + 1];
+      if (mercator) {
+        s_poi = lonlat2mercator(epoly[j][0], epoly[j][1]);
+        e_poi = lonlat2mercator(epoly[j + 1][0], epoly[j + 1][1]);
+      }
+      if (isRayIntersectsSegment(poi, s_poi, e_poi)) {
+        sinsc += 1;
+      }
+    }
+  }
+  if (sinsc % 2 == 1) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+function drawMapDataPoints(series, opts, config, context) {
+  var mapOption = assign({}, {
+    border: true,
+    mercator: false,
+    borderWidth: 1,
+    active:true,
+    borderColor: '#666666',
+    fillOpacity: 0.6,
+    activeBorderColor: '#f04864',
+    activeFillColor: '#facc14',
+    activeFillOpacity: 1
+  }, opts.extra.map);
+  var coords, point;
+  var data = series;
+  var bounds = getBoundingBox(data);
+  if (mapOption.mercator) {
+    var max = lonlat2mercator(bounds.xMax, bounds.yMax)
+    var min = lonlat2mercator(bounds.xMin, bounds.yMin)
+    bounds.xMax = max[0]
+    bounds.yMax = max[1]
+    bounds.xMin = min[0]
+    bounds.yMin = min[1]
+  }
+  var xScale = opts.width / Math.abs(bounds.xMax - bounds.xMin);
+  var yScale = opts.height / Math.abs(bounds.yMax - bounds.yMin);
+  var scale = xScale < yScale ? xScale : yScale;
+  var xoffset = opts.width / 2 - Math.abs(bounds.xMax - bounds.xMin) / 2 * scale;
+  var yoffset = opts.height / 2 - Math.abs(bounds.yMax - bounds.yMin) / 2 * scale;
+  for (var i = 0; i < data.length; i++) {
+    context.beginPath();
+    context.setLineWidth(mapOption.borderWidth * opts.pix);
+    context.setStrokeStyle(mapOption.borderColor);
+    context.setFillStyle(hexToRgb(series[i].color, series[i].fillOpacity||mapOption.fillOpacity));
+    if (mapOption.active == true && opts.tooltip) {
+      if (opts.tooltip.index == i) {
+        context.setStrokeStyle(mapOption.activeBorderColor);
+        context.setFillStyle(hexToRgb(mapOption.activeFillColor, mapOption.activeFillOpacity));
+      }
+    }
+    var coorda = data[i].geometry.coordinates
+    for (var k = 0; k < coorda.length; k++) {
+      coords = coorda[k];
+      if (coords.length == 1) {
+        coords = coords[0]
+      }
+      for (var j = 0; j < coords.length; j++) {
+        var gaosi = Array(2);
+        if (mapOption.mercator) {
+          gaosi = lonlat2mercator(coords[j][0], coords[j][1])
+        } else {
+          gaosi = coords[j]
+        }
+        point = coordinateToPoint(gaosi[1], gaosi[0], bounds, scale, xoffset, yoffset)
+        if (j === 0) {
+          context.beginPath();
+          context.moveTo(point.x, point.y);
+        } else {
+          context.lineTo(point.x, point.y);
+        }
+      }
+      context.fill();
+      if (mapOption.border == true) {
+        context.stroke();
+      }
+    }
+  }
+  if (opts.dataLabel == true) {
+    for (var i = 0; i < data.length; i++) {
+      var centerPoint = data[i].properties.centroid;
+      if (centerPoint) {
+        if (mapOption.mercator) {
+          centerPoint = lonlat2mercator(data[i].properties.centroid[0], data[i].properties.centroid[1])
+        }
+        point = coordinateToPoint(centerPoint[1], centerPoint[0], bounds, scale, xoffset, yoffset);
+        let fontSize = data[i].textSize * opts.pix || config.fontSize;
+        let fontColor = data[i].textColor || opts.fontColor;
+        if(mapOption.active && mapOption.activeTextColor && opts.tooltip && opts.tooltip.index == i){
+          fontColor = mapOption.activeTextColor;
+        }
+        let text = data[i].properties.name;
+        context.beginPath();
+        context.setFontSize(fontSize)
+        context.setFillStyle(fontColor)
+        context.fillText(text, point.x - measureText(text, fontSize, context) / 2, point.y + fontSize / 2);
+        context.closePath();
+        context.stroke();
+      }
+    }
+  }
+  opts.chartData.mapData = {
+    bounds: bounds,
+    scale: scale,
+    xoffset: xoffset,
+    yoffset: yoffset,
+    mercator: mapOption.mercator
+  }
+  drawToolTipBridge(opts, config, context, 1);
+  context.draw();
+}
+
+function normalInt(min, max, iter) {
+  iter = iter == 0 ? 1 : iter;
+  var arr = [];
+  for (var i = 0; i < iter; i++) {
+    arr[i] = Math.random();
+  };
+  return Math.floor(arr.reduce(function(i, j) {
+    return i + j
+  }) / iter * (max - min)) + min;
+};
+
+function collisionNew(area, points, width, height) {
+  var isIn = false;
+  for (let i = 0; i < points.length; i++) {
+    if (points[i].area) {
+      if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i].area[0]) {
+        if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) {
+          isIn = true;
+          break;
+        } else {
+          isIn = false;
+        }
+      } else {
+        isIn = true;
+        break;
+      }
+    }
+  }
+  return isIn;
+};
+
+function getWordCloudPoint(opts, type, context) {
+  let points = opts.series;
+  switch (type) {
+    case 'normal':
+      for (let i = 0; i < points.length; i++) {
+        let text = points[i].name;
+        let tHeight = points[i].textSize * opts.pix;
+        let tWidth = measureText(text, tHeight, context);
+        let x, y;
+        let area;
+        let breaknum = 0;
+        while (true) {
+          breaknum++;
+          x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+          y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+          area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 +
+            opts.height / 2
+          ];
+          let isCollision = collisionNew(area, points, opts.width, opts.height);
+          if (!isCollision) break;
+          if (breaknum == 1000) {
+            area = [-100, -100, -100, -100];
+            break;
+          }
+        };
+        points[i].area = area;
+      }
+      break;
+    case 'vertical':
+      function Spin() {
+        //获取均匀随机值,是否旋转,旋转的概率为(1-0.5)
+        if (Math.random() > 0.7) {
+          return true;
+        } else {
+          return false
+        };
+      };
+      for (let i = 0; i < points.length; i++) {
+        let text = points[i].name;
+        let tHeight = points[i].textSize * opts.pix;
+        let tWidth = measureText(text, tHeight, context);
+        let isSpin = Spin();
+        let x, y, area, areav;
+        let breaknum = 0;
+        while (true) {
+          breaknum++;
+          let isCollision;
+          if (isSpin) {
+            x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+            y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+            area = [y - 5 - tWidth + opts.width / 2, (-x - 5 + opts.height / 2), y + 5 + opts.width / 2, (-x + tHeight + 5 + opts.height / 2)];
+            areav = [opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) - 5, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) - 5, opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) + tHeight, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) + tWidth + 5];
+            isCollision = collisionNew(areav, points, opts.height, opts.width);
+          } else {
+            x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+            y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+            area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + opts.height / 2];
+            isCollision = collisionNew(area, points, opts.width, opts.height);
+          }
+          if (!isCollision) break;
+          if (breaknum == 1000) {
+            area = [-1000, -1000, -1000, -1000];
+            break;
+          }
+        };
+        if (isSpin) {
+          points[i].area = areav;
+          points[i].areav = area;
+        } else {
+          points[i].area = area;
+        }
+        points[i].rotate = isSpin;
+      };
+      break;
+  }
+  return points;
+}
+
+function drawWordCloudDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let wordOption = assign({}, {
+    type: 'normal',
+    autoColors: true
+  }, opts.extra.word);
+  if (!opts.chartData.wordCloudData) {
+    opts.chartData.wordCloudData = getWordCloudPoint(opts, wordOption.type, context);
+  }
+  context.beginPath();
+  context.setFillStyle(opts.background);
+  context.rect(0, 0, opts.width, opts.height);
+  context.fill();
+  context.save();
+  let points = opts.chartData.wordCloudData;
+  context.translate(opts.width / 2, opts.height / 2);
+  for (let i = 0; i < points.length; i++) {
+    context.save();
+    if (points[i].rotate) {
+      context.rotate(90 * Math.PI / 180);
+    }
+    let text = points[i].name;
+    let tHeight = points[i].textSize * opts.pix;
+    let tWidth = measureText(text, tHeight, context);
+    context.beginPath();
+    context.setStrokeStyle(points[i].color);
+    context.setFillStyle(points[i].color);
+    context.setFontSize(tHeight);
+    if (points[i].rotate) {
+      if (points[i].areav[0] > 0) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.strokeText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+          } else {
+            context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+          }
+        } else {
+          context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+        }
+      }
+    } else {
+      if (points[i].area[0] > 0) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.strokeText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+          } else {
+            context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+          }
+        } else {
+          context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+        }
+      }
+    }
+    context.stroke();
+    context.restore();
+  }
+  context.restore();
+}
+
+function drawFunnelDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let funnelOption = assign({}, {
+    type:'funnel',
+    activeWidth: 10,
+    activeOpacity: 0.3,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    fillOpacity: 1,
+    minSize: 0,
+    labelAlign: 'right',
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.funnel);
+  let eachSpacing = (opts.height - opts.area[0] - opts.area[2]) / series.length;
+  let centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.height - opts.area[2]
+  };
+  let activeWidth = funnelOption.activeWidth * opts.pix;
+  let radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - activeWidth, (opts.height - opts.area[0] - opts.area[2]) / 2 - activeWidth);
+  let seriesNew = getFunnelDataPoints(series, radius, funnelOption, eachSpacing, process);
+  context.save();
+  context.translate(centerPosition.x, centerPosition.y);
+  funnelOption.customColor = fillCustomColor(funnelOption.linearType, funnelOption.customColor, series, config);
+  if(funnelOption.type == 'pyramid'){
+    for (let i = 0; i < seriesNew.length; i++) {
+      if (i == seriesNew.length -1) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(-activeWidth, -eachSpacing);
+            context.lineTo(-seriesNew[i].radius - activeWidth, 0);
+            context.lineTo(seriesNew[i].radius + activeWidth, 0);
+            context.lineTo(activeWidth, -eachSpacing);
+            context.lineTo(-activeWidth, -eachSpacing);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, -eachSpacing);
+        context.lineTo(-seriesNew[i].radius, 0);
+        context.lineTo(seriesNew[i].radius, 0);
+        context.lineTo(0, -eachSpacing);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      } else {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(0, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, 0);
+            context.lineTo(-seriesNew[i + 1].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i + 1].radius + activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, 0);
+            context.lineTo(0, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-seriesNew[i].radius, 0);
+        context.lineTo(-seriesNew[i + 1].radius, -eachSpacing);
+        context.lineTo(seriesNew[i + 1].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      }
+      context.translate(0, -eachSpacing)
+    }
+  }else{
+    context.translate(0, - (seriesNew.length - 1) * eachSpacing);
+    for (let i = 0; i < seriesNew.length; i++) {
+      if (i == seriesNew.length - 1) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(-activeWidth - funnelOption.minSize/2, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing);
+            context.lineTo(activeWidth + funnelOption.minSize/2, 0);
+            context.lineTo(-activeWidth - funnelOption.minSize/2, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing, centerPosition.x + seriesNew[i].radius, centerPosition.y ];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-funnelOption.minSize/2, 0);
+        context.lineTo(-seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, -eachSpacing);
+        context.lineTo(funnelOption.minSize/2, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      } else {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(0, 0);
+            context.lineTo(-seriesNew[i + 1].radius - activeWidth, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i + 1].radius + activeWidth, 0);
+            context.lineTo(0, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i - 1)];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-seriesNew[i + 1].radius, 0);
+        context.lineTo(-seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i + 1].radius, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      }
+      context.translate(0, eachSpacing)
+    }
+  }
+  
+  context.restore();
+  if (opts.dataLabel !== false && process === 1) {
+    drawFunnelText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition);
+  }
+  if (process === 1) {
+    drawFunnelCenterText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: seriesNew
+  };
+}
+
+function drawFunnelText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) {
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    if(item.labelShow === false){
+      continue;
+    }
+    let startX, endX, startY, fontSize;
+    let text = item.formatter ? item.formatter(item,i,series,opts) : util.toFixed(item._proportion_ * 100) + '%';
+    text = item.labelText ? item.labelText : text;
+    if (labelAlign == 'right') {
+      if (i == series.length -1) {
+        startX = (item.funnelArea[2] + centerPosition.x) / 2;
+      } else {
+        startX = (item.funnelArea[2] + series[i + 1].funnelArea[2]) / 2;
+      }
+      endX = startX + activeWidth * 2;
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix;
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.color);
+      context.setFillStyle(item.color);
+      context.beginPath();
+      context.moveTo(startX, startY);
+      context.lineTo(endX, startY);
+      context.stroke();
+      context.closePath();
+      context.beginPath();
+      context.moveTo(endX, startY);
+      context.arc(endX, startY, 2 * opts.pix, 0, 2 * Math.PI);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.textColor || opts.fontColor);
+      context.fillText(text, endX + 5, startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+    if (labelAlign == 'left') {
+      if (i == series.length -1) {
+        startX = (item.funnelArea[0] + centerPosition.x) / 2;
+      } else {
+        startX = (item.funnelArea[0] + series[i + 1].funnelArea[0]) / 2;
+      }
+      endX = startX - activeWidth * 2;
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix;
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.color);
+      context.setFillStyle(item.color);
+      context.beginPath();
+      context.moveTo(startX, startY);
+      context.lineTo(endX, startY);
+      context.stroke();
+      context.closePath();
+      context.beginPath();
+      context.moveTo(endX, startY);
+      context.arc(endX, startY, 2, 0, 2 * Math.PI);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.textColor || opts.fontColor);
+      context.fillText(text, endX - 5 - measureText(text, fontSize, context), startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+  }
+}
+
+function drawFunnelCenterText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) {
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    let startY, fontSize;
+    if (item.centerText) {
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.centerTextSize * opts.pix || opts.fontSize * opts.pix;
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.centerTextColor || "#FFFFFF");
+      context.fillText(item.centerText, centerPosition.x - measureText(item.centerText, fontSize, context) / 2, startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+  }
+}
+
+
+function drawCanvas(opts, context) {
+  context.save();
+  context.translate(0, 0.5);
+  context.restore();
+  context.draw();
+}
+
+var Timing = {
+  easeIn: function easeIn(pos) {
+    return Math.pow(pos, 3);
+  },
+  easeOut: function easeOut(pos) {
+    return Math.pow(pos - 1, 3) + 1;
+  },
+  easeInOut: function easeInOut(pos) {
+    if ((pos /= 0.5) < 1) {
+      return 0.5 * Math.pow(pos, 3);
+    } else {
+      return 0.5 * (Math.pow(pos - 2, 3) + 2);
+    }
+  },
+  linear: function linear(pos) {
+    return pos;
+  }
+};
+
+function Animation(opts) {
+  this.isStop = false;
+  opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
+  opts.timing = opts.timing || 'easeInOut';
+  var delay = 17;
+  function createAnimationFrame() {
+    if (typeof setTimeout !== 'undefined') {
+      return function(step, delay) {
+        setTimeout(function() {
+          var timeStamp = +new Date();
+          step(timeStamp);
+        }, delay);
+      };
+    } else if (typeof requestAnimationFrame !== 'undefined') {
+      return requestAnimationFrame;
+    } else {
+      return function(step) {
+        step(null);
+      };
+    }
+  };
+  var animationFrame = createAnimationFrame();
+  var startTimeStamp = null;
+  var _step = function step(timestamp) {
+    if (timestamp === null || this.isStop === true) {
+      opts.onProcess && opts.onProcess(1);
+      opts.onAnimationFinish && opts.onAnimationFinish();
+      return;
+    }
+    if (startTimeStamp === null) {
+      startTimeStamp = timestamp;
+    }
+    if (timestamp - startTimeStamp < opts.duration) {
+      var process = (timestamp - startTimeStamp) / opts.duration;
+      var timingFunction = Timing[opts.timing];
+      process = timingFunction(process);
+      opts.onProcess && opts.onProcess(process);
+      animationFrame(_step, delay);
+    } else {
+      opts.onProcess && opts.onProcess(1);
+      opts.onAnimationFinish && opts.onAnimationFinish();
+    }
+  };
+  _step = _step.bind(this);
+  animationFrame(_step, delay);
+}
+
+Animation.prototype.stop = function() {
+  this.isStop = true;
+};
+
+function drawCharts(type, opts, config, context) {
+  var _this = this;
+  var series = opts.series;
+  //兼容ECharts饼图类数据格式
+  if (type === 'pie' || type === 'ring' || type === 'mount' || type === 'rose' || type === 'funnel') {
+    series = fixPieSeries(series, opts, config);
+  }
+  var categories = opts.categories;
+  if (type === 'mount') {
+    categories = [];
+    for (let j = 0; j < series.length; j++) {
+      if(series[j].show !== false) categories.push(series[j].name)
+    }
+    opts.categories = categories;
+  }
+  series = fillSeries(series, opts, config);
+  var duration = opts.animation ? opts.duration : 0;
+  _this.animationInstance && _this.animationInstance.stop();
+  var seriesMA = null;
+  if (type == 'candle') {
+    let average = assign({}, opts.extra.candle.average);
+    if (average.show) {
+      seriesMA = calCandleMA(average.day, average.name, average.color, series[0].data);
+      seriesMA = fillSeries(seriesMA, opts, config);
+      opts.seriesMA = seriesMA;
+    } else if (opts.seriesMA) {
+      seriesMA = opts.seriesMA = fillSeries(opts.seriesMA, opts, config);
+    } else {
+      seriesMA = series;
+    }
+  } else {
+    seriesMA = series;
+  }
+  /* 过滤掉show=false的series */
+  opts._series_ = series = filterSeries(series);
+  //重新计算图表区域
+  opts.area = new Array(4);
+  //复位绘图区域
+  for (let j = 0; j < 4; j++) {
+    opts.area[j] = opts.padding[j] * opts.pix;
+  }
+  //通过计算三大区域:图例、X轴、Y轴的大小,确定绘图区域
+  var _calLegendData = calLegendData(seriesMA, opts, config, opts.chartData, context),
+    legendHeight = _calLegendData.area.wholeHeight,
+    legendWidth = _calLegendData.area.wholeWidth;
+
+  switch (opts.legend.position) {
+    case 'top':
+      opts.area[0] += legendHeight;
+      break;
+    case 'bottom':
+      opts.area[2] += legendHeight;
+      break;
+    case 'left':
+      opts.area[3] += legendWidth;
+      break;
+    case 'right':
+      opts.area[1] += legendWidth;
+      break;
+  }
+
+  let _calYAxisData = {},
+    yAxisWidth = 0;
+  if (opts.type === 'line' || opts.type === 'column'|| opts.type === 'mount' || opts.type === 'area' || opts.type === 'mix' || opts.type === 'candle' || opts.type === 'scatter'  || opts.type === 'bubble' || opts.type === 'bar') {
+      _calYAxisData = calYAxisData(series, opts, config, context);
+      yAxisWidth = _calYAxisData.yAxisWidth;
+    //如果显示Y轴标题
+    if (opts.yAxis.showTitle) {
+      let maxTitleHeight = 0;
+      for (let i = 0; i < opts.yAxis.data.length; i++) {
+        maxTitleHeight = Math.max(maxTitleHeight, opts.yAxis.data[i].titleFontSize ? opts.yAxis.data[i].titleFontSize * opts.pix : config.fontSize)
+      }
+      opts.area[0] += maxTitleHeight;
+    }
+    let rightIndex = 0,
+      leftIndex = 0;
+    //计算主绘图区域左右位置
+    for (let i = 0; i < yAxisWidth.length; i++) {
+      if (yAxisWidth[i].position == 'left') {
+        if (leftIndex > 0) {
+          opts.area[3] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix;
+        } else {
+          opts.area[3] += yAxisWidth[i].width;
+        }
+        leftIndex += 1;
+      } else if (yAxisWidth[i].position == 'right') {
+        if (rightIndex > 0) {
+          opts.area[1] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix;
+        } else {
+          opts.area[1] += yAxisWidth[i].width;
+        }
+        rightIndex += 1;
+      }
+    }
+  } else {
+    config.yAxisWidth = yAxisWidth;
+  }
+  opts.chartData.yAxisData = _calYAxisData;
+
+  if (opts.categories && opts.categories.length && opts.type !== 'radar' && opts.type !== 'gauge' && opts.type !== 'bar') {
+    opts.chartData.xAxisData = getXAxisPoints(opts.categories, opts, config);
+    let _calCategoriesData = calCategoriesData(opts.categories, opts, config, opts.chartData.xAxisData.eachSpacing, context),
+      xAxisHeight = _calCategoriesData.xAxisHeight,
+      angle = _calCategoriesData.angle;
+    config.xAxisHeight = xAxisHeight;
+    config._xAxisTextAngle_ = angle;
+    opts.area[2] += xAxisHeight;
+    opts.chartData.categoriesData = _calCategoriesData;
+  } else {
+    if (opts.type === 'line' || opts.type === 'area' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') {
+      opts.chartData.xAxisData = calXAxisData(series, opts, config, context);
+      categories = opts.chartData.xAxisData.rangesFormat;
+      let _calCategoriesData = calCategoriesData(categories, opts, config, opts.chartData.xAxisData.eachSpacing, context),
+        xAxisHeight = _calCategoriesData.xAxisHeight,
+        angle = _calCategoriesData.angle;
+      config.xAxisHeight = xAxisHeight;
+      config._xAxisTextAngle_ = angle;
+      opts.area[2] += xAxisHeight;
+      opts.chartData.categoriesData = _calCategoriesData;
+    } else {
+      opts.chartData.xAxisData = {
+        xAxisPoints: []
+      };
+    }
+  }
+
+  //计算右对齐偏移距离
+  if (opts.enableScroll && opts.xAxis.scrollAlign == 'right' && opts._scrollDistance_ === undefined) {
+    let offsetLeft = 0,
+      xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+      startX = opts.chartData.xAxisData.startX,
+      endX = opts.chartData.xAxisData.endX,
+      eachSpacing = opts.chartData.xAxisData.eachSpacing;
+    let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+    let screenWidth = endX - startX;
+    offsetLeft = screenWidth - totalWidth;
+    _this.scrollOption.currentOffset = offsetLeft;
+    _this.scrollOption.startTouchX = offsetLeft;
+    _this.scrollOption.distance = 0;
+    _this.scrollOption.lastMoveTime = 0;
+    opts._scrollDistance_ = offsetLeft;
+  }
+
+  if (type === 'pie' || type === 'ring' || type === 'rose') {
+    config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(seriesMA, config, context, opts);
+  }
+  
+  switch (type) {
+    case 'word':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawWordCloudDataPoints(series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'map':
+      context.clearRect(0, 0, opts.width, opts.height);
+      drawMapDataPoints(series, opts, config, context);
+      setTimeout(()=>{
+        this.uevent.trigger('renderComplete');
+      },50)
+      break;
+    case 'funnel':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.funnelData = drawFunnelDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'line':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawLineDataPoints.xAxisPoints,
+            calPoints = _drawLineDataPoints.calPoints,
+            eachSpacing = _drawLineDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'scatter':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawScatterDataPoints = drawScatterDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawScatterDataPoints.xAxisPoints,
+            calPoints = _drawScatterDataPoints.calPoints,
+            eachSpacing = _drawScatterDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'bubble':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawBubbleDataPoints = drawBubbleDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawBubbleDataPoints.xAxisPoints,
+            calPoints = _drawBubbleDataPoints.calPoints,
+            eachSpacing = _drawBubbleDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'mix':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawMixDataPoints = drawMixDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawMixDataPoints.xAxisPoints,
+            calPoints = _drawMixDataPoints.calPoints,
+            eachSpacing = _drawMixDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'column':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawColumnDataPoints.xAxisPoints,
+            calPoints = _drawColumnDataPoints.calPoints,
+            eachSpacing = _drawColumnDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'mount':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawMountDataPoints = drawMountDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawMountDataPoints.xAxisPoints,
+            calPoints = _drawMountDataPoints.calPoints,
+            eachSpacing = _drawMountDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'bar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawXAxis(categories, opts, config, context);
+          var _drawBarDataPoints = drawBarDataPoints(series, opts, config, context, process),
+            yAxisPoints = _drawBarDataPoints.yAxisPoints,
+            calPoints = _drawBarDataPoints.calPoints,
+            eachSpacing = _drawBarDataPoints.eachSpacing;
+          opts.chartData.yAxisPoints = yAxisPoints;
+          opts.chartData.xAxisPoints = opts.chartData.xAxisData.xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, yAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'area':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawAreaDataPoints.xAxisPoints,
+            calPoints = _drawAreaDataPoints.calPoints,
+            eachSpacing = _drawAreaDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'ring':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'pie':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'rose':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawRoseDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'radar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'arcbar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.arcbarData = drawArcbarDataPoints(series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'gauge':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.gaugeData = drawGaugeDataPoints(categories, series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'candle':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawCandleDataPoints = drawCandleDataPoints(series, seriesMA, opts, config, context, process),
+            xAxisPoints = _drawCandleDataPoints.xAxisPoints,
+            calPoints = _drawCandleDataPoints.calPoints,
+            eachSpacing = _drawCandleDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          if (seriesMA) {
+            drawLegend(seriesMA, opts, config, context, opts.chartData);
+          } else {
+            drawLegend(opts.series, opts, config, context, opts.chartData);
+          }
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+  }
+}
+
+function uChartsEvent() {
+  this.events = {};
+}
+
+uChartsEvent.prototype.addEventListener = function(type, listener) {
+  this.events[type] = this.events[type] || [];
+  this.events[type].push(listener);
+};
+
+uChartsEvent.prototype.delEventListener = function(type) {
+  this.events[type] = [];
+};
+
+uChartsEvent.prototype.trigger = function() {
+  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+    args[_key] = arguments[_key];
+  }
+  var type = args[0];
+  var params = args.slice(1);
+  if (!!this.events[type]) {
+    this.events[type].forEach(function(listener) {
+      try {
+        listener.apply(null, params);
+      } catch (e) {
+          //console.log('[uCharts] '+e);
+      }
+    });
+  }
+};
+
+var uCharts = function uCharts(opts) {
+  opts.pix = opts.pixelRatio ? opts.pixelRatio : 1;
+  opts.fontSize = opts.fontSize ? opts.fontSize : 13;
+  opts.fontColor = opts.fontColor ? opts.fontColor : config.fontColor;
+  if (opts.background == "" || opts.background == "none") {
+    opts.background = "#FFFFFF"
+  }
+  opts.title = assign({}, opts.title);
+  opts.subtitle = assign({}, opts.subtitle);
+  opts.duration = opts.duration ? opts.duration : 1000;
+  opts.yAxis = assign({}, {
+    data: [],
+    showTitle: false,
+    disabled: false,
+    disableGrid: false,
+    gridSet: 'number',
+    splitNumber: 5,
+    gridType: 'solid',
+    dashLength: 4 * opts.pix,
+    gridColor: '#cccccc',
+    padding: 10,
+    fontColor: '#666666'
+  }, opts.yAxis);
+  opts.xAxis = assign({}, {
+    rotateLabel: false,
+    rotateAngle:45,
+    disabled: false,
+    disableGrid: false,
+    splitNumber: 5,
+    calibration:false,
+    fontColor: '#666666',
+    fontSize: 13,
+    lineHeight: 20,
+    marginTop: 0,
+    gridType: 'solid',
+    dashLength: 4,
+    scrollAlign: 'left',
+    boundaryGap: 'center',
+    axisLine: true,
+    axisLineColor: '#cccccc',
+    titleFontSize: 13,
+    titleOffsetY: 0,
+    titleOffsetX: 0,
+    titleFontColor: '#666666'
+  }, opts.xAxis);
+  opts.xAxis.scrollPosition = opts.xAxis.scrollAlign;
+  opts.legend = assign({}, {
+    show: true,
+    position: 'bottom',
+    float: 'center',
+    backgroundColor: 'rgba(0,0,0,0)',
+    borderColor: 'rgba(0,0,0,0)',
+    borderWidth: 0,
+    padding: 5,
+    margin: 5,
+    itemGap: 10,
+    fontSize: opts.fontSize,
+    lineHeight: opts.fontSize,
+    fontColor: opts.fontColor,
+    formatter: {},
+    hiddenColor: '#CECECE'
+  }, opts.legend);
+  opts.extra = assign({
+    tooltip:{
+      legendShape: 'auto'
+    }
+  }, opts.extra);
+  opts.rotate = opts.rotate ? true : false;
+  opts.animation = opts.animation ? true : false;
+  opts.rotate = opts.rotate ? true : false;
+  opts.canvas2d = opts.canvas2d ? true : false;
+  
+  let config$$1 = assign({}, config);
+  config$$1.color = opts.color ? opts.color : config$$1.color;
+  if (opts.type == 'pie') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  if (opts.type == 'ring') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.ring.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  if (opts.type == 'rose') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pix;
+
+  //屏幕旋转
+  config$$1.rotate = opts.rotate;
+  if (opts.rotate) {
+    let tempWidth = opts.width;
+    let tempHeight = opts.height;
+    opts.width = tempHeight;
+    opts.height = tempWidth;
+  }
+
+  //适配高分屏
+  opts.padding = opts.padding ? opts.padding : config$$1.padding;
+  config$$1.yAxisWidth = config.yAxisWidth * opts.pix;
+  config$$1.fontSize = opts.fontSize * opts.pix;
+  config$$1.titleFontSize = config.titleFontSize * opts.pix;
+  config$$1.subtitleFontSize = config.subtitleFontSize * opts.pix;
+  if(!opts.context){
+    throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!');
+  }
+  this.context = opts.context;
+  if (!this.context.setTextAlign) {
+    this.context.setStrokeStyle = function(e) {
+      return this.strokeStyle = e;
+    }
+    this.context.setLineWidth = function(e) {
+      return this.lineWidth = e;
+    }
+    this.context.setLineCap = function(e) {
+      return this.lineCap = e;
+    }
+    this.context.setFontSize = function(e) {
+      return this.font = e + "px sans-serif";
+    }
+    this.context.setFillStyle = function(e) {
+      return this.fillStyle = e;
+    }
+    this.context.setTextAlign = function(e) {
+      return this.textAlign = e;
+    }
+    this.context.setTextBaseline = function(e) {
+      return this.textBaseline = e;
+    }
+    this.context.setShadow = function(offsetX,offsetY,blur,color) {
+      this.shadowColor = color;
+      this.shadowOffsetX = offsetX;
+      this.shadowOffsetY = offsetY;
+      this.shadowBlur = blur;
+    }
+    this.context.draw = function() {}
+  }
+  //兼容NVUEsetLineDash
+  if(!this.context.setLineDash){
+    this.context.setLineDash = function(e) {}
+  }
+  opts.chartData = {};
+  this.uevent = new uChartsEvent();
+  this.scrollOption = {
+    currentOffset: 0,
+    startTouchX: 0,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  this.opts = opts;
+  this.config = config$$1;
+  drawCharts.call(this, opts.type, opts, config$$1, this.context);
+};
+
+uCharts.prototype.updateData = function() {
+  let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  this.opts = assign({}, this.opts, data);
+  this.opts.updateData = true;
+  let scrollPosition = data.scrollPosition || 'current';
+  switch (scrollPosition) {
+    case 'current':
+      this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+      break;
+    case 'left':
+      this.opts._scrollDistance_ = 0;
+      this.scrollOption = {
+        currentOffset: 0,
+        startTouchX: 0,
+        distance: 0,
+        lastMoveTime: 0
+      };
+      break;
+    case 'right':
+      let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context), yAxisWidth = _calYAxisData.yAxisWidth;
+      this.config.yAxisWidth = yAxisWidth;
+      let offsetLeft = 0;
+      let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config), xAxisPoints = _getXAxisPoints0.xAxisPoints,
+        startX = _getXAxisPoints0.startX,
+        endX = _getXAxisPoints0.endX,
+        eachSpacing = _getXAxisPoints0.eachSpacing;
+      let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+      let screenWidth = endX - startX;
+      offsetLeft = screenWidth - totalWidth;
+      this.scrollOption = {
+        currentOffset: offsetLeft,
+        startTouchX: offsetLeft,
+        distance: 0,
+        lastMoveTime: 0
+      };
+      this.opts._scrollDistance_ = offsetLeft;
+      break;
+  }
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+uCharts.prototype.zoom = function() {
+  var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.opts.xAxis.itemCount;
+  if (this.opts.enableScroll !== true) {
+    console.log('[uCharts] 请启用滚动条后使用')
+    return;
+  }
+  //当前屏幕中间点
+  let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.opts.chartData.eachSpacing) + Math.round(this.opts.xAxis.itemCount / 2);
+  this.opts.animation = false;
+  this.opts.xAxis.itemCount = val.itemCount;
+  //重新计算x轴偏移距离
+  let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context),
+    yAxisWidth = _calYAxisData.yAxisWidth;
+  this.config.yAxisWidth = yAxisWidth;
+  let offsetLeft = 0;
+  let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+    xAxisPoints = _getXAxisPoints0.xAxisPoints,
+    startX = _getXAxisPoints0.startX,
+    endX = _getXAxisPoints0.endX,
+    eachSpacing = _getXAxisPoints0.eachSpacing;
+  let centerLeft = eachSpacing * centerPoint;
+  let screenWidth = endX - startX;
+  let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
+  offsetLeft = screenWidth / 2 - centerLeft;
+  if (offsetLeft > 0) {
+    offsetLeft = 0;
+  }
+  if (offsetLeft < MaxLeft) {
+    offsetLeft = MaxLeft;
+  }
+  this.scrollOption = {
+    currentOffset: offsetLeft,
+    startTouchX: 0,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
+  this.opts._scrollDistance_ = offsetLeft;
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+uCharts.prototype.dobuleZoom = function(e) {
+  if (this.opts.enableScroll !== true) {
+    console.log('[uCharts] 请启用滚动条后使用')
+    return;
+  }
+  const tcs = e.changedTouches;
+  if (tcs.length < 2) {
+    return;
+  }
+  for (var i = 0; i < tcs.length; i++) {
+    tcs[i].x = tcs[i].x ? tcs[i].x : tcs[i].clientX;
+    tcs[i].y = tcs[i].y ? tcs[i].y : tcs[i].clientY;
+  }
+  const ntcs = [getTouches(tcs[0], this.opts, e),getTouches(tcs[1], this.opts, e)]; 
+  const xlength = Math.abs(ntcs[0].x - ntcs[1].x);
+  // 记录初始的两指之间的数据
+  if(!this.scrollOption.moveCount){
+    let cts0 = {changedTouches:[{x:tcs[0].x,y:this.opts.area[0] / this.opts.pix + 2}]};
+    let cts1 = {changedTouches:[{x:tcs[1].x,y:this.opts.area[0] / this.opts.pix + 2}]};
+    if(this.opts.rotate){
+      cts0 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[0].y}]};
+      cts1 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[1].y}]};
+    }
+    const moveCurrent1 = this.getCurrentDataIndex(cts0).index;
+    const moveCurrent2 = this.getCurrentDataIndex(cts1).index;
+    const moveCount = Math.abs(moveCurrent1 - moveCurrent2);
+    this.scrollOption.moveCount = moveCount;
+    this.scrollOption.moveCurrent1 = Math.min(moveCurrent1, moveCurrent2);
+    this.scrollOption.moveCurrent2 = Math.max(moveCurrent1, moveCurrent2);
+    return;
+  }
+  
+  let currentEachSpacing = xlength / this.scrollOption.moveCount;
+  let itemCount = (this.opts.width - this.opts.area[1] - this.opts.area[3]) / currentEachSpacing;
+  itemCount = itemCount <= 2 ? 2 : itemCount;
+  itemCount = itemCount >= this.opts.categories.length ? this.opts.categories.length : itemCount;
+  this.opts.animation = false;
+  this.opts.xAxis.itemCount = itemCount;
+  // 重新计算滚动条偏移距离
+  let offsetLeft = 0;
+  let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+    xAxisPoints = _getXAxisPoints0.xAxisPoints,
+    startX = _getXAxisPoints0.startX,
+    endX = _getXAxisPoints0.endX,
+    eachSpacing = _getXAxisPoints0.eachSpacing;
+  let currentLeft = eachSpacing * this.scrollOption.moveCurrent1;
+  let screenWidth = endX - startX;
+  let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
+  offsetLeft = -currentLeft+Math.min(ntcs[0].x,ntcs[1].x)-this.opts.area[3]-eachSpacing;
+  if (offsetLeft > 0) {
+    offsetLeft = 0;
+  }
+  if (offsetLeft < MaxLeft) {
+    offsetLeft = MaxLeft;
+  }
+  this.scrollOption.currentOffset= offsetLeft;
+  this.scrollOption.startTouchX= 0;
+  this.scrollOption.distance=0;
+  calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
+  this.opts._scrollDistance_ = offsetLeft;
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+}
+
+uCharts.prototype.stopAnimation = function() {
+  this.animationInstance && this.animationInstance.stop();
+};
+
+uCharts.prototype.addEventListener = function(type, listener) {
+  this.uevent.addEventListener(type, listener);
+};
+
+uCharts.prototype.delEventListener = function(type) {
+  this.uevent.delEventListener(type);
+};
+
+uCharts.prototype.getCurrentDataIndex = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    let _touches$ = getTouches(touches, this.opts, e);
+    if (this.opts.type === 'pie' || this.opts.type === 'ring') {
+      return findPieChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.pieData, this.opts);
+    } else if (this.opts.type === 'rose') {
+      return findRoseChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.pieData, this.opts);
+    } else if (this.opts.type === 'radar') {
+      return findRadarChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.radarData, this.opts.categories.length);
+    } else if (this.opts.type === 'funnel') {
+      return findFunnelChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.funnelData);
+    } else if (this.opts.type === 'map') {
+      return findMapChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts);
+    } else if (this.opts.type === 'word') {
+      return findWordChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.wordCloudData);
+    } else if (this.opts.type === 'bar') {
+      return findBarChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
+    } else {
+      return findCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
+    }
+  }
+  return -1;
+};
+
+uCharts.prototype.getLegendDataIndex = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    let _touches$ = getTouches(touches, this.opts, e);
+    return findLegendIndex({
+      x: _touches$.x,
+      y: _touches$.y
+    }, this.opts.chartData.legendData);
+  }
+  return -1;
+};
+
+uCharts.prototype.touchLegend = function(e) {
+  var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    var _touches$ = getTouches(touches, this.opts, e);
+    var index = this.getLegendDataIndex(e);
+    if (index >= 0) {
+      if (this.opts.type == 'candle') {
+        this.opts.seriesMA[index].show = !this.opts.seriesMA[index].show;
+      } else {
+        this.opts.series[index].show = !this.opts.series[index].show;
+      }
+      this.opts.animation = option.animation ? true : false;
+      this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+      drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+    }
+  }
+
+};
+
+uCharts.prototype.showToolTip = function(e) {
+  var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (!touches) {
+    console.log("[uCharts] 未获取到event坐标信息");
+  }
+  var _touches$ = getTouches(touches, this.opts, e);
+  var currentOffset = this.scrollOption.currentOffset;
+  var opts = assign({}, this.opts, {
+    _scrollDistance_: currentOffset,
+    animation: false
+  });
+  if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column' || this.opts.type === 'scatter' || this.opts.type === 'bubble') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1 || index.length>0) {
+      var seriesData = getSeriesDataItem(this.opts.series, index, current.group);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList !== undefined ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index,
+          group: current.group
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'mount') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e).index : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, opts._series_[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: opts.chartData.calPoints[index].x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'bar') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1 || index.length>0) {
+      var seriesData = getSeriesDataItem(this.opts.series, index, current.group);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.x = _touches$.x;
+        opts.tooltip = {
+          textList: option.textList !== undefined ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'mix') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1) {
+      var currentOffset = this.scrollOption.currentOffset;
+      var opts = assign({}, this.opts, {
+        _scrollDistance_: currentOffset,
+        animation: false
+      });
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var _getMixToolTipData = getMixToolTipData(seriesData, this.opts, index, this.opts.categories, option),
+          textList = _getMixToolTipData.textList,
+          offset = _getMixToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'candle') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1) {
+      var currentOffset = this.scrollOption.currentOffset;
+      var opts = assign({}, this.opts, {
+        _scrollDistance_: currentOffset,
+        animation: false
+      });
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.opts, index, this.opts.categories, this.opts.extra.candle, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose' || this.opts.type === 'funnel') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, opts._series_[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'map') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, this.opts.series[index]);
+      seriesData.name = seriesData.properties.name
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    opts.updateData = false;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'word') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, this.opts.series[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    opts.updateData = false;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'radar') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var textList = seriesData.map((item) => {
+          return {
+            text: option.formatter ? option.formatter(item, this.opts.categories[index], index, this.opts) : item.name + ': ' + item.data,
+            color: item.color,
+            legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? item.legendShape : this.opts.extra.tooltip.legendShape
+          };
+        });
+        var offset = {
+          x: _touches$.x,
+          y: _touches$.y
+        };
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+};
+
+uCharts.prototype.translate = function(distance) {
+  this.scrollOption = {
+    currentOffset: distance,
+    startTouchX: distance,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  let opts = assign({}, this.opts, {
+    _scrollDistance_: distance,
+    animation: false
+  });
+  drawCharts.call(this, this.opts.type, opts, this.config, this.context);
+};
+
+uCharts.prototype.scrollStart = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  var _touches$ = getTouches(touches, this.opts, e);
+  if (touches && this.opts.enableScroll === true) {
+    this.scrollOption.startTouchX = _touches$.x;
+  }
+};
+
+uCharts.prototype.scroll = function(e) {
+  if (this.scrollOption.lastMoveTime === 0) {
+    this.scrollOption.lastMoveTime = Date.now();
+  }
+  let Limit = this.opts.touchMoveLimit || 60;
+  let currMoveTime = Date.now();
+  let duration = currMoveTime - this.scrollOption.lastMoveTime;
+  if (duration < Math.floor(1000 / Limit)) return;
+  if (this.scrollOption.startTouchX == 0) return;
+  this.scrollOption.lastMoveTime = currMoveTime;
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches && this.opts.enableScroll === true) {
+    var _touches$ = getTouches(touches, this.opts, e);
+    var _distance;
+    _distance = _touches$.x - this.scrollOption.startTouchX;
+    var currentOffset = this.scrollOption.currentOffset;
+    var validDistance = calValidDistance(this, currentOffset + _distance, this.opts.chartData, this.config, this.opts);
+    this.scrollOption.distance = _distance = validDistance - currentOffset;
+    var opts = assign({}, this.opts, {
+      _scrollDistance_: currentOffset + _distance,
+      animation: false
+    });
+		this.opts = opts;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+    return currentOffset + _distance;
+  }
+};
+
+uCharts.prototype.scrollEnd = function(e) {
+  if (this.opts.enableScroll === true) {
+    var _scrollOption = this.scrollOption,
+      currentOffset = _scrollOption.currentOffset,
+      distance = _scrollOption.distance;
+    this.scrollOption.currentOffset = currentOffset + distance;
+    this.scrollOption.distance = 0;
+    this.scrollOption.moveCount = 0;
+  }
+};
+
+export default uCharts;

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.