微信小程序使用echarts

在这里插入图片描述

思路

  • 五个tab公用一个柱状图组件
  • 切换tab以及切换时间改变数据,传入子组件,子组件监听数据重新更新
  • 点击柱状图显示具体数值
  • 每个时间点有两个柱子(高压和低压),柱状图显示高压的最大值到最小值的范围
  • 除了血压其余只有一条柱子
  • 步数比较特殊,不是范围,而是一个具体的步数数值
  • 根据tab设置不同的最小值
  • 假如最大值==最小值,显示一个点
  • 所有横坐标全部显示,不滚动

下载wx-echarts

image.png

堆叠柱状图子组件

image.png

  • bar.json
{
  "component": true,
  "usingComponents": {
    "ec-canvas": "../../../ec-canvas/ec-canvas"
  }
}
  • bar.wxml
<view class="w100 h100">
  <ec-canvas id="mychart-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
</view>
  • bar.js
import * as echarts from '../../../ec-canvas/echarts';
Component({
  options: {
    addGlobalClass: true,
  },
  data: {
    ec: {
      lazyLoad: true // 懒加载
    },
    time: [],
    low1: [],
    high1: [],
    low2: [],
    high2: [],
    step: []
  },
  properties: {
    list: {
      type: Array,
      observer: function (newVal, oldVal) {
        if (newVal.length || oldVal.length) {
          console.log(newVal, oldVal, 88)
          let time = newVal.map(item => item.date)
          let low1 = newVal.map(item => item.firstLowIndicators * 1)
          let high1 = newVal.map(item => item.firstHighIndicators && item.firstHighIndicators == item.firstLowIndicators ? 'solo' : item.firstHighIndicators * 1 - item.firstLowIndicators * 1)
          // let high1 = newVal.map(item => (item.firstHighIndicators * 1 - item.firstLowIndicators * 1 == 0) ? 1 : item.firstHighIndicators * 1 - item.firstLowIndicators * 1)
          let low2 = newVal.map(item => item.secondLowIndicators * 1)
          let high2 = newVal.map(item => item.secondHighIndicators && item.secondHighIndicators == item.secondLowIndicators ? 'solo' : item.secondHighIndicators * 1 - item.secondLowIndicators * 1)
          // let high2 = newVal.map(item => (item.secondHighIndicators * 1 - item.secondLowIndicators * 1 == 0) ? 1 : item.secondHighIndicators * 1 - item.secondLowIndicators * 1)
          let step = newVal.map(item => item.firstHighIndicators)
          this.setData({
            time,
            low1,
            high1,
            low2,
            high2,
            step
          })
          this.initChart(); // 数据变化时重新初始化图表
        }
      }
    },
    tab: {
      type: Number,
      value: 1
    }
  },
  methods: {
    initChart() {
      // 绑定组件
      this.barComponent = this.selectComponent("#mychart-bar");
      // 初始化柱状图
      this.barComponent.init((canvas, width, height, dpr) => {
        // 初始化图表
        const chart = echarts.init(canvas, null, {
          width: width,
          height: height,
          devicePixelRatio: dpr // 解决模糊显示问题
        })
        // 开发中根据从后端获取barData数据,动态更新图表
        chart.setOption(this.getOption())
        return chart
      })
    },
    getOption() {
      var option = {
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow",
          },
          formatter: (params) => {
            // console.log(params)
            if (this.data.tab == 5) {
              return (
                params[0].axisValue +
                "\n" +
                params[0].marker +
                params[1].seriesName +
                ":" +
                (params[0].value || 0)
              )
            } else if (this.data.tab == 1) {
              return (
                params[0].axisValue +
                "\n" +
                params[1].marker +
                params[0].seriesName +
                ":" +
                params[0].value +
                "~" +
                (params[0].value + ((params[1].value + '').slice(-6) == '521125' ? 0 : params[1].value)) +
                "\n" +
                params[3].marker +
                params[2].seriesName +
                ":" +
                params[2].value +
                "~" +
                (params[2].value * 1 + ((params[3].value + '').slice(-6) == '521125' ? 0 : params[3].value * 1))
              );
            } else {
              return (
                params[0].axisValue +
                "\n" +
                params[1].marker +
                params[0].seriesName +
                ":" +
                params[0].value +
                "~" +
                (params[0].value + ((params[1].value + '').slice(-6) == '521125' ? 0 : params[1].value))
              )
            }
          },
        },
        grid: {
          top: '8%',
          left: '5%',
          right: '5%',
          bottom: '3%',
          containLabel: true
        },
        // dataZoom: [{
        //   type: 'inside', // 内置型数据区域缩放
        //   show: true,
        //   startValue: 0,
        //   endValue: 5,
        // }],
        xAxis: {
          type: 'category',
          splitLine: {
            show: false
          },
          data: this.data.time
        },
        yAxis: {
          type: 'value',
          min: [40, 80, 50, 34, 0][this.data.tab * 1 - 1],
        },
        series: [{
            name: ['舒张压范围', '血氧范围', '心率范围', '体温范围', '步数'][this.data.tab * 1 - 1],
            type: 'bar',
            stack: 'Total',
            barWidth: 4,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent'
            },
            data: this.data.tab == 5 ? 0 : this.data.low1
          },
          {
            name: '',
            type: 'bar',
            stack: 'Total',
            barWidth: 4,
            label: {
              // show: true,
              position: 'inside'
            },
            itemStyle: {
              color: '#2bdc70', // 设置整个系列柱子的颜色为蓝色
              barBorderRadius: 10 // 设置所有柱子的圆角半径为10px
            },
            data: this.data.tab == 5 ? this.data.step : this.data.high1.map(item => item == 'solo' ? [2.0521125, 0.3521125, 1.0521125, 0.12521125, 0][this.data.tab * 1 - 1] : item)
          },
          {
            name: ['舒张压范围', '血氧范围', '心率范围', '体温范围', '步数'][this.data.tab * 1 - 1],
            type: 'bar',
            stack: 'Total1',
            barWidth: 4,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent',
            },
            data: this.data.low2
          },
          {
            name: '',
            type: 'bar',
            stack: 'Total1',
            barWidth: 4,
            label: {
              // show: true,
              position: 'inside'
            },
            itemStyle: {
              color: '#fa5151', // 设置整个系列柱子的颜色为蓝色
              barBorderRadius: 10 // 设置所有柱子的圆角半径为10px
            },
            data: this.data.high2.map(item => item == 'solo' ? [2.0521125, 0.3521125, 0.521125, 0.0521125, 0][this.data.tab * 1 - 1] : item)
          }
        ]
      };
      return option
    }
  }
})

