📄 xgraph.c
字号:
} if (getparstring("titleColor",&titleColor)) { from.addr = (char *)titleColor; XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to); if (to.addr) XtSetArg(args[nargs],XtNtitleColor, *((unsigned long*)to.addr)); nargs++; } if (getparstring("labelFont",&labelFont)) { from.addr = (char *)labelFont; XtConvertAndStore(axes,XtRString,&from,XtRFont,&to); if (to.addr) XtSetArg(args[nargs],XtNlabelFont, *((Font*)to.addr)); nargs++; } if (getparstring("titleFont",&titleFont)) { from.addr = (char *)titleFont; XtConvertAndStore(axes,XtRString,&from,XtRFont,&to); if (to.addr) XtSetArg(args[nargs],XtNtitleFont, *((Font*)to.addr)); nargs++; } XtSetValues(axes,args,nargs); x1beg = x1min; getparfloat("x1beg",&x1beg); x1end = x1max; getparfloat("x1end",&x1end); x2beg = x2min; getparfloat("x2beg",&x2beg); x2end = x2max; getparfloat("x2end",&x2end); XtcwpSetAxesValues(axes,x1beg,x1end,x2beg,x2end); /* set up keypress */ XtAddEventHandler(axes, KeyPress, FALSE, (XtEventHandler) key_pressed, &key_data); /* get graph parameters */ for (i=0; i<nplot; i++) { mark[i] = i%NMARKS; marksize[i] = 0; linewidth[i] = 1; linecolor[i] = 2+i%6; } if ((npar=getparint("mark",mark))) for (j=npar; j<nplot; j++) mark[j] = mark[npar-1]; if ((npar=getparint("marksize",marksize))) for (j=npar; j<nplot; j++) marksize[j] = marksize[npar-1]; if ((npar=getparint("linewidth",linewidth))) for (j=npar; j<nplot; j++) linewidth[j] = linewidth[npar-1]; if ((npar=getparint("linecolor",linecolor))) for (j=npar; j<nplot; j++) linecolor[j] = linecolor[npar-1]; /* get plotting order JGHACK */ if (getparint("reverse", &plot_direction)) plot_direction=-1; /* JGHACK */ /* add callbacks to axes widget */ XtAddCallback(axes,XtNresizeCallback,(XtCallbackProc) resizeCB,NULL); exposeCD.nplot = nplot; exposeCD.n = &n[0]; exposeCD.data = data; exposeCD.linewidth = &linewidth[0]; exposeCD.linecolor = &linecolor[0]; exposeCD.mark = &mark[0]; exposeCD.marksize = &marksize[0]; exposeCD.plot_direction=plot_direction; /* JGHACK */ XtAddCallback(axes,XtNexposeCallback,(XtCallbackProc) exposeCB,&exposeCD); XtAddCallback(axes,XtNinputCallback,(XtCallbackProc) inputCB,NULL); /* realize and go */ XtRealizeWidget(toplevel); XtMainLoop(); return EXIT_SUCCESS;}void resizeCB (Widget w, XtPointer clientdata, XtcwpAxesCallbackStruct *ca){ if(((char *) clientdata)-((char *) clientdata)) resizeCB(w,clientdata,ca); /* printf("resize callback\n"); */}#define NCOLOR 8static char *color[NCOLOR] = { "black", "white", "red", "green", "blue", "cyan", "magenta", "yellow",};void exposeCB (Widget w, ExposeCD *cd, XtcwpAxesCallbackStruct *ca){ int nplot=cd->nplot; int *n=cd->n; float **data=cd->data; int *linewidth=cd->linewidth; int *linecolor=cd->linecolor; int *mark=cd->mark; int *marksize=cd->marksize; int nplot_start, nplot_end; /* JGHACK */ Position x=ca->x,y=ca->y; Dimension width=ca->width,height=ca->height; float x1beg=ca->x1beg,x1end=ca->x1end, x2beg=ca->x2beg,x2end=ca->x2end; int style=ca->style; Display *dpy=XtDisplay(w); Window win=XtWindow(w); XWindowAttributes wa; Colormap cmap; XColor scolor,ecolor; XRectangle rect; unsigned long black=BlackPixelOfScreen(XtScreen(w)); GC gc; int iplot,icolor; float xmin,xmax,ymin,ymax,xbase,xscale,ybase,yscale; static int firstexpose=1; /* if first expose, check style and, if necessary, swap x,y coords */ if (firstexpose) { if (style==XtcwpSEISMIC) { /* JGHACK ......*/ if (cd->plot_direction==1) { nplot_start=0; nplot_end=nplot-1; } else { nplot_start=nplot-1; nplot_end=0; } for (iplot=nplot_start; (cd->plot_direction==1) ? (iplot<=nplot_end) : (iplot>=nplot_end); iplot+=cd->plot_direction) { /* .......JGHACK */ int ni=n[iplot],i; for (i=0; i<ni; ++i) { float temp=data[iplot][2*i]; data[iplot][2*i] = data[iplot][2*i+1]; data[iplot][2*i+1] = temp; } } } firstexpose = 0; } /* determine current colormap */ XGetWindowAttributes(dpy,win,&wa); cmap = wa.colormap; /* create GC */ gc = XCreateGC(dpy,win,0L,NULL); /* set clip to axes box */ rect.x = x; rect.y = y; rect.width = width; rect.height = height; XSetClipRectangles(dpy,gc,0,0,&rect,1,Unsorted); /* determine min and max coordinates */ xmin = x; xmax = x+((int) width); ymin = y; ymax = y+((int) height); /* determine base and scale factors */ if (style==XtcwpNORMAL) { xscale = ((float) width)/(x1end-x1beg); xbase = x-x1beg*xscale; yscale = ((float) height)/(x2beg-x2end); ybase = y-x2end*yscale; } else { xscale = ((float) width)/(x2end-x2beg); xbase = x-x2beg*xscale; yscale = ((float) height)/(x1end-x1beg); ybase = y-x1beg*yscale; } /* loop over plots */ /* JGHACK ......*/ if (cd->plot_direction==1) { nplot_start=0; nplot_end=nplot-1; } else { nplot_start=nplot-1; nplot_end=0; } for (iplot=nplot_start; (cd->plot_direction==1) ? (iplot<=nplot_end) : (iplot>=nplot_end); iplot+=cd->plot_direction) { /* ........JGHACK */ /* set line width */ XSetLineAttributes(dpy,gc, linewidth[iplot], LineSolid, CapButt, JoinMiter); /* set line color */ icolor = linecolor[iplot]; if (icolor<0) icolor = 0; else if (icolor>=NCOLOR) icolor = NCOLOR-1; if (XAllocNamedColor(dpy,cmap,color[icolor],&scolor,&ecolor)) XSetForeground(dpy,gc,ecolor.pixel); else XSetForeground(dpy,gc,black); /* draw lines between points */ if (linewidth[iplot]!=0) { int xi,yi,in,xilast,yilast,inlast,i,ni=n[iplot]; float *pdata; pdata = data[iplot]; xi = xbase+xscale*(*pdata++); yi = ybase+yscale*(*pdata++); in = (xi>=xmin && xi<=xmax && yi>=ymin && yi<=ymax); for (i=1; i<ni; ++i) { xilast = xi; yilast = yi; inlast = in; xi = xbase+xscale*(*pdata++); yi = ybase+yscale*(*pdata++); in = (xi>=xmin && xi<=xmax && yi>=ymin && yi<=ymax); if (in || inlast) XDrawLine(dpy,win,gc, xilast,yilast,xi,yi); } } /* draw marks at points */ if (marksize[iplot]!=0) { int xi,yi,in,i,ni=n[iplot]; float *pdata; pdata = data[iplot]; for (i=0; i<ni; ++i) { xi = xbase+xscale*(*pdata++); yi = ybase+yscale*(*pdata++); in = (xi>=xmin && xi<=xmax && yi>=ymin && yi<=ymax); if (in) xDrawMark(dpy,win,gc,xi,yi, mark[iplot],marksize[iplot]); } } } /* free GC */ XFreeGC(dpy,gc);}void inputCB (Widget w, XtPointer clientdata, XtcwpAxesCallbackStruct *ca){ int x=ca->x,y=ca->y,width=ca->width,height=ca->height; float x1beg=ca->x1beg,x1end=ca->x1end,x2beg=ca->x2beg,x2end=ca->x2end; int style=ca->style; XEvent *event=ca->event; int xb,yb,wb,hb; float x1begn,x1endn,x2begn,x2endn; static int firstinput=1; static float x1begs,x1ends,x2begs,x2ends; /* if first input, save initial axes limits */ if (firstinput) { x1begs = x1beg; x1ends = x1end; x2begs = x2beg; x2ends = x2end; firstinput = (int) (((char *) clientdata)-((char *) clientdata))/*0*/; } /* track pointer and get rubber box */ XtcwpRubberBox(XtDisplay(w),XtWindow(w),*event,&xb,&yb,&wb,&hb); /* if new box has zero width or height */ if (wb==0 || hb==0) { /* restore initial limits */ XtcwpSetAxesValues(w,x1begs,x1ends,x2begs,x2ends); /* else if non-zero zoom box */ } else { /* clip box */ if (xb<x) { wb -= x-xb; xb = x; } if (yb<y) { hb -= y-yb; yb = y; } if (xb+wb>x+width) wb = x-xb+width; if (yb+hb>y+height) hb = y-yb+height; /* determine axes limits */ if (style==XtcwpNORMAL) { x1begn = x1beg+(xb-x)*(x1end-x1beg)/width; x1endn = x1beg+(xb+wb-x)*(x1end-x1beg)/width; x2begn = x2end+(yb+hb-y)*(x2beg-x2end)/height; x2endn = x2end+(yb-y)*(x2beg-x2end)/height; } else { x1endn = x1beg+(yb+hb-y)*(x1end-x1beg)/height; x1begn = x1beg+(yb-y)*(x1end-x1beg)/height; x2begn = x2beg+(xb-x)*(x2end-x2beg)/width; x2endn = x2beg+(xb+wb-x)*(x2end-x2beg)/width; } /* set axes limits */ XtcwpSetAxesValues(w,x1begn,x1endn,x2begn,x2endn); } /* force an expose event */ XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,True);}static void xDrawMark(Display *dpy, Drawable d, GC gc, int x, int y, int index, int size){ XPoint points[4]; switch (index%NMARKS) { case MPLUS: /* plus */ XDrawLine(dpy,d,gc,x-(int)(0.5*size),y,x+(int)(0.5*size),y); XDrawLine(dpy,d,gc,x,y-(int)(0.5*size),x,y+(int)(0.5*size)); break; case MASTERISK: /* asterisk */ XDrawLine(dpy,d,gc,x-(int)(0.5*size),y,x+(int)(0.5*size),y); XDrawLine(dpy,d,gc,x-(int)(0.25*size),y-(int)(0.433*size), x+(int)(0.25*size),y+(int)(0.433*size)); XDrawLine(dpy,d,gc,x+(int)(0.25*size),y-(int)(0.433*size), x-(int)(0.25*size),y+(int)(0.433*size)); break; case MCROSS: /* X */ XDrawLine(dpy,d,gc,x-(int)(0.5*size),y-(int)(0.5*size), x+(int)(0.5*size),y+(int)(0.5*size)); XDrawLine(dpy,d,gc,x+(int)(0.5*size),y-(int)(0.5*size), x-(int)(0.5*size),y+(int)(0.5*size)); break; case MTRIANGLE: /* triangle */ points[0].x = x-(int)(0.5*size); points[0].y = y+(int)(0.25*size); points[1].x = x+(int)(0.5*size); points[1].y = y+(int)(0.25*size); points[2].x = x; points[2].y = y-(int)(0.559*size); points[3].x = x-(int)(0.5*size); points[3].y = y+(int)(0.25*size); XDrawLines(dpy,d,gc,points,4,CoordModeOrigin); break; case MSQUARE: /* square */ XDrawRectangle(dpy,d,gc,x-(int)(0.5*size),y-(int)(0.5*size), size,size); break; case MCIRCLE: /* circle */ XDrawArc(dpy,d,gc,x-(int)(0.5*size),y-(int)(0.5*size), size,size,0,360*64); break; case MFILLEDTRIANGLE: /* filled triangle */ points[0].x = x-(int)(0.75*size); points[0].y = y+(int)(0.375*size); points[1].x = x+(int)(0.75*size); points[1].y = y+(int)(0.375*size); points[2].x = x; points[2].y = y-(int)(0.838*size); points[3].x = x-(int)(0.75*size); points[3].y = y+(int)(0.375*size); XFillPolygon(dpy,d,gc,points,4,Convex,CoordModeOrigin); break; case MFILLEDSQUARE: /* filled square */ XFillRectangle(dpy,d,gc,x-(int)(0.5*size),y-(int)(0.5*size), size,size); break; case MFILLEDCIRCLE: /* filled circle */ XFillArc(dpy,d,gc,x-(int)(0.5*size),y-(int)(0.5*size), size,size,0,360*64); break; }}/*****************************************************************************Bill Wingle's routine to handle key presses.*****************************************************************************/void key_pressed (Widget w, graphics_data *data, XKeyEvent *event){ char buffer[2]; int bufsize = 2; KeySym key; XComposeStatus compose; XLookupString (event, buffer, bufsize, &key, &compose); if (key==XK_q || key==XK_Q) { exit(0); } }/* ARGSUSED *//*static void Quit (Widget w, XEvent *event, String *params, Cardinal *num_params){ exit(0);}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -