uniapp EChars图表

news2024/11/16 2:48:02

1. uniapp EChars图表

(1)Apache ECharts 一个基于 JavaScript 的开源可视化图表库
  https://echarts.apache.org/examples/zh/index.html
(1)官网图例
在这里插入图片描述
(2)个人实现图例
在这里插入图片描述

1.1. 下载echart

1.1.1. 下载

(1)方法一:从 npm 安装
   使用 npm 安装 ECharts 到你的 uni-app 项目中。在项目根目录下打开终端,执行以下命令:

npm install echarts --save

(2)方法二:选择需要的模块,在线定制下载
  下载 - Apache ECharts
  即echarts.min.js 下载

1.1.2. 应用市场插件

  在插件市场下载插件,使用hbuilderx导入即可。
https://ext.dcloud.net.cn/plugin?id=4899
在这里插入图片描述

1.1.3. 引用

// An highlighted block
  import echarts from '@/components/echarts/echarts.vue';

  下面的是 echarts.vue的代码 您可以在components 创建一个echarts的文件夹里面放echarts.vue
代码里script.src = ‘./static/echarts.min.js’ (更改路径不行的话,还是建议使用此路径

1.2. 示例代码

在这里插入图片描述

1.2.1. echars-helper.js

import echarsData from "../data/echarsData.json";

var ecahrsHelper = {
    UNITS: {
        '年': 31557600000,
        '月': 2629800000,
        '天': 86400000,
        '小时': 3600000,
        '分钟': 60000,
        '秒': 1000
    },
    colorConstant: {
        colorArr: [
            '#FF3333', 'rgb(21,169,85)', '#0e9fff', '#FF8833',
            '#11f6ad', '#9b7516', 'rgb(0,255,255)', '#FFD700',
            '#d7b482', '#b01496', '#00ff00', '#A020F0',
            '#fbcc00', 'rgb(103,161,181)', '#0acf59',
            '#11f6ad', 'rgb(0,255,255)', '#0acf59']
    },

    getBarLine2Option: function (optionObj) {
        var legendArr = []
        optionObj.yObj.forEach((item, index) => {
            legendArr.push(item.name)
        })
        var option = {
            title: {
                text: optionObj.title,
                textStyle: {
                    fontSize: 12,
                    color: '#666666'
                },
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                // // itemHeight: 8,
                // // itemWidth: 8,
                // // type: 'scroll',
                orient: 'horizontal', // vertical
                x: 'right',      //可设定图例在左、右、居中
                // // y:'bottom',     //可设定图例在上、下、居中
                // // padding:[0,50,0,0],   //可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                // // data: analyseArr,
                // //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                // // diamond:菱形 pin:水滴  arrow:箭头
                // icon: 'roundRect',
            },
            grid: {
                left: '2%',
                right: '2%',
                bottom: '3%',
                top: '15%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
            },
            yAxis: {
                type: 'value',
                boundaryGap: [0, 0.01],
                // name:"123",//坐标轴名称。
                nameLocation: 'end',//坐标轴名称显示位置。
                axisLabel: {//坐标轴刻度标签的相关设置。
                    //     interval:0,
                    //     rotate:"45"
                    formatter: (value) => {//数字
                        if (value >= 10000) {
                            value = (value / 10000) + 'w';
                        }
                        if (value >= 1000) {
                            value = (value / 1000) + 'k';
                        }
                        return value;
                    }
                }
            },
            series: optionObj.yObj
        };
        return option || '';
    },
    /**
     * 初始化折线、饼状图配置
     */
    getBarLineOption: function (optionObj) {
        var legendArr = []
        optionObj.yObj.forEach((item, index) => {
            legendArr.push(item.name)
        })
        var option = {
            title: {
                text: optionObj.title,
                textStyle: {
                    fontSize: 15,
                    color: '#000',
                },
            },
            tooltip: {
                trigger: 'axis',
                shadowBlur: 0,
                textStyle: {
                    textShadowBlur: 0
                },
                renderMode: 'richText',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: legendArr,
                // itemHeight: 8,
                // itemWidth: 8,
                // type: 'scroll',
                orient: 'horizontal', // vertical
                x: 'right',//可设定图例在左、右、居中
                // y:'bottom',//可设定图例在上、下、居中
                // padding:[0,50,0,0],//可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                // data: analyseArr,
                //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                // diamond:菱形 pin:水滴  arrow:箭头
                // icon: 'roundRect',
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                boundaryGap: true,
                data: optionObj.xArr
            },
            yAxis: {
                type: 'value',
                boundaryGap: [0, 0.01],
                name: "单位(件)",//坐标轴名称。
                nameLocation: 'end',//坐标轴名称显示位置。
                axisLabel: {//坐标轴刻度标签的相关设置。
                    interval: 0,
                    rotate: "0",//坐标轴刻度标签角度
                    formatter: (value) => {//数字
                        if (value >= 10000) {
                            value = (value / 10000) + 'w';
                        }
                        if (value >= 1000) {
                            value = (value / 1000) + 'k';
                        }
                        return value;
                    }
                }
            },
            series: optionObj.yObj
        }
        return option || '';
    },

    getPieOption: function (optionObj) {
        var totalNum = 0
        optionObj.pieArr.forEach((item, index) => {
            totalNum += Number(item.value);
        })
        var option = {
            title: {标题
                subtext: "",
                text: optionObj.title + `\n` + '总数' + `\n` + totalNum + '人次',
                top: 'center',
                left: 'center',
                textStyle: {
                    fontSize: 11,
                }
            },
            legend: {
                itemHeight: 8,
                itemWidth: 8,
                // type: 'scroll',
                orient: 'horizontal', // vertical
                x: 'center', //可设定图例在左、右、居中
                y: 'bottom', //可设定图例在上、下、居中
                // padding:[0,50,0,0],//可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
                data: optionObj.pieArr,
                //circle:圆形 rect:矩形 roundRect:圆角矩形  triangle:角形
                // diamond:菱形 pin:水滴  arrow:箭头
                icon: 'rect',
            },
            tooltip: {//弹出框
                //trigger:触发类型,'item'数据项图形触发,主要在散点图,
                // 饼图等无类目轴的图表中使用。'axis'坐标轴触发,主要在柱状图,
                // 折线图等会使用类目轴的图表中使用。
                trigger: 'item',
                //triggerOn:提示框触发的条件,'mousemove'鼠标移动时触发。
                // 'click'鼠标点击时触发。'mousemove|click'同时鼠标移动和点击时触发。
                // 'none'不在 'mousemove' 或 'click' 时触发
                //triggerOn:"mousemove",
                //是否显示提示框浮层
                //showContent:true,
                //是否永远显示提示框内容
                //alwaysShowContent:false,
                //浮层显示的延迟,单位为 ms
                //showDelay:0,
                //浮层隐藏的延迟,单位为 ms
                //hideDelay:100,
                //鼠标是否可进入提示框浮层中
                //enterable:false,
                //是否将 tooltip 框限制在图表的区域内
                confine: true,
                //提示框浮层的移动动画过渡时间,单位是 s,设置为 0 的时候会紧跟着鼠标移动
                //transitionDuration:0.4,
                //提示框浮层的位置,默认不设置时位置会跟随鼠标的位置,[10, 10],回掉函数,
                // inside鼠标所在图形的内部中心位置,top、left、bottom、right
                // 鼠标所在图形上侧,左侧,下侧,右侧,
                //position:['50%', '50%'],
                //提示框浮层内容格式器,支持字符串模板和回调函数两种形式,
                // 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等
                //formatter:"{b0}: {c0}<br />{b1}: {c1}",
                // formatter: '{a} <br/>{b}: {c} ({d}%)'
                formatter: '{b}  {c} 人({d}%)',
                //标题背景色,
                //backgroundColor:"white",
                //边框颜色
                //borderColor:"#ccc",
                //边框线宽
                //borderWidth:0,
                //图例内边距,单位px  5  [5, 10]  [5,10,5,10]
                padding: 4,
                //textStyle:文本样式
                textStyle: {
                    fontSize: 10,
                }
            },
            series: [
                {
                    name: '统计分析',
                    type: 'pie',
                    clickable: true, //是否开启点击
                    minAngle: 2,//最小的扇区角度(0 ~ 360),用于防止某个值过小导致扇区太小影响交互
                    avoidLabelOverlap: true,//是否启用防止标签重叠策略
                    hoverAnimation: true,//是否开启 hover 在扇区上的放大动画效果。
                    silent: false,//图形是否不响应和触发鼠标事件
                    radius: ['30%', '50%'],
                    center: ['50%', '50%'],
                    labelLine: {
                        normal: {
                            length: 30, //第一条线
                            length2: 8, //第二条线
                            // lineStyle: {
                            //     width: 1, // 线条的宽度
                            //     color: "#000", //线的颜色设置, 如没有设置颜色则线条的颜色跟随饼状图的颜色
                            // }
                        }
                    },
                    label: {
                        // formatter: '{b|{b}}\n \n {per|{d}%}  ',
                        //formatter: '{b|{b}}\n \n {per|{d}%}  ',
                        formatter: '{b|{b}}',
                        borderWidth: 20,
                        borderRadius: 4,
                        padding: [20, 40],
                        normal: {
                            formatter(params) {
                                let text = params.name
                                if (text.length <= 6) {
                                    return text = text + '\n' + params.percent + '%';
                                } else if (text.length > 6 && text.length <= 12) {
                                    return text = `${text.slice(0, 6)}\n${text.slice(6)}`
                                        + params.percent + '%'
                                } else if (text.length > 12 && text.length <= 18) {
                                    return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12)}`
                                        + params.percent + '%'
                                } else if (text.length > 24 && text.length <= 30) {
                                    return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24)}`
                                        + params.percent + '%'
                                } else if (text.length > 30) {
                                    return text = `${text.slice(0, 6)}\n${text.slice(6, 12)}\n${text.slice(12, 18)}\n${text.slice(24, 30)}\n${text.slice(30)}`
                                        + params.percent + '%'
                                }
                            },
                            textStyle: {
                                fontSize: 8
                            },
                            //柱状图颜色
                            // color: function (params) {
                            //     // 颜色列表返回颜色
                            //     return colorConstant.colorArr[(params.dataIndex
                            //         % colorConstant.colorArr.length)];
                            // },
                        },
                        rich: {
                            a: {
                                color: '#6E7079',
                                lineHeight: 22,
                                align: 'center'
                            },
                            b: {
                                color: '#4C5058',
                                fontSize: 12,
                                fontWeight: 'bold',
                                lineHeight: 18,
                                align: "bottom",
                                font: "Xingkai SC",
                            },
                            c: {
                                fontSize: 12,
                                lineHeight: 30,
                                color: '#63BF6A',
                                align: "center"
                            },
                            d: {
                                fontSize: 10,
                                lineHeight: 12,
                                color: '#4C5058',
                                align: "top"
                            }
                        }
                    },
                    data: optionObj.pieArr,
                    itemStyle: {
                        normal: {
                            //柱状图颜色
                            color: function (params) {
                                // 颜色列表返回颜色
                                var colorArr = ecahrsHelper.colorConstant.colorArr
                                return colorArr[(params.dataIndex % colorArr.length)];
                            },

                        }
                    }
                }
            ]
        };
        return option || '';
    },
};