父组件

<view style="width: 100%; height: 260px;">
    <my-bar list="{{barList}}"></my-bar>
</view>

"usingComponents": {
    "my-bar": "./components/bar/bar",
    "solo-table": "./components/table/table"
  },
  
  
  barList: [{
         time: this.data.active,
         low1: 50,
         high1: 80,
         low2: 80,
         high2: 140
       }, {
         time: this.data.active,
         low1: 50,
         high1: 90,
         low2: 90,
         high2: 150
       }, {
         time: this.data.active,
         low1: 50,
         high1: 80,
         low2: 70,
         high2: 100
       }, {
         time: this.data.active,
         low1: 50,
         high1: 80,
         low2: 60,
         high2: 140
       }, {
         time: this.data.active,
         low1: 70,
         high1: 100,
         low2: 100,
         high2: 140
       }, ]

定制echarts.min.js

image.png

完整父组件

<view class="w100 min100">
  <van-sticky offset-top="{{ 0 }}">
    <van-tabs style="z-index: 99;" sticky animated class="gray-2 bold bg-white" active="{{ tab }}" bind:change="onChangeTab" color="#217EF7" line-width="{{20}}" line-height="{{4}}">
      <van-tab title="血压" name="1"></van-tab>
      <van-tab title="血氧" name="2"></van-tab>
      <van-tab title="心率" name="3"></van-tab>
      <van-tab title="体温" name="4"></van-tab>
      <van-tab title="步数" name="5"></van-tab>
    </van-tabs>
  </van-sticky>
  <time bindchangeTab="onChangeTime" bindchangeDay="onChangeDay"></time>

  <view class="flex w100 pl-30 ptb-20">
    <view class="bold size-32 flex-1">{{title}}统计分析</view>
    <!-- <van-tabs animated type="card" class="gray-2 flex-1" active="{{ active }}" bind:change="onChangeTime" color="#217EF7">
      <van-tab title="日" name="1"></van-tab>
      <van-tab title="周" name="2"></van-tab>
      <van-tab title="月" name="3"></van-tab>
    </van-tabs> -->
  </view>
  <view style="width: 100%; height: 250px;">
    <my-bar list="{{barList}}" tab="{{tab*1}}"></my-bar>
  </view>
  <view class="pd-30">
    <table1 head="{{head}}" list="{{tableList}}" tab="{{tab*1}}">
    </table1>
  </view>
  <view wx:if="{{tab==1}}">
    <view class="bold size-32 flex-1 plr-30 mt-30 mb-30">30天血压趋势情况</view>
    <view style="width: 100%; height: 320px;">
      <my-scatter list="{{scatterList}}"></my-scatter>
    </view>
    <view class="pd-30">
      <solo-table total="{{total}}" list="{{soloTable}}"></solo-table>
    </view>
  </view>
