Source: drawSvg.js

/**
 * Get the size of the svg based on the no. of rows and row length and other parameter.,.
 * @param {Object} parameters - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * prsm is an json attribute insire prsm_data(Global data variable from prsm.js)
 */
function getSvgSize(parameters,prsm)
{
	let num_of_rows = getNumOfRows(parameters,prsm) ;
	let no_of_blocks = parameters.row_length/parameters.block_length - 1 ;
	let width = parameters.letter_width * (parameters.row_length - 1)+ (no_of_blocks)*parameters.gap_width + parameters.right_margin + parameters.left_margin;
	if(parameters.show_num)
	{
		width = width + parameters.numerical_width * 2 ;
	}
	if(isShiftAnnotationNeeded(parameters,prsm))
	{
		parameters.row_height = parameters.row_height + 0.2*parameters.row_height;
		parameters.top_margin = 45 ;
	}
	let height = parameters.row_height * num_of_rows + parameters.bottom_margin + parameters.top_margin ;
	let first_position,last_position,start_info = null ,end_info = null ;
	[parameters,first_position, last_position,start_info,end_info] = skip_list(parameters,prsm);
	return [width,height];
}
/**
 * Get number of rows of the sequence based on the row length
 * @param {Object} parameters - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * prsm is an json attribute insire prsm_data(Global data variable from prsm.js)
 */
function getNumOfRows(parameters,prsm)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	[parameters,first_position, last_position,start_info,end_info] = skip_list(parameters,prsm);
	let new_sequence_length = last_position - first_position ;
	let num_of_rows = parseInt(new_sequence_length/parameters.row_length) ;
	let skip_acid_count = 0 ;
	if((start_info != null || end_info != null)&& parameters.show_skipped_lines)
	{
		skip_acid_count = skip_acid_count + 1;
	}
	num_of_rows = num_of_rows + skip_acid_count;
	return num_of_rows ;
}
/**
 * draw the sequence on to svg
 * @param {Object} parameters - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {String} id - Contians id of the SVG tag from html.
 */
function buildSvg(parameters,prsm,id)
{
	let first_residue_position = parseInt(prsm.annotated_protein.annotation.first_residue_position) ;
	let last_residue_position = parseInt(prsm.annotated_protein.annotation.last_residue_position) ;
	let seqlength = parseInt(prsm.annotated_protein.annotation.protein_length) ;
	// Accomodate large numerical number at the start and end of the sequence without getting trimmed by adding extra margin values
	if(seqlength >= 1000)
	{
		parameters.left_margin = parameters.left_margin + parameters.font_width ;
		parameters.right_margin = parameters.right_margin + parameters.font_width ;
	}
	let width,height ;
	[width,height] = getSvgSize(parameters,prsm) ;
	// create a group under svg with svgId_g
	let id_temp = id + "_g" ;
	let svgContainer = d3.select("#"+id).attr("width",width)
									.attr("height",height)
									.attr("font-family","'FreeMono',Miltonian,monospace")
									.attr("font-size","16px")
									.style("fill", parameters.svgBackground_color)
	svgContainer = svgContainer.append("g")
								.attr("id",id_temp)
								.attr("class",id_temp);
	text = 	svgContainer.selectAll("text");
	let first_position,last_position,start_info = null ,end_info = null ;
	//	Get the new first and last position based on the amount of acids are needed to be skipped 
	[parameters,first_position, last_position,start_info,end_info] = skip_list(parameters,prsm);
	
	prsm.annotated_protein.annotation.residue.forEach(function(input,index){
		if(parseInt(input.position) >= first_position && parseInt(input.position) < last_position )
		{
			let x,y ;
			//	Get the x and y coordinates of the acid position	
			[x,y] = calibrateCoordinates(parameters,parseInt(input.position),first_position) ;
			text.data(input.acid)
				.enter()
				.append("text")
				.attr("id",function(d,i){
					return "id_"+id_temp+"_"+input.position ;
				})
				.attr("x", function(d,i){ 
					return x ;
				})
				.attr("y", function(d,i){ 
					return y ;
				})
				.text(function(d,i){
					return d ;
				})
				.style("fill", function(d,i){
					if(parseInt(input.position) < first_residue_position || parseInt(input.position) > last_residue_position)
					{
						return "grey" ;
					}
					else
					{
						return "black" ;
					}
				})
		}
	});
	return [parameters,id] ;
}

