ai-watch-app/components/sleep-info/sleep-info.vue

477 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<tm-nav-bar
left-icon="arrow-left"
title="睡眠"
@clickLeft="back"
:rightText="`全部数据`"
@clickRight="goAllPath" />
<view class="flx jcsb ac" style="height: 40rpx;background-color: #fff;padding: 20rpx;">
<view class="" style="font-size: 40rpx;font-weight: bold;">
</view>
<view class="" style="color: #b8b8b8;font-size: 24rpx;">
{{time}}
</view>
</view>
<view class="flx">
<view class="w-5">
<view class="canvas_box">
<canvas canvas-id="circleCanvas" style="width: 250px; height: 250px;margin: 0 auto;"></canvas>
<view class="" style="height: 40rpx;"></view>
<view class="flx flx_sb">
<view class="flx flx_ac">
<!-- color:'#e933dd',
bigColor:'#6452da', -->
<view class="circle" style="background-color:#6452da ;" >
</view>
<view class="sleep_info">
<view class="info_title">
睡眠时长
</view>
<view class="info_val">
{{sleep.shen}}
</view>
</view>
</view>
<view class="flx flx_ac">
<view class="sleep_info">
<view class="info_title" style="text-align: right;">
深度睡眠
</view>
<view class="info_val">
{{sleep.qian}}
</view>
</view>
<view class="circle" style="background-color:#e933dd ;">
</view>
</view>
</view>
</view>
</view>
<view class="w-5">
<view class="radius_box" style="margin: 20rpx;margin-top: 40rpx ;">
<view class="flx flx_sb title_box">
<view class="title">
{{sleep.shen}}
</view>
</view>
<sleep-list-data :canvas-id="'sleep-canvas-id'" :dataList="sleepList"></sleep-list-data>
<view class="flx flx_sb flx_ac" style="margin-top: 20rpx;">
<view class="flx flx_ac">
<view class="flx flx_ac">
<image src="../../static/icon/sleep.png" style="width: 30rpx;margin-right: 5rpx;" mode="widthFix"></image>
</view>
<view class="small-title" v-if="fallAsleepTime.length > 0">
{{ fallAsleepTime[2] }}:{{ fallAsleepTime[3] }} , {{ fallAsleepTime[0] }}/{{ fallAsleepTime[1] }}
</view>
<view class="small-title" v-else>
</view>
</view>
<view class="flx flx_ac">
<view class="small-title" v-if="exitSleepTime.length > 0">
{{ exitSleepTime[2] }}:{{ exitSleepTime[3] }} , {{ exitSleepTime[0] }}/{{ exitSleepTime[1] }}
</view>
<view class="small-title" v-else>
</view>
<view class="flx flx_ac">
<image src="../../static/image/richu.png" style="width: 50rpx;" mode="widthFix"></image>
</view>
</view>
</view>
</view>
<view class="radius_box" style="margin: 20rpx;padding-bottom: 20rpx;margin-top: 40rpx;" v-if="option.series[0].data.length > 0">
<view class="" style="font-size: 26rpx;margin-bottom: 30rpx;">
睡眠阶段
</view>
<view class="flx flx_sb">
<view class="">
<view style="width: 200rpx; height:200rpx;background-color: #fff;"><l-echart ref="chartRef" @finished="init"></l-echart></view>
</view>
<view class="flx flx_sb" style="width: 100%;margin-left: 40rpx;flex-direction: column;padding: 20rpx 0;padding-right: 40rpx;">
<view class="flx flx_sb line">
<view class="flx small-title flx_ac">
<view class="dian0 yuan" style="margin-right: 10rpx;">
</view>
<view class="">
深睡
</view>
</view>
<view class="">
<view class="c0">
{{ sleepData.shen }}%
</view>
</view>
</view>
<view class="flx flx_sb line">
<view class="flx small-title flx_ac">
<view class="dian1 yuan" style="margin-right: 10rpx;">
</view>
<view class="">
浅睡
</view>
</view>
<view class="">
<view class="c1">
{{ sleepData.qian }}%
</view>
</view>
</view>
<view class="flx flx_sb line">
<view class="flx small-title flx_ac">
<view class="dian2 yuan" style="margin-right: 10rpx;">
</view>
<view class="">
快速动眼
</view>
</view>
<view class="">
<view class="c2">
{{ sleepData.kuai }}%
</view>
</view>
</view>
</view>
</view>
</view>
<view class="radius_box" style="margin: 20rpx;padding-bottom: 20rpx;margin-top: 40rpx;">
<view class="flx flx_sb title_box flx_ac">
<view class="title" >
目标
</view>
<view class="more" style="font-size: 24rpx;">
8 小时
</view>
</view>
</view>
</view>
</view>
<view class="" style="height: 40rpx"></view>
</view>
</template>
<script>
import { mapGetters } from "vuex";
import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
export default {
name: 'sleep-info',
data() {
return {
sleepData:{
shen:0,
qian:0,
kuai:0
},
isOption:false,
isInit:false,
exitSleepTime:[],
fallAsleepTime:[],
option:{
tooltip: {
show:false
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
data:[],
type: 'pie',
radius: ['70%', '90%'],
avoidLabelOverlap: false,
labelLine: {
show: false
},
}
]
},
cavasConfig:{
canvasWidth: 250,
canvasHeight: 250,
lineWidth:20,
radius: 68, // 内圆的半径
startAngle: -90, // 起始角度,-90度即垂直方向的3点钟位置
bigRadius:90,// 外圆的半径
cxt:null,
colorBg:'#f7c1f5',
bigColorBg:'#d1ccf4',
color:'#e933dd',
bigColor:'#6452da',
bigAngle:0,
angle:0,
startSmallAngle:0,
bigStartAngle:0,
stop:0,
bigStop:0,
maxTime:480
},
sleepList:[],
time: new Date().toISOString().substring(0, 10),
sleep:{
shen:'0 分',
qian:'0 分'
}
}
},
watch:{
isInit(newVal,oldVal){
if(this.isOption == true){
this.doDrawPie()
}
},
isOption(newVal,oldVal){
if(this.isInit == true){
this.doDrawPie()
}
}
},
mounted() {
this.getDataList()
this.cavasConfig.ctx = uni.createCanvasContext('circleCanvas', this);
this.drawCircle('bottom',360,this.cavasConfig.bigRadius,this.cavasConfig.bigColorBg);
this.drawCircle('bottom',360,this.cavasConfig.radius,this.cavasConfig.colorBg);
},
computed: {
...mapGetters({
getActiceDevice: "api/getActiceDevice"
})
},
methods: {
init() {
this.isInit = true
console.log('iiiiiiiiiiiiint')
},
async doDrawPie(){
const chart = await this.$refs.chartRef.init(echarts);
chart.setOption(this.option)
},
countOccurrences(array, value) {
return array.reduce((count, current) => {
return current === value ? count + 1 : count;
}, 0);
},
back() {
this.$emit('back', 1)
},
// 全部数据
goAllPath() {
this.$emit('allData', 3)
},
getDataList(){
let type = 'SleepDatas'
let res = this.$store.dispatch('api/getDeviceListDays', {
type: type,
// type: (this.type),
device_real_time: this.time,
device_id:this.getActiceDevice.device_id
}).then(res => {
if(res.data.length > 0){
this.sleep.shen = this.min2Hour(res.data[0].data_msg[0].sleepTotalTime)
this.sleep.qian = this.min2Hour(res.data[0].data_msg[0].deepSleepTime)
this.cavasConfig.angle = this.getAngle(res.data[0].data_msg[0].deepSleepTime)
this.cavasConfig.bigAngle = this.getAngle(res.data[0].data_msg[0].sleepTotalTime)
this.sleepList = res.data[0].data_msg[0].sleepCurve
this.option.series[0].data = [
{
value:this.countOccurrences(this.sleepList,0),
itemStyle:{
color:'#e933dd'
}
},
{
value:this.countOccurrences(this.sleepList,1),
itemStyle:{
color:'#6452da'
}
},
{
value:this.countOccurrences(this.sleepList,2),
itemStyle:{
color:'#4faffc'
}
},
];
let len = this.sleepList.length
this.sleepData.shen = this.getPercent(this.sleepList,0)
this.sleepData.qian = this.getPercent(this.sleepList,1)
this.sleepData.kuai = this.getPercent(this.sleepList,2)
this.exitSleepTime = res.data[0].data_msg[0].exitSleepTime.split('-')
this.fallAsleepTime = res.data[0].data_msg[0].fallAsleepTime.split('-')
this.isOption = true
}
this.doAnimation(0)
this.doAnimation(1)
})
},
getPercent(data,find){
let len = data.length
return (this.countOccurrences(data,find) / len * 100).toFixed(1)
},
getAngle(min){
return min/this.cavasConfig.maxTime * 360
},
min2Hour(min){
let hour = (Math.floor(min / 60))
let minute = (min % 60)
return (hour?hour + ' 小时 ' + minute+ ' 分':minute+ ' 分')
},
doAnimation(type){
if(type == 0){
if(this.cavasConfig.bigStop === 1){
return
}
if(this.cavasConfig.bigStartAngle >= this.cavasConfig.bigAngle){
this.cavasConfig.bigStartAngle = this.cavasConfig.bigAngle
this.cavasConfig.bigStop = 1;
}else{
this.cavasConfig.bigStartAngle += this.cavasConfig.bigAngle/50
}
this.drawCircle('round',this.cavasConfig.bigStartAngle,this.cavasConfig.bigRadius,this.cavasConfig.bigColor);
}else{
if(this.cavasConfig.stop == 1){
return
}
if(this.cavasConfig.startSmallAngle >= this.cavasConfig.angle){
this.cavasConfig.startSmallAngle = this.cavasConfig.angle
this.cavasConfig.stop = 1;
}else{
this.cavasConfig.startSmallAngle += this.cavasConfig.angle/50
}
this.drawCircle('round',this.cavasConfig.startSmallAngle,this.cavasConfig.radius,this.cavasConfig.color);
}
// window.requestAnimationFrame(() => {
setTimeout(() => {
this.doAnimation(type)
},(17))
// })
},
// lineCap线条类型 edangle绘制角度 radius 直径 color 线条颜色
drawCircle(lineCap,edangle,radius,color) {
this.cavasConfig.ctx.save()
const cx = this.cavasConfig.canvasWidth / 2
const cy = this.cavasConfig.canvasHeight / 2
this.cavasConfig.ctx.translate(cx,cy)
this.cavasConfig.ctx.scale(1, 1);
this.cavasConfig.ctx.lineCap = lineCap
let start = this.cavasConfig.startAngle*Math.PI/180
let end = (edangle+this.cavasConfig.startAngle)*Math.PI/180
this.cavasConfig.ctx.beginPath()
this.cavasConfig.ctx.arc(0,0, radius , start, end);
this.cavasConfig.ctx.lineWidth = this.cavasConfig.lineWidth; // 设置线宽
this.cavasConfig.ctx.strokeStyle = color; // 设置绘制样式为蓝色
this.cavasConfig.ctx.stroke(); // 绘制路径
this.cavasConfig.ctx.closePath()
this.cavasConfig.ctx.restore()
this.cavasConfig.ctx.draw(true)
}
}
}
</script>
<style lang="scss" scoped>
.dian0{
background-color: #e933dd;
}
.dian1{
background-color: #6452da;
}
.dian2{
background-color: #4faffc;
}
.c0{
color: #e933dd;
font-size: 26rpx;
}
.c1{
color: #6452da;
font-size: 26rpx;
}
.c2{
color: #4faffc;
font-size: 26rpx;
}
.yuan{
width: 16rpx;
height: 16rpx;
border-radius: 50%;
}
.small-title{
font-size: 24rpx;
color: #999;
}
.canvas_box{
background-color: #fff;
padding: 20rpx;
.circle {
width: 40rpx;
height: 40rpx;
margin: 0 auto;
border-radius: 50%;
margin: 0 10rpx;
}
.sleep_info{
.info_title{
font-size: 24rpx;
color: #999;
}
.info_val{
}
}
}
.title_box{
margin-bottom: 20rpx;
.title{
font-size: 28rpx;
}
.more{
color: #999;
}
}
.video {
width: 80%;
padding: 0rpx 20rpx;
}
/* 隐藏所有默认控件 */
video::-webkit-media-controls {
display: none !important;
}
video::-moz-media-controls {
display: none !important;
}
video::-ms-media-controls {
display: none !important;
}
/* 针对不同浏览器的隐藏控件的方式 */
video::part(media-controls) {
display: none !important;
}
</style>