jones2000
jones2000
  • 发布:2019-10-13 04:23
  • 更新:2019-10-13 04:23
  • 阅读:2794

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

分类:uni-app

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

背景

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

安装插件

在工程里建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 关注 分享

要回复文章请先登录注册