Web 前端实战:Gitee 贡献图
前言
这次要做的 Web 前端实战是一个 Gitee 个人主页下的贡献图(在线 Demo),偶尔做一两个,熟悉熟悉 JS 以及 jQ。整体来说这个案例并不难,主要是控制第一个节点以及最后一个节点处于星期几;且必须保持365个节点。

开始
布局设计
整体的布局是上下,顶部一个 div、下面一个 div。下面的 div 是左右布局,左边是星期、右边是贡献节点。一列贡献节点一共有7个(不一定每一列都是7个)。星期要与每一行贡献节点保持平行。左右布局的高度保持一致,因此,每一个贡献节点的宽和高就取自布局的高/7。
<div id="cb-chart">
<div class="top-bar">
<div class="occupation"></div>
<div class="months"></div>
</div>
<div class="bottom">
<div class="left-side">
<div class="week">周一</div>
<div class="week">周四</div>
<div class="week">周日</div>
</div>
<div class="right-side"></div>
</div>
</div>
CSS 样式
div#cb-chart
div.top-bar和div.bottom两个容器内的元素都是水平方向排列。div.top-bar的高度占整个div#cb-chart的 20%;div.bottom自然就是 80%。

#cb-chart {
width: 940px;
height: 140px;
}
#cb-chart .top-bar {
display: flex;
height: 20%;
width: 100%;
}
#cb-chart .bottom {
display: flex;
height: 80%;
width: 100%;
}
div.bottom
星期与贡献节点是左右排列在整个容器的,且星期占整个容器的 8%:
#cb-chart .bottom .left-side {
width: 8%;
height: 100%;
}
#cb-chart .bottom .right-side {
width: 92%;
height: 100%;
}
星期下的所有元素要均匀分配整个div.left-side的纵向空间:
#cb-chart .bottom .left-side {
/* ...... */
display: flex;
flex-direction: column;
justify-content: space-between;
}
div.right-side中的所有元素(贡献节点)都是从上到下排列,若超出容器的空间时自动换行,左右之间的元素要保持垂直水平对齐:
#cb-chart .bottom .right-side {
/* ...... */
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
flex-direction: column;
align-content: center;
align-items: center;
}
div.top-bar
下面两张图显示了顶部容器最左边有一个不显示的且占了空间的元素,主要目的是用来隔开星期剩余的空间,使顶部容器的每一个月份能够完美对齐下面的贡献节点。


因此在div.top-bar中加了一个空元素<div class="occupation"></div>:
#cb-chart .top-bar .occupation {
width: 8%;
}
div.left-side的宽度 8%,所以它也是 8%;而div.months自然就占整个容器的 92%。
#cb-chart .top-bar .months {
font-size: 12px;
height: 100%;
width: 92%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: center;
}
div.point
这个就是每一个贡献节点元素的样式,宽高必须要经过计算之后才可以给出来,节点的宽和高取自div.bottom 的高/7。使用 CSS var() 函数代替固定的值:
#cb-chart .bottom .right-side .point {
width: var(--point-size);
height: var(--point-size);
border: 1px solid #FFF;
box-sizing: border-box;
background-color: white;
}
JS 部分
绘制节点图
在开始之前要给div.right-side处添加大于365个的贡献节点的 div 元素:
function drawChartGrid() {
let $el = $("#cb-chart .bottom .right-side");
$el.css("--point-size", `${ $el.height() / 7 }px`);
for ( let h = 0; h < 54; h++ ) {
for ( let v = 0; v < 7; v++ ) {
$el.append(`<div class="point"></div>`);
}
}
}

