跳到主要内容

5 篇博文 含有标签「网站建设」

查看所有标签

基于echarts的hexo博客热力图

· 阅读需 8 分钟

最近觉得博客的 archive 页太空旷了,和首页雷同,且文章多了之后,archieve 页很长。archive 页平时也不做停留,基本没有意义。因此,我决定改造一下 archive,修复并添加一些东西。首先是历史文章要支持展开和收起,这样,archive 页面就不会过长了。然后,仿照 github contribution, 做一个 博客热力图,记录历史文章提交日历图。

展开/收起控件添加

在年份上添加一个 onclick 事件,来控制对应年份文章的 display 属性。难点是原模板中年份 div 和 post-item div 是平级的,即:

<div class="year"></div>
<div class="post-item"></div>
<div class="post-item"></div>
<div class="post-item"></div>
...
<div class="year"></div>
<div class="post-item"></div>
<div class="post-item"></div>
<div class="post-item"></div>
...

这样兄弟选择器是没法只选中对应的年份的所有文章的。解决方法是给文章的 div 添加对应的年份 class,如'y2023'.并且给 onclick 事件传入年份变量。

post contribution

echarts 是一个开源的图表库,支持创建丰富类型的图表,且配置性高。


echarts 使用手册 https://echarts.apache.org/handbook/zh/get-started/


开始并不顺利,安装就卡住了。按照'hexo echarts'去 google,得到的方案是装一个 npm 包,但是实际上无效,图表没有被解析。后来用了质朴的 cdn 导入方式才成功。安装成功后,跑了一个 demo 也成功了,可是实现我的定制化需求时又犯了难。我的需求是,显示过去一年内,每天的文章创建数。echarts 有很多配置项,不看文档是搞不清楚的。然而,配置项文档都是文字说明,没有对应的效果展示。还好,有 chatgpt。描述好需求,gpt 给出了非常接近的答案,再经过几轮问答补充细节后,我想要的效果就达成了。

接着是数据的问题。我一开始的想法是,先在 ejs 中遍历 site.posts,获得一个键为日期,值为当日发布文章数的对象。然后创建一个数据生成函数,遍历近一年的每一天,从之前的对象中取值。但是,当我实现到一半,发现一个问题:ejs 创建的对象,无法被 script 标签读到。又是 gpt 给出了解决方案:将对象绑定在全局 window 上。

完整代码:

  <div id="main" style="width:100%; height:300px; margin: 0 auto"></div>
<%
const postsCountByDate = {};
site.posts.each((item, index) => {
let postDate = new Date(item.date);
// 获取年、月、日
let formattedDate = postDate.getFullYear() + '-' + (postDate.getMonth() + 1) + '-' + postDate.getDate();
postsCountByDate[formattedDate] = (postsCountByDate[formattedDate] || 0) + 1;
});
%>

<script>
// 将 postsCountByDate 绑定到全局对象 window 上
window.postsCountByDate = <%- JSON.stringify(postsCountByDate) %>;
</script>



<script type="text/javascript">


var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;

function generateRandomData(startDate, endDate) {
let currentDate = new Date(startDate);
const endDateObj = new Date(endDate);
const data = [];


while (currentDate <= endDateObj) {
let formattedCur = currentDate.getFullYear() + '-' + (currentDate.getMonth() + 1) + '-' + currentDate.getDate();
const val = postsCountByDate[formattedCur] || 0
// const val = Math.floor(Math.random() * 100); // 生成 0 到 99 之间的随机数
data.push([currentDate.toLocaleDateString(), val]);

currentDate.setDate(currentDate.getDate() + 1);
}

return data;
}

const startDate = new Date(); //
startDate.setFullYear(startDate.getFullYear() - 1); // 一年前的日期 e.g 2023.1.10
const endDate = new Date(); // 当前日期 e.g 2024.1.10

const simulatedData = generateRandomData(startDate, endDate);

option = {
title: {
top: 30,
left: 'center',
text: 'Post Contribution'
},
tooltip: {},
visualMap: {
show: true,
min: 0,
max: 3, // 你的数据中的最大值
calculable: true,
orient: 'horizontal',
left: 'right',
bottom: 10,
inRange: {
color: ['#FFFFFF', '#FF0000'] // 白色到其他颜色的渐变色,可以根据需要调整颜色值
},
pieces: [
{ value: 0, color: '#FFFFFF' }, // 将值为0的数据映射到白色
{ min: 1 } // 其他数据按照设定的颜色渐变
]
},

calendar: {
top: 120,
left: 30,
right: 30,
cellSize: ['auto', 13],
range: [startDate, endDate],
itemStyle: {
borderWidth: 0.5
},
yearLabel: { show: false }
},
series: {
type: 'heatmap',
coordinateSystem: 'calendar',
data: simulatedData
}
};