export {
    ecahrsHelper
}

1.2.2. pageEchars.vue

<template>
    <view class="base-echars-page">
        <!--饼状图-->
        <view class="base-echars-layout">
            <view class="base-echars-title-layout">
                <image class="base-echars-title-icon"
                       src="../../../static/icon/icon-loc.png"></image>
                <view class="base-echars-title-title">饼状图</view>
            </view>
            <view class="base-echars-body">
                <l-echart ref="pieChart" @finished="initPieEchars"></l-echart>
            </view>
        </view>
        <!--柱状、柱状图-->
        <view class="base-echars-layout">
            <view class="base-echars-title-layout">
                <image class="base-echars-title-icon"
                       src="../../../static/icon/icon-loc.png"></image>
                <view class="base-echars-title-title">柱状、柱状图</view>
            </view>
            <view class="base-echars-body">
                <l-echart ref="barLinechart" @finished="initBarLineEchars"></l-echart>
            </view>
        </view>
        <!--双柱状、柱状图-->
        <view class="base-echars-layout">
            <view class="base-echars-title-layout">
                <image class="base-echars-title-icon"
                       src="../../../static/icon/icon-loc.png"></image>
                <view class="base-echars-title-title">双柱状、柱状图</view>
            </view>
            <view class="base-echars-body">
                <l-echart ref="barLine2chart" @finished="initBarLine2Echars"></l-echart>
            </view>
        </view>
    </view>
