index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <template>
  2. <view>
  3. <!-- <van-tabs v-model="active">
  4. <van-tab title="日"> -->
  5. <view class="top-box">
  6. <view class="container-top" @click="showDayPicker = true">
  7. <view class="top-left">
  8. <view class="word">今日</view>
  9. <text>{{formatDate(dayValue)}}</text>
  10. </view>
  11. <!-- <view class="top-right" @click.stop="fullscreenFn">
  12. <image src="/static/image/full.png" mode=""></image>
  13. </view> -->
  14. </view>
  15. <view class="chartsMain" v-if="dayArea.categories.length">
  16. <canvas canvas-id="canvasArea" id="canvasArea" class="charts"></canvas>
  17. </view>
  18. <view class="chartsMain" v-else>
  19. <image src="/static/image/none.png" mode=""></image>
  20. </view>
  21. </view>
  22. <content-page :dayInfo="dayInfo"></content-page>
  23. <!-- </van-tab>
  24. <van-tab title="月">
  25. <view class="top-box">
  26. <view class="container-top" @click="showMonthPicker = true">
  27. <view class="top-left">
  28. <view class="word">月份</view>
  29. <text>{{formatMonth(monthValue)}}</text>
  30. </view>
  31. <view class="top-right">
  32. <image src="/static/image/full.png" mode=""></image>
  33. </view>
  34. </view>
  35. <view class="chartsMain">
  36. <canvas canvas-id="canvasMonthArea" id="canvasMonthArea" class="charts"
  37. @touchstart="touchArea"></canvas>
  38. </view>
  39. </view>
  40. <content-page></content-page>
  41. </van-tab>
  42. <van-tab title="年">
  43. <view class="top-box">
  44. <view class="container-top" @click="showYearPicker = true">
  45. <view class="top-left">
  46. <view class="word">年份</view>
  47. <text>{{formatYear(yearValue)}}</text>
  48. </view>
  49. <view class="top-right">
  50. <image src="/static/image/full.png" mode=""></image>
  51. </view>
  52. </view>
  53. <view class="chartsMain">
  54. <canvas canvas-id="canvasYearArea" id="canvasYearArea" class="charts"
  55. @touchstart="touchArea"></canvas>
  56. </view>
  57. </view>
  58. <content-page></content-page>
  59. </van-tab>
  60. </van-tabs> -->
  61. <van-popup :show="showDayPicker" position="bottom">
  62. <van-datetime-picker @cancel="showDayPicker=false" @confirm="onConfirm" :value="currentDay" type="date" />
  63. </van-popup>
  64. <van-popup :show="showMonthPicker" position="bottom">
  65. <van-datetime-picker @cancel="showMonthPicker=false" @confirm="onMonthConfirm" type="year-month"
  66. :value="currentMonth" />
  67. </van-popup>
  68. <van-popup :show="showYearPicker" position="bottom">
  69. <van-datetime-picker @cancel="showYearPicker=false" @confirm="onYearConfirm" type="year"
  70. :value="currentYear" />
  71. </van-popup>
  72. </view>
  73. </template>
  74. <script>
  75. import * as infoApi from '@/api/info/index.js';
  76. import dayjs from "@/plugin/dayjs/dayjs.min.js";
  77. import contentPage from './components/content.vue'
  78. // 图表
  79. import uCharts from "@/components/ucharts/ucharts.js";
  80. import {
  81. mapGetters
  82. } from "vuex";
  83. // import uCharts from "@/components/u-charts/u-charts.js";
  84. var _self;
  85. var canvaRing = null;
  86. var canvaArea = null;
  87. var canvaGauge = null;
  88. var canvaPie = null;
  89. var canvaColumn = null;
  90. var canvaFunnel = null;
  91. var canvaWord = null;
  92. export default {
  93. components: {
  94. contentPage
  95. },
  96. data() {
  97. return {
  98. active: 2,
  99. cWidth: '',
  100. cHeight: '',
  101. pixelRatio: 1,
  102. dayValue: new Date(),
  103. monthValue: new Date(),
  104. yearValue: new Date(),
  105. showDayPicker: false, //日
  106. showMonthPicker: false, //月
  107. showYearPicker: false, //年
  108. // minDate:new Date().getTime(),
  109. currentDay: new Date().getTime(),
  110. currentMonth: new Date().getTime(),
  111. currentYear: new Date().getTime(),
  112. fullscreen: false,
  113. dayInfo: {}, //日数据
  114. dayTimeList: [], //日X轴数据
  115. dayDataList: [], //日图表数据
  116. // 日折线图
  117. dayArea: {
  118. categories: [],
  119. // categories: ['08:22','08:22','08:22','08:22'],
  120. series: [{
  121. name: '',
  122. data: [],
  123. // data: [68,92,66,79],
  124. color: '#F35546'
  125. }]
  126. },
  127. // 月折线图
  128. monthArea: {
  129. categories: ['6月', '7月', '8月', ],
  130. series: [{
  131. name: '学习前端',
  132. data: [100, 80, 95, ],
  133. color: '#F35546'
  134. }]
  135. },
  136. // 年折线图
  137. yearArea: {
  138. categories: ['6月', '7月'],
  139. series: [{
  140. name: '学习前端',
  141. data: [100, 80, ],
  142. color: '#F35546'
  143. }]
  144. },
  145. };
  146. },
  147. computed: mapGetters(['deviceId']),
  148. async onLoad() {
  149. _self = this;
  150. this.cWidth = uni.upx2px(680);
  151. this.cHeight = uni.upx2px(400);
  152. await this.getData()
  153. this.getServerData();
  154. },
  155. mounted() {
  156. console.log(this.formatDate(this.currentDate), 333);
  157. },
  158. methods: {
  159. getData() {
  160. console.log(this.deviceId, 8889999);
  161. let data = this.formatDate(this.dayValue).split("-"); // ["2023", "10", "18"]
  162. let params = {
  163. deviceId: this.deviceId,
  164. year: data[0],
  165. month: data[1],
  166. day: data[2],
  167. // day:"17",
  168. }
  169. return infoApi.getBloodOxygen(params).then(res => {
  170. console.log(res, 44);
  171. if (res.data === null) {
  172. this.dayInfo = {}
  173. this.dayInfo.list = []
  174. this.dayArea.categories = []
  175. }
  176. if (res.code === 0 && res.data.list.length) {
  177. this.dayInfo = res.data
  178. // 组装接口数据。上方折线图若超过10条,截取10条
  179. let categoriesArr = res.data.list.map(item => this.formatHHmm(item.createTime))
  180. let seriesArr = res.data.list.map(item => item.bloodOxygen)
  181. this.dayArea.categories = categoriesArr.length > 10 ? categoriesArr.slice(-10) :
  182. categoriesArr
  183. this.dayArea.series[0].data = seriesArr.length > 10 ? seriesArr.slice(-10) : seriesArr
  184. }
  185. })
  186. .catch(err => {
  187. return this.$util.Tips({
  188. title: err,
  189. // icon: 'error'
  190. });
  191. });
  192. },
  193. fullscreenFn() {
  194. wx.requestFullScreen({
  195. success: (res) => {
  196. console.log(res, 666);
  197. this.fullscreen = true
  198. }
  199. });
  200. },
  201. formatter(type, val) {
  202. if (type === 'year') {
  203. return `${val}年`;
  204. } else if (type === 'month') {
  205. return `${val}月`;
  206. }
  207. return val;
  208. },
  209. onYearConfirm(value) {
  210. console.log(value, 444);
  211. this.yearValue = value.detail
  212. this.showYearPicker = false
  213. },
  214. onMonthConfirm(value) {
  215. this.monthValue = value.detail
  216. this.showMonthPicker = false;
  217. console.log(this.formatMonth(this.monthValue), 777);
  218. },
  219. async onConfirm(value) {
  220. this.dayValue = value.detail;
  221. await this.getData()
  222. this.getServerData();
  223. this.showDayPicker = false;
  224. },
  225. formatHHmm: function(date) {
  226. return dayjs(date).format("HH:mm");
  227. },
  228. formatDate: function(date) {
  229. return dayjs(date).format("YYYY-MM-DD");
  230. },
  231. formatMonth: function(date) {
  232. return dayjs(date).format("YYYY-MM");
  233. },
  234. formatYear: function(date) {
  235. return dayjs(date).format("YYYY");
  236. },
  237. changeDay() {
  238. this.showDayPicker = true
  239. },
  240. getServerData() {
  241. console.log('是否先执行');
  242. _self.showArea("canvasArea", this.chartData, 'day');
  243. _self.showArea("canvasMonthArea", this.chartData, 'month');
  244. _self.showArea("canvasYearArea", this.chartData, 'year');
  245. },
  246. // 折线图
  247. showArea(canvasId, chartData, type) {
  248. const categories = type == 'day' ? _self.dayArea.categories : type == 'month' ? _self.monthArea
  249. .categories : _self.yearArea.categories
  250. const series = type == 'day' ? _self.dayArea.series : type == 'month' ? _self.monthArea.series : _self
  251. .yearArea.series
  252. canvaArea = new uCharts({
  253. $this: _self,
  254. canvasId: canvasId,
  255. type: 'area',
  256. fontSize: 11,
  257. legend: {
  258. show: false
  259. },
  260. dataLabel: true,
  261. dataPointShape: true,
  262. background: '#FFFFFF',
  263. pixelRatio: _self.pixelRatio,
  264. categories: categories,
  265. series: series,
  266. animation: true,
  267. padding: [20, 10, 10, 10],
  268. xAxis: {
  269. type: 'grid',
  270. gridColor: '#CCCCCC',
  271. gridType: 'solid',
  272. dashLength: 8,
  273. disableGrid: true,
  274. rotateLabel: true,
  275. rotateAngle: -50,
  276. },
  277. yAxis: {
  278. gridType: 'solid',
  279. gridColor: '#CCCCCC',
  280. dashLength: 8,
  281. splitNumber: 5,
  282. data: [{
  283. format: function(val) {
  284. return val.toFixed(2);
  285. },
  286. max: 105,
  287. min: 0
  288. }]
  289. // min: 10,
  290. // max: 180,
  291. },
  292. width: _self.cWidth * _self.pixelRatio,
  293. height: _self.cHeight * _self.pixelRatio,
  294. extra: {
  295. area: {
  296. type: 'straight',
  297. // type: 'curve',
  298. opacity: 0.2,
  299. addLine: true,
  300. width: 2
  301. }
  302. }
  303. });
  304. },
  305. touchArea(e) {
  306. canvaArea.showToolTip(e, {
  307. format: function(item, category) {
  308. return item.name + ' ' + category + ' ' + ':' + item.data
  309. }
  310. });
  311. },
  312. }
  313. };
  314. </script>
  315. <style lang="scss" scoped>
  316. // ::v-deep .van-tab__pane--active{
  317. // width: 100%;
  318. // }
  319. .top-box {
  320. padding: 28rpx 32rpx 19rpx;
  321. background-color: #fff;
  322. .container-top {
  323. display: flex;
  324. align-items: center;
  325. justify-content: space-between;
  326. margin-bottom: 28rpx;
  327. .top-left {
  328. .word {
  329. font-size: 36rpx;
  330. font-weight: 500;
  331. color: #000000;
  332. }
  333. text {
  334. font-size: 24rpx;
  335. font-weight: 500;
  336. color: #777777;
  337. line-height: 33rpx;
  338. }
  339. }
  340. .top-right {
  341. width: 32rpx;
  342. height: 32rpx;
  343. image {
  344. width: 32rpx;
  345. height: 32rpx;
  346. }
  347. }
  348. }
  349. .chartsMain {
  350. width: 100%;
  351. // height: 450rpx;
  352. // box-sizing: border-box;
  353. background: #fff;
  354. border-top: 2rpx solid #f2f2f2;
  355. text-align: center;
  356. image {
  357. width: 70%;
  358. // height: 100%;
  359. }
  360. .charts {
  361. width: 680rpx;
  362. height: 400rpx;
  363. box-sizing: border-box;
  364. }
  365. }
  366. }
  367. </style>