feat: 个人最佳趋势改为折线图 + 底部最佳趋势日期 + 修复
- 趋势组件 trend-chart 新增 chartType(line/bar),line 模式用内联 SVG 渲染折线+渐变面积(无 canvas) - 记录页个人最佳趋势改用折线图,峰值信息移到图表下方对称高亮块显示最佳趋势产生日期 - 修复1: linePoints 漏存绝对坐标 y 导致运行时 toFixed 崩溃 - 修复2: 折线模式漏渲染数据点数值(valueText),现圆点上方显示且 0 值不显示
This commit is contained in:
@@ -150,3 +150,32 @@
|
|||||||
- 清残留:删 preview-buttons.html + rmdir cloudfunctions/shared(空死目录,重构遗留);.claude/.codegraph 已被 packOptions.ignore 的 `.!*` 忽略,不动。
|
- 清残留:删 preview-buttons.html + rmdir cloudfunctions/shared(空死目录,重构遗留);.claude/.codegraph 已被 packOptions.ignore 的 `.!*` 忽略,不动。
|
||||||
- 未做:全局错误上报(wx.onError)、自定义隐私弹窗(用户仅确认做这三个清理项)。
|
- 未做:全局错误上报(wx.onError)、自定义隐私弹窗(用户仅确认做这三个清理项)。
|
||||||
- 改动未提交(git status 显示 M/D 文件)。clean-console.js 为一性工具,留 .workbuddy 不进包。
|
- 改动未提交(git status 显示 M/D 文件)。clean-console.js 为一性工具,留 .workbuddy 不进包。
|
||||||
|
|
||||||
|
## 上线前优化续:组件按需注入 + records 补声明 + 提交推送
|
||||||
|
- 微信开发者工具「代码质量」扫描显示「组件:启用组件按需注入 — 未通过」。
|
||||||
|
- 根因:project.config.json 缺 `lazyCodeLoading` 配置项。已加 `"lazyCodeLoading": "requiredComponents"`(只加载页面 usingComponents 声明且模板实际用到的组件)。
|
||||||
|
- 核实:7 组件均静态写死在 WXML,无动态 `<component is=`/抽象节点/custom-tab-bar 不受影响 → 无负面影响;基础库 <2.10.1 用户自动回退全量加载(无害)。
|
||||||
|
- 顺带发现真 bug:pages/records/records.json 漏声明 ui-skeleton(WXML 第 4/6 行已用)→ 已补;5 页面声明与 WXML 实际使用现已完全一致。
|
||||||
|
- 提交:commit `187c426`(14 文件,+100/-199,含之前的 console 清理+project.config 开关+删 preview-buttons.html+lazyCodeLoading+records 补声明)。clean-console.js 一次性工具未入库。
|
||||||
|
- 推送:soao(https://git.soao.net/lc/wx_pbzc.git)成功(b52db87..187c426);**origin(github)当前环境到 github.com:443 SSL 连接被重置(HTTP2 framing/SSL_ERROR_SYSCALL 交替),多次重试失败——环境网络抖动,非代码问题**。本地 commit 安全,待网络恢复后重试 `git push origin main`。
|
||||||
|
|
||||||
|
## 功能:个人最佳趋势改为折线图 + 底部加最佳趋势产生日期
|
||||||
|
- 用户要求:记录页「个人最佳趋势」(bestTrendData)从柱状图改折线图,并在底部加「最佳趋势产生日期」(像「最高训练日」那样)。
|
||||||
|
- 实现:趋势组件 `trend-chart` 加 `chartType`(bar|line,默认 bar,柱状图完全不动)+ `lineColor` 属性。line 模式用**内联 SVG(data URI)→`<image>`** 渲染折线+半透明面积(无 canvas,和组件 no-canvas 理念一致);圆点与横轴标签用 WXML 绝对定位(按 xPercent/yPercent),保证清晰且能吃主题色(因 SVG 在 image 内读不到 CSS 变量,颜色由页面传 hex)。
|
||||||
|
- 几何:viewBox=640×H(H=peak?170:200),`mode=widthFix` 让 SVG 宽高比与容器 rpx 一致→stroke 均匀不拉伸;x 按 (i+0.5)*640/N 均分,y 用 topPad/bottomPad 留头尾余量;零值点落到接近底部。
|
||||||
|
- 数据层不动(getBestTrendData 仍返回 label=周一/7月 等周期标签,符合"就像最高训练日"的粒度)。
|
||||||
|
- records 页:best 趋势 `<trend-chart chart-type="line" line-color="{{bestLineColor}}">`;原在 header 的 `best-trend-best` 文本移到图表下方,复用 `.trend-highlight` 对称块(icons.crownFill + bestTrendSummary.peakTitle + peakText);新增 `_buildBestSummary` 把 peakTitle 覆盖为「个人最佳日/月」(通用 getTrendSummary 原给"最高训练日",不对);bestLineColor=theme.primary(peak 实际用主题主色,非金)。
|
||||||
|
- 验证:node --check 通过;tests/trend-state.test.js 5/5 通过(数据层未变);SVG 字符串模拟确认无 NaN、含 stroke/fill-opacity/width/height。删了 records.wxss 里已不用的 .best-trend-best 样式。
|
||||||
|
- 改动未提交(git status 有 M)。待用户审阅后可提交(soao 国内远程稳定;origin 仍待网络恢复推)。
|
||||||
|
|
||||||
|
## BUG 修复:折线图运行时崩溃(toFixed of undefined)
|
||||||
|
- 现象:记录页切换 trend 模式报 `Cannot read property 'toFixed' of undefined`(trend-chart.js:90, _buildLineSvg 内 `p.y.toFixed`)。
|
||||||
|
- 根因:`_compute` 生成 linePoints 时只存了 `x`(绝对)与 `yPercent`(百分比),**漏存绝对坐标 `y`**;`_buildLineSvg` 画 polyline/area 用的是 viewBox 绝对坐标 `p.x`/`p.y`,`p.y` 为 undefined → 崩。WXML 圆点/标签用 xPercent/yPercent 定位(无误)。
|
||||||
|
- 修复:linePoints 返回对象补 `y`(与 x 同为 viewBox 坐标);`_buildLineSvg` 加防御 `valid = points.filter(p => p && typeof p.x==='number' && typeof p.y==='number')`,first/last/area/polyline 全改走 `valid`,空则返 ''。
|
||||||
|
- 验证:node --check 通过;用真实 getBestTrendData 输出实跑 _compute(week/month)均生成 lineSvg 不再崩;稀疏数组也安全。临时 repro 脚本已删。改动未提交。
|
||||||
|
|
||||||
|
## BUG 修复:折线图数据点未显示数值
|
||||||
|
- 现象:折线模式每个数据点旁没有数值文字(柱状图有,折线没有)。
|
||||||
|
- 根因:line 模式 WXML 只渲染了圆点(`trend-line-dot`)与横轴 label,**漏渲染 valueText**;且 linePoints 返回对象未透传 `value` 字段,无法做 `value>0` 判断。
|
||||||
|
- 修复:trend-chart.js 的 linePoints 返回补 `value: b.value`(bars 项第57行本就有 value);WXML 圆点内加 `<text wx:if="{{item.value>0}}" class="trend-line-value">{{item.valueText}}</text>`(仿柱状图,0 值不显示);WXSS 加 `.trend-line-value`(绝对定位在 dot 上方居中,16rpx,高亮点用主色加粗),并把 `.trend-chart.line` 的 padding-top 16rpx→30rpx 给最高点数值留缓冲防裁切。
|
||||||
|
- 验证:node --check 通过;bars.value 字段确认存在。改动未提交。
|
||||||
|
|||||||
@@ -27,3 +27,4 @@
|
|||||||
- 页面叫法:index=训练首页,timer=训练页,leaderboard=排行榜,records=记录,settings=设置。
|
- 页面叫法:index=训练首页,timer=训练页,leaderboard=排行榜,records=记录,settings=设置。
|
||||||
- 美化按"见效快优先"分批,每轮 `node --check` + grep 残留再交付。
|
- 美化按"见效快优先"分批,每轮 `node --check` + grep 残留再交付。
|
||||||
- **git push 须 `dangerouslyDisableSandbox:true`**(沙箱隔离致 github SSL 超时);无 SSH,仅 HTTPS remote。
|
- **git push 须 `dangerouslyDisableSandbox:true`**(沙箱隔离致 github SSL 超时);无 SSH,仅 HTTPS remote。
|
||||||
|
- **GitHub 链路不稳**:国内环境到 `github.com:443` 常 SSL 重置/HTTP2 framing 失败(非代码问题),`git.soao.net`(soao) 国内远程稳定。策略:soao 为主远程、实时同步;`origin`(GitHub) 失败则延后推或本地代理(`127.0.0.1:7890` 等)临时 `git -C <repo> config http.proxy` 推完 `config --unset` 撤销。代码已 commit 则零丢失风险。
|
||||||
|
|||||||
@@ -1,38 +1,53 @@
|
|||||||
const { getBarPercent } = require('../../utils/util')
|
const { getBarPercent } = require('../../utils/util')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trend bar chart - pure CSS (no canvas), matches the calendar-heatmap's
|
* Trend chart — pure CSS bar mode + optional SVG line mode (no canvas),
|
||||||
* rendering approach for consistency.
|
* matching the calendar-heatmap's rendering approach for consistency.
|
||||||
*
|
*
|
||||||
* chartData: [{ label, value, valueText, highlight }]
|
* chartData: [{ label, value, valueText, highlight }]
|
||||||
* - label: bottom caption (e.g. "一" / "7月")
|
* - label: bottom caption (e.g. "一" / "7月")
|
||||||
* - value: numeric magnitude (seconds); drives bar height
|
* - value: numeric magnitude (seconds); drives bar height / line y
|
||||||
* - valueText: formatted string shown above the bar (e.g. "1分30秒")
|
* - valueText: formatted string shown above the bar (e.g. "1分30秒")
|
||||||
* - highlight: truthy -> theme glow + bold label (today / this month)
|
* - highlight: truthy -> theme glow + bold label (today / this month)
|
||||||
*
|
*
|
||||||
* Bar height is strictly proportional to value/max. Zero values render a
|
* chartType: 'bar' (default) | 'line'
|
||||||
* faint stub so empty dates remain visible without distorting the data.
|
* - bar: CSS columns, height strictly proportional to value/max.
|
||||||
|
* - line: inline SVG (data URI) polyline + translucent area, rendered in an
|
||||||
|
* <image>; dots + axis labels are real WXML elements positioned by
|
||||||
|
* percentage so they stay crisp and theme-colored (SVG inside <image>
|
||||||
|
* cannot read page CSS variables). The viewBox aspect is matched to
|
||||||
|
* the container's rpx aspect (widthFix) so the stroke stays uniform
|
||||||
|
* — no non-uniform horizontal/vertical stretch.
|
||||||
|
*
|
||||||
|
* lineColor: hex used for the SVG stroke + area fill. Must be passed by the
|
||||||
|
* page because SVG inside <image> cannot read page CSS variables.
|
||||||
*/
|
*/
|
||||||
|
const VB_W = 640
|
||||||
|
|
||||||
Component({
|
Component({
|
||||||
properties: {
|
properties: {
|
||||||
chartData: { type: Array, value: [] },
|
chartData: { type: Array, value: [] },
|
||||||
variant: { type: String, value: 'total' }
|
variant: { type: String, value: 'total' },
|
||||||
|
chartType: { type: String, value: 'bar' },
|
||||||
|
lineColor: { type: String, value: '#FF6B35' }
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
bars: []
|
bars: [],
|
||||||
|
linePoints: [],
|
||||||
|
lineSvg: ''
|
||||||
},
|
},
|
||||||
observers: {
|
observers: {
|
||||||
'chartData'(chartData) {
|
'chartData, chartType, lineColor'(chartData, chartType, lineColor) {
|
||||||
this._compute(chartData)
|
this._compute(chartData, chartType, lineColor)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
ready() {
|
ready() {
|
||||||
this._compute(this.properties.chartData)
|
this._compute(this.properties.chartData, this.properties.chartType, this.properties.lineColor)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
_compute(chartData) {
|
_compute(chartData, chartType, lineColor) {
|
||||||
const arr = Array.isArray(chartData) ? chartData : []
|
const arr = Array.isArray(chartData) ? chartData : []
|
||||||
const max = arr.reduce((m, d) => Math.max(m, Number(d && d.value) || 0), 0)
|
const max = arr.reduce((m, d) => Math.max(m, Number(d && d.value) || 0), 0)
|
||||||
const bars = arr.map((d) => {
|
const bars = arr.map((d) => {
|
||||||
@@ -45,7 +60,49 @@ Component({
|
|||||||
percent: getBarPercent(v, max)
|
percent: getBarPercent(v, max)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.setData({ bars })
|
|
||||||
|
const N = arr.length
|
||||||
|
let linePoints = []
|
||||||
|
let lineSvg = ''
|
||||||
|
if (N > 0 && chartType === 'line') {
|
||||||
|
const lineH = this.properties.variant === 'peak' ? 170 : 200
|
||||||
|
const topPad = 16
|
||||||
|
const bottomPad = 12
|
||||||
|
const plot = lineH - topPad - bottomPad
|
||||||
|
linePoints = bars.map((b, i) => {
|
||||||
|
const x = (i + 0.5) * (VB_W / N)
|
||||||
|
const y = topPad + (1 - b.percent / 100) * plot
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
xPercent: (x / VB_W) * 100,
|
||||||
|
yPercent: (y / lineH) * 100,
|
||||||
|
label: b.label,
|
||||||
|
valueText: b.valueText,
|
||||||
|
value: b.value,
|
||||||
|
highlight: b.highlight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
lineSvg = this._buildLineSvg(linePoints, VB_W, lineH, lineColor || '#FF6B35')
|
||||||
|
}
|
||||||
|
this.setData({ bars, linePoints, lineSvg })
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildLineSvg(points, W, H, color) {
|
||||||
|
const valid = (points || []).filter(p => p && typeof p.x === 'number' && typeof p.y === 'number')
|
||||||
|
if (valid.length === 0) return ''
|
||||||
|
const pts = valid.map(p => `${p.x.toFixed(2)},${p.y.toFixed(2)}`).join(' ')
|
||||||
|
const first = valid[0]
|
||||||
|
const last = valid[valid.length - 1]
|
||||||
|
let area = `M ${first.x.toFixed(2)},${H} `
|
||||||
|
valid.forEach((p) => { area += `L ${p.x.toFixed(2)},${p.y.toFixed(2)} ` })
|
||||||
|
area += `L ${last.x.toFixed(2)},${H} Z`
|
||||||
|
const svg =
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">` +
|
||||||
|
`<path d="${area}" fill="${color}" fill-opacity="0.16"/>` +
|
||||||
|
`<polyline points="${pts}" fill="none" stroke="${color}" stroke-width="5" stroke-linejoin="round" stroke-linecap="round"/>` +
|
||||||
|
`</svg>`
|
||||||
|
return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
<view class="trend-chart {{variant === 'peak' ? 'peak' : ''}}">
|
<view class="trend-chart {{variant === 'peak' ? 'peak' : ''}} {{chartType === 'line' ? 'line' : ''}}">
|
||||||
<view class="trend-bars">
|
<!-- Bar mode -->
|
||||||
<view class="trend-bar-col" wx:for="{{bars}}" wx:key="label">
|
<block wx:if="{{chartType !== 'line'}}">
|
||||||
<view class="trend-bar {{item.value === 0 ? 'zero' : ''}} {{item.highlight ? 'highlight' : ''}}" style="height: {{item.percent}}%;">
|
<view class="trend-bars">
|
||||||
<text class="trend-bar-value" wx:if="{{item.value > 0}}">{{item.valueText}}</text>
|
<view class="trend-bar-col" wx:for="{{bars}}" wx:key="label">
|
||||||
|
<view class="trend-bar {{item.value === 0 ? 'zero' : ''}} {{item.highlight ? 'highlight' : ''}}" style="height: {{item.percent}}%;">
|
||||||
|
<text class="trend-bar-value" wx:if="{{item.value > 0}}">{{item.valueText}}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="trend-labels">
|
||||||
<view class="trend-labels">
|
<text class="trend-bar-label {{item.highlight ? 'highlight' : ''}}" wx:for="{{bars}}" wx:key="label">{{item.label}}</text>
|
||||||
<text class="trend-bar-label {{item.highlight ? 'highlight' : ''}}" wx:for="{{bars}}" wx:key="label">{{item.label}}</text>
|
</view>
|
||||||
</view>
|
</block>
|
||||||
|
|
||||||
|
<!-- Line mode -->
|
||||||
|
<block wx:else>
|
||||||
|
<view class="trend-line">
|
||||||
|
<image class="trend-line-img" src="{{lineSvg}}" mode="widthFix"></image>
|
||||||
|
<view wx:for="{{linePoints}}" wx:key="label" class="trend-line-dot {{item.highlight ? 'highlight' : ''}}" style="left: {{item.xPercent}}%; top: {{item.yPercent}}%;">
|
||||||
|
<text wx:if="{{item.value > 0}}" class="trend-line-value">{{item.valueText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="trend-line-labels">
|
||||||
|
<text wx:for="{{linePoints}}" wx:key="label" class="trend-line-label {{item.highlight ? 'highlight' : ''}}" style="left: {{item.xPercent}}%;">{{item.label}}</text>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -92,3 +92,80 @@
|
|||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Line mode ---- */
|
||||||
|
.trend-chart.line {
|
||||||
|
/* extra top room so the value caption above the highest dot isn't clipped */
|
||||||
|
padding-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-dot {
|
||||||
|
position: absolute;
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
margin-left: -8rpx;
|
||||||
|
margin-top: -8rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--primary);
|
||||||
|
border: 3rpx solid var(--card-bg, #FFFFFF);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-chart.peak .trend-line-dot {
|
||||||
|
background: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-dot.highlight {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
margin-left: -10rpx;
|
||||||
|
margin-top: -10rpx;
|
||||||
|
box-shadow: 0 0 14rpx rgba(var(--primary-rgb), 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* value caption floats above the dot so it never eats into the line */
|
||||||
|
.trend-line-value {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
font-size: 16rpx;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-dot.highlight .trend-line-value {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-labels {
|
||||||
|
position: relative;
|
||||||
|
height: 28rpx;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-label {
|
||||||
|
position: absolute;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trend-line-label.highlight {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ Page({
|
|||||||
trendSummary: {},
|
trendSummary: {},
|
||||||
bestTrendData: [],
|
bestTrendData: [],
|
||||||
bestTrendSummary: {},
|
bestTrendSummary: {},
|
||||||
|
bestLineColor: '#FF6B35',
|
||||||
showDayDetail: false,
|
showDayDetail: false,
|
||||||
dayDetail: {},
|
dayDetail: {},
|
||||||
icons: iconsMod.build()
|
icons: iconsMod.build()
|
||||||
@@ -138,7 +139,8 @@ Page({
|
|||||||
trendData,
|
trendData,
|
||||||
trendSummary: { ...util.getTrendSummary(trendData, trendMode), streakCount: Number(streak.count) || 0 },
|
trendSummary: { ...util.getTrendSummary(trendData, trendMode), streakCount: Number(streak.count) || 0 },
|
||||||
bestTrendData,
|
bestTrendData,
|
||||||
bestTrendSummary: util.getTrendSummary(bestTrendData, trendMode),
|
bestTrendSummary: this._buildBestSummary(bestTrendData, trendMode),
|
||||||
|
bestLineColor: theme.primary,
|
||||||
loading: false
|
loading: false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -199,7 +201,8 @@ Page({
|
|||||||
trendData,
|
trendData,
|
||||||
trendSummary: { ...util.getTrendSummary(trendData, mode), streakCount: Number(storage.getStreak().count) || 0 },
|
trendSummary: { ...util.getTrendSummary(trendData, mode), streakCount: Number(storage.getStreak().count) || 0 },
|
||||||
bestTrendData,
|
bestTrendData,
|
||||||
bestTrendSummary: util.getTrendSummary(bestTrendData, mode)
|
bestTrendSummary: this._buildBestSummary(bestTrendData, mode),
|
||||||
|
bestLineColor: themeMod.getCurrentTheme().primary
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -217,6 +220,16 @@ Page({
|
|||||||
return util.getBestTrendData(storage.getRecords(), mode)
|
return util.getBestTrendData(storage.getRecords(), mode)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 个人最佳趋势的峰值摘要:复用通用 getTrendSummary,但把 peakTitle 从
|
||||||
|
* "最高训练日/月" 覆盖成 "个人最佳日/月",贴合"个人最佳趋势"区块语义。
|
||||||
|
*/
|
||||||
|
_buildBestSummary(bestTrendData, mode) {
|
||||||
|
const s = util.getTrendSummary(bestTrendData, mode)
|
||||||
|
s.peakTitle = mode === 'month' ? '个人最佳月' : '个人最佳日'
|
||||||
|
return s
|
||||||
|
},
|
||||||
|
|
||||||
onDayTap(e) {
|
onDayTap(e) {
|
||||||
const { year, month, day } = e.detail
|
const { year, month, day } = e.detail
|
||||||
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
|
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
|
||||||
|
|||||||
@@ -125,9 +125,13 @@
|
|||||||
<image class="history-title-icon" src="{{icons.crownFill}}" mode="aspectFit"></image>
|
<image class="history-title-icon" src="{{icons.crownFill}}" mode="aspectFit"></image>
|
||||||
<text class="best-trend-title">个人最佳趋势</text>
|
<text class="best-trend-title">个人最佳趋势</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="best-trend-best">{{bestTrendSummary.peakText}}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<trend-chart chart-data="{{bestTrendData}}" variant="peak"></trend-chart>
|
<trend-chart chart-data="{{bestTrendData}}" variant="peak" chart-type="line" line-color="{{bestLineColor}}"></trend-chart>
|
||||||
|
<view class="trend-highlight">
|
||||||
|
<image class="trend-highlight-icon" src="{{icons.crownFill}}" mode="aspectFit"></image>
|
||||||
|
<text class="trend-highlight-title">{{bestTrendSummary.peakTitle}}</text>
|
||||||
|
<text class="trend-highlight-text">{{bestTrendSummary.peakText}}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
</block>
|
</block>
|
||||||
|
|||||||
@@ -360,12 +360,6 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.best-trend-best {
|
|
||||||
color: var(--primary);
|
|
||||||
font-size: 20rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- history ---- */
|
/* ---- history ---- */
|
||||||
.history-section {
|
.history-section {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user