option && myChart.setOption(option);


</script>

附上改造后的 archive 页:

17051159772241705115976390.png

更新

经过一段时间的使用,发现了以下问题:

  • 右下角的范围筛选控件很丑,但是删不掉;
  • 手机上显示效果很差。

在参考别人博客的类似效果后,我想实现:

  • 鼠标悬停在单元格上显示的是标题;
  • 去掉筛选控件

这一次,又是 chatgpt 的答案就几近完美。看来它对 echarts 非常熟悉。

// 获取博客文章数据
const postsCountByDate = {};
site.posts.each((item, index) => {
let postDate = new Date(item.date);
// 获取年、月、日
let formattedDate =
postDate.getFullYear() +
"-" +
(postDate.getMonth() + 1) +
"-" +
postDate.getDate();
let arrofTitle = postsCountByDate[formattedDate] || [];
arrofTitle.push(item.title);
postsCountByDate[formattedDate] = arrofTitle;
});

// heatmap options数据准备
var chartDom = document.getElementById("heatmap");
var myChart = echarts.init(chartDom);
var option;

var dates = Object.keys(postsCountByDate);
var colors = ["#FFFFFF", "#FFCCCC", "#FF9999", "#FF6666", "#FF3333", "#FF0000"];

// 提取数据中的标题
var titles = [];
Object.keys(postsCountByDate).forEach(function (key) {
titles = titles.concat(postsCountByDate[key]);
});

// 计算最大值
var maxCount = Math.max.apply(
null,
Object.values(postsCountByDate).map((arr) => arr.length)
);

// 计算开头结尾时间,作为calendar的range
const startDate = new Date(); //
startDate.setFullYear(startDate.getFullYear() - 1); // 一年前的日期 e.g 2023.1.10
// const startDate = moment().subtract(6, 'months').toDate(); // 6个月前的日期 e.g 2023.7.10
const endDate = new Date(); // 当前日期 e.g 2024.1.10
let startDate_ = new Date(startDate);
let endDate_ = new Date(endDate);
formatted_startDate =
startDate_.getFullYear() +
"-" +
(startDate_.getMonth() + 1) +
"-" +
startDate_.getDate();
formatted_endDate =
endDate_.getFullYear() +
"-" +
(endDate_.getMonth() + 1) +
"-" +
endDate_.getDate();

option = {
title: {
top: 0,
left: "center",
// text: 'Post Contribution'
},
tooltip: {
position: "top",
formatter: function (params) {
var date = params.data[0];
var titles = postsCountByDate[date] || [];
return titles.join("<br>");
},
},

calendar: {
top: "middle",
left: "center",
cellSize: ["auto", 13],
range: [formatted_startDate, formatted_endDate],
itemStyle: {
borderWidth: 0.5,
},
yearLabel: { show: false },
monthLabel: {
nameMap: [
"Jan",
"",
"Mar",
"",
"May",
"",
"Jul",
"",
"Sep",
"",
"Nov",
"",
],
},
dayLabel: { show: true, firstDay: 1, nameMap: "en" },
},
series: {
type: "heatmap",
coordinateSystem: "calendar",
data: dates.map(function (date) {
return [date, postsCountByDate[date].length];
}),
label: {
show: false,
formatter: function (params) {
return params.value[1];
},
},
itemStyle: {
normal: {
color: function (params) {
var count = params.value[1];
var level = Math.ceil(count / (maxCount / colors.length));
level = Math.min(level, colors.length - 1);
return colors[level];
},
},
},
},
};

option && myChart.setOption(option);

// 响应式图表
window.addEventListener("resize", function () {
myChart.resize();
});

逐步让Google收录本博客

· 阅读需 3 分钟
Jason Lee
The owner of this blog site

前言

这个博客建立快满一年了,到目前为止积累了 77 篇文章,都是原创。建立之初以为半年之内 Google 会自动收录,没想到现在依旧未收录。之前有手动向 Google 提交过网址,但是好像是所有权验证问题失败了。这一次,我打算纪录下从开始提交到最终收录的全过程,顺便可以学到一点 seo 的知识。本文将持续更新。

第一天

登录 google search console,并验证了网站所有权(DNS 方式)后,有两个资源:一个是根域名 jasonleehere.com,一个是二级域名 blog.jasonleehere.com。然后向 Google 提交 sitemap(之前已经安装好 hexo-sitemap 插件并生成好 xml 文件)。想要查询 Google 收录的网址和数量,可以在“网页索引编制”中查看:

