前言

这次要做的 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. ORM执行sql语句 双下划线 外键字段创建 ORM跨表查询

    目录 模型层之ORM执行SQL语句 方式1一 方式二 方式三 神奇的双下划线查询 ORM外键字段的创建 1.创建基础表 2.确定外键关系 3.表的查看 数据的录入 外键字段相关操作 针对一对多 ''' ...

  2. npm Error: Cannot find module 'are-we-there-yet'

    npm 损坏了,are-we-there-yet是npm所依赖的npmlog依赖的一个包,重新安装npm即可 踩坑,直接安装还是报错,不管执行哪个命令都是报下面这个错 网上百度了很多,有的说把node ...

  3. C++进阶(位图+布隆过滤器的概念和实现+海量数据处理)

    位图 概念 位图: 所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景.通常是用来判断某个数据存不存在的. 适用场景: 如果我们需要对大量的数据进行处理,判断该数据在不在,比如40 ...

  4. 痞子衡嵌入式:Farewell, 我的写博故事2022

    -- 题图:苏州荷塘月色 2022 年的最后一天,写个年终总结.困扰大家三年之久的新冠疫情终于在 12 月全面放开了,痞子衡暂时还没有阳,计划坚持到总决赛.对于 2023 年,痞子衡还是充满期待的,慢 ...

  5. day13-功能实现12

    家居网购项目实现012 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 29.功能27-Ajax检验注册名 29.1需求分析/图 ...

  6. 第七节 VOR/DME进近程序保护区的绘制

    飞行程序设计软件实践 通过前面六节的练习,2023社区版插件的主要功能都已经使用到了.今天通过VOR/DME非精密进近程序,再将这些功能串起来使用一下.今天的软件,我们使用浩辰CAD2023版(过期后 ...

  7. [Untiy]贪吃蛇大作战(一)——开始界面

    前言: 刚学unity没多久吧(大概1个月多点),这是我自己做的除官网之外的第一个游戏demo,中间存在很多不足的地方,但是还是希望可以给需要的人提供一些思路和帮助,有问题的小伙伴可以找我一起探讨一起 ...

  8. 基于DB Visualizer的hive连接配置

    1.准备工作 从CDH官网下载hive使用的连接用jar包 https://www.cloudera.com/downloads/connectors/hive/jdbc/2-5-16.html 解压 ...

  9. 解决angular11打包报错Type 'Event' is missing the following properties from type 'any[]': ...Type 'Event' is not assignable to type 'string'

    出现这种情况,需要检查一下以下事项 1.ts类型声明和html里写的是否一致 1.1举例如下,子组件代码需要注意事项,子组件调用父组件方法,点击传参给父组件,在父组件触发一些时间,当前this指向是父 ...

  10. ES中的内置对象--jquery如何优化代码,少用$进行查找,减少查找次数的方法