HQChart使用教程44-uniapp使用条件编译同时支持h5,app,小程序

10 篇文章 3 订阅


今天在群里帮一位朋友排查HQChart同时在多端使用的问题。我整理了以下

背景

由于小程序/app很多局限性(无法创建DOM,canvas异步绘图等)导致HQChart开发的时候分成两个版本(小程序版本和H5页面版本)。
使用条件编译我们可以把这2个版本组件同时包含的工程中,并且通过平台判断动态加载对应版本的js.

通过uniapp下载hqchart插件

安装

插件地址: https://ext.dcloud.net.cn/plugin?id=4591
直接通过HBuilder X就可以安装,一般安装的目录在uni_modules\jones-hqchart2下面

使用

改下import路径就可以,其他不变

// #ifdef H5	
import HQChart from '@/uni_modules/jones-hqchart2/js_sdk/umychart.uniapp.h5.js'
//HQChart.JSChart.SetDomain("xxxxx.com");
//HQChart.JSComplier.SetDomain("xxxx.com");
// #endif

// #ifndef H5
import {JSCommon} from '@/uni_modules/jones-hqchart2/js_sdk/umychart.wechat.3.0.js'
import {JSCommonHQStyle} from '@/uni_modules/jones-hqchart2/js_sdk/umychart.style.wechat.js'
import {JSCommonComplier} from "@/uni_modules/jones-hqchart2/js_sdk/umychart.complier.wechat.js"

//禁用日志
JSConsole.Complier.Log=()=>{ };
JSConsole.Chart.Log=()=>{ };
// #endif

手动安装插件

在工程里建2个目录,把HQChart的2个版本分别考入对应的目录里。
版本对应关系看以前的教程
HQChart使用教程35 - 如何在uni-app创建K线图(h5)
HQChart使用教程37 - 如何在uni-app创建k线图(app)
在这里插入图片描述

template 设置

由于小程序/app是无法动态创建dom,所有只能是先在模板里写死一个画布,在初始化的时候绑定到HQChart中。H5是可以直接内部创建dom,所以只需要传入一个div,HQChart自动会创建画布. 我们使用条件编译在不同的平台使用不同的模板
注意 id的名字尽量使用不一样的,如h5如果使用id=‘kline’ 在app/小程序就使用id=‘kline2’

<!--  #ifdef  H5 -->
<div>
	<div class='kline' id="kline" ref='kline'  v-show="KLine.IsShow"></div>
	<div class='minute' id="minute" ref='minute'  v-show="Minute.IsShow"></div>
</div>
<!--  #endif -->

<!--  #ifndef  H5 -->
<view>
	<canvas id="kline2" canvas-id='kline2' class='kline2' v-bind:style="{width: ChartWidth+'px', height: ChartHeight+'px'}"  v-show="KLine.IsShow"
	  @touchstart="KLineTouchStart" @touchmove='KLineTouchMove' @touchend='KLineTouchEnd' ></canvas>  
	  <canvas id="minute2" canvas-id='minute2' class='minute' v-bind:style="{width: ChartWidth+'px', height: ChartHeight+'px'}" v-show="Minute.IsShow"
	   @touchstart="MinuteTouchStart" @touchmove='MinuteTouchMove' @touchend='MinuteTouchEnd' ></canvas>
</view>
<!--  #endif -->

这样2个模板就同时存在一个页面中了

创建插件设置

为每个平台创建一个创建插件的函数,然后通过一个总的创建函数动态调用对应的创建方法
下面是也创建K线图为例子‘CreateKLineChart_h5()'是h5平台的创建插件方法, 'CreateKLineChart_app()'是app和小程序创建的方法,在"CreateKLineChart()'通过条件编译就可以动态选择使用对应的创建函数
为了代码的可读和可维护性我这边是拆分成2个创建函数,你也可以在CreateKLineChart里面把2个平台的创建都写里面,只过不这样可读性比较差。

CreateKLineChart()
{
	// #ifdef H5
	this.CreateKLineChart_h5();
	// #endif
	
	// #ifndef H5
	this.CreateKLineChart_app();
	// #endif
},

下面是2个平台对应的创建方法,走势图的创建也是一样

CreateKLineChart_h5()  //创建K线图
{
    if (g_KLine.JSChart) return;
    this.KLine.Option.Symbol=this.Symbol;
    let chart=HQChart.JSChart.Init(this.$refs.kline);
this.KLine.Option.NetworkFilter=this.NetworkFilter;
    chart.SetOption(this.KLine.Option);
    g_KLine.JSChart=chart;
},
		
