!! Copyright (C) Stichting Deltares, 2005-2020. !! !! This file is part of iMOD. !! !! This program is free software: you can redistribute it and/or modify !! it under the terms of the GNU General Public License as published by !! the Free Software Foundation, either version 3 of the License, or !! (at your option) any later version. !! !! This program is distributed in the hope that it will be useful, !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! GNU General Public License for more details. !! !! You should have received a copy of the GNU General Public License !! along with this program. If not, see . !! !! Contact: imod.support@deltares.nl !! Stichting Deltares !! P.O. Box 177 !! 2600 MH Delft, The Netherlands. !! MODULE MOD_GRAPH USE WINTERACTER USE RESOURCE USE MOD_DBL USE MODPLOT USE MOD_GRAPH_PAR USE MOD_UTL CONTAINS !###====================================================================== SUBROUTINE GRAPH_INIT(WMODE,LMULT,LEXPORT,DIR,GRAPHTXT,SUBTITLE,IBATCH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: WMODE INTEGER,INTENT(IN),OPTIONAL :: IBATCH LOGICAL,INTENT(IN),OPTIONAL :: LEXPORT,LMULT CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: DIR,GRAPHTXT,SUBTITLE CHARACTER(LEN=256) :: PNGNAME LOGICAL :: LMESSAGE INTEGER :: NG,I,IXDLU,IYDLU,IXPIX,IYPIX,NGRAPHS,IMULT LEXPORTIT=.FALSE.; IF(PRESENT(LEXPORT))LEXPORTIT=LEXPORT LMESSAGE =.FALSE.; IF(PRESENT(IBATCH))THEN; IF(IBATCH.EQ.0)LMESSAGE=.TRUE.; ENDIF IGBITMAP=0 CALL WDIALOGLOAD(ID_DSCENTOOL_FIGURE,ID_DSCENTOOL_FIGURE); CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0) IF(PRESENT(LMULT))THEN; IF(LMULT)CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,1); ENDIF !## maximize window IF(LEXPORTIT)THEN IXPIX=WINFOSCREEN(SCREENWIDTH) IYPIX=WINFOSCREEN(SCREENHEIGHT) #if(defined(WINTERACTER11)) CALL WDIALOGUNITSFROMPIXELS(IXPIX,IYPIX,IXDLU,IYDLU) CALL WDIALOGSIZE(IXDLU,IYDLU) #endif ENDIF CALL WDIALOGTITLE('Graph') ; IF(PRESENT(GRAPHTXT))CALL WDIALOGTITLE(TRIM(GRAPHTXT)) CALL WDIALOGPUTIMAGE(ID_ZOOMIN,ID_ICONZOOMIN,1) CALL WDIALOGPUTIMAGE(ID_ZOOMOUT,ID_ICONZOOMOUT,1) CALL WDIALOGPUTIMAGE(ID_ZOOMFULL,ID_ICONZOOMFULL,1) CALL WDIALOGPUTIMAGE(ID_ZOOMBOX,ID_ICONZOOMBOX,1) CALL WDIALOGPUTIMAGE(ID_MOVE,ID_ICONMOVE,1) CALL WDIALOGPUTIMAGE(ID_COPY,ID_ICONCOPY,1) !## how many unique graph-number NGRAPHS=SIZE(GRAPHDIM%GRAPHNAMES); CALL WDIALOGPUTMENU(IDF_MENU1,GRAPHDIM%GRAPHNAMES,NGRAPHS,1) IF(NGRAPHS.EQ.1)THEN; CALL WDIALOGPUTCHECKBOX(IDF_CHECK1,0); CALL WDIALOGFIELDSTATE(IDF_CHECK1,3); ENDIF CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IMULT); I=ABS(IMULT-1); CALL WDIALOGFIELDSTATE(IDF_MENU1,I); CALL WDIALOGFIELDSTATE(IDF_LABEL2,I) CALL WDIALOGPUTSTRING(IDF_LABEL1,'>>> Move your mouse in the graph for coordinates <<<') CALL WDIALOGPUTSTRING(IDF_LABEL3,'') ; IF(PRESENT(SUBTITLE)) CALL WDIALOGPUTSTRING(IDF_LABEL3,TRIM(SUBTITLE)) !## position graph initially IF(ALLOCATED(GRAPHUNITS))DEALLOCATE(GRAPHUNITS); IF(ALLOCATED(GRAPHAREA))DEALLOCATE(GRAPHAREA) IF(ALLOCATED(PGXMIN))DEALLOCATE(PGXMIN); IF(ALLOCATED(PGXMAX))DEALLOCATE(PGXMAX) IF(ALLOCATED(PGYMIN))DEALLOCATE(PGYMIN); IF(ALLOCATED(PGYMAX))DEALLOCATE(PGYMAX) ALLOCATE(GRAPHUNITS(6,NGRAPHS),GRAPHAREA(4,NGRAPHS)) ALLOCATE(PGXMIN(NGRAPHS),PGXMAX(NGRAPHS),PGYMIN(NGRAPHS),PGYMAX(NGRAPHS)) CALL GRAPH_INIT_AREAS(IMULT) !## set y-as to fit all available entries CALL GRAPH_DRAW(1,NGRAPHS,.TRUE.) IF(.NOT.LEXPORTIT)THEN CALL UTL_DIALOGSHOW(-1,-1,0,WMODE) ELSE !## generate all figures DO NG=1,SIZE(GRAPHDIM%GRAPHNAMES) CALL GRAPH_DRAW(NG,NG,.FALSE.) CALL UTL_CREATEDIR(DIR) PNGNAME=TRIM(DIR)//'\'//TRIM(GRAPHDIM(NG)%GRAPHNAMES)//'.PNG' I=INFOERROR(1) CALL WBITMAPSAVE(IGBITMAP,PNGNAME) I=INFOERROR(1) IF(I.NE.0)THEN IF(LMESSAGE)THEN CALL WMESSAGEBOX(OKONLY,EXCLAMATIONICON,COMMONOK,'iMOD cannot SAVE the requested bitmap file called:'//CHAR(13)//& TRIM(PNGNAME),'Error') ELSE WRITE(*,'(/A/)') 'iMOD cannot SAVE the requested bitmap file called: '//TRIM(PNGNAME) ENDIF ELSE IF(NG.EQ.SIZE(GRAPHDIM%GRAPHNAMES))THEN IF(LMESSAGE)THEN CALL WMESSAGEBOX(OKONLY,INFORMATIONICON,COMMONOK,'iMOD SAVED (all) the requested bitmaps in the folder:'//CHAR(13)//& TRIM(DIR)//'\*.PNG'//CHAR(13)//'successfully.','Information') ELSE WRITE(*,'(/A/)') 'iMOD SAVED (all) the requested bitmaps in the folder: '//TRIM(DIR)//'\*.PNG' ENDIF ENDIF ENDIF ENDDO ENDIF END SUBROUTINE GRAPH_INIT !###====================================================================== SUBROUTINE GRAPH_INIT_AREAS(IMULT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IMULT INTEGER :: IGRAPH,NCOL,NROW,ICOL,IROW,NGRAPHS REAL(KIND=DP_KIND) :: DX,DY NGRAPHS=SIZE(GRAPHDIM%GRAPHNAMES) !## set area depending on number of graphs IF(IMULT.EQ.0)THEN DO IGRAPH=1,NGRAPHS GRAPHAREA(1,IGRAPH)=0.0D0; GRAPHAREA(2,IGRAPH)=0.0D0 GRAPHAREA(3,IGRAPH)=1.0D0; GRAPHAREA(4,IGRAPH)=1.0D0 ENDDO ELSE DX=SQRT(DBLE(NGRAPHS)); NCOL=CEILING(DX) DY=DBLE(NGRAPHS)/DBLE(NCOL); NROW=CEILING(DY) DX=1.0D0/DBLE(NCOL); DY=1.0D0/DBLE(NROW) IGRAPH=0; DO IROW=1,NROW; DO ICOL=1,NCOL IGRAPH=IGRAPH+1; IF(IGRAPH.GT.NGRAPHS)EXIT GRAPHAREA(1,IGRAPH)=DBLE(ICOL-1)*DX; GRAPHAREA(2,IGRAPH)=1.0D0-DBLE(IROW )*DY GRAPHAREA(3,IGRAPH)=DBLE(ICOL )*DX; GRAPHAREA(4,IGRAPH)=1.0D0-DBLE(IROW-1)*DY ENDDO; ENDDO ENDIF END SUBROUTINE GRAPH_INIT_AREAS !###====================================================================== SUBROUTINE GRAPH_MAIN(ITYPE,MESSAGE,IEXIT) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: ITYPE INTEGER,INTENT(OUT),OPTIONAL :: IEXIT TYPE(WIN_MESSAGE),INTENT(INOUT) :: MESSAGE INTEGER :: IG1,IG2,IMULT,I CALL WDIALOGSELECT(ID_DSCENTOOL_FIGURE) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IMULT) IF(IMULT.EQ.1)THEN; IG1=1; IG2=SIZE(GRAPHDIM%GRAPHNAMES); ENDIF IF(PRESENT(IEXIT))IEXIT=0 SELECT CASE (ITYPE) CASE (MOUSEMOVE) CALL GRAPH_MOUSE(MESSAGE,0,I) CASE (PUSHBUTTON) SELECT CASE (MESSAGE%VALUE1) CASE (ID_ZOOMIN,ID_ZOOMOUT,ID_ZOOMBOX,ID_MOVE) CALL GRAPH_ZOOM(ID_DSCENTOOL_FIGURE,MESSAGE%VALUE1) CASE (ID_ZOOMFULL) IF(IMULT.EQ.0)THEN; CALL WDIALOGGETMENU(IDF_MENU1,IG1); IG2=IG1; ENDIF; CALL GRAPH_DRAW(IG1,IG2,.TRUE.) CASE (ID_COPY) CALL WCLIPBOARDPUTBITMAP(IGBITMAP) CASE (IDHELP) CALL UTL_GETHELP('5.9.2','TMO.PT.Start') CASE (IDCANCEL) CALL GRAPH_CLOSE(); IF(PRESENT(IEXIT))IEXIT=1 END SELECT CASE (FIELDCHANGED) SELECT CASE (MESSAGE%VALUE2) CASE (IDF_CHECK1) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IMULT); CALL WDIALOGFIELDSTATE(IDF_MENU1,ABS(IMULT-1)); CALL GRAPH_INIT_AREAS(IMULT) IF(IMULT.EQ.0)THEN; CALL WDIALOGGETMENU(IDF_MENU1,IG1); IG2=IG1; ENDIF CALL GRAPH_DRAW(IG1,IG2,.FALSE.) CASE (IDF_MENU1) CALL WDIALOGSELECT(ID_DSCENTOOL_FIGURE) CALL WDIALOGGETMENU(IDF_MENU1,IG1); IG2=IG1 !## redraw image at current zoom-settings CALL GRAPH_DRAW(IG1,IG2,.FALSE.) END SELECT CASE (RESIZE,EXPOSE) !## refresh graph IF(IMULT.EQ.0)THEN; CALL WDIALOGGETMENU(IDF_MENU1,IG1); IG2=IG1; ENDIF CALL GRAPH_DRAW(IG1,IG2,.FALSE.) END SELECT END SUBROUTINE GRAPH_MAIN !###====================================================================== SUBROUTINE GRAPH_CLOSE() !###====================================================================== IMPLICIT NONE IF(WINFOMOUSE(MOUSECURSOR).NE.CURARROW)CALL WCURSORSHAPE(CURARROW) CALL WDIALOGSELECT(ID_DSCENTOOL_FIGURE); CALL WDIALOGUNLOAD() CALL WBITMAPDESTROY(IGBITMAP) DEALLOCATE(GRAPHUNITS,GRAPHAREA,PGXMIN,PGXMAX,PGYMIN,PGYMAX) CALL WINDOWSELECT(MPW%IWIN) CALL IGRSELECT(DRAWWIN,MPW%IWIN) CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0) CALL DBL_IGRUNITS(MPW%XMIN,MPW%YMIN,MPW%XMAX,MPW%YMAX,IOFFSET=1) END SUBROUTINE GRAPH_CLOSE !###====================================================================== SUBROUTINE GRAPH_MOUSE(MESSAGE,IDOWN,IGRAPH) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IDOWN INTEGER,INTENT(OUT) :: IGRAPH TYPE(WIN_MESSAGE),INTENT(INOUT) :: MESSAGE INTEGER :: I,IMULT REAL(KIND=DP_KIND) :: DX,DY,XR,YR,XP,YP CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0); CALL DBL_IGRUNITS(0.0D0,0.0D0,1.0D0,1.0D0) IF(MESSAGE%WIN.EQ.ID_DSCENTOOL_FIGURE)THEN IF(IDOWN.EQ.0.AND.WINFOMOUSE(MOUSECURSOR).NE.CURCROSSHAIR)CALL WCURSORSHAPE(CURCROSSHAIR) CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IMULT) IF(IMULT.EQ.1)THEN !## get right coordinates XP=MESSAGE%GX; YP=MESSAGE%GY DO IGRAPH=1,SIZE(GRAPHAREA,2) IF(MESSAGE%GX.GE.GRAPHAREA(1,IGRAPH).AND.MESSAGE%GX.LE.GRAPHAREA(3,IGRAPH).AND. & MESSAGE%GY.GE.GRAPHAREA(2,IGRAPH).AND.MESSAGE%GY.LE.GRAPHAREA(4,IGRAPH))THEN EXIT ENDIF ENDDO ELSE CALL WDIALOGGETMENU(IDF_MENU1,IGRAPH) ENDIF IF(IGRAPH.GT.SIZE(GRAPHAREA,2))THEN; IGRAPH=0; RETURN; ENDIF DX=GRAPHAREA(3,IGRAPH)-GRAPHAREA(1,IGRAPH); DY=GRAPHAREA(4,IGRAPH)-GRAPHAREA(2,IGRAPH) XR=(MESSAGE%GX-GRAPHAREA(1,IGRAPH))/DX; YR=(MESSAGE%GY-GRAPHAREA(2,IGRAPH))/DY DX=GRAPHUNITS(3,IGRAPH)-GRAPHUNITS(1,IGRAPH); DY=GRAPHUNITS(4,IGRAPH)-GRAPHUNITS(2,IGRAPH) XP=GRAPHUNITS(1,IGRAPH)+XR*DX; YP=GRAPHUNITS(2,IGRAPH)+YR*DY IF(ASSOCIATED(GRAPHDIM(IGRAPH)%XTXT))THEN I=NINT(XP) IF(I.GE.1.AND.I.LE.SIZE(GRAPHDIM(IGRAPH)%XTXT))THEN CALL WDIALOGPUTSTRING(IDF_LABEL1,'Date='//TRIM(GRAPHDIM(IGRAPH)%XTXT(I))//'; Ycrd='//TRIM(UTL_REALTOSTRING(YP))) ELSE CALL WDIALOGPUTSTRING(IDF_LABEL1,'Date=[unknown]; Ycrd='//TRIM(UTL_REALTOSTRING(YP))) ENDIF ELSE IF(GRAPHDIM(IGRAPH)%LDATE)THEN CALL WDIALOGPUTSTRING(IDF_LABEL1,'Date='//TRIM(JDATETOGDATE(INT(XP)))//'; Ycrd='//TRIM(UTL_REALTOSTRING(YP))) ELSE CALL WDIALOGPUTSTRING(IDF_LABEL1,'Xcrd='//TRIM(RTOS(XP,'F',2))//'; Ycrd='//TRIM(UTL_REALTOSTRING(YP))) ENDIF ENDIF ELSE IF(IDOWN.EQ.0.AND.WINFOMOUSE(MOUSECURSOR).NE.CURARROW)CALL WCURSORSHAPE(CURARROW) ENDIF MESSAGE%GX=XP; MESSAGE%GY=YP END SUBROUTINE GRAPH_MOUSE !###====================================================================== SUBROUTINE GRAPH_DRAW(IG,JG,LINI) !###====================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IG,JG LOGICAL,INTENT(IN) :: LINI INTEGER :: IW,IH,I,J,NP,IDD,IDF,NG,N,IGRAPH REAL(KIND=DP_KIND) :: DX,DY,XMIN,YMIN,XMAX,YMAX,X1,X2,Y1,Y2,D1,D2 TYPE(AXESOBJ) :: AXES IDD=ID_DSCENTOOL_FIGURE; IDF=IDF_PICTURE1 !## childwindow - size for the bitmap CALL WDIALOGSELECT(IDD); CALL IGRSELECT(DRAWFIELD,IDF) IW=WINFODRAWABLE(DRAWABLEWIDTH); IH=WINFODRAWABLE(DRAWABLEHEIGHT) IF(IGBITMAP.NE.0)CALL WBITMAPDESTROY(IGBITMAP) CALL WBITMAPCREATE(IGBITMAP,IW,IH) !## select proper bitmap CALL IGRSELECT(DRAWBITMAP,IGBITMAP) !## change plotmode CALL IGRPLOTMODE(MODECOPY) !## plot axis and correct xmin,ymin,xmax,ymax for axes CALL IGRCOLOURN(WRGB(255,255,255)) !## find initial axes IF(LINI)THEN DO IGRAPH=1,SIZE(GRAPHDIM) !## process all graphs on equal "displays" groups AXES%XMIN= HUGE(1.0D0); AXES%XMAX=-HUGE(1.0D0) IF(GRAPHDIM(IGRAPH)%IFIXX.EQ.0)THEN DO NG=IG,JG !## no connected IF(GRAPHDIM(IGRAPH)%IGROUP.NE.GRAPHDIM(NG)%IGROUP)CYCLE DO I=1,SIZE(GRAPH,1) NP=GRAPH(I,NG)%NP XMIN=MINVAL(GRAPH(I,NG)%RX(1:NP)); XMAX=MAXVAL(GRAPH(I,NG)%RX(1:NP)) IF(NP.EQ.1)THEN XMIN=XMIN-0.5D0; XMAX=XMAX+0.5D0 ELSE XMIN=XMIN-(GRAPH(I,NG)%RX(2) -GRAPH(I,NG)%RX(1 ))/2.0D0 XMAX=XMAX+(GRAPH(I,NG)%RX(NP)-GRAPH(I,NG)%RX(NP-1))/2.0D0 ENDIF AXES%XMIN=MIN(AXES%XMIN,XMIN) AXES%XMAX=MAX(AXES%XMAX,XMAX) ENDDO ENDDO ELSE AXES%XMIN=MIN(AXES%XMIN,GRAPHDIM(IGRAPH)%XMIN) AXES%XMAX=MAX(AXES%XMAX,GRAPHDIM(IGRAPH)%XMAX) ENDIF IF(GRAPHDIM(IGRAPH)%IFIXX.EQ.0)THEN IF(AXES%XMIN.EQ.AXES%XMAX)THEN AXES%XMIN=AXES%XMIN-1.0D0; AXES%XMAX=AXES%XMAX+1.0D0 ENDIF DX=(AXES%XMAX-AXES%XMIN)/10.0D0 AXES%XMIN=AXES%XMIN-DX; AXES%XMAX=AXES%XMAX+DX ENDIF AXES%YMIN= HUGE(1.0D0); AXES%YMAX=-HUGE(1.0D0) IF(GRAPHDIM(IGRAPH)%IFIXY.EQ.0)THEN DO NG=IG,JG !## no connected IF(GRAPHDIM(IGRAPH)%IGROUP.NE.GRAPHDIM(NG)%IGROUP)CYCLE DO I=1,SIZE(GRAPH,1) NP=GRAPH(I,NG)%NP YMIN=MINVAL(GRAPH(I,NG)%RY(1:NP)); YMAX=MAXVAL(GRAPH(I,NG)%RY(1:NP)) IF(GRAPH(I,NG)%GTYPE.EQ.1)YMIN=MIN(YMIN,0.0D0) AXES%YMIN=MIN(AXES%YMIN,YMIN) AXES%YMAX=MAX(AXES%YMAX,YMAX) ENDDO ENDDO ELSE AXES%YMIN=MIN(AXES%YMIN,GRAPHDIM(IGRAPH)%YMIN) AXES%YMAX=MAX(AXES%YMAX,GRAPHDIM(IGRAPH)%YMAX) ENDIF IF(GRAPHDIM(1)%IFIXY.EQ.0)THEN IF(AXES%YMIN.EQ.AXES%YMAX)THEN AXES%YMIN=AXES%YMIN-1.0D0; AXES%YMAX=AXES%YMAX+1.0D0 ENDIF DY=(AXES%YMAX-AXES%YMIN)/10.0D0 AXES%YMIN=AXES%YMIN-DY; AXES%YMAX=AXES%YMAX+DY ENDIF DO NG=IG,JG IF(GRAPHDIM(IGRAPH)%IGROUP.NE.GRAPHDIM(NG)%IGROUP)CYCLE PGXMIN(NG)=AXES%XMIN; PGXMAX(NG)=AXES%XMAX PGYMIN(NG)=AXES%YMIN; PGYMAX(NG)=AXES%YMAX ENDDO ENDDO ELSE ENDIF !## process all graphs on equal displays DO IGRAPH=IG,JG !## set area depending on number of synchronized graphs CALL DBL_IGRAREA(GRAPHAREA(1,IGRAPH),GRAPHAREA(2,IGRAPH),GRAPHAREA(3,IGRAPH),GRAPHAREA(4,IGRAPH)) AXES%XMIN=PGXMIN(IGRAPH); AXES%XMAX=PGXMAX(IGRAPH) AXES%YMIN=PGYMIN(IGRAPH); AXES%YMAX=PGYMAX(IGRAPH) IF(GRAPHDIM(IGRAPH)%IFIXX.EQ.0)THEN AXES%IFIXX =0 AXES%XINT =10 ELSE AXES%IFIXX =1 AXES%XINT =GRAPHDIM(IGRAPH)%XINT !## size of arrays IF(ASSOCIATED(GRAPHDIM(IGRAPH)%XTXT))THEN N=SIZE(GRAPHDIM(IGRAPH)%XTXT); ALLOCATE(AXES%XTXT(N),AXES%XPOS(N)) AXES%XTXT=GRAPHDIM(IGRAPH)%XTXT AXES%XPOS=GRAPHDIM(IGRAPH)%XPOS ENDIF ENDIF IF(GRAPHDIM(IGRAPH)%IFIXY.EQ.0)THEN AXES%IFIXY =0 AXES%YINT =10 ELSE AXES%IFIXY =1 AXES%YINT =GRAPHDIM(IGRAPH)%YINT IF(ASSOCIATED(GRAPHDIM(IGRAPH)%YTXT))THEN N=SIZE(GRAPHDIM(IGRAPH)%YTXT); ALLOCATE(AXES%YTXT(N),AXES%YPOS(N)) AXES%YTXT=GRAPHDIM(IGRAPH)%YTXT AXES%YPOS=GRAPHDIM(IGRAPH)%YPOS ENDIF ENDIF IF(GRAPHDIM(IGRAPH)%IFIXY2.EQ.0)THEN AXES%IFIXY2=0 AXES%Y2INT=10 ELSE AXES%IFIXY2=1 AXES%Y2INT =GRAPHDIM(IGRAPH)%Y2INT IF(ASSOCIATED(GRAPHDIM(IGRAPH)%Y2TXT))THEN N=SIZE(GRAPHDIM(IGRAPH)%Y2TXT); ALLOCATE(AXES%Y2TXT(N),AXES%Y2POS(N)) AXES%Y2TXT=GRAPHDIM(IGRAPH)%Y2TXT AXES%Y2POS=GRAPHDIM(IGRAPH)%Y2POS ENDIF ENDIF AXES%IAXES=(/1,0/) !## left/bottom axes only AXES%ICLRRASTER=WRGB(220,220,220) AXES%XFACTOR=1.0D0 AXES%YFACTOR=1.0D0 AXES%DXAXESL=40.0D0 AXES%DYAXESB=20.0D0 AXES%DYAXEST=75.0D0 AXES%DXAXESR=150.0D0 AXES%TFONT=FFHELVETICA !## text-font AXES%CHS=5.0D0; IF(GRAPHDIM(IGRAPH)%TEXTSIZE.NE.0.0D0)AXES%CHS=GRAPHDIM(IGRAPH)%TEXTSIZE AXES%YTITLE=GRAPHDIM(IGRAPH)%YTITLE AXES%XTITLE=GRAPHDIM(IGRAPH)%XTITLE AXES%LDATE=GRAPHDIM(IGRAPH)%LDATE AXES%ICLRBACKGROUND=WRGB(123,152,168) !## plot axes and set units CALL GRAPH_PLOTAXES(AXES,IGRAPH) !## draw line and different colour above/below zero CALL IGRFILLPATTERN(OUTLINE) CALL IGRLINETYPE(DOTTED) CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_IGRJOIN(AXES%XMIN,0.0D0,AXES%XMAX,0.0D0) CALL IGRLINETYPE(SOLIDLINE) !## current selected graph to be plotted NG=IGRAPH DO I=SIZE(GRAPH,1),1,-1 !## skip last entry for boreholes IF(GRAPH(I,NG)%GTYPE.EQ.4.AND.I.EQ.1)EXIT !## draw histogram / filled per pare (stack histograms) IF(GRAPH(I,NG)%GTYPE.EQ.1.OR.GRAPH(I,NG)%GTYPE.GE.3)THEN DO J=1,GRAPH(I,NG)%NP IF(GRAPH(I,NG)%NP.EQ.1)THEN D1=0.5D0; D2=0.5D0 ELSE IF(J.EQ.1)THEN D1=(GRAPH(I,NG)%RX(J+1)-GRAPH(I,NG)%RX(J))/2.0D0; D2=D1 ELSEIF(J.EQ.GRAPH(I,NG)%NP)THEN D2=(GRAPH(I,NG)%RX(J)-GRAPH(I,NG)%RX(J-1))/2.0D0; D1=D2 ELSE D1=(GRAPH(I,NG)%RX(J)-GRAPH(I,NG)%RX(J-1))/2.0D0 D2=(GRAPH(I,NG)%RX(J+1)-GRAPH(I,NG)%RX(J))/2.0D0 ENDIF ENDIF X1=GRAPH(I,NG)%RX(J)-D1 X2=GRAPH(I,NG)%RX(J)+D2 !## histogram IF(GRAPH(I,NG)%GTYPE.EQ.1)THEN Y1=MIN(0.0D0,GRAPH(I,NG)%RY(J)) Y2=MAX(0.0D0,GRAPH(I,NG)%RY(J)) !## stacked ELSE IF(I.EQ.1)THEN Y1=MIN(0.0D0,GRAPH(I,NG)%RY(J)) Y2=MAX(0.0D0,GRAPH(I,NG)%RY(J)) ELSE Y1=MIN(GRAPH(I-1,NG)%RY(J),GRAPH(I,NG)%RY(J)) Y2=MAX(GRAPH(I-1,NG)%RY(J),GRAPH(I,NG)%RY(J)) ENDIF ENDIF CALL IGRFILLPATTERN(SOLID) IF(Y1.NE.Y2)THEN !## borehole, take colour from previous interval IF(GRAPH(I,NG)%GTYPE.EQ.4)THEN CALL IGRCOLOURN(GRAPH(I-1,NG)%ICLR) ELSE CALL IGRCOLOURN(GRAPH(I,NG)%ICLR) ENDIF CALL DBL_IGRRECTANGLE(X1,Y1,X2,Y2) CALL IGRFILLPATTERN(OUTLINE) CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_IGRRECTANGLE(X1,Y1,X2,Y2) ELSE CALL DBL_IGRJOIN(X1,Y1,X2,Y2) ENDIF END DO !## draw lines ELSEIF(GRAPH(I,NG)%GTYPE.EQ.2)THEN CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(GRAPH(I,NG)%ICLR) DO J=1,GRAPH(I,NG)%NP-1 CALL DBL_IGRJOIN(GRAPH(I,NG)%RX(J) ,GRAPH(I,NG)%RY(J),& GRAPH(I,NG)%RX(J+1),GRAPH(I,NG)%RY(J+1)) END DO ENDIF ENDDO ENDDO !## put legends; process all graphs on equal displays DO IGRAPH=IG,JG AXES%XMIN=GRAPHUNITS(1,IGRAPH); AXES%YMIN=GRAPHUNITS(2,IGRAPH) AXES%XMAX=GRAPHUNITS(3,IGRAPH); AXES%YMAX=GRAPHUNITS(4,IGRAPH) CALL DBL_IGRAREA(GRAPHAREA(1,IGRAPH), GRAPHAREA(2,IGRAPH), GRAPHAREA(3,IGRAPH), GRAPHAREA(4,IGRAPH)) CALL DBL_IGRUNITS(GRAPHUNITS(1,IGRAPH),GRAPHUNITS(2,IGRAPH),GRAPHUNITS(3,IGRAPH),GRAPHUNITS(4,IGRAPH)) ! CALL IGRLINEWIDTH(2); CALL IGRCOLOURN(WRGB(0,0,0)); CALL IGRFILLPATTERN(OUTLINE) ! CALL DBL_IGRRECTANGLE(AXES%XMIN,AXES%YMIN,AXES%XMAX,AXES%YMAX); CALL IGRLINEWIDTH(1) !## put legend in local coordinate system CALL DBL_WGRTEXTORIENTATION(IALIGN=ALIGNLEFT,ANGLE=0.0D0,IDIR=DIRHORIZ,NALIGN=ALIGNLEFT) DX=AXES%CHW*(AXES%XMAX-AXES%XMIN) DY=AXES%CHH*(AXES%YMAX-AXES%YMIN) XMIN=AXES%XMIN+DX*7.5D0 XMAX=XMIN+DX*2.0D0 YMAX=AXES%YMAX-DY !## ipattern:0=solid,1=line,2=points,3=legend DO I=1,SIZE(GRAPH,1) !## skip this legend IF(TRIM(GRAPH(I,IGRAPH)%LEGTXT).EQ.'')CYCLE YMIN=YMAX-DY !## plot axes-text CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_WGRTEXTSTRING(XMAX+DX,(YMAX+YMIN)/2.0D0,' '//TRIM(GRAPH(I,IGRAPH)%LEGTXT)) SELECT CASE (GRAPH(I,IGRAPH)%GTYPE) CASE (2) !## lines CALL UTL_DRAWLEGENDBOX(XMIN,YMIN,XMAX,YMAX,GRAPH(I,IGRAPH)%ICLR,1,SOLIDLINE,1) CASE (1,3,4) !## filled CALL UTL_DRAWLEGENDBOX(XMIN,YMIN,XMAX,YMAX,GRAPH(I,IGRAPH)%ICLR,1,SOLIDLINE,0) END SELECT YMAX=YMIN ENDDO CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_WGRTEXTORIENTATION(ALIGNRIGHT) CALL DBL_WGRTEXTSTRING(AXES%XMAX-1.5D0*DX,AXES%YMIN+0.75D0*DY,TRIM(GRAPHDIM(IGRAPH)%GRAPHNAMES)) CALL DBL_WGRTEXTORIENTATION(ALIGNLEFT) ENDDO IF(.NOT.LEXPORTIT)THEN CALL WDIALOGSELECT(IDD) CALL IGRSELECT(DRAWFIELD,IDF) CALL WBITMAPPUT(IGBITMAP,0,1) ENDIF IF(ASSOCIATED(AXES%XTXT)) DEALLOCATE(AXES%XTXT) IF(ASSOCIATED(AXES%YTXT)) DEALLOCATE(AXES%YTXT) IF(ASSOCIATED(AXES%Y2TXT))DEALLOCATE(AXES%Y2TXT) IF(ASSOCIATED(AXES%XPOS)) DEALLOCATE(AXES%XPOS) IF(ASSOCIATED(AXES%YPOS)) DEALLOCATE(AXES%YPOS) IF(ASSOCIATED(AXES%Y2POS))DEALLOCATE(AXES%Y2POS) END SUBROUTINE GRAPH_DRAW !###==================================================================== SUBROUTINE GRAPH_ZOOM(IDD,IDZ) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: IDZ,IDD REAL(KIND=DP_KIND),PARAMETER :: FZIN =0.75D0 REAL(KIND=DP_KIND),PARAMETER :: FZOUT=1.5D0 TYPE(WIN_MESSAGE) :: MESSAGE INTEGER :: ITYPE,IDOWN,IDCURSOR,I,IGRAPH,IMULT REAL(KIND=DP_KIND) :: FZ,XC1,YC1,XC2,YC2,XC3,YC3,DX,DY LOGICAL :: LEX INTEGER,DIMENSION(6) :: ID DATA ID/ID_ZOOMIN,ID_ZOOMOUT,ID_ZOOMFULL,ID_ZOOMBOX,ID_MOVE,ID_COPY/ CALL WDIALOGGETCHECKBOX(IDF_CHECK1,IMULT) IF(IDZ.EQ.ID_ZOOMIN)THEN FZ=FZIN IDCURSOR=ID_CURSORPOINTPLUS ELSEIF(IDZ.EQ.ID_ZOOMOUT)THEN FZ=FZOUT IDCURSOR=ID_CURSORPOINTMIN ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN IDCURSOR=ID_CURSORZOOMRECTANGLE ELSEIF(IDZ.EQ.ID_MOVE)THEN IDCURSOR=ID_CURSORHAND ENDIF DO I=1,SIZE(ID); IF(ID(I).NE.IDZ)CALL WDIALOGFIELDSTATE(ID(I),0); END DO CALL WCURSORSHAPE(IDCURSOR) IDOWN=0; LEX=.FALSE.; XC1=0.0D0; YC1=0.0D0 DO CALL WMESSAGE(ITYPE,MESSAGE) IF(MESSAGE%WIN.EQ.IDD)THEN SELECT CASE(ITYPE) CASE(MOUSEMOVE) CALL GRAPH_MOUSE(MESSAGE,1,IGRAPH) !## skip, no graph selected IF(IGRAPH.LE.0)CYCLE XC2=MESSAGE%GX; YC2=MESSAGE%GY IF(IDZ.EQ.ID_MOVE)THEN IF(IDOWN.GT.0)THEN DX=XC1-XC2; DY=YC1-YC2 !## all figures are synced (yet) PGXMAX(IGRAPH)=PGXMAX(IGRAPH)+DX; PGXMIN(IGRAPH)=PGXMIN(IGRAPH)+DX PGYMAX(IGRAPH)=PGYMAX(IGRAPH)+DY; PGYMIN(IGRAPH)=PGYMIN(IGRAPH)+DY IF(IMULT.EQ.1)THEN CALL GRAPH_DRAW(1,SIZE(GRAPHAREA,2),.FALSE.) ELSE CALL GRAPH_DRAW(IGRAPH,IGRAPH,.FALSE.) ENDIF ENDIF CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0); CALL DBL_IGRUNITS(0.0D0,0.0D0,1.0D0,1.0D0) ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN IF(IDOWN.GT.0)THEN CALL IGRPLOTMODE(MODEXOR); CALL IGRCOLOURN(WRGB(255,255,255)) CALL IGRFILLPATTERN(OUTLINE); CALL IGRLINETYPE(DASHED) CALL DBL_IGRAREA( GRAPHAREA(1,IGRAPH) ,GRAPHAREA(2,IGRAPH), GRAPHAREA(3,IGRAPH), GRAPHAREA(4,IGRAPH)) CALL DBL_IGRUNITS(GRAPHUNITS(1,IGRAPH),GRAPHUNITS(2,IGRAPH),GRAPHUNITS(3,IGRAPH),GRAPHUNITS(4,IGRAPH)) IF(LEX)CALL DBL_IGRRECTANGLE(XC1,YC1,XC3,YC3); LEX=.FALSE. IF(IDOWN.EQ.1)THEN IF(XC1.NE.XC2.AND.YC1.NE.YC2)LEX=.TRUE. IF(LEX)CALL DBL_IGRRECTANGLE(XC1,YC1,XC2,YC2) ENDIF CALL DBL_IGRAREA(0.0D0,0.0D0,1.0D0,1.0D0); CALL DBL_IGRUNITS(0.0D0,0.0D0,1.0D0,1.0D0) ENDIF ENDIF XC3=XC2; YC3=YC2 CASE (RESIZE,EXPOSE) !## refresh graph IF(IMULT.EQ.1)THEN CALL GRAPH_DRAW(1,SIZE(GRAPHAREA,2),.FALSE.) ELSE CALL GRAPH_DRAW(IGRAPH,IGRAPH,.FALSE.) ENDIF CASE (MOUSEBUTUP) IF(IDZ.EQ.ID_MOVE)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) CALL WCURSORSHAPE(ID_CURSORHAND); IDOWN=0 END SELECT ENDIF CASE (MOUSEBUTDOWN) IF(IDZ.EQ.ID_ZOOMIN.OR.IDZ.EQ.ID_ZOOMOUT)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IGRAPH.GT.0)THEN XC2 = XC3; YC2 = YC3 DX = PGXMAX(IGRAPH)-PGXMIN(IGRAPH) DY = PGYMAX(IGRAPH)-PGYMIN(IGRAPH) PGXMAX(IGRAPH)= XC2+0.5D0*DX*FZ; PGXMIN(IGRAPH)= XC2-0.5D0*DX*FZ PGYMIN(IGRAPH)= YC2-0.5D0*DY*FZ; PGYMAX(IGRAPH)= YC2+0.5D0*DY*FZ IF(IMULT.EQ.1)THEN CALL GRAPH_DRAW(1,SIZE(GRAPHAREA,2),.FALSE.) ELSE CALL GRAPH_DRAW(IGRAPH,IGRAPH,.FALSE.) ENDIF ENDIF CASE (3) EXIT END SELECT ELSEIF(IDZ.EQ.ID_MOVE)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IDOWN.EQ.0)THEN XC1=XC2; YC1=YC2; IDOWN=1 CALL WCURSORSHAPE(ID_CURSORHANDGREP) ENDIF CASE (3) EXIT END SELECT ELSEIF(IDZ.EQ.ID_ZOOMBOX)THEN SELECT CASE (MESSAGE%VALUE1) CASE (1) IF(IDOWN.EQ.0)THEN XC1=XC2; YC1=YC2; IDOWN=1 ELSE IF(IGRAPH.GT.0)THEN PGXMAX(IGRAPH)=MAX(XC1,XC3); PGXMIN(IGRAPH)=MIN(XC1,XC3) PGYMAX(IGRAPH)=MAX(YC1,YC3); PGYMIN(IGRAPH)=MIN(YC1,YC3) ENDIF EXIT ENDIF END SELECT ENDIF END SELECT ENDIF ENDDO CALL WCURSORSHAPE(CURARROW) IF(IDZ.EQ.ID_ZOOMBOX)THEN; CALL IGRPLOTMODE(MODECOPY); CALL IGRLINETYPE(SOLIDLINE); ENDIF IF(IGRAPH.NE.0)THEN !## refresh graph IF(IMULT.EQ.1)THEN CALL GRAPH_DRAW(1,SIZE(GRAPHAREA,2),.FALSE.) ELSE CALL GRAPH_DRAW(IGRAPH,IGRAPH,.FALSE.) ENDIF ENDIF DO I=1,SIZE(ID); IF(ID(I).NE.IDZ)CALL WDIALOGFIELDSTATE(ID(I),1); END DO END SUBROUTINE GRAPH_ZOOM !###==================================================================== SUBROUTINE GRAPH_ALLOCATE(NI,NJ) !###==================================================================== IMPLICIT NONE INTEGER,INTENT(IN) :: NI,NJ INTEGER :: I,J !## ni=number of lines; nj=number of seperated graphs ALLOCATE(GRAPH(NI,NJ),GRAPHDIM(NJ)) DO I=1,NI; DO J=1,NJ; NULLIFY(GRAPH(I,J)%RX,GRAPH(I,J)%RY); ENDDO; ENDDO END SUBROUTINE GRAPH_ALLOCATE !###==================================================================== SUBROUTINE GRAPH_DEALLOCATE() !###==================================================================== IMPLICIT NONE INTEGER :: I,J IF(ALLOCATED(GRAPH))THEN DO I=1,SIZE(GRAPH,1); DO J=1,SIZE(GRAPH,2) IF(ASSOCIATED(GRAPH(I,J)%RX))DEALLOCATE(GRAPH(I,J)%RX) IF(ASSOCIATED(GRAPH(I,J)%RY))DEALLOCATE(GRAPH(I,J)%RY) END DO; END DO DEALLOCATE(GRAPH) ENDIF IF(ALLOCATED(GRAPHDIM))THEN DO I=1,SIZE(GRAPHDIM) IF(ASSOCIATED(GRAPHDIM(I)%XTXT)) DEALLOCATE(GRAPHDIM(I)%XTXT) IF(ASSOCIATED(GRAPHDIM(I)%YTXT)) DEALLOCATE(GRAPHDIM(I)%YTXT) IF(ASSOCIATED(GRAPHDIM(I)%Y2TXT))DEALLOCATE(GRAPHDIM(I)%Y2TXT) IF(ASSOCIATED(GRAPHDIM(I)%XPOS)) DEALLOCATE(GRAPHDIM(I)%XPOS) IF(ASSOCIATED(GRAPHDIM(I)%YPOS)) DEALLOCATE(GRAPHDIM(I)%YPOS) IF(ASSOCIATED(GRAPHDIM(I)%Y2POS))DEALLOCATE(GRAPHDIM(I)%Y2POS) ENDDO DEALLOCATE(GRAPHDIM) ENDIF END SUBROUTINE GRAPH_DEALLOCATE !###====================================================================== SUBROUTINE GRAPH_PLOTAXES(AXES,IWINID) !###====================================================================== IMPLICIT NONE TYPE(AXESOBJ),INTENT(INOUT) :: AXES INTEGER,INTENT(IN) :: IWINID CHARACTER(LEN=24) :: CDATE INTEGER :: I,J,IWD,IHD,IWS,IHS,NL,NI,N REAL(KIND=DP_KIND) :: DX,DY,DXTIC,DYTIC,X,Y,DMX1,RATIO,DMX2,DMY1,DMY2,TWIDTH,THEIGHT,& XASMIN,XASMAX,YASMIN,YASMAX,XASINT,YASINT,SX_RATIO,SY_RATIO, & Y2ASMIN,Y2ASMAX,Y2ASINT,D2Y,INT_BU,FCT REAL(KIND=DP_KIND) :: XJDCOR !## correction for x in case of large numbers caused by julian-date !## drawable settings IWD=WINFODRAWABLE(DRAWABLEWIDTH) IHD=WINFODRAWABLE(DRAWABLEHEIGHT) !## screen setting IWS=WINFOSCREEN(SCREENWIDTH) IHS=WINFOSCREEN(SCREENHEIGHT) SX_RATIO=REAL(IWS)/REAL(IWD) SY_RATIO=REAL(IHS)/REAL(IHD) !## determine axes min/max values XASMIN=AXES%XMIN XASMAX=AXES%XMAX XJDCOR=0.0D0 !## correct for large julian-date numbers IF(AXES%LDATE)THEN XJDCOR=-XASMIN XASMIN= XASMIN+XJDCOR XASMAX= XASMAX+XJDCOR ENDIF YASMIN=AXES%YMIN YASMAX=AXES%YMAX !## second y-axes IF(AXES%IAXES(2).EQ.1)THEN Y2ASMIN=AXES%Y2MIN Y2ASMAX=AXES%Y2MAX Y2ASINT=AXES%Y2INT ENDIF CALL UTL_GETAXESCALES(XASMIN,YASMIN,XASMAX,YASMAX) XASINT=AXES%XINT YASINT=AXES%YINT IF(AXES%IFIXX.EQ.0)THEN XASINT=SXVALUE(2)-SXVALUE(1) XASMIN=SXVALUE(1) ENDIF IF(AXES%IFIXY.EQ.0)THEN YASINT=SYVALUE(2)-SYVALUE(1) YASMIN=SYVALUE(1) ENDIF !## second y-axes IF(AXES%IAXES(2).EQ.1)THEN IF(AXES%IFIXY2.EQ.0)THEN CALL UTL_GETAXESCALES(XASMIN,Y2ASMIN,XASMAX,Y2ASMAX) Y2ASINT=SYVALUE(2)-SYVALUE(1) Y2ASMIN=SYVALUE(1) ENDIF ENDIF DX=AXES%XMAX-AXES%XMIN DY=AXES%YMAX-AXES%YMIN IF(AXES%IAXES(2).EQ.1)THEN D2Y =AXES%Y2MAX-AXES%Y2MIN DMY1=D2Y*(SY_RATIO*(1.0D0/AXES%DYAXESB)) DMY2=D2Y*(SY_RATIO*(1.0D0/AXES%DYAXEST)) GRAPHUNITS(5,IWINID)=AXES%Y2MIN-DMY1 GRAPHUNITS(6,IWINID)=AXES%Y2MAX+DMY2 ENDIF !## compute marge - depends on size - textsize depend on these distances!!! DMX1=DX*(SX_RATIO*(1.0D0/AXES%DXAXESL)) DMX2=DX*(SX_RATIO*(1.0D0/AXES%DXAXESR)) DMY1=DY*(SY_RATIO*(1.0D0/AXES%DYAXESB)) DMY2=DY*(SY_RATIO*(1.0D0/AXES%DYAXEST)) GRAPHUNITS(1,IWINID)=AXES%XMIN-DMX1+XJDCOR GRAPHUNITS(3,IWINID)=AXES%XMAX+DMX2+XJDCOR GRAPHUNITS(2,IWINID)=AXES%YMIN-DMY1 GRAPHUNITS(4,IWINID)=AXES%YMAX+DMY2 !## tic length DXTIC=DMX1/8.0D0 DYTIC=DMY1/8.0D0 NL=1; IF(AXES%XTITLE.NE.''.OR.AXES%YTITLE.NE.'')NL=NL+1 !## entire bitmap CALL IGRAREACLEAR() CALL DBL_IGRUNITS(GRAPHUNITS(1,IWINID),GRAPHUNITS(2,IWINID),GRAPHUNITS(3,IWINID),GRAPHUNITS(4,IWINID)) RATIO=(GRAPHUNITS(3,IWINID)-GRAPHUNITS(1,IWINID))/(GRAPHUNITS(4,IWINID)-GRAPHUNITS(2,IWINID)) !## compute proper textsize as ratio of dy IF(AXES%CHS.LE.0.0D0)AXES%CHS=5.0D0 FCT=AXES%CHS*SY_RATIO CALL UTL_SETTEXTSIZE(TWIDTH,THEIGHT,FCT=FCT) CALL DBL_WGRTEXTFONT(IFAMILY=AXES%TFONT,TWIDTH=TWIDTH,THEIGHT=THEIGHT,ISTYLE=0) AXES%CHH=THEIGHT AXES%CHW=TWIDTH !## fill deltares blue colour CALL IGRFILLPATTERN(SOLID) CALL IGRCOLOURN(AXES%ICLRBACKGROUND) CALL DBL_IGRRECTANGLE(GRAPHUNITS(1,IWINID),GRAPHUNITS(2,IWINID),GRAPHUNITS(3,IWINID),GRAPHUNITS(4,IWINID)) !## white drawing area CALL IGRFILLPATTERN(SOLID) CALL IGRCOLOURN(WRGB(255,255,255)) CALL DBL_IGRRECTANGLE(AXES%XMIN+XJDCOR,AXES%YMIN,AXES%XMAX+XJDCOR,AXES%YMAX) CALL IGRLINEWIDTH(1) CALL IGRLINETYPE(DASHED) !## === VERTICAL AXES === CALL DBL_WGRTEXTORIENTATION(IALIGN=ALIGNCENTRE,ANGLE=90.0D0,IDIR=DIRHORIZ,NALIGN=ALIGNCENTRE) IF(.NOT.ASSOCIATED(AXES%YTXT))THEN I=0; INT_BU=YASINT DO !## get length of vertical axes I=I+1; Y=YASMIN-YASINT; DY=0.0D0 DO Y=Y+YASINT IF(Y.GE.AXES%YMAX)EXIT IF(Y.GT.AXES%YMIN)THEN WRITE(CDATE,UTL_GETFORMAT(Y*AXES%YFACTOR)) Y*AXES%YFACTOR; CDATE=ADJUSTL(CDATE) DY=DY+1.0D0*WGRTEXTLENGTH(TRIM(CDATE))*WINFOGRREAL(GRAPHICSCHHEIGHT) ENDIF END DO !## increase interval in case axes is too big IF(DY.LE.(AXES%YMAX-AXES%YMIN))EXIT YASINT=INT_BU*REAL(I)*0.5 !## nothing in between found IF(YASINT.GE.(AXES%YMAX-AXES%YMIN))EXIT ENDDO !## vertical axes - vertical plotting CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) Y=YASMIN-YASINT DO IF(UTL_EQUALS_REAL(Y,Y+YASINT/4.0D0))THEN Y=Y+YASINT ELSE Y=Y+YASINT/4.0D0 ENDIF IF(Y.GT.AXES%YMAX)EXIT IF(Y.GT.AXES%YMIN)THEN CALL DBL_IGRJOIN((AXES%XMIN+XJDCOR)-DXTIC/2.0D0,Y,(AXES%XMIN+XJDCOR)+DXTIC/2.0D0,Y) CALL DBL_IGRJOIN((AXES%XMAX+XJDCOR)-DXTIC/2.0D0,Y,(AXES%XMAX+XJDCOR)+DXTIC/2.0D0,Y) ENDIF ENDDO !## vertical axes - vertical plotting Y =YASMIN-YASINT DX=DMX1/REAL(NL+1) J=0; DO Y=Y+YASINT IF(Y.GE.AXES%YMAX)EXIT IF(Y.GT.AXES%YMIN)THEN J=J+1 CALL IGRLINETYPE(DASHED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(AXES%XMIN+XJDCOR,Y,AXES%XMAX+XJDCOR,Y) !## raster CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) CALL DBL_IGRJOIN((AXES%XMIN+XJDCOR)-DXTIC,Y,(AXES%XMIN+XJDCOR)+DXTIC,Y) !## plot right axes in case no secondary y-axes is plotted IF(AXES%IAXES(2).EQ.0)CALL DBL_IGRJOIN((AXES%XMAX+XJDCOR)-DXTIC,Y,(AXES%XMAX+XJDCOR)+DXTIC,Y) IF(ASSOCIATED(AXES%YTXT))THEN CALL DBL_WGRTEXTSTRING((AXES%XMIN+XJDCOR)-DX,Y,TRIM(AXES%YTXT(J))) ELSE !## plot axes-text CALL DBL_WGRTEXTREAL((AXES%XMIN+XJDCOR)-DX,Y,Y*AXES%YFACTOR,TRIM(UTL_GETFORMAT(Y*AXES%YFACTOR))) ENDIF ENDIF END DO !## plot predefined axes ELSE !## vertical axes - vertical plotting DX=DMX1/REAL(NL+1) DO J=1,2 IF(J.EQ.1)N=0; NI=1; IF(J.EQ.2)NI=N/10 DO I=1,SIZE(AXES%YPOS),MAX(1,NI) Y=AXES%YPOS(I) IF(Y.LE.AXES%YMIN)CYCLE IF(Y.GE.AXES%YMAX)EXIT IF(J.EQ.1)THEN N=N+1 CALL IGRLINETYPE(DASHED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(AXES%XMIN+XJDCOR,Y,AXES%XMAX+XJDCOR,Y) !## raster CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) CALL DBL_IGRJOIN((AXES%XMIN+XJDCOR)-DXTIC,Y,(AXES%XMIN+XJDCOR)+DXTIC,Y) !## plot right axes in case no secondary y-axes is plotted IF(AXES%IAXES(2).EQ.0)CALL DBL_IGRJOIN((AXES%XMAX+XJDCOR)-DXTIC,Y,(AXES%XMAX+XJDCOR)+DXTIC,Y) ELSE CALL DBL_WGRTEXTSTRING((AXES%XMIN+XJDCOR)-DX,Y,TRIM(AXES%YTXT(I))) ENDIF ENDDO ENDDO ENDIF !## vertical axes IF(LEN_TRIM(AXES%YTITLE).NE.0)THEN X=(AXES%XMIN+XJDCOR)-(2.0D0*DX) Y=(AXES%YMAX+AXES%YMIN)/2.0D0 IF(AXES%YFACTOR.NE.1.0D0)THEN CALL DBL_WGRTEXTSTRING(X,Y,TRIM(AXES%YTITLE)//' (x '//TRIM(RTOS(1.0D0/AXES%YFACTOR,'F',2))//')') ELSE CALL DBL_WGRTEXTSTRING(X,Y,TRIM(AXES%YTITLE)) ENDIF ENDIF !## === SECOND VERTICAL AXES === !## second vertical axes - vertical plotting IF(AXES%IAXES(2).EQ.1)THEN CALL DBL_IGRUNITS(GRAPHUNITS(1,IWINID),GRAPHUNITS(5,IWINID),GRAPHUNITS(3,IWINID),GRAPHUNITS(6,IWINID)) IF(.NOT.ASSOCIATED(AXES%Y2TXT))THEN I=0; INT_BU=Y2ASINT DO !## get length of vertical axes I=I+1; Y=Y2ASMIN-Y2ASINT; DY=0.0D0 DO Y=Y+Y2ASINT IF(Y.GE.AXES%Y2MAX)EXIT IF(Y.GT.AXES%Y2MIN)THEN WRITE(CDATE,UTL_GETFORMAT(Y)) Y; CDATE=ADJUSTL(CDATE) DY=DY+1.0D0*WGRTEXTLENGTH(TRIM(CDATE))*WINFOGRREAL(GRAPHICSCHHEIGHT) ENDIF END DO !## increase interval in case axes is too big IF(DY.LT.(AXES%Y2MAX-AXES%Y2MIN))EXIT Y2ASINT=INT_BU*REAL(I,8)*0.5D0 !## nothing in between found IF(Y2ASINT.GE.(AXES%Y2MAX-AXES%Y2MIN))EXIT ENDDO CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,0,0)) Y=Y2ASMIN-Y2ASINT DO IF(UTL_EQUALS_REAL(Y,Y+Y2ASINT/4.0D0))THEN Y=Y+Y2ASINT ELSE Y=Y+Y2ASINT/4.0D0 ENDIF IF(Y.GE.AXES%Y2MAX)EXIT IF(Y.GT.AXES%Y2MIN)THEN CALL DBL_IGRJOIN(AXES%XMAX+DXTIC/2.0+XJDCOR,Y,AXES%XMAX-DXTIC/2.0D0+XJDCOR,Y) CALL DBL_IGRJOIN(AXES%XMAX+DXTIC/2.0+XJDCOR,Y,AXES%XMAX-DXTIC/2.0D0+XJDCOR,Y) ENDIF END DO Y =Y2ASMIN-Y2ASINT DX=DMX1/REAL(NL+1) J=0; DO Y=Y+Y2ASINT IF(Y.GT.AXES%Y2MAX)EXIT IF(Y.GT.AXES%Y2MIN)THEN J=J+1 CALL IGRLINETYPE(DOTTED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(AXES%XMIN+XJDCOR,Y,AXES%XMAX+XJDCOR,Y) CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,0,0)) CALL DBL_IGRJOIN(AXES%XMAX+DXTIC+XJDCOR,Y,AXES%XMAX-DXTIC+XJDCOR,Y) CALL DBL_WGRTEXTREAL(AXES%XMAX+DX+XJDCOR,Y,Y,TRIM(UTL_GETFORMAT(Y))) ENDIF END DO ELSE DX=DMX1/REAL(NL+1) DO I=1,2 IF(I.EQ.1)N=0; NI=1; IF(I.EQ.2)NI=N/10 DO J=1,SIZE(AXES%Y2POS),MAX(1,NI) Y=AXES%Y2POS(J) IF(Y.LE.AXES%Y2MIN)CYCLE IF(Y.GT.AXES%Y2MAX)EXIT IF(I.EQ.1)THEN N=N+1 CALL IGRLINETYPE(DOTTED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(AXES%XMIN+XJDCOR,Y,AXES%XMAX+XJDCOR,Y) CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,0,0)) CALL DBL_IGRJOIN(AXES%XMAX+DXTIC+XJDCOR,Y,AXES%XMAX-DXTIC+XJDCOR,Y) ELSE CALL DBL_WGRTEXTSTRING(AXES%XMAX+DX+XJDCOR,Y,TRIM(AXES%Y2TXT(J))) ENDIF ENDDO ENDDO ENDIF !## vertical axes IF(LEN_TRIM(AXES%YTITLE).NE.0)THEN X= AXES%XMAX+XJDCOR+(2.0D0*DX) Y=(AXES%Y2MAX+AXES%Y2MIN)/2.0D0 CALL DBL_WGRTEXTSTRING(X,Y,TRIM(AXES%Y2TITLE)) ENDIF CALL DBL_IGRUNITS(GRAPHUNITS(1,IWINID),GRAPHUNITS(2,IWINID),GRAPHUNITS(3,IWINID),GRAPHUNITS(4,IWINID)) ENDIF !## === HORIZONTAL AXES === CALL DBL_WGRTEXTORIENTATION(IALIGN=ALIGNCENTRE,ANGLE=0.0D0,IDIR=DIRHORIZ,NALIGN=ALIGNCENTRE) IF(.NOT.ASSOCIATED(AXES%XTXT))THEN !## now I know the textsize, determine number of classes I=0; INT_BU=XASINT DO !## get length of vertical axes I=I+1; X=XASMIN-XASINT; DX=0.0D0 J=0; DO X=X+XASINT IF(X.GE.AXES%XMAX+XJDCOR)EXIT IF(X.GT.AXES%XMIN+XJDCOR)THEN J=J+1 IF(AXES%LDATE)THEN CDATE=JDATETOFDATE(X-XJDCOR,AXES%XOFFSET) DX=DX+1.2*WGRTEXTLENGTH(TRIM(CDATE))*WINFOGRREAL(GRAPHICSCHWIDTH) ELSE WRITE(CDATE,UTL_GETFORMAT(X)) X; CDATE=ADJUSTL(CDATE) DX=DX+1.2*WGRTEXTLENGTH(TRIM(CDATE))*WINFOGRREAL(GRAPHICSCHWIDTH) ENDIF ENDIF END DO !## increase interval in case axes is too big IF(DX.LE.(AXES%XMAX-AXES%XMIN))EXIT XASINT=INT_BU*REAL(I,8)*0.5D0 !## nothing in between found IF(XASINT.GE.(AXES%XMAX-AXES%XMIN))EXIT ENDDO !## horizontal axes - horizontal plotting !## minor axes CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) X=XASMIN-XASINT DO IF(UTL_EQUALS_REAL(X,X+XASINT/4.0D0))THEN X=X+XASINT ELSE X=X+XASINT/4.0D0 ENDIF IF(X.GT.AXES%XMAX+XJDCOR)EXIT IF(X.GT.AXES%XMIN+XJDCOR)THEN CALL DBL_IGRJOIN(X,AXES%YMIN-DYTIC/2.0D0,X,AXES%YMIN+DYTIC/2.0D0) CALL DBL_IGRJOIN(X,AXES%YMAX-DYTIC/2.0D0,X,AXES%YMAX+DYTIC/2.0D0) ENDIF ENDDO X = XASMIN-XASINT DY= DMY1/REAL(NL+1,8) J=0; DO X=X+XASINT IF(X.GE.AXES%XMAX+XJDCOR)EXIT IF(X.GT.AXES%XMIN+XJDCOR)THEN J=J+1 CALL IGRLINETYPE(DASHED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(X,AXES%YMIN,X,AXES%YMAX) CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) CALL DBL_IGRJOIN(X,AXES%YMIN-DYTIC,X,AXES%YMIN+DYTIC) CALL DBL_IGRJOIN(X,AXES%YMAX-DYTIC,X,AXES%YMAX+DYTIC) IF(AXES%LDATE)THEN CDATE=JDATETOFDATE(X-XJDCOR,AXES%XOFFSET) CALL DBL_WGRTEXTSTRING(X,AXES%YMIN-DY,TRIM(CDATE)) ELSE CALL DBL_WGRTEXTREAL(X,AXES%YMIN-DY,X*AXES%XFACTOR,TRIM(UTL_GETFORMAT((X+XJDCOR)*AXES%XFACTOR))) ENDIF ENDIF END DO !## predefined axes and labels ELSE !## plot major axes DY= DMY1/REAL(NL+1,8) DO J=1,2 IF(J.EQ.1)N=0; NI=1; IF(J.EQ.2)NI=N/10 DO I=1,SIZE(AXES%XPOS),MAX(1,NI) X=AXES%XPOS(I)+XJDCOR IF(X.LT.AXES%XMIN+XJDCOR)CYCLE IF(X.GE.AXES%XMAX+XJDCOR)EXIT IF(J.EQ.1)THEN N=N+1 CALL IGRLINETYPE(DASHED) CALL IGRCOLOURN(AXES%ICLRRASTER) CALL DBL_IGRJOIN(X,AXES%YMIN,X,AXES%YMAX) CALL IGRLINETYPE(SOLIDLINE) CALL IGRCOLOURN(WRGB(256,256,256)) CALL DBL_IGRJOIN(X,AXES%YMIN-DYTIC,X,AXES%YMIN+DYTIC) CALL DBL_IGRJOIN(X,AXES%YMAX-DYTIC,X,AXES%YMAX+DYTIC) ELSE CALL DBL_WGRTEXTSTRING(X,AXES%YMIN-DY,TRIM(AXES%XTXT(I))) ENDIF ENDDO ENDDO ENDIF !## horizontal axes IF(LEN_TRIM(AXES%XTITLE).NE.0)THEN X=(AXES%XMAX+AXES%XMIN)/2.0D0 Y= AXES%YMIN-2.0D0*DY IF(AXES%XFACTOR.NE.1.0D0)THEN CALL DBL_WGRTEXTSTRING(X+XJDCOR,Y,TRIM(AXES%XTITLE)//' (x '//TRIM(RTOS(1.0D0/AXES%XFACTOR,'F',2))//')') ELSE CALL DBL_WGRTEXTSTRING(X+XJDCOR,Y,TRIM(AXES%XTITLE)) ENDIF ENDIF CALL IGRCOLOURN(WRGB(256,256,256)) CALL IGRLINETYPE(SOLIDLINE) !## back-translation GRAPHUNITS(1,IWINID)=GRAPHUNITS(1,IWINID)-XJDCOR GRAPHUNITS(3,IWINID)=GRAPHUNITS(3,IWINID)-XJDCOR CALL DBL_IGRUNITS(GRAPHUNITS(1,IWINID),GRAPHUNITS(2,IWINID),GRAPHUNITS(3,IWINID),GRAPHUNITS(4,IWINID)) !## black axes CALL IGRLINETYPE(SOLIDLINE) CALL IGRFILLPATTERN(OUTLINE) CALL IGRLINEWIDTH(2) CALL IGRCOLOURN(WRGB(0,0,0)) CALL DBL_IGRRECTANGLE(AXES%XMIN,AXES%YMIN,AXES%XMAX,AXES%YMAX) CALL IGRLINEWIDTH(1) CALL GRAPH_PLOTAXES_VIEW(AXES,IWINID) END SUBROUTINE GRAPH_PLOTAXES !###====================================================================== SUBROUTINE GRAPH_PLOTAXES_VIEW(AXES,IWINID) !###====================================================================== IMPLICIT NONE TYPE(AXESOBJ),INTENT(INOUT) :: AXES INTEGER,INTENT(IN) :: IWINID REAL(KIND=DP_KIND) :: DX,DY,DXA,DYA REAL(KIND=DP_KIND) :: X1V,Y1V,X2V,Y2V !## for now - only map active drawing area DX = GRAPHUNITS(3,IWINID)-GRAPHUNITS(1,IWINID) DY = GRAPHUNITS(4,IWINID)-GRAPHUNITS(2,IWINID) !## correct units for marge X1V=(AXES%XMIN-GRAPHUNITS(1,IWINID))/DX X2V=(AXES%XMAX-GRAPHUNITS(1,IWINID))/DX Y1V=(AXES%YMIN-GRAPHUNITS(2,IWINID))/DY Y2V=(AXES%YMAX-GRAPHUNITS(2,IWINID))/DY DXA=WINFOGRREAL(GRAPHICSAREAMAXX)-WINFOGRREAL(GRAPHICSAREAMINX) DYA=WINFOGRREAL(GRAPHICSAREAMAXY)-WINFOGRREAL(GRAPHICSAREAMINY) X1V=X1V*DXA X2V=X2V*DXA Y1V=Y1V*DYA Y2V=Y2V*DYA X1V=X1V+WINFOGRREAL(GRAPHICSAREAMINX) X2V=X2V+WINFOGRREAL(GRAPHICSAREAMINX) Y1V=Y1V+WINFOGRREAL(GRAPHICSAREAMINY) Y2V=Y2V+WINFOGRREAL(GRAPHICSAREAMINY) CALL DBL_IGRVIEWPORT(X1V,Y1V,X2V,Y2V) END SUBROUTINE GRAPH_PLOTAXES_VIEW END MODULE MOD_GRAPH