drawSvg.js 5.64 KB
/**
* 画线路svg 图
* type: 0 上行站点  1 下行站点  2  上下行共有  3 不同名合并
*/
var drawSvg = (function(){
	
	var mt = 81//顶部距离
		,p = 132//上下行之间的间隔
		,x = d3.scale.linear()
		,w;
	
	var upStation = function(value){
		return value.type != 1 ;
	}
	
	var downStation = function(value){
		return value.type != 0;
	}
	
	var textY = function(d){
	}
	
	var upLine = d3.svg.line().x(function(d) {
			return d.cx;
		}).y(function(){return mt});
	
	var downLine = d3.svg.line().x(function(d) {
			return d.cx;
		}).y(function(){return mt + p});
	
	var cx = function(d, i){
		return x(i);
	}
	
	var drawSvgObject = {
		init: function(data, container){
			w = $('.line_chart:first').width();
			var svg = d3.select('#' + container).append('svg')
						.attr('width', w).attr('opacity', 0)
				,dLen = data.length;
			
			x.range([ 50 , w - 10]).domain([ 0,  dLen]);
			
			//上行线条 path
			svg.append('path')
				.attr('d', function(){
					return upLine([{cx: x(0)}, {cx: x(dLen - 1)}]);
				})
				.attr('class', 'up_path');
			
			//下行线条 path
			svg.append('path')
				.attr('d', function(){
					return downLine([{cx: x(0)}, {cx: x(dLen - 1)}]);
				})
				.attr('class', 'down_path');
			
			//左弧线 path
			svg.append('path')
				.attr('d', function(){
					var cx = x(0) - 8
						,cy = mt + 5
						,arc = cx - 18;
					return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8);
				})
				.attr('class', 'up_path arc');
			
			//右弧线 path
			svg.append('path')
				.attr('d', function(){
					var cx = x(dLen - 1) + 8
						,cy = mt + 5
						,arc = cx + 18;
					return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8);
				})
				.attr('class', 'down_path arc');
			
			var g = svg.append('g').selectAll('g')
					.data(data)
					.enter()
					.append('g').attr('class', 'item');
			
			//上行站点 circle
			g.append('circle')
					.attr('class', function(d){
						if(d.type != 1)
							return 'up_station_circle';
					})
					.attr('cx', cx)
					.attr('cy', mt);
			
			//站点名称 text
			g.append('text')
				.attr('class', function(d, i){
					var c = 'station_text';
					if(i == 0)
						c += ' start';
					else if(i == dLen - 1)
						c += ' end';
					if(d.type == 3)
						c += ' up';
					return c;
				})
				.text(function(d){
					return d.type==3 ? d.name[0] : d.name;
				})
				.attr('x', function(d, i){return (d.type==3?(x(i) - 8):x(i))})
				.attr('y', mt + 10);
			
			//下行站点
			g.select(function(d){return d.type!=0?this:null})
				.append('circle')
				.attr('class', function(d){
					if(d.type != 0)
						return 'down_station_circle';
				})
				.attr('cx', cx)
				.attr('cy', mt + p);
			
			//上下行不同名(异站合并)
			g.select(function(d){return d.type==3?this:null})
				.append('text')
				.attr('class', 'station_text down')
				.text(function(d){return d.name[1]})
				.attr('x', function(d, i){return x(i) + 8;})
				.attr('y', mt + 10);
			
			/**
			 * ---------------  文字居中啊,长度截断啊处理一下 ----------------------
			 */
			svg.selectAll('text')
				.attr('transform', function(d, i){
					var len = $(this).text().length;
					return 'translate(0,' + (len < 7?(7 - len) * 8:0) + ')';
				})
				.text(function(){
					var t = $(this).text()
						len = t.length;
					if(len > 7){
						$(this).data('fullname', t);
						return t.substring(0, 7);
					}
					return t;
				});
			
			$(' .text-load', '#'+container).remove();
			svg.transition().duration(500).attr('opacity', 1);
			
			up(svg, data, g);
		}
	};
	
	//更新
	function up(svg, data, g){
		/**
		 * ------------- 抽站 --------------------------------
		 */
		var ms = w / 37
			,dLen = data.length;
		if(ms < dLen){
			var rs  = dLen - ms
				,s = parseInt(dLen / 2 - rs)
				,e = (rs + s) * 2;
			
			var rsEmes = [];
			//中间开始,隔站抽
			for(;s < e; s +=2)
				rsEmes.push(g[0][s]);
			
			var i = 0;
			(function(){
				var f = arguments.callee;
				if(i >= rsEmes.length){
					upPosi(svg)
				}
				
				$(rsEmes[i]).fadeOut(30, function(){
					$(this).remove();
					i ++;
					f();
				});
			})();
		}
	}
	
	function upPosi(svg){
		//重新等比例位置
		var gItems = svg.selectAll('g.item')
			,dLen = gItems[0].length;
		x.domain([ 0,  dLen]);
		gItems.select(function(d, i){
			var ts = $(this).find('text')
				,xv = x(i);
			if(ts.length == 2){
				xv = x(i) - 8;
				d3.select(ts[1])
					.transition().duration(500)//过渡
					.attr('x', x(i) + 8);
			}
			d3.select(ts[0])
				.transition().duration(500)//过渡
				.attr('x', xv);
			
			d3.select(this).selectAll('circle')
				.transition().duration(500)//过渡
				.attr('cx', x(i));
		});
		//缩线
		svg.select('path.up_path')
			.transition().delay(500).duration(500)//过渡
			.attr('d', function(){
				return upLine([{cx: x(0)}, {cx: x(dLen - 1)}]);
			});
		
		svg.select('path.down_path')
			.transition().delay(500).duration(500)//过渡
			.attr('d', function(){
				return downLine([{cx: x(0)}, {cx: x(dLen - 1)}]);
			});
		
		svg.select('path.down_path.arc')
			.transition().delay(500).duration(500)//过渡
			.attr('d', function(){
				var cx = x(dLen - 1) + 8
					,cy = mt + 5
					,arc = cx + 18;
				return 'M' + cx + ',' + cy + ' C' + arc + ',' + (cy + 5) + ' ' + arc + ',' + (cy + p - 13) + ' ' + cx + ',' + (cy + p - 8);
			});
	}
	
	return drawSvgObject;
})();