微信小程序使用ucharts时遇到的一些坑及其解决方案(持续更新)

Posted 莫诺库诺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序使用ucharts时遇到的一些坑及其解决方案(持续更新)相关的知识,希望对你有一定的参考价值。

前言

新项目是一个微信小程序,由于未来有跨端的可能,且为了降低开发成本,于是选择了uni-app框架进行小程序的开发。
项目需求在小程序上显示各种图表,web端使用的是功能的强大的echarts,但由于官方并没有专门的移动端版本(有和微信团队一起开发的微信版,但无法跨端),虽然网上有各种个人适配版,但或多或少都有一些问题。
因此综合考虑,最后选型的结果是使用专为uni-app适配的移动端图表插件ucharts。
ucharts方面这里就不多介绍了,本文主要记录在使用过程中遇到的各种坑。
本文使用ucharts的方式为组件工具
另外,其实有一些问题官方文档是有提供相应的解决方案的,而且提供的在线配置工具也能很方便的看到调整后的效果,当然这是收费的,30块一年,100块终身。收费这个事我就不多评论了,仁者见仁智者见智,毕竟单纯只是用的话是不收费的,为了开发便利,我还是暂且先开了一年。

1. uchats开启canvas2d后,渲染位置出错的问题。

先说结论:模拟器和实机的环境不同,模拟器上出现位置问题不用理会,真机上是正常的。

canvas2d接口拥有更好的性能,并且支持同层渲染。ucharts中开启canvas2d的方法为在组件的props中加入:canvas2d="true"

<qiun-data-charts :type="chartsShowType" :chartData="chartsData" :opts="opts" :ontouch="true" :canvas2d="true" :canvasId="canvasId" />

需要注意的是,在开启canvas2d后,必须要传入canvasId,并且canvasId一般为随机字符串,不能是数字开头。这里的id可以用随机生成字符串的方法生成。(但其实ucharts官方在组件内部内置了随机生成id的方法,即使你不传canvasId,内部也会自动生成,这节省了一些麻烦,如果不是有特殊需求的话,直接不传也可以)

开启该接口后,在微信开发工具中的模拟器中,图表的定位发生了问题:

好家伙,这能看?于是尝试各种改样式,统统无效。
后来通过查阅资料得知,小程序的canvas在开启2d模式后,因为模拟器的环境和实机环境的差异,ucharts的图表在模拟器上会出现穿透问题,但真机是正常的。由于小程序最终还是要运行在真机上的,因此建议无视模拟器上的穿透问题即可。需要在模拟器上看调整的结果时,可以暂时将2d模式关闭,要真机看效果时再加上。

2. 用scroll-view包裹后,提示窗位置不对的问题。

如果有要在同一个垂直显示多个图表的需求的情况下,自然需要用到scroll-view组件来实现垂直滚动,但是在使用scroll-view包裹封装好的ucharts组件后,会发现点击图表时的判定点会出现问题,明明点击线条却点到下面的图例去了……
这里官方文档提供了解决方法,如果你用的是原生方式绘图的话,那么需要自己动手去校正坐标了:

如果遇到不显示tooltip或者显示位置不正确的情况,可能是canvas外层包裹了sroll-view或swiper或父元素采用fixed定位导致touch事件的event错乱。解决方法:将错误的event坐标处理回正确的点击坐标,需要在event中加上或减去部分的x,y坐标,具体数值可以通过去掉外层包裹和没有去掉外层包裹打印出来的event计算得出

但如果你用的是组件方式,那么官方已经把封装好的属性inScrollView提供给你了,直接使用即可解决问题,
非常省事:

<qiun-data-charts :type="chartsShowType" :chartData="chartsData" 
	:opts="opts":ontouch="true" :canvasId="canvasId" :inScrollView="true"/>

3. 折线图图例的线宽太长,想要改小点怎么办?

默认折线图的图例线宽是这样的:

图例有点太长了,现在有需求要改小点,但是官方文档里并有提供对应的接口,怎么办?还能怎么办,只能去改源码了。
找到并打开ucharts插件目录下的u-charts.js文件,全局搜索图例绘制方法function drawLegend,并跳转到switch (item.legendShape)这一片段:

      switch (item.legendShape) 
        case 'line':
          context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
          context.fillRect(startX, startY + 0.5 * lineHeight - 4 * opts.pix + 1, 10 * opts.pix, 6 * 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);
      

