Last active
December 14, 2015 05:49
-
-
Save danko3/5038268 to your computer and use it in GitHub Desktop.
Function Grapher by jonny. Hacked by me to be used by PlotFile.ahk.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;;;;;;;;;;;;; | |
; | |
; Function Grapher by jonny | |
; | |
; | |
;;;Functions;;; | |
; | |
;GraphCreate(id,x,y,w,h,pre="") | |
; Initializes the graph, sets its options, | |
; and draws it at the specified location. | |
; Returns 1 if it's successful, 0 if there's | |
; a logical error (e.g. bad option), and blank | |
; if there's a problem allocating memory. | |
; | |
; id: | |
; The window ID (ahk_id) of the window to | |
; draw the graph on. | |
; | |
; x: | |
; The x-coordinate to draw the graph at. | |
; | |
; y: | |
; The y-coordinate to draw the graph at. | |
; | |
; w: | |
; The width of the graph. | |
; | |
; h: | |
; The height of the graph. | |
; | |
; pre: | |
; The prefix for the global option variables, | |
; explained further below. | |
; For example, if pre = "GraphOpts_", then it | |
; will read GraphOpts_xScl for the xScl option | |
; | |
; color: | |
; The color to draw the equation in. This must | |
; be in RGB form (0xRRGGBB), not an HTML color. | |
; If this parameter is unspecified or not a valid | |
; RGB color, the defGraphColor option will be used. | |
; | |
; | |
;GraphClear() | |
; Clears all equations off the graph. | |
; | |
; | |
;GraphDraw() | |
; Redraws the graph. Shouldn't be necessary to | |
; use, since GraphCreate binds this to WM_PAINT. | |
; | |
; | |
;GraphDestroy() | |
; Frees all memory associated with the graph. | |
; You MUST call this before exiting the script, | |
; or there will be a memory leak. | |
; Note that this will not remove the graph's image | |
; from the display. The window must be redrawn | |
; to visually clear it. | |
; | |
; | |
; | |
;;;Options;;; | |
; | |
; To use these, set any of them as global variables | |
; with a consistent prefix (required). Then pass | |
; the prefix to GraphCreate as a string, via the | |
; 'pre' parameter. Any options left unset will get | |
; their default values. | |
; | |
; | |
;paperColor (0xFFFFFF - white) | |
; The color of the graph's background, or the | |
; "graph paper." Must be a full RGB color. | |
; | |
;axisColor (0x000000 - black) | |
; The color of the x and y axes, if visible. | |
; Must be a full RGB color. | |
; | |
;gridColor (0xDFDFDF - light grey) | |
; The color of the grid beneath the graph. | |
; Must be a full RGB color. | |
; | |
;defGraphColor (0x0000FF - blue) | |
; The default color for Graph(), if the 'color' | |
; parameter isn't valid or specified. | |
; | |
;lineWidth (3) | |
; The width of the lines generated by Graph(). | |
; Must be greater than or equal to zero. | |
; | |
;xScl (1) | |
; The scale of the x-plane of the grid, in | |
; logical units. For instance, a value of 10 | |
; would draw a vertical line wherever x is | |
; a multiple of 10, and a value of 0.5 would | |
; draw two vertical lines for every integral | |
; x-value. Must be greater than zero. | |
; | |
;yScl (1) | |
; The scale of the y-plane of the grid, in | |
; logical units. Same as above, except for | |
; the horizontal lines with y. Must be greater | |
; than zero. | |
; | |
;xMin (-10) | |
; The smallest x-value displayed on the graph, | |
; or the left edge of its viewable area. Must | |
; be less than xMax. | |
; | |
;yMin (-10) | |
; The smallest y-value displayed on the graph, | |
; or the bottom edge of its viewable area. Must | |
; be less than yMax. | |
; | |
;xMax (10) | |
; The largest x-value displayed on the graph, | |
; or the right edge of its viewable area. Must | |
; be greater than xMin. | |
; | |
;yMax (10) | |
; The largest y-value displayed on the graph, | |
; or the top edge of its viewable area. Must be | |
; greater than yMin. | |
; | |
; | |
; | |
;;;Remarks;;; | |
; | |
; Use this at your own risk. I've tested it a lot, | |
; but there's still a chance it'll cause a serious | |
; memory leak. | |
; | |
; Avoid naming any global variables with the prefix | |
; '__graph_' while the graph is created, since these | |
; functions use it to communicate. | |
; | |
; Graph() uses two temporary files which it creates | |
; in A_Temp, so don't be alarmed if you notice that | |
; your script is suddenly opening weird files. (It | |
; deletes them when it's finished, so they'll only | |
; consume space for a few milliseconds.) | |
; | |
; ;; Mods by danko | |
; * xScl and yScl xMax yMax | |
; * added tics and labels | |
GraphCreate(WindowID,xCoord,yCoord,Width,Height,OptPre="") | |
{ | |
global | |
local paperColor,axisColor,gridColor,xScl,yScl,xMin,yMin | |
,xMax,yMax,Pen,Brush | |
if __graph_Exists | |
return 0 | |
;Grid options | |
;background color (white) | |
;paperColor := %OptPre%paperColor ? %OptPre%paperColor : 0xFFFFFF | |
paperColor := 0xFFFFFF | |
;color for axes (black) | |
axisColor := %OptPre%axisColor ? %OptPre%axisColor : 0x000000 | |
;grid color (grey) | |
gridColor := %OptPre%gridColor ? %OptPre%gridColor : 0xDFDFDF | |
;default color for new equations (blue) | |
__graph_color := %OptPre%defGraphColor ? %OptPre%defGraphColor : 0x0000FF | |
;scale of grid for the x plane | |
xScl := %OptPre%xScl ? %OptPre%xScl : PlotWidth/10 | |
;scale of grid for the y plane | |
yScl := %OptPre%yScl ? %OptPre%yScl : PlotHeight/10 | |
;lowest x-value shown on graph | |
xMin := %OptPre%xMin ? %OptPre%xMin : 0 | |
;lowest y-value shown on graph | |
yMin := %OptPre%yMin ? %OptPre%yMin : 0 | |
;highest x-value shown on graph | |
xMax := %OptPre%xMax ? %OptPre%xMax : Width | |
;highest y-value shown on graph | |
yMax := %OptPre%yMax ? %OptPre%yMax : Height | |
;sanity checks | |
if (paperColor > 0xFFFFFF || paperColor < 0 | |
|| axisColor > 0xFFFFFF || axisColor < 0 | |
|| gridColor > 0xFFFFFF || gridColor < 0 | |
|| __graph_color > 0xFFFFFF || __graph_color < 0 | |
|| __graph_lineWidth < 0 | |
|| xScl <= 0 || yScl <= 0 | |
|| xMin >= xMax || yMin >= yMax) | |
{ | |
__graph_color = | |
__graph_lineWidth = | |
return 0 | |
} | |
__graph_X := xCoord | |
__graph_Y := yCoord | |
__graph_W := Width | |
__graph_H := Height | |
;compute how many units on the graph each pixel | |
;corresponds to | |
__graph_xUnit := Width / (xMax - xMin) | |
__graph_yUnit := Height / (yMax - yMin) | |
;how far, in graph units, the left | |
;edge is from the origin | |
__graph_leftDist := xMin * __graph_xUnit | |
;how far the top edge is from the | |
;origin, this time in terms of y | |
__graph_topDist := yMax * __graph_yUnit | |
;Device Context for the window to be drawn to | |
__graph_WindowDC := DllCall("GetDC", UInt,WindowID) | |
if not __graph_WindowDC | |
return | |
;first memory DC, containing the "graph paper," | |
;the background of the graph | |
__graph_PaperDC := DllCall("CreateCompatibleDC", UInt,WindowDC) | |
if not __graph_PaperDC | |
return | |
;create a bitmap on the DC | |
__graph_PaperDC_BM := DllCall("CreateCompatibleBitmap" | |
, UInt,__graph_WindowDC, UInt,Width, UInt,Height) | |
DllCall("SelectObject", UInt,__graph_PaperDC | |
, UInt,__graph_PaperDC_BM) | |
;second Memory DC, containing the finished product | |
;of the paper with the graphed equations on it | |
__graph_MemoryDC := DllCall("CreateCompatibleDC", UInt,WindowDC) | |
if not __graph_MemoryDC | |
return | |
;create a bitmap on the DC | |
__graph_MemoryDC_BM := DllCall("CreateCompatibleBitmap" | |
, UInt,__graph_WindowDC, UInt,Width, UInt,Height) | |
DllCall("SelectObject", UInt,__graph_MemoryDC | |
, UInt,__graph_MemoryDC_BM) | |
;set up the graph paper | |
;first the background and border | |
Pen := DllCall("CreatePen", UInt,0, UInt,0, UInt,paperColor) | |
DllCall("SelectObject", UInt,__graph_PaperDC, UInt,Pen) | |
Brush := DllCall("CreateSolidBrush", UInt,paperColor) | |
DllCall("SelectObject", UInt,__graph_PaperDC, UInt,Brush) | |
DllCall("Rectangle", UInt,__graph_PaperDC, UInt,0, UInt,0 | |
, UInt,Width, UInt,Height) | |
DllCall("DeleteObject", UInt,Pen) | |
DllCall("DeleteObject", UInt,Brush) | |
;now the grid | |
Pen := DllCall("CreatePen", UInt,0, UInt,0, UInt,gridColor) | |
DllCall("SelectObject", UInt,__graph_PaperDC, UInt,Pen) | |
;vertical lines (x-plane) | |
Loop | |
{ | |
if (A_Index >= ( (xMax - xMin) / xScl )) | |
break | |
DllCall("MoveToEx", UInt,__graph_PaperDC | |
, UInt,Round(A_Index*__graph_xUnit*xScl), UInt,0, UInt,0) | |
DllCall("LineTo", UInt,__graph_PaperDC | |
, UInt,Round(A_Index*__graph_xUnit*xScl), UInt,Height) | |
} | |
;horizontal lines (y-plane) | |
Loop | |
{ | |
if (A_Index >= ( (yMax - yMin) / yScl )) | |
break | |
DllCall("MoveToEx", UInt,__graph_PaperDC | |
, UInt,0, UInt,Round(A_Index*__graph_yUnit*yScl), UInt,0) | |
DllCall("LineTo", UInt,__graph_PaperDC | |
, UInt,Width, UInt,Round(A_Index*__graph_yUnit*yScl)) | |
} | |
DllCall("DeleteObject", UInt,Pen) | |
;axes | |
Pen := DllCall("CreatePen", UInt,0, UInt,0, UInt,axisColor) | |
DllCall("SelectObject", UInt,__graph_PaperDC, UInt,Pen) | |
if (xMin < 0 and xMax > 0) | |
{ | |
DllCall("MoveToEx", UInt,__graph_PaperDC | |
, UInt,Round((-xMin)*__graph_xUnit), UInt,0, UInt,0) | |
DllCall("LineTo", UInt,__graph_PaperDC | |
, UInt,Round((-xMin)*__graph_xUnit), UInt,Height) | |
} | |
if (yMin < 0 and yMax > 0) | |
{ | |
DllCall("MoveToEx", UInt,__graph_PaperDC | |
, UInt,0, UInt,Round(yMax*__graph_yUnit), UInt,0) | |
DllCall("LineTo", UInt,__graph_PaperDC | |
, UInt,Width, UInt,Round(yMax*__graph_yUnit)) | |
} | |
DllCall("DeleteObject", UInt,Pen) | |
__graph_Exists := true | |
GraphClear() | |
; WM_PAINT: 0x0F | |
OnMessage(0x0F,"GraphDraw") | |
return 1 | |
} | |
Graph(Equation,Color = -1) | |
{ | |
global | |
local EquDC,EquDC_BM,Pen,FirstVal,GraphSpec,R,G,B | |
if (!__graph_Exists or !A_AhkPath) | |
return 0 | |
if (Color < 0 or Color > 0xFFFFFF) | |
Color := __graph_color | |
;CreatePen expects a BGR-formatted COLORREF | |
R := Color & 0x0000FF | |
G := Color & 0x00FF00 | |
B := Color & 0xFF0000 | |
R <<= 16 | |
B >>= 16 | |
Color := R | G | B | |
;px/py: Positional coordinates used to | |
; place the graph | |
; | |
;x/y: Actual coordinates that the function | |
; is computed in | |
; | |
;Equation must be in terms of 'x' | |
FileAppend, | |
( LTrim | |
#NoTrayIcon | |
Loop %__graph_W% | |
{ | |
px := A_Index | |
x := (px + %__graph_leftDist%) / %__graph_xUnit% | |
y := (%Equation%) * %__graph_yUnit% | |
py := Round(%__graph_topDist% - y) | |
GraphSpec .= py . ";" | |
} | |
FileDelete gspec | |
FileAppend,`%GraphSpec`%,gspec | |
),%A_Temp%\tempGraph.ahk | |
RunWait,"%A_AhkPath%" "%A_Temp%\tempGraph.ahk",%A_Temp% | |
FileRead,GraphSpec,%A_Temp%\gspec | |
FileDelete %A_Temp%\tempGraph.ahk | |
FileDelete %A_Temp%\gspec | |
Pen := DllCall("CreatePen", UInt,0, UInt,__graph_lineWidth, UInt,Color) | |
DllCall("SelectObject", UInt,__graph_MemoryDC, UInt,Pen) | |
StringTrimRight,GraphSpec,GraphSpec,1 | |
FirstVal := InStr(GraphSpec,";") | |
DllCall("MoveToEx", UInt,__graph_MemoryDC, UInt,1, UInt,SubStr(GraphSpec,1,FirstVal-1), UInt,0) | |
StringTrimLeft,GraphSpec,GraphSpec,FirstVal | |
Loop,Parse,GraphSpec,; | |
DllCall("LineTo", UInt,__graph_MemoryDC, UInt,A_Index + 1, UInt,A_LoopField) | |
DllCall("DeleteObject", UInt,Pen) | |
GraphDraw() | |
return 1 | |
} | |
GraphClear() | |
{ | |
global | |
if not __graph_Exists | |
return | |
DllCall("BitBlt", UInt,__graph_MemoryDC, UInt,0, UInt,0 | |
, UInt,__graph_W, UInt,__graph_H, UInt,__graph_PaperDC | |
, UInt,0, UInt,0, UInt,0x00CC0020) | |
GraphDraw() | |
} | |
GraphDraw() | |
{ | |
global | |
if not __graph_Exists | |
return | |
DllCall("BitBlt", UInt,__graph_WindowDC, UInt,__graph_X | |
, UInt,__graph_Y, UInt,__graph_W, UInt,__graph_H | |
, UInt,__graph_MemoryDC, UInt,0, UInt,0, UInt,0x00CC0020) | |
} | |
GraphDestroy() | |
{ | |
global | |
;WM_PAINT: 0x0F | |
OnMessage(0x0F,"") | |
DllCall("DeleteObject", UInt,__graph_PaperDC) | |
DllCall("DeleteObject", UInt,__graph_PaperDC_BM) | |
DllCall("DeleteObject", UInt,__graph_MemoryDC) | |
DllCall("DeleteObject", UInt,__graph_MemoryDC_BM) | |
DllCall("ReleaseDC", UInt,0, UInt,__graph_WindowDC) | |
__graph_PaperDC = | |
__graph_PaperDC_BM = | |
__graph_MemoryDC = | |
__graph_MemoryDC_BM = | |
__graph_WindowDC = | |
__graph_X = | |
__graph_Y = | |
__graph_W = | |
__graph_H = | |
__graph_color = | |
__graph_lineWidth = | |
__graph_xUnit = | |
__graph_yUnit = | |
__graph_leftDist = | |
__graph_topDist = | |
__graph_Exists = | |
} | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; added by danko | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; Setup plot window, size, margins, etc. | |
; linewidth of graphs | |
__graph_lineWidth = 1 | |
; Plot window size (real estate) | |
PlotHeight = 500 | |
PlotWidth := round(x_A + x_A/10,-2) | |
if PlotWidth < 100 | |
PlotWidth = 100 | |
Topmargin = 40 | |
BottomMargin = 80 | |
LeftMargin = 60 | |
;RightMargin = 50 | |
tic = 5 | |
longtic = 10 | |
ylabel := round(ydif/plotheight,4) | |
;MsgBox, ylabel= %ylabel% | |
Y_Pos_top_X_Scale_tic := TopMargin-tic | |
Y_Pos_top_X_Scale_longtic := TopMargin-longtic | |
Y_Pos_bottom_X_Scale := PlotHeight+TopMargin | |
X_Pos_Left_Y_Scale_tic := LeftMargin-tic | |
X_Pos_Left_Y_Scale_longtic := LeftMargin-longtic | |
X_Pos_Right_Y_Scale := Plotwidth+LeftMargin | |
; Labelpositions | |
Y_Pos_top_X_label := TopMargin-3*longtic | |
Y_Pos_bottom_X_label := TopMargin+PlotHeight+longtic+5 | |
X_Pos_Left_Y_label := LeftMargin-4*longtic | |
LegendaPos := Plotheight+Topmargin+50 | |
; Plot window size (including borders) | |
WindowWidth := PlotWidth+LeftMargin+50 | |
WindowHeight := PlotHeight+TopMargin+BottomMargin | |
; Scale / Ticmarks | |
; Made with tiny progress bars. Outside markers only | |
; because progress bars fall 'behind' the plot window. | |
; X-axis | |
;for the first Xtic (upper and lower axis) | |
Gui Add,Progress,w1 h10 x%LeftMargin% y%Y_Pos_top_X_Scale_longtic% background0000000 | |
Gui Add,Progress,w1 h10 x%LeftMargin% y%Y_Pos_bottom_X_Scale% background0000000 | |
; the first label | |
Gui Add,text, x%LeftMargin% y%Y_Pos_top_X_label% +Center, 0 | |
;Gui Add,text, x%LeftMargin% y%Y_Pos_bottom_X_label% +Center, %time% | |
; tics and labels | |
loop, %PlotWidth% | |
{ | |
if !mod(A_Index,10) ; tic every 10 units | |
{ | |
pos := A_Index+LeftMargin | |
Gui Add,Progress,w1 h5 x%pos% y%Y_Pos_top_X_Scale_tic% background0000000 | |
Gui Add,Progress,w1 h5 x%pos% y%Y_Pos_bottom_X_Scale% background0000000 | |
} | |
if !mod(A_Index,50) ; long tic every 50 units | |
{ | |
Gui Add,Progress,w1 h10 x%pos% y%Y_Pos_top_X_Scale_longtic% background0000000 | |
Gui Add,Progress,w1 h10 x%pos% y%Y_Pos_bottom_X_Scale% background0000000 | |
} | |
if !mod(A_Index,100) ; label every 100 units | |
Gui Add,text, x%pos% y%Y_Pos_top_X_label% +Center,%A_Index% | |
} | |
; Y-axis | |
;for the first Ytic (Left and right axis) | |
Gui Add,Progress,h1 w10 x%X_Pos_Left_Y_Scale_longtic% y%TopMargin% background0000000 | |
Gui Add,Progress,h1 w10 x%X_Pos_Right_Y_Scale% y%TopMargin% background0000000 | |
Y_label := round(ymin+ydif,2) | |
; the first Y label | |
Gui Add,text, y%Y_Pos_top_X_Scale_longtic% x%X_Pos_Left_Y_label% +Right w20,%Y_label% | |
;tics and labels | |
loop, %PlotHeight% | |
{ | |
if !mod(A_Index,10) ; tic every 10 units | |
{ | |
pos := A_Index+TopMargin | |
Gui Add,Progress,h1 w5 y%pos% x%X_Pos_Left_Y_Scale_tic% background0000000 | |
Gui Add,Progress,h1 w5 y%pos% x%X_Pos_Right_Y_Scale% background0000000 | |
} | |
if !mod(A_Index,50) ; long tic every 50 units | |
{ | |
Gui Add,Progress,h1 w10 y%pos% x%X_Pos_Left_Y_Scale_longtic% background0000000 | |
Gui Add,Progress,h1 w10 y%pos% x%X_Pos_Right_Y_Scale% background0000000 | |
} | |
pos := pos-10 | |
if !mod(A_Index,100) ; label every 100 units | |
{ | |
Y_label := round(Ymin+ydif-A_Index*ylabel,2) | |
Gui Add,text, y%pos% x%X_Pos_Left_Y_label% +Right,%y_label% | |
} | |
} | |
; Legenda demo | |
; Red progressbar first | |
Gui Add,Progress,h10 w30 y%LegendaPos% x%LeftMargin% backgroundff00000 | |
gui, font, bold cred | |
Gui Add,text, xp+35 yp-4, chan1 | |
; Green progressbar | |
Gui Add,Progress,h10 w30 y%LegendaPos% xp+100 background00aa00 | |
gui, font, c009900 ; a darker shade of green. (more esthetic?) | |
Gui Add,text, xp+35 yp-4, chan2 | |
gui, font ; reset the font |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment