有趣的便籤網站-使用Sdcb.WordCloud生成詞雲圖
前言
最近也是忙着面試、背題,終於閒下來,也是來更新下網站順便寫一篇文章~
上週在網上看到一個靜態的便籤網站,我也是拿來用併發布了一篇文章,找到一個有趣的便籤牆網站 - ZY知識庫,後續也是製作了一個可以提交內容的便籤網站,也發佈了一篇文章,可以提交內容的便籤牆來了 - ZY知識庫。
這兩篇文章都比較火,特別是可以提交內容的便籤網站,截止今日,已經有4000千多條評論,去除重複的也有3000多條,保守估計,網站搭建至今,訪問人數和使用人數應該總和有100+。
大部分人提交的內容都是表白、鼓勵、吐槽之類的內容,也有一些人發佈了惡意評論,當然已經被我刪除掉了。
需要注意的是,網站默認只會展示最新的150條信息,如果你發現你之前的信息找不到了,刷新網頁好多次還是沒看到,那麼可能排序到最新的第150條數據後面去了。
下面是網站發佈以來更新的內容
- 2025/11/04 限制內容長度不能超過30字
- 2025/11/05 限制
xss攻擊 - 2025/11/06 高估互聯網的素質了,還是加上了關鍵詞過濾
- 2025/11/07 被惡意刷屏,無奈添加接口限流
那麼也是為了看看大家都發布的什麼內容,也是心血來潮想着用詞雲圖實現一下,通過數據清洗、篩選來看看出現頻率最高的詞語有哪些,並用 詞雲圖 的形式展示出來,話不多説開始操作。
便籤網站直達地址:https://pljzy.top/noteweb
前端設計
前端頁面就很簡單的設計了一個詞雲圖跳轉按鈕,通過點擊這個按鈕可以查看詞雲圖。
後端設計
後端採用的是.Net框架,那麼生成詞雲圖必然也是.Net框架下的包,我這裏使用的是 Sdcb.WordCloud 包。
dotnet add package Sdcb.WordCloud
這個包Star數比較少,可能因為詞雲圖本身不是很知名吧,之前繪製詞雲圖還是學校時期用 python 繪製過。不得不説 python 的包是又多又方便~
sdcb/Sdcb.WordCloud: Generate WordCloud image from .NET/.NET Core
踩坑指南
我在本地 windows 環境下生成詞雲圖是沒問題的,當我部署到 Liunx 系統下時,會提示缺少依賴,後面發現需要手動導入 SkiaSharp.NativeAssets.Linux.NoDependencies 包。
dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies
關鍵代碼
public async Task GenerateWordCloud()
{
try
{
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<MyDbContext>();
var allNotes = await db.Notes.Select(n => n.Content).ToListAsync();
var text = string.Join(" ", allNotes);
// 處理文本並生成詞頻統計
var words = ProcessText(text)
.GroupBy(word => word)
.ToDictionary(g => g.Key, g => g.Count())
.OrderByDescending(kv => kv.Value) // 按詞頻降序排序
.Take(150) // 取前150個高頻詞
.ToDictionary(kv => kv.Key, kv => kv.Value)
.Select(kv => new WordScore(kv.Key, kv.Value)); // 轉換為WordScore對象集合
// 創建詞雲實例,設置畫布大小為1000x1000
WordCloud wc = WordCloud.Create(new WordCloudOptions(1000, 1000, words));
byte[] pngBytes = wc.ToSKBitmap().Encode(SKEncodedImageFormat.Png, 100).AsSpan().ToArray();
string filePath = "wwwroot/wordcloud.png";
// 將PNG圖片保存到文件
await File.WriteAllBytesAsync(filePath, pngBytes);
_logger.LogInformation($"詞雲圖已更新: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
}
catch (Exception ex)
{
_logger.LogError(ex, "生成詞雲圖時發生錯誤");
}
}
這裏由於各方面因素影響,只獲取了詞頻出現最多的前 150 條數據。
定時任務
由於詞雲圖生成比較慢,我試了一下150條數據,生成大概要 20~30s ,如果做成接口的話響應很慢,用户體驗也不好。
那麼我也是採用後台定時任務去執行,我使用的是 Hangfire ,每隔4小時重新繪製一次圖像。
dotnet add package Hangfire
dotnet add package Hangfire.MemoryStorage
關鍵代碼
builder.Services.AddHangfire(config =>
config.UseMemoryStorage());
builder.Services.AddHangfireServer();
// 每天0:00, 4:00, 8:00, 12:00, 16:00, 20:00執行
RecurringJob.AddOrUpdate<WordCloudService>(
"generate-wordcloud",
service => service.GenerateWordCloud(),
"0 0,4,8,12,16,20 * * *");
多提一嘴
Hangfire 可以選擇是否開啓儀表板,儀表板截圖如下,用來查看任務執行情況還是挺方便的。
詞雲圖效果
好像大家都有喜歡的人呀,詞雲圖每隔4小時更新一次,如果發現自己發的文字沒有在裏面可能是出現頻率不高,不過不建議大家刷留言~
結尾
如果對項目源代碼感興趣的可以訪問 Github 並點上 Star ,ZyPLJ/NoteWeb: 便籤牆帶後端版本,可以隨心所欲(注意文明用語)的發送便籤~。
這個項目也就到這裏結束了,後續不會更新內容,網站會一直存在,除非服務器到期和其他不可避免因素導致網站關閉。
總的來説,這是一個很有趣的項目,希望能一直存在下去~
參考鏈接
- 一次小而美的重構:使用 C# 在 Avalonia 中生成真正好看的詞雲