CreateKLineChart_app()
{
	if (this.KLine.JSChart) return;
	
	let element = new JSCommon.JSCanvasElement();
	// #ifdef APP-PLUS
	element.IsUniApp=true;	//canvas需要指定下 是uniapp的app
	// #endif
	element.ID = 'kline2';
	element.Height = this.ChartHeight;  //高度宽度需要手动绑定!!
	element.Width = this.ChartWidth;
			
	g_KLine.JSChart = JSCommon.JSChart.Init(element);
	this.KLine.Option.NetworkFilter=this.NetworkFilter;
	this.KLine.Option.Symbol=this.Symbol;
	g_KLine.JSChart.SetOption(this.KLine.Option);
},

HQChart大小调整

由于app/小程序无法获取dom,所以只能是在外部把画布的长宽设置到HQChart中(动态获取只能通过其他的查询元素函数获取,比较麻烦,关键还是异步的,非常搞不懂获取一个元素信息还使用异步,难道以目前的手机配置查询几千几万了dom信息不能在毫秒级处理完),
H5是可以动态获取dom,就不存在这个文件,改变了外层的div调用HQChart的OnSize()方法就可以动态把div的大小绑定画布上。

OnSize()
{
	// #ifdef H5
	this.OnSize_h5();
	// #endif
},

OnSize_h5()
{
	var chartHeight = this.ChartHeight;
	var chartWidth = this.ChartWidth;
	 
	var kline=this.$refs.kline;
	kline.style.width=chartWidth+'px';
	kline.style.height=chartHeight+'px';
	if (g_KLine.JSChart) g_KLine.JSChart.OnSize();
	
	var minute=this.$refs.minute;
	minute.style.width=chartWidth+'px';
	minute.style.height=chartHeight+'px';
	if (g_Minute.JSChart) g_Minute.JSChart.OnSize();
},

这样多端支持就完成了。点运行,然后喝杯咖啡吧,编译调试真的很慢。

效果图

在这里插入图片描述
在这里插入图片描述

完整代码

<template>
	<div class='divchart' >
		<!--  #ifdef  H5 -->
		<div>
		<div class='kline' id="kline" ref='kline'  v-show="KLine.IsShow"></div>
		<div class='minute' id="minute" ref='minute'  v-show="Minute.IsShow"></div>
		</div>
		<!--  #endif -->
		
		<!--  #ifndef  H5 -->
		<view>
			<canvas id="kline2" canvas-id='kline2' class='kline2' v-bind:style="{width: ChartWidth+'px', height: ChartHeight+'px'}"  v-show="KLine.IsShow"
			  @touchstart="KLineTouchStart" @touchmove='KLineTouchMove' @touchend='KLineTouchEnd' ></canvas>  
			  <canvas id="minute2" canvas-id='minute2' class='minute' v-bind:style="{width: ChartWidth+'px', height: ChartHeight+'px'}" v-show="Minute.IsShow"
			   @touchstart="MinuteTouchStart" @touchmove='MinuteTouchMove' @touchend='MinuteTouchEnd' ></canvas>
		</view>
		<!--  #endif -->
		
		<div class="button-sp-area">
			<button class="mini-btn" type="default" size="mini" @click="ChangeMinutePeriod(MINUTE_PERIOD_ID.MINUTE_ID)">分时</button>
			<button class="mini-btn" type="default" size="mini" @click="ChangeMinutePeriod(MINUTE_PERIOD_ID.MINUTE_5DAY_ID)">5</button>
			<button class="mini-btn" type="default" size="mini" @click="ChangeKLinePeriod(KLINE_PERIOD_ID.KLINE_DAY_ID)">日线</button>
			<button class="mini-btn" type="default" size="mini" @click="ChangeKLinePeriod(KLINE_PERIOD_ID.KLINE_WEEK_ID)">周线</button>
			<button class="mini-btn" type="default" size="mini" @click="ChangeKLinePeriod(KLINE_PERIOD_ID.KLINE_MINUTE_ID)">1分钟</button>
			<button class="mini-btn" type="default" size="mini" @click="ChangeKLinePeriod(KLINE_PERIOD_ID.KLINE_15MINUTE_ID)">15分钟</button>
		</div>
		
	</div>
</template>

<script>
// #ifdef H5	
import HQChart from '../../umychart_uniapp_h5/umychart.uniapp.h5.js'
// #endif

// #ifndef H5
import {JSCommon} from '../../umychart.uniapp/umychart.wechat.3.0.js'
// #endif

function DefaultData() { }