</template>

<script>
    import pageUtil from '../../../utils/pageUtil.js';
    import {ecahrsHelper} from '../../../helper/ecahrsHelper';
    import echarsData from '../../../data/echarsData.json'
    // #ifdef VUE3
    // #ifdef MP
    // 由于vue3 使用vite 不支持umd格式的包,小程序依然可以使用,但需要使用require
    const echarts = require('../../../static/echarts.min');
    // #endif
    // #ifndef MP
    // 由于 vue3 使用vite 不支持umd格式的包,故引入npm的包
    import * as echarts from 'echarts/dist/echarts.esm';
    // #endif
    // #endif
    export default {
        data() {
            return {
                showTip: false,

            }
        },
        onReady() {
            pageUtil.setTitleBar('基础信息')
        },
        methods: {
            /**
             * 初始化饼状图
             */
            initPieEchars() {
                this.$refs.pieChart.init(echarts, chart => {
                    var optionObj = {}
                    optionObj.title = '数据统计'
                    optionObj.pieArr = echarsData.rows
                    var option = ecahrsHelper.getPieOption(optionObj)
                    chart.setOption(option);
                    // 监听tooltip显示事件
                    chart.on('showTip', (params) => {
                        this.showTip = true
                        console.log('showTip::')
                    });
                    // 监听tooltip隐藏事件
                    chart.on('hideTip', (params) => {
                        setTimeout(() => {
                            this.showTip = false
                        }, 300)
                    });

                    setTimeout(() => {

                    }, 1000)

                });
            },

            /**
             *  初始化柱状、折线图
             */
            initBarLineEchars() {
                this.$refs.barLinechart.init(echarts, chart => {
                    var optionObj = {}
                    optionObj.title = '数据统计表'
                    optionObj.xArr = []
                    var yArr = []
                    echarsData.rows.forEach((item, index) => {
                        optionObj.xArr.push(item.name)
                        yArr.push(item.value)
                    })
                    optionObj.yObj = [
                        {
                            name: '邮件营销',
                            type: 'line',//bar:柱状图  line:折线图
                            stack: '总量',
                            data: []
                        }
                    ]
                    optionObj.yObj[0].data = yArr
                    var option = ecahrsHelper.getBarLineOption(optionObj)
                    chart.setOption(option);
                    // 监听tooltip显示事件
                    chart.on('showTip', (params) => {
                        this.showTip = true
                        console.log('showTip::')
                    });
                    // 监听tooltip隐藏事件
                    chart.on('hideTip', (params) => {
                        setTimeout(() => {
                            this.showTip = false
                        }, 300)
                    });

                    setTimeout(() => {

                    }, 1000)

                });
            },
            /**
             * 初始化双柱状、折线图
             */
            initBarLine2Echars() {
                this.$refs.barLine2chart.init(echarts, chart => {
                    var optionObj = {}
                    optionObj.title = '数据统计表'
                    optionObj.xArr = []
                    var yArr = []
                    var y2Arr = []
                    echarsData.rows.forEach((item, index) => {
                        optionObj.xArr.push(item.name)
                        yArr.push(item.value)
                        y2Arr.push(item.value2)
                    })
                    optionObj.yObj =
                        [
                            {
                                name: '邮件营销',
                                type: 'bar',//bar:柱状图  line:折线图
                                // stack: '总量',
                                data: [],
                                color: '#f00',
                            },
                            {
                                name: '邮件营销3',
                                type: 'bar',//bar:柱状图  line:折线图
                                // stack: '总量',
                                data: [],
                                color: '#0f0',
                            }
                        ]
                    optionObj.yObj[0].data = yArr
                    optionObj.yObj[1].data = y2Arr
                    var option = ecahrsHelper.getBarLine2Option(optionObj)
                    chart.setOption(option);
                    // 监听tooltip显示事件
                    chart.on('showTip', (params) => {
                        this.showTip = true
                        console.log('showTip::')
                    });
                    // 监听tooltip隐藏事件
                    chart.on('hideTip', (params) => {
                        setTimeout(() => {
                            this.showTip = false
                        }, 300)
                    });

                    setTimeout(() => {

                    }, 1000)

                });
            },
        }
    }
