uniapp 如何引入eacharts折线图,并实现Tab切换更新数据概述:本文eacharts采用uCharts组件,
概述:本文eacharts采用uCharts组件,tab采用Uniapp插件市场的sevenq-tab插件,废话不多说,直接上代码。
效果图:
线上体验地址:http://59.172.38.221:8014/#/
1. 下载sevenq-tab插件: 插件地址:ext.dcloud.net.cn/plugin?id=1…
2. 下载uCharts插件 插件地址:ext.dcloud.net.cn/search?q=uC…
2. 下载成功效果图:
- 下载导入成功后,在uni_modules文件下即可有两个该组件,页面无需引用,直接使用
3.页面使用
<template>
<view class="main-container">
<!-- #ifdef MP-WEIXIN -->
<u-navbar title="统一收银数据大屏" > </u-navbar>
<!-- #endif -->
<sevenq-tab :active-tab="activeTab" :tab-list="tabList" :object-style="objectStyle" @change="onTab">
</sevenq-tab>
<view class="today-data" :class="activeTab == 0 ? 'right-border' : activeTab == 3 ? 'left-border' : activeTab == 1 || activeTab == 2 ? 'border-radius' : ''">
<view class="content" :class="activeTab !== 4 ? '' : ''">
<view class="tittle">今日数据</view>
<view class="today-statistics top">
<view class="top-lable">累计流水</view>
<view class="flex">
<view class="mount-symbol">¥</view>
<view class="top-mount">{{ totalAmount || 0 }}</view>
</view>
</view>
<view class="today-statistics bottom">
<view class="top-lable">当日流水</view>
<view class="flex">
<view class="mount-symbol">¥</view>
<view class="top-mount">{{ todayAmount || 0 }}</view>
</view>
</view>
<view class="tittle">增长趋势</view>
<view class="common-hot seven-hot">近7天</view>
<view class="charts-box">
<sevenEacharts ref="sevenEacharts"></sevenEacharts>
</view>
<view class="common-hot seven-hot other-hot">近15天</view>
<view class="charts-box">
<middleEacharts ref="middleEacharts"></middleEacharts>
</view>
<view class="common-hot seven-hot">近30天</view>
<view class="charts-box">
<MonthEacharts ref="MonthEacharts"></MonthEacharts>
</view>
</view>
</view>
</view>
</template>
<script>
import sevenEacharts from "./sevenEacharts"
import MonthEacharts from "./MonthEacharts"
import middleEacharts from "./middleEacharts"
export default {
components: {
sevenEacharts,
MonthEacharts,
middleEacharts
},
data() {
return {
activeTab: 0,
totalAmount: 0,
todayAmount: 0,
tittle: '统一收银数据大屏',
tabList: [
{ id: 0, label: '整体统计'},
{ id: 1, label: '商业统计'},
{ id: 2, label: '硃山统计'},
{ id: 3, label: '奥姿统计'},
],
objectStyle: {
tabHeight: "50px",
activeColor: "#ffffff",
defaultColor: "#e2e8f8",
primaryColor: "#506CEB",
borderRadius: '12px',
deviceId: uni.getSystemInfoSync().deviceId
}
}
},
onLoad() {
this.activeTab = 0
this.getStatistics()
},
methods: {
getStatistics() {
this.$H.get('/trade/statistics/getTradeStatistics', {type: this.activeTab}, { deviceId: this.deviceId }).then(res => {
if (res.code == 200) {
this.totalAmount = res.data.totalAmount
this.todayAmount = res.data.todayAmount
}
});
},
onTab(e) {
this.activeTab = e
this.getStatistics()
this.$refs.sevenEacharts.getInitEacharts(this.activeTab, this.deviceId)
this.$refs.middleEacharts.getInitEacharts(this.activeTab, this.deviceId)
this.$refs.MonthEacharts.getInitEacharts(this.activeTab, this.deviceId)
}
}
}
</script>
<style lang="scss" scoped>
.right-border {
border-radius: 0 20rpx 0 0;
}
.left-border {
border-radius: 0 0 0 20rpx;
}
.border-radius {
border-radius: 20rpx;
}
.today-data {
background-color: #fff;
padding: 15rpx 15rpx 0 15rpx;
margin: 0 18rpx 18rpx 18rpx;
.tittle {
font-weight: 600;
color: #000000;
font-size: 28rpx;
margin-bottom: 25rpx;
}
.top {
background-image: linear-gradient(to right, #88CCFE, #5380FD);
}
.bottom {
background-image: linear-gradient(to right, #69DEEB, #42F8FE);
}
.today-statistics {
color: #fff;
margin: 25rpx 0;
border-radius: 12rpx;
text-align: center;
padding: 20rpx 0 10rpx 0;
background-color: #5FB1FE;
.top-lable {
font-size: 25rpx;
margin-bottom: -7rpx;
}
.flex {
justify-content: center;
.mount-symbol {
font-size: 25rpx;
margin: 25rpx 5rpx 0 0;
}
.top-mount {
font-size: 46rpx;
}
}
}
.common-hot {
width: 100rpx;
border-radius: 12rpx;
font-size: 28rpx;
color: #fff;
text-align: center;
}
.seven-hot {
background-color: #1487FF;
}
.other-hot {
background-color: #34D4EB;
}
}
.charts-box {
width: 100%;
height: 300px;
}
.main-container {
// background-image: linear-gradient(to bottom, #D3E9FD, #F2F7FD);
background: linear-gradient( 360deg, #F4F7FD 0%, #D3E9FD 100%)!important;
.inner-box {
width: 100%;
height: 420rpx;
background-color: #fff;
padding: 15rpx;
border-bottom-left-radius: 24rpx;
border-bottom-right-radius: 24rpx;
}
}
/* #ifdef MP-WEIXIN */
::v-deep .tab-list .tab-selected::before {
height: 50px !important;
}
::v-deep .tab-list .tab-selected::after {
height: 50px !important;
}
::v-deep .tab-list .not-selected::before {
height: 50px !important;
}
::v-deep .tab-list .not-selected::after {
height: 50px !important;
}
/* #endif */
</style>
- sevenq-tab 插件里的单位都是px,unaipp运行到各自平台,根本不能适配,这里是坑,所以需要将px换算成对应的rpx,具体修改后代码如下:
<template>
<view class="tab-container">
<view class="tab-list" :style="{backgroundColor:objectStyle.defaultColor}">
<view v-for="tab in tabList" :key="tab.id" class="tab-item"
:class="activeTab === tab.id ? 'tab-selected' : 'not-selected'" @click="onTab(tab.id)"
:style="activeTab === tab.id?wxObjectStyle:defaultObjectStyle">
<view>{{ tab.label }}</view>
</view>
</view>
<view class="tab-content">
<slot :name="activeTab"></slot>
</view>
</view>
</template>
<script>
export default {
props: {
//当前激活的tab栏id
activeTab: {
type: Number,
default: 1
},
//tab栏的数据 id需对应上
tabList: {
type: Array,
default: () => {
return []
}
},
//主题样式
objectStyle: {
type: Object,
default: () => {
return {
tabHeight: "52px",
activeColor: "#ffffff",
defaultColor: "#e2e8f8",
primaryColor: "#406CED",
borderRadius: '12px'
}
}
}
},
methods: {
onTab(e) { //传递当前选中的标签
this.$emit('change', e)
},
},
computed: {
styleObject() { //主题样式
const obj = {
'--tab-height': this.objectStyle.tabHeight,
'--active-color': this.objectStyle.activeColor,
'--default-color': this.objectStyle.defaultColor,
'--primary-color': this.objectStyle.primaryColor,
'--border-radius': this.objectStyle.borderRadius
};
return obj
},
boxShadowOffset() { //动态计算涟漪量
const getBoxHeight = parseFloat(this.objectStyle.tabHeight.replace(/\D/g, ''));
return getBoxHeight / 1.3
},
dynamicBoxShadowStyle() { //APP端动态计算阴影偏移度
const activeColor = this.objectStyle.activeColor;
return {
'--shadow-offset': `${this.boxShadowOffset}px`,
'box-shadow': `24px var(--shadow-offset) 0 ${activeColor}, -24px var(--shadow-offset) 0 0 ${activeColor}`,
};
},
wxObjectStyle() { //小程序端动态计算阴影偏移度 (小程序使用计算属性动态绑定style必须返回字符串形式)
const getBoxHeight = parseFloat(this.objectStyle.tabHeight.replace(/\D/g, ''));
const activeColor = this.objectStyle.activeColor;
const offset = (getBoxHeight / 1.3)
const height=this.objectStyle.tabHeight
return `height:${height};box-shadow: 24px ${offset}px 0 ${activeColor}, -24px ${offset}px 0 0 ${activeColor};`
},
defaultObjectStyle(){
const height=this.objectStyle.tabHeight
return `height:${height}`
}
},
}
</script>
<style lang="scss" scoped>
.tab-container {
margin: 0 18rpx;
.tab-list {
display: flex;
position: relative;
z-index: 2;
background-color: #e2e8f8;
overflow: hidden; // 重点
.tab-item {
flex: 1;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
// opacity: 0.65; // 暂时删除,不选中样式需要重新编写
// font-weight: 600;
position: relative;
}
.tab-selected {
opacity: 1;
background: #ffffff;
color: #527BFD;
font-weight: 600;
border-radius: 10px 10px 0 0;
}
.tab-selected::before {
content: '';
position: absolute;
left: -10rpx;
bottom: 0;
width: 22rpx;
height: 102rpx;
border-top-left-radius: 10px;
background-color: #ffffff;
transform: skewX(-15deg); // 重点
}
.tab-selected::after {
content: '';
position: absolute;
right: -10rpx;
bottom: 0;
width: 22rpx;
height: 102rpx;
border-top-right-radius: 10px;
background-color: #ffffff;
transform: skewX(15deg); // 重点
}
.not-selected::before {
content: '';
position: absolute;
left: 12rpx;
bottom: 0;
width: 22rpx;
height: 102rpx;
background: #e2e8f8;
border-bottom-left-radius: 10px;
transform: skewX(15deg); // 重点
}
.not-selected::after {
content: '';
position: absolute;
right: 12rpx;
bottom: 0;
width: 22rpx;
height:102rpx;
background: #e2e8f8;
border-bottom-right-radius: 10px;
transform: skewX(-15deg); // 重点
z-index: 1;
}
}
}
</style>
4. 页面如果有多个eacharts,需要将eacharts提取成组件,单独引入使用,否则数据会被最后一个eacharts数据覆盖,造成多个eacharts数据一样,本文三个eacharts组件代码一致,只是接口数据不一致,本文只展示其中一个组件,其他组件复制引用即可
- 如果启用了X轴滚动条,需要开启canvas2d,ontouch,onmovetip模式
<template>
<qiun-data-charts :canvas2d="true" :ontouch="true" :onmovetip="true" type="line" :opts="optsConfig" :chartData="charResultData"/>
</view>
</template>
<script>
export default {
data() {
return {
activeTab: 0,
configData: {
categories: [],
series: [
{
name: "",
linearColor: [
[
0,
"#1890FF"
],
[
0.25,
"#00B5FF"
],
[
0.5,
"#00D1ED"
],
[
0.75,
"#00E6BB"
],
[
1,
"#90F489"
]
],
setShadow: [
3,
8,
10,
"#1890FF"
],
data: []
},
]
},
optsConfig : {
update:true,
scrollAlign:'left',//图表滚动条起始位置
canvasSevenId: new Date().getTime() + 1,
color: ["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
padding: [20,0,20,0], // 画布填充边距,顺序为上右下左
dataLabel: false,
dataPointShape: false,
enableScroll: true, //是否显示滚动条,默认false
legend: {
show:false
},
xAxis: {
scrollShow: true, //是否显示滚动条,默认false
itemCount: 7,
disableGrid: true
},
yAxis: {
gridType: "dash",
dashLength: 2,
data: [
{
min: 0,
max: 1000
}
]
},
extra: {
line: {
type: "curve",
width: 2,
activeType: "hollow",
linearType: "custom",
onShadow: true,
animation: "horizontal"
}
}
},
charResultData: {},
}
},
mounted() {
this.getEacharts()
},
methods: {
getInitEacharts(activeTab) {
this.activeTab = activeTab
this.charResultData = {}
this.getEacharts()
},
getEacharts() {
this.$H.get('/trade/statistics/getTradeChart', {type: this.activeTab, dateType: 2 }, { deviceId: uni.getSystemInfoSync().deviceId }).then(res => {
if (res.code == 200) {
// 近7天数据
let mountEachart = []
let eachartCategories = []
res.data.forEach((item) => {
eachartCategories.push(item.date.split('-').slice(1).join('-'))
mountEachart.push(item.dayAmount)
})
// 横轴
this.configData.categories = eachartCategories
// 纵轴
this.configData.series[0].data = mountEachart
// 纵轴最大值
this.optsConfig.yAxis.data[0].max = Math.max(...mountEachart)
this.charResultData = JSON.parse(JSON.stringify(this.configData));
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
END...
转载自:https://juejin.cn/post/7425704711775174694