diff options
| author | Eltrac <hi@guhub.cn> | 2025-05-21 21:05:29 +0800 |
|---|---|---|
| committer | Eltrac <hi@guhub.cn> | 2025-05-21 21:05:29 +0800 |
| commit | 7674fa264017b4ddfb419e6bfaa3d23938a1fe3f (patch) | |
| tree | 12526d77f07f6a4f4365a49a84c071b05ffcc699 | |
| parent | 6262a22c4f150af5475df6901d571f7e80b96fe9 (diff) | |
feat: replace heatmap with wordcount bar chart
| -rw-r--r-- | layouts/_default/section.html | 2 | ||||
| -rw-r--r-- | layouts/partials/components/heatmap.html | 88 | ||||
| -rw-r--r-- | layouts/partials/components/wordCountChart.html | 93 |
3 files changed, 94 insertions, 89 deletions
diff --git a/layouts/_default/section.html b/layouts/_default/section.html index 1849c814..d1ad5401 100644 --- a/layouts/_default/section.html +++ b/layouts/_default/section.html @@ -2,7 +2,7 @@ <article class="posts"> {{ partial "header.html" . }} <div id="posts-archive" class="posts-list"> - {{ partial "components/heatmap.html" . }} + {{ partial "components/wordCountChart.html" . }} <!-- Post Archive List --> {{ $first := true }} <!-- 在循环外定义一次 $first 变量 --> {{ range (where site.RegularPages "Type" "eq" "posts").GroupByDate "2006" -}} diff --git a/layouts/partials/components/heatmap.html b/layouts/partials/components/heatmap.html deleted file mode 100644 index f2058258..00000000 --- a/layouts/partials/components/heatmap.html +++ /dev/null @@ -1,88 +0,0 @@ -<!-- Post Word-count Heatmap --> -<div id="cal-heatmap-container"> - <div id="cal-heatmap"></div> -</div> - -<style> - .ch-container{display:block}.ch-container,.ch-domain,.ch-domain-container,.ch-domain-container-animation-wrapper{overflow:visible}.ch-domain-container.in-transition .ch-domain-container-animation-wrapper{overflow:hidden}.ch-domain-bg{fill:transparent}.ch-domain-text{fill:currentColor;font-size:10px}.ch-subdomain{overflow:visible}.ch-subdomain-bg{fill:#ededed}.ch-subdomain-bg.highlight{stroke:#444;stroke-width:1px}.ch-subdomain-bg:hover{stroke:#000;stroke-width:1px}.ch-subdomain-text{font-size:8px;pointer-events:none}[data-theme=dark] .ch-subdomain-bg{fill:#2d333b}[data-theme=dark] .ch-subdomain-bg.highlight{stroke:#768390}[data-theme=dark] .ch-subdomain-bg:hover{stroke:#636e7b}#ch-plugin-legend>svg{background:transparent;color:currentColor}#ch-tooltip{background:#222;border-radius:2px;box-shadow:2px 2px 2px rgba(0,0,0,.2);box-sizing:border-box;color:#bbb;display:none;font-size:12px;line-height:1.4;padding:5px 10px;text-align:center}#ch-tooltip[data-show]{display:block}#ch-tooltip-arrow,#ch-tooltip-arrow:before{background:inherit;height:8px;position:absolute;width:8px}#ch-tooltip-arrow{visibility:hidden}#ch-tooltip-arrow:before{content:"";transform:rotate(45deg);visibility:visible}#ch-tooltip[data-popper-placement^=top]>#ch-tooltip-arrow{bottom:-4px;margin-left:-4px}#ch-tooltip[data-popper-placement^=bottom]>#ch-tooltip-arrow{margin-left:-4px;top:-4px}#ch-tooltip[data-popper-placement^=left]>#ch-tooltip-arrow{right:-4px}#ch-tooltip[data-popper-placement^=right]>#ch-tooltip-arrow{left:-4px}#ch-tooltip[data-theme=dark]{background:#636e7b;color:#cdd9e5} #cal-heatmap-container { - display: flex; - width: 100%; - overflow: hidden; - justify-content: flex-end; - margin: 1rem 0; - min-height: 110px; /* Give it some height before loading */ - } -</style> - -<script> -// Function to load the heatmap -function loadHeatmap() { - // Load the required libraries dynamically - const d3Script = document.createElement('script'); - d3Script.src = 'https://d3js.org/d3.v7.min.js'; - - const calScript = document.createElement('script'); - calScript.src = 'https://unpkg.com/cal-heatmap/dist/cal-heatmap.min.js'; - - // Load cal-heatmap after d3 is loaded - d3Script.onload = function() { - document.head.appendChild(calScript); - - calScript.onload = function() { - const CalHeatmap = window.CalHeatmap; - const cal = new CalHeatmap(); - - // Calculate the date 6 months ago - const startDate = new Date(); - startDate.setMonth(startDate.getMonth() - 11); - - // Render the heatmap - cal.paint({ - domain: { type: 'month' }, - subDomain: { type: 'day' }, - scale: { - color: { - range: ['#eee', 'black'], - type: 'linear', - domain: [0, 6000], - }, - }, - date: { - timezone: 'Asia/Shanghai', - start: startDate, - }, - data: { - source: '/cal-heatmap.json', - x: d => new Date(d.date), - y: d => d.value, - defaultValue: 0, - }, - }); - }; - }; - - document.head.appendChild(d3Script); -} - -// Check if IntersectionObserver is supported -if ('IntersectionObserver' in window) { - // Create an observer - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - // If the element is in the viewport - if (entry.isIntersecting) { - loadHeatmap(); - observer.unobserve(entry.target); // Stop observing after loading - } - }); - }, { - rootMargin: '200px', // Load 200px before entering viewport - }); - - // Observe the container - observer.observe(document.getElementById('cal-heatmap-container')); -} else { - // Fallback for browsers without IntersectionObserver - window.addEventListener('load', loadHeatmap); -} -</script> diff --git a/layouts/partials/components/wordCountChart.html b/layouts/partials/components/wordCountChart.html new file mode 100644 index 00000000..65d0e986 --- /dev/null +++ b/layouts/partials/components/wordCountChart.html @@ -0,0 +1,93 @@ +<style> +.chart-container { + display: flex; + align-items: flex-end; + justify-content: flex-end; + height: 300px; + gap: 0.5rem; + padding: 1rem; + font-size: 0.75rem; + width: 100%; + overflow-x: auto; + box-sizing: border-box; +} + +.chart-item { + display: flex; + flex-direction: column; + justify-content: center; +} + +.bar { + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + width: 1rem; + gap: 0.25rem; + height: 200px; /* fixed height for value + bar */ + position: relative; +} + +.bar-number { + font-size: 0.65rem; + writing-mode: vertical-rl; +} + +.bar-value { + width: 100%; + background-color: #333; + flex-shrink: 0; + transition: height 0.3s; +} + +.bar-label { + height: 3rem; + writing-mode: vertical-rl; + text-align: center; + flex-shrink: 0; +} +</style> + +{{/* Group word counts per month */}} +{{ $monthly := dict }} +{{ range .Site.RegularPages }} + {{ $month := .Date.Format "2006-01" }} + {{ $count := .WordCount }} + {{ with index $monthly $month }} + {{ $monthly = merge $monthly (dict $month (add . $count)) }} + {{ else }} + {{ $monthly = merge $monthly (dict $month $count) }} + {{ end }} +{{ end }} + +{{/* Sort months */}} +{{ $months := slice }} +{{ range $month, $_ := $monthly }} + {{ $months = $months | append $month }} +{{ end }} +{{ $months = sort $months }} + +{{/* Find max value */}} +{{ $max := 0 }} +{{ range $month := $months }} + {{ $val := index $monthly $month }} + {{ if gt $val $max }}{{ $max = $val }}{{ end }} +{{ end }} + +<div class="chart-container"> + {{ range $month := $months }} + {{ $val := index $monthly $month }} + {{ $height := mul (div (float $val) (float $max)) 100 }} + {{ $opacity := add 0.5 (div $height 200) }} + <div class="chart-item"> + <div class="bar"> + <div class="bar-number">{{ $val }}</div> + <div class="bar-value invert-if-dark" + style="height: {{ printf "%.1f" $height }}%; + background-color: rgba(20,20,20,{{ printf "%.2f" $opacity }});"></div> + </div> + <div class="bar-label">{{ $month }}</div> + </div> + {{ end }} +</div> |
