uniapp app使用echart(renderjs, 仅支持 app-vue、h5 端)并封装成组件使用

仅支持 app-vue、h5 端

1.先根据文档renderjs说明,并且查看示例:https://ext.dcloud.net.cn/plugin?id=1207,下载renderjs-echarts-demo压缩包

2.将renderjs-echarts-demo\static的echarts拷贝放到项目目录static中,只能放到static目录中,不然会报错echarts.init is not a function,这个回答在示例地址底部作者有回答

3.复制renderjs-echarts-demo\pages\index的index.vue代码到你自己的页面,保存即可以显示图标,经测试在h5,模拟器,手机都可以查看图标

实现效果:

ps里面有一个坑,在app上formatter自定义函数不生效问题。解决方案:在setOption之前加上formatter方法,下面有具体写法

<template>
	<view class="content">
		<view :prop="option" :change:prop="echarts.updateEcharts" id="echarts" class="echarts"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				option: {
          color: ['#78b4d1', '#fcd664', '#78a999'],
          tooltip: {											//提示组件
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            }
          },
          legend: {
            data: [{
				name: '水',
				textStyle: {
				    color: '#999999' 
				}
			},{
				name: '电',
				textStyle: {
					color: '#999999' 
				}
			},{
				name: '冷量',
				textStyle: {
					color: '#999999' 
			    }
			}],
            icon: 'circle',								    //图例icon园
			top: '10%',
			align: 'right',								    //图例icon位置
			itemWidth: '10'								    //图例icon大小
          },
          grid: {
            left: '5%',
            right: '10%',
            bottom: '5%',
            containLabel: true						        //防止标签溢出
          },
          xAxis: {
			type: 'value',
			position: 'top',							    //横坐标位于顶部
			interval: 50,									//横坐标间距50
			splitLine: {
				lineStyle: {
					color: '#eeeeee',
					type: 'dashed'						    //轴线虚线
				}
			},
			axisLine: {										//坐标轴轴线隐藏
				show: false
            },
			axisTick: {										//坐标轴刻度隐藏
				show: false,
			},
			axisLabel: {									//坐标轴刻度文字
				color: '#999999'
			}
          },
          yAxis: {
			type: 'category',
			data: [{
				value: 'B栋',
				textStyle: {
					fontSize: 14
				}
			},{
				value: 'A栋',
				textStyle: {
					fontSize: 14
			    }
			}],
			axisLine: {										//坐标轴轴线隐藏
				show: false
            },
			splitLine: {									//坐标分割线隐藏
				show: false
			},
			axisTick: {                		                //坐标轴刻度隐藏
				show: false
			}
          },
          series: [
              {
                name: '水',
                type: 'bar',
				data: [110, 90],
				barGap: '150%',						        //类目 柱间距
				barCategoryGap: '40%',                      //类目 y轴值间距
				label: {
					show: true,							    //显示柱值
					position: 'right',			            //位置显示在右边
					color: '#000',
				},
              },
              {
                name: '电',
                type: 'bar',
				data: [140, 100],
				barGap: '150%',
				barCategoryGap: '40%',
				label: {
					show: true,
					position: 'right',
					color: '#000'
				}
              },{
                name: '冷量',
                type: 'bar',
				data: [130, 70],
				barGap: '150%',
				barCategoryGap: '40%',
				label: {
					show: true,
					position: 'right',
					color: '#000',
					// formatter: () => {    不这么做的原因是app上不生效,在setOption之前加上formatter方法

					// }
				}
              }
          ]
				}
			}
		},
		methods: {
		}
	}
</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'))
				// 这么做解决app上formatter自定义函数不生效问题。
				this.option.series[0].label.formatter = function formatter(data) {
					return data.value + 'm³'
				}
				this.option.series[1].label.formatter = function formatter(data) {
					return data.value + 'kwh'
				}
				this.option.series[2].label.formatter = function formatter(data) {
					return data.value + 'kwh'
				}
				// 观测更新的数据在 view 层可以直接访问到
				myChart.setOption(this.option)
			},
			updateEcharts(newValue, oldValue, ownerInstance, instance) {
				// 监听 service 层数据变更
				myChart.setOption(newValue)
			}
		}
	}
</script>

