diff --git a/src/main/resources/static/js/siteCharts.js b/src/main/resources/static/js/siteCharts.js index f7325c3..0f138d9 100644 --- a/src/main/resources/static/js/siteCharts.js +++ b/src/main/resources/static/js/siteCharts.js @@ -89,7 +89,10 @@ } function formatDateYMD(date) { - return date.toISOString().slice(0, 10); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; } function renderTaxonomyCharts(container, tags, categories) { diff --git a/src/main/resources/static/min/siteCharts.min.js b/src/main/resources/static/min/siteCharts.min.js index 3a782cf..f40f878 100644 --- a/src/main/resources/static/min/siteCharts.min.js +++ b/src/main/resources/static/min/siteCharts.min.js @@ -1,4 +1,4 @@ !function(){"use strict";var e;let t=["#3b82f6","#10b981","#f59e0b","#ef4444","#8b5cf6","#ec4899","#14b8a6","#f97316","#6366f1","#0ea5e9"],a=new Map;function r(e){let t=Number(e)||0;return t>=1e6?(t/1e6).toFixed(1)+"M":t>=1e3?(t/1e3).toFixed(1)+"K":t.toString()}function o(e,t,a){return t.split(".").reduce((e,t)=>{if(e&&Object.prototype.hasOwnProperty.call(e,t))return e[t]},e)??a}function n(e,t,a){let r=document.createElement("section");r.className="xhhaocom-chartboard-section";let o=document.createElement("header");o.className="xhhaocom-chartboard-section__header",o.innerHTML=`
${t}
${a?`
${a}
`:""} - `,r.appendChild(o);let n=document.createElement("div");return n.className="xhhaocom-chartboard-section__body",r.appendChild(n),e.appendChild(r),n}function l(e,t){let a=document.createElement("div");a.className="xhhaocom-chartboard-card";let r=document.createElement("div");r.className="xhhaocom-chartboard-card__canvas";let o=document.createElement("canvas");if(r.appendChild(o),a.appendChild(r),t){let n=document.createElement("footer");n.className="xhhaocom-chartboard-card__footer",n.textContent=t,a.appendChild(n)}return e.appendChild(a),o}function i(e){return e.toISOString().slice(0,10)}let d=["rgba(255, 99, 132, 0.22)","rgba(255, 159, 64, 0.22)","rgba(255, 205, 86, 0.22)","rgba(75, 192, 192, 0.22)","rgba(54, 162, 235, 0.22)","rgba(153, 102, 255, 0.22)","rgba(201, 203, 207, 0.22)","rgba(236, 72, 153, 0.22)","rgba(16, 185, 129, 0.22)","rgba(14, 165, 233, 0.22)"],s=["rgb(255, 99, 132)","rgb(255, 159, 64)","rgb(255, 205, 86)","rgb(75, 192, 192)","rgb(54, 162, 235)","rgb(153, 102, 255)","rgb(201, 203, 207)","rgb(236, 72, 153)","rgb(16, 185, 129)","rgb(14, 165, 233)"];function c(e){return Array.from({length:e},(e,t)=>({background:d[t%d.length],border:s[t%s.length]}))}function h(){!function e(t,a=50){if("undefined"!=typeof Chart){t();return}if(a<=0){console.error("[ChartBoard] Chart.js 加载超时");return}setTimeout(()=>e(t,a-1),100)}(()=>{document.querySelectorAll(".xhhaocom-chartboard").forEach(e=>{if(!e.hasAttribute("data-initialized")){var d;e.setAttribute("data-initialized","true"),(d=e).classList.add("xhhaocom-chartboard"),d.innerHTML='
数据加载中…
',fetch("/apis/api.data.statistics.xhhao.com/v1alpha1/chart/data").then(e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return e.json()}).then(e=>(function e(d,s){(function e(t){let r=a.get(t);r&&(r.forEach(e=>{e?.destroy&&e.destroy()}),a.delete(t))})(d),d.innerHTML="";let h=d.getAttribute("data-types"),m=h?h.split(",").map(e=>e.trim()).filter(Boolean):["tags","categories","articles","comments","topArticles"],p=[];if(m.includes("tags")||m.includes("categories")){let $=m.includes("tags")?s.tags:null,u=m.includes("categories")?s.categories:null;p.push(...function e(a,r,i){let d=n(a,"标签与分类统计","展示全部标签和分类的文章数量占比"),s=[],c=(r||[]).map(e=>({name:e?.name??o(e,"spec.displayName")??o(e,"metadata.name")??"未命名标签",count:Number(e?.count??e?.total??o(e,"status.visiblePostCount",0))})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count),h=(i||[]).map(e=>({name:e?.name??o(e,"spec.displayName")??o(e,"metadata.name")??"未命名分类",count:Number(e?.total??e?.count??o(e,"status.visiblePostCount",0))})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count);if(!c.length&&!h.length)return d.innerHTML='
暂无标签或分类数据
',[];let m=[];if(c.length){let p=(r?.length||0)-c.length,$=p>0?`已使用标签 ${c.length} 个(另有 ${p} 个未使用)`:`已使用标签 ${c.length} 个`,u=l(d,$),g=u.closest(".xhhaocom-chartboard-card");g&&g.classList.add("xhhaocom-chartboard-card--animated");let b=new Chart(u,{type:"doughnut",data:{labels:c.map(e=>e.name),datasets:[{data:c.map(e=>e.count),backgroundColor:c.map((e,a)=>t[a%t.length]),borderWidth:2,borderColor:"#ffffff",cutout:"55%",hoverOffset:8,hoverBorderWidth:3}]},options:{maintainAspectRatio:!1,animation:{animateRotate:!0,animateScale:!0,duration:1200,easing:"easeOutQuart"},interaction:{intersect:!1,mode:"point"},plugins:{legend:{display:!1},tooltip:{enabled:!0,backgroundColor:"rgba(0, 0, 0, 0.8)",padding:12,cornerRadius:8,displayColors:!0,callbacks:{label:e=>`${e.label}: ${e.raw} 篇文章`}}},onHover(e,t){u.style.cursor=t.length>0?"pointer":"default"}}});b.canvas.style.height="220px",b.canvas.style.maxHeight="220px",b.resize(),m.push(b),g&&s.push(g)}if(h.length){let _=(i?.length||0)-h.length,f=_>0?`已使用分类 ${h.length} 个(另有 ${_} 个未使用)`:`已使用分类 ${h.length} 个`,v=l(d,f),x=v.closest(".xhhaocom-chartboard-card");x&&x.classList.add("xhhaocom-chartboard-card--animated");let y=[...h].sort((e,t)=>e.count-t.count),C=new Chart(v,{type:"line",data:{labels:y.map(e=>e.name),datasets:[{label:"文章数量",data:y.map(e=>e.count),borderColor:t[0],backgroundColor:t[0]+"20",borderWidth:3,fill:!0,tension:.4,pointRadius:5,pointHoverRadius:8,pointBackgroundColor:t[0],pointBorderColor:"#ffffff",pointBorderWidth:2,pointHoverBackgroundColor:t[0],pointHoverBorderColor:"#ffffff",pointHoverBorderWidth:3}]},options:{maintainAspectRatio:!1,animation:{duration:1500,easing:"easeOutQuart"},interaction:{intersect:!1,mode:"index"},scales:{x:{beginAtZero:!1,grid:{display:!1},ticks:{font:{size:11},maxRotation:45,minRotation:0}},y:{beginAtZero:!0,grid:{color:"rgba(0, 0, 0, 0.05)",drawBorder:!1},ticks:{font:{size:11},callback:e=>Number(e)}}},plugins:{legend:{display:!1},tooltip:{enabled:!0,backgroundColor:"rgba(0, 0, 0, 0.8)",padding:12,cornerRadius:8,displayColors:!0,callbacks:{label:e=>`${e.label}: ${e.raw} 篇文章`}}},onHover(e,t){v.style.cursor=t.length>0?"pointer":"default"}}});m.push(C),x&&s.push(x)}return 1===s.length&&(s[0].style.gridColumn="span 2"),m}(d,$,u))}m.includes("articles")&&p.push(...function e(t,a){let r=n(t,"文章发布趋势","按日期统计文章发布数量"),o=new Map;if((a||[]).forEach(e=>{let t=e.date||e.name;if(!t)return;let a=new Date(t);if(Number.isNaN(a.valueOf()))return;a.setHours(0,0,0,0);let r=i(a),n=Number(e.total??e.count??0);o.set(r,(o.get(r)||0)+n)}),!o.size)return r.innerHTML='
暂无文章数据
',[];let l=new Date;l.setHours(0,0,0,0);let d=new Date(l),s=new Date(d.getTime()-314496e5),c=new Date(s),h=(c.getDay()+6)%7;c.setDate(c.getDate()-h);let m=Math.ceil((Math.floor((d-c)/864e5)+1)/7),p=Array.from({length:m},(e,t)=>new Date(c.getTime()+7*t*864e5)),$=Math.max(...o.values(),0),u=document.createElement("div");u.className="xhhaocom-chartboard-card xhhaocom-chartboard-card--heatmap",u.style.gridColumn="1 / -1";let g=document.createElement("div");g.className="xhhaocom-chartboard-heatmap";let b=document.createElement("div");b.className="xhhaocom-chartboard-heatmap__tooltip",b.style.display="none",u.appendChild(b);let _=document.createElement("div");_.className="xhhaocom-chartboard-heatmap__months";let f=document.createElement("div");f.className="xhhaocom-chartboard-heatmap__weekdays",["一","二","三","四","五","六","日"].forEach(e=>{let t=document.createElement("div");t.className="xhhaocom-chartboard-heatmap__weekday",t.textContent=e,f.appendChild(t)});let v=document.createElement("div");v.className="xhhaocom-chartboard-heatmap__grid";let x=()=>{let e=u.getBoundingClientRect();if(0===e.width){requestAnimationFrame(x);return}let t=window.innerWidth<=768;if(t){let a="12px";_.style.gridTemplateColumns=`repeat(${m}, ${a})`,v.style.gridTemplateColumns=`repeat(${m}, ${a})`,document.documentElement.style.setProperty("--chartboard-heatmap-cell",a),document.documentElement.style.setProperty("--chartboard-heatmap-cell-width",a);return}let r=e.width-40-30-10,o=`${Math.max(8,Math.floor((r-(m-1)*4)/m))}px`;_.style.gridTemplateColumns=`repeat(${m}, ${o})`,v.style.gridTemplateColumns=`repeat(${m}, ${o})`,document.documentElement.style.setProperty("--chartboard-heatmap-cell",o),document.documentElement.style.setProperty("--chartboard-heatmap-cell-width",o)},y=new ResizeObserver(()=>{x()}),C,w=()=>{clearTimeout(C),C=setTimeout(()=>{x()},150)},E=e=>{if(!e||!$)return 0;if($<=1)return e>0?1:0;let t=Math.max(1,Math.ceil(.25*$)),a=Math.max(t+1,Math.ceil(.5*$));return e>=Math.max(a+1,Math.ceil(.75*$))?4:e>=a?3:e>=t?2:1},L=(e,t,a)=>{b.innerHTML=`${t}${a?`发布 ${a} 篇文章`:"无文章发布"}`,b.style.display="flex";let r=u.getBoundingClientRect(),o=b.getBoundingClientRect(),n=e.clientX-r.left+12,l=e.clientY-r.top-o.height-10;n+o.width>r.width&&(n=r.width-o.width-8),l<0&&(l=e.clientY-r.top+12),b.style.transform=`translate(${Math.round(n)}px, ${Math.round(l)}px)`},k=()=>{b.style.display="none",b.style.transform="translate(-9999px, -9999px)"},N=["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],H=[];{let T=new Date(s.getFullYear(),s.getMonth(),1),R=new Date(d.getFullYear(),d.getMonth(),1);for(;T<=R;){let M=new Date(T),B=new Date(T.getFullYear(),T.getMonth()+1,0),A=Md?new Date(d):B,z=Math.floor((A-c)/864e5),S=Math.floor((P-c)/864e5),O=Math.max(0,Math.min(m-1,Math.floor(z/7))),W=Math.max(O+1,Math.min(m,Math.floor(S/7)+1));H.push({label:N[T.getMonth()],start:O,end:W}),T.setMonth(T.getMonth()+1)}}if(H.length){let D=[],F=0;H.forEach(e=>{let t=Math.max(F,e.start),a=Math.max(t+1,e.end);t=Math.min(t,m-1),a=Math.min(a,m),!(t>=m)&&(D.push({label:e.label,start:t,end:a}),F=a)}),H=D}p.forEach((e,t)=>{let a=document.createElement("div");a.className="xhhaocom-chartboard-heatmap__column";for(let r=0;r<7;r++){let n=new Date(e.getTime()+864e5*r),l=document.createElement("div");l.className="xhhaocom-chartboard-heatmap__day";let c=i(n),h=n>=s&&n<=d;if(h){let m=o.get(c)||0,p=E(m);l.dataset.level=p.toString(),l.dataset.value=m.toString(),l.dataset.date=c;let $=e=>L(e,c,m);l.addEventListener("mouseenter",$),l.addEventListener("mousemove",$),l.addEventListener("mouseleave",k)}else l.classList.add("is-outside");a.appendChild(l)}v.appendChild(a)}),u.addEventListener("mouseleave",k);let Y=0;if(H.forEach(e=>{if(e.start>Y){let t=document.createElement("div");t.className="xhhaocom-chartboard-heatmap__month is-placeholder",t.style.gridColumn=`span ${e.start-Y}`,_.appendChild(t)}let a=Math.max(1,e.end-e.start),r=document.createElement("div");r.className="xhhaocom-chartboard-heatmap__month",r.textContent=e.label,r.style.gridColumn=`span ${a}`,_.appendChild(r),Y=e.end}),Y{let t=document.createElement("span");t.className="xhhaocom-chartboard-heatmap__legend-dot",t.dataset.level=e.toString(),q.appendChild(t)});let K=document.createElement("span");return K.textContent="较多",q.appendChild(K),Z.appendChild(q),g.appendChild(Z),u.appendChild(g),r.appendChild(u),y.observe(u),window.addEventListener("resize",w),window.addEventListener("orientationchange",w),x(),[{type:"heatmap"}]}(d,s.articles)),m.includes("comments")&&p.push(...function e(t,a){let r=n(t,"评论活跃用户","按评论作者统计评论数量");if(!a?.length)return r.innerHTML='
暂无评论数据
',[];let o=a.map(e=>({name:e?.username||e?.name||e?.email||"匿名",count:Number(e?.count??0)})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count).slice(0,10);if(!o.length)return r.innerHTML='
暂无评论数据
',[];let i=l(r,`活跃评论用户 Top ${o.length}`),d=i.closest(".xhhaocom-chartboard-card");d&&d.classList.add("xhhaocom-chartboard-card--animated");let s=c(o.length),h=new Chart(i,{type:"bar",data:{labels:o.map(e=>e.name),datasets:[{label:"评论数量",data:o.map(e=>e.count),backgroundColor:s.map(e=>e.background),borderColor:s.map(e=>e.border),borderWidth:1.5,borderRadius:{topLeft:14,topRight:14,bottomLeft:14,bottomRight:14},barPercentage:.65,categoryPercentage:.6}]},options:{maintainAspectRatio:!1,animation:{duration:1400,easing:"easeOutQuart"},interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,grid:{color:"rgba(148, 163, 184, 0.18)",drawBorder:!1,borderDash:[4,4]},ticks:{precision:0,font:{size:12}}},x:{grid:{drawBorder:!1},ticks:{font:{size:12},autoSkip:!1}}},plugins:{legend:{display:!1},tooltip:{backgroundColor:"rgba(15, 23, 42, 0.88)",cornerRadius:8,padding:12,displayColors:!1,callbacks:{title:e=>e[0]?.label||"",label:e=>`评论 ${e.raw} 次`}}},onHover(e,t){i.style.cursor=t.length?"pointer":"default"}}});return[h]}(d,s.comments)),m.includes("topArticles")&&p.push(...function e(t,a){let o=n(t,"热门文章 Top10","按访问量排序的热门文章");if(!a?.length)return o.innerHTML='
暂无热门文章数据
',[];let i=a.map(e=>({name:e.name||"未命名文章",views:Number(e.views??e.count??0)})).filter(e=>e.views>0).sort((e,t)=>t.views-e.views).slice(0,10);if(!i.length)return o.innerHTML='
暂无热门文章数据
',[];let d=l(o,`热门文章 Top ${i.length}`),s=d.closest(".xhhaocom-chartboard-card");s&&s.classList.add("xhhaocom-chartboard-card--animated");let h=c(i.length),m=window.innerWidth<=768,p=new Chart(d,{type:"bar",data:{labels:i.map(e=>e.name.length>16?e.name.slice(0,16)+"…":e.name),datasets:[{label:"访问量",data:i.map(e=>e.views),backgroundColor:h.map(e=>e.background),borderColor:h.map(e=>e.border),borderWidth:1.5,borderRadius:{topLeft:14,topRight:14,bottomLeft:14,bottomRight:14},barPercentage:.65,categoryPercentage:.6}]},options:{maintainAspectRatio:!1,animation:{duration:1500,easing:"easeOutQuart"},interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,grid:{color:"rgba(148, 163, 184, 0.18)",drawBorder:!1,borderDash:[4,4]},ticks:{callback:e=>r(e),font:{size:12}}},x:{grid:{drawBorder:!1},ticks:{display:!m,font:{size:12},autoSkip:!1}}},plugins:{legend:{display:!1},tooltip:{backgroundColor:"rgba(15, 23, 42, 0.88)",cornerRadius:8,padding:12,displayColors:!1,callbacks:{title:e=>e[0]?.label||"",label:e=>`访问量 ${r(e.raw)}`}}},onHover(e,t){d.style.cursor=t.length?"pointer":"default"}}});return[p]}(d,s.top10Articles));let g=p.filter(e=>e&&"function"==typeof e.destroy);g.length>0&&a.set(d,g),0===d.children.length&&(d.innerHTML='
暂无可展示的数据
')})(d,e||{})).catch(e=>{console.error("[ChartBoard] fetch error:",e),d.innerHTML=`
获取图表数据失败:${e.message}
`})}})})}if(e=h,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e(),"undefined"!=typeof MutationObserver){let m=new MutationObserver(()=>{h()});m.observe(document.body,{childList:!0,subtree:!0})}}(); + `,r.appendChild(o);let n=document.createElement("div");return n.className="xhhaocom-chartboard-section__body",r.appendChild(n),e.appendChild(r),n}function l(e,t){let a=document.createElement("div");a.className="xhhaocom-chartboard-card";let r=document.createElement("div");r.className="xhhaocom-chartboard-card__canvas";let o=document.createElement("canvas");if(r.appendChild(o),a.appendChild(r),t){let n=document.createElement("footer");n.className="xhhaocom-chartboard-card__footer",n.textContent=t,a.appendChild(n)}return e.appendChild(a),o}function i(e){const t=e.getFullYear(),a=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${a}-${r}`}let d=["rgba(255, 99, 132, 0.22)","rgba(255, 159, 64, 0.22)","rgba(255, 205, 86, 0.22)","rgba(75, 192, 192, 0.22)","rgba(54, 162, 235, 0.22)","rgba(153, 102, 255, 0.22)","rgba(201, 203, 207, 0.22)","rgba(236, 72, 153, 0.22)","rgba(16, 185, 129, 0.22)","rgba(14, 165, 233, 0.22)"],s=["rgb(255, 99, 132)","rgb(255, 159, 64)","rgb(255, 205, 86)","rgb(75, 192, 192)","rgb(54, 162, 235)","rgb(153, 102, 255)","rgb(201, 203, 207)","rgb(236, 72, 153)","rgb(16, 185, 129)","rgb(14, 165, 233)"];function c(e){return Array.from({length:e},(e,t)=>({background:d[t%d.length],border:s[t%s.length]}))}function h(){!function e(t,a=50){if("undefined"!=typeof Chart){t();return}if(a<=0){console.error("[ChartBoard] Chart.js 加载超时");return}setTimeout(()=>e(t,a-1),100)}(()=>{document.querySelectorAll(".xhhaocom-chartboard").forEach(e=>{if(!e.hasAttribute("data-initialized")){var d;e.setAttribute("data-initialized","true"),(d=e).classList.add("xhhaocom-chartboard"),d.innerHTML='
数据加载中…
',fetch("/apis/api.data.statistics.xhhao.com/v1alpha1/chart/data").then(e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);return e.json()}).then(e=>(function e(d,s){(function e(t){let r=a.get(t);r&&(r.forEach(e=>{e?.destroy&&e.destroy()}),a.delete(t))})(d),d.innerHTML="";let h=d.getAttribute("data-types"),m=h?h.split(",").map(e=>e.trim()).filter(Boolean):["tags","categories","articles","comments","topArticles"],p=[];if(m.includes("tags")||m.includes("categories")){let $=m.includes("tags")?s.tags:null,u=m.includes("categories")?s.categories:null;p.push(...function e(a,r,i){let d=n(a,"标签与分类统计","展示全部标签和分类的文章数量占比"),s=[],c=(r||[]).map(e=>({name:e?.name??o(e,"spec.displayName")??o(e,"metadata.name")??"未命名标签",count:Number(e?.count??e?.total??o(e,"status.visiblePostCount",0))})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count),h=(i||[]).map(e=>({name:e?.name??o(e,"spec.displayName")??o(e,"metadata.name")??"未命名分类",count:Number(e?.total??e?.count??o(e,"status.visiblePostCount",0))})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count);if(!c.length&&!h.length)return d.innerHTML='
暂无标签或分类数据
',[];let m=[];if(c.length){let p=(r?.length||0)-c.length,$=p>0?`已使用标签 ${c.length} 个(另有 ${p} 个未使用)`:`已使用标签 ${c.length} 个`,u=l(d,$),g=u.closest(".xhhaocom-chartboard-card");g&&g.classList.add("xhhaocom-chartboard-card--animated");let b=new Chart(u,{type:"doughnut",data:{labels:c.map(e=>e.name),datasets:[{data:c.map(e=>e.count),backgroundColor:c.map((e,a)=>t[a%t.length]),borderWidth:2,borderColor:"#ffffff",cutout:"55%",hoverOffset:8,hoverBorderWidth:3}]},options:{maintainAspectRatio:!1,animation:{animateRotate:!0,animateScale:!0,duration:1200,easing:"easeOutQuart"},interaction:{intersect:!1,mode:"point"},plugins:{legend:{display:!1},tooltip:{enabled:!0,backgroundColor:"rgba(0, 0, 0, 0.8)",padding:12,cornerRadius:8,displayColors:!0,callbacks:{label:e=>`${e.label}: ${e.raw} 篇文章`}}},onHover(e,t){u.style.cursor=t.length>0?"pointer":"default"}}});b.canvas.style.height="220px",b.canvas.style.maxHeight="220px",b.resize(),m.push(b),g&&s.push(g)}if(h.length){let _=(i?.length||0)-h.length,f=_>0?`已使用分类 ${h.length} 个(另有 ${_} 个未使用)`:`已使用分类 ${h.length} 个`,v=l(d,f),x=v.closest(".xhhaocom-chartboard-card");x&&x.classList.add("xhhaocom-chartboard-card--animated");let y=[...h].sort((e,t)=>e.count-t.count),C=new Chart(v,{type:"line",data:{labels:y.map(e=>e.name),datasets:[{label:"文章数量",data:y.map(e=>e.count),borderColor:t[0],backgroundColor:t[0]+"20",borderWidth:3,fill:!0,tension:.4,pointRadius:5,pointHoverRadius:8,pointBackgroundColor:t[0],pointBorderColor:"#ffffff",pointBorderWidth:2,pointHoverBackgroundColor:t[0],pointHoverBorderColor:"#ffffff",pointHoverBorderWidth:3}]},options:{maintainAspectRatio:!1,animation:{duration:1500,easing:"easeOutQuart"},interaction:{intersect:!1,mode:"index"},scales:{x:{beginAtZero:!1,grid:{display:!1},ticks:{font:{size:11},maxRotation:45,minRotation:0}},y:{beginAtZero:!0,grid:{color:"rgba(0, 0, 0, 0.05)",drawBorder:!1},ticks:{font:{size:11},callback:e=>Number(e)}}},plugins:{legend:{display:!1},tooltip:{enabled:!0,backgroundColor:"rgba(0, 0, 0, 0.8)",padding:12,cornerRadius:8,displayColors:!0,callbacks:{label:e=>`${e.label}: ${e.raw} 篇文章`}}},onHover(e,t){v.style.cursor=t.length>0?"pointer":"default"}}});m.push(C),x&&s.push(x)}return 1===s.length&&(s[0].style.gridColumn="span 2"),m}(d,$,u))}m.includes("articles")&&p.push(...function e(t,a){let r=n(t,"文章发布趋势","按日期统计文章发布数量"),o=new Map;if((a||[]).forEach(e=>{let t=e.date||e.name;if(!t)return;let a=new Date(t);if(Number.isNaN(a.valueOf()))return;a.setHours(0,0,0,0);let r=i(a),n=Number(e.total??e.count??0);o.set(r,(o.get(r)||0)+n)}),!o.size)return r.innerHTML='
暂无文章数据
',[];let l=new Date;l.setHours(0,0,0,0);let d=new Date(l),s=new Date(d.getTime()-314496e5),c=new Date(s),h=(c.getDay()+6)%7;c.setDate(c.getDate()-h);let m=Math.ceil((Math.floor((d-c)/864e5)+1)/7),p=Array.from({length:m},(e,t)=>new Date(c.getTime()+7*t*864e5)),$=Math.max(...o.values(),0),u=document.createElement("div");u.className="xhhaocom-chartboard-card xhhaocom-chartboard-card--heatmap",u.style.gridColumn="1 / -1";let g=document.createElement("div");g.className="xhhaocom-chartboard-heatmap";let b=document.createElement("div");b.className="xhhaocom-chartboard-heatmap__tooltip",b.style.display="none",u.appendChild(b);let _=document.createElement("div");_.className="xhhaocom-chartboard-heatmap__months";let f=document.createElement("div");f.className="xhhaocom-chartboard-heatmap__weekdays",["一","二","三","四","五","六","日"].forEach(e=>{let t=document.createElement("div");t.className="xhhaocom-chartboard-heatmap__weekday",t.textContent=e,f.appendChild(t)});let v=document.createElement("div");v.className="xhhaocom-chartboard-heatmap__grid";let x=()=>{let e=u.getBoundingClientRect();if(0===e.width){requestAnimationFrame(x);return}let t=window.innerWidth<=768;if(t){let a="12px";_.style.gridTemplateColumns=`repeat(${m}, ${a})`,v.style.gridTemplateColumns=`repeat(${m}, ${a})`,document.documentElement.style.setProperty("--chartboard-heatmap-cell",a),document.documentElement.style.setProperty("--chartboard-heatmap-cell-width",a);return}let r=e.width-40-30-10,o=`${Math.max(8,Math.floor((r-(m-1)*4)/m))}px`;_.style.gridTemplateColumns=`repeat(${m}, ${o})`,v.style.gridTemplateColumns=`repeat(${m}, ${o})`,document.documentElement.style.setProperty("--chartboard-heatmap-cell",o),document.documentElement.style.setProperty("--chartboard-heatmap-cell-width",o)},y=new ResizeObserver(()=>{x()}),C,w=()=>{clearTimeout(C),C=setTimeout(()=>{x()},150)},E=e=>{if(!e||!$)return 0;if($<=1)return e>0?1:0;let t=Math.max(1,Math.ceil(.25*$)),a=Math.max(t+1,Math.ceil(.5*$));return e>=Math.max(a+1,Math.ceil(.75*$))?4:e>=a?3:e>=t?2:1},L=(e,t,a)=>{b.innerHTML=`${t}${a?`发布 ${a} 篇文章`:"无文章发布"}`,b.style.display="flex";let r=u.getBoundingClientRect(),o=b.getBoundingClientRect(),n=e.clientX-r.left+12,l=e.clientY-r.top-o.height-10;n+o.width>r.width&&(n=r.width-o.width-8),l<0&&(l=e.clientY-r.top+12),b.style.transform=`translate(${Math.round(n)}px, ${Math.round(l)}px)`},k=()=>{b.style.display="none",b.style.transform="translate(-9999px, -9999px)"},N=["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],H=[];{let T=new Date(s.getFullYear(),s.getMonth(),1),R=new Date(d.getFullYear(),d.getMonth(),1);for(;T<=R;){let M=new Date(T),B=new Date(T.getFullYear(),T.getMonth()+1,0),A=Md?new Date(d):B,z=Math.floor((A-c)/864e5),S=Math.floor((P-c)/864e5),O=Math.max(0,Math.min(m-1,Math.floor(z/7))),W=Math.max(O+1,Math.min(m,Math.floor(S/7)+1));H.push({label:N[T.getMonth()],start:O,end:W}),T.setMonth(T.getMonth()+1)}}if(H.length){let D=[],F=0;H.forEach(e=>{let t=Math.max(F,e.start),a=Math.max(t+1,e.end);t=Math.min(t,m-1),a=Math.min(a,m),!(t>=m)&&(D.push({label:e.label,start:t,end:a}),F=a)}),H=D}p.forEach((e,t)=>{let a=document.createElement("div");a.className="xhhaocom-chartboard-heatmap__column";for(let r=0;r<7;r++){let n=new Date(e.getTime()+864e5*r),l=document.createElement("div");l.className="xhhaocom-chartboard-heatmap__day";let c=i(n),h=n>=s&&n<=d;if(h){let m=o.get(c)||0,p=E(m);l.dataset.level=p.toString(),l.dataset.value=m.toString(),l.dataset.date=c;let $=e=>L(e,c,m);l.addEventListener("mouseenter",$),l.addEventListener("mousemove",$),l.addEventListener("mouseleave",k)}else l.classList.add("is-outside");a.appendChild(l)}v.appendChild(a)}),u.addEventListener("mouseleave",k);let Y=0;if(H.forEach(e=>{if(e.start>Y){let t=document.createElement("div");t.className="xhhaocom-chartboard-heatmap__month is-placeholder",t.style.gridColumn=`span ${e.start-Y}`,_.appendChild(t)}let a=Math.max(1,e.end-e.start),r=document.createElement("div");r.className="xhhaocom-chartboard-heatmap__month",r.textContent=e.label,r.style.gridColumn=`span ${a}`,_.appendChild(r),Y=e.end}),Y{let t=document.createElement("span");t.className="xhhaocom-chartboard-heatmap__legend-dot",t.dataset.level=e.toString(),q.appendChild(t)});let K=document.createElement("span");return K.textContent="较多",q.appendChild(K),Z.appendChild(q),g.appendChild(Z),u.appendChild(g),r.appendChild(u),y.observe(u),window.addEventListener("resize",w),window.addEventListener("orientationchange",w),x(),[{type:"heatmap"}]}(d,s.articles)),m.includes("comments")&&p.push(...function e(t,a){let r=n(t,"评论活跃用户","按评论作者统计评论数量");if(!a?.length)return r.innerHTML='
暂无评论数据
',[];let o=a.map(e=>({name:e?.username||e?.name||e?.email||"匿名",count:Number(e?.count??0)})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count).slice(0,10);if(!o.length)return r.innerHTML='
暂无评论数据
',[];let i=l(r,`活跃评论用户 Top ${o.length}`),d=i.closest(".xhhaocom-chartboard-card");d&&d.classList.add("xhhaocom-chartboard-card--animated");let s=c(o.length),h=new Chart(i,{type:"bar",data:{labels:o.map(e=>e.name),datasets:[{label:"评论数量",data:o.map(e=>e.count),backgroundColor:s.map(e=>e.background),borderColor:s.map(e=>e.border),borderWidth:1.5,borderRadius:{topLeft:14,topRight:14,bottomLeft:14,bottomRight:14},barPercentage:.65,categoryPercentage:.6}]},options:{maintainAspectRatio:!1,animation:{duration:1400,easing:"easeOutQuart"},interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,grid:{color:"rgba(148, 163, 184, 0.18)",drawBorder:!1,borderDash:[4,4]},ticks:{precision:0,font:{size:12}}},x:{grid:{drawBorder:!1},ticks:{font:{size:12},autoSkip:!1}}},plugins:{legend:{display:!1},tooltip:{backgroundColor:"rgba(15, 23, 42, 0.88)",cornerRadius:8,padding:12,displayColors:!1,callbacks:{title:e=>e[0]?.label||"",label:e=>`评论 ${e.raw} 次`}}},onHover(e,t){i.style.cursor=t.length?"pointer":"default"}}});return[h]}(d,s.comments)),m.includes("topArticles")&&p.push(...function e(t,a){let o=n(t,"热门文章 Top10","按访问量排序的热门文章");if(!a?.length)return o.innerHTML='
暂无热门文章数据
',[];let i=a.map(e=>({name:e.name||"未命名文章",views:Number(e.views??e.count??0)})).filter(e=>e.views>0).sort((e,t)=>t.views-e.views).slice(0,10);if(!i.length)return o.innerHTML='
暂无热门文章数据
',[];let d=l(o,`热门文章 Top ${i.length}`),s=d.closest(".xhhaocom-chartboard-card");s&&s.classList.add("xhhaocom-chartboard-card--animated");let h=c(i.length),m=window.innerWidth<=768,p=new Chart(d,{type:"bar",data:{labels:i.map(e=>e.name.length>16?e.name.slice(0,16)+"…":e.name),datasets:[{label:"访问量",data:i.map(e=>e.views),backgroundColor:h.map(e=>e.background),borderColor:h.map(e=>e.border),borderWidth:1.5,borderRadius:{topLeft:14,topRight:14,bottomLeft:14,bottomRight:14},barPercentage:.65,categoryPercentage:.6}]},options:{maintainAspectRatio:!1,animation:{duration:1500,easing:"easeOutQuart"},interaction:{mode:"index",intersect:!1},scales:{y:{beginAtZero:!0,grid:{color:"rgba(148, 163, 184, 0.18)",drawBorder:!1,borderDash:[4,4]},ticks:{callback:e=>r(e),font:{size:12}}},x:{grid:{drawBorder:!1},ticks:{display:!m,font:{size:12},autoSkip:!1}}},plugins:{legend:{display:!1},tooltip:{backgroundColor:"rgba(15, 23, 42, 0.88)",cornerRadius:8,padding:12,displayColors:!1,callbacks:{title:e=>e[0]?.label||"",label:e=>`访问量 ${r(e.raw)}`}}},onHover(e,t){d.style.cursor=t.length?"pointer":"default"}}});return[p]}(d,s.top10Articles));let g=p.filter(e=>e&&"function"==typeof e.destroy);g.length>0&&a.set(d,g),0===d.children.length&&(d.innerHTML='
暂无可展示的数据
')})(d,e||{})).catch(e=>{console.error("[ChartBoard] fetch error:",e),d.innerHTML=`
获取图表数据失败:${e.message}
`})}})})}if(e=h,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",e):e(),"undefined"!=typeof MutationObserver){let m=new MutationObserver(()=>{h()});m.observe(document.body,{childList:!0,subtree:!0})}}();