自己封装的在uniapp中使用echarts
本质是通过renderjs封装了一个极简echarts组件,可扩展性高,自由度高,已在安卓app中使用过。下面是模拟的调用方式。
·
本质是通过renderjs封装了一个极简echarts组件,可扩展性高,自由度高,已在安卓app中使用过
<template>
<view class="content-echarts">
<!-- #ifdef APP-PLUS || H5 -->
<view
id="echarts"
class="echarts"
:prop="renderOption"
:change:prop="echarts.updateEcharts"
@click="echarts.onClick"
/>
<!-- #endif -->
</view>
</template>
<script>
export default {
name: 'DynamicEcharts',
data() {
return {
// 初始给空对象,避免第一次 null
renderOption: {}
};
},
methods: {
/* 父组件通过 this.$refs.xxx.setChart(option) 调用 */
setChart(option) {
this.renderOption = JSON.parse(JSON.stringify(option));
}
}
};
</script>
<!-- ============ renderjs 逻辑 ============ -->
<script module="echarts" lang="renderjs">
let myChart = null;
let inited = false;
/* 统一的时间轴 formatter */
function timeFormatter(val) {
// val 形如 11-21 09:33
const [date, time] = val.split(' ');
const [m, d] = date.split('/');
return `${m}-${d}\n${time}`;
}
export default {
beforeDestroy() {
/* 关键:组件被 v-if 销毁时释放原生内存 */
if (myChart) {
myChart.dispose();
myChart = null;
}
inited = false;
},
methods: {
/* change:prop 入口 */
updateEcharts(newOption) {
if (!newOption || !Object.keys(newOption).length) return;
if (!inited) {
// 动态加载 echarts
if (typeof window.echarts === 'function') {
this.doInit(newOption);
} else {
const script = document.createElement('script');
script.src = 'static/echarts.js';
script.onload = () => this.doInit(newOption);
document.head.appendChild(script);
}
} else {
// 直接更新
if (newOption.xAxis?.axisLabel) {
newOption.xAxis.axisLabel.formatter = timeFormatter;
}
myChart.setOption(newOption, true);
}
},
doInit(option) {
myChart = window.echarts.init(document.getElementById('echarts'));
inited = true;
if (option.xAxis?.axisLabel) {
option.xAxis.axisLabel.formatter = timeFormatter;
}
if(typeof option.series[0] === 'object'){
option.series[0].areaStyle = {
opacity: 0.8,
color: new window.echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#80C962",
},
{
offset: 1,
color: "transparent",
},
]),
}
}
if(typeof option.series[1] === 'object'){
option.series[1].areaStyle = {
opacity: 0.8,
color: new window.echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#19A5E9",
},
{
offset: 1,
color: "transparent",
},
]),
}
}
myChart.setOption(option);
},
onClick(event, ownerInstance) {
// 如需向逻辑层抛事件,用 ownerInstance.callMethod
// ownerInstance.callMethod('onViewClick', { test: 'test' });
}
}
};
</script>
<style scoped>
.content-echarts {
width: 1180px;
height: 422px;
overflow: hidden;
background: #fafafa;
border-radius: 14px;
}
.echarts {
width: 1180px;
height: 422px;
}
</style>
下面是模拟的调用方式
const categories = [];
const tempData = [];
const humiData = [];
let [t, h, m] = [25, 26, 33]; // 初始值
const total = 50; // 数据条数(任意改)
// 随机波动函数
function randomFluctuation(base, range) {
return base + Math.random() * range - range / 2;
}
for (let i = 0; i < total; i++) {
categories.push(`11-21 09:${String(++m).padStart(2, '0')}`);
// 温度数据,以初始值为基础,加上随机波动
t = randomFluctuation(t, 2); // 波动范围为 ±1
tempData.push(t.toFixed(2)); // 保留两位小数
// 湿度数据,以初始值为基础,加上随机波动
h = randomFluctuation(h, 3); // 波动范围为 ±1.5
humiData.push(h.toFixed(2)); // 保留两位小数
}
/* 统一白色样式 */
const whiteStyle = {
color: '#222',
fontSize: 16, // 字号
lineStyle: {
color: '#555', // Y 轴颜色
width: 2 // Y 轴粗细
}
};
let option = {
backgroundColor: 'transparent', // 透明背景,适应黑色主题
title: { show: false },
legend: {
data: ['温度', '湿度'],
textStyle: whiteStyle, // 图例文字白色
top: 20,
},
grid: { left: '1.5%', right: '1.5%', bottom: '5%', top: '12%', containLabel: true },
xAxis: {
type: 'category',
boundaryGap: false,
data: categories,
axisLine: { ...whiteStyle, onZero: false }, // ❌ 去掉 X 轴轴线
axisTick: { show: false }, // 刻度线也隐藏(可选)
axisLabel: {
showMinLabel: true, // 保证第一个
showMaxLabel: true, // 保证最后一个
...whiteStyle, // 文字白色
}
},
yAxis: [
{
type: 'value',
name: '℃',
nameTextStyle: whiteStyle,
axisLabel: whiteStyle,
axisLine: whiteStyle, // Y 轴线想保留就留,颜色白色
axisTick: whiteStyle,
splitLine: { show: false },
alignTicks: true,
},
{
type: 'value',
name: '%',
alignTicks: true,
nameTextStyle: whiteStyle,
axisLabel: whiteStyle,
axisLine: whiteStyle,
axisTick: whiteStyle,
splitLine: { show: false }
}
],
series: [
{
showSymbol: false,
name: '温度',
type: 'line',
yAxisIndex: 0,
data: tempData,
smooth: true,
itemStyle: { color: '#80C962' },
lineStyle: {
color: '#80C962',
width: 2 // ← 加粗
},
},
{
showSymbol: false,
name: '湿度',
type: 'line',
yAxisIndex: 1,
data: humiData,
smooth: true,
itemStyle: { color: '#19A5E9' },
lineStyle: {
color: '#19A5E9',
width: 2 // ← 加粗
},
}
]
};
this.$refs.chart.setChart(option);
<view style="flex:1;width:100%;overflow:hidden;">
<EchartsDom ref="chart" />
</view>
更多推荐

所有评论(0)