</script>
<style>
</style>

2. uniapp EChars图表步骤

  在 uni-app 中使用 ECharts 数据可视化库,通常需要完成以下步骤:

2.1. 安装 ECharts

  使用 npm 安装 ECharts 到你的 uni-app 项目中。在项目根目录下打开终端,执行以下命令:

npm install echarts --save

2.2. 引入 ECharts

  对于 Vue 单文件组件(.vue 文件)
  在需要使用 ECharts 的 Vue 组件中,通过 import 语句引入 ECharts。同时,如果你需要使用地图功能,还需要额外引入相应的文件并注册。

<template>
  <view>
    <canvas ref="chartCanvas"></canvas>
  </view>
</template>
 
<script>
import * as echarts from 'echarts';
import 'echarts/map/js/china.js'; // 引入中国地图(按需引入其他地图)
 
export default {
  data() {
    return {
      chartInstance: null,
    };
  },
  mounted() {
    this.initChart();
  },
  methods: {
    async initChart() {
      // 等待 canvas 元素渲染完成(对于 H5 环境可能需要)
      await this.$nextTick();
 
      // 获取 canvas 元素
      const chartDom = this.$refs.chartCanvas;
 
      // 初始化 ECharts 实例
      this.chartInstance = echarts.init(chartDom);
 
      // 加载地图数据(如果需要)
      echarts.registerMap('China', china); // 注册中国地图
 
      // 设置图表配置项
      const option = {
        // ...具体的图表配置项
      };
 
      // 载入图表
      this.chartInstance.setOption(option);
    },
  },
  beforeDestroy() {
    // 销毁图表实例以避免内存泄漏
    if (this.chartInstance) {
      this.chartInstance.dispose();
      this.chartInstance = null;
    }
  },
};
</script>

  对于使用 uni-app 插件市场的 ECharts 插件
  如果你选择使用 uni-app 插件市场提供的 ECharts 插件(如 uni-ec-canvas),则需要按照插件文档的指引进行安装和使用。
  通常情况下,你需要在 pages.json 中配置插件,然后在模板中使用特定的组件标签(如 ),并设置其属性来传递图表配置和数据。

