AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Control] "_diagramm_" a Chart-function by denick

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Zed Gecko



Joined: 23 Sep 2006
Posts: 98

PostPosted: Sun Jun 01, 2008 1:10 am    Post subject: [Control] "_diagramm_" a Chart-function by denick Reply with quote

denick aka. nick has created a very handy GDI-chart/plotter-function in the german forum:
http://de.autohotkey.com/forum/topic2962-15.html

And i think it´s worth sharing it with the "non-kraut"-part of the comunity.

this is the comment-translated version of the _diagramm_-function Version:(2008-05-31)

Code:

; ==============================================================================
; __Diagramm__()
; ------------------------------------------------------------------------------
; Created by: denick
; Original Post: http://de.autohotkey.com/forum/topic2962-15.html
; ------------------------------------------------------------------------------
; Function:
; A control showing a diagram or graph for a List of x/y-Values
; to be inserted in a Gui.
; ------------------------------------------------------------------------------
; Parameters:
; G#           Number of Gui, Value  between: 1 - 98
;              99 is RESERVED (check: Specialities).
; XD           X-Position of diagram-area
; YD           Y-Position of diagram-area
; VL           List of Values, a LF-seperated (`n) list each line of this
;            with respectively two fields seperated by |
;              Field1 : a short description of the value
;              Field2 : the numerical value
;              Field2 can have a decimal point or comma.
; HY           Hight of Diagram in Pixel (Y-Axis)
; YH           highest showable value
; YL           lowest showable value
; SY           Label of Y-Axis as "|"-seperated List.
;              Each list-element has this Format: P;F;T
;              P = position in the scope between 1 - HY (check below)
;              F = text format:
;                  L = left
;                  C = center
;                  R = right
;              T = textual entry
;              If F and T are empty, only a grid is drawn.
;              Empty string (""): no Label, no grid
;              a string without "|" will be rejected
; MX           maximal number of displayable values (X-Axis)
; FX           integer-scale-factor for the width of the diagram:
;              widht in Pixel = MX * FX
; SX           Label of X-Axis as  "|"-seperated List.
;               Each list-element has this Format: P;F;T
;              P = position in the scope between 1 - MX
;              F = text format:
;                  L = Left of the given position P
;                  C = centered under the given position P
;              T = textual entry
;              If F and T are empty, only a grid is drawn.
;              Empty string (""): no Label, no grid
;              a string without "|" will be rejected
; Optional VC  Color of value-display
;              Range: HTML-Colorname | RGB-Hexcode (0x888888) | 0
;              Standard: 0 = "Gray"
;              VC can be a "|"-seperated color-list, too
;              the colors will be used alternatingly.
; Optional BC  Color of diagram-background
;              Range: HTML-Colorname | RGB-Hexcode (0x888888) | 0
;              Standard: 0 = "White"
; Optional GC  Color of diagram-grid
;              ange: HTML-Colorname | RGB-Hexcode (0x888888) | 0
;              Standard: 0 = "Grid" (normal Gui-background)
;              If BC = GC the grid is invisible unless it
;              will be displayed in the foreground (check Parameter GF).
; Optional HC  Color of "Crosshair" when displaying values
;              Range: HTML-Colorname | RGB-Hexcode (0x888888) | 0
;              Standard: 0 = "Red"
;              Attention: HC can not be identical to the (first) Color in VC
;              , because it is used as transparent-color
; Optional GF  Grid is displayed in foreground, Values: 0 | 1
;              Standard: 0 = Background
; Optional PL  Plottermode, the values will be displayed as curve
;              Range: 0 - 3, Values <> 0 define the strength of the line
;              Standard: 0 = bar chart
; ------------------------------------------------------------------------------
; Return-values:
; If the funtion fails it returns: 0 (False).
; If not, the width and height of the created diagram will be returned (seperated by "|")
; Based on the Parameter XD und YD and the returned values other controls can be positioned
; ------------------------------------------------------------------------------
; Specialities:
; This function needs the GDIPlus.dll.
; This function uses "__Diagramm__" as prefix for functions and label.
; This prefix should not be used in the calling script.
; This function uses Gui number 99 internally.
; This Gui number should not be used in the calling script.
; ------------------------------------------------------------------------------
; Thanks:
; I especially thank
;     jonny & tonne for    http://www.autohotkey.com/forum/post-107890.html
;     holomind for         http://www.autohotkey.com/forum/topic12012.html
;     Sean for             http://www.autohotkey.com/forum/topic17179.html
; and all the others, that posted about GDI/GDIPlus in the ahk-forum.
; ------------------------------------------------------------------------------
__Diagramm__( G#
            , XD
            , YD
            , VL
            , HY
            , YH
            , YL
            , SY
            , MX
            , FX
            , SX
            , VC = 0
            , BC = 0
            , GC = 0
            , HC = 0
            , GF = 0
            , PL = 0 )
{
   ; HTML-Colors in BGR-Format
   Static Black := 0x000000
   Static Green := 0x008000
   Static Silver := 0xC0C0C0
   Static Lime := 0x00FF00
   Static Gray := 0x808080
   Static Olive := 0x800080
   Static White := 0xFFFFFF
   Static Yellow := 0x00FFFF
   Static Maroon := 0x000080
   Static Navy := 0x800000
   Static Red := 0x0000FF
   Static Blue := 0xFF0000
   Static Purple := 0x800080
   Static Teal := 0x808000
   Static Fuchsia := 0xFF00FF
   Static Aqua := 0xFFFF00
   Static Grid := 0xD8E9EC
   ; Prefix for functions, label, etc.
   Static PRE := "__Diagramm__"
   ; Sonstige statische Variablen
   Static SHD
   Static SYL
   Static SF
   Static SFX
   Static XB
   Static YB
   Static PICX
   Static PICY
   Static PHID
   Static PVID
   Static CC
   Static TT
   Static RL
   MSG := ""
   PNG := A_Temp . "\__Diagramm__.png"
   ; check Parameter and set to Standard if neccessary
   GoSub, %PRE%Parameter
   If (MSG) {
      MsgBox, 262160, %PRE%, %MSG%
      ErrorLevel := 1
      Return False
   }
   ; process axis-labeling
   GoSub, %PRE%Achsen
   If (MSG) {
      MsgBox, 262160, %PRE%, %MSG%
      ErrorLevel := 1
      Return False
   }
   ; build diagramm
   SFX := FX
   HD := HY
   WD := MX * FX
   SysGet, XB, 45
   Sysget, YB, 46
   ; labeling of Y-Axis
   GH := 0
   GW := 0
   If (SYT) {
      X := XD
      GW := X + SYM - 1
      YM := YD + YB + (SYH / 2)
      Loop, %SY0% {
         StringSplit, SP, SY%A_Index%, `;
         If (SP0 = 3 And SP2 <> "" And SP3 <> "") {
            O := SP2 = "C" ? "Center"
              :  SP2 = "R" ? "Right"
              :  ""
            Y := YM + SP1 - (SYH / 2)
            Gui, %G#%:Add, Text
               , x%X% y%Y% w%SYM% h%SYH% %O% 0x200 BackgroundTrans
               , %SP3%
            GH := Y + SYH - 1
         }
      }
   }
   ; build diagram-background
   DX := XD + SYM + (SYH // 2) + XB
   DY := YD + (SYH // 2) + YB
   GW := DX + WD + XB - 1
   If (DY + HD + YB - 1) > GH {
      GH := DY + HD + YB - 1
   }
   Gui, 99:+LastFound
   ; Device Context (DC) for the GUI,
   ; that is dram to
   WDC := DllCall("GetDC", UInt, WinExist())
   If Not WDC {
      MsgBox, 262160, %PRE%, Fehler beim Aufruf von GetDc!
      ErrorLevel := 1
      Return False
   }
   ; DC for the background of the grafic (the paper)
   PDC := DllCall("CreateCompatibleDC", UInt, 0)
   If Not PDC {
      MsgBox, 262160, %PRE%, Fehler beim Aufruf von CreateCompatibleDC!
      ErrorLevel := 1
      Return False
   }
   ; Eine Bitmap auf dem Papier erzeugen
   PDC_BM := DllCall("CreateCompatibleBitmap", UInt, WDC, UInt, WD, UInt, HD)
   If Not PDC_BM {
      MsgBox, 262160, %PRE%, Fehler beim Aufruf von CreateCompatibleBitmap!
      ErrorLevel := 1
      Return False
   }
   DllCall("SelectObject", UInt, PDC, UInt ,PDC_BM)

   ; create Paint-tools for für Frame (PEN) and background (BRUSH)
   ;  and change the paper
   PEN := DllCall( "CreatePen", UInt, 0, UInt, 0, UInt, BC )
   DllCall("SelectObject", UInt, PDC, UInt, PEN)
   BRUSH := DllCall( "CreateSolidBrush", UInt, BC )
   DllCall("SelectObject", UInt, PDC, UInt, BRUSH)
   ; now draw a rectangle
   DllCall("Rectangle", UInt, PDC, UInt, 0, UInt, 0, UInt, WD, UInt, HD)
   ; release the Paint-tools
   DllCall("DeleteObject", UInt, PEN)
   DllCall("DeleteObject", UInt, BRUSH)
   ; conditionally draw grid in background
   If Not (GF) {
      GoSub, %PRE%Raster
   }
   ; draw diagram
   X := 0
   F := HD / (YH - YL)
   SHD := HD
   SYL := YL
   SF := F
   VCI := 0
   RL := "|"
   CC := ""
   PEN := ""
   BRUSH := ""
   Loop, Parse, VL, `n
   {
      If (A_Index > MX) {
         Break
      }
      StringSplit, SP, A_LoopField, |
      StringReplace, V, SP2, `,, .
      If (PL) {

      }
      If (V <= YL) {
         If (PL) {
            V := YL
         } Else {
            X += FX
            RL .= A_Index . ";" . SP1 . ";" . SP2 . "|"
            Continue
         }
      }
      If (V > YH) {
         V := YH
      }
      H := Round((V - YL) * F)
      If (PL) {
         If (PEN = "") {
            X += PL // 2
            PEN := DllCall("CreatePen", UInt, 0, UInt, PL, UInt, VC1)
            DllCall("SelectObject", UInt, PDC, UInt, PEN)
         }
         If (A_Index = 1) {
            DllCall("MoveToEx", UInt, PDC, UInt, X, UInt, HD - H, UInt, 0)
         } Else {
            DllCall("LineTo", UInt, PDC, UInt, X, UInt, HD - H)
         }
      } Else {
         VCI := ++VCI > VC0 ? 1 : VCI
         If (CC != VC%VCI%) {
            CC := VC%VCI%
            If (PEN) {
               DllCall("DeleteObject", UInt, PEN)
            }
            PEN := DllCall("CreatePen", UInt, 0, UInt, 0, UInt, CC)
            DllCall("SelectObject", UInt, PDC, UInt, PEN)
            If (BRUSH) {
               DllCall("DeleteObject", UInt, BRUSH)
            }
            BRUSH := DllCall( "CreateSolidBrush", UInt, CC )
            DllCall("SelectObject", UInt, PDC, UInt, BRUSH)
         }
         DllCall("Rectangle", UInt, PDC, UInt, X, UInt, HD - H
               , UInt, X + FX, UInt, HD)
      }
      X += FX
      RL .= A_Index . ";" . SP1 . ";" . SP2 . "|"
   }
   DllCall("DeleteObject", UInt, BRUSH)
   DllCall("DeleteObject", UInt, PEN)
   ; conditionally draw grid in foreground
   If (GF) {
      GoSub, %PRE%Raster
   }
   ; save diagram as picture and display
   MSG := __Diagramm__Speichern(PDC_BM, PNG)
   ; release objekts
   DllCall("DeleteObject", UInt, PDC)
   DllCall("DeleteObject", UInt, PDC_BM)
   DllCall("ReleaseDC", UInt, 0, UInt, WDC)
   Gui, 99:Destroy
   If (MSG) {
      Msgbox, 262160, %PRE%, %MSG%
      ErrorLevel := 1
      Return False
   }
   X := DX - 2
   Y := DY - 2
   Gui, %G#%:Add, Pic, x%X% y%Y% g%PRE%Pic hwndPICID +E0x200, %PNG%
   ControlGetPos, PICX, PICY, , , , ahk_id %PICID%
   XX := PICX - X
   ; Label of X-Axis
   If (SXT) {
      P := 0
      Y := DY + HD + YB + (SYH // 2) - 1
      GH := Y + SYH - 1
      Loop, %SX0% {
         StringSplit, SP, SX%A_Index%, `;
         SP1 *= FX
         If (SP0 = 3 And SP2 <> "" And SP3 <> "") {
            If (SP2 = "L") {
               X := DX + P
               W := SP1 - P
               P := SP1
               Gui, %G#%:Add, Text
                  , x%X% y%Y% w%W% h%SYH% 0x200 Center BackgroundTrans
                  , %SP3%
               If (X + W - 1) > GW {
                  GW := X + W - 1
               }
            } ELSE {
               X := DX + SP1
               Gui, %G#%:Add, Text
                  , x%X% y%Y% h%SYH% 0x200 BackgroundTrans hwndCTID
                  , %SP3%
               ControlGetPos, , , W, , , ahk_id %CTID%
               X := X - (W // 2) + XX
               ControlMove, , X, , , , ahk_id %CTID%
               P := X + W
               If (P > GW) {
                  GW := P
               }
            }
         }
      }
   }
   ; at last the Gui for the CrossHair
   Gui, 99:+Alwaysontop +ToolWindow +LastFound +Owner%G#%
   Gui, 99:Margin, 0, 0
   VC := SubStr(VC1, 1, 2) . SubStr(VC1, -1)
       . SubStr(VC1, 5, 2) . SubStr(VC1, 3, 2)
   Gui, 99:Color, %VC%
   Y := HD // 2
   W := WD + 2
   Gui, 99:Add, Progress
      , x0 y%Y% h3 w%W% c%HC% hwndPHID, 100
   Control, ExStyle, -0x20000, , ahk_id %PHID%
   X := WD // 2
   H := HD + 2
   Gui, 99:Add, Progress
      , x%X% y0 h%H% w3 Vertical c%HC% hwndPVID, 100
   Control, ExStyle, -0x20000, , ahk_id %PVID%
   Gui, 99:Show, w%WD% h%HD% Hide
   Winset, TransColor, %VC%
   Gui, 99:-Caption
   ; And done!
   Return Round(GW - XD) . "|" . Round(GH - YD)
   ; ===========================================================================
   ; Subroutines ===============================================================
   ; ===========================================================================
   ; Gui-Routines
   ; ---------------------------------------------------------------------------
   __Diagramm__Pic:
      MouseGetPos, MX, MY, WID
      WinGetPos, WX, WY, , , ahk_id %WID%
      IX := ((MX - PICX - XB + SFX - 1) // SFX)
      If RegExMatch(RL
                  , "S)\|" . IX . ";[^;]+;[^\|]+\|"
                  , RX) {
         RX := SubStr(RX, 2, -1)
         TT := ""
         Loop, Parse, RX, `;
         {
            If (A_Index = 2) {
               TT .= A_LoopField . " : "
               Continue
            }
            If (A_Index = 3) {
               TT .= A_LoopField
               V := A_LoopField
               Break
            }
         }
         StringReplace, V, V, `,, ., All
         X := MX - PICX - XB -1
         Y := SHD - Round((V - SYL) * SF) - 1
         ControlMove, , X, , , , ahk_id %PVID%
         ControlMove, , , Y, , , ahk_id %PHID%
         X := WX + PICX + XB - 1
         Y := WY + PICY + YB - 1
         Gui, 99:Show, x%X% y%Y% NA
         ToolTip, %TT%
         KeyWait, LButton
         ToolTip
         Gui, 99:Hide
      } Else {
         ToolTip
         Gui, 99:Hide
      }
   Return
   ; ---------------------------------------------------------------------------
   ; checking parameters
   ; ---------------------------------------------------------------------------
   __Diagramm__Parameter:
      MSG := ""
      If (G# < 1 Or G# > 99) {
         MSG := "Der Parameter G# ist ungültig:`n" . G#
         Return
      }
      G# := Round(G#)
      If (XD + 0) = "" {
         MSG := "Der Parameter XD ist ungültig:`n" . XD
         Return
      }
      XD := Round(Abs(XD))
      If (YD + 0) = "" {
         MSG := "Der Parameter YD ist ungültig:`n" . YD
         Return
      }
      YD := Round(Abs(YD))
      If Not InStr(VL, "|") {
         MSG := "Der Parameter VL ist ungültig!"
         Return
      }
      If Not ((HY + 0) > 0) {
         MSG := "Der Parameter HY ist ungültig:`n" . HY
         Return
      }
      HY := Round(Abs(HY))
      If (YH + 0) = "" {
         MSG := "Der Parameter YH ist ungültig:`n" . YH
         Return
      }
      If (YL + 0) = "" {
         MSG := "Der Parameter YL ist ungültig:`n" . YL
         Return
      }
      If Not (YL < YH) {
         MSG := "Der Parameter YL ist nicht kleiner als YH:`n"
              . YL . " - " . YH
         Return
      }
      If (SY) {
         If Not InStr(SY, "|") {
            MSG := "Der Parameter SY ist ungültig:`n" . SY
            Return
         }
      }
      If Not ((MX + 0) > 0) {
         MSG := "Der Parameter MX ist ungültig:`n" . MX
         Return
      }
      MX := Round(MX)
      If Not ((FX + 0) > 0) {
         MSG := "Der Parameter FX ist ungültig:`n" . FX
         Return
      }
      FX := Round(FX)
      If (SX) {
         If Not InStr(SX, "|") {
            MSG := "Der Parameter SX ist ungültig:`n" . SX
            Return
         }
      }
      If (VC = 0) {
         VC := Gray
      }
      StringSplit, VC, VC, |
      Loop, %VC0%
      {
         CC := VC%A_Index%
         If (%CC% != "") {
            VC%A_Index% := %CC%
            Continue
         }
         If Not RegExMatch(CC, "i)^0x[0-9a-f]{6}$") {
            MSG := "Parameter VC: Die Angabe " . CC . " ist ungültig!"
            Return
         }
         VC%A_Index% := SubStr(CC, 1, 2) . SubStr(CC, -1)
                      . SubStr(CC, 5, 2) . SubStr(CC, 3, 2)
      }
      If (BC = 0) {
         BC := White
      } Else {
         If (%BC% != "") {
            BC := %BC%
         } Else {
            If Not RegExMatch(BC, "i)^0x[0-9a-f]{6}$") {
               MSG := "Parameter BC: Die Angabe " . BC . " ist ungültig!"
               Return
            }
            BC := SubStr(BC, 1, 2) . SubStr(BC, -1)
                . SubStr(BC, 5, 2) . SubStr(BC, 3, 2)
         }
      }
      If (GC = 0) {
         GC := Grid
      } Else {
         If (%GC% != "") {
            GC := %GC%
         } Else {
            If Not RegExMatch(GC, "i)^0x[0-9a-f]{6}$") {
               MSG := "Parameter GC: Die Angabe " . GC . " ist ungültig!"
               Return
            }
            GC := SubStr(GC, 1, 2) . SubStr(GC, -1)
                . SubStr(GC, 5, 2) . SubStr(GC, 3, 2)
         }
      }
      ; Achtung: HC wird als RGB-Wert benötigt!
      If (HC = 0) {
         HC := SubStr(Red, -1) . SubStr(Red, 5, 2) . SubStr(Red, 3, 2)
      } Else {
         If (%HC% != "") {
            HC := SubStr(%HC%, -1) . SubStr(%HC%, 5, 2) . SubStr(%HC%, 3, 2)
         } Else {
            If Not RegExMatch(HC, "i)^0x[0-9a-f]{6}$") {
               MSG := "Parameter HC: Die Angabe " . HC . " ist ungültig!"
               Return
            }
         }
      }
      If (GF != 0 And GF != 1) {
         MSG := "Der Parameter GF ist ungültig:`n" . GF
         Return
      }
      If PL Not Between 0 And 3
      {
         MSG := "Der Parameter PL ist ungültig:`n" . PL
         Return
      }
   Return
   ; ---------------------------------------------------------------------------
   ; check parameters SX and SY for Axis-labeling
   ; ---------------------------------------------------------------------------
   __Diagramm__Achsen:
      MSG := ""
      SYW := SYH := SYM := 0
      SXT := SYT := ""
      ; process Y-Axis labeling
      If (SY) {
         StringSplit, SY, SY, |
         Loop, %SY0% {
            StringSplit, SP, SY%A_Index%, `;
            If (SP0 = 3 And SP1 <> "" And SP3 <> "") {
               O := SP2 = "C" ? "0x200 Center"
                 :  SP2 = "R" ? "0x200 Right"
                 :  "0x200"
               Gui, %G#%:Add, Text, x%XD% y%YD% %O% hwndCTID Hidden, %SP3%
               ControlGetPos, , , SYW, SYH, , ahk_id %CTID%
               If (SYW > SYM) {
                  SYM := SYW
                  SYT := SP3
               }
            }
         }
      }
      ; process X-Axis labeling
      If (SX) {
         StringSplit, SX, SX, |
         Loop, %SX0% {
            StringSplit, SP, SX%A_Index%, `;
            If (SP0 = 3 And SP2 <> "" And SP3 <> "") {
               SXT := SP3
               Break
            }
         }
      }
   Return
   ; ---------------------------------------------------------------------------
   ; draw Grid
   ; ---------------------------------------------------------------------------
   __Diagramm__Raster:
      ; now the grid
      PEN := DllCall("CreatePen", UInt, 0, UInt, 0, UInt, GC)
      DllCall("SelectObject", UInt, PDC, UInt, PEN)
      If (SY) {
         X := 0
         Loop, %SY0% {
            StringSplit, SP, SY%A_Index%, `;
            If (SP1 > 1 And SP1 < HD) {
               Y := SP1 - 1
               DllCall("MoveToEx", UInt, PDC, UInt, 0, UInt, Y, UInt, 0)
               DllCall("LineTo", UInt, PDC, UInt, WD, UInt, Y)
            }
         }
      }
      If (SX) {
         Y := 0
         Loop, %SX0% {
            StringSplit, SP, SX%A_Index%, `;
            SP1 *= FX
            If (SP1 > 1 And SP1 < WD) {
               X := SP1 - 1
               DllCall("MoveToEx", UInt, PDC, UInt, X, UInt, 0, UInt, 0)
               DllCall("LineTo", UInt, PDC, UInt, X, UInt, HD)
            }
         }
      }
      DllCall("DeleteObject", UInt, PEN)
   Return
}
; ==============================================================================
__Diagramm__Speichern(ByRef hBitMap, ByRef File)
{
   FileDelete, %File%
   VarSetCapacity(wFile, (StrLen(File) * 2) + 1)
   DllCall("kernel32\MultiByteToWideChar"
         , UInt, 0
         , UInt, 0
         , UInt, &File
         , Int, -1
         , UInt, &wFile
         , Int, StrLen(File) + 1)
   SplitPath, File, , , Ext
   hGDIPDLL := DllCall("LoadLibrary", Str, "GDIplus.dll")
   If (hGDIPDLL = 0) {
      Return, "Die GDIPlus.dll konnte nicht gefunden werden!"
   }
   VarSetCapacity(vGDIP, 4 * 4, 0)
   NumPut(1, vGDIP)
   RET := DllCall("GDIplus\GdiplusStartup"
                , UIntP, hGDIP
                , UInt, &vGDIP
                , UInt, 0)
   If (RET != 0) {
      DllCall("FreeLibrary", UInt, GDIPL)
      Return, "GDIPlus konnte nicht gestartet werden!"
   }
   hBM := 0
   DllCall("GDIplus\GdipCreateBitmapFromHBITMAP"
         , UInt, hBitMap
         , UInt, 0
         , UIntP, hBM)
   If (hBM = 0) {
      DllCall("GDIplus\GdiplusShutdown", UInt, hGDIP)
      DllCall("FreeLibrary", UInt, hGDIPDLL)
      Return, "GDIPlus: Das Diagrammbild konnte nicht erzeugt werden!"
   }
   DllCall("gdiplus\GdipGetImageEncodersSize"
         , UintP, nCount
         , UintP, nSize)
   VarSetCapacity(vEnc, nSize)
   DllCall("gdiplus\GdipGetImageEncoders"
         , Uint, nCount
         , Uint, nSize
         , Uint, &vEnc)
   Loop, %nCount% {
         pTypes := NumGet(vEnc, (76 * (A_Index - 1)) + 44)
         nSize :=DllCall("kernel32\WideCharToMultiByte"
                       , UInt, 0
                       , UInt, 0
                       , UInt, pTypes
                       , Int, -1
                       , UInt, 0
                       , Int,  0
                       , UInt, 0
                       , UInt, 0)
         VarSetCapacity(sTypes, nSize)
         DllCall("kernel32\WideCharToMultiByte"
               , UInt, 0
               , Uint, 0
               , Uint, pTypes
               , Uint, -1
               , Str, sTypes
               , UInt, nSize + 1
               , UInt, 0
               , UInt, 0)
         If !InStr(sTypes, "." . Ext)
            Continue
         pCodec := &vEnc + (76 * (A_Index - 1))
         Break
   }
   If (!pCodec) {
      DllCall("GDIplus\GdipDisposeImage", "Uint", hBM)
      DllCall("GDIplus\GdiplusShutdown"
            , UInt, hGDIP)
      DllCall("FreeLibrary", UInt, hGDIPDLL)
      Return, "GDIPlus:Es konnte kein passender Codec gefunden werden!"
   }
   RC := DllCall("GDIplus\GdipSaveImageToFile"
                , UInt, hBM
                , UInt, &wFile
                , UInt, pCodec
                , UInt, 0)
   DllCall("GDIplus\GdipDisposeImage", "Uint", hBM)
   DllCall("GDIplus\GdiplusShutdown", UInt, hGDIP)
   DllCall("FreeLibrary", UInt, hGDIPDLL)
   If (RC) {
      Return, "GDIPlus: Das Bild konnte nicht gespeichert werden! RC: " . RC
   }
   Return 0
}
; ==============================================================================


Some demos:



Code:
#NoEnv
#Include __Diagramm__.ahk

; ######################################
; hier kommt nur noch meine messreihe
; typische messreihe
; #####################################
zu_testzwecken:
; Ich habe die Darstellung etwas verkürzt
messreihe =
(
1;113,2813`n2;177,7344`n3;178,7109`n4;180,6641`n5;179,6875`n6;181,6406
7;181,6406`n8;183,5938`n9;185,5469`n10;186,5234`n11;187,5`n12;189,4531
13;191,4063`n14;195,3125`n15;199,2188`n16;202,1484`n17;206,0547`n18;208,0078
19;208,9844`n20;210,9375`n21;213,8672`n22;215,8203`n23;216,7969`n24;219,7265
25;222,6563`n26;227,5391`n27;230,4688`n28;234,375`n29;239,2578`n30;244,1406
31;247,0703`n32;250`n33;252,9297`n34;254,8828`n35;259,7656`n36;262,6953
37;264,6484`n38;270,5078`n39;271,4844`n40;273,4375`n41;274,4141`n42;279,2969
43;283,2031`n44;286,1328`n45;288,0859`n46;289,0625`n47;295,8984`n48;295,8984
49;301,7578`n50;303,7109`n51;307,6172`n52;311,5234`n53;314,4531`n54;317,3828
55;320,3125`n56;326,1719`n57;330,0781`n58;331,0547`n59;333,0078`n60;336,9141
61;338,8672`n62;340,8203`n63;343,75`n64;347,6563`n65;351,5625`n66;356,4453
67;359,375`n68;366,2109`n69;366,2109`n70;371,0938`n71;375`n72;374,0234
73;379,8828`n74;384,7656`n75;388,6719`n76;388,6719`n77;389,6484`n78;392,5781
79;395,5078`n80;396,4843`n81;399,414`n82;405,2734`n83;407,2266`n84;412,1094
85;414,0625`n86;417,9687`n87;420,8984`n88;417,9687`n89;417,9687`n90;416,9922
91;418,9453`n92;419,9219`n93;436,5235`n94;458,9843`n95;474,6094`n96;481,4453
97;487,3047`n98;488,2812`n99;500`n100;503,9063`n101;500`n102;510,7422
103;507,8125`n104;513,6719`n105;515,625`n106;526,3672`n107;529,2969
108;532,2266`n109;540,0391`n110;544,9219`n111;554,6875`n112;556,6406
113;558,5938`n114;567,3828`n115;568,3594`n116;576,1719`n117;578,125
118;588,8671`n119;591,7969`n120;598,6328`n121;602,5391`n122;610,3516
123;619,1406`n124;625`n125;626,9531`n126;634,7656`n127;636,7188`n128;640,6249
129;639,6484`n130;651,3672`n131;656,25`n132;662,1093`n133;660,1563`n134;666,0156
135;674,8047`n136;679,6875`n137;685,5469`n138;698,2422`n139;706,0547
140;699,2188`n141;713,8671`n142;715,8203`n143;722,6563`n144;727,5391
145;734,375`n146;739,2578`n147;744,1406`n148;751,9531`n149;757,8125
150;764,6484`n151;769,5312`n152;776,3672`n153;780,2735`n154;785,1563
155;792,9687`n156;795,8984`n157;800,7813`n158;803,7109`n159;811,5234
160;814,4531`n161;814,4531`n162;823,2422`n163;830,0781`n164;832,0313
165;833,0079`n166;841,7968`n167;849,6094`n168;856,4453`n169;858,3984
170;855,4688`n171;855,4688`n172;859,3751`n173;860,3516`n174;877,9297
175;870,1172`n176;967,7734`n177;937,5`n178;884,7656`n179;891,6015
180;881,8359`n181;898,4375`n182;895,5079`n183;894,5313`n184;897,4609
185;907,2266`n186;898,4375`n187;905,2734`n188;900,3906`n189;0`n190;0`n191;0
192;0`n193;0`n194;0`n195;0`n196;0`n197;0`n198;0`n199;0`n200;30,27344`n201;0
202;0`n203;0`n204;0`n205;0`n206;0`n207;0`n208;0`n209;0`n210;1200`n211;0
212;0`n213;0`n214;0`n215;0`n216;0`n217;0`n218;0`n219;0`n220;1150`n221;0
222;0`n223;0`n224;0`n225;0`n226;0`n227;0`n228;0`n229;0`n230;1100`n231;0
232;0`n233;0`n234;0`n235;0`n236;0`n237;0`n238;0`n239;0`n240;1050`n241;0
242;0`n243;0`n244;0`n245;0`n246;0`n247;0`n248;0`n249;0`n250;1000
)
StringReplace, messreihe, messreihe, `;, |, All
; Anzahl der Messwerte
MX := 250
; Faktor für X-Achse
FX := 2
; Höhe des Diagrammfeldes
DH := 360
; Höchster (H) und niedrigster (L) anzuzeigender Wert
YH := 1200
YL := 0
; Beschriftung für Y-Achse
YScaler := ""
I := 0
C := 1200
D1 := 50
D2 := DH // (C // 50)
Loop, % (DH // D2) {
   YScaler .= I . (Mod(C, 100) ? ";;|" : ";R;" . C . "|")
   C -= D1
   I += D2
}
StringTrimRight, YScaler, YScaler, 1
; Beschriftung für Y-Achse
XScaler := ""
I := 0
D := 10
Loop, % (MX // D) {
   I += 10
   XScaler .= I . (Mod(I, 50) ? ";;|" : ";C;" . I . "|")
}
StringTrimRight, XScaler, XScaler, 1
; Ränder
XM := 10
YM := 10
; Los geht's
Gui, +ToolWindow
Gui, Margin, %XM%, %YM%
Gui, Font, s10, Tahoma
Gui, Add, Text, h20 Center 0x200 vÜberschrift
; Diagrammposition
DX := XM
DY := 40
RC := __Diagramm__( 1, DX, DY, messreihe, DH, YH, YL, YScaler, MX, FX, XScaler
                  , 0, 0, 0, 0, 0, 2 )
If Not RC {
   MsgBox, Fehler beim Aufruf der Funktion __Diagramm__()
   ExitApp
}
DW := DH := 0
If RegExMatch(RC, "^(?P<W>\d+)\|(?P<H>\d+)$", D) {
   X := XM
   Y := YM + DH + YM - 1
   GuiControl, Move, Überschrift, w%DW% h20
   Gui, Font, s12
   GuiControl, Font, Überschrift
   GuiControl, , Überschrift
      , Breite Diagrammbereich : %DW% Pixel - Höhe Diagrammbereich : %DH% Pixel
   Gui, Font, s10
   X := DX
   Y := DY + DH + YM
   W := DW // 100 * 25
   Gui, Add, Button, x%X% y%Y% w%W%, Aktion 1
   X := DX + (DW // 2) - (W // 2)
   Gui, Add, Button, x%X% yp wp, Aktion 2
   X := DX + DW - W
   Gui, Add, Button, x%X% yp wp, Aktion 3
}

Gui, Show, AutoSize , % "    Messreihe vom " . A_DD . "." . A_MM . "." A_YYYY
Return
; ------------------------------------------------------------------------------
GuiCLose:
GuiEscape:
ExitApp





Code:
#NoEnv
#Include __Diagramm__.ahk
; Schuldenliste generieren
Schulden := ""
Städte := "München|Berlin|Bonn"
StringSplit, Stadt, Städte, |
Farben := "Black|Red|0xFFEF00"
Monate := "Januar|Februar|März|April|Mai|Juni|Juli|August|September|Oktober|"
Monate .= "November|Dezember"
StringSplit, Monat, Monate, |
I := 0
Loop, 36 {
   I := ++I > 3 ? 1 : I
   Random, U, 7000, 10000
   Schulden .= Stadt%I% . "|" . U . "`n"
}
StringTrimRight, Schulden, Schulden, 1
; Maximale Anzahl der darzustellenden Werte
MX := 36
; Faktor für die X-Achse
FX := 20
; Höhe des Diagrammfeldes
DH := 500
; Höchster und niedrigster anzuzeigender Wert
YH := 10000
YL := 5000
; Beschriftung für Y-Achse
YScaler := ""
I := 0
C := YH
D1 := 100
D2 := DH // ((YH - YL) // D1)
Loop, % (DH // D2) + 1 {
   YScaler .= I . (Mod(C, 500) ? ";;|" : ";R;"
            . SubStr(C, 1, -3) . "." . SubStr(C, -2) . "|")
   C -= D1
   I += D2
}
StringTrimRight, YScaler, YScaler, 1
; Beschriftung für Y-Achse
XScaler := ""
I := 0
D := 3
Loop, % (MX // D) {
   I += D
   XScaler .= I . ";L;" . Monat%A_Index% . "|"
}
StringTrimRight, XScaler, XScaler, 1
; Ränder
XM := 10
YM := 10
; Gui
Gui, +ToolWindow
Gui, Margin, %XM%, %YM%
Gui, Font, s8
RC := __Diagramm__(  1, XM, YM, Schulden, DH, YH, YL, YScaler, MX, FX, XScaler
                  , Farben, "Silver", "White", "Blue" )
If Not RC{
   MsgBox, Fehler beim Aufruf der Funktion __Diagramm__()
   ExitApp
}
Gui, Show, , % "    Durchschnittliche monatliche Neuverschuldung 2007 in Tsd. €"
Return
; ------------------------------------------------------------------------------
GuiCLose:
GuiEscape:
ExitApp





Code:
#NoEnv
#Include __Diagramm__.ahk

; ------------------------------------------------------------------------------
; Funktionsparameter:
; Höhe des Diagrammfeldes
H_D := 360
; Höchster und niedrigster anzuzeigender Wert
H_Y := 1
L_Y := -1
; Maximale Anzahl der darzustellenden Werte
M_X := 361
; Faktor für die X-Achse
F_X := 2
; Raster und Beschriftung für Y-Achse
I := 0
D := H_D // 20
S_Y := I . ";R;1,00|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";R;0,00|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";;|"
S_Y .= (I += D) . ";R;-1,00"
; Raster und Beschriftung für X-Achse
S_X := " "
V_I := 1
Loop, % (M_X // 45) {
   V_I += 45
   S_X .= V_I . ";;|"
}
S_X .= M_X . ";L;Kurvenverlauf über den Bereich von 0 - 360°"
; Werteliste erstellen: Sinuskurve
V_L := ""
V_I := 0
Loop, %M_X% {
   V_L .= V_I . "|" . Sin(V_I * 0.01745329252) . "`n"
   V_I++
}
V_L := SubStr(V_L, 1, -1)
; Diagramm anzeigen
Gui, Margin, 20, 20
Gui, Font, s10
If Not __Diagramm__(  1, 20, 20, V_L, H_D, H_Y, L_Y, S_Y, M_X, F_X, S_X
                , "Lime", "Gray", "Silver", 0, 0, 2)
   ExitApp
Gui, Show, , Sinuskurve
Return
; ------------------------------------------------------------------------------
GuiCLose:
GuiEscape:
ExitApp
Back to top
View user's profile Send private message
SoggyDog



Joined: 02 May 2006
Posts: 223
Location: Greeley, CO

PostPosted: Mon Jun 02, 2008 2:45 pm    Post subject: Reply with quote

Cool!

I might have to resume work on my Biorhythms and re-work it to use this instead of the third-party rmChart.dll.

Thanks!
_________________

SoggyDog
Download AutoHotKey Wallpaper
Does 'Fuzzy Logic' tickle?
Back to top
View user's profile Send private message Send e-mail Visit poster's website MSN Messenger
Laszlo



Joined: 14 Feb 2005
Posts: 4031
Location: Pittsburgh

PostPosted: Mon Jun 02, 2008 7:33 pm    Post subject: Reply with quote

Nicely written! It makes graphing really easy. (In the Popup calculator script there is a simpler graphing facility, consuming some 150 lines. There were earlier some more graphing scripts posted to the Forum, like shimanov’s analytic graphing facility.)
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Mon Jun 02, 2008 11:59 pm    Post subject: Reply with quote

So good!
_________________
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group