年前的时候也做了echarts的封装,但是不知道为什么,在真机测试的时候,就是渲染不出来,图表不显示。
今天终于可以在真机渲染出来了!!!好激动!
效果图
图一H5的:
图二是华为手机的:
项目结构:
1.echarts组件:
<template>
<view>
<view class="echarts" :id="option.id" :prop="option" :change:prop="echarts.update" @click="echarts.onClick"></view>
</view>
</template>
<script>
export default {
name: 'Echarts',
props: {
option: {
type: Object,
required: true
}
},
created() {
// 设置随机数id
let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let len = t.length
let id = ''
for (let i = 0; i < 32; i++) {
id += t.charAt(Math.floor(Math.random() * len))
}
this.option.id = id
},
methods: {
/**
* renderjs内的点击事件,回调到父组件
* @param {Object} params
*/
onViewClick(params) {
this.$emit('click', params)
}
}
}
</script>
<script module="echarts" lang="renderjs">
import echarts from '@/components/echarts/echarts.min.js'
export default {
data() {
return {
chart: null,
clickData: null // echarts点击事件的值
}
},
mounted() {
this.init();
},
methods: {
/**
* 初始化echarts
*/
init() {
// 根据id初始化图表
this.chart = echarts.init(document.getElementById(this.option.id))
this.update(this.option)
// echarts的点击事件
this.chart.on('click', params => {
// 把点击事件的数据缓存下来
this.clickData = params
})
},
/**
* 点击事件,可传递到外部
* @param {Object} event
* @param {Object} instance
*/
onClick(event, instance) {
if (this.clickData) {
// 把echarts点击事件相关的值传递到renderjs外
instance.callMethod('onViewClick', {
value: this.clickData.data,
name: this.clickData.name,
seriesName: this.clickData.seriesName
})
// 上次点击数据置空
this.clickData = null
}
},
/**
* 监测数据更新
* @param {Object} option
*/
update(option) {
if (this.chart) {
// 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数
if (option) {
// tooltip
if (option.tooltip) {
// 判断是否设置tooltip的位置
if (option.tooltip.positionStatus) {
option.tooltip.position = this.tooltipPosition()
}
// 判断是否格式化tooltip
// if (option.tooltip.formatterStatus) {
option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands)
// }
}
}
// 设置新的option
this.chart.setOption(option, option.notMerge)
}
},
/**
* 设置tooltip的位置,防止超出画布
*/
tooltipPosition() {
return (point, params, dom, rect, size) => {
// 其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小
let x = point[0]
let y = point[1]
let viewWidth = size.viewSize[0]
let viewHeight = size.viewSize[1]
let boxWidth = size.contentSize[0]
let boxHeight = size.contentSize[1]
let posX = 0 // x坐标位置
let posY = 0 // y坐标位置
if (x >= boxWidth) { // 左边放的下
posX = x - boxWidth - 1
}
if (y >= boxHeight) { // 上边放的下
posY = y - boxHeight - 1
}
return [posX, posY]
}
},
/**
* tooltip格式化
* @param {Object} unit 数值后的单位
* @param {Object} formatFloat2 是否保留两位小数
* @param {Object} formatThousands 是否添加千分位
*/
tooltipFormatter(unit, formatFloat2, formatThousands) {
return params => {
let result = ''
// unit = unit ? unit : ''
for (let i in params) {
if (i == 0) {
result += params[i].data.date
}
let value = '--'
if (params[i].data !== null) {
if(params[i].seriesName=='睡眠效率平均'){
unit='%'
}else if(params[i].seriesName=='睡眠时长平均'||params[i].seriesName=='卧床时长平均'){
unit='h'
}else if(params[i].seriesName=='酒平均'||params[i].seriesName=='咖啡平均'){
unit='杯'
}else if(params[i].seriesName=='烟平均'){
unit='根'
}
value = params[i].data
// 保留两位小数
// if (formatFloat2) {
// value = this.formatFloat2(value)
// }
// 添加千分位
// if (formatThousands) {
// value = this.formatThousands(value)
// }
}
// #ifdef H5
result += '\n' + params[i].seriesName + ':' + params[i].data.value + unit
// #endif
// #ifdef APP-PLUS
result += '<br/>' + params[i].marker + params[i].seriesName + ':' + params[i].data.value + unit
// #endif
}
return result
}
},
/**
* 保留两位小数
* @param {Object} value
*/
formatFloat2(value) {
let temp = Math.round(parseFloat(value) * 100) / 100
let xsd = temp.toString().split('.')
if (xsd.length === 1) {
temp = (isNaN(temp) ? '0' : temp.toString()) + '.00'
return temp
}
if (xsd.length > 1) {
if (xsd[1].length < 2) {
temp = temp.toString() + '0'
}
return temp
}
},
/**
* 添加千分位
* @param {Object} value
*/
formatThousands(value) {
if (value === undefined || value === null) {
value = ''
}
if (!isNaN(value)) {
value = value + ''
}
let re = /\d{1,3}(?=(\d{3})+$)/g
let n1 = value.replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) {
return s1.replace(re, '$&,') + s2
})
return n1
}
}
}
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
}
</style>
2.依赖的库echarts.min.js
这个字数太多了,从官网下载就行了,或者去GitHub拿
https://github.com/apache/echarts/tree/4.2.1/dist
3. 使用示例
<template>
<view>
<echarts :option="option" style="height: 560rpx;" @click="echartsClick"></echarts>
<button @click="updateClick">切换数据</button>
</view>
</template>
<script>
import echarts from '@/components/echarts/echarts.vue'
export default {
data() {
return {
option: {},
option2: {
//dataZoom-inside 内置型数据区域缩放组件 所谓内置 1平移:在坐标系中滑动拖拽进行数据区域平移。2缩放:PC端:鼠标在坐标系范围内滚轮滚动(MAC触控板类同;移动端:在移动端触屏上,支持两指滑动缩放。
dataZoom: [
{
type: 'inside', //1平移 缩放
throttle: '50', //设置触发视图刷新的频率。单位为毫秒(ms)。
minValueSpan: 6, //用于限制窗口大小的最小值,在类目轴上可以设置为 5 表示 5 个类目
start: 1, //数据窗口范围的起始百分比 范围是:0 ~ 100。表示 0% ~ 100%。
end:20, //数据窗口范围的结束百分比。范围是:0 ~ 100。
zoomLock: true //如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。
}
],
// 主要用来控制图表四周留白
grid: {
left: '15%',
top: '10%'
},
// 提示框组件
tooltip: {
trigger: 'axis', //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
backgroundColor: '#505050', //提示框浮层的背景颜色。
textStyle:{
color: '#ffffff' // 坐标轴线线的颜色。
},
// 自定义提示框内容
formatter: function (params, ticket, callback) {
var text ='湿度平均: ' + params[0].data.value+"%\n";
var sleep = '工作平均: ' + params[1].data.value+"h\n";
var bed = '休息平均: ' + params[2].data.value+"h\n";
return text+sleep+bed;
},
position: function (point, params, dom, rect, size) {
// 固定在顶部
return 'top';
}
},
//直角坐标系 grid 中的 x 轴,
xAxis: {
type: 'category', //'category' 类目轴,适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
nameTextStyle: {
fontSize: 30
},
// 坐标轴轴线相关设置
axisLine: {
lineStyle: {
color: '#E5E5E5' // 坐标轴线线的颜色。
}
},
// 坐标轴刻度标签(类目,简单说就是x轴上的内容)的相关设置
axisLabel: {
// 是否显示坐标刻度标签(这了指是否显示x轴上的月份)
show: true,
// 标签文字的颜色
color: '#000000'
},
axisPointer: {
//去掉移动的指示线
type: 'line',
// snap: true,
handle: {
show: true,
color: '#969696',
size:20
},
},
//x轴刻度线设置
axisTick: {
show: true
},
// 类目数据,在类目轴(type: 'category')中有效。
data: [
'1/1',
'1/2',
'1/3',
'1/4',
'1/5',
'1/6',
'1/7',
'1/8',
'1/9',
'1/10',
'1/11',
'1/12',
'1/13',
'1/14',
'1/15',
'1/16',
'1/17',
'1/18',
'1/19',
'1/20',
'1/21',
'1/22',
'1/23',
'1/24',
'1/25',
'1/26',
'1/27',
'1/28',
'1/29',
'1/30',
'1/31'
],
},
//直角坐标系 grid 中的 y 轴,
yAxis: [
{
type: 'value', //'value' 数值轴,适用于连续数据。
min: 0,
max: 100,
// 坐标轴轴线相关设置
axisLine: {
show: false //y轴线消失
},
// 坐标轴刻度标签(类目,简单说就是x轴上的内容)的相关设置
axisLabel: {
show: true,
// 标签文字的颜色
color: '#999',
formatter: '{value} %'
},
//y轴刻度线设置
axisTick: {
show: false
},
splitNumber: 5 //坐标轴的分割段数,需要注意的是这个分割段数只是个预估值,最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整.在类目轴中无效。
},
{
type: 'value',
min: 0,
splitNumber:5,
axisLine: {
show: false //y轴线消失
},
max: 15,
axisLabel: {
formatter: '{value} h'
}
},
],
series: [
{
type: 'line', //折线图是用折线将各个数据点标志连接起来的图表,用于展现数据的变化趋势。和全局设置type效果一样,表示折线图
// 系列中的数据内容数组。数组项通常为具体的数据项。
yAxisIndex: 0,
data: [
{
value: 80,
date: '2022年1月1日'
},
{
value: 86,
date: '2022年1月2日'
},
{
value: 87,
date: '2022年1月3日'
},
{
value: 85,
date: '2022年1月4日'
},
{
value: 90,
date: '2022年1月5日'
},
{
value: 91,
date: '2022年1月6日'
},
{
value: 92,
date: '2022年1月7日'
},
{
value: 93,
date: '2022年1月8日'
},
{
value: 89,
date: '2022年1月9日'
},
{
value: 78,
date: '2022年1月10日'
},
{
value: 83,
date: '2022年1月11日'
},
{
value: 77,
date: '2022年1月12日'
},
{
value: 80,
date: '2022年1月13日'
},
{
value: 86,
date: '2022年1月14日'
},
{
value: 87,
date: '2022年1月15日'
},
{
value: 85,
date: '2022年1月16日'
},
{
value: 90,
date: '2022年1月17日'
},
{
value: 91,
date: '2022年1月18日'
},
{
value: 92,
date: '2022年1月19日'
},
{
value: 93,
date: '2022年1月20日'
},
{
value: 89,
date: '2022年1月21日'
},
{
value: 78,
date: '2022年1月22日'
},
{
value: 83,
date: '2022年1月23日'
},
{
value: 77,
date: '2022年1月24日'
},
{
value: 93,
date: '2022年1月25日'
},
{
value: 89,
date: '2022年1月26日'
},
{
value: 78,
date: '2022年1月27日'
},
{
value: 83,
date: '2022年1月28日'
},
{
value: 77,
date: '2022年1月29日'
},
{
value: 77,
date: '2022年1月30日'
},
{
value: 77,
date: '2022年1月31日'
},
],
// 折线条的样式
lineStyle: {
color: '#2f5f8f',
width: 1
},
// 折线拐点的样式
itemStyle: {
normal: {
// 静止时:
color: '#2f5f8f'
},
emphasis: {
// 鼠标经过时:
color: '#2f5f8f'
}
},
symbol: 'emptyCircle', //拐点样式
symbolSize: 6 //拐点大小
},
{
type: 'line', //折线图是用折线将各个数据点标志连接起来的图表,用于展现数据的变化趋势。和全局设置type效果一样,表示折线图
// 系列中的数据内容数组。数组项通常为具体的数据项。
yAxisIndex: 1,
data: [
{
value: 8,
date: '2022年1月1日'
},
{
value: 8,
date: '2022年1月2日'
},
{
value: 7,
date: '2022年1月3日'
},
{
value: 8,
date: '2022年1月4日'
},
{
value: 9,
date: '2022年1月5日'
},
{
value: 9,
date: '2022年1月6日'
},
{
value: 9,
date: '2022年1月7日'
},
{
value: 9.3,
date: '2022年1月8日'
},
{
value: 8.9,
date: '2022年1月9日'
},
{
value: 7.8,
date: '2022年1月10日'
},
{
value: 8.3,
date: '2022年1月11日'
},
{
value: 7.7,
date: '2022年1月12日'
},
{
value: 8.0,
date: '2022年1月13日'
},
{
value: 8.6,
date: '2022年1月14日'
},
{
value: 8.7,
date: '2022年1月15日'
},
{
value: 8.5,
date: '2022年1月16日'
},
{
value: 9,
date: '2022年1月17日'
},
{
value: 9.1,
date: '2022年1月18日'
},
{
value: 9.2,
date: '2022年1月19日'
},
{
value: 9.3,
date: '2022年1月20日'
},
{
value: 8.9,
date: '2022年1月21日'
},
{
value: 7.8,
date: '2022年1月22日'
},
{
value: 8.3,
date: '2022年1月23日'
},
{
value: 7.7,
date: '2022年1月24日'
},
{
value: 9.3,
date: '2022年1月25日'
},
{
value: 8.9,
date: '2022年1月26日'
},
{
value: 7.8,
date: '2022年1月27日'
},
{
value: 8.3,
date: '2022年1月28日'
},
{
value: 7.7,
date: '2022年1月29日'
},
{
value: 7.7,
date: '2022年1月30日'
},
{
value: 7.7,
date: '2022年1月31日'
},
],
// 折线条的样式
lineStyle: {
color: '#3c79b6',
width: 1
},
// 折线拐点的样式
itemStyle: {
normal: {
// 静止时:
color: '#3c79b6'
},
emphasis: {
// 鼠标经过时:
color: '#3c79b6'
}
},
symbol: 'emptyCircle', //拐点样式
symbolSize: 6 //拐点大小
},
{
type: 'line', //折线图是用折线将各个数据点标志连接起来的图表,用于展现数据的变化趋势。和全局设置type效果一样,表示折线图
// 系列中的数据内容数组。数组项通常为具体的数据项。
yAxisIndex: 1,
data:[
{
value: 7,
date: '2022年1月1日'
},
{
value: 6,
date: '2022年1月2日'
},
{
value: 7,
date: '2022年1月3日'
},
{
value: 5,
date: '2022年1月4日'
},
{
value: 9,
date: '2022年1月5日'
},
{
value: 9,
date: '2022年1月6日'
},
{
value: 9,
date: '2022年1月7日'
},
{
value: 9,
date: '2022年1月8日'
},
{
value: 8,
date: '2022年1月9日'
},
{
value: 7,
date: '2022年1月10日'
},
{
value: 8,
date: '2022年1月11日'
},
{
value: 7,
date: '2022年1月12日'
},
{
value: 8,
date: '2022年1月13日'
},
{
value: 8,
date: '2022年1月14日'
},
{
value: 8,
date: '2022年1月15日'
},
{
value: 8,
date: '2022年1月16日'
},
{
value: 9,
date: '2022年1月17日'
},
{
value: 9,
date: '2022年1月18日'
},
{
value: 9,
date: '2022年1月19日'
},
{
value: 9,
date: '2022年1月20日'
},
{
value: 8,
date: '2022年1月21日'
},
{
value: 7,
date: '2022年1月22日'
},
{
value: 8,
date: '2022年1月23日'
},
{
value: 7,
date: '2022年1月24日'
},
{
value: 9,
date: '2022年1月25日'
},
{
value: 8,
date: '2022年1月26日'
},
{
value: 7,
date: '2022年1月27日'
},
{
value: 8,
date: '2022年1月28日'
},
{
value: 7,
date: '2022年1月29日'
},
{
value: 7,
date: '2022年1月30日'
},
{
value: 7,
date: '2022年1月31日'
},
],
// 折线条的样式
lineStyle: {
color: '#55aaff',
width: 1
},
// 折线拐点的样式
itemStyle: {
normal: {
// 静止时:
color: '#55aaff'
},
emphasis: {
// 鼠标经过时:
color: '#55aaff'
}
},
symbol: 'emptyCircle', //拐点样式
symbolSize: 6 //拐点大小
},
]
},
option3: {
notMerge: true, // 自定义变量:true代表不合并数据,比如从折线图变为柱形图则需设置为true;false或不写代表合并
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
}
}]
}
};
},
components: {
echarts
},
onLoad() {
this.option = this.option3
},
methods: {
/**
* 点击事件
* @param {Object} params
*/
echartsClick(params) {
console.log('点击数据', params)
},
/**
* 切换数据
*/
updateClick() {
if (this.option === this.option2) {
this.option = this.option3
} else {
this.option = this.option2
}
}
}
};
</script>
<style></style>