function plotgraph(canv,data,properties,hints){
	
	function drawgraph(xpos,ypos){
		/*
		* xpos - позиция мышки Х
		* ypos - позиция мышки Y
		*/
		
		//находим максимальный элемент в данных
		var max_point = 0;
		for(j = 0; j < data.graph.length; j++){
			for(i = 0;i < data.graph[j].point.length; i++){
				if(max_point < data.graph[j].point[i].val){
					max_point = data.graph[j].point[i].val;
				}
			}
		}
		
		//масштабируем максимальное значение
		mxpos = 5;
		i=1;
		while(max_point > mxpos){
			if(i < 3){
				mxpos = mxpos*2;
			}
			else if(i == 3){
				mxpos = 50;
			}
			else if(i < 7 && i > 3){
				mxpos = mxpos*2;
			}
			else if(i == 7){
				mxpos = 500;
			}
			else{
				mxpos = mxpos + 500;
			}
			i++
		}
		max_point = mxpos;
		
		//определяем канвас его высоту и ширину неизменяемые переменные
		var canvas = $(canv)[0];
		var cwidth = canvas.width;
		var cheight = canvas.height;
		canvas = canvas.getContext("2d");
		
		//определяем количество пикселей в одном делений по вертикали и горизонтали
		var vrazmpx = (cheight-20)/max_point;
		var grazmpx = (cwidth)/data.graph[0].point.length + ((cwidth)/data.graph[0].point.length)/(data.graph[0].point.length-1) - 20/data.graph[0].point.length;
		
		//определяем переменные которые будут передоваться
		
		//рисуем сетку
			//заливаем
			canvas.fillStyle   = properties.background; //цвет фона
			canvas.strokeStyle = properties.linescolor; //цвет линий
			canvas.fillRect(0,0,cwidth,cheight);
			canvas.lineWidth = properties.lineswidth; 


	//[ рисуем прозрачный фон под графиком
		for(j = 0; j < data.graph.length; j++){
			
			canvas.strokeStyle = data.graph[j].properties.linecolor;
			canvas.fillStyle = data.graph[j].properties.spacecolor;
			canvas.globalAlpha = data.graph[j].properties.spacealpha;
			
			canvas.beginPath();
			canvas.moveTo(10,cheight);
			for(i=0;i<data.graph[j].point.length;i++){
				if(i != data.graph[j].point.length - 1){
					canvas.lineTo(grazmpx*i + 10,cheight - data.graph[j].point[i].val*vrazmpx);
				}
				else{
					if(grazmpx*i+10 > cwidth - 10){
						canvas.lineTo(cwidth - 10,cheight - data.graph[j].point[i].val*vrazmpx);
					}
				}
			}
			if(grazmpx*i+10 > cwidth - 10){
				canvas.lineTo(cwidth - 10,cheight);
			}
			else{
				canvas.lineTo(grazmpx*(i-1) + 10,cheight);
			}
			canvas.closePath();
			canvas.fill();
		}
		canvas.globalAlpha = 1;
	//] (конец) рисуем прозрачный фон под графиком	
		
			canvas.fillStyle   = properties.background; //цвет фона
			canvas.strokeStyle = properties.linescolor; //цвет линий
			
			canvas.beginPath();
			
			//рисуем 1ну линию по горизонтали
			canvas.moveTo(0,vrazmpx*(max_point/2) + 0.5 + 20);
			canvas.lineTo(cwidth,vrazmpx*(max_point/2) + 0.5 + 20);
			
			//рисуем вертикальные линии с текстом
			vlinewidth = 0;
			canvas.fillStyle = properties.verticalfontcolor;
			canvas.font = properties.verticalfont;
			
			for(i = 0; i < data.graph[0].point.length; i++){
				
				vlinewidth = vlinewidth + grazmpx;

				if(vlinewidth > properties.gridwidth && cwidth-grazmpx*i > properties.gridwidth ){
					canvas.moveTo(grazmpx*i + 10.5, 0);
					canvas.lineTo(grazmpx*i + 10.5,cheight);

					vlinewidth = 0;

					//пишем текст снизу возле горизонтальных линий
					if(i != 0 && i != data.graph[0].point.length){
						canvas.fillText(data.graph[0].point[i].gval, grazmpx*i + 13.5, cheight - 3);
					}
				}
			}
			canvas.closePath();
			canvas.stroke();
			
			//пишем текст на горизонтальной линии
			canvas.fillStyle = properties.gorizontfontcolor;
			canvas.font = properties.gorizontfont;
			
			canvas.fillText(max_point, 1 , properties.gorizontfont.match(/[0-9]+/i)*1);
			canvas.fillText(max_point/2 , 1 , vrazmpx*(max_point/2) + properties.gorizontfont.match(/[0-9]+/i)*1 + 20); 
			
			canvas.textAlign = 'right';
			canvas.fillText(max_point/2, cwidth-1, vrazmpx*(max_point/2) + properties.gorizontfont.match(/[0-9]+/i)*1 + 20);
			canvas.fillText(max_point, cwidth-1, properties.gorizontfont.match(/[0-9]+/i)*1);
			canvas.textAlign = 'left';
			
		
		//рисуем линии соединяющие точки
		for(j = 0; j < data.graph.length; j++){
			
			canvas.lineWidth = data.graph[j].properties.linewidth;
			canvas.strokeStyle = data.graph[j].properties.linecolor;
			
			canvas.beginPath();
			for(i=0; i < data.graph[j].point.length; i++){
				if(i != data.graph[j].point.length - 1){
					canvas.lineTo(grazmpx*i + 10,cheight - data.graph[j].point[i].val*vrazmpx);
				}
				else{
					if(grazmpx*i+10 > cwidth - 10){
						canvas.lineTo(cwidth - 10,cheight - data.graph[j].point[i].val*vrazmpx);
					}
				}
			}
			canvas.stroke();
		}
		
		//стрим точки
		for(j = 0; j < data.graph.length; j++){
			
			canvas.fillStyle = data.graph[j].properties.pointcolor;
			var pointradius = data.graph[j].properties.pointradius;
			var pradius = data.graph[j].properties.pointradius;
			var activepointradius = data.graph[j].properties.activepointwidth;
			
			for(i=0;i < data.graph[j].point.length;i++){
				
				canvas.beginPath();
				
				//смотрим активна точка или нет
				if( (xpos > (grazmpx*i - grazmpx/2)) && (xpos < (grazmpx*i + grazmpx/2)) && (xpos != 0) && (ypos != 0) ){
					pradius = activepointradius;
				}
				else{
					pradius = pointradius;
				}
				
				if(i != data.graph[0].point.length - 1){
					canvas.arc(grazmpx*i + 10,cheight - data.graph[j].point[i].val*vrazmpx,pradius,0,2*Math.PI,true);
				}
				else{
					if(grazmpx*i+10 > cwidth - 10){
						canvas.arc(cwidth - 10,cheight - data.graph[j].point[i].val*vrazmpx,pradius,0,2*Math.PI,true);
					}
				}
				canvas.closePath();
				canvas.fill();
			}
		}
			
		//функция рисует прямоугольник с закругленными углами
		function roundRect(x, y, width, height, radius, fill, stroke){
			
			if (typeof stroke == "undefined" ) {
				stroke = true;
			}
			if (typeof radius === "undefined") {
				radius = 5;
			}
			canvas.beginPath();
			
			canvas.moveTo(x + radius, y);
			canvas.lineTo(x + width - radius, y);
			canvas.quadraticCurveTo(x + width, y, x + width, y + radius);
			canvas.lineTo(x + width, y + height - radius);
			canvas.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
			canvas.lineTo(x + radius, y + height);
			canvas.quadraticCurveTo(x, y + height, x, y + height - radius);
			canvas.lineTo(x, y + radius);
			canvas.quadraticCurveTo(x, y, x + radius, y);
			
			canvas.closePath();
			
			if (stroke) {
				canvas.stroke();
			}
			if (fill) {
				canvas.fill();
			}        

		}
		
	//[ рисуем подзказки
		canvas.lineWidth = hints.borderwidth;
		canvas.strokeStyle = hints.bordercolor;
		canvas.fillStyle = hints.background;
		
		//-вложенный цикл для определения некотрых переменных
		var lines = []; //массив в котором будут храниться строки
		var pointpos = 0;
		for(j = 0; j < data.graph.length; j++){
			for(i = 0; i < data.graph[j].point.length; i++){

			//смотрим активна точка или нет
				if( (xpos > (grazmpx*i - grazmpx/2)) && (xpos < (grazmpx*i + grazmpx/2)) && xpos != 0 && ypos != 0){
					
					var tstring = data.graph[j].point[i].desc.split(' /n ');
					pointpos = i;

					for(t = 0; t < tstring.length; t++){
						lines.push(tstring[t]);
					}
				}			
			}
		}
		
		//определяем высоту и ширину прямоугольника
		var recwidth = 0; //ширина прямоугольника
		var recheight = 0; //высота прямоугольника
		for(i = 0; i < lines.length; i++){
			
			var fontstyle = hints.font[i].font;
			canvas.font = fontstyle;
			
			var atext = canvas.measureText(lines[i]);
			
			if(recwidth < atext.width){
				recwidth = atext.width;
			}
			
			recheight = recheight + fontstyle.match(/[0-9]+/i)*1; //высота прямоугольника
		}
		recheight = recheight + (lines.length + 1) * hints.lineheight + hints.paddingtb * 2 + hints.borderwidth*2; //добрвляем отступы к высоте прямоугольника
		recwidth = recwidth + hints.paddinglr * 2 + hints.borderwidth*2; //добовляем отступы по бокам к прямоугольнику
		
		var recxpos = grazmpx*pointpos - recwidth; //позиция X прямоугольника
		var recypos = cheight - data.graph[0].point[pointpos].val*vrazmpx  - recheight/2; //позиция Y прямоугольника
		
		
		//рисуем подсказки
		if(lines.length != 0){
			//проверяем не вылез ли прямоугольник за рамки
			if(recxpos < 0){
				recxpos = grazmpx*pointpos + 20;
			}
			if(recypos < 0){
				recypos = 2;
			}
			else if(recypos + recheight > cheight){
				recypos = cheight - recheight - 4;
			}
			roundRect(recxpos, recypos, recwidth, recheight, hints.borderradius, true, true);
			
			//пишем текст в прямоугольнике
			var tecypos = recypos + hints.paddingtb;
			for(i = 0; i < lines.length; i++){
				canvas.font = hints.font[i].font;
				tecypos = tecypos + hints.font[i].font.match(/[0-9]+/i)*1 + hints.lineheight;
				canvas.fillStyle = hints.font[i].color;
				canvas.fillText(lines[i], recxpos + hints.paddinglr, tecypos);
			}
		}
	//] (конец) рисуем подзказки		
		
	}//end plotgraph
	
	$(canv).mousemove(function(event){
		var offset = $(this).offset();
		
		var xpos = event.pageX - offset.left;
		var ypos = event.pageY - offset.top;

		drawgraph(xpos,ypos);
	});
	
	$(canv).mouseleave(function(){
		
		drawgraph(0,0);
		
	});
	
	drawgraph(0,0);
	
}