<style>
	.content {
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.echarts {
		/* margin-top: 100px; */
		width: 100%;
		height: 100%;
	}
</style>

封装组件

实现效果:一个组件,可以实现不同的图表功能

实现思路:

1.在同个页面使用多个图表,需要id名不一致

2.option配置项需改成配置项

实现过程:

1.父级传id名传给组件或者组件里生成随机数加上前缀

2.父级传option配置项传给组件

实现中出现问题:uniapp中的renderjs在app中是于逻辑层分开,无法获取逻辑层中的data或者props,所以无法给renderjs中的id无法改成配置项

解决过程思路:1.从逻辑层传入renderjs 2.既然逻辑层传入renderjs在app中无效,h5有效,那可不可以在renderjs定义变量传给逻辑层,在动态改变

解决过程分析:(主要为解决renderjs的id改成配置项的问题)

1.从逻辑层传入根据uniapp提供的dome,需要触发点击,即:change:prop,再通过ownerInstance.callMethod来调用method中的方法,但问题是,这个组件根本不用点击呀,如何在mouted中调用renderjs中的方法?翻看社区,百度,博客等,社区有给一个 this.$ownerInstance.callMethod,经测试,这个再h5有效,app无效,无法调用renderjs中的方法(不信你们可以自己试试),那咋办,社区等都找了个遍,无提供答案,那试试第二种了

2.在renderjs中定义一个随机数,然后通过this.$ownerInstance.callMethod传给逻辑层,然后动态改变,结果,h5跟app都空白。。。(有人试了可以的话,留言跟我说下,谢谢)

再出现一个解决思路:为什么renderjs中有一个this.option,为什么这个可以?

尝试:跟renderjs的this.option定义一样,那试试看定义一个跟他一模一样的会不会可以?

结果:没用,不管怎么定义,renderjs获取不到

再出现一个解决思路:那我把从新定义一个变量,在变量里面修改,再给:prop,会不会可以?

结果:可以。。。原因不明(有人知道的话,可以跟我说下,谢谢)

过程用到网址:https://ask.dcloud.net.cn/question/97817            https://ask.dcloud.net.cn/question/92340         有兴趣的可以研究下

效果

组件

<template>
	<view class="content">
		<view :prop="echartInfo" :change:prop="echarts.updateEcharts" :id="echartInfo.id" :class="echartInfo.id" style="width: 100%;height: 100%"></view>
	</view>
</template>

<script>
	export default {
    props: {
			echartInfo: {
				type: Object,
				default: () => {}
			}
		}
	}
</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() {
				let option = this.echartInfo.option
				let id = this.echartInfo.id
				myChart = echarts.init(document.getElementById(id))
				// 观测更新的数据在 view 层可以直接访问到
				myChart.setOption(option)
			},
			updateEcharts(newValue, oldValue, ownerInstance, instance) {
				// 监听 service 层数据变更
				myChart.setOption(newValue)
			}
		}
	}
</script>

<style>
	.content {
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}
</style>

页面

<template>
  <div class="minitor-container">
    <div class="minitor">
      <echart :echartInfo="echartInfo"></echart>
      <echart :echartInfo="echartInfo2"></echart>
    </div>
  </div>
</template>

