前言

这次要做的 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-bardiv.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 函数,暂时不用管,它是随机生成数据的函数。

目前为止的效果如上图所示。

代码仓库

Github 仓库地址

04#Web 实战:Gitee 贡献图的更多相关文章

  1. Web 前端实战:Gitee 贡献图

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

  2. K8S(14)监控实战-grafana出图_alert告警

    k8s监控实战-grafana出图_alert告警 目录 k8s监控实战-grafana出图_alert告警 1 使用炫酷的grafana出图 1.1 部署grafana 1.1.1 准备镜像 1.1 ...

  3. 07#Web 实战:实现 GitHub 个人主页项目拖拽排序

    实现效果图 GitHub 和 Gitee 个人主页中可以对自己的项目进行拖拽排序,于是我就想自己实现一个.本随笔只是记录一下大概的实现思路,如果感兴趣的小伙伴可以通过代码和本随笔的说明去理解实现过程. ...

  4. golang web实战之二(iris)

    之前写了一篇为:golang web实战之一(beego,mvc postgresql) 听说iris更好: 1.  iris hello world package main import &quo ...

  5. 《黑客攻防技术宝典Web实战篇@第2版》读书笔记1:了解Web应用程序

    读书笔记第一部分对应原书的第一章,主要介绍了Web应用程序的发展,功能,安全状况. Web应用程序的发展历程 早期的万维网仅由Web站点构成,只是包含静态文档的信息库,随后人们发明了Web浏览器用来检 ...

  6. 黑客攻防技术宝典web实战篇:核心防御机制习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 黑客攻防技术宝典web实战篇是一本非常不错的书,它的著作人之一是burpsuite的作者,课后的习题值得关注 ...

  7. PicGo软件搭配gitee实现图床

    1.安装PicGo软件,并配置gitee 1.1安装picGo picGo 安装gitee-uploader 插件 官网下载地址如下:最新版本 可以自行选择版本进行下载,这里我选择了最新的版本进行下载 ...

  8. 【超详细】MakeDown(Typora)+PicGo+Gitee实现图床

    [超详细]MakeDown(Typora)+PicGo+Gitee实现图床 序言:我们有时在用makedown整理笔记时想把自己的笔记上传到博客园,可是发现在上传过程中makedown中的图片显示不出 ...

  9. Typora+PicGO+Gitee实现图床功能

    Typora+PicGO+Gitee实现图床功能 版本 typora(0.9.86) PicGo(2.3.0) 主要参考链接 出现问题就先看看这个 问题一 打开PicGo后安装github插件会一直安 ...

  10. Web 前端实战:雷达图

    前言 在Canvas 线性图形(五):多边形实现了绘制多边形的函数.本篇文章将记录如何绘制雷达图.最终实现的效果是这样的: 绘制雷达图 雷达图里外层 如动图中所示,雷达图从里到外一共有 6 层,所以, ...

随机推荐

  1. 跨机房ES同步实战

    作者:谢泽华 背景 众所周知单个机房在出现不可抗拒的问题(如断电.断网等因素)时,会导致无法正常提供服务,会对业务造成潜在的损失.所以在协同办公领域,一种可以基于同城或异地多活机制的高可用设计,在保障 ...

  2. vba 正则表达式用法

    Sub Regexp_test(Sht As String, str As String)On Error Resume NextDim regx As ObjectDim arr, brr, mhS ...

  3. adb环境配置及常用命令

    一.adb环境配置 1.下载并安装adb驱动 2.下载adb工具platform-tools.rar,解压放在某个文件夹下 3.右击此电脑->属性->高级系统设置->环境变量-> ...

  4. 【Redis场景2】缓存更新策略(双写一致)

    在业务初始阶段,流量很少的情况下,通过直接操作数据是可行的操作,但是随着业务量的增长,用户的访问量也随之增加,在该阶段自然需要使用一些手段(缓存)来减轻数据库的压力:所谓遇事不决,那就加一层. 在当前 ...

  5. Spark详解(08) - Spark(3.0)内核解析和源码欣赏

    Spark详解(08) - Spark(3.0)内核解析和源码欣赏 源码全流程 Spark提交流程(YarnCluster) Spark通讯架构 Spark任务划分 Task任务调度 Shuffle原 ...

  6. VMware搭建内网渗透环境

    网络结构: 攻击机:kali 192.168.1.103 DMZ区域:防火墙 WAN:192.168.1.104 LAN:192.168.10.10 winserver03 LAN:192.168.1 ...

  7. [LeetCode]819. 最常见的单词

    题目 给定一个段落 (paragraph) 和一个禁用单词列表 (banned).返回出现次数最多,同时不在禁用列表中的单词.题目保证至少有一个词不在禁用列表中,而且答案唯一. 禁用列表中的单词用小写 ...

  8. (9)go-micro微服务Redis配置

    目录 一 go-redis介绍 二 go-redis安装 三 redis初始化连接 四 存储mail邮件 五 存储token 六 最后 一 go-redis介绍 Redis(Remote Dictio ...

  9. ac自动姬

    字符串 ac自动姬 前言 省选临近,不能再颓了! 说着开始研究起moonlight串流.真香 本期博客之所以在csdn上发了一份,因为没有图床!如果有图床我一定会自力更生的! 好像和字符串没有毛关系 ...

  10. jQuery查找标签、操作标签、事件和动画效果,Bootstrap页面框架的介绍和使用讲解

    今日内容 jQuery查找标签 1.基本选择器: $('#d1') id选择器 $('.c1') class选择器 $('div') 标签选择器 2.组合选择器: $('div#d1') 查找id是d ...