Js时间轴渲染
-
建立一个div规定时间轴的长度。假设为常量d;
-
有一组时间数据假设为data = [{Matter:事件, StartTime:开始时间, EndTime:结束时间,Color:颜色},{},{}…等],其中一条例如{Matter:”吃饭”,StartTime:” 2018/10/10 12:00”,EndTime:”2018/10/10 12:40”,Color:”red”}
-
获取数据条数
var intLength = data.length
- 声明数组储存时间轴每个节点的时间值Time[](数组长度为时间数据条数乘以2在加 上起止时间也就是2intLength + 2,最大索引也就是2intLength + 1,时间单位为毫秒),每两个节点之间的时间状态State[](数组长度为Time[]长度减1也就是2intLength + 1最大索引也就是2intLength)。
三条时间数据为例草图
-
规定时间轴的起始时间与结束时间,把数据中的第一个时间提前得到起始时间,把最后一个时间延后得到结束时间
1) 把第一个时间与最后一个时间转化为JS时间对象
var sTiem = new Date(Date.parse(data[0].StartTime));
var sTiem = new Date(Date.parse(data[intLength - 1].EndTime));
2) 提前第一个时间得到起始时间,延后最后一个时间得到结束时间。
//(注:当然你也不可直接用数据的最大时间与最小时间不进行提前与延误,但我还是以我的为例)
if (sTiem.getHours() > 12) { //判断如果时间大于12点就等于十二点否则就等于0点 (最小时间)
Time[0] = new Date(sTiem.getFullYear(), sTiem.getMonth(), sTiem.getDate(), 12).getTime();
} else {
Time[0] = new Date(sTiem.getFullYear(), sTiem.getMonth(), sTiem.getDate(), 0).getTime();
}
if (eTiem.getHours < 12) { //判断如果时间小于12点就等于十二点否则就等于第二天0点 (最大时间)
Time[intLength * 2 + 1] = new Date(eTiem.getFullYear(), eTiem.getMonth(), eTiem.getDate(), 12).getTime();
} else {
Time[intLength * 2 + 1] = new Date(eTiem.getFullYear(), eTiem.getMonth(), eTiem.getDate(), 24).getTime();
}
- 接下来循环给两个数组赋值。
//循环给数组赋值
var T = 1;
var B = 0
for (var i = 0; i < intLength; i++) {
State[B] = false;
B++;
State[B] = true;
B++;
Time[T] = new Date(Date.parse(data[i].StartTime)).getTime();
T++;
Time[T] = new Date(Date.parse(data[i].EndTime)).getTime();
T++;
}
把时间数据中的时间值转化为毫秒赋值给时间数组Time[],把每个时间段的状态赋值给State[]。再给最后一个状态数据赋值
State[intLength * 2] = false;
-
接下来获取每一段时间的像素。
1)声明数组储存每一段时间的像素linee[].
2)利用结束时间减去开始时间获取时间轴的时间间隔
var whole = Time[Time.length - 1] - Time[0];
3)利用循环算出每一小段时间站总时间的比例在乘以div的长度常量d得到每一段时间的像素赋值给数组 linee[]
for (var i = 0; i < Time.length - 1 ; i++) {
linee[i] = parseInt(((Time[i + 1] - Time[i]) / whole) * d);
}
- 特殊情况处理,采用循环遍历像素数组linee[],找出像素为0的字段进行删除。并且对应的删除时间节点与状态。
//利用循环遍历像素数组查找出0像素的字段进行删除,并且对应的删除时间节点与状态
for (var i = 0; i < linee.length; i++) {
if (linee[i] == 0) {
Time.splice(i, 1);
State.splice(i, 1);
linee.splice(i, 1);
i--;
}
}
三条数据为例的特殊情况,两条数据前后时间相接。
- 利用循环把时间数组中的毫秒转化为显示的标准格式。
for (var i = 0; i < Time.length; i++) {
Time[i] = DateString(new Date(Time[i]));
}
//js日期对象转化为字符串
function DateString(Time) {
var year = Time.getFullYear();
var Month = Time.getMonth() + 1;
if (Month < 10) {
Month = "0" + Month;
}
var day = Time.getDate();
if (day < 10) {
day = "0" + day;
}
var hour = Time.getHours();
if (hour < 10) {
hour = "0" + hour;
}
var Minutes = Time.getMinutes();
if (Minutes < 10) {
Minutes = "0" + Minutes;
}
return year + "-" + Month + "-" + day + " " + hour + ":" + Minutes;
}
10.接下来把数据渲染成时间轴。linee数组储存的是像素宽度,Time数组储存了节点时间,State数组储存了状态,先清空div,然后利用循环给div内部追加一个个小长条。这样时间轴就基本构成。
$("#A").empty(); //清空div
var dd = 0;
for (var i = 0; i < linee.length; i++) {
var span1 = '<span>' + Time[i] + '</span>';
var span2 = '';
var color = '';
var Matter = '';
if (i == (linee.length - 1)) {
span2 = '<span>' + Time[i + 1] + '</span>';
}
if (State[i]) {
color = 'background:#' + data[dd].Color + ';'
Matter = data[dd].Matter;
dd++;
}
$("#A").append('<div class="come" style="' + color + 'width:' + linee[i] + 'px;">' + Matter + span1 + span2 + '</div>');
}
spanP(); //位置调整
目前效果图
11.最后一步我们对样式
进行一些调整,使时间轴看起来更和谐美观。
//span 样式调整
function spanP() {
var span = $("#A span");
if (span.length > 0) {
for (var i = 0; i < span.length; i++) {
if (i % 2 == 0) {
if (i == (span.length - 1)) {
$(span[i]).addClass("RightB")
} else {
$(span[i]).addClass("leftB")
}
} else {
if (i == (span.length - 1)) {
$(span[i]).addClass("RightT")
} else {
$(span[i]).addClass("leftT")
}
}
}
}
}
获取所有存放时间值的span标签,对他们分别给上不同的样式类。样式如下
#A .come{
height:25px;
float:left;
border-right:solid #808080 1px;
position:relative;
text-align:center;
font-size:12px;
line-height:25px;
}
#A .come span{
font-size:5px;
position:absolute;
line-height:16px;
}
#A .come:last-child{
border-right:none;
}
.leftB{
top:30px;
left:-50px;
}
.leftT{
top:-20px;
left:-50px;
}
.RightB{
top:30px;
right:-50px;
}
.RightT{
top:-20px;
right:-50px;
}
最后的效果图如下
这样时间轴完成了,谢谢观赏——宋心成