xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 98c3331e5c81c4bfa5036a9b6bc521ec2d439166)
1 
2 #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
3 #include <petscviewer.h>
4 PetscClassId PETSC_DRAWLG_CLASSID = 0;
5 
6 #undef __FUNCT__
7 #define __FUNCT__ "PetscDrawLGGetAxis"
8 /*@
9    PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
10    This is useful if one wants to change some axis property, such as
11    labels, color, etc. The axis context should not be destroyed by the
12    application code.
13 
14    Not Collective, if PetscDrawLG is parallel then PetscDrawAxis is parallel
15 
16    Input Parameter:
17 .  lg - the line graph context
18 
19    Output Parameter:
20 .  axis - the axis context
21 
22    Level: advanced
23 
24 @*/
25 PetscErrorCode  PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis)
26 {
27   PetscFunctionBegin;
28   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) {
29     *axis = 0;
30     PetscFunctionReturn(0);
31   }
32   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
33   PetscValidPointer(axis,2);
34   *axis = lg->axis;
35   PetscFunctionReturn(0);
36 }
37 
38 #undef __FUNCT__
39 #define __FUNCT__ "PetscDrawLGGetDraw"
40 /*@
41    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
42 
43    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
44 
45    Input Parameter:
46 .  lg - the line graph context
47 
48    Output Parameter:
49 .  draw - the draw context
50 
51    Level: intermediate
52 
53 @*/
54 PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
55 {
56   PetscFunctionBegin;
57   PetscValidHeader(lg,1);
58   PetscValidPointer(draw,2);
59   if (((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) *draw = (PetscDraw)lg;
60   else {
61     PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
62     *draw = lg->win;
63   }
64   PetscFunctionReturn(0);
65 }
66 
67 
68 #undef __FUNCT__
69 #define __FUNCT__ "PetscDrawLGSPDraw"
70 /*@
71    PetscDrawLGSPDraw - Redraws a line graph.
72 
73    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG
74 
75    Input Parameter:
76 .  lg - the line graph context
77 
78    Level: intermediate
79 
80 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
81 
82    Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same
83 
84 @*/
85 PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
86 {
87   PetscDrawLG    sp = (PetscDrawLG)spin;
88   PetscReal      xmin,xmax,ymin,ymax;
89   PetscErrorCode ierr;
90   int            i,j,dim,nopts,rank;
91   PetscDraw      draw = lg->win;
92 
93   PetscFunctionBegin;
94   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
95   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
96   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2);
97 
98   xmin = PetscMin(lg->xmin,sp->xmin);
99   ymin = PetscMin(lg->ymin,sp->ymin);
100   xmax = PetscMax(lg->xmax,sp->xmax);
101   ymax = PetscMax(lg->ymax,sp->ymax);
102 
103   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
104   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
105   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
106 
107   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
108   if (!rank) {
109 
110     dim   = lg->dim;
111     nopts = lg->nopts;
112     for (i=0; i<dim; i++) {
113       for (j=1; j<nopts; j++) {
114         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_BLACK+i);CHKERRQ(ierr);
115         if (lg->use_dots) {
116           ierr = PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED,"x");CHKERRQ(ierr);
117         }
118       }
119     }
120 
121     dim   = sp->dim;
122     nopts = sp->nopts;
123     for (i=0; i<dim; i++) {
124       for (j=0; j<nopts; j++) {
125         ierr = PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");CHKERRQ(ierr);
126       }
127     }
128   }
129   ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr);
130   ierr = PetscDrawPause(lg->win);CHKERRQ(ierr);
131   PetscFunctionReturn(0);
132 }
133 
134 
135 #undef __FUNCT__
136 #define __FUNCT__ "PetscDrawLGCreate"
137 /*@
138     PetscDrawLGCreate - Creates a line graph data structure.
139 
140     Collective over PetscDraw
141 
142     Input Parameters:
143 +   draw - the window where the graph will be made.
144 -   dim - the number of curves which will be drawn
145 
146     Output Parameters:
147 .   outctx - the line graph context
148 
149     Level: intermediate
150 
151     Concepts: line graph^creating
152 
153 .seealso:  PetscDrawLGDestroy()
154 @*/
155 PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outctx)
156 {
157   PetscErrorCode ierr;
158   PetscBool      isnull;
159   PetscObject    obj = (PetscObject)draw;
160   PetscDrawLG    lg;
161 
162   PetscFunctionBegin;
163   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
164   PetscValidPointer(outctx,2);
165   ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr);
166   if (isnull) {
167     ierr = PetscDrawOpenNull(PetscObjectComm((PetscObject)obj),(PetscDraw*)outctx);CHKERRQ(ierr);
168     PetscFunctionReturn(0);
169   }
170   ierr = PetscHeaderCreate(lg,_p_PetscDrawLG,int,PETSC_DRAWLG_CLASSID,"PetscDrawLG","Line graph","Draw",PetscObjectComm((PetscObject)obj),PetscDrawLGDestroy,0);CHKERRQ(ierr);
171 
172   lg->view    = 0;
173   lg->destroy = 0;
174   lg->nopts   = 0;
175   lg->win     = draw;
176   lg->dim     = dim;
177   lg->xmin    = 1.e20;
178   lg->ymin    = 1.e20;
179   lg->xmax    = -1.e20;
180   lg->ymax    = -1.e20;
181 
182   ierr = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
183   ierr = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
184 
185   lg->len     = dim*CHUNCKSIZE;
186   lg->loc     = 0;
187   lg->use_dots= PETSC_FALSE;
188 
189   ierr = PetscDrawAxisCreate(draw,&lg->axis);CHKERRQ(ierr);
190   ierr = PetscLogObjectParent((PetscObject)lg,(PetscObject)lg->axis);CHKERRQ(ierr);
191 
192   *outctx = lg;
193   PetscFunctionReturn(0);
194 }
195 
196 #undef __FUNCT__
197 #define __FUNCT__ "PetscDrawLGSetColors"
198 /*@
199    PetscDrawLGSetColors - Sets the color of each line graph drawn
200 
201    Logically Collective over PetscDrawLG
202 
203    Input Parameter:
204 +  lg - the line graph context.
205 -  colors - the colors
206 
207    Level: intermediate
208 
209    Concepts: line graph^setting number of lines
210 
211 @*/
212 PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int *colors)
213 {
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
218   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
219   ierr = PetscFree(lg->colors);CHKERRQ(ierr);
220   ierr = PetscMalloc1(lg->dim,&lg->colors);CHKERRQ(ierr);
221   ierr = PetscMemcpy(lg->colors,colors,lg->dim*sizeof(int));CHKERRQ(ierr);
222   PetscFunctionReturn(0);
223 }
224 
225 #undef __FUNCT__
226 #undef __FUNCT__
227 #define __FUNCT__ "PetscDrawLGSetLegend"
228 /*@C
229    PetscDrawLGSetLegend - sets the names of each curve plotted
230 
231    Logically Collective over PetscDrawLG
232 
233    Input Parameter:
234 +  lg - the line graph context.
235 -  names - the names for each curve
236 
237    Level: intermediate
238 
239    Concepts: line graph^setting number of lines
240 
241 @*/
242 PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
243 {
244   PetscErrorCode ierr;
245   PetscInt       i;
246 
247   PetscFunctionBegin;
248   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
249   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
250 
251   if (lg->legend) {
252     for (i=0; i<lg->dim; i++) {
253       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
254     }
255     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
256   }
257   if (names) {
258     ierr = PetscMalloc1(lg->dim,&lg->legend);CHKERRQ(ierr);
259     for (i=0; i<lg->dim; i++) {
260       ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr);
261     }
262   }
263   PetscFunctionReturn(0);
264 }
265 
266 #undef __FUNCT__
267 #define __FUNCT__ "PetscDrawLGGetDimension"
268 /*@
269    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
270 
271    Logically Collective over PetscDrawLG
272 
273    Input Parameter:
274 .  lg - the line graph context.
275 
276    Output Parameter:
277 .  dim - the number of curves.
278 
279    Level: intermediate
280 
281    Concepts: line graph^setting number of lines
282 
283 @*/
284 PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
285 {
286   PetscFunctionBegin;
287   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
288   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
289   *dim = lg->dim;
290   PetscFunctionReturn(0);
291 }
292 
293 #undef __FUNCT__
294 #define __FUNCT__ "PetscDrawLGSetDimension"
295 /*@
296    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
297 
298    Logically Collective over PetscDrawLG
299 
300    Input Parameter:
301 +  lg - the line graph context.
302 -  dim - the number of curves.
303 
304    Level: intermediate
305 
306    Concepts: line graph^setting number of lines
307 
308 @*/
309 PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
310 {
311   PetscErrorCode ierr;
312   PetscInt       i;
313 
314   PetscFunctionBegin;
315   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
316   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
317   PetscValidLogicalCollectiveInt(lg,dim,2);
318   if (lg->dim == dim) PetscFunctionReturn(0);
319 
320   ierr = PetscFree2(lg->x,lg->y);CHKERRQ(ierr);
321   if (lg->legend) {
322     for (i=0; i<lg->dim; i++) {
323       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
324     }
325     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
326   }
327   ierr    = PetscFree(lg->colors);CHKERRQ(ierr);
328   lg->dim = dim;
329   ierr    = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
330   ierr    = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
331   lg->len = dim*CHUNCKSIZE;
332   PetscFunctionReturn(0);
333 }
334 
335 #undef __FUNCT__
336 #define __FUNCT__ "PetscDrawLGReset"
337 /*@
338    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
339 
340    Logically Collective over PetscDrawLG
341 
342    Input Parameter:
343 .  lg - the line graph context.
344 
345    Level: intermediate
346 
347    Concepts: line graph^restarting
348 
349 @*/
350 PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
351 {
352   PetscFunctionBegin;
353   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
354   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
355   lg->xmin  = 1.e20;
356   lg->ymin  = 1.e20;
357   lg->xmax  = -1.e20;
358   lg->ymax  = -1.e20;
359   lg->loc   = 0;
360   lg->nopts = 0;
361   PetscFunctionReturn(0);
362 }
363 
364 #undef __FUNCT__
365 #define __FUNCT__ "PetscDrawLGDestroy"
366 /*@
367    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
368 
369    Collective over PetscDrawLG
370 
371    Input Parameter:
372 .  lg - the line graph context
373 
374    Level: intermediate
375 
376 .seealso:  PetscDrawLGCreate()
377 @*/
378 PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
379 {
380   PetscErrorCode ierr;
381   PetscInt       i;
382 
383   PetscFunctionBegin;
384   if (!*lg) PetscFunctionReturn(0);
385   if (((PetscObject)(*lg))->classid != PETSC_DRAW_CLASSID) PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1);
386 
387   if (--((PetscObject)(*lg))->refct > 0) {*lg = 0; PetscFunctionReturn(0);}
388   if (((PetscObject)(*lg))->classid == PETSC_DRAW_CLASSID) {
389     ierr = PetscObjectDestroy((PetscObject*)lg);CHKERRQ(ierr);
390     PetscFunctionReturn(0);
391   }
392   if ((*lg)->legend) {
393     for (i=0; i<(*lg)->dim; i++) {
394       ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr);
395     }
396     ierr = PetscFree((*lg)->legend);CHKERRQ(ierr);
397   }
398   ierr = PetscFree((*lg)->colors);CHKERRQ(ierr);
399   ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr);
400   ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr);
401   ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr);
402   PetscFunctionReturn(0);
403 }
404 #undef __FUNCT__
405 #define __FUNCT__ "PetscDrawLGIndicateDataPoints"
406 /*@
407    PetscDrawLGIndicateDataPoints - Causes LG to draw a big dot for each data-point.
408 
409    Not Collective, but ignored by all processors except processor 0 in PetscDrawLG
410 
411    Input Parameters:
412 +  lg - the linegraph context
413 -  flg - should mark each data point
414 
415    Options Database:
416 .  -lg_indicate_data_points  <true,false>
417 
418    Level: intermediate
419 
420    Concepts: line graph^showing points
421 
422 @*/
423 PetscErrorCode  PetscDrawLGIndicateDataPoints(PetscDrawLG lg,PetscBool flg)
424 {
425   PetscFunctionBegin;
426   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
427 
428   lg->use_dots = flg;
429   PetscFunctionReturn(0);
430 }
431 
432 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
433 #include <X11/Xlib.h>
434 #include <X11/Xutil.h>
435 #include <setjmp.h>
436 static jmp_buf PetscXIOErrorJumpBuf;
437 static void PetscXIOHandler(Display *dpy)
438 {
439   longjmp(PetscXIOErrorJumpBuf, 1);
440 }
441 #endif
442 
443 #undef __FUNCT__
444 #define __FUNCT__ "PetscDrawLGDraw"
445 /*@
446    PetscDrawLGDraw - Redraws a line graph.
447 
448    Not Collective,but ignored by all processors except processor 0 in PetscDrawLG
449 
450    Input Parameter:
451 .  lg - the line graph context
452 
453    Level: intermediate
454 
455 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw()
456 
457 @*/
458 PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
459 {
460   PetscReal      xmin=lg->xmin,xmax=lg->xmax,ymin=lg->ymin,ymax=lg->ymax;
461   PetscErrorCode ierr;
462   int            i,j,dim = lg->dim,nopts = lg->nopts,rank,cl;
463   PetscDraw      draw = lg->win;
464   PetscBool      isnull;
465 
466   PetscFunctionBegin;
467   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
468   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
469   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
470   if (isnull) PetscFunctionReturn(0);
471 
472 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
473   if (!setjmp(PetscXIOErrorJumpBuf)) XSetIOErrorHandler((XIOErrorHandler)PetscXIOHandler);
474   else {
475     XSetIOErrorHandler(NULL);
476     ierr = PetscDrawSetType(draw,PETSC_DRAW_NULL);CHKERRQ(ierr);
477     PetscFunctionReturn(0);
478   }
479 #endif
480 
481   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
482   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
483   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
484   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
485 
486   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
487   if (!rank) {
488 
489     for (i=0; i<dim; i++) {
490       for (j=1; j<nopts; j++) {
491         if (lg->colors) cl = lg->colors[i];
492         else cl = PETSC_DRAW_BLACK+i;
493         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);
494         if (lg->use_dots) {
495           ierr = PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl,"x");CHKERRQ(ierr);
496         }
497       }
498     }
499   }
500   if (lg->legend) {
501     PetscReal xl,yl,xr,yr,tw,th;
502     size_t    len,mlen = 0;
503     int       cl;
504     ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
505     ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
506     for (i=0; i<dim; i++) {
507       ierr = PetscStrlen(lg->legend[i],&len);CHKERRQ(ierr);
508       mlen = PetscMax(mlen,len);
509     }
510     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - 2*tw,yr - 3*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
511     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
512     for  (i=0; i<dim; i++) {
513       cl   = (lg->colors ? lg->colors[i] : i + 1);
514       ierr = PetscDrawLine(draw,xr - (mlen + 6.7)*tw,yr - (4 + i)*th,xr - (mlen + 3.2)*tw,yr - (4 + i)*th,cl);CHKERRQ(ierr);
515       ierr = PetscDrawString(draw,xr - (mlen + 3)*tw,yr - (4.5 + i)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr);
516     }
517     ierr = PetscDrawLine(draw,xr - 2*tw,yr - 3*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
518     ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr);
519   }
520   ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr);
521   ierr = PetscDrawPause(lg->win);CHKERRQ(ierr);
522 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X)
523   XSetIOErrorHandler(NULL);
524 #endif
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "PetscDrawLGView"
530 /*@
531   PetscDrawLGView - Prints a line graph.
532 
533   Not collective
534 
535   Input Parameter:
536 . lg - the line graph context
537 
538   Level: beginner
539 
540 .keywords:  draw, line, graph
541 @*/
542 PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
543 {
544   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
545   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
546   PetscErrorCode ierr;
547 
548   PetscFunctionBegin;
549   if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
550   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID,1);
551   if (nopts < 1)                  PetscFunctionReturn(0);
552   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
553 
554   if (!viewer){
555     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr);
556   }
557   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);CHKERRQ(ierr);
558   for (i = 0; i < dim; i++) {
559     ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr);
560     for (j = 0; j < nopts; j++) {
561       ierr = PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr);
562     }
563   }
564   PetscFunctionReturn(0);
565 }
566 
567 #undef __FUNCT__
568 #define __FUNCT__ "PetscDrawLGSetFromOptions"
569 /*@
570     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
571 
572     Collective over PetscDrawLG
573 
574     Options Database:
575 
576     Level: intermediate
577 
578     Concepts: line graph^creating
579 
580 .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
581 @*/
582 PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
583 {
584   PetscErrorCode ierr;
585   PetscBool      flg,set;
586 
587   PetscFunctionBegin;
588   ierr = PetscOptionsGetBool(NULL,"-lg_indicate_data_points",&flg,&set);CHKERRQ(ierr);
589   if (set) {
590     ierr = PetscDrawLGIndicateDataPoints(lg,flg);CHKERRQ(ierr);
591   }
592   PetscFunctionReturn(0);
593 }
594