Initial commit

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
lofyer
2026-07-13 15:38:41 +08:00
co-authored by factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
commit 71db82393a
180 changed files with 170640 additions and 0 deletions
@@ -0,0 +1,208 @@
{# 第一部分:总体概览的所有图表 #}
<script>
// ===== 1. 得分对比横向条形图 =====
const scoreCompare = {{ score_compare_data | tojson }};
(function() {
const chart = echarts.init(document.getElementById('score-compare-chart'));
const option = {
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
legend: { data: [scoreCompare.school_name, '区均值', '同类学校均值'], bottom: 5, textStyle: { fontSize: 12 } },
grid: { left: '3%', right: '8%', bottom: '18%', top: '5%', containLabel: true },
xAxis: { type: 'value', min: 30, max: 80 },
yAxis: { type: 'category', data: scoreCompare.categories, axisLabel: { fontSize: 12 } },
series: [
{ name: scoreCompare.school_name, type: 'bar', data: scoreCompare.school_values,
itemStyle: { color: COLORS.primary }, barWidth: '22%',
label: { show: true, position: 'right', fontSize: 11 } },
{ name: '区均值', type: 'bar', data: scoreCompare.district_avg,
itemStyle: { color: COLORS.gray }, barWidth: '22%' },
{ name: '同类学校均值', type: 'bar', data: scoreCompare.same_type_avg,
itemStyle: { color: COLORS.warning }, barWidth: '22%' },
],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
// ===== 2. 七维度雷达图 =====
const radarData = {{ radar_data | tojson }};
(function() {
const chart = echarts.init(document.getElementById('radar-chart'));
const option = {
tooltip: {},
legend: { data: radarData.legend, bottom: 10 },
radar: {
indicator: radarData.dimensions.map(d => ({ name: d, max: 80 })),
shape: 'polygon', splitNumber: 4,
axisName: { color: '#333', fontSize: 12 }, radius: '65%',
},
series: [{
type: 'radar',
data: radarData.series.map((s, i) => ({
value: s.values, name: s.name,
areaStyle: { opacity: i === 0 ? 0.3 : 0.1 },
lineStyle: { width: i === 0 ? 3 : 1 },
})),
}],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
// ===== 3. 聚类类型分布饼图 =====
const clusterDist = {{ cluster_type_dist_data | tojson }};
if (clusterDist.total) {
(function() {
const chart = echarts.init(document.getElementById('cluster-type-dist-chart'));
const option = {
tooltip: { trigger: 'item' },
legend: { bottom: 5, textStyle: { fontSize: 11 } },
series: [{
type: 'pie', radius: ['35%', '60%'], center: ['50%', '45%'],
avoidLabelOverlap: true,
itemStyle: { borderRadius: 8, borderColor: '#fff', borderWidth: 2 },
label: { show: true, formatter: '{b}\n{c}所 ({d}%)', fontSize: 12 },
emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold' } },
data: [
{ value: clusterDist.good_count, name: '课程实施较好类', itemStyle: { color: COLORS.primary } },
{ value: clusterDist.weak_count, name: '课程实施待提升类', itemStyle: { color: COLORS.warning } },
]
}],
graphic: [{
type: 'text', left: 'center', top: '40%',
style: {
text: clusterDist.school_name + '\n属于' + (clusterDist.school_cluster === '较好' ? '较好类' : '待提升类'),
textAlign: 'center', fill: COLORS.primary, fontSize: 12, fontWeight: 'bold',
}
}],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
}
// ===== 4. 两类学校折线对比图 =====
const clusterLine = {{ cluster_line_compare_data | tojson }};
if (clusterLine.dimensions) {
(function() {
const chart = echarts.init(document.getElementById('cluster-line-chart'));
const option = {
tooltip: { trigger: 'axis' },
legend: {
data: ['课程实施较好类(' + clusterLine.good_count + '所)', '课程实施待提升类(' + clusterLine.weak_count + '所)'],
bottom: 5, textStyle: { fontSize: 11 }
},
grid: { left: '3%', right: '4%', bottom: '18%', top: '8%', containLabel: true },
xAxis: {
type: 'category', data: clusterLine.dimensions.map(d => d.replace('力', '')),
axisLabel: { fontSize: 11, rotate: 15 }, boundaryGap: false,
},
yAxis: { type: 'value', min: 40, max: 60 },
series: [
{
name: '课程实施较好类(' + clusterLine.good_count + '所)',
type: 'line', data: clusterLine.good_values,
lineStyle: { width: 3, color: COLORS.primary }, itemStyle: { color: COLORS.primary },
symbol: 'circle', symbolSize: 8,
label: { show: true, position: 'top', fontSize: 10, color: COLORS.primary, formatter: p => p.value.toFixed(2) },
},
{
name: '课程实施待提升类(' + clusterLine.weak_count + '所)',
type: 'line', data: clusterLine.weak_values,
lineStyle: { width: 3, color: COLORS.warning }, itemStyle: { color: COLORS.warning },
symbol: 'circle', symbolSize: 8,
label: { show: true, position: 'bottom', fontSize: 10, color: COLORS.warning, formatter: p => p.value.toFixed(2) },
},
],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
}
// ===== 5. 聚类类型对比雷达图 =====
const clusterRadar = {{ cluster_radar_data | tojson }};
if (clusterRadar.dimensions) {
(function() {
const chart = echarts.init(document.getElementById('cluster-radar-chart'));
const colorMap = [COLORS.cluster_good, COLORS.cluster_weak, COLORS.danger];
const option = {
tooltip: {},
legend: {
data: clusterRadar.legend, bottom: 5, textStyle: { fontSize: 11 },
formatter: function(name) {
if (name === '课程实施较好类') return name + '(' + clusterRadar.good_count + '所)';
if (name === '课程实施待提升类') return name + '(' + clusterRadar.weak_count + '所)';
return name;
}
},
radar: {
indicator: clusterRadar.dimensions.map(d => ({ name: d, max: 80 })),
shape: 'polygon', splitNumber: 4,
axisName: { color: '#333', fontSize: 11 }, radius: '60%',
},
series: [{
type: 'radar',
data: clusterRadar.series.map((s, i) => ({
value: s.values, name: s.name,
areaStyle: { opacity: i === 2 ? 0.05 : 0.15 },
lineStyle: { width: i === 2 ? 3 : 2, type: i === 2 ? 'solid' : 'dashed', color: colorMap[i] },
itemStyle: { color: colorMap[i] },
symbol: i === 2 ? 'diamond' : 'circle', symbolSize: i === 2 ? 8 : 4,
})),
}],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
}
// ===== 6. 区内学校排名条形图 =====
const rankingData = {{ school_ranking_data | tojson }};
if (rankingData.schools) {
(function() {
const chart = echarts.init(document.getElementById('school-ranking-chart'));
const barColors = rankingData.schools.map(s => s === rankingData.current_school ? COLORS.primary : COLORS.gray);
const option = {
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
grid: { left: '3%', right: '12%', bottom: '5%', top: '5%', containLabel: true },
xAxis: { type: 'value', min: 35, max: 65 },
yAxis: { type: 'category', data: rankingData.schools.slice().reverse(),
axisLabel: { fontSize: 12, fontWeight: function(v) { return v === rankingData.current_school ? 'bold' : 'normal'; } } },
series: [{
type: 'bar', barWidth: '50%',
data: rankingData.total_scores.slice().reverse().map((v, i) => ({
value: v, itemStyle: { color: barColors.slice().reverse()[i] },
})),
label: { show: true, position: 'right', fontSize: 12, fontWeight: 'bold', formatter: p => p.value.toFixed(1) },
}],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
}
// ===== 7. 维度间相关性热力图 =====
const corrData = {{ correlation_data | tojson }};
if (corrData.dimensions) {
(function() {
const chart = echarts.init(document.getElementById('correlation-chart'));
const names = corrData.short_names || corrData.dimensions;
const option = {
tooltip: { position: 'top', formatter: p => corrData.dimensions[p.value[0]] + ' × ' + corrData.dimensions[p.value[1]] + '<br/>相关系数: ' + p.value[2] },
grid: { left: '15%', right: '12%', bottom: '18%', top: '3%' },
xAxis: { type: 'category', data: names, axisLabel: { rotate: 30, fontSize: 11 }, splitArea: { show: true } },
yAxis: { type: 'category', data: names, axisLabel: { fontSize: 11 }, splitArea: { show: true } },
visualMap: { min: -1, max: 1, calculable: true, orient: 'vertical', right: 0, top: 'center',
inRange: { color: ['#fee2e2', '#fef3c7', '#f3f4f6', '#dbeafe', '#2563eb'] }, textStyle: { fontSize: 11 } },
series: [{
type: 'heatmap', data: corrData.data,
label: { show: true, fontSize: 11, formatter: p => p.value[2].toFixed(2) },
itemStyle: { borderWidth: 2, borderColor: '#fff' },
}],
};
chart.setOption(option);
window.addEventListener('resize', () => chart.resize());
})();
}
</script>