Smartzkid
2008-10-14 20:34:45
Generates a graph from a TPA. Returns a bitmap handle.
Why should it be in SRL? There's nothing better than a graph when it comes to showing any rate/time. It makes a great addition to any script form and is extremely customizable; the possibilities are endless.
Todo:
-Use canvas line functions for the gridlines & axis
-Axis labling (alpha blended)
-Split gridlining & axising into one function, single line graphing into another, then write a function to combine the two. Will allow for multiple lines on one graph
-Optimization
-Bar graph version? (If I do this, I'll split everything into 3 functions; one to create gridlines, then one each for bar graphs and line graphs)
Known bugs:
-Gridlines are often off by a small amount (about 3x3 points off)
Function & Example:
Why should it be in SRL? There's nothing better than a graph when it comes to showing any rate/time. It makes a great addition to any script form and is extremely customizable; the possibilities are endless.
Todo:
-Use canvas line functions for the gridlines & axis
-Axis labling (alpha blended)
-Split gridlining & axising into one function, single line graphing into another, then write a function to combine the two. Will allow for multiple lines on one graph
-Optimization
-Bar graph version? (If I do this, I'll split everything into 3 functions; one to create gridlines, then one each for bar graphs and line graphs)
Known bugs:
-Gridlines are often off by a small amount (about 3x3 points off)
Function & Example:
program Grapher;
{*******************************************************************************
function GraphPtsEx( ... ): integer;
By: Smartzkid
Description: Graphs points stored in TPA 'pts', returns handle to a bitmap
Parameters:
GraphPxlsX, GraphPxlsY: integer; Size of the graph
zoom: integer; Zoom
pts: TPointArray; Graph points
GraphBCGColor, Background color
GraphAxisColor, Axis color
GraphLineColor: integer; Line color
Axis_ForceVisible: boolean; Force origin to be visible
connectPoints: boolean; Draws lines connecting points
pointSize: integer; Draws circles for each point (1 = disabled)
gridlines: boolean; Draw gridlines
GridlineXS\pacing, GridlineYSpacing, Spacing between gridlines
GridlineColor: integer): integer; Gridline color
*******************************************************************************}
function GraphPtsEx(GraphPxlsX, GraphPxlsY: integer; zoom: integer; pts: TPointArray; GraphBCGColor, GraphAxisColor, GraphLineColor: integer; Axis_ForceVisible: boolean; connectPoints: boolean; pointSize: integer; gridlines: boolean; GridlineXSpacing, GridlineYSpacing, GridlineColor: integer): integer;
var
x_min, x_max, y_min, y_max: integer;
i, temp: integer;
scaleX, scaleY: extended;
Graph_BMP, Result_BMP: integer;
graphPoints: TPointArray;
canvas: TCanvas;
begin
//Param-error catching
if(GraphPxlsX < 1)then
Exit;
if(GraphPxlsY < 1)then
Exit;
if(zoom < 1)then
zoom := 1;
if(Gridlines)then
begin
if(GridlineXSpacing < 1)then
GridlineXSpacing := 5;
if(GridlineYSpacing < 1)then
GridlineYSpacing := 5;
end;
//Create the bitmap that the graph will be displayed on and fill with a given color
Graph_BMP := BitmapFromString(GraphPxlsX, GraphPxlsY, '');
FastDrawClear(Graph_BMP, GraphBCGColor);
if(Axis_ForceVisible = false)then
begin
x_min := pts[0].x;
y_min := pts[0].y;
end;
//Find lowest and highest points
for i := 0 to high(pts) do
begin
if(pts[i].x < x_min)then
x_min := pts[i].x;
if(pts[i].x > x_max)then
x_max := pts[i].x;
if(pts[i].y < y_min)then
y_min := pts[i].y;
if(pts[i].y > y_max)then
y_max := pts[i].y;
end;
//add a 10% 'buffer' to the x axis
temp := round((abs(x_max) - x_min) / 10);
x_min := x_min - temp;
x_max := x_max + temp;
//add a 10% 'buffer' to the y axis
temp := round((abs(y_max) - y_min) / 10);
y_min := y_min - temp;
y_max := y_max + temp;
//Determine Graph-point to pixel scale
scaleX := GraphPxlsX / round(x_max - x_min);
scaleY := GraphPxlsY / round(y_max - y_min);
if(Gridlines)then
begin
//Draw vertical gridlines
for temp := 0 to round(GraphPxlsX / (GridlineXSpacing * ScaleX)) do
for i := 0 to GraphPxlsY - 1 do
FastSetPixel(Graph_BMP, round(GridlineXSpacing * temp * ScaleX) + (round(abs(x_min) * scaleX) mod GridlineXSpacing), i, GridlineColor);
//Draw horizontal gridlines
for temp := 0 to round(GraphPxlsY / (GridlineYSpacing * ScaleY)) - 1 do
for i := 0 to GraphPxlsX - 1 do
FastSetPixel(Graph_BMP, i, round(GridlineYSpacing * temp * ScaleY) + (round(((GraphPxlsY / ScaleY) + abs(y_min)) * scaleY) mod GridlineYSpacing), GridlineColor);
end;
//Draw vertical axis
if(x_min < 0)then
for i := 0 to GraphPxlsY - 1 do
FastSetPixel(Graph_BMP, round(abs(x_min) * scaleX), i, GraphAxisColor);
//Draw horizontal axis
if(y_min < 0)then
for i := 0 to GraphPxlsX - 1 do
FastSetPixel(Graph_BMP, i, round(((GraphPxlsY / ScaleY) - abs(y_min)) * scaleY), GraphAxisColor);
//Calculate the points
SetLength(graphPoints, Length(pts));
for i := 0 to high(pts) do
begin
graphPoints[i].X := round((pts[i].x - x_min) * scaleX);
graphPoints[i].Y := round(GraphPxlsY - ((pts[i].y - y_min) * scaleY));
end;
//Graph the points
for i := 0 to High(graphPoints) do
try
FastSetPixel(Graph_BMP, graphPoints[i].X, GraphPoints[i].Y, GraphLineColor);
except
writeln('Error at pt ' + inttostr(i + 1));
writeln(inttostr(graphPoints[i].X) + ', ' + inttostr(graphPoints[i].Y));
end;
if(connectPoints) or (pointSize > 1)then
canvas := GetBitmapCanvas(Graph_BMP);
if(connectPoints)then
canvas.Pen.Color := GraphLineColor; //Sets line color
if(pointSize > 1)then
canvas.Brush.Color := GraphLineColor; //Fills elipses with line color
if(connectPoints)then
for i := 0 to High(graphPoints) - 1 do
try
canvas.MoveTo(graphPoints[i].X, graphPoints[i].Y);
canvas.LineTo(graphPoints[i + 1].X, graphPoints[i + 1].Y);
except
writeln('Error drawing line between pts ' + inttostr(i) + ' and ' + inttostr(i + 1));
end;
if(pointSize > 1)then
for i := 0 to High(graphPoints) do
canvas.Ellipse(graphPoints[i].X - pointSize, graphPoints[i].Y - pointSize, graphPoints[i].X + pointSize, graphPoints[i].Y + pointSize);
Result_BMP := BitmapFromString(GraphPxlsX * zoom, GraphPxlsY * zoom, '');
SafeCopyCanvas(canvas, GetBitmapCanvas(Result_BMP), 0, 0, GraphPxlsX, GraphPxlsY, 0, 0, GraphPxlsX * zoom, GraphPxlsY * zoom)
FreeBitmap(Graph_BMP);
result := Result_BMP;
end;
{*******************************************************************************
function GraphPts(GraphPxlsX, GraphPxlsY: integer; pts: TPointArray): integer;
By: Smartzkid
Description: Graphs points stored in TPA 'pts', returns handle to a bitmap
Parameters:
GraphPxlsX, GraphPxlsY: integer; Size of the graph
pts: TPointArray; Graph points
*******************************************************************************}
function GraphPts(GraphPxlsX, GraphPxlsY: integer; pts: TPointArray): integer;
begin
result := GraphPtsEx(GraphPxlsX, GraphPxlsY, 1, pts, 16777215, 5018076, 0, false, true, 2, true, 10, 10, 16701619);
end;
var
data: TPointArray;
graph, i: integer;
begin
SetLength(data, 50);
for i := 0 to High(data) do
data [i] := Point((i - 25) * 2, RandomRange(-50, 50));
graph := GraphPtsEx(250, 250, 1, data, 16777215, 5018076, 0, false, true, 2, true, 5, 5, 16701619);
DisplayDebugImgWindow(250, 250);
SafeCopyCanvas(GetBitmapCanvas(graph), GetDebugCanvas, 0, 0, 250, 250, 0, 0, 250, 250);
FreeBitmap(Graph);
end.