/**
 * Get the terminated/skipped acid information on to the svg
 * @param {Object} parameters - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {String} id - Contians id of the SVG tag from html.
 */
function skippedAcidNotification(parameters,prsm,id)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	//	Get the new first and last position based on the amount of acids are needed to be skipped
	[parameters,first_position, last_position,start_info,end_info] = skip_list(parameters,prsm);
	let svgContainer = d3.select("#"+id+"_g") ;
	let x,y ;
	if(parameters.show_skipped_lines)
	{
		if(!(start_info == null))
		{
			//	Get the coordinates to write the skip information at the start of acid
			[x,y] = calibrateSkipStart(parameters) ;
			svgContainer.append("text")
				.attr("x", x)
				.attr("y", y)
				.style("fill","black")
				.text(start_info);
		}
		if(end_info != null)
		{
			//	Get the coordinates to write the skip information at the end of acid
			[x,y] = calibrateSkipEnd(parameters,last_position,first_position) ;
			svgContainer.append("text")
			.attr("x", x)
			.attr("y", y)
			.style("fill","black")
			.text(end_info) ;
		}
	}
}
/**
 * Put the numerical positions at the start and end of each row of the sequence
 * @param {*} para Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {String} id - Contians id of the SVG tag from html.
 */
function getNumValues(para,prsm,id)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	//	Get the new first and last position based on the amount of acids are needed to be skipped
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	let svgContainer = d3.select("#"+id+"_g") ;
	prsm.annotated_protein.annotation.residue.forEach(function(input,index){
		if(parseInt(input.position) >= first_position && parseInt(input.position) < last_position )
		{
			let x,y ;
			l_position_temp = input.position ;
			//	write the numerical values only at the start position and end position(this is in the
			// 	form of 29,59 etc.,. as the data starts with 0 as 1st element)
			if(parseInt(l_position_temp)%(para.row_length) ==  0 || parseInt(l_position_temp)%(para.row_length)  ==  (para.row_length-1) 
									|| parseInt(l_position_temp) == (last_position-1))
			{
				let id_temp ;
				position = parseInt(input.position) +1;
				if(parseInt(input.position)%para.row_length ==  0)
				{
					//	Get the coordinates of left numerical
					[x,y] = calibrateLeftNum(para,parseInt(l_position_temp),first_position) ;
					x = x ;
					id_temp = "left_align" ;
				}
				else
				{
					//	Get the coordinates of right numerical
					[x,y] = calibrateRightNum(para,parseInt(l_position_temp),first_position) ;
					id_temp = "right_align" ;
				}
				svgContainer.append("text")
					.attr("id", id_temp)
					.attr("x",x)
					.attr("y",y)
					.text(function(d,i){
						return position ;
					})
					.style("text-anchor",function(d,i){
						//	Align the left numerical towards left side
						if(id_temp == "left_align")
						{
							return "end" ;
						}
						return null ;
					})
					.style("fill", "black");
				
				if(parseInt(l_position_temp) == (last_position-1) && last_position%(para.row_length) ==  1)
				{
					[x,y] = calibrateRightNum(para,parseInt(l_position_temp),first_position) ;
					id_temp = "right_align" ;
					svgContainer.append("text")
					.attr("id", id_temp)
					.attr("x",x)
					.attr("y",y)
					.text(function(d,i){
						return position ;
					})
					.style("fill", "black");
				}
			}
		}
	})
}
/**
 * Draw annotations
 * @param {Object} para Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {String} id - Contians id of the SVG tag from html.
 */
