Wenzi

用js制作一个简单的明朝时间轴

蚊子前端博客
发布于 2015/12/07 07:00
这些日子在看《明朝那些事儿》,里面有很多重要的事件,于是就想着根据时间的推移,用一种可视化的方式展现出明朝各种的大事件

不多说,先上地址:明朝——时间轴
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; // 滚动条向右移动
	}
})

当然还有很多其他的内容需要添加上,比如各个派系,内阁首辅是谁等等,需要完善的地方还有很多。

标签:javascriptdom
阅读(1961)
Simple Empty
No data