2.3. 创建图表容器

  在 Vue 组件的模板部分,创建一个 元素作为 ECharts 图表的容器,并为其指定一个 ref,以便在 JavaScript 中通过 this.$refs 访问。

<template>
  <view>
    <canvas ref="chartCanvas"></canvas>
  </view>
</template>

2.4. 初始化图表

  在 Vue 组件的 mounted 生命周期钩子中,初始化 ECharts 实例。
• 首先等待 DOM 更新完毕(使用 this.$nextTick())
• 然后获取 canvas 元素,使用 echarts.init() 方法初始化图表实例。
• 接着设置图表的配置项(option)
• 最后调用 setOption() 方法加载图表。

export default {
  data() {
    return {
      chartInstance: null,
    };
  },
  mounted() {
    this.initChart();
  },
  methods: {
    async initChart() {
      await this.$nextTick();
      const chartDom = this.$refs.chartCanvas;
      this.chartInstance = echarts.init(chartDom);
      const option = {
        // ...具体的图表配置项
      };
      this.chartInstance.setOption(option);
    },
  },
  // ...其他生命周期钩子,如销毁时清理图表资源
};

2.5. 配置图表

  根据你的需求,编写 ECharts 的配置项(option)。
  这通常包括:
  • 图表类型、
  • 数据源、
  • 颜色、
  • 图例、
  • 坐标轴、
  • 系列等设置。
  ECharts 文档提供了详细的配置项说明和示例。

const option = {
  title: {
    text: '示例图表',
  },
  tooltip: {},
  legend: {
    data: ['数据系列'],
  },
  xAxis: {
    data: ['类别A', '类别B', '类别C'],
  },
  yAxis: {},
  series: [
    {
      name: '数据系列',
      type: 'bar',
      data: [100, 200, 300],
    },
  ],
};

2.6. 更新图表数据

  当需要动态更新图表数据时,可以直接修改 option 对象中的数据部分,然后调用 setOption() 方法重新加载图表。
  为了优化性能,可以使用 setOption() 的第二个参数 notMerge 设置为 false,以合并新旧配置而不是完全替换。

// 更新数据
const newData = [400, 500, 600];
this.option.series[0].data = newData;
// 重新加载图表
this.chartInstance.setOption(this.option, { notMerge: true });

2.7. 注意事项

   跨平台兼容性:确保你的 ECharts 版本与 uni-app 的版本兼容,并且了解不同平台(如 H5、小程序、App)   可能存在的差异和限制。某些功能可能需要特定版本的 ECharts 或 uni-app 支持。
  • 地图数据:如果你使用地图图表,需要单独引入对应的地图数据文件,并使用 echarts.registerMap() 方法注册地图。地图数据可以从 ECharts 官方下载或在线定制。
  • 性能优化:对于大数据量或复杂图表,注意优化数据处理和渲染性能,可以利用 ECharts 的数据分流、懒加载等功能。
  遵循以上步骤,你应该能够在 uni-app 中成功集成并使用 ECharts 图表。
  具体实现时,请参考 ECharts 官方文档以获取最新的配置选项和最佳实践。

3. uni-app 如何使用 renderjs 创建echart图表

  在 uni-app 中使用 renderjs 模式创建 ECharts 图表,主要是利用 uni-app 提供的 RenderJS 能力,将 ECharts 渲染到指定的容器内。
  RenderJS 是 uni-app 为解决跨端渲染复杂图形和自定义组件而引入的一种机制。
  以下是一个基本步骤指南:

3.1. 安装 ECharts

  确保已通过 npm 安装 ECharts:

npm install echarts --save

3.2. 创建 ECharts 配置文件

  在项目中创建一个 .js 文件(如 chartConfig.js),编写所需的 ECharts 配置对象:

// chartConfig.js
export default {
  title: {
    text: '示例图表'
  },
  tooltip: {},
  legend: {
    data: ['数据系列']
  },
  xAxis: {
    data: ['类别A', '类别B', '类别C']
  },
  yAxis: {},
  series: [
    {
      name: '数据系列',
      type: 'bar',
      data: [100, 200, 300]
    }
  ]
};

3.3. 创建 renderjs 页面

  在 uni-app 项目中创建一个使用 RenderJS 的页面(如 chartPage.vue)。在 中添加一个 renderjs 标签作为 ECharts 的渲染容器:

<!-- chartPage.vue -->
<template>
  <view>
    <renderjs :canvas-id="'chartCanvas'"></renderjs>
  </view>
</template>

3.4. 编写 renderjs 函数

   在

<script>
import * as echarts from 'echarts';
import chartConfig from './chartConfig.js';
 