可以看出来,这段代码就是根据图类型来绘制图例的,那么case 'line'就是折线图,我们再看moveTo()fillRect()方法,其实直接改矩形填充方法fillRect()的第三个参数width就可以了,但如果只改这里的话,图例的位置会有点歪,所以起始点也需要调整,调整前后的代码如下:
调整前

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);

调整后

context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
context.fillRect(startX, startY + 0.5 * lineHeight - 4 * opts.pix + 1, 10 * opts.pix, 6 * opts.pix);

具体调多少可以根据自己的需求慢慢去调。

4. 图例的位置放到图表上面后,X轴文字显示不全(开启了旋转)以及图例被数据文字覆盖的问题

问题现象如下图所示,这个很好改,直接通过设置修改边距即可,下面的代码设置仅供参考,具体数值可以自己去试。

opts: 
	padding: [15,10,5,15], // 画布填充边距[上,右,下,左],Array格式,修改前为[15,10,0,15]
    legend: 
    	margin: 10, // 图例外侧填充边距,默认为5
    

修改之后:

另外在这里补充一下改变图例相对于图表位置的方法,下面以将图例放置于上方为例(其实官方文档里是有写的):

opts: 
	legend: 
		position: "top"
	

5.ucharts加入动态切换图表类型

实在没有想到的是,ucharts居然不支持动态切换图表类型……
所以没办法又只能自己去改源码了。
由于opts和chartsData是可以动态更新的,通过官方文档中的指南可知,动态更新通过watch选项实现,因此打开qiun-data-charts.vue,跳转到watch选项的optsProps这一段:

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
,

其中的关键代码是this.checkData(this.drawData);,这是用来重绘图表的。想要动态改变类型,那么久需要监听改变类型的属性type,由于传入的值是字符串,因此判断一下前后的值是否一致就行了。代码如下:

type: 
	hanlder(val, oldval) 
		if (val !== oldval) 
			this.checkData(this.drawData);
		
	

此时便可实现动态切换图表类型了。如果你想加一些判断或是别的需求,那么以此为基础改就可以了。

P.S: 如果上面的代码无效,可以尝试下面的写法:

type(val, oldval) 
	if (val !== oldval) 
		this.checkData(this.drawData);
	

两种写法其实是一样的,但不知道为何第一种写法会存在不生效的情况。

6. ucharts图表无法横向拖动

按照官方文档的介绍,开启横向拖动需要设置以下两点:

  • opts.enableScroll=true;
opts: 
	enableScroll: true

  • 在组件上将ontouch设为true
 <qiun-data-charts 
   type="column"
   :opts="opts"
   :chartData="chartData"
   :ontouch="true"
 />

设置完运行之后,发现虽然滚动条出现了,模拟器上也可以正常拖动,但是真机调试却无论如何都无法拖动。
如果你也出现这种情况,那么多半是因为在组件外部套上了scroll-view视图容器,如果是这样的话,可以尝试在scroll-view容器上将属性scroll-x设为true,应该能解决这个问题。

<scroll-view scroll-x="true"></scroll-view>

7.加入图表横屏展示的功能

由于手机屏幕宽度的限制,当数据量较大时,观看体验并不是很好,因此横屏展示的功能就显得必要了,还好ucharts官方提供了横屏展示的功能,可以免去自己手改的麻烦,不过在实现的时候还是需要注意一些地方。
详情参见:使用ucharts在小程序中加入图表横屏展示的功能

8. ucharts如何加入图例下拉显示/左右滚动的功能

在数据的项目比较多的时候,图例显示的也会很多,由于移动设备的屏幕比较小,且默认是竖屏观看,这样会导致下面的图表被压的很厉害,如下图所示(图片中间有个奇怪的箭头,暂且无视)

一个比较好的办法就是加入图例下拉显示/左右滚动的功能,由于这一块牵扯的东西比较多,相对而言难度也比较大,因此之后会单独写一篇博文详细的阐述解决思路和具体的代码,然后链接在此处。这里先做一个预告。