function annotations(para,prsm,id)
{
	/*	Get annotation position	and information */
	var annotations = json2CleavagePositions(prsm) ;
	/* 	Drawing Annotation on to screen using D3 polyline	*/
	annotations.forEach(function(annotation,index){
		let l_charge = getIonCharge(annotations,annotation.position);
		
		if(annotation.exist_n_ion == "1" && annotation.exist_c_ion == "1")
		{
			drawAnnotation_YB(para,prsm,annotation,l_charge,id) ;
		}
		else
		{
			if(annotation.exist_n_ion == "1")
			{
				drawAnnotation_B(para,prsm,annotation,l_charge,id) ;
			} 
			if(annotation.exist_c_ion == "1")
			{
				drawAnnotation_Y(para,prsm,annotation,l_charge,id) ;
			}
		}
	})
}
/**
 * Invoke drawAnnotation method to draw the annotation when the ion type is B
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {Object} annotation - Json object with information of the position
 * @param {String} l_charge - Contains the Charge to be displayed on the annotation
 * @param {String} id - Contians id of the SVG tag from html.
 */
function drawAnnotation_B(para,prsm,annotation,l_charge,id)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	let x,y ;
	[x,y] = calibrateCoordinates(para,parseInt(annotation.position)-1,first_position);
	x = x + (para.letter_width/2) ;
	// Setting polyline coordinates
	let coordinates = (x-2)+","+(y-13)+ " " +(x+4)+","+ (y-11)+" "+(x+4)+","+(y+2);
	
	drawAnnotation(annotation,l_charge,id,coordinates,x,y);
}
/**
 * Invoke drawAnnotation method to draw the annotation when the ion type is Y
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {Object} annotation - Json object with information of the position
 * @param {String} l_charge - Contains the Charge to be displayed on the annotation
 * @param {String} id - Contians id of the SVG tag from html.
 */
function drawAnnotation_Y(para,prsm,annotation,l_charge,id)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	let x,y ;
	[x,y] = calibrateCoordinates(para,parseInt(annotation.position)-1,first_position);
	x = x + (para.letter_width/2) ;
	// Setting polyline coordinates
	let coordinates = (x+4)+","+ (y-11)+" "+(x+4)+","+(y+2)+ " "+(x+10) + ","+(y+5);
	drawAnnotation(annotation,l_charge,id,coordinates,x,y);
	
}
/**
 * invoke drawAnnotation method to draw the annotation when the ion type is Y and B
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {Object} annotation - Json object with information of the position
 * @param {String} l_charge - Contains the Charge to be displayed on the annotation
 * @param {String} id - Contians id of the SVG tag from html.
 */
function drawAnnotation_YB(para,prsm,annotation,l_charge,id)
{
	let first_position,last_position,start_info = null ,end_info = null ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	let x,y ;
	[x,y] = calibrateCoordinates(para,parseInt(annotation.position)-1,first_position);
	x = x + (para.letter_width/2) ;
	// Setting polyline coordinates
	let coordinates =  (x-2)+","+(y-13)+ " " + (x+4)+","+ (y-11)+" "+(x+4)+","+(y+2)+ " "+(x+10) + ","+(y+5);
	drawAnnotation(annotation,l_charge,id,coordinates,x,y);
}
/**
 * Function to draw the annotations based on annotation type and coordinates
 * @param {Object} annotation - Json object with information of the position
 * @param {String} l_charge - Contains the Charge to be displayed on the annotation
 * @param {String} id - Contians id of the SVG tag from html.
 * @param {String} coordinates - Contains String with coordinates to draw a polyline in a apecific format understandable by D3
 * @param {Integer} x - Contains x coordinate to draw a tooltip at specific position on hover of annotation
 * @param {Integer} y - Contains y coordinate to draw a tooltip at specific position on hover of annotation
 */
