diff --git a/pages/parent/report/report.js b/pages/parent/report/report.js index ef10e54..c10fca8 100644 --- a/pages/parent/report/report.js +++ b/pages/parent/report/report.js @@ -290,9 +290,35 @@ Page({ const currentDataLabels = list.map(i => { const score = i.lastScore != null ? i.lastScore : '' const rank = i.rank != null ? i.rank : '' + return '' return rank ? score + '\n' + rank : String(score) }) + // 富文本 label:名称行 + 颜色区分的成绩行(上次/本次+等级) + const labelLines = list.map(i => { + const name = i.name || '' + const lines = [] + // 名称行,超5字自动换行 + if (name.length > 15) { + const mid = Math.ceil(name.length / 2) + lines.push(name.slice(0, mid)) + lines.push(name.slice(mid)) + } else { + lines.push(name) + } + // 成绩行:上次(蓝)/本次+等级(红) + const prevScore = i.prevScore != null ? String(i.prevScore) : '-' + const lastScore = i.lastScore != null ? String(i.lastScore) : '-' + const rank = i.rank ? i.rank : '' + const currentText = rank ? lastScore + rank : lastScore + lines.push([ + { text: prevScore, color: '#4A90E2' }, + { text: ' / ', color: '#999999' }, + { text: currentText, color: '#E74C3C' }, + ]) + return lines + }) + const query = wx.createSelectorQuery().in(that) query.select('#radarCanvas').fields({ node: true, size: true }).exec(res => { if (!res[0]) return @@ -307,15 +333,15 @@ Page({ height: that.data.radarCHeight * that.data.pixelRatio, categories, series: [ - { name: '上次成绩', data: prevData, color: '#4A90E2', dataLabel: false }, - { name: '本次成绩', data: currentData, color: '#E74C3C', dataLabels: currentDataLabels, textColor: '#E74C3C', textSize: 11 }, + { name: '上次成绩', data: prevData, color: '#4A90E2', dataLabels: currentDataLabels }, + { name: '本次成绩', data: currentData, color: '#E74C3C', dataLabels: currentDataLabels, textColor: '#E74C3C', textSize: 11 }, ], pixelRatio: that.data.pixelRatio, animation: true, tapLegend:true, background: 'rgba(0,0,0,0)', color: ['#4A90E2', '#E74C3C'], - padding: [0, 0, 0, 15], + padding: [0, 0, 0, 20], legend: { show: true, position: 'bottom', @@ -339,6 +365,7 @@ Page({ labelMargin: 30, labelPointShow: false, max: 100, + labelLines, }, }, }) diff --git a/subpackage/teacher/report-detail/report-detail.js b/subpackage/teacher/report-detail/report-detail.js index 0820e13..b49591c 100644 --- a/subpackage/teacher/report-detail/report-detail.js +++ b/subpackage/teacher/report-detail/report-detail.js @@ -119,7 +119,10 @@ Page({ // min: Math.max(0, that.data.moderateHR - 20), max: that.data.highHR + 20, fontSize: 12, - tofix:0 + formatter: function (val) { + console.log('y轴刻度', val) + return val.toFixed(0); + } }] }, extra: { diff --git a/subpackage/teacher/student-fitness-detail/student-fitness-detail.js b/subpackage/teacher/student-fitness-detail/student-fitness-detail.js index 4d09b85..e394f4b 100644 --- a/subpackage/teacher/student-fitness-detail/student-fitness-detail.js +++ b/subpackage/teacher/student-fitness-detail/student-fitness-detail.js @@ -252,10 +252,34 @@ Page({ }); const prevData = list.map(i => i.prevScore || 0); const currentData = list.map(i => i.lastScore || 0); + // 本次成绩数据标签:显示分数 + 等级 const currentDataLabels = list.map(i => { - const score = i.lastScore != null ? i.lastScore : ''; - const rank = i.rank != null ? i.rank : ''; - return rank ? score + '\n' + rank : String(score); + const score = i.lastScore != null ? i.lastScore : '' + const rank = i.rank != null ? i.rank : '' + return '' + return rank ? score + '\n' + rank : String(score) + }) + + // 富文本 label:名称行 + 颜色区分的成绩行(上次/本次+等级) + const labelLines = list.map(i => { + const name = i.name || ''; + const lines = []; + if (name.length > 15) { + const mid = Math.ceil(name.length / 2); + lines.push(name.slice(0, mid)); + lines.push(name.slice(mid)); + } else { + lines.push(name); + } + const prevScore = i.prevScore != null ? String(i.prevScore) : '-'; + const lastScore = i.lastScore != null ? String(i.lastScore) : '-'; + const rank = i.rank ? i.rank : ''; + const currentText = rank ? lastScore + rank : lastScore; + lines.push([ + { text: prevScore + '/', color: '#4A90E2' }, + { text: currentText, color: '#E74C3C' }, + ]); + return lines; }); const query = wx.createSelectorQuery().in(that); @@ -272,15 +296,15 @@ Page({ height: that.data.radarCHeight * that.data.pixelRatio, categories, series: [ - { name: '上次成绩', data: prevData, color: '#4A90E2', dataLabel: false }, - { name: '本次成绩', data: currentData, color: '#E74C3C', dataLabels: currentDataLabels, textColor: '#E74C3C', textSize: 11 }, + { name: '上次成绩', data: prevData, color: '#4A90E2', dataLabels: currentDataLabels }, + { name: '本次成绩', data: currentData, color: '#E74C3C', dataLabels: currentDataLabels }, ], pixelRatio: that.data.pixelRatio, animation: true, tapLegend: true, background: 'rgba(0,0,0,0)', color: ['#4A90E2', '#E74C3C'], - padding: [0, 0, 0, 10], + padding: [0, 0, 0, 20], legend: { show: true, position: 'bottom', @@ -304,6 +328,7 @@ Page({ labelMargin: 30, labelPointShow: false, max: 100, + labelLines, }, }, }); diff --git a/utils/chart/u-charts.js b/utils/chart/u-charts.js index a161b16..7e5f3dc 100644 --- a/utils/chart/u-charts.js +++ b/utils/chart/u-charts.js @@ -450,6 +450,8 @@ function measureText(text, fontSize, context) { width += 3.25; } else if (/:/.test(item)) { width += 2.5; + } else if (/\//.test(item)) { + width += 3.5; } else if (/[\u4e00-\u9fa5]/.test(item)) { width += 10; } else if (/\(|\)/.test(item)) { @@ -2461,31 +2463,79 @@ function drawRadarLabel(angleList, radius, centerPosition, opts, config, context y: (radius + labelMargin * opts.pix) * Math.sin(angle) }; var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition); - var startX = posRelativeCanvas.x; var startY = posRelativeCanvas.y; - var labelLines = (opts.categories[index] || '').split('\n'); - var maxLineWidth = Math.max.apply(null, labelLines.map(function(l) { return measureText(l, config.fontSize, context); })); - if (util.approximatelyEqual(pos.x, 0)) { - startX -= maxLineWidth / 2; - } else if (pos.x < 0) { - startX -= maxLineWidth; - } - context.beginPath(); - context.setFontSize(config.fontSize); - context.setFillStyle(radarOption.labelColor || opts.fontColor); - var lineHeight = config.fontSize + 4 * opts.pix; - var offsetY = labelLines.length > 1 ? -(labelLines.length - 1) * lineHeight / 2 : 0; - labelLines.forEach(function(line, li) { - var lx = posRelativeCanvas.x; + var richLines = radarOption.labelLines && radarOption.labelLines[index]; + if (richLines) { + // Rich text mode: each element is a plain string or array of {text, color} segments + context.beginPath(); + context.setFontSize(config.fontSize); + var lineHeight = config.fontSize + 4 * opts.pix; + var offsetY = richLines.length > 1 ? -(richLines.length - 1) * lineHeight / 2 : 0; + richLines.forEach(function(lineData, li) { + var y = startY + config.fontSize / 2 + offsetY + li * lineHeight; + if (Array.isArray(lineData)) { + // Multi-color segments + var totalWidth = lineData.reduce(function(sum, seg) { + return sum + measureText(seg.text, config.fontSize, context); + }, 0); + var lx; + if (util.approximatelyEqual(pos.x, 0)) { + lx = posRelativeCanvas.x - totalWidth / 2; + } else if (pos.x < 0) { + lx = posRelativeCanvas.x - totalWidth; + } else { + lx = posRelativeCanvas.x; + } + lineData.forEach(function(seg) { + var segWidth = measureText(seg.text, config.fontSize, context); + context.setFillStyle(seg.color || radarOption.labelColor || opts.fontColor); + context.fillText(seg.text, lx, y); + lx += segWidth; + }); + } else { + // Plain string + var lineText = String(lineData); + var lx; + if (util.approximatelyEqual(pos.x, 0)) { + lx = posRelativeCanvas.x - measureText(lineText, config.fontSize, context) / 2; + } else if (pos.x < 0) { + lx = posRelativeCanvas.x - measureText(lineText, config.fontSize, context); + } else { + lx = posRelativeCanvas.x; + } + context.setFillStyle(radarOption.labelColor || opts.fontColor); + context.fillText(lineText, lx, y); + } + }); + context.closePath(); + context.stroke(); + } else { + // Original plain text mode + var labelLines = (opts.categories[index] || '').split('\n'); + var maxLineWidth = Math.max.apply(null, labelLines.map(function(l) { return measureText(l, config.fontSize, context); })); + var startX = posRelativeCanvas.x; if (util.approximatelyEqual(pos.x, 0)) { - lx -= measureText(line, config.fontSize, context) / 2; + startX -= maxLineWidth / 2; } else if (pos.x < 0) { - lx -= measureText(line, config.fontSize, context); + startX -= maxLineWidth; } - context.fillText(line, lx, startY + config.fontSize / 2 + offsetY + li * lineHeight); - }); - context.closePath(); - context.stroke(); + context.beginPath(); + context.setFontSize(config.fontSize); + context.setFillStyle(radarOption.labelColor || opts.fontColor); + var lineHeight = config.fontSize + 4 * opts.pix; + var offsetY = labelLines.length > 1 ? -(labelLines.length - 1) * lineHeight / 2 : 0; + labelLines.forEach(function(line, li) { + var lx = posRelativeCanvas.x; + if (util.approximatelyEqual(pos.x, 0)) { + lx -= measureText(line, config.fontSize, context) / 2; + } else if (pos.x < 0) { + lx -= measureText(line, config.fontSize, context); + } + context.fillText(line, lx, startY + config.fontSize / 2 + offsetY + li * lineHeight); + }); + context.closePath(); + context.stroke(); + } } });