不多说,先上地址:明朝——时间轴。
git地址:ming_timeline。
目前皇帝和事件的数据只弄了几个,后续会接着完善,也欢迎大家补充,^_^。
这个项目没有使用什么高深的技术,就是用html拼接出来的。这个时间轴主要是由三部分组成:
- 时间刻度轴(公历)
- 皇帝在位轴(从某年到某年在位)
- 大事件轴(于某年发生某事)
1. 时间刻度轴 #
设置时间刻度轴需要设置两个变量:每个年份之间的像素距离(year_per)和每个大刻度之间的年数(year_degree)
// 设置时间刻度
setYearLine : function(defaults){
var html = '<ul class="clearfix">';
for(var i=defaults.year_start; i<defaults.year_end; i=i+defaults.year_degree){
html += '<li>'+i+'</li>';
}
html += '</ul>';
$('#year').append(html).find('li').css({'width':defaults.year_per*defaults.year_degree+'px'});
$('#content').css({'width':defaults.year_per*(defaults.year_end-defaults.year_start)});
}
2. 皇帝在位轴 #
通常皇帝的属性有:姓名,继位年份,驾崩年份,庙号,年号,后人评价等,因此我们设置的结构体是:
{
start : 1368, // 继位年份
end : 1398, // 驾崩年份
miao : '明太祖', // 庙号
name : '朱元璋', // 姓名
nian : '洪武' // 年号
}
然后根据开始和结束年份计算出皇帝的在位时间,不过,细细想一下,继位时间和驾崩时间只要其中一个就行了,因为上一个皇帝的驾崩时间就是下一个皇帝的继位时间。
// 设置皇帝在位轴
setEmperorLine : function(defaults){
var data = emperor_data;
var marginLeft = util.getItemPix(data[0].start);
var html = '<ul class="clearfix" style="margin-left:'+marginLeft+'px">';
for(var i=0, t=data.length; i<t; i++){
var item = data[i],
width = (item.end-item.start)*defaults.year_per,
bgcolor = util.randomColor(),
nian_s = item.nian ? '('+item.nian+')' : '';
html += '<li style="width:'+width+'px; background:'+bgcolor+';">'+item.name+'-'+(item.miao||'')+ nian_s +'</li>';
}
html += '</ul>';
$('#line').append(html);
}
3. 大事件轴 #
重点来了,一个事件通常有两种情况:瞬发性事件(如明朝建立)和持续性事件(如胡惟庸案持续近10年),瞬发性事件在某个时间点突然就完成了,而持续性事件则有开始时间和结束时间,因此我们设计的结构体是这样的,瞬发性事件只有开始时间,没有结束时间:
{
start : 1380, // 开始时间
nian_start : '洪武十三年', // 年号开始计时
end : 1392, // 结束时间(可选,若为瞬发性时间,则省略该字段)
nian_end : '洪武二十五年', // 年号结束计时(可选,若为瞬发性时间,则省略该字段)
title : '胡惟庸案', // 事件名称
info : '胡惟庸案发,株连三万余人;罢中书省,废丞相制度.改大都督府为五军都督府.罢御史台,废御史大夫' // 事件简要介绍(可选,若事件名称即可说明,则无需此字段)
}
然后在往页面中渲染的时候,判断end
字段是否存在且不为空。若是,则表示此事件是持续性的,否则就是瞬发性的。这里还要补充一下,虽然很多事件都是有持续时间的,从酝酿,到爆发,再到结束;但是这些事件经常找不到没有明确的开始和结束时间,大部分只能归为瞬发性事件。
有的事件可能发生在同一年,或者发生的时间间隔很短,若这几个事件排在同一条线上,会形成重叠,造成阅读困难。因此这里借用瀑布流的思路,用一个数组level
,来存储每一阶最大的年份,每次插入事件时,都会拿当前事件的开始年份和数组中存储的数据进行比较;当然条件是有限使用第一阶,第一阶的当前年份上有数据(即第一阶的年份比当前年份大),则使用第二阶的数据;若第二阶不满足,则使用第三阶,以此类推。
// 设置重要事件轴
setThingLine : function(){
var html = '',
data = thing_data,
level = [0, 0, 0, 0, 0], // 防止多个进度条重复,每个数字表示当前进度最后的年份,数组的最后一个表示年份最小的那一组
len_1 = level.length-1;
for(var i=0, t=data.length; i<t; i++){
var item = data[i],
startLeft = util.getItemPix(item.start),
bgcolor = util.randomColor(),
sty_width = '',
sty_cls = 'item_one',
info = item.info ? ' > <div class="info">'+item.info+'</div>' : '', // 若有事件描述则添加上,否则为空
bt = 0;
// 判断当前事件应该在第几阶
for(var j=0; j<len_1; j++){
if(item.start>level[j]+2){
level[j] = item.end || item.start;
level[len_1] = j;
break;
}
}
bt = (level[len_1])*34+8;
if(item.end){
// 若存在结束时间
var endLeft = util.getItemPix(item.end);
sty_width = 'width:'+(endLeft-startLeft)+'px;';
sty_cls = 'item';
}
html += '<div class="'+sty_cls+'" style="left:'+startLeft+'px; '+sty_width+' border-color:'+bgcolor+';">\
<div class="proce" style="background:'+bgcolor+'; bottom:'+bt+'px">'+item.title+info+'</div>\
</div>';
}
$('#thing').append(html);
}
4. 其他 #
好了,现在基本框架是形成了,但是因为现在时间轴是横着放的,而不是竖着放的(其实最开始是按照竖轴设计的,但是感觉添加文字不太方便,后改成横着了),那么鼠标的滚轮就用不上了,很多人喜欢边滚滑轮边看,横着的话,只能拖动滚动条了。没关系,我已经替你想好了,我已经为展示内容的区域设置了滚轮事件。当然,关于滚轮的更详细的内容,可以参考张鑫旭的文章【JS滚轮事件(mousewheel/DOMMouseScroll)了解】
// 鼠标滚轮,滚动条左右滚动
document.getElementById('main').addEventListener('mousewheel', function(event){
var e = event || window.event,
delta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
var sleft = this.scrollLeft;
// 向上滚轮
if(delta>0){
this.scrollLeft = sleft-100; // 滚动条向左移动
}else{
this.scrollLeft = sleft+100; // 滚动条向右移动
}
})
当然还有很多其他的内容需要添加上,比如各个派系,内阁首辅是谁等等,需要完善的地方还有很多。