WordPress教程:如何给博客添加heatmap热力图

斌仔 分类:
文章字数 719 字 阅读时间 12 分钟
🤖 由 ChatGPT 生成的文章摘要
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

受椒盐豆豉:如何给 Hugo 博客添加热力图 这篇文章的启发,椒盐豆豉做的是hugo版本,我博客使用的是 WordPress,本想自己开发一个,奈何懒+工作忙就搁置了。

一次晚上逛推,看到了雪糕做的 WordPress 版本:WP Post Heatmap 给 WordPress 博客添加热力图,看着效果不错,第二天,趁着有点时间就给自己的博客整上了。

雪糕做的是插件版本,我只想给我的统计页面直接使用,不想安装插件。

我就看了看雪糕的源码,将主要的部分复制到了我的统计页面代码中。

复制完,我发现页面方格显示的是全部的年份的日期,有点不太直观,我就想能不能直接通过切换年份来展示这一整年的方格(这一灵感借鉴于 Github 个人主页提交代码热力图)。

Github 个人主页提交代码热力图
Github 个人主页提交代码热力图

几天不看椒盐豆豉的热力图文章,再去看,发现 Liminal Negative Space 给热力图添加了多文章显示

今天正好周六就把教程写一下,方便爱折腾的小伙伴使用。(期间家里还断网了,真是遭老罪了。我去修网了🐶)

年份切换功能实现

奈何我代码能力不是很强,只能求助ChatGPT帮我写了一个页面年份切换的 select 选择框

<div id="year-selector-container">
<label for="year-selector">选择年份:</label>
<select id="year-selector">
  <!-- 添加从2020年到当前年份的选项 -->
  <?php
    $currentYear = date("Y");
      for ($year = 2024; $year >= 2020; $year--) {
      echo "<option value='$year'>$year</option>";
     }
  ?>
</select>
</div>

既然选择框都有了,那不得加上切换年份变换整个年份日期的功能

document.getElementById('year-selector').addEventListener('change', function() {  // 获取用户选择的年份
    var selectedYear = document.getElementById('year-selector').value;
    heatmapOption.calendar.range = wholeYearRange(selectedYear);
    heatmapChart.setOption(heatmapOption);
});

function wholeYearRange(selectedYear) {
    const wholeYearStart = new Date(selectedYear, 0, 1); // 一年的开始日期
    const wholeYearEnd = new Date(selectedYear, 11, 31); // 一年的结束日期

    const startDateFormatted = echarts.format.formatTime('yyyy-MM-dd', wholeYearStart);
    const endDateFormatted = echarts.format.formatTime('yyyy-MM-dd', wholeYearEnd);
    // console.log([startDateFormatted, endDateFormatted])
    return [startDateFormatted, endDateFormatted];
}

到这基本上年份切换功能就完成了。

下面就贴一下全部代码,快快用起来吧。

全部代码

  1. 写在页面显示的位置,例如标签之间
<div id="year-selector-container">
<label for="year-selector">选择年份:</label>
<select id="year-selector">
  <!-- 添加从2020年到当前年份的选项 -->
  <?php
    $currentYear = date("Y");
      for ($year = 2024; $year >= 2020; $year--) {
      echo "<option value='$year'>$year</option>";
     }
  ?>
</select>
</div>
<div id="heatmap-chart" style="width: 100%; height:180px;"></div>
  1. 引入 echats cdn链接
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
  1. 具体功能实现代码,请看这里,这里面可是来自4个人的精华😋
<script>
  var heatmapChart = echarts.init(document.getElementById('heatmap-chart'));
<? php
//获取全部文章发布时间、字数、标题、链接
$args = array('numberposts' => -1, // Fetch all posts
);
$posts = get_posts($args);
$post_data = array();

foreach($posts as $post) {
    $date = get_the_date('Y-m-d', $post);
    $word_count = mb_strlen(strip_tags(strip_shortcodes($post - > post_content)), 'UTF8');
    $title = get_the_title($post);
    $url = get_permalink($post - > ID);
    $post_data[] = array('date' => $date, 'word_count' => $word_count, 'title' => $title, 'url' => $url);
} ?>

let option;
const dataMap = new Map();
  // 使用postData来接收php中获取的全部文章发布时间、字数、标题、链接
var postData = <?=json_encode($post_data); ? >;
postData.forEach(function(post) {
    const key = post.date; // Date of the post
    const value = dataMap.get(key);
    const wordCount = post.word_count;
    const link = post.url; // URL of the post
    const title = post.title; // Title of the post
    // In the case of multiple articles on the same day, prefer the one with more words.
    // if (value == null || wordCount > value.wordCount) {
    //     console.log(dataMap)
    //     dataMap.set(key, {key, wordCount, link, title});
    // }
    if (value == null) {
        dataMap.set(key, [{
            wordCount,
            link,
            title
        }]);
    } else {
        value.push({
            key,
            wordCount,
            link,
            title
        });
    }
});

