# 前言

本来最开始只是因为 JsDeliver ... 又又又挂了,导致部分用到的 CDN 在家里访问不了 —— 本来上次就已经把大部分脚本引用从 JsDeliver 切换到 Staticfile 了,然而还是有少几个在 Staticfile 没有的导致没法换
然后就发现,一旦这『少数』脚本出了问题,网页就会一直卡在那儿等它... 等半天真的是

于是就想办法搞,比如 fancybox、justifiedGallery、jquery、valine、whatwg-fetch 等

# 处理

之前 fancyboxjustifiedGalleryjquery 三个是由原 Shoka 作者合并申请的:

#! DO NOT EDIT THE FOLLOWING vendors SETTINGS
#! UNLESS YOU KNOW WHAT YOU ARE DOING
#! Script dependencies will be combined with jsDelivr (cdn.jsdelivr.net)

于是先是把合并的拆开,找地方再把拆开的给一一引用起来,弄好后又发现新问题:右键页面空白处,也会弹出图片菜单,开始还以为我引用搞出问题了,结果测试半天发现,不是 fancybox 那一坨的问题...

找不到原因了,反正也基本没用过,于是干脆直接删了,然后禁用图片点击

而后,又回到最开始界面卡加载慢的原因: whatwg-fetch ,查到原仓库,看到描述说是为了兼容 polifill 而写的,另外已经两年没更新了

这个 CDN 国内找了几个都没有,考虑到目前新浏览器已经是自己支持 fetch 操作了,于是调了一阵子还是将其『瘦身』掉了

# 页顶大图修改

然后去搜索了一下网上同样使用 Shoka 的,结果基本全挂了,少数几个还能正常访问的,例如 lavenderdh

然后... 看到 lavenderdh 文章 ,是说把页顶图片放大至全屏的修改 —— 这个本来以前刚换 Shoka 的时候就见过,这次感觉:哎,还不错,于是加上了

# 添加文章统计

然后,顺便翻了下博主的主页 —— 虽然看着已经很久没更新了,不过页面的文章统计功能这次吸引了我的注意,再一翻,竟然还写了相关文章记录的,于是参考着给我的也加上。

跟着步骤还是挺顺利,然而博主的嵌入方式有点不优雅... 好像有点问题,我想把这功能加入主题配置中,然后改成按需加载。

于是... 花费的研究时间就足以让我也写篇文章记录一下了。

# 图表显示问题

首先,图表显示有点问题,例如统计图只显示当前一个月的、饼图重叠等...

比如:

跟着博主参考的链接进去看了下,一通改,算是修好了

# 发布日历显示问题

这个功能该是博主 lavenderdh 自己加的,然而在我这有些问题 —— 博主上边显示的是 每一年 的,到我这又不对劲,就只有一年的了

另外整体显示极小:大概是因为一年日期的网格,没法填满宽度导致的

后面对比了下网页源码上图表数据代码:

我的 (博主博文贴出来的):

series: [{
    type: 'heatmap',
    coordinateSystem: 'calendar',
    calendarIndex: 0,
    data: ${datePosts}
}]

博主的:

series: [{
        type: 'heatmap',
        coordinateSystem: 'calendar',
        calendarIndex: 0,
        data: 
    },
    {
    type: 'heatmap',
    coordinateSystem: 'calendar',
    calendarIndex: 1,
    data: 
    },
    {
    type: 'heatmap',
    coordinateSystem: 'calendar',
    calendarIndex: 2,
    data: 
    }]

这代码完全不一样了好吧... 其它诸如格子大小不对劲、偏移导致年份、星期显示不出来也是,可能是博主后面改了,没更新博文

于是对比着生成的 HTML 网页源码改了下,把显示宽度问题解决了,至于统计多年提交... 想了想放弃了,显示一年也行吧,还要 Git 上提交记录不也只展示最近一年么?

—— 不然改起来又要研究咋动态去生成 (不然总不可能直接写死的吧?也许还真是写死的...?看着 lavenderdh 的统计页面 切换主题的代码,手动设置了三个日历的数据)
在这里浪费的时间够多了,本来是因为昨天在写 Cinemachine文档整理翻译 文章的时候,本地预览看到网页显示比较慢,结果......

# 延迟加载执行问题

原本的嵌入方式,第一次 fetch 页面(不是刷新),会导致什么都没有,白屏
主要原因是:操作代码是 JS,而且嵌入网页中的,引用却是外部的 Script:https://cdn.staticfile.org/echarts/5.4.2/echarts.min.js

导致在 echarts 本身的 Script 还没拉取下来之前,先一步执行自己的逻辑代码,就要遭(这是分析了一阵流程发现的)

  • 博主说的解决方式是直接全局引用 echarts ,这个后续我也尝试过

首先,按照原本的做法把功能弄了进来,并且修改为了配置模式:

# statistics 文章统计功能
postStatistics:
  beginDate: 2015-12 #开始统计日期
  tagCount: 10 #统计标签个数

然后,意图采用延迟加载的方式去解决这个问题,发现没能解决,也是这时候有点意识到问题了

想了想又研究着改成全局加载做尝试,然而发现 echarts 这东西... 内容有点丰富,单文件都 999KB ,约等于 1M 大小了

要是只有几十 KB 我倒无所谓了,但这种大小全局加载,就感觉太不优雅了,还是想改成 按需加载 的方式