uniapp使用图表

目录

一、各图表在uniapp微信小程序中的bug

秋云ucharts:

echarts:

二、使用秋云ucharts

三、使用小程序echarts(echarts-for-wx)

四、各图表遇到的问题以及应用

1、解决echarts.js文件过大的问题

2、ucharts横屏显示(秋云原生)

3、点击ucharts,图表横屏显示

4、小程序echarts横屏显示

5、[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!


一、各图表在uniapp微信小程序中的bug

秋云ucharts:

1、使用的是秋云ucharts(注意此插件和scroll-view不可以同时使用,不然会出现图表随滚动条滚动的情况)

2、开启滚动条后图表两侧有白边问题——此问题是因为组件上的 background 为默认的 rgba(0,0,0,0) 透明色或者没有指定导致,请在组件上加入background="rgba(0,0,0,1)"(您的背景色)。如果父元素为图片,尽量不要开启滚动条,此时图表是透明色,可以显示父元素背景图片。

3、没有图表标记就只有实心和空心两个,不能自定义图片

echarts:

1、tooltip使用extraCssText: 'transform: rotate(90deg)',进行旋转无效

二、使用秋云ucharts

 官网地址:https://www.ucharts.cn/v2/#/

方法一:使用uni_modules版本

步骤:

1、在插件库搜索echarts,选择秋云ucharts,点击使用HBuilder导入插件

2、直接在页面使用

<qiun-data-charts type="column" :canvas2d="true" :opts="opts" :chartData="chartData" :ontouch="true" />
data() 
			return 
				chartData: ,
				opts: 
					color: ["#FAC858", "#EE6666", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4",
						"#ea7ccc"
					],
					padding: [10, 10, 0, 5],
					touchMoveLimit: 24,
					enableScroll: true, //开启滚动条
					legend: ,
					xAxis: 
						disableGrid: true,
						scrollShow: false, //滚动条不显示
						itemCount: 5 //图表可视区显示的X轴数据点数量,仅在启用enableScroll时有效
					,
					yAxis: 
						data: [
							min: 0
						]
					,
					extra: 
						column: 
							type: "group",
							width: 20,
							activeBgColor: "#000000",
							activeBgOpacity: 0.08,
							linearType: "custom",
							seriesGap: 3,
							linearOpacity: 0.5,
							barBorderCircle: true,
							customColor: [
								"#FA7D8D",
								"#EB88E2"
							]
						
					
				,
			;
		,
onReady() 
	this.getServerData();
,
		methods: 
			getServerData() 
				//模拟从服务器获取数据时的延时
				setTimeout(() => 
					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
					let res = 
						categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
						series: [
								name: "目标值",
								data: [35, 36, 31, 33, 13, 34]
							,
							
								name: "完成量",
								data: [18, 27, 21, 24, 6, 28]
							
						]
					;
					this.chartData = JSON.parse(JSON.stringify(res));
				, 500);
			,
		

方法二:非uni_modules版本

这种方式其实就是把 qiun-data-charts 当成我们自己写的组件一样,按照 定义 -》引入 -》注册 -》使用 四步走方式导入。

在官网——指南——组件方式——非uni_modules版本

 

 以上是已经把使用说明中的是三个文件删除了,若是不想删除,就使用示例项目——组件——非uni-modlues——components下所有文件

然后修改qiun-data-charts的vue文件中的路径

 在所需页面引入组件并使用组件

<template>
	<view class="container">
		<qiun-data-charts type="column" :canvas2d="true" :opts="opts" :chartData="chartData" :ontouch="true" />
	</view>
</template>

<script>
	export default 
		data() 
			return 
				chartData: ,
				opts: 
					color: ["#FAC858", "#EE6666", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4",
						"#ea7ccc"
					],
					padding: [10, 0, 0, 0],
					dataLabel: false,
					dataPointShapeType: 'hollow',
					touchMoveLimit: 24,
					enableScroll: true, //开启滚动条
					scrollShow: false, //滚动条不显示
					legend: ,
					xAxis: 
						disableGrid: true,
						itemCount: 5 //图表可视区显示的X轴数据点数量,仅在启用enableScroll时有效
					,
					yAxis: 
						data: [
							min: 0
						]
					,
					extra: 
						column: 
							type: "group",
							width: 20,
							activeBgColor: "#000000",
							activeBgOpacity: 0.08,
							linearType: "custom",
							seriesGap: 3,
							linearOpacity: 0.5,
							barBorderCircle: true,
							customColor: [
								"#FA7D8D",
								"#EB88E2"
							]
						
					
				,
			;
		,
		onReady() 
			this.getServerData();
		,
		methods: 
			getServerData() 
				//模拟从服务器获取数据时的延时
				setTimeout(() => 
					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
					let res = 
						categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
						series: [
								name: "目标值",
								data: [35, 36, 31, 33, 13, 34]
							,
							
								name: "完成量",
								data: [18, 27, 21, 24, 6, 28]
							
						]
					;
					this.chartData = JSON.parse(JSON.stringify(res));
				, 500);
			,
		
	
</script>

<style lang="scss">
	/* 请根据需求修改图表容器尺寸,如果父容器没有高度图表则会显示异常 */
    .charts-box 
      width: 100%;
      height: 320px;
    
</style>

三、使用小程序echarts(echarts-for-wx)

压缩包 :https://github.com/WangXinYu-China/mini_program_echarts

去GitHub下载压缩包,或是插件市场下echarts-for-wx

(1)插件库使用HBuilder导入,生成一个js_sdk目录,将此文件下uni-ec-canvas目录复制到components下即可

(2)在页面中引用

<template>
	<view class="container">
		<view class="tu">
			<uni-ec-canvas class="uni-ec-canvas" id="uni-ec-canvas" ref="uni-ec-canvas" canvas-id="uni-ec-canvas"
				:ec="ec"></uni-ec-canvas>
		</view>
	</view>
</template>

<script>
	import uniEcCanvas from '@/components/uni-ec-canvas/uni-ec-canvas.vue'
    export default 
		components: 
			uniEcCanvas,
		,
        data() 
			return 
				ec: 
					option: 
						grid: 
							left: '13%',
							right: '5%',
							bottom: '15%',
							top: '20%'
						,
						dataZoom: 
							start: 95,
							end: 100,
							type: "inside"
						,
						tooltip: 
							trigger: 'axis',
							axisPointer: 
								type: 'cross',
							,
							// position:[20,20]
						,
						xAxis: 
							type: 'category',
							data: [],
							axisTick: 
								show: true
							,
							boundaryGap: false,
							axisLine: 
								lineStyle:  //改变xy轴线条的颜色
									color: "#9da2af",
									width: 1 //这里是为了突出显示加上的
								
							,
							axisLabel: 
								textStyle:  //改变xy轴上文字的颜色
									color: "#9da2af",
									fontSize: '10',
								
							
						,
						yAxis: 
							type: 'value',
							scale: true, //是否是脱离 0 值比例。设置成 true 后坐标刻度不会强制包含零刻度
							axisLine: 
								show: true
							,
							splitLine:  //网格线
								lineStyle: 
									color: "#9da2af",
									type: 'solid' //设置网格线类型 dotted:虚线 solid:实线
								
							,
							axisTick: 
								show: false
							,
							axisLine: 
								lineStyle:  //改变xy轴线条的颜色
									color: "#9da2af",
									width: 1 //这里是为了突出显示加上的
								
							,
							axisLabel: 
								textStyle:  //改变xy轴上文字的颜色
									color: "#9da2af",
									fontSize: '10',
								
							,
						,
						series: [
							name: '',
							data: [],
							markPoint: 
								data: [
										name: '',
										value: '买',
										coord: [],
										itemStyle: 
											color: 'rgb(255, 1, 5)'
										
									,
									
										name: '',
										value: '卖',
										coord: [],
										itemStyle: 
											color: 'rgb(0, 170, 0)'
										
									,
								],
								symbolSize: 25,
								tooltip: 
									trigger: 'item',
									formatter: function(value) 
										return value.data.coord[0] + '\\n' + value.data.coord[1]
									
								
								// animation:false
							,
							type: 'line',
							smooth: false,
							symbol: 'none',
							itemStyle: 
								normal: 
									color: "#3bb632", //折线点的颜色
									lineStyle: 
										color: "#00f2f1", //折线的颜色
										width: 1
									
								
							,
						, ]
					, //echart 配置项
				,
			
		,
        //onLoad主要配置ec.option.series[0].markPoint.data、ec.option.xAxis.data、ec.option.series[0].data
		onLoad: function(option) 
			const item = JSON.parse(decodeURIComponent(option.item));
			const number = JSON.parse(decodeURIComponent(option.number));
			this.number = number
			this.getreport = item;
			let buy = [];
			let mai = [];
			let orderList = this.getreport.orderList
			// 筛选符合条件的数组  放入到定义的新数组中
			for (let i = 0; i < orderList.length; i++) 
				if (orderList[i].trade_type == 1) 
					buy[buy.length] = orderList[i]
				
				if (orderList[i].trade_type == 0) 
					mai[mai.length] = orderList[i]
				
			
			// 循环遍历数组,将数组加入到coord中
			for (let j = 0; j < buy.length; j++) 
				let obj = 
					name: '',
					value: '买',
					coord: [buy[j].trade_date, buy[j].trade_price],
					itemStyle: 
						color: 'rgb(255, 1, 5)'
					
				
				this.ec.option.series[0].markPoint.data.push(obj)
			
			for (let r = 0; r < mai.length; r++) 
				let obj1 = 
					name: '',
					value: '卖',
					coord: [mai[r].trade_date, mai[r].trade_price],
					itemStyle: 
						color: 'rgb(0, 170, 0)'
					
				
				this.ec.option.series[0].markPoint.data.push(obj1)
			
			// X轴数据
			this.ec.option.xAxis.data = this.getreport.chartsData.chartx
			// Y轴数据
			this.ec.option.series[0].data = this.getreport.chartsData.charty
			// 历史数据
			this.tabData = item.tradeList
		,
    
</script>
<style lang="scss">
	.uni-container 
		height: 100%;
		width: 100%;
	

	.tu 
		width: 100%;
		height: 600rpx;
		// background-color: aqua;
		background-size: 100% 100%;
		margin-top: 2%;
	
</style>

四、各图表遇到的问题以及应用

1、解决echarts.js文件过大的问题

ECharts 在线构建 (apache.org):https://echarts.apache.org/zh/builder.html

去echarts官网自定义构建并下载文件 ,下载的是echarts.min.js文件,将项目中的echarts.js替换成echarts.min.js文件

然后修改文件uni-ec-canvas.vue ,将echarts.js修改成echarts.min.js

 此时会报错,打开echarts.min.js ,搜索报错信息t.addEventListener

在搜索到之后,在 t.addEventListener后面添加 ?.

 若是还是大,则使用分包

2、ucharts横屏显示(秋云原生)

 注意:原生写法级别是最高的

关键的代码:rotate:true,

<template>
	<view class="container">
		<view class="qiun-charts-rotate">
			<canvas canvas-id="canvasColumn" id="canvasColumn" class="charts-rotate" :width="cWidth2*pixelRatio"
				:height="cHeight2*pixelRatio" :style="'width':cWidth2+'px','height':cHeight2+'px'"
				@touchstart="touchColumn"></canvas>
			<canvas canvas-id="canvasColumn" id="canvasColumn" class="charts-rotate" @touchstart="touchColumn"></canvas>
		</view>
	</view>
</template>

<script>
	import uCharts from '@/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js'
	var _self;
	var canvaColumn = null;
	export default 
		data() 
			return 
				cWidth2: '',
				cHeight2: '',
				pixelRatio: 1,
			
		,
		onLoad() 
			_self = this;
			//#ifdef MP-ALIPAY
			uni.getSystemInfo(
				success: function(res) 
					if (res.pixelRatio > 1) 
						//正常这里给2就行,如果pixelRatio=3性能会降低一点
						//_self.pixelRatio =res.pixelRatio;
						_self.pixelRatio = 2;
					
				
			);
			//#endif
			this.cWidth2 = uni.upx2px(700);
			this.cHeight2 = uni.upx2px(1100);
			this.getServerData();
		,
		methods: 
			getServerData() 
				// 使用接口时请将以下4行放入调用接口执行成功后的方法里,并将数据换成接口的数据
				let Column = 
					categories: [],
					series: []
				;
				Column.categories = ['2012', '2013', '2014', '2015', '2016', '2017'];
				Column.series = [
						name: '新成交量3',
						data: [35, 36, 31, 33, 13, 34]
					,
					
						name: '新成交量4',
						data: [18, 27, 21, 24, 6, 28]
					
				];
				_self.showColumn('canvasColumn', Column);
			,
			showColumn(canvasId, chartData) 
				canvaColumn = new uCharts(
					$this: _self,
					canvasId: canvasId,
					context: uni.createCanvasContext(canvasId, _self),
					type: 'column',
					padding: [15, 5, 0, 15],
					legend: 
						show: true,
						padding: 5,
						lineHeight: 11,
						margin: 0
					,
					fontSize: 11,
					background: '#FFFFFF',
					pixelRatio: _self.pixelRatio,
					animation: true,
					rotate: true,
					categories: chartData.categories,
					series: chartData.series,
					xAxis: 
						disableGrid: true
					,
					yAxis: 
						data: [
							position: 'right',
							axisLine: false,
							format: val => 
								return val.toFixed(0) + '元';
							
						]
					,
					dataLabel: true,
					width: _self.cWidth2 * _self.pixelRatio,
					height: _self.cHeight2 * _self.pixelRatio,
					extra: 
						column: 
							type: 'group',
							width: (_self.cWidth2 * _self.pixelRatio * 0.45) / chartData.categories.length
						
					
				);
			,
			touchColumn(e) 
				canvaColumn.showToolTip(e, 
					format: function(item, category) 
						if (typeof item.data === 'object') 
							return category + ' ' + item.name + ':' + item.data.value;
						 else 
							return category + ' ' + item.name + ':' + item.data;
						
					
				);
				canvaColumn.touchLegend(e, 
					animation: true
				);
			,
			changeData() 
				if (isJSON(_self.textarea)) 
					let newdata = JSON.parse(_self.textarea);
					canvaColumn.updateData(
						series: newdata.series,
						categories: newdata.categories,
						animation: true
					);
				 else 
					uni.showToast(
						title: '数据格式错误',
						image: '../../../static/images/alert-warning.png'
					);
				
			
		
	
</script>

<style lang="scss">
	/*样式的width和height一定要与定义的cWidth和cHeight相对应*/
	.qiun-charts-rotate 
		width: 700upx;
		height: 1100upx;
		background-color: #FFFFFF;
		padding: 25upx;
	

	.charts-rotate 
		width: 700upx;
		height: 1100upx;
		background-color: #FFFFFF;
	
</style>

3、点击ucharts,图表横屏显示

<template>
	<view class="container">

		<!-- <qiun-data-charts type="column" :canvas2d="true" :opts="opts" :chartData="chartData" :ontouch="true" /> -->
		<button @click="show" v-if="isFull" class="btn">全屏</button>

		<view v-if="isFull">
			<qiun-data-charts type="column" :canvas2d="true" :opts="opts" :chartData="chartData" :ontouch="true" />
		</view>

		<view v-else class="big">
			<view class="qiun-charts-rotate">
				<qiun-data-charts type="column" :canvas2d="true" :opts="opt" :chartData="chartData" :ontouch="true" />
			</view>
			<view>
				<image class='img' src="../../static/c1.png" @click='close'
					style='width: 20px;height: 20px;margin-left: auto;display:block;'>
			</view>
		</view>
	</view>
</template>

<script>
	import uCharts from '@/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js'
	import echarts from '@/uni_modules/qiun-data-charts/static/app-plus/echarts.min.js'
	var _self;
	var canvaColumn = null;
	export default 
		data() 
			return 
				isFull: true, //遮罩层
				chartData: ,
				opts: 
					color: ["#FAC858", "#EE6666", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4",
						"#ea7ccc"
					],
					padding: [10, 0, 0, 0],
					dataLabel: false,
					dataPointShapeType: 'hollow',
					touchMoveLimit: 24,
					enableScroll: true, //开启滚动条
					scrollShow: false, //滚动条不显示
					legend: ,
					xAxis: 
						disableGrid: true,
						itemCount: 5 //图表可视区显示的X轴数据点数量,仅在启用enableScroll时有效
					,
					yAxis: 
						data: [
							min: 0
						]
					,
					extra: 
						column: 
							type: "group",
							width: 20,
							activeBgColor: "#000000",
							activeBgOpacity: 0.08,
							linearType: "custom",
							seriesGap: 3,
							linearOpacity: 0.5,
							barBorderCircle: true,
							customColor: [
								"#FA7D8D",
								"#EB88E2"
							]
						
					
				,
				// cWidth: 750,
				// cHeight: 500,
				opt: 
					color: ["#FAC858", "#EE6666", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4",
						"#ea7ccc"
					],
					padding: [10, 0, 0, 0],
					dataLabel: false,
					dataPointShapeType: 'hollow',
					touchMoveLimit: 24,
					rotate: true,
					enableScroll: true, //开启滚动条
					scrollShow: false, //滚动条不显示
					legend: ,
					xAxis: 
						disableGrid: true,
						itemCount: 5 //图表可视区显示的X轴数据点数量,仅在启用enableScroll时有效
					,
					yAxis: 
						data: [
							min: 0
						]
					,
					extra: 
						column: 
							type: "group",
							width: 20,
							activeBgColor: "#000000",
							activeBgOpacity: 0.08,
							linearType: "custom",
							seriesGap: 3,
							linearOpacity: 0.5,
							barBorderCircle: true,
							customColor: [
								"#FA7D8D",
								"#EB88E2"
							]
						
					
				,
			
		,
		onReady() 
			this.ServerData();
		,
		methods: 
			ServerData() 
				//模拟从服务器获取数据时的延时
				setTimeout(() => 
					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
					let res = 
						categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
						series: [
								name: "目标值",
								data: [35, 36, 31, 33, 13, 34]
							,
							
								name: "完成量",
								data: [18, 27, 21, 24, 6, 28]
							
						]
					;
					this.chartData = JSON.parse(JSON.stringify(res));
				, 500);
			,
			show() 
				this.isFull = false
			,
			close() 
				this.isFull = true
			,
		
	
</script>

<style lang="scss">
	/*样式的width和height一定要与定义的cWidth和cHeight相对应*/
	.qiun-charts-rotate 
		width: 700upx;
		height: 1100upx;
		background-color: #FFFFFF;
		padding: 25upx;
	

	.charts-rotate 
		width: 700upx;
		height: 1100upx;
		background-color: #FFFFFF;
	


	// 按钮
	.btn 
		width: 200rpx;
		height: 50rpx;
		background-color: aquamarine;
		color: #000;
		line-height: 50rpx;
	


	// 全屏样式
	.big 
		background-color: #FFFFFF;
	

	.img 
		position: relative;
		right: auto;
	
</style>

4、小程序echarts横屏显示

将xAxis与yAxis里面的内容互换,可以横纵切换展示

标注旋转使用series的 symbolRotate,标注里面的字旋转使用series的markPoint的label的rotate

<template>
	<view class="container">
		<view class="tu">
			<uni-ec-canvas class="uni-ec-canvas" id="uni-ec-canvas" ref="uni-ec-canvas" canvas-id="uni-ec-canvas"
				:ec="ec"></uni-ec-canvas>
		</view>
	</view>
</template>
<script>
	import uniEcCanvas from '@/components/uni-ec-canvas/uni-ec-canvas.vue'
	export default 
		components: 
			uniEcCanvas,
		,
		data() 
			return 
				ec: 
					option: 
						tooltip: 
							trigger: 'axis',
							// extraCssText: 'transform: rotate(90deg)',
							formatter: (params) =>  // 提示框浮层内容格式器 以函数的形式修改
								return tipFormatter(params) // 见最底层的函数
							
						,
						dataZoom: [
							//在内部可以纵向拖动
							
								type: 'inside',
								yAxisIndex: [0],
								start: 50,
								end: 100
							
						],
						xAxis: 
							type: 'value', //数据
							position: 'top', //x 轴的位置【top bottom】
							nameRotate: -90, //坐标轴名字旋转,角度值。
							axisLabel:  //坐标轴刻度标签的相关设置。
								rotate: 90 //刻度标签旋转的角度,
							,
							// scale: true, //是否是脱离 0 值比例
						,
						yAxis: 
							type: 'category',
							data: ['2022-1-1', '2022-1-2', '2022-1-3', '2022-1-4', '2022-1-5', '2022-1-6', '2022-1-7',
								'2022-1-8', '2022-1-9',
							],
							inverse: 'true', //是否是反向坐标轴。
							splitLine:  //网格线
								lineStyle: 
									color: "#9da2af",
									type: 'solid' //设置网格线类型 dotted:虚线 solid:实线
								
							,
							axisTick: 
								show: false
							,
							axisLine: 
								lineStyle:  //改变xy轴线条的颜色
									color: "#9da2af",
									width: 1 //这里是为了突出显示加上的
								
							,
							axisLabel: 
								rotate: -90,
								textStyle:  //改变xy轴上文字的颜色
									color: "#9da2af",
									fontSize: '10',
								
							,
						,
						series: [
							name: '',
							type: 'line',
							data: [1, 1.5, 2, 5, 3, 2, 0, 2.5, 3.5],
							symbolSize: 40,
							symbol: "pin",
							symbolRotate: -90,
							markPoint: 
								label: 
									show: true
								,
								data: [
										name: '',
										value: '买',
										coord: [5, 33.4],
										itemStyle: 
											color: 'rgb(255, 1, 5)'
										
									,
									
										name: '',
										value: '卖',
										coord: [5, 30.4],
										itemStyle: 
											color: 'rgb(0, 170, 0)'
										
									,
								],
								tooltip: 
									trigger: 'item',
									formatter: function(value) 
										return value.data.coord[0] + '\\n' + value.data.coord[1]
									
								
							,
							itemStyle: 
								normal: 
									color: "#3bb632", //折线点的颜色
									lineStyle: 
										color: "#00f2f1", //折线的颜色
										width: 1
									
								
							,
						]
					
				,
			
		,
		methods: 
			tipFormatter(params) 
				var name = '上传时间 2019-4-19-14:59:31\\n'; // 悬浮层内容,可自定义
				var name2 = '我是自定义的内容'; // 悬浮层内容,可自定义
				var divWarp = $('<div style="width: 100px;"/>'); // 使用JQ(或原生js) 生成一个dom 外盒子
				var divContent = $(
					'<view style = "backgroundColor: #696969; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); padding: 2px 5px; transform:rotate(90deg);">'
				); // 承载内容的盒子,并给盒子样式
				var p = $('<p>').text(name); // 内容标签, 可以有多个
				var p2 = $('<p>').text(name2); // 内容标签, 可以有多个
				var divFirst = divContent.append(p); // 将 p 加到 divContent
				var divSecond = divContent.append(p2); // 将 p2 加到 divContent
				var view = divWarp.append(divFirst).append(divSecond); // 将内容盒子加到外盒子上
				return view.html(); // 渲染到html 并将结果返回
			
		
	
</script>
<style lang="scss">
	/* 请根据需求修改图表容器尺寸,如果父容器没有高度图表则会显示异常 */
	.tu 
		width: 100%;
		height: 1100upx;
		// background-color: aqua;
		// background-color: aquamarine;
		// background-image: url(@/static/rowbj.png);
		background-size: 100% 100%;
		margin-top: 2%;
	

	.uni-ec-canvas 
		transform: rotate(90);
	
</style>

5、[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!

使用uniapp引入ucharts图表时控制台报错

直接添加一句context:uni.createCanvasContext(canvasId, _self)

​​​​​​​

 

以上是关于微信小程序使用ucharts时遇到的一些坑及其解决方案(持续更新)的主要内容,如果未能解决你的问题,请参考以下文章

一名Android开发者的微信小程序填坑之路

微信小程序的坑(持续更新中)

微信小程序 scroll-view的两个坑

微信小程序wx.request组件的那些坑

网页程序迁移至微信小程序web-view详解

uniapp实战笔记微信小程序设置字体的开发踩坑记录