export default {
  onReady() {
    this.renderChart();
  },
  methods: {
    async renderChart() {
      const canvasId = 'chartCanvas';
      const chartInstance = echarts.init({
        canvas: this.$refs[canvasId].canvas,
        renderer: 'canvas'
      });
 
      chartInstance.setOption(chartConfig);
 
      // 如果需要监听窗口大小改变以自适应图表,可以添加以下代码
      window.addEventListener('resize', () => {
        chartInstance.resize();
      });
    }
  }
};
</script>

3.5. (可选)注册自定义主题

   如果需要使用自定义主题,可以按照 ECharts 官方文档的指引创建主题 JSON 文件,然后在 renderjs 函数中注册:

// 引入主题文件
import customTheme from './customTheme.json';
echarts.registerTheme('myCustomTheme', customTheme);
// 使用自定义主题初始化图表
const chartInstance = echarts.init({
  canvas: this.$refs[canvasId].canvas,
  renderer: 'canvas',
  theme: 'myCustomTheme'
});

3.6. ((可选)更新图表数据

   当需要动态更新图表数据时,可以修改配置对象中的数据部分,然后调用 setOption() 方法:

// 更新数据
chartConfig.series[0].data = [400, 500, 600];
// 重新加载图表
chartInstance.setOption(chartConfig, { notMerge: true });

3.7. 注意事项

  跨平台兼容性:确保 ECharts 版本与 uni-app 的版本兼容,并了解不同平台(如 H5、小程序、App)可能存在的差异和限制。
  • 性能优化:对于大数据量或复杂图表,注意优化数据处理和渲染性能,可以利用 ECharts 的数据分流、懒加载等功能。

<template>
    <view class="content">
        <!-- #ifdef APP-PLUS || H5 -->
        <view @click="echarts.onClick" :prop="option" :change:prop="echarts.updateEcharts" id="echarts" class="echarts"></view>
        <button @click="changeOption">更新数据</button>
        <!-- #endif -->
        <!-- #ifndef APP-PLUS || H5 -->
        <view>APPH5 环境不支持</view>
        <!-- #endif -->
    </view>
</template>
 
<script>
    export default {
        data() {
            return {
                option: {
                    title: {
                        text: 'ECharts 入门示例'
                    },
                    tooltip: {},
                    legend: {
                        data: ['销量']
                    },
                    xAxis: {
                        data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
                    },
                    yAxis: {},
                    series: [{
                        name: '销量',
                        type: 'bar',
                        data: [5, 20, 36, 10, 10, 20]
                    }]
                }
            }
        },
        onLoad() {
 
        },
        methods: {
            changeOption() {
                const data = this.option.series[0].data
                // 随机更新示例数据
                data.forEach((item, index) => {
                    data.splice(index, 1, Math.random() * 40)
                })
            },
            onViewClick(options) {
                console.log(options)
            }
        }
    }
</script>
 
<script module="echarts" lang="renderjs">
    let myChart
    export default {
        mounted() {
            if (typeof window.echarts === 'function') {
                this.initEcharts()
            } else {
                // 动态引入较大类库避免影响页面展示
                const script = document.createElement('script')
                // view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
                script.src = 'static/echarts.js'
                script.onload = this.initEcharts.bind(this)
                document.head.appendChild(script)
            }
        },
        methods: {
            initEcharts() {
                myChart = echarts.init(document.getElementById('echarts'))
                // 观测更新的数据在 view 层可以直接访问到
                myChart.setOption(this.option)
            },
            updateEcharts(newValue, oldValue, ownerInstance, instance) {
                // 监听 service 层数据变更
                myChart.setOption(newValue)
            },
            onClick(event, ownerInstance) {
                // 调用 service 层的方法
                ownerInstance.callMethod('onViewClick', {
                    test: 'test'
                })
            }
        }
    }
</script>
 
<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
 
    .echarts {
        margin-top: 100px;
        width: 100%;
        height: 300px;
    }
</style>

4. 什么是 RenderJS in uni-app?

   RenderJS 是 uni-app 提供的一种技术手段,允许开发者在特定环境下(通常指 App 端的 Vue 页面)直接在视图层(而非逻辑层)执行 JavaScript 代码。
   这样做的主要目的是 为了提升复杂视图渲染和交互的性能,尤其是在处理大量图形绘制、动画效果、地图渲染等场景时,通过减少逻辑层与视图层之间的通信损耗,提供更高效的视图更新和用户交互体验。

4.1. RenderJS 主要具有以下特点:

   1. 运行环境:RenderJS 代码仅支持在 uni-app 的 App-Vue 环境 和 H5 环境 中运行。这意味着它不适用于小程序等其他平台,也不适用于原生的 iOS 或 Android 开发。
   2. 性能优势:通过在视图层直接执行 JavaScript,RenderJS 可以避免频繁的数据绑定和视图更新,显著降低逻辑层与视图层之间的通讯损耗,特别适合处理需要密集计算或实时更新的视图内容,如地图渲染、图表绘制、游戏图形等。
   3. 交互能力:RenderJS 提供了更强大的视图交互能力,可以直接响应触屏事件、手势识别等,实现流畅的用户交互体验。
   4. 库支持:尽管 uni-app 提供了自身的地图、图表等组件,但有时开发者可能需要使用第三方库(如 Leaflet、ECharts、Three.js 等)以满足更复杂的需求。RenderJS 允许在视图层直接引入并使用这些库,从而实现更丰富的功能。

4.2. 使用 RenderJS 的基本步骤如下:

4.2.1. 准备页面结构

   在 uni-app 的 Vue 页面中,需要创建一个用于承载 RenderJS 代码的容器。通常,这会是一个特殊的 标签,带有唯一的 canvas-id 属性,以便在 JavaScript 中引用:

### 4.2.2. 编写 RenderJS 代码    编写需要在视图层执行的 JavaScript 代码。这可以包括 DOM 操作、样式设置、事件监听、图形绘制等。代码通常保存在 Vue 组件的 methods 或 computed 中,然后在适当的生命周期钩子(如 mounted 或 onReady)中执行:

// 页面脚本 (继续在 renderjsPage.vue)

4.2.3. 引入外部库

   如果需要在 RenderJS 中使用第三方库,如 Leaflet、ECharts 等,需要确保库的源码可以在视图层访问,并在 RenderJS 代码中正确初始化:
   • 安装库:使用 npm 安装所需的库。
   • 引入库:将库的源码(通常是压缩后的 .js 文件)作为字符串嵌入到 renderJsCode 中。这可能需要使用 fs.readFileSync 或 Webpack 的 raw-loader 等工具。
   • 初始化库:在 renderJsCode 中编写库的初始化代码,确保库在 RenderJS 环境中能够正常工作。

4.2.4. 数据通信

  由于 RenderJS 运行在视图层,与 Vue 逻辑层之间需要进行数据交换:
  • 逻辑层向 RenderJS 传递数据:将数据作为变量直接写入 renderJsCode 字符串中,或者通过 uni.postMessage 从逻辑层发送数据到视图层。
  • RenderJS 向逻辑层发送数据:在 RenderJS 代码中使用 uni.postMessage 发送数据到逻辑层,逻辑层通过监听 uni.onMessage 事件接收数据。
注意事项
  • 性能优化:合理组织 RenderJS 代码,避免频繁的数据交换,确保高效执行。
  • 兼容性检查:确保所使用的库和 RenderJS 代码在目标平台上(App 端的 Vue 页面)能够正常工作。
  • 异常处理:在 RenderJS 代码中适当使用 try…catch 语句捕获并处理可能发生的错误
  在实际开发过程中,请参考 uni-app 的官方文档以获取最新的 API 说明和最佳实践。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2169178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新手教学系列——系统模块划分原则:如何让系统架构更加灵活与高效

在现代软件开发中,模块化设计是一个至关重要的概念。对于初学者来说,理解如何合理划分系统模块不仅能提高代码的可读性,还能让系统架构更具灵活性和可维护性。本文将深入探讨模块划分的基本原则,结合功能边界和数据边界的划分实例,帮助大家在实际开发中掌握模块化设计的精…

高校竞赛管理系统的设计与实现

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…

828华为云征文 | 华为云Flexus云服务器X实例搭建Zabbix网络设备监视系统(Ubuntu服务器运维)

前言 Flexus X实例内嵌智能应用调优算法&#xff0c;性能强悍&#xff0c;基础模式GeekBench单核及多核跑分可达同规格独享型实例的1.6倍&#xff0c;性能模式更是超越多系列旗舰型云主机&#xff0c;为企业业务提供强劲动力。 &#x1f4bc; Flexus X Zabbix&#xff1a;打造…

Spring Boot 快速入门教程

1. Spring Boot 简介 Spring Boot 是一个基于 Spring 框架的项目&#xff0c;它简化了基于 Spring 的 Java 应用程序的创建和部署。Spring Boot 通过提供一系列的“Starters”来简化 Maven 配置&#xff0c;同时使用约定大于配置的原则&#xff0c;让开发者能够以最少的配置启…

计算机视觉硬件整理(四):相机与镜头参数介绍

文章目录 前言一、工业相机常用分类二、工业相机的基本参数三、工业相机的接口四、工业镜头的参数五、工业镜头的选择要点 前言 随着科技的飞速发展&#xff0c;工业自动化和智能制造在当今社会扮演着越来越重要的角色。在这个背景下&#xff0c;工业相机作为一种关键的视觉检…

C# 委托(Delegate)一

一.Delegate的定义说明&#xff1a; C# 中的委托&#xff08;Delegate&#xff09;就是类似于 C 或 C 中函数的指针。Delegate 是存有对某个方法引用的一种引用类型变量&#xff0c;引用可在运行时是可以被改变的&#xff0c;特别适用于实现事件和回调方法。所有的Delegate都是…

微服务MongoDB解析部署使用全流程

1、什么是MongoDB 1、非关系型数据库 NoSQL&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在处理web2.0网站&#xff0c;特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心&#xff0c;出现了很多难以克服的问…

H5响应式的文化传媒娱乐公司HTML网站模板源码

源码名称&#xff1a;响应式的文化传媒娱乐公司HTML网站模板源码 源码介绍&#xff1a;一款自适应H5文化传媒娱乐公司官网源码&#xff0c;源码带有6个H5页面&#xff0c;可用于文化传媒和娱乐公司官网。 需求环境&#xff1a;H5 下载地址&#xff1a; https://www.51888w.c…

【漏洞复现】天融信 运维安全审计系统 synRequest.do 远程命令执行漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

深度学习:自然语言处理的基本原理

概念&#xff1a; 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和语言学领域的一个分支&#xff0c;它致力于研究如何让计算机能够理解、解释和生成人类语言&#xff0c;以及如何实现人与计算机之间的有效通信。自然语言处理…

【AndroidStudio】关于AndroidStudio的常见控件TextView和Button

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;AndroidStudio 1.常见控件TextView 1.1基本信息 TextView主要用于在界面上显示一段文本信息。最基本的代码格式如下&#xff1a; <TextView android:id"id/text_vie…

Shell 脚本管理 Java 应用程序的高效方法

在软件开发中&#xff0c;管理和监控 Java 应用程序的运行状态变得愈加重要。本文将分享一个自用的简单但高效的 Shell 脚本&#xff0c;帮助轻松管理 JAR 包的启动、停止和日志管理。 脚本功能概述 本脚本提供以下主要功能&#xff1a; 检查 JAR 包的运行状态启动尚未运行的…

OpenHarmony(鸿蒙南向)——平台驱动指南【MIPI DSI】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DSI&#xff08;Display Serial Interface&#x…

防火墙的区域划分+来自公网、内网的ip欺骗攻击+防御

一、适用场景&#xff1a; 1、某些企业的WIFI覆盖不全面的情况下&#xff0c;企业职工想通过自己购置的无线路由器实现使用无线WIFI时&#xff0c;无意间接入无线路由器&#xff0c;导致ip欺骗攻击形成。 2、当企业对某个网段中的某些ip地址&#xff0c;限制其不能连外网&…

玩转指针(3)

一、字符指针变量 字符指针变量&#xff08;如char* p&#xff09;的两种赋值方式 ①将字符类型地址赋值给字符指针变量 int main() {char a w;char* p &a;*p m;return 0; }②将常量字符串赋值给字符指针变量 常量字符串的介绍&#xff1a;用" "引起来的就…

【有啥问啥】大型语言模型的涌现能力(Emergent Abilities):新一代AI的曙光

大型语言模型的涌现能力&#xff08;Emergent Abilities&#xff09;&#xff1a;新一代AI的曙光 随着人工智能技术的飞速发展&#xff0c;大型语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;展现出了令人惊叹的涌现能力。这种能力并非模型规模简单线性…

OJ在线评测系统 后端 判题机模块预开发 架构分析 使用工厂模式搭建

判题机模块预开发(架构师)(工厂模式) 判题机模块 是为了把代码交个代码沙箱去处理 得到结果返回 代码沙箱 梳理判题模块和代码沙箱的关系 判题模块&#xff1a;调用代码沙箱 把代码和输入交给代码沙箱去执行 代码沙箱&#xff1a;只负责接受代码和输入 返回编译的结果 不负…

mat (Eclipse Memory Analyzer Tool)使用以及详解

前言 在Java开发中&#xff0c;内存问题往往不易被发现&#xff0c;但它们可能导致应用性能下降甚至崩溃。Eclipse Memory Analyzer Tool&#xff08;MAT&#xff09;是一个强大的开源工具&#xff0c;专门用于分析Java堆转储&#xff08;heap dumps&#xff09;文件&#xff…

【含文档】基于Springboot+Vue的高校竞赛管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 系统定义了三个…

2024四川省赛 The 2024 Sichuan Provincial Collegiate Programming Contest补题记录

B - Link Summon(补) 题意 每一组样例给定五个数字&#xff0c;分别对应1 2 3 4 5的数量&#xff0c;问能凑出多少个6(每个数字都可以当对应数字或者1使用) 思路 由于数字的数量固定&#xff0c;所以为了尽可能凑出多个6&#xff0c;贪心优先选择数量最少的数字配对方式 首…