DefaultData.GetKLineOption = function () 
{
    let data = 
    {
        Type: '历史K线图', 
        
        Windows: //窗口指标
        [
            {Index:"MA",Modify: false, Change: false}, 
            {Index:"VOL",Modify: false, Change: false}
        ], 
 
        IsCorssOnlyDrawKLine:true,
        CorssCursorTouchEnd:true,
 
        Border: //边框
        {
            Left:   1,
            Right:  1, //右边间距
            Top:    25,
            Bottom: 25,
        },
 
        KLine:
        {
            Right:1,                            //复权 0 不复权 1 前复权 2 后复权
            Period:0,                           //周期: 0 日线 1 周线 2 月线 3 年线 
            PageSize:30,
            IsShowTooltip:false
        },
		
		ExtendChart:
		[
			{Name:'KLineTooltip' },	//开启手机端tooltip
		], 
		
		Frame:  //子框架设置
		[
		    {SplitCount:3},
		    {SplitCount:2},
		    {SplitCount:3},
		],
        
    };
 
    return data;
}
 
DefaultData.GetMinuteOption=function()
{
    var option= 
    {
        Type:'分钟走势图',   //创建图形类型
            
        Windows: //窗口指标
        [
            
        ], 
            
        IsAutoUpdate:true,       //是自动更新数据
        DayCount:1,                 //1 最新交易日数据 >1 多日走势图
        IsShowRightMenu:false,       //是否显示右键菜单
        CorssCursorTouchEnd:true,
 
        MinuteLine:
        {
            //IsDrawAreaPrice:false,      //是否画价格面积图
        },
 
        Border: //边框
        {
            Left:1,    //左边间距
            Right:1,   //右边间距
            Top:20,
            Bottom:20
        },
            
        Frame:  //子框架设置
        [
            {SplitCount:3},
            {SplitCount:2},
            {SplitCount:3},
        ],
 
        ExtendChart:    //扩展图形
        [
            {Name:'MinuteTooltip' }  //手机端tooltip
        ],
    };
 
    return option;
}


//周期枚举
var KLINE_PERIOD_ID=
{
    KLINE_DAY_ID:0,
    KLINE_WEEK_ID:1,
    KLINE_MONTH_ID:2,
    KLINE_YEAR_ID:3,

    KLINE_MINUTE_ID:4,
    KLINE_5MINUTE_ID:5,
    KLINE_15MINUTE_ID:6,
    KLINE_30MINUTE_ID:7,
    KLINE_60MINUTE_ID:8
}

//周期枚举
var MINUTE_PERIOD_ID=
{
    MINUTE_ID:1,
    MINUTE_2DAY_ID:2,
    MINUTE_3DAY_ID:3,
    MINUTE_4DAY_ID:4,
    MINUTE_5DAY_ID:5,
}

