移除期望城市TOP8图表(无实际作用), 其余三图自动重排

This commit is contained in:
mzl92
2026-08-27 15:51:44 +08:00
parent 5843898e59
commit 2faaa6f032
3 changed files with 4 additions and 11 deletions
+3 -9
View File
@@ -103,9 +103,8 @@ tr.today:hover td{background:#fde68a!important}
<div class="panel"><h3>近30天趋势</h3><div id="chTrend" style="height:300px"></div></div> <div class="panel"><h3>近30天趋势</h3><div id="chTrend" style="height:300px"></div></div>
<div class="chartRow"> <div class="chartRow">
<div class="panel"><h3>评分级别分布</h3><div id="chLevel" style="height:280px"></div></div> <div class="panel"><h3>评分级别分布</h3><div id="chLevel" style="height:280px"></div></div>
<div class="panel"><h3>学历分布</h3><div id="chEdu" style="height:280px"></div></div> <div class="panel"><h3>学历分布</h3><div id="chEdu" style="height:280px"></div></div>
<div class="panel"><h3>期望城市 TOP8</h3><div id="chCity" style="height:280px"></div></div> <div class="panel"><h3>筛选漏斗</h3><div id="chFunnel" style="height:280px"></div></div>
<div class="panel"><h3>筛选漏斗</h3><div id="chFunnel" style="height:280px"></div></div>
</div> </div>
</section> </section>
<section class="pane"> <section class="pane">
@@ -240,7 +239,7 @@ async function loadStats(){
const charts=[]; const charts=[];
function mkChart(id){const c=echarts.init($(id));charts.push(c);return c} function mkChart(id){const c=echarts.init($(id));charts.push(c);return c}
function renderCharts(s){ function renderCharts(s){
if(typeof echarts==='undefined'){['chTrend','chLevel','chEdu','chCity','chFunnel'].forEach(id=>{$(id).innerHTML='<div style="color:var(--sub);padding:40px;text-align:center">图表库未加载</div>'});return} if(typeof echarts==='undefined'){['chTrend','chLevel','chEdu','chFunnel'].forEach(id=>{$(id).innerHTML='<div style="color:var(--sub);padding:40px;text-align:center">图表库未加载</div>'});return}
charts.splice(0).forEach(c=>c.dispose()); charts.splice(0).forEach(c=>c.dispose());
const axis='#6b7280',split='#e5e7eb'; const axis='#6b7280',split='#e5e7eb';
mkChart('chTrend').setOption({ mkChart('chTrend').setOption({
@@ -263,11 +262,6 @@ function renderCharts(s){
xAxis:{type:'category',data:s.byEducation.map(x=>x.k),axisLabel:{color:axis,interval:0},axisLine:{lineStyle:{color:split}}}, xAxis:{type:'category',data:s.byEducation.map(x=>x.k),axisLabel:{color:axis,interval:0},axisLine:{lineStyle:{color:split}}},
yAxis:{type:'value',axisLabel:{color:axis},splitLine:{lineStyle:{color:split}}}, yAxis:{type:'value',axisLabel:{color:axis},splitLine:{lineStyle:{color:split}}},
series:[{type:'bar',barWidth:'55%',data:s.byEducation.map(x=>x.c),itemStyle:{color:'#2563eb',borderRadius:[4,4,0,0]}}]}); series:[{type:'bar',barWidth:'55%',data:s.byEducation.map(x=>x.c),itemStyle:{color:'#2563eb',borderRadius:[4,4,0,0]}}]});
mkChart('chCity').setOption({
tooltip:{},grid:{left:70,right:30,top:20,bottom:30},
xAxis:{type:'value',axisLabel:{color:axis},splitLine:{lineStyle:{color:split}}},
yAxis:{type:'category',data:s.byCity.map(x=>x.k).reverse(),axisLabel:{color:axis}},
series:[{type:'bar',barWidth:'55%',data:s.byCity.map(x=>x.c).reverse(),itemStyle:{color:'#0ea5e9',borderRadius:[0,4,4,0]}}]});
const lv=s.byLevel.reduce((m,x)=>(m[x.k]=x.c,m),{}); const lv=s.byLevel.reduce((m,x)=>(m[x.k]=x.c,m),{});
mkChart('chFunnel').setOption({ mkChart('chFunnel').setOption({
tooltip:{trigger:'item',formatter:'{b}: {c}'}, tooltip:{trigger:'item',formatter:'{b}: {c}'},
+1 -1
View File
@@ -43,7 +43,7 @@ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
ok('累计候选人为五位数(数据在库)', /\d{5,}/.test(statText)); ok('累计候选人为五位数(数据在库)', /\d{5,}/.test(statText));
ok('级别分布含推荐', statText.includes('推荐')); ok('级别分布含推荐', statText.includes('推荐'));
const canvasN = await p.evaluate(() => document.querySelectorAll('#main canvas').length); const canvasN = await p.evaluate(() => document.querySelectorAll('#main canvas').length);
ok(`图表已渲染(canvas=${canvasN},≥5)`, canvasN >= 5); ok(`图表已渲染(canvas=${canvasN},≥4)`, canvasN >= 4);
console.log('== 4. 候选人列表与筛选(滑动到第二屏) =='); console.log('== 4. 候选人列表与筛选(滑动到第二屏) ==');
await p.evaluate(() => setPane(1)); await sleep(500); await p.evaluate(() => setPane(1)); await sleep(500);
-1
View File
@@ -154,7 +154,6 @@ app.get('/api/stats', requireAuth, (req, res) => {
greetedTotal: rdb.prepare('SELECT COUNT(*) c FROM candidates WHERE greeted = 1').get().c, greetedTotal: rdb.prepare('SELECT COUNT(*) c FROM candidates WHERE greeted = 1').get().c,
byLevel: rdb.prepare("SELECT COALESCE(score_level,'?') k, COUNT(*) c FROM candidates GROUP BY score_level").all(), byLevel: rdb.prepare("SELECT COALESCE(score_level,'?') k, COUNT(*) c FROM candidates GROUP BY score_level").all(),
byEducation: rdb.prepare("SELECT COALESCE(NULLIF(education,''),'未知') k, COUNT(*) c FROM candidates GROUP BY education ORDER BY c DESC LIMIT 8").all(), byEducation: rdb.prepare("SELECT COALESCE(NULLIF(education,''),'未知') k, COUNT(*) c FROM candidates GROUP BY education ORDER BY c DESC LIMIT 8").all(),
byCity: rdb.prepare("SELECT expected_city k, COUNT(*) c FROM candidates WHERE expected_city != '' GROUP BY expected_city ORDER BY c DESC LIMIT 8").all(),
byAccount: rdb.prepare("SELECT COALESCE(NULLIF(account,''),'未知') k, COUNT(*) c, SUM(greeted) g FROM candidates GROUP BY account ORDER BY c DESC").all(), byAccount: rdb.prepare("SELECT COALESCE(NULLIF(account,''),'未知') k, COUNT(*) c, SUM(greeted) g FROM candidates GROUP BY account ORDER BY c DESC").all(),
last30: rdb.prepare(`SELECT substr(scraped_at,1,10) d, COUNT(*) c, last30: rdb.prepare(`SELECT substr(scraped_at,1,10) d, COUNT(*) c,
SUM(CASE WHEN score_level='推荐' THEN 1 ELSE 0 END) rec, SUM(CASE WHEN score_level='推荐' THEN 1 ELSE 0 END) rec,