const data = [];
for (const[key, value] of dataMap.entries()) {
    // data.push([key, value.wordCount]);
    var sum = 0;
    for (const v of value) {
        sum += v.wordCount;
    }
    data.push([key, (sum / 1000).toFixed(1)]);
}

document.getElementById('year-selector').addEventListener('change',
function() { // 获取用户选择的年份
    var selectedYear = document.getElementById('year-selector').value;
    heatmapOption.calendar.range = wholeYearRange(selectedYear);
    heatmapChart.setOption(heatmapOption);
});

function wholeYearRange(selectedYear) {
    const wholeYearStart = new Date(selectedYear, 0, 1); // 一年的开始日期
    const wholeYearEnd = new Date(selectedYear, 11, 31); // 一年的结束日期
    const startDateFormatted = echarts.format.formatTime('yyyy-MM-dd', wholeYearStart);
    const endDateFormatted = echarts.format.formatTime('yyyy-MM-dd', wholeYearEnd);
    // console.log([startDateFormatted, endDateFormatted])
    return [startDateFormatted, endDateFormatted];
}

heatmapOption = {
    title: {
        top: 0,
        left: 'center',
        text: '博客废话产量'
    },
    tooltip: {
        formatter: function(p) {
            // const post = dataMap.get(p.data[0]);
            // // console.log(post);
            // return post.title + ' | ' + post.wordCount + ' 千字' + ' | ' + post.key;
            const date = p.data[0];
            const posts = dataMap.get(date);
            var content = `$ {
                date
            }`;
            for (const[i, post] of posts.entries()) {
                content += "<br>";
                var link = post.link;
                var title = post.title;
                // var date = post.key;
                var wordCount = (post.wordCount / 1000).toFixed(1);
                content += `• < a href = "${link}"target = "_blank" > $ {
                    title
                } | $ {
                    wordCount
                }千字 < /a>`
            }
            return content;
        }
    },
    visualMap: {
        min: 0,
        max: 10,
        type: 'piecewise',
        orient: 'horizontal',
        left: 'center',
        top: 30,

        inRange: {
            / / [floor color, ceiling color] color: ['#7aa8744c', '#7AA874']
            },
            splitNumber: 4,
            text: ['千字', ''],
            showLabel: true,
            itemGap: 20,
        },
        calendar: {
            top: 80,
            left: 20,
            right: 4,
            cellSize: ['auto', 12],
            range: wholeYearRange(2024),
            itemStyle: {
                color: '#F1F1F1',
                borderWidth: 2.5,
                borderColor: '#fff',
            },
            yearLabel: {
                show: false
            },
            // the splitline between months. set to transparent for now.
            splitLine: {
                lineStyle: {
                    color: 'rgba(0, 0, 0, 0.0)',
                    // shadowColor: 'rgba(0, 0, 0, 0.5)',
                    // shadowBlur: 5,
                    // width: 0.5,
                    // type: 'dashed',
                }
            }
        },
        series: {
            type: 'heatmap',
            coordinateSystem: 'calendar',
            data: data,
        }
    };

    heatmapChart.setOption(heatmapOption);

    heatmapChart.on('click',
    function(params) {
        if (params.componentType === 'series') {
            const post = dataMap.get(params.data[0])[0];
            window.open(post.link, '_blank').focus();
        }
    });
 </script>

你觉得这篇文章怎么样?

0
0
0
0

非常感激每一位打赏的朋友!

支付宝扫码支持
微信扫码支持

扫一扫,请博主喝咖啡☕

文章作者: 斌仔
文章链接: https://www.wangdu.site/course/2027.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文武科技柜

相关推荐

共有 10 条评论

  1. https://oba.by

    这个功能不错~~

    1. 斌仔

      整上玩玩[g=ciya]

      1. https://oba.by

        用这个插件加上了,哈哈

        1. 斌仔

          找了好几个页面终于找到了,不错不错,没加时间筛选,感觉少点内味

  2. koobai

    整了一个,完美

  3. KK

    搞上了,发现又没啥用。。。。给删掉了,浪费我一两个小时。。

    1. 斌仔

      可能大家享受的是折腾的过程,折腾完了索然无味

  4. xuzzhan

    这代码是html代码吗?还是说怎么弄的,不大会>_<

    1. 斌仔

      这是php+html代码

  5. akau

    折腾了一个小时,发现一个错误(可能只有我出现了这个错误)heatmapChart.setOption(heatmapOption);这一行变量未定义,应该给个定义(腾讯混元AI写的)
    var heatmapChart = echarts.init(document.getElementById('heatmap-chart'));
    heatmapChart.setOption(heatmapOption);