var g_KLine={ JSChart:null };
var g_Minute={ JSChart:null };
export default 
{
	data() 
	{
		let data=
		{
			Symbol:'600000.sh',
			ChartWidth:300,
			ChartHeight:500,
			KLine:
			{
				
				Option:DefaultData.GetKLineOption(), 
				IsShow:true,
			},
			Minute:
			{
				
				Option:DefaultData.GetMinuteOption(),
				IsShow:false,
			},
			
			MINUTE_PERIOD_ID:MINUTE_PERIOD_ID,
			KLINE_PERIOD_ID:KLINE_PERIOD_ID,
		};
		
		return data;
	},
	
	onLoad() 
	{
		
	},
	
	onReady()
	{
		this.OnSize();
		this.CreateKLineChart(); 
	},
	
	methods: 
	{
		OnSize()
		{
			// #ifdef H5
			this.OnSize_h5();
			// #endif
		},
		
		OnSize_h5()
		{
			var chartHeight = this.ChartHeight;
			var chartWidth = this.ChartWidth;
			 
			var kline=this.$refs.kline;
			kline.style.width=chartWidth+'px';
			kline.style.height=chartHeight+'px';
			if (g_KLine.JSChart) g_KLine.JSChart.OnSize();
			
			var minute=this.$refs.minute;
			minute.style.width=chartWidth+'px';
			minute.style.height=chartHeight+'px';
			if (g_Minute.JSChart) g_Minute.JSChart.OnSize();
		},
				
		CreateKLineChart_h5()  //创建K线图
        {
            if (g_KLine.JSChart) return;
            this.KLine.Option.Symbol=this.Symbol;
            let chart=HQChart.JSChart.Init(this.$refs.kline);
			this.KLine.Option.NetworkFilter=this.NetworkFilter;
            chart.SetOption(this.KLine.Option);
            g_KLine.JSChart=chart;
        },
		
		CreateKLineChart_app()
		{
			if (this.KLine.JSChart) return;
			
			let element = new JSCommon.JSCanvasElement();
			// #ifdef APP-PLUS
			element.IsUniApp=true;	//canvas需要指定下 是uniapp的app
			// #endif
			element.ID = 'kline2';
			element.Height = this.ChartHeight;  //高度宽度需要手动绑定!!
			element.Width = this.ChartWidth;
					
			g_KLine.JSChart = JSCommon.JSChart.Init(element);
			this.KLine.Option.NetworkFilter=this.NetworkFilter;
			this.KLine.Option.Symbol=this.Symbol;
			g_KLine.JSChart.SetOption(this.KLine.Option);
		},
		
		CreateKLineChart()
		{
			// #ifdef H5
			this.CreateKLineChart_h5();
			// #endif
			
			// #ifndef H5
			this.CreateKLineChart_app();
			// #endif
		},
		
		//K线周期切换
		ChangeKLinePeriod:function(period)
		{
			this.Minute.IsShow=false;
			this.KLine.IsShow=true;
			if (!g_KLine.JSChart)    //不存在创建
			{
				this.KLine.Option.Period=period;
				this.CreateKLineChart_h5();
			}
			else
			{
				g_KLine.JSChart.ChangePeriod(period);
			}
		},
		
		CreateMinuteChart_h5() //创建日线图
		{
			if (g_Minute.JSChart) return;
			this.Minute.Option.Symbol=this.Symbol;
			let chart=HQChart.JSChart.Init(this.$refs.minute);
			this.Minute.Option.NetworkFilter=this.NetworkFilter;
			chart.SetOption(this.Minute.Option);
			g_Minute.JSChart=chart;
		},
		
		CreateMinuteChart_app()
		{
			if (g_Minute.JSChart) return;
			
			var element = new JSCommon.JSCanvasElement();
			// #ifdef APP-PLUS
			element.IsUniApp=true;	//canvas需要指定下 是uniapp的app
			// #endif
			element.ID = 'minute2';
			element.Height = this.ChartHeight;  //高度宽度需要手动绑定!!
			element.Width = this.ChartWidth;
					
			g_Minute.JSChart = JSCommon.JSChart.Init(element);
			this.Minute.Option.NetworkFilter=this.NetworkFilter;
			this.Minute.Option.Symbol=this.Symbol;
			g_Minute.JSChart.SetOption(this.Minute.Option);
		},
		
		CreateMinuteChart()
		{
			// #ifdef H5
			this.CreateMinuteChart_h5();
			// #endif
			
			// #ifndef H5
			this.CreateMinuteChart_app();
			// #endif
		},
		
		//走势图多日切换
		ChangeMinutePeriod:function(period)
		{
			this.Minute.IsShow=true;
			this.KLine.IsShow=false;
			if (!g_Minute.JSChart)   //不存在创建
			{
				this.Minute.Option.DayCount=period;
				this.CreateMinuteChart();
			}
			else
			{
				g_Minute.JSChart.ChangeDayCount(period);
			}
		},
		
		NetworkFilter:function(data, callback)
		{
			console.log(`[HQChart:NetworkFilter] Name=${data.Name} Explain=${data.Explain}` );
		},
		
		///
		//手势事件 app/小程序才有
		//KLine事件
		KLineTouchStart: function (event) 
		{
		  if (g_KLine.JSChart) g_KLine.JSChart.OnTouchStart(event);
		},
		
		KLineTouchMove: function (event) 
		{
		  if (g_KLine.JSChart) g_KLine.JSChart.OnTouchMove(event);
		},
		
		KLineTouchEnd: function (event) 
		{
		  if (g_KLine.JSChart) g_KLine.JSChart.OnTouchEnd(event);
		},
		
		//走势图事件
		MinuteTouchStart: function (event) 
		{
		  if (g_Minute.JSChart) g_Minute.JSChart.OnTouchStart(event);
		},
		
		MinuteTouchMove: function (event) 
		{
		  if (g_Minute.JSChart) g_Minute.JSChart.OnTouchMove(event);
		},
		
		MinuteTouchEnd: function (event) 
		{
		  if (g_Minute.JSChart) g_Minute.JSChart.OnTouchEnd(event);
		},
	}
}

</script>

<style>
	
</style>

如果还有问题可以加交流QQ群: 950092318

HQChart代码地址
地址:github.com/jones2000/HQChart

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HQChart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值