unit librgraf; interface const MaxNrPuntos = 300; type Coord = record X, Y: real; end; Modos = (lineas, puntos, marcas); Grafico = object colFondo, colEjes, colTexto, colGraf: integer; Modo: Modos; titX, titY: string[30]; Datos: array [1..MaxNrPuntos] of Coord; nrDatos: integer; procedure Inicializar; procedure Agregar(X, Y: real); procedure Dibujar(X, Y, tX, tY: integer); end; implementation uses Graph; procedure Grafico.Inicializar; begin nrDatos := 0; colFondo := Green; colEjes := Black; colGraf := LightRed; colTexto := White; Modo := lineas; titX := 'Tiempo'; end; procedure Grafico.Agregar(X, Y: real); begin if nrDatos < MaxNrPuntos then begin inc(nrDatos); Datos[nrDatos].X := X; Datos[nrDatos].Y := Y; end; end; procedure Grafico.Dibujar(X, Y, tX, tY: integer); var I, posX, posY: integer; Xscale, Yscale, Ymin, Ymax, Xmin, Xmax: real; S: string; begin { Primer paso: buscar los limites de la tabla de valores } Xmin := Datos[1].X; Xmax := Xmin; Ymin := Datos[1].Y; Ymax := Ymin; for I := 2 to nrDatos do begin if Datos[I].X < Xmin then Xmin := Datos[I].X; if Datos[I].X > Xmax then Xmax := Datos[I].X; if Datos[I].Y < Ymin then Ymin := Datos[I].Y; if Datos[I].Y > Ymax then Ymax := Datos[I].Y; end; { Luego determinamos el factor de escala: Unidades usuario/pixel } Xscale := 0.8 * tX / (Xmax - Xmin); Yscale := 0.8 * tY / (Ymax - Ymin); { Abrimos la ventana de graficar } SetViewPort(X, Y, X+tX, Y+tY, true); SetFillStyle(SolidFill, colFondo); { Llenamos el fondo con el color deseado } Bar(0, 0, tX-1, tY-1); { Trazamos los ejes } SetColor(colEjes); Line(round(0.1*tX), tY-round(0.1*tY), round(0.1*tX), tY-round(0.9*tY)); if (Ymin*Ymax > 0) then begin { Este es el caso simple, el eje abajo en el grafico } Line(round(0.1*tX), tY-round(0.1*tY), round(0.1*tX), tY-round(0.9*tY)); end else begin { Pero si el grafico cambia de signo, podemos poner el eje en su lugar correcto (0) } Line(round(0.1*tX), tY - (round(Yscale * (0 - Ymin) + 0.1*tY)), round(0.9*tX), tY - (round(Yscale * (0 - Ymin) + 0.1*tY))); end; { Agregamos el texto del eje X } SetColor(colTexto); OutTextXY(round(0.1*tX), tY-14, titX); { ... el valor minimo para el eje Y ... } str(Ymin:10, S); OutTextXY(round(0.1*tX)+2, tY-round(0.1*tY)-10, S); { ... y el valor maximo } str(Ymax:10, S); OutTextXY(round(0.1*tX)+2, tY-round(0.9*tY), S); { Finalmente graficamos... } SetColor(colGraf); posX := round(Xscale * (Datos[1].X - Xmin) + 0.1*tX); posY := tY - (round(Yscale * (Datos[1].Y - Ymin) + 0.1*tY)); case Modo of lineas: MoveTo(posX, posY); puntos: PutPixel(posX, posY, colGraf); marcas: begin MoveTo(posX-2, posY+3); LineTo(posX, posY-3); LineTo(posX+2, posY+3); LineTo(posX-2, posY+3); end; end; for I := 2 to nrDatos do begin posX := round(Xscale * (Datos[I].X - Xmin) + 0.1*tX); posY := tY - (round(Yscale * (Datos[I].Y - Ymin) + 0.1*tY)); case Modo of lineas: LineTo(posX, posY); puntos: PutPixel(posX, posY, colGraf); marcas: begin MoveTo(posX-2, posY-2); LineTo(posX-2, posY+2); LineTo(posX+2, posY+2); LineTo(posX+2, posY-2); LineTo(posX-2, posY-2); end; end; end; end; begin end.