Shako 自带的延迟加载逻辑一样不行( vendorJs(XX)

后面又想到,既然现在的主要问题是内嵌入网页的代码先执行导致,那么将两者都变成外部引用呢?

如果尝试的话,问题就变成如何动态生成可以被链接的代码了,因为 Shoka 默认是把所有生成代码合并成一个 app.js ,加那里边又是代码膨胀了


最后加到了新创建的那个 charts.js 里边

主要是 echarts-init 执行初始化,其中代码是调用生成动态的那几个图表函数:

<script id="echartsInit">
    function switchPostChart () {
      // 这里为了统一颜色选取的是 “明暗模式” 下的两种字体颜色,也可以自己定义
      let color = document.documentElement.getAttribute('data-theme') === null ? '#fff' : '#000'
      if (document.getElementById('posts-calendar')) {
          let postsCalendarNew = postsCalendarOption
          postsCalendarNew.textStyle.color = color
          postsCalendarNew.title.textStyle.color = color
          postsCalendarNew.visualMap.textStyle.color = color
          postsCalendarNew.calendar.itemStyle.color = color
          postsCalendarNew.calendar.yearLabel.color = color
          postsCalendarNew.calendar.monthLabel.color = color
          postsCalendarNew.calendar.dayLabel.color = color
          postsCalendar.setOption(postsCalendarNew)
      }
      if (document.getElementById('posts-chart')) {
          let postsOptionNew = postsOption
          postsOptionNew.textStyle.color = color
          postsOptionNew.title.textStyle.color = color
          postsOptionNew.xAxis.axisLine.lineStyle.color = color
          postsOptionNew.yAxis.axisLine.lineStyle.color = color
          postsChart.setOption(postsOptionNew)
      }
      if (document.getElementById('tags-chart')) {
          let tagsOptionNew = tagsOption
          tagsOptionNew.textStyle.color = color
          tagsOptionNew.title.textStyle.color = color
          tagsOptionNew.xAxis.axisLine.lineStyle.color = color
          tagsOptionNew.yAxis.axisLine.lineStyle.color = color
          tagsChart.setOption(tagsOptionNew)
      }
      if (document.getElementById('categories-chart')) {
          let categoriesOptionNew = categoriesOption
          categoriesOptionNew.textStyle.color = color
          categoriesOptionNew.title.textStyle.color = color
          categoriesOptionNew.legend.textStyle.color = color
          categoriesChart.setOption(categoriesOptionNew)
      }
  }
  document.getElementsByClassName("theme")[0].addEventListener("click", function () { setTimeout(switchPostChart, 200) });
  function venderJs(callback)
  {
    if(window['echartload'])
    {
      callback();
      return;
    }
    var script = document.createElement('script');
    script.onload = script.onreadystatechange = function() {
      script.onload = script.onreadystatechange = null;
      script = undefined;
      callback();
    };
    script.src = '${hexo.theme.config.vendors.js.echart}';
    window['echartload']=true;
    document.head.appendChild(script);
  }
  venderJs(function(){
    Do_postsCalendar();
    Do_postsChart();
    Do_tagsChart();
    Do_categoriesChart();
  })

外面统计页面,就只保持最低限度的几个 HTML 配置了:

---
title: 文章统计
date: 2023-5-28
copyright: false
echart: true
---
<!-- 文章发布日历 -->
<div id="posts-calendar" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章发布时间统计图 -->
<div id="posts-chart" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章标签统计图 -->
<div id="tags-chart" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章分类统计图 -->
<div id="categories-chart" style="border-radius: 8px; height: 450px; padding: 10px;"></div>
<!-- 初始化使用 -->
<div id="echarts-init"></div>

效果如下所示:

# 标签统计图显示不全

主要发生在刻度过多时 —— 我加了个自定义的标签的配置,然后随便配了个 15 就出现了

参考 柱状图 x 轴坐标显示不全 可以解决 (但是压缩起来叠加会很难看,我又去掉了)

# 其它

# Hexo 系统变得缓慢

原因似乎是因为 charts 注册的 after_render:html 会对项目中生成的每个 HTML 作解析判断
想加入页面开关避免无谓解析呢,但是貌似已经获取不到 page.XXX 这种信息了,相当于页面已经渲染完毕,因此只能在最开始多判断一层,少解析一些速度会快点

# 图表没有去重

导致子分类会被单独归为另外一类,得做一次去重

# 总结

其它还修了一波其它问题,比如 vendorJS 函数会反复插入 js 脚本的 BUG (不知道是不是我改出来的)

就这样

对于 echats 统计功能,虽然不能说封装完美,至少做到了 按需加载 ,不会因为第一次 fetch 进统计页面白屏,也不会因为一个页面使用就必须始终加载 —— 感觉这样才优雅一些

如果用我修改的主题的话,只需要新建一个 statistics 页面,直接就可以用了,统计开始时间也在 config 配置中:

# statistics 文章统计功能
postStatistics:
  beginDate: 2015-12 #开始统计日期
  tagCount: 10 #统计标签个数

周末时间折腾了一天搞这个,还是挺心疼的... 终于弄完了,这两天本来计划趁周末把算法之美收尾,然后将阅读笔记复习一遍上传博客的,结果尽搞其它去了...

一通操作下来,虽然感觉我已经可以做到自动生成 lavenderdh 的统计页面 那种多年分的日历图
貌似其实挺简单的:理论上通过 JSON.stringify 将对应字典转换成 json 赋值给 series heatmap 就行了, tagsChart 就是一个很好的示例

不过考虑了下时间关系和本身效果 —— 还是先算了,本来也不是很重要的效果

今天待会儿先把博客弄规矩,以及 Cinemachine文档整理翻译 再过一遍看有没有写的不通畅的,然后把 DOTS 笔记也上传一下

将算法之美的笔记整理成文章... 只能等明天或者后天再说了

不过... 这个 echarts 确实厉害,效果相当好,以后有需要没准也用得上

# 参考文章

  • Shoka 主题:新增文章统计页面
  • Hexo 博客文章统计图