function drawAnnotation(annotation,l_charge,id,coordinates,x,y)
{
	let svgContainer = d3.select("#"+id+"_g");
	svgContainer.append("polyline")
				.attr("points", coordinates)
				.style("fill", "none")
				.style("stroke", "1e90ff")
				.style("stroke-width", "1");	
		/*	Rectangle to have flexible on click and on mouse actions	*/
	svgContainer.append("rect")
				.attr("id","annoTooltip")
				.attr("x", x)
				.attr("y", y-14)
				.attr("width", 13)
				.attr("height", 23)
				.style("opacity", 0)
				.attr("cursor", "pointer")
				.on("click",function(){
					if(id == "l_svg")
					{
						input = annotation.ion_position;
						showIonPeaks(input);
					}
				})
				.on("mouseover", function(){
					appendTooltip(l_charge);
				})
				.on("mouseout", function(d){
					removeToolTip();	
				});
}
/**
 * Function to add tooltip to the polylines on mouseOver
 * @param {String} charge - Contains consolidated charge to display on tooltip
 */
function appendTooltip(charge)
{
	var div = d3.select("body").append("div")	
								.attr("class", "tooltip")				
								.style("opacity", 0); 
		div.transition()		
			.duration(10)		
			.style("opacity", .9);
		div.html(charge)	
		.style("left", (d3.event.pageX)  + "px")		
		.style("top", (d3.event.pageY - 28)+ "px") ;
}
/**
 * Function to remove tooltip to the polylines on mouseOver
 */
function removeToolTip()
{
	d3.selectAll(".tooltip").remove();
}
/**
 * Function to show the notification text at the top and bottom of the SVG sequence SVG of skipped amino acids
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 */
function skip_list(para,prsm)
{
	let l_afirst_residue_position = parseInt(prsm.annotated_protein.annotation.first_residue_position) ;
	let l_alast_residue_position = parseInt(prsm.annotated_protein.annotation.last_residue_position) ;	
	let l_asequence_length = parseInt(prsm.annotated_protein.annotation.protein_length) ;
	let new_first_position = 0 ;
	let initial_skip_count = 0 ;
	let start_info = null ;
	if(l_afirst_residue_position > (parseInt(para.row_length) + l_afirst_residue_position%parseInt(para.row_length) ) )
	{
		new_first_position = l_afirst_residue_position - ((l_afirst_residue_position%para.row_length)+para.row_length );
		initial_skip_count = new_first_position ;
		start_info = "... "+initial_skip_count + " amino acid residues are skipped at the N-terminus ... ";
	}
	let new_last_position = l_alast_residue_position + 1 ;
	let final_skip_count = 0 ;
	let end_info = null ;
	if(l_alast_residue_position+(para.row_length - (l_alast_residue_position%para.row_length) +para.row_length) < l_asequence_length)
	{
		new_last_position = l_alast_residue_position+( para.row_length - (l_alast_residue_position%para.row_length) + para.row_length)  ;
		end_skip_count = l_asequence_length-new_last_position ;
		end_info = "... "+end_skip_count + " amino acid residues are skipped at the C-terminus ... ";
	}
	else if(l_alast_residue_position+1 < l_asequence_length)
	{
		new_last_position = l_asequence_length ;
	}
	return[para,new_first_position,new_last_position,start_info,end_info];
}
 /**
  * Draw the annotations to show the start and end position of the sequence
  * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
  * @param {Object} prsm - Contains the complete information of prsm. 
  * @param {String} id - Contians id of the SVG tag from html.
  */
function drawAnnoOfStartEndPosition(para,prsm,id)
{
	let first_residue_position = parseInt(prsm.annotated_protein.annotation.first_residue_position) ;
	let last_residue_position = parseInt(prsm.annotated_protein.annotation.last_residue_position) ;
	let sequence_length = parseInt(prsm.annotated_protein.annotation.protein_length) ;
	let first_position,last_position,start_info = null ,end_info = null ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	let svgContainer = d3.select("#"+id+"_g");
	if(first_residue_position != 0)
	{
		let x,y ;
		[x,y] = calibrateCoordinates(para, first_residue_position-1, first_position );
		x = x + (para.letter_width/2) ;
		let first_position_coordinates = (x)+","+(y+2)+ " " +(x+5)+","+ (y+2)+" "+(x+5)+","+(y-12)+ " "+(x) + ","+(y-12);
		svgContainer.append("polyline")
					.attr("class","none")
					.attr("points", first_position_coordinates)
					.style("fill", "none")
					.style("stroke", "red")
					.style("stroke-width", "1.3") ;
	}
	if((sequence_length != last_residue_position +1 ) )
	{
		let x,y ;
		[x,y] = calibrateCoordinates(para, last_residue_position, first_position );
		x = x + (para.letter_width/2) ;
		let first_position_coordinates = (x+7)+","+(y-12)+ " " +(x+2)+","+ (y-12)+" "+(x+2)+","+(y+2)+ " "+(x+7) + ","+(y+2);
		svgContainer.append("polyline")
					.attr("class","none")
					.attr("points", first_position_coordinates)
					.style("fill", "none")
					.style("stroke", "red")
					.style("stroke-width", "1.3") ;
	}
}
 /**
  * Color the background of the occurence
  * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
  * @param {Object} prsm - Contains the complete information of prsm. 
  * @param {String} id - Contians id of the SVG tag from html.
  */
