21
This commit is contained in:
parent
593f13ca15
commit
b24b09557d
|
|
@ -16,7 +16,7 @@
|
||||||
| 8.2 | 细分能力精准分析(×8) | `/report/sub-ability-detail?recordId=3&parentId=1` | 网页截图 | 单智能5项子能力雷达图+柱状图+结论 | ✅ 已完成 |
|
| 8.2 | 细分能力精准分析(×8) | `/report/sub-ability-detail?recordId=3&parentId=1` | 网页截图 | 单智能5项子能力雷达图+柱状图+结论 | ✅ 已完成 |
|
||||||
| 8.3 | 细分能力精准分析-竖向柱状图(×8) | `/report/sub-ability-detail-v?recordId=3&parentId=8` | 网页截图 | 单智能5项子能力雷达图+竖向柱状图+结论 | ✅ 已完成 |
|
| 8.3 | 细分能力精准分析-竖向柱状图(×8) | `/report/sub-ability-detail-v?recordId=3&parentId=8` | 网页截图 | 单智能5项子能力雷达图+竖向柱状图+结论 | ✅ 已完成 |
|
||||||
| 9 | 先天学习类型分析 | `/report/learning-types?recordId=3` | 网页截图 | CategoryType=4 雷达图+竖向柱状图(多色)+结论 | ✅ 已完成 |
|
| 9 | 先天学习类型分析 | `/report/learning-types?recordId=3` | 网页截图 | CategoryType=4 雷达图+竖向柱状图(多色)+结论 | ✅ 已完成 |
|
||||||
| 10 | 学习关键能力分析 | `/report/learning-abilities` | 网页截图 | CategoryType=5 结果+结论 | ⬜ 骨架 |
|
| 10 | 学习关键能力分析 | `/report/learning-abilities?recordId=3` | 网页截图 | CategoryType=5 雷达图+竖向柱状图(多色) | ✅ 已完成 |
|
||||||
| 11 | 科学大脑类型分析 | `/report/brain-types` | 网页截图 | CategoryType=6 结果+结论 | ⬜ 骨架 |
|
| 11 | 科学大脑类型分析 | `/report/brain-types` | 网页截图 | CategoryType=6 结果+结论 | ⬜ 骨架 |
|
||||||
| 12 | 性格类型分析 | `/report/character-types` | 网页截图 | CategoryType=7 结果+结论 | ⬜ 骨架 |
|
| 12 | 性格类型分析 | `/report/character-types` | 网页截图 | CategoryType=7 结果+结论 | ⬜ 骨架 |
|
||||||
| 13 | 未来关键发展能力分析 | `/report/future-abilities` | 网页截图 | CategoryType=8 结果+结论 | ⬜ 骨架 |
|
| 13 | 未来关键发展能力分析 | `/report/future-abilities` | 网页截图 | CategoryType=8 结果+结论 | ⬜ 骨架 |
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
@page "/report/learning-abilities"
|
@page "/report/learning-abilities"
|
||||||
@model MiAssessment.Api.Pages.Report.LearningAbilitiesModel
|
@model MiAssessment.Api.Pages.Report.LearningAbilitiesModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "学习关键能力分析";
|
ViewData["Title"] = "学习的关键能力";
|
||||||
ViewData["PageTitle"] = "学习关键能力分析";
|
ViewData["PageTitle"] = null;
|
||||||
|
ViewData["PageNumber"] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (!Model.IsSuccess)
|
@if (!Model.IsSuccess)
|
||||||
|
|
@ -13,7 +14,178 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="learning-abilities-content">
|
<div class="la-page">
|
||||||
<p class="no-content">学习关键能力分析占位 - 具体内容后续实现</p>
|
<!-- 板块标题 -->
|
||||||
|
<div class="la-section-title">5、学习的关键能力</div>
|
||||||
|
|
||||||
|
<!-- 雷达图 + 竖向柱状图 -->
|
||||||
|
<div class="la-charts">
|
||||||
|
<!-- 左侧:雷达图 -->
|
||||||
|
<div class="la-chart-panel">
|
||||||
|
<div class="la-chart-title">学习的关键能力</div>
|
||||||
|
<canvas id="radarChart" width="520" height="480"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧:竖向柱状图 -->
|
||||||
|
<div class="la-chart-panel">
|
||||||
|
<div class="la-chart-title">学习的关键能力排名</div>
|
||||||
|
<canvas id="barChart" width="560" height="480"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@section Styles {
|
||||||
|
<link rel="stylesheet" href="/css/pages/learning-abilities.css" />
|
||||||
|
}
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
|
||||||
|
<script>
|
||||||
|
window.__deferRenderComplete = true;
|
||||||
|
|
||||||
|
// 雷达图数据(按 CategoryId 排序)
|
||||||
|
var radarLabels = [@Html.Raw(string.Join(",", Model.Items.Select(x => $"\"{x.CategoryName}\"")))];
|
||||||
|
var radarScores = [@Html.Raw(string.Join(",", Model.Items.Select(x => x.Score.ToString("F0"))))];
|
||||||
|
var maxScore = Math.ceil(Math.max(...radarScores) / 2) * 2 + 2;
|
||||||
|
|
||||||
|
// 柱状图数据(按分数降序)
|
||||||
|
var barLabels = [@Html.Raw(string.Join(",", Model.ItemsByScore.Select(x => $"\"{x.CategoryName}\"")))];
|
||||||
|
var barScores = [@Html.Raw(string.Join(",", Model.ItemsByScore.Select(x => x.Score.ToString("F0"))))];
|
||||||
|
var barMax = Math.ceil(Math.max(...barScores) / 2) * 2 + 2;
|
||||||
|
|
||||||
|
// 每根柱子不同颜色
|
||||||
|
var barColors = ['#4A90E2', '#52A06A', '#F5A623', '#E88B9C', '#2ABFBF'];
|
||||||
|
var barColorsAlpha = ['rgba(74,144,226,0.7)', 'rgba(82,160,106,0.7)', 'rgba(245,166,35,0.7)', 'rgba(232,139,156,0.7)', 'rgba(42,191,191,0.7)'];
|
||||||
|
|
||||||
|
// 雷达图主色(蓝色系)
|
||||||
|
var radarColor = '#4A90E2';
|
||||||
|
|
||||||
|
// ---- 雷达图 ----
|
||||||
|
var ctxRadar = document.getElementById('radarChart').getContext('2d');
|
||||||
|
new Chart(ctxRadar, {
|
||||||
|
type: 'radar',
|
||||||
|
data: {
|
||||||
|
labels: radarLabels,
|
||||||
|
datasets: [{
|
||||||
|
data: radarScores,
|
||||||
|
backgroundColor: 'rgba(74, 144, 226, 0.12)',
|
||||||
|
borderColor: 'rgba(74, 144, 226, 0.8)',
|
||||||
|
borderWidth: 2,
|
||||||
|
pointBackgroundColor: 'rgba(74, 144, 226, 0.9)',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointRadius: 4,
|
||||||
|
pointBorderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: false,
|
||||||
|
plugins: { legend: { display: false } },
|
||||||
|
scales: {
|
||||||
|
r: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: maxScore,
|
||||||
|
ticks: {
|
||||||
|
stepSize: 2,
|
||||||
|
font: { size: 12 },
|
||||||
|
backdropColor: 'transparent',
|
||||||
|
color: '#999'
|
||||||
|
},
|
||||||
|
pointLabels: {
|
||||||
|
font: { size: 14, weight: '500' },
|
||||||
|
color: '#333',
|
||||||
|
padding: 12
|
||||||
|
},
|
||||||
|
grid: { color: 'rgba(0,0,0,0.06)' },
|
||||||
|
angleLines: { color: 'rgba(0,0,0,0.06)' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [{
|
||||||
|
afterDatasetsDraw: function(chart) {
|
||||||
|
var meta = chart.getDatasetMeta(0);
|
||||||
|
var ctx2 = chart.ctx;
|
||||||
|
ctx2.font = 'bold 13px sans-serif';
|
||||||
|
ctx2.fillStyle = radarColor;
|
||||||
|
ctx2.textBaseline = 'middle';
|
||||||
|
meta.data.forEach(function(point, i) {
|
||||||
|
var val = radarScores[i];
|
||||||
|
var cx = chart.scales.r.xCenter;
|
||||||
|
var cy = chart.scales.r.yCenter;
|
||||||
|
var dx = point.x - cx;
|
||||||
|
var dy = point.y - cy;
|
||||||
|
var dist = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
if (dist === 0) dist = 1;
|
||||||
|
var ox = (dx / dist) * 18;
|
||||||
|
var oy = (dy / dist) * 18;
|
||||||
|
ctx2.textAlign = 'center';
|
||||||
|
ctx2.fillText(val, point.x + ox, point.y + oy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---- 竖向柱状图 ----
|
||||||
|
var barDataLabelPlugin = {
|
||||||
|
id: 'barDataLabels',
|
||||||
|
afterDatasetsDraw: function(chart) {
|
||||||
|
var ctx = chart.ctx;
|
||||||
|
var meta = chart.getDatasetMeta(0);
|
||||||
|
var dataset = chart.data.datasets[0];
|
||||||
|
ctx.font = 'bold 13px "Microsoft YaHei", sans-serif';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.textBaseline = 'bottom';
|
||||||
|
meta.data.forEach(function(bar, i) {
|
||||||
|
var val = dataset.data[i];
|
||||||
|
ctx.fillStyle = '#333';
|
||||||
|
ctx.fillText(val, bar.x, bar.y - 4);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ctxBar = document.getElementById('barChart').getContext('2d');
|
||||||
|
new Chart(ctxBar, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: barLabels,
|
||||||
|
datasets: [{
|
||||||
|
data: barScores,
|
||||||
|
backgroundColor: barColorsAlpha,
|
||||||
|
borderColor: barColors,
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: 3,
|
||||||
|
barThickness: 56
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: false,
|
||||||
|
plugins: { legend: { display: false } },
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: barMax,
|
||||||
|
ticks: {
|
||||||
|
stepSize: 2,
|
||||||
|
font: { size: 12 },
|
||||||
|
color: '#999'
|
||||||
|
},
|
||||||
|
grid: { color: 'rgba(0,0,0,0.05)' }
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
ticks: {
|
||||||
|
font: { size: 13 },
|
||||||
|
color: '#666'
|
||||||
|
},
|
||||||
|
grid: { display: false }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
padding: { top: 25 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [barDataLabelPlugin]
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.setAttribute('data-render-complete', 'true');
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,48 @@
|
||||||
using MiAssessment.Core.Interfaces;
|
using MiAssessment.Core.Interfaces;
|
||||||
|
using MiAssessment.Model.Models.Report;
|
||||||
|
|
||||||
namespace MiAssessment.Api.Pages.Report;
|
namespace MiAssessment.Api.Pages.Report;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 学习关键能力分析 PageModel
|
/// 学习的关键能力分析页 PageModel
|
||||||
|
/// 路由:/report/learning-abilities?recordId=3
|
||||||
|
/// CategoryType=5 的5种能力:学习专注力、学习思考力、学习转化力、学习记忆力、学习动机力
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LearningAbilitiesModel : ReportPageModelBase
|
public class LearningAbilitiesModel : ReportPageModelBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 能力列表(按 CategoryId 排序,雷达图用)
|
||||||
|
/// </summary>
|
||||||
|
public List<CategoryResultDataDto> Items { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按分数降序排列(柱状图用)
|
||||||
|
/// </summary>
|
||||||
|
public List<CategoryResultDataDto> ItemsByScore { get; set; } = new();
|
||||||
|
|
||||||
public LearningAbilitiesModel(IReportDataService reportDataService)
|
public LearningAbilitiesModel(IReportDataService reportDataService)
|
||||||
: base(reportDataService)
|
: base(reportDataService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task OnDataLoadedAsync()
|
||||||
|
{
|
||||||
|
if (ReportData?.ResultsByType == null ||
|
||||||
|
!ReportData.ResultsByType.TryGetValue(5, out var allItems))
|
||||||
|
{
|
||||||
|
ErrorMessage = "缺少学习关键能力数据";
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
Items = allItems.OrderBy(x => x.CategoryId).ToList();
|
||||||
|
|
||||||
|
if (Items.Count == 0)
|
||||||
|
{
|
||||||
|
ErrorMessage = "未找到学习关键能力数据";
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemsByScore = Items.OrderByDescending(x => x.Score).ToList();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* ============================================
|
||||||
|
学习的关键能力分析页
|
||||||
|
页面固定尺寸:1309×926px
|
||||||
|
只有雷达图+竖向柱状图,无结论卡片
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
.la-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 板块标题 */
|
||||||
|
.la-section-title {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #E67E73;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 雷达图 + 柱状图并排 ---- */
|
||||||
|
.la-charts {
|
||||||
|
display: flex;
|
||||||
|
gap: 40px;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.la-chart-panel {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图表小标题 */
|
||||||
|
.la-chart-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #E67E73;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user