drawSvg.js 7.44 KB
/**
* 画线路svg 图
* 
* type: 0 上行站点  1 下行站点  2  上下行共有  3  合并不同站点
*/

var drawSvg = (function(){
	
	//顶部距离
	var mTop = 21;
	//上下行之间高度
	var h = 132;
	
	var xScale;
	var drawSvgObject = {
		init: function(data, container){
			var stations = data;
			var svg = d3.selectAll('#' + container).append('svg').attr('width',
					'100%').attr('opacity', 0),
				w = $('.line_chart:first').width();
			
			var dLen = stations.length;
			
			//站点太多
			var ms = w / 42;
			if(ms < dLen){
				for(var i = 0; i < dLen - ms; i ++){
					//要被清理的站点
					var rem = stations[i + 2];
					stations.splice(i + 2, 1);
					
					//设置哪些点需要虚线连接
					var prev = stations[i + 1];
					prev.clear = rem.type + 10;
				}
				dLen = stations.length;
			}
			var indent = w / 12 - (dLen * 2) - 2;
			
			//横向比例尺  -根据svg的宽度平均分布站点
			xScale = d3.scale.linear().domain([ 0,  dLen])
					.range([ indent, w]);
			
			$.each(stations, function(i, d) {
				d.cx = xScale(i);
			});
			
			$('#' + container).find('.text-load').remove();
			svg.transition().duration(1000).attr('opacity', 1);
			//线
			drawRoutePath(svg, stations);
			//点
			drawStationCircle(svg, stations);
			//两端弧线
			brackets(svg);
			//字
			drawText(svg, stations);
			//修正位置
			adjustTwoName(svg);
		}
	};
	
	var upLine = d3.svg.line().x(function(d) {
		return d.cx;
	}).y(function(d) {
		return mTop;
	});

	var downLine = d3.svg.line().x(function(d) {
		return d.cx;
	}).y(function(d) {
		return mTop + h;
	});
	
	 var line = d3.svg.line().x(function(d) {
			return d.attr('cx');
	}).y(function(d) {
			return d.attr('cy');
	});
	
	var circleClass = function(d, type, c){
		if(d.type == type){
			if(type == 1){
				c = 'up-circle-none';
			}
			else{
				c = 'down-circle-none';
			}
		}
		return c;
	}
	
	var getText = function(t){
		if (t.length > 7) {
			return t.substring(0, 7) + '·';
		}
		return t;
	}
	
	//画圆点
	var drawStationCircle = function(svg, stations){
		
		//上行
		svg.append('g').selectAll('circle').data(stations).enter().append('circle')
				.attr('cy', mTop)
				.attr('class', function(d){return circleClass(d, 1, 'station_circle')})
				.attr('cx', function(d, i) {
					return d.cx;
				});
		
		svg.append('g').selectAll('circle').data(stations).enter().append('circle')
				.attr('class', function(d, i){
					var classzz = circleClass(d, 1, 'up_station_circle_inside');
					if(i == 0)
						classzz += ' start';
					else if(i == stations.length - 1)
						classzz += ' end';
					
					return classzz;
				})
				.attr('cy', mTop)
				.attr('id', function(d){
					var id = d.id[0];
					return id;
				})
				.attr('cx', function(d, i) {
					return d.cx;
				});
		
		//下行 
		svg.append('g').selectAll('circle').data(stations).enter().append('circle')
				.attr('class', function(d){return circleClass(d, 0, 'station_circle')})
				.attr('cy', mTop + h)
				.attr('cx', function(d, i) {
					return d.cx;
				});
		svg.append('g').selectAll('circle').data(stations).enter().append('circle')
				.attr('class', function(d, i){
					var classzz = circleClass(d, 0, 'down_station_circle_inside');
					if(i == 0)
						classzz += ' start';
					else if(i == stations.length - 1)
						classzz += ' end';
					
					return classzz;
				})
				.attr('cy', mTop + h)
				.attr('cx', function(d, i) {
					return d.cx;
				})
				.attr('id', function(d){
					var id = d.id[1];
					return id;
				});
	}
	
	var brackets = function(svg){
		//左括号
		svg.append('g').append('path')
			.attr('d', function(){
				var up = svg.select('.up_station_circle_inside.start')
					,down = svg.select('.down_station_circle_inside.start');
				
				var upX = parseInt(up.attr('cx')) -5
					, upY =  parseInt(up.attr('cy')) + 8
					, downX = parseInt(down.attr('cx')) -5
					, downY = parseInt(down.attr('cy')) -8
					,arc = (upX - 18);
				return 'M' + upX + ',' + upY + ' C' + arc + ',' + (upY + 5) + ' ' + arc + ',' + (downY - 5) + ' ' + downX + ',' + downY;
			})
			.attr('class', 'up_path')
			.attr('fill', 'none'); 
			
	 	//右括号
		svg.append('g').append('path')
		.attr('d', function(){
			var up = svg.select('.up_station_circle_inside.end')
				,down = svg.select('.down_station_circle_inside.end');

			var upX = parseInt(up.attr('cx')) + 5
				, upY =  parseInt(up.attr('cy')) + 8
				, downX = parseInt(down.attr('cx')) + 5
				, downY = parseInt(down.attr('cy')) -8
				,arc = (upX + 18);
			return 'M' + upX + ',' + upY + ' C' + arc + ',' + (upY + 5) + ' ' + arc + ',' + (downY - 5) + ' ' + downX + ',' + downY;
		})
		.attr('class', 'down_path')
		.attr('fill', 'none');
	}
	
	//画线条
	var drawRoutePath = function(svg, stations){
		//上下行拆分数组
		var upArray = [], downArray = [];
		$.each(stations, function(i, st){
			if(st.type == 0)
				upArray.push(st);
			else if(st.type == 1)
				downArray.push(st);
			else if(st.type == 2){
				upArray.push(st);
				downArray.push(st);
			}
		});
		
		//上行线条
		svg.append('g').selectAll('path')
			.data(upArray.slice(0, upArray.length - 1)).enter().append('path')
			.attr('d', function(d, i) {
				return upLine([ d, upArray[i + 1] ]);
			})
			.attr('class', 'up_path')
			.attr('stroke-dasharray', function(d){
				if(d.clear == 10 || d.clear == 12){
					$(this).css('stroke-width', '5px');
					return '2,1';
				}
				return 0;
			}); 

		//下行线条
		svg.append('g').selectAll('path')
				.data(downArray.slice(0, downArray.length - 1)).enter().append('path')
				.attr('d', function(d, i) {
					return downLine([ d, downArray[i + 1] ]);
				})
				.attr('class', 'down_path')
				.attr('stroke-dasharray', function(d){//虚线
					if(d.clear == 11 || d.clear == 12){
						$(this).css('stroke-width', '5px');
						return '2,1';
					}
					return 0;
				}); 
	}
	
	//写文字
	var drawText = function(svg, stations){
		svg.append('g').selectAll('text').data(stations).enter()
		.append('text')
		.attr('y',
			function(d, i) {
				var t;
				if(d.type == 1)
					t = d.name[1];
				else
					t = d.name[0];
				return mTop + 5 + (h - (18 * (t.length > 7 ? 7 : t.length))) / 2;
			})
		.attr('class', function(d, i){
			var classz = 'station_text';
			if(i == 0)
				classz += ' start';
			else if(i == stations.length - 1)
				classz += ' end';
			return classz;
		})
		.text(function(d){
			if(d.type == 1)
				t = d.name[1];
			else
				t = d.name[0];
			
			if(d.type == 3)
				$(this).attr('type', 3).attr('downName', d.name[1]);
			return getText(t);
		})
		.attr('x', function(d, i) {
			return xScale(i);
		});
	}
	
	var adjustTwoName = function(svg){
		//上下行不同名
		var lastG = svg.append('g');
		$.each($('.station_text[type=3]'), function(i, obj){
			var x = parseInt($(obj).attr('x'))
				,diff = 8;
			
			lastG.append('text')
				.attr('y', function(){
					var t = $(obj).attr('downname');
					return mTop + 5 + (h - (18 * (t.length > 7 ? 7 : t.length))) / 2;
				})
				.attr('class', 'station_text')
				.attr('x', (x + diff))
				.attr('fill', 'red')
				.text(getText($(obj).attr('downname')));
			
			$(obj).attr('fill', '#337AB7')
				.removeAttr('type').removeAttr('downname')
				.attr('x', x - diff);
		});
	}
	
	return drawSvgObject;
})();