summaryrefslogtreecommitdiff
path: root/layouts
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-05-21 21:05:29 +0800
committerEltrac <hi@guhub.cn>2025-05-21 21:05:29 +0800
commit7674fa264017b4ddfb419e6bfaa3d23938a1fe3f (patch)
tree12526d77f07f6a4f4365a49a84c071b05ffcc699 /layouts
parent6262a22c4f150af5475df6901d571f7e80b96fe9 (diff)
feat: replace heatmap with wordcount bar chart
Diffstat (limited to 'layouts')
-rw-r--r--layouts/_default/section.html2
-rw-r--r--layouts/partials/components/heatmap.html88
-rw-r--r--layouts/partials/components/wordCountChart.html93
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>