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 no
仅支持 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。。
更多推荐
所有评论(0)