</view>
{
  "usingComponents": {
    "my-bar": "./components/bar/bar",
    "bar1": "./components/bar1/bar",
    "my-scatter": "./components/scatter/scatter",
    "solo-table": "./components/solo-table/table",
    "table1": "./components/table/table",
    "time": "./components-time/time/time"
  },
  "navigationBarTitleText": "健康监测"
}
 Page({
   data: {
     tab: 1, // 大分类
     title: '血压',
     timeRange: 'day', //时间切换
     queryDate: '', //时间切换
     //  bar
     barList: [],
     stepList: [],
     scatterList: [],
     total: 0,
     soloTable: [],
     //  表格
     head: [{
         text: '指标',
         prop: 'name'
       },
       {
         text: '最高',
         prop: 'max'
       },
       {
         text: '最低',
         prop: 'min'
       },
       {
         text: '参考值',
         prop: 'range'
       }
     ],
     tableList: []
   },
   onLoad(option) {
     let now = this.getNowData(new Date(), 'day')
     this.setData({
       timeRange: 'day',
       queryDate: now.content
     })
     this.getList()
     this.getList30()
   },
   getList() {
     let {
       timeRange,
       queryDate,
       tab
     } = this.data
     console.log(timeRange, queryDate, 8888888888888, timeRange == 'weeks' ? queryDate.split(' 至 ').join(',') : timeRange == 'day' ? queryDate : queryDate.split(' 至 ')[0].split('-')[0] + '-' + queryDate.split(' 至 ')[0].split('-')[1])
     wx.http('occupant/health-records/chartList', Object.assign({
       dataSource: 1, //0 手动录入   1智能手表   2、健康检测
       userId: wx.getStorageSync('userInfo').userId,
       timeRange: timeRange == 'weeks' ? 'week' : timeRange,
       queryDate: timeRange == 'weeks' ? queryDate.split(' 至 ').join(',') : timeRange == 'day' ? queryDate : queryDate.split(' 至 ')[0].split('-')[0] + '-' + queryDate.split(' 至 ')[0].split('-')[1],
       firstIndicator: ['diastolic_blood_pressure', 'blood_oxygen', 'heart_rate', 'temperature', 'step_count'][tab * 1 - 1],
     }, tab == 1 ? {
       secondIndicator: ['systolic_blood_pressure'][tab * 1 - 1]
     } : {})).then(res => {
       if (res.data.table && res.data.table.length) {
         if (tab == 1) {
           res.data.table[0].name = '舒张压'
           res.data.table[0].range = '60-90'
           res.data.table[1].range = '90-140'
           res.data.table[1].name = '收缩压'
         } else if (tab == 2) {
           res.data.table[0].name = '血氧'
           res.data.table[0].range = '95-100%'
         } else if (tab == 3) {
           res.data.table[0].name = '心率'
           res.data.table[0].range = '60-100'
         } else if (tab == 4) {
           res.data.table[0].name = '体温'
           res.data.table[0].range = '35.3-37.3℃'
         } else if (tab == 5) {
           res.data.table[0].name = '步数'
           res.data.table[0].range = '5000-10000步'
         }
       }
       //  if (tab == 5) {
       //    this.setData({
       //      stepList: res.data.charts || [],
       //      tableList: res.data.table
       //    })
       //  } else {

       //  }
       this.setData({
         barList: res.data.charts || [],
         tableList: res.data.table
       })
     })
   },
   getList30() {
     wx.http('occupant/health-records/bloodPressureTrend', {
       dataSource: 1, //0 手动录入   1智能手表   2、健康检测
       userId: wx.getStorageSync('userInfo').userId,
     }).then(res => {
       this.setData({
         scatterList: res.data.charts,
         total: res.data.total,
         soloTable: res.data.table,
       })
     })
   },
   onChangeTab(e) {
     this.setData({
       tab: e.detail.name,
       title: e.detail.title
     })
     this.getList()
     if (this.data.tab == 1) {
       this.getList30()
     }
   },
   //  onChangeTime(e) { 
   //    this.setData({
   //      timeRange: e.detail.id, 
   //    }) 
   //  },
   // 点击切换获取默认时间
   getNowData(date, dateType, direction) {
     let updateData = {};
     let content = "";
     let year = date.getFullYear();
     let month = date.getMonth() + 1;
     let day = date.getDate();
     let weeksDay = date.getDay();
     switch (dateType) {
       case 'day': {
         year = date.getFullYear();
         month = date.getMonth() + 1;
         day = date.getDate();
         content = year + "-" + month + "-" + day;
         break;
       }
       case 'weeks': {

         //获取当天在这一周是属于第几天,然后计算这一周的起始天日期和结束的日期
         weeksDay = date.getDay();

         let starDate = new Date(date.getTime());
         starDate.setDate(date.getDate() - weeksDay + 1);
         let startYear = starDate.getFullYear();
         let startMonth = starDate.getMonth() + 1;
         let startDay = starDate.getDate();

         let endDate = new Date(date.getTime());
         let endYear = endDate.getFullYear();
         let endMonth = endDate.getMonth() + 1;
         let endDay = endDate.getDate();
         //  let weeksDay = date.getDay(); // 获取今天是周几,注意:0代表周日,1代表周一

         //  // 计算本周第一天(周一)
         //  let startDate = new Date(date.getTime());
         //  if (weeksDay !== 0) { // 如果不是周日
         //    startDate.setDate(date.getDate() - weeksDay + 1); // 减去当前是周几再加1,得到周一
         //  } else {
         //    // 如果是周日,直接使用当前日期即可,因为已经是新的一周的开始
         //  }
         //  let startYear = startDate.getFullYear();
         //  let startMonth = startDate.getMonth() + 1; // 月份需要加1
         //  let startDay = startDate.getDate();

         //  // 计算本周最后一天(周日)
         //  let endDate = new Date(startDate.getTime());
         //  endDate.setDate(startDate.getDate() + 6); // 从周一基础上加6天到达周日
         //  let endYear = endDate.getFullYear();
         //  let endMonth = endDate.getMonth() + 1;
         //  let endDay = endDate.getDate();

         content = startYear + "-" + startMonth + "-" + startDay + ' 至 ' + endYear + "-" + endMonth + "-" + endDay;
         break;
       }
       case 'month': {
         let starDate = new Date(date.getTime());
         //计算当月的第一天日期
         starDate.setDate(1);
         let startYear = starDate.getFullYear();
         let startMonth = starDate.getMonth() + 1;
         let startDay = starDate.getDate();

         let endDate = new Date(date.getTime());
         let endYear = endDate.getFullYear();
         let endMonth = endDate.getMonth() + 1;
         let endDay = endDate.getDate();

         content = startYear + "-" + startMonth + "-" + startDay + ' 至 ' + endYear + "-" + endMonth + "-" + endDay;
         break;
       }
     }
     updateData.content = content;
     return updateData;
   },
   onChangeDay(e) {
     console.log(e.detail.id, 999999)
     this.setData({
       queryDate: e.detail.id.date.curDate,
     })
     if (e.detail.id.type) {
       this.setData({
         timeRange: e.detail.id.type,
       })
     }
     this.getList()
   },
 });
  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小曲曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值