16871396076941687139607410.png

现在就等明天回来,看看网页是否被收录。

第二天

已收录,可通过在 google 搜索栏键入网址来找到:

16872193526401687219352555.png

16872195266361687219526444.png

前五个结果都是我的网站里的内容。但是,如果直接搜索 jasonleehere 或者 blog jasonleehere 是不会显示的,因为有其他来源的网页占据,一直到了第五页才有我。

这样就是成功了,后续就是看看 google search console 里的数据分析,看看有没有人通过 google 点进我的网站。

第三天

效果栏里开始有数据了。

16873078462601687307845321.png

第四天

非常幸运地,第四天就有了网页索引报告。可以看出,第一批收录了 10 个网页,其余大部分网页处在看见了但暂时未收录的状态。

16873931464181687393145504.png

主题更换和迁移到vercel记录

· 阅读需 4 分钟

首先是主题更换。之前用的主题原生很多动画和功能,但是我本身是不喜欢复杂的,所以把背景和功能改的很精简。但是这样反而做的不称心。我的理想样式是:文章居中,两侧没有除了目录外的任何东西。所以,我找到了目前用的这个 orange 主题,这次我用的时间打算长些,短时间不换了。

其次是静态网站服务器从 github-pages 转移到 vercel。主要考虑是,github-pages 要求对应的仓库必须是公开的,这样有心人可以看到每一次过往文章提交修改记录,这让我觉得有点膈应。vercel 是一种流行的无服务平台,代码托管在 github 仓库后,vercel 可以实现自动部署和发布。现在的工作流是,本地修改好文章,直接推到 github 私有仓库,vercel 检测到变化,自动部署。值得一提的是,我顺便更换了 DNS 的 nameserver,由原来 namesilo 默认的,换到全球最大的 CDN 商 cloudflare。中间的过程记录一下。

vercel 创建实例成功后,会分配一个 example.vercel.app的二级域名。为了将买到的域名用上,需要去自定义设置,添加域名,vercel 会给你一个 A 或者 CNAME 记录。如果是一级域名,给 A 记录;如果是二级域名,给 CNAME 记录。这时候要在 cloudflare 添加记录。首先注册 cloudflare,然后,输入自己先前购买的域名,自动导入目前的 DNS 解析记录和 nameserver。这时候,将 DNS 解析规则先删除,并来到 namesilo 的管理页面,改变 nameserver 为 cloudflare 提供的地址。到这里的修改都是实时生效的。回到 cloudflare,刷新,cloudflare 开始接管你的域名,这一过程会花费十几分钟。

然后,将之前 vercel 提供的解析记录,提供给 cloudflare。不同于 github-pages,只有输入一条就能解析了。

其中,名称就是二级域名,内容是 vercel 的地址。成功后,这是你浏览器发出的请求就会被 cloudflare 所解析啦,并且可以勾选他们家提供的 CDN 服务。据说,中国大陆的 cloudflare CDN 反而是减速器,所以我没选。设置好后,实测不用翻墙就可以访问网站。

以后就专心写文章啦!

namesilo购买域名和github pages配置

· 阅读需 2 分钟

自从建立网站以来,每次访问,都困扰于输入长长的域名前缀 www,此外,goldspot 似乎也太长且拗口。坑爹的是,goldspot 绑定的 namesilo 账号不知为什么登不上去了。索性重开新号,购买新域名。

购买域名的过程不再赘述,这次花了人民币 16.90 元。为了将买到的 rula.life 和 li199-code.github.io 绑定,需要如下操作:

首先,在 github 的仓库设置里,输入 custom domain 并保存。注意要带上 www。然后将 hexo 本地博客源文件夹的 source 文件夹下的 CNAME 记录修改如下:

rula.life

不带 http 和 www。最后,在 namesilo 的 DNS 设置界面,选择 github 模板,一键应用。回到 github pages,设置 enforce https,完毕!

注意:在 pages 设置界面,DNS 检查时,要出现如下显示,才说明 CNAME 和 Namesilo 设置成功:

TLS

Hello World!

· 阅读需 1 分钟

记录一下本网站的建立过程

首先,本网站是一个静态博客,基于 GitHub pages 提供的免费服务器,域名在 Namesilo 上购买,页面管理器为基于 nodejs 的 hexo, 总花费¥ 6.72/year. 建站第一天,感觉访问速度还可以。因为在国外买的域名,还不用备案,很爽,all for freedom.

日常管理上,需要发布新文章时,在 Git Bash 上执行下列流程:

    hexo new "title"
hexo g
hexo s
hexo d

如果后期网站外观固定下来,维护起来还是很省心的,nice。