Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

diokhan

grafico com tamanho dinamico

Mensagens Recomendadas

diokhan

boas, eu tenho este código que faz um gráfico em GD:

function GraphPatent($id)
	{
		try {
		    $stmt = $this->dbh->prepare("SELECT B.Q_START_BLAST, B.Q_END_BLAST, B.EVALUE,
		    							B.ACCESSION_ID, P.LENGTH_PROTEIN FROM PROTEIN AS P
										Inner Join BLAST AS B ON B.ID_PROTEIN = P.ID_PROTEIN
										Inner Join BLAST_NAME_DB AS BN ON BN.ID_BLAST_DB = B.ID_BLAST_DB
										WHERE P.ID_PROTEIN = :id AND BN.DESCRIPTION LIKE '%pat%'
										LIMIT 0, 20");
			$stmt->bindParam(':id', $id);
		    $stmt->execute();

		} catch (PDOException $e) {
			return -1;
		    echo 'Query error: ' . $e->getMessage();
		}

		$count = $stmt->rowCount();
       	$stmt->closeCursor();

       	if (empty($count))
       	{
       		return 0;
       		exit;
       	}else{

       		$stmt2 = $this->dbh->prepare("SELECT P.LENGTH_PROTEIN FROM PROTEIN AS P WHERE P.ID_PROTEIN = :id");
       		$stmt2->bindParam(':id', $id);
		    $stmt2->execute();

		    $result = $stmt2->fetch(PDO::FETCH_BOTH);
       		// altura e largura da imagem
       		$iw = 800;
			$ih = $count * 35 + 55;
			// margem geral da imagem
			$gm = 20;
			// escala da timeline em px
			$ts = 40;


			// escala de referencia
			$scale = 20;
			// factor de diferenca entre escala em px e escala de referencia
			$fscale = 2;
			// escala maxima de referencia
			$mscale = ceil($result['LENGTH_PROTEIN']) + 40;

		    // fontes
			$fonts['arial'] = './Fonts/arial.ttf';
			$fonts['tahoma'] = './Fonts/tahoma.ttf';

			// cria a imagem
			$img = imagecreatetruecolor($iw, $ih);

			// define as cores
			$colors2['white'] = imagecolorallocate($img, 255, 255, 255); // white background graph
			$colors2['grey'] = imagecolorallocate($img, 235, 235, 235); // grey back graph
			$colors['black'] = imagecolorallocate($img, 0, 0, 0);
			$colors['blue'] = imagecolorallocate($img, 16, 78, 139);
			$colors['green'] = imagecolorallocate($img, 0, 128, 0);
			$colors['grey'] = imagecolorallocate($img, 139, 139, 131);
			$colors['red'] = imagecolorallocate($img, 205, 0, 0);

			$radius = 3;
			$rad = 20;
			$drawGraph = new Graphs;

			// preenche o background
			imagefilledrectangle($img, 0, 0, $iw, $ih, $colors2['grey']);
			$graphDraw = $drawGraph->imagefillroundedrect($img, 0, 0, $iw, $ih, $rad, $colors2['white']);

			// preenche a linha principal da timeline
			imagefilledrectangle($img, $gm, $gm, $iw-$mscale, $gm+1, $colors['black']);

			// preenche a escala da timeline
			$x = $gm;
			$s = 0;
			while($s <= ($mscale))
			{
				imagefilledrectangle($img, $x, $gm, $x+1, $gm+7, $colors['black']);
				if ($s < 10)
					$tmargin = $x-1;
				elseif ($s < 100)
					$tmargin = $x-3;
				else
					$tmargin = $x-6;
				imagefttext($img, 8, 0, $tmargin, $gm+20, $colors['red'], $fonts['tahoma'], $s);
				$s = $s+$scale;
				$x = $x+$ts;
			}

       	// busca valores do blast patenteado
       		try
			{
			    $stmt2 = $this->dbh->prepare("SELECT B.Q_START_BLAST, B.Q_END_BLAST, B.EVALUE,
			    							B.ACCESSION_ID FROM PROTEIN AS P
											Inner Join BLAST AS B ON B.ID_PROTEIN = P.ID_PROTEIN
											Inner Join BLAST_NAME_DB AS BN ON BN.ID_BLAST_DB = B.ID_BLAST_DB
											WHERE P.ID_PROTEIN = :id AND BN.DESCRIPTION LIKE '%pat%'
											LIMIT 0, 20");
				$stmt2->bindParam(':id', $id);
			    $stmt2->execute();
			} catch (PDOException $e) {
				return -1;
			    echo 'Query error: ' . $e->getMessage();
			}

			$res2 = $stmt2->fetchAll(PDO::FETCH_BOTH);
    		$graphPat = array();
    		$j = 0;
    		foreach( $res2 as $row )
		    {
				$graphPat[$j]['start'] = $row["Q_START_BLAST"];
				$graphPat[$j]['end'] = $row["Q_END_BLAST"];
				$graphPat[$j]['label1'] = $row["ACCESSION_ID"];
				$graphPat[$j]['label2'] = $row["EVALUE"];
				if ($row["EVALUE"] <= 1e-20){
					$graphPat[$j]['color'] = $colors['red'];
				}else{
					$graphPat[$j]['color'] = $colors['blue'];
				}
				$j++;
			}

			$x = 50;
			foreach ($graphPat as $b)
			{
				// posicao texto inicio
				if ($b['start'] < 10){
					$tsmargin = -7;
				}elseif ($b['start'] < 100){
					$tsmargin = -12;
				}else{
					$tsmargin = -17;
				}
				// posicao texto fim
				if ($b['end'] < 10){
					$temargin = 4;
				}elseif ($b['end'] < 100){
					$temargin = 4;
				}else{
					$temargin = 4;
				}

				// grafico
				$graphDraw = $drawGraph->imagefillroundedrect($img, $gm+($b['start']*$fscale), $gm+$x, $gm+($b['end']*$fscale), $gm+$x+12, $radius, $b['color']);
				//imagefilledrectangle($img, $gm+($b['start']*$fscale), $gm+$x, $gm+($b['end']*$fscale), $gm+$x+12, $b['color']);
				// texto inicio
				imagefttext($img, 8, 0, $gm+($b['start']*$fscale)+$tsmargin-3, $gm+$x+10, $colors['red'], $fonts['tahoma'], $b['start']);
				// texto fim
				imagefttext($img, 8, 0, $gm+($b['end']*$fscale)+$temargin, $gm+$x+10, $colors['red'], $fonts['tahoma'], $b['end']);
				// label
				imagefttext($img, 8, 0, $gm+($b['start']*$fscale), $x+15, $colors['black'], $fonts['tahoma'], $b['label1']." - (".$b['label2'].")");
				$x=$x+35;
			}

			$rand = mt_rand(1,2147483647); // random
			imagepng($img, 'images/graph/blastPat'.$rand.'.png'); // grava a imagem em png com random
			//imagepng($img, 'images/graph/proteinPatTest.png'); // grava a imagem em png sem random
			imagedestroy($img);  // liberta a imagem da memoria
			return $rand;
		}
	}

mas estou a tentar adaptar para o tamanho do gráfico e da escala seja dinâmico, conforme o tamanho da sequência, que vou buscar a tabela, alguém pode dar uma ajuda ou dicas de como o devo fazer? 🤔


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
diokhan

sei que deve haver outra solução mais simples, mas neste momento o que consegui fazer foi isto:

// escala da timeline em px
			if (ceil($result[0]) < 200){
				$ts = 70;
			}elseif (ceil($result[0]) >= 200 && ceil($result[0]) < 300){
				$ts = 50;
			}elseif (ceil($result[0]) >= 300 && ceil($result[0]) < 400){
				$ts = 35;
			}elseif (ceil($result[0]) >= 400 && ceil($result[0]) < 500){
				$ts = 70;
			}elseif (ceil($result[0]) >= 500 && ceil($result[0]) < 600){
				$ts = 58.4;
			}elseif (ceil($result[0]) >= 600 && ceil($result[0]) < 700){
				$ts = 50;
			}elseif (ceil($result[0]) >= 700 && ceil($result[0]) < 800){
				$ts = 43.8;
			}elseif (ceil($result[0]) >= 800 && ceil($result[0]) < 900){
				$ts = 38.9;
			}elseif (ceil($result[0]) >= 900 && ceil($result[0]) < 1000){
				$ts = 70;
			}elseif (ceil($result[0]) >= 1000 && ceil($result[0]) < 1100){
				$ts = 63.8;
			}elseif (ceil($result[0]) >= 1100 && ceil($result[0]) < 1400){
				$ts = 50;
			}elseif (ceil($result[0]) >= 1400){
				$ts = 35;
			}

			// escala de referencia
        		if (ceil($result[0]) < 200){
				$scale = 20;
			}elseif (ceil($result[0]) >= 200 && ceil($result[0]) < 300){
				$scale = 20;
			}elseif (ceil($result[0]) >= 300 && ceil($result[0]) < 400){
				$scale = 20;
			}elseif (ceil($result[0]) >= 400 && ceil($result[0]) < 500){
				$scale = 50;
			}elseif (ceil($result[0]) >= 500 && ceil($result[0]) < 600){
				$scale = 50;
			}elseif (ceil($result[0]) >= 600 && ceil($result[0]) < 700){
				$scale = 50;
			}elseif (ceil($result[0]) >= 700 && ceil($result[0]) < 800){
				$scale = 50;
			}elseif (ceil($result[0]) >= 800 && ceil($result[0]) < 900){
				$scale = 50;
			}elseif (ceil($result[0]) >= 900 && ceil($result[0]) < 1000){
				$scale = 100;
			}elseif (ceil($result[0]) >= 1000 && ceil($result[0]) < 1100){
				$scale = 100;
			}elseif (ceil($result[0]) >= 1100 && ceil($result[0]) < 1400){
				$scale = 100;
			}elseif (ceil($result[0]) >= 1400){
				$scale = 100;
			}

			// factor de diferenca entre escala em px e escala de referencia
        		if (ceil($result[0]) < 200){
				$fscale = 3.5;
			}elseif (ceil($result[0]) >= 200 && ceil($result[0]) < 300){
				$fscale = 2.5;
			}elseif (ceil($result[0]) >= 300 && ceil($result[0]) < 400){
				$fscale = 1.8;
			}elseif (ceil($result[0]) >= 400 && ceil($result[0]) < 500){
				$fscale = 1.4;
			}elseif (ceil($result[0]) >= 500 && ceil($result[0]) < 600){
				$fscale = 1.2;
			}elseif (ceil($result[0]) >= 600 && ceil($result[0]) < 700){
				$fscale = 1;
			}elseif (ceil($result[0]) >= 700 && ceil($result[0]) < 800){
				$fscale = 0.9;
			}elseif (ceil($result[0]) >= 800 && ceil($result[0]) < 900){
				$fscale = 0.8;
			}elseif (ceil($result[0]) >= 900 && ceil($result[0]) < 1000){
				$fscale = 0.7;
			}elseif (ceil($result[0]) >= 1000 && ceil($result[0]) < 1100){
				$fscale = 0.65;
			}elseif (ceil($result[0]) >= 1100 && ceil($result[0]) < 1400){
				$fscale = 0.5;
			}elseif (ceil($result[0]) >= 1400){
				$fscale = 0.35;
			}

			// escala maxima de referencia
        		if (ceil($result[0]) < 200){
				$mscale = 200;
			}elseif (ceil($result[0]) >= 200 && ceil($result[0]) < 300){
				$mscale = 300;
			}elseif (ceil($result[0]) >= 300 && ceil($result[0]) < 400){
				$mscale = 400;
			}elseif (ceil($result[0]) >= 400 && ceil($result[0]) < 500){
				$mscale = 500;
			}elseif (ceil($result[0]) >= 500 && ceil($result[0]) < 600){
				$mscale = 600;
			}elseif (ceil($result[0]) >= 600 && ceil($result[0]) < 700){
				$mscale = 700;
			}elseif (ceil($result[0]) >= 700 && ceil($result[0]) < 800){
				$mscale = 800;
			}elseif (ceil($result[0]) >= 800 && ceil($result[0]) < 900){
				$mscale = 900;
			}elseif (ceil($result[0]) >= 900 && ceil($result[0]) < 1000){
				$mscale = 1000;
			}elseif (ceil($result[0]) >= 1000 && ceil($result[0]) < 1100){
				$mscale = 1100;
			}elseif (ceil($result[0]) >= 1100 && ceil($result[0]) < 1400){
				$mscale = 1400;
			}elseif (ceil($result[0]) >= 1400){
				$mscale = 2000;
			}

se alguém puder dar umas ideias para melhorar o meu código com algum ciclo mais simples aceito opiniões


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
diokhan

encontrei uma solução mais simples:

// altura e largura da imagem
		    $iw = 800;
			$ih = $count * 35 + 55;

			// margem geral da imagem
			$gm = 20;

			// escala maxima de referencia
			$mscale = $result[0] + 20;
			//echo "mscale ".$mscale." / ";			

			// escala da timeline em px
			$ts = 70;

			// escala de referencia
			$scale = round($result[0] / 10);
			//echo "scale ".$scale;

			// factor de diferenca entre escala em px e escala de referencia
			if ($result[0] < 400){
				$div = $result[0] + 15;
				$calc = (68.5 /$div) * 11;
			}elseif ($result[0] >= 400 && $result[0] < 1000){
				$div = $result[0] + 80;
				$calc = (68.5 /$div) * 12;
			}elseif ($result[0] >= 1000){
				$div = $result[0] + 80;
				$calc = (68.5 /$div) * 11;
			}
			$fscale = number_format($calc, 1, '.', '');
			//echo " / fscale ".$fscale;

feito por mim, se alguém encontrar erros ou melhorias avisem :thumbsup:


...Join the dark side...and get a free cookie...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.