function massShiftBackgroundColor(para,prsm,id)
{
	let Background_color = json2BackgroundColorArray(prsm);
	let non_data_indicator = false ;
	let first_position,last_position,start_info = null ,end_info = null ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	Background_color.forEach(function(input,index){
		let left_position = parseInt(input.left_position) ;
		let right_position = parseInt(input.right_position) ;
		let annotation = input.anno ;
		let isShiftNeeded = shiftAnnotation(para,prsm,index) ;
		while(left_position < right_position)
		{
			let leftPosition, rightPosition ;
			[leftPosition,rightPosition] = getRightPosition(para,left_position,right_position) ;
			rightPosition = rightPosition - 1 ;
			let x,y;
			[x,y] = calibrateCoordinates(para, leftPosition ,first_position);
			let x1,y1;
			[x1,y1] = calibrateCoordinates(para, rightPosition ,first_position);
			let width = x1-x;
			rect_Backgroundcolor(x,y,id,width,para);
			MassShift(x,y,id,annotation,isShiftNeeded);
			left_position = parseInt(rightPosition) + 1 ;
			annotation = "";
			//break ;
		}
	})
	
}
/**
 * Get the right end position to color the background color when there is a change of row
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Integer} leftPosition - Contains start position of acid to add color to the background
 * @param {Integer} rightPosition - Contains end position of the acid to add color to the background
 */
function getRightPosition(para,leftPosition, rightPosition)
{
	if( parseInt(rightPosition/para.row_length) > parseInt(leftPosition/para.row_length) )
	{
		rightPosition = (parseInt(leftPosition/para.row_length)+1)*para.row_length ;
	}
	
	return [leftPosition, rightPosition] ;
}
/**
 * Modifying the color array to match the array of letters and positions
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {String} id - Contians id of the SVG tag from html.
 */
function addColorToFixedPtms(prsm,id){
	let known_Change = json2FixedPtmOccurence(prsm);
	known_Change.forEach(function(position,i){
		l_class_id ="#id_"+id+"_g_"+position ;
		d3.select(l_class_id)
			.style("fill", "red")
	})
}
/**
 * Get the charge of the Ion by consilidating all the prefix and the charges at that position
 * @param {Array} l_annotation_array - Contains charges at all the positions of the acids
 * @param {Integer} position - Current position at which the chage has to be displayed on tooltip
 */
function getIonCharge(l_annotation_array,position){
	let l_charge = "";
	for(let j=0;j<l_annotation_array.length;j++){
		if(position == l_annotation_array[j].position )
		{
			 l_charge = l_charge + l_annotation_array[j].ion_type+l_annotation_array[j].ion_display_position
			 						+" "+l_annotation_array[j].peak_charge+"+ " ;
		}
	}
	return l_charge ;
}