定位起始节点和结束节点
这些贡献度节点的数量是大于365个的,并且每一天的星期数都是有变化的,所以要计算今天是星期几,以及去年的今天是星期几,这样才可以定位起始节点和结束节点。
从起始节点开始,循环到结束节点,这之间就是准确的节点数量,一共365个。使用 $().slice(start, end)函数循环,循环对象是div.right-side下的所有div.point。
函数需要两个变量来控制循环,起始和结束。起始就是去年的今天的星期是几?在 JS Date() 对象中,索引值 1 代表星期一;索引值 0 代表星期日。由于贡献节点的索引值是从 0 开始的,所以,索引值 0 代表星期一,6 代表星期日。所以,要进行计算:
| 星期 | Date 中的索引值 | 贡献节点索引值 |
|---|---|---|
| 星期一 | 1 | 0 |
| 星期二 | 2 | 1 |
| 星期三 | 3 | 2 |
| 星期四 | 4 | 3 |
| 星期五 | 5 | 4 |
| 星期六 | 6 | 5 |
| 星期日 | 0 | 6 |
查找规律,除星期日以外,Date 中的索引值与贡献节点的索引值总是相差 1。所以,只需要 Date 中的索引值(weekIndex)减去 1 就知道slice()函数从哪里开始。
特殊情况星期日:当weekIndex - 1 < 0时,说明是星期日,函数要从索引值 6 开始。
function drawPoints() {
let nowDate = new Date();
let oldDate = new Date(`${ nowDate.getFullYear() - 1 }-${ nowDate.getMonth() + 1 }-${ nowDate.getDate() }`);
let weekIndex = oldDate.getDay();
let start = weekIndex - 1 < 0 ? 6 : weekIndex - 1;
let end = start === 6 ? 372 : 365 + weekIndex;
$(`#cb-chart .bottom .right-side .point`).slice(start, end).each((i, el) => {
// ......
});
}
绘制节点颜色
节点的颜色根据贡献的数量来设置:
function setPointColor(el, number) {
if ( number > 0 && number <= 5 ) {
$(el).addClass("a-type-point");
} else if ( number > 5 && number <= 10 ) {
$(el).addClass("b-type-point");
} else if ( number > 10 && number <= 15 ) {
$(el).addClass("c-type-point");
} else if ( number > 15 ) {
$(el).addClass("d-type-point");
} else {
$(el).addClass("e-type-point");
}
}
函数要获取当前循环的贡献节点的 DOM 对象,以及这个节点对应的贡献数量。函数在下面进行调用:
function drawPoints() {
// ......
let data = getPointsData(oldDate);
$(`#cb-chart .bottom .right-side .point`).slice(start, end).each((i, el) => {
setPointColor(el, data[i].number);
});
}
这里出现了一个
getPointsData函数,暂时不用管,它是随机生成数据的函数。

目前为止的效果如上图所示。
Gitee 仓库
https://gitee.com/shiramashiro/web-learning/tree/main/src/03.案例
Web 前端实战:Gitee 贡献图的更多相关文章
- Web 前端实战:雷达图
前言 在Canvas 线性图形(五):多边形实现了绘制多边形的函数.本篇文章将记录如何绘制雷达图.最终实现的效果是这样的: 绘制雷达图 雷达图里外层 如动图中所示,雷达图从里到外一共有 6 层,所以, ...
- Web 前端实战:JQ 实现树形控件
前言 这是一篇个人练习 Web 前端各种常见的控件.组件的实战系列文章.本篇文章将介绍个人通过 JQuery + 无序列表 + CSS 动画完成一个简易的树形控件. 最终实现的效果是: 这样结构比较复 ...
- web前端开发学习路径图
第一阶段 WEB前端工程师课程 HTML语句,HTML页面结构.css语法.style属性.link和style标签.id属性.等HTML语句中的相关属性: 通过Dreamweaver制作出跨越平台限 ...
- WEB前端知识体系脑图
说在开始的话: 我上大学那会,虽说主要是学Java语言,但是web前端也稍微学了一些,那时候对前端也没多在意,因为涉入的不深,可以搞一个差不多可以看的界面就可以了,其他也没过多在意. 因为稍微了解一点 ...
- Web 前端实战(三):雷达图
前言 在<Canvas 线性图形(五):多边形>实现了绘制多边形的函数.本篇文章将记录如何绘制雷达图.最终实现的效果是这样的: 绘制雷达图 雷达图里外层 如动图中所示,雷达图从里到外一共有 ...
- 【h5+c3】web前端实战项目、快装webapp手机案例源码
快装WebApp项目(Web移动端开发案例)webapp移动端项目源码.html5+css3实战案例分享.微信端H5实例开发 简介快装WebApp是一个面向移动端的快速装修app,此项目为手机端:使用 ...
- Web 前端实战:JQ 实现下拉菜单
实现过程 实现一个简易的鼠标悬停菜单项显示其子项的下拉框控件.将用到 CSS 绝对定位.流式布局.动画等:JQuery 鼠标移入和移出事件.DOM 查找.效果图如下: HTML 结构: <div ...
- web前端职业规划(转)
关于一个WEB前端的职业规划,其实是有各种的答案,没有哪种答案是完全正确的,全凭自己的选择,只要是自己选定了, 坚持去认真走,就好.在这里,我只是简要说一下自己对于这块儿内容的理解.有一个观点想要分享 ...
- 一张图告诉你移动Web前端所有技术(工程化、预编译、自动化)
你要的移动web前端都在这里! 大前端方向:移动Web前端.Native客户端.Node.js. 大前端框架:React.Vue.js.Koa 跨终端技术:HTML5.CSS 3.JavaScript ...
随机推荐
- Oracle数据库丢失表排查思路
Oracle数据库丢失表排查思路 说明:由于系统采用ID取模分表法进行Oracle数据存储,某日发现Oracle数据库中缺少对应的几张业务数据表,遂进行相关问题查询,简单记录一下排查思路: 由于我们代 ...
- (持续更新)虚树,KD-Tree,长链剖分,后缀数组,后缀自动机
真的就是讲课两天,吸收一个月呢! \(1.\)虚树 \(2.\)KD-Tree \(3.\)长链剖分 \(4.\)后缀数组 后缀数组 \(5.\)后缀自动机 后缀自动机
- Jmeter(五十四) - 从入门到精通高级篇 - 如何在linux系统下运行jmeter脚本 - 上篇(详解教程)
1.简介 上一篇宏哥已经介绍了如何在Linux系统中安装Jmeter,想必各位小伙伴都已经在Linux服务器或者虚拟机上已经实践并且都已经成功安装好了,那么今天宏哥就来介绍一下如何在Linux系统下运 ...
- 你难道不知道Vue-cookie?
install npm install vue-cookies --save main.js import VueCookies from 'vue-cookies'Vue.use(VueCookie ...
- SAP string 转 number 类型
try. cl_fdt_calculation=>convert_string_to_number( exporting iv_text = conv #( lwa_at ...
- freeswitch拨打分机号
概述 电话语音服务中,有一种稍微复杂的场景,就是总机分机的落地场景,客户拨打总机号码之后,需要再拨打分机号转接到指定的话机. 分机号的拨打一般在总机接通之后,会有语音提示,总机收号之后转接分机. 分机 ...
- Min_25 筛与杜教筛
杜教筛 \(\) 是 \(\) 的前缀和,\(\), \(\) 同理. 假设 \( × = ℎ\) ,并且 \(, \) 易求出,\(\) 难求出. 那么 \[H () = \sum_{ \cdot ...
- IDEA的项目结构和IDEA的HelloWord
IDEA首次驱动 1. 选择不导入任何设置,点击 OK 2. 选择 Create New Project 3. 点击 new 按钮,配置安装的 JDK9 版本 选择 JDK9 目录,点击确定 4. 不 ...
- 体验SRCNN和FSRCNN两种图像超分网络应用
摘要:图像超分即超分辨率,将图像从模糊的状态变清晰. 本文分享自华为云社区<图像超分实验:SRCNN/FSRCNN>,作者:zstar. 图像超分即超分辨率,将图像从模糊的状态变清晰.本文 ...
- centos7 yum error yum doesn't have enough cached data
1.vi /etc/resolv.conf,添加下面一行 nameserver 114.114.114.114 修改完成后service network restart进行重启,试一下yum upda ...