<script>
  import echart from '@/components/echart'
  export default {
    components: {
      echart
    },
    data() {
      return {
        echartInfo: {
          id: 'echart1',
          option: {
            color: ['#78b4d1', '#fcd664', '#78a999'],
            tooltip: {											//提示组件
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            legend: {
              data: [{
                name: '水',
                textStyle: {
                  color: '#999999' 
                }
              },{
                name: '电',
                textStyle: {
                  color: '#999999' 
                }
              },{
                name: '冷量',
                textStyle: {
                  color: '#999999' 
                }
              }],
              icon: 'circle',								//图例icon园
              top: '10%',
              align: 'right',								//图例icon位置
              itemWidth: '10'								//图例icon大小
            },
            grid: {
              left: '5%',
              right: '10%',
              bottom: '5%',
              containLabel: true						//防止标签溢出
            },
            xAxis: {
              type: 'value',
              position: 'top',							//横坐标位于顶部
              interval: 50,									//横坐标间距50
              splitLine: {
                lineStyle: {
                  color: '#eeeeee',
                  type: 'dashed'						//轴线虚线
                }
              },
              axisLine: {										//坐标轴轴线隐藏
                show: false
              },
              axisTick: {										//坐标轴刻度隐藏
                show: false,
              },
              axisLabel: {									//坐标轴刻度文字
                color: '#999999'
              }
            },
            yAxis: {
              type: 'category',
              data: [{
                value: 'A栋',
                textStyle: {
                  fontSize: 14
                }
              },{
                value: 'B栋',
                textStyle: {
                  fontSize: 14
                }
              }],
              axisLine: {										//坐标轴轴线隐藏
                show: false
              },
              splitLine: {									//坐标分割线隐藏
                show: false
              },
              axisTick: {                		//坐标轴刻度隐藏
                show: false
              },
              inverse: true
            },
            series: [
                {
                  name: '水',
                  type: 'bar',
                  data: [110, 90],
                  barGap: '150%',						//类目 柱间距
                  barCategoryGap: '40%',    //类目 y轴值间距
                  label: {
                    show: true,							//显示柱值
                    position: 'right',			//位置显示在右边
                    color: '#000',
                    formatter:"{c}m³"
                  }
                },
                {
                  name: '电',
                  type: 'bar',
                  data: [140, 100],
                  barGap: '150%',
                  barCategoryGap: '40%',
                  label: {
                    show: true,
                    position: 'right',
                    color: '#000',
                    formatter:"{c}m³"
                  }
                },{
                  name: '冷量',
                  type: 'bar',
                  data: [130, 70],
                  barGap: '150%',
                  barCategoryGap: '40%',
                  label: {
                    show: true,
                    position: 'right',
                    color: '#000',
                    // unit: 'm³'
                    formatter:"{c}m³"
                  }
                }
            ]
          },
        },
        echartInfo2: {
          id: 'echart_2',
          option: {
            // color: ['#5eb0f1'],
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            grid: {
              left: '5%',
              right: '10%',
              top: '10%',
              containLabel: true
            },
            xAxis: {
              type: 'value',
              axisLine: {
                show: false
              },
              axisLabel: {
                show: false
              },
              axisTick: {
                show: false
              },
              splitLine: {
                show: false
              }
            },
            yAxis: [{
              type: 'category',
              data: ['视频监控', '视频监控', '视频监控', '视频监控', '视频监控', '视频监控'],
              axisLine: {
                show: false
              },
              axisTick: {
                show: false
              },
              splitLine: {
                show: false
              },
              inverse:true
            },{
              type: 'category',
              data: ['100','80','50','80','50','80'],
              axisLine: {
                show: false
              },
              axisTick: {
                show: false
              },
              splitLine: {
                show: false
              },
              inverse:true
            }],
            series: [{
              type: 'bar',
              yAxisIndex: 0,
              data: ['100','80','50','80','50','80'],
              barWidth: 6,
              itemStyle: {
                normal: {
                  color: '#5eb0f1',
                }
              },
              label:{
                show: false,
                // position:"right",
                // formatter:"{c}%"
              }
            }, {
              type: 'bar',
              silent: true,
              yAxisIndex: 1,
              barWidth: 6,
              itemStyle: {
                normal: {
                  color: 'rgba(180, 180, 180, 0.2)',
                }
              },
              data: ['100', '100', '100', '100', '100', '100']
            }]
          }
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
.minitor-container{
  height: 100%;
  background-color: #fff;
  .minitor{
    height: 400rpx
  }
}
</style>

ps:因为uniapp上的demo的echart.js不是最新的,很多新的echart配置不能用,需要去下载最新的echart.js替换即可,地址:

https://echarts.apache.org/zh/changelog.html#v5-0-1

https://github.com/apache/echarts/tree/5.0.1/dist

 

第二种app使用echarts方法,那就是写html,用iframe嵌入,很明显小程序也是不支持的,h5和app都可以,不过多个图表得写多个html。。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Uniapp是一个基于Vue.js的跨平台开发框架,可以同时开发小程序、H5APP等多个平台。在Uniapp封装组件使用的步骤如下: 1. 创建组件文件夹:在项目中的components文件夹下新建一个文件夹,用于存放封装组件。 2. 创建组件:在新建的组件文件夹中创建.vue文件,编写组件的模板、样式和逻辑代码。例如: ```vue <template> <view> <text>{{message}}</text> <button @click="handleClick">点击</button> </view> </template> <script> export default { data() { return { message: 'Hello World!' } }, methods: { handleClick() { console.log('click') } } } </script> <style> .view { display: flex; justify-content: center; align-items: center; height: 100%; } </style> ``` 3. 注册组件:在组件文件夹下新建一个index.js文件,用于注册组件。例如: ```js import MyComponent from './MyComponent.vue' export default { install(Vue) { Vue.component('my-component', MyComponent) } } ``` 4. 引入组件:在需要使用组件的页面中,引入该组件并调用install方法进行注册。例如: ```js import Vue from 'vue' import MyComponent from '@/components/my-component/index.js' Vue.use(MyComponent) ``` 5. 使用组件:在模板中使用组件即可。例如: ```vue <template> <view> <my-component></my-component> </view> </template> ``` 以上就是Uniapp封装组件使用的步骤。需要注意的是,组件的命名应该遵循驼峰式命名规则,例如MyComponent。同时,注册组件使用组件名应该是短横线分隔命名规则,例如'my-component'。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值