/**
 * Code to color the background of a occurence acids
 * @param {Integer} x - Contains x coordinate of the start postion to add background color
 * @param {Integer} y - Contains y coordinate of the end position to add background color
 * @param {String} id - Contains id of the SVG tag from html.
 * @param {Integer} width - Contains width to whuich backgroud color has to be added
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 */
function rect_Backgroundcolor(x,y,id,width,para){
	/*	font-size 16px is equal to 12pt	*/
	let font_width = 12 ;
	/*	to draw the rect color uniformly */
	let font_height = 15 ;
	let svgContainer = d3.select("#"+id+"_g");
	svgContainer.append("rect")
					.attr("x", x)
					.attr("y", y-font_height)
					.attr("width", width+font_width)
					.attr("height", 20)
					.attr("dy", "0em")
					.style("fill", para.background_color)
					.style("fill-opacity", ".4")
					.style("stroke-width", "1.5px");
}
/**
 * MassShift value at the top of the acids
 * @param {Integer} x - Contains x coordinate at which the mass shift is added on top of acid 
 * @param {Integer} y - Contains y coordinate at which the mass shift is added on top of acid
 * @param {String} id - Contains id of the SVG tag from html.
 * @param {String} value - Contains Value to be displyed on the acid
 * @param {Boolean} isShift - Contains true if mass shifts adjacent to each other are overlapping
 */
function MassShift(x,y,id,value,isShift)
{
	let dy = -1.2 ;
	// If Adjacent mass shifts are overlapping, an additional shift is provided to not overlap
	if(isShift)
	{
		dy = 1.7*dy ;
	}
	dy = dy+"em" ;
	let svgContainer = d3.select("#"+id+"_g");
	svgContainer.append("text")
				   .attr("x", x)
				   .attr("y", y)
				   .attr("dy", dy) 
				   .text(function(){
					   return value ;
				   })
					.attr("fill","black")
				   .attr("font-size","15px");
}
/**
 * shift the position of the mass shift when overlapping one another
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm. 
 * @param {Integer} index - Current index form the list of annotations
 */
function shiftAnnotation(para,prsm,index)
{
	let isshiftNeeded = false ;
	let bgColorAndMassShift = json2BackgroundColorArray(prsm) ; 
	/*	font-size 16px is equal to 12pt*/
	let font_width = 12 ;
	let first_position, last_position,start_info,end_info ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	for(let i = 1; i<bgColorAndMassShift.length;i++)
	{
		if(i == index)
		{
			let x1,y1 ;
			[x1,y1] = calibrateCoordinates(para,parseInt(bgColorAndMassShift[i].left_position),first_position) ;
			
			let x2,y2 ;
			[x2,y2] = calibrateCoordinates(para,parseInt(bgColorAndMassShift[i-1].left_position),first_position) ;
			/* subtract -2 for CSS and alignment purpose*/
			if((Math.abs(x2-x1) + font_width )< bgColorAndMassShift[i-1].anno.length*(font_width-2) )
			{
				isshiftNeeded = true ;
			}
		}
	}
	return isshiftNeeded ;
}
/**
 * Check if over shifting is need when annotations collide with each other
 * @param {Object} para - Contains parameters of width, letter space etc., to draw SVG
 * @param {Object} prsm - Contains the complete information of prsm.  
 */
function isShiftAnnotationNeeded(para,prsm)
{
	let isshiftNeeded = false ;
	let bgColorAndMassShift = json2BackgroundColorArray(prsm) ; 
	/*	font-size 16px is equal to 12pt*/
	let font_width = 12 ;
	let first_position, last_position,start_info,end_info ;
	[para,first_position, last_position,start_info,end_info] = skip_list(para,prsm);
	for(let i = 1; i<bgColorAndMassShift.length;i++)
	{
			let x1,y1 ;
			[x1,y1] = calibrateCoordinates(para,parseInt(bgColorAndMassShift[i].left_position),first_position) ;
			
			let x2,y2 ;
			[x2,y2] = calibrateCoordinates(para,parseInt(bgColorAndMassShift[i-1].left_position),first_position) ;
			/* subtract -2 for CSS and alignment purpose*/
			if((Math.abs(x2-x1) + font_width )< bgColorAndMassShift[i-1].anno.length*(font_width-2) )
			{
				isshiftNeeded = true ;
				break ;
			}
	}
	return isshiftNeeded ;
}