source: trunk/src/Plotter2.cpp @ 2895

Last change on this file since 2895 was 2895, checked in by WataruKawasaki, 10 years ago

New Development: Yes

JIRA Issue: Yes CAS-6168

Ready for Test: Yes

Interface Changes:

What Interface Changed:

Test Programs:

Put in Release Notes: Yes

Module(s): sd.plotter2

Description: added methods to sd.plotter2 to enable changing the size and shape of the entire region to be plotted (which is referred to as 'viewsurface' in PGPLOT).


File size: 35.7 KB
Line 
1#include "Plotter2.h"
2
3namespace asap {
4
5Plotter2RectInfo::Plotter2RectInfo() {
6    xmin = 0.0;
7    xmax = 1.0;
8    ymin = 0.0;
9    ymax = 1.0;
10    color = 15; // gray
11    fill  = 4;  // hatch
12    width = 1;
13}
14
15Plotter2RectInfo::~Plotter2RectInfo() {
16}
17
18Plotter2DataInfo::Plotter2DataInfo() {
19    xData.clear();
20    yData.clear();
21
22    drawLine  = true;
23    lineStyle = 1;       // solid line
24    lineWidth = 1;
25    lineColor = -1;      // undefined (default color should be assigned)
26
27    drawMarker  = false;
28    markerType  = 20;    // small circle
29    markerSize  = 1.0;
30    markerColor = 1;     // default foreground color (black)
31
32    hasData = false;     // has no data
33}
34
35Plotter2DataInfo::~Plotter2DataInfo() {
36}
37
38Plotter2ViewportInfo::Plotter2ViewportInfo() {
39    showViewport = true;
40
41    vpPosXMin = 0.1;
42    vpPosXMax = 0.9;
43    vpPosYMin = 0.1;
44    vpPosYMax = 0.9;
45
46    vpRangeXMin = 0.0;
47    vpRangeXMax = 1.0;
48    vpRangeYMin = 0.0;
49    vpRangeYMax = 1.0;
50    isAutoRangeX = true;
51    isAutoRangeY = true;
52    autoRangeMarginX = 0.0;
53    autoRangeMarginY = 0.1;
54
55    hasDataRange = false;
56
57    isAutoTickIntervalX = true;
58    isAutoTickIntervalY = true;
59    majorTickIntervalX = 0.1;
60    majorTickIntervalY = 0.1;
61    nMajorTickWithinTickNumsX = 2;
62    nMajorTickWithinTickNumsY = 2;
63    nMinorTickWithinMajorTicksX = 5;
64    nMinorTickWithinMajorTicksY = 5;
65
66    numLocationX = "b";
67    numLocationY = "l";
68
69    fontSizeDef = 1.0;
70
71    vData.clear();
72    vRect.clear();
73
74    labelXString = "";
75    labelXPosX = 0.5;
76    labelXPosY = 0.05;
77    labelXAngle = 0.0;
78    labelXFJust = 0.5;
79    labelXSize = fontSizeDef * 1.1;
80    labelXColor = 1;
81    labelXBColor = 0;
82
83    labelYString = "";
84    labelYPosX = 0.05;
85    labelYPosY = 0.5;
86    labelYAngle = 90.0;
87    labelYFJust = 0.5;
88    labelYSize = fontSizeDef * 1.1;
89    labelYColor = 1;
90    labelYBColor = 0;
91
92    titleString = "";
93    titlePosX = 0.5;
94    titlePosY = 0.95;
95    titleAngle = 0.0;
96    titleFJust = 0.5;
97    titleSize = fontSizeDef * 1.5;
98    titleColor = 1;
99    titleBColor = 0;
100
101    vpBColor = -1; // transparent (<0)
102}
103
104Plotter2ViewportInfo::~Plotter2ViewportInfo() {
105    vData.clear();
106}
107
108void Plotter2ViewportInfo::adjustRange() {
109    if (hasDataRange) {
110        if (isAutoRangeX) {
111            adjustRangeX(&vpRangeXMin, &vpRangeXMax);
112        }
113        if (isAutoRangeY) {
114            adjustRangeY(&vpRangeYMin, &vpRangeYMax);
115        }
116    }
117}
118
119void Plotter2ViewportInfo::adjustRangeX(float* xmin, float* xmax) {
120    float xmargin = (maxXData - minXData) * autoRangeMarginX;
121    *xmin = minXData - xmargin;
122    *xmax = maxXData + xmargin;
123}
124
125void Plotter2ViewportInfo::adjustRangeY(float* ymin, float* ymax) {
126    float ymargin = (maxYData - minYData) * autoRangeMarginY;
127    *ymin = minYData - ymargin;
128    *ymax = maxYData + ymargin;
129}
130
131std::vector<float> Plotter2ViewportInfo::getRangeX() {
132    float minX, maxX;
133
134    if (isAutoRangeX) {
135        adjustRangeX(&minX, &maxX);
136    } else {
137        minX = vpRangeXMin;
138        maxX = vpRangeXMax;
139    }
140
141    std::vector<float> res;
142    res.clear();
143    res.push_back(minX);
144    res.push_back(maxX);
145
146    return res;
147}
148
149std::vector<float> Plotter2ViewportInfo::getRangeY() {
150    float minY, maxY;
151
152    if (isAutoRangeY) {
153        adjustRangeY(&minY, &maxY);
154    } else {
155        minY = vpRangeYMin;
156        maxY = vpRangeYMax;
157    }
158
159    std::vector<float> res;
160    res.clear();
161    res.push_back(minY);
162    res.push_back(maxY);
163
164    return res;
165}
166
167void Plotter2ViewportInfo::adjustTickInterval() {
168    if (hasDataRange) {
169        if (isAutoTickIntervalX) {
170            adjustTickIntervalX(vpRangeXMin, vpRangeXMax);
171        }
172        if (isAutoTickIntervalY) {
173            adjustTickIntervalY(vpRangeYMin, vpRangeYMax);
174        }
175    }
176}
177
178void Plotter2ViewportInfo::adjustTickIntervalX(const float xmin, const float xmax) {
179    majorTickIntervalX = (float)pow(10.0, ceil(log10((xmax - xmin)/10.0)));
180    if ((xmax - xmin) / majorTickIntervalX < 4.0) {
181        majorTickIntervalX /= 2.0;
182    }
183    if ((xmax - xmin) / majorTickIntervalX < 4.0) {
184        majorTickIntervalX /= 2.0;
185    }
186}
187
188void Plotter2ViewportInfo::adjustTickIntervalY(const float ymin, const float ymax) {
189    majorTickIntervalY = (float)pow(10.0, ceil(log10((ymax - ymin)/10.0)));
190    if ((ymax - ymin) / majorTickIntervalY < 4.0) {
191        majorTickIntervalY /= 2.0;
192    }
193    if ((ymax - ymin) / majorTickIntervalY < 4.0) {
194        majorTickIntervalY /= 2.0;
195    }
196}
197
198void Plotter2ViewportInfo::setData(const std::vector<float>& inXData, const std::vector<float>& inYData, const int id) {
199    if (!hasDataRange) {
200        minXData = inXData[0];
201        maxXData = inXData[0];
202        minYData = inYData[0];
203        maxYData = inYData[0];
204
205        hasDataRange = true;
206    }
207
208    Plotter2DataInfo* info = &vData[id];
209
210    info->xData.clear();
211    info->xData.reserve(inXData.size());
212    for (unsigned int i = 0; i < inXData.size(); ++i) {
213        info->xData.push_back(inXData[i]);
214
215        if (!info->hasData) {
216            updateXDataRange(inXData[i]);
217        }
218    }
219
220    info->yData.clear();
221    info->yData.reserve(inYData.size());
222    for (unsigned int i = 0; i < inYData.size(); ++i) {
223        info->yData.push_back(inYData[i]);
224
225        if (!info->hasData) {
226            updateYDataRange(inYData[i]);
227        }
228    }
229
230    if (info->hasData) {
231        updateAllDataRanges();
232    } else {
233        info->hasData = true;
234    }
235
236    adjustRange();
237    adjustTickInterval();
238}
239
240void Plotter2ViewportInfo::updateXDataRange(const float data) {
241    if (data < minXData) {
242        minXData = data;
243    }
244    if (maxXData < data) {
245        maxXData = data;
246    }
247}
248
249void Plotter2ViewportInfo::updateYDataRange(const float data) {
250    if (data < minYData) {
251        minYData = data;
252    }
253    if (maxYData < data) {
254        maxYData = data;
255    }
256}
257
258void Plotter2ViewportInfo::updateAllDataRanges() {
259    minXData = vData[0].xData[0];
260    maxXData = minXData;
261    minYData = vData[0].yData[0];
262    maxYData = minYData;
263
264    for (unsigned int i = 0; i < vData.size(); ++i) {
265        for (unsigned int j = 0; j < vData[i].xData.size(); ++j) {
266            updateXDataRange(vData[i].xData[j]);
267            updateYDataRange(vData[i].yData[j]);
268        }
269    }
270}
271
272void Plotter2ViewportInfo::getWorldCoordByWindowCoord(const float winX, const float winY, float* worldX, float* worldY) {
273    float xratio = (winX - vpPosXMin) / (vpPosXMax - vpPosXMin);
274    if (winX < 0.0) {
275        xratio = 0.5;
276    }
277    *worldX = vpRangeXMin + xratio * (vpRangeXMax - vpRangeXMin);
278    float yratio = (winY - vpPosYMin) / (vpPosYMax - vpPosYMin);
279    if (winY < 0.0) {
280        yratio = 0.5;
281    }
282    *worldY = vpRangeYMin + yratio * (vpRangeYMax - vpRangeYMin);
283}
284
285Plotter2::Plotter2() {
286    filename = "";
287    device = "xwindow";
288    hasDevice = false;
289
290    vInfo.clear();
291    Plotter2ViewportInfo vi;
292    vInfo.push_back(vi);
293
294    hasDefaultViewport = true;
295    currentViewportId = 0;
296
297    width = 8.82796; // default viewsurface width seems to be this value.
298    aspect = 0.75;   // default viewsurface aspect
299}
300
301Plotter2::~Plotter2() {
302    close();
303    vInfo.clear();
304}
305
306std::string Plotter2::getFileName() {
307    return filename;
308}
309
310void Plotter2::setFileName(const std::string& inFilename) {
311    filename = inFilename;
312}
313
314std::string Plotter2::getDevice() {
315    return device;
316}
317
318void Plotter2::setDevice(const std::string& inDevice) {
319    device = inDevice;
320}
321
322void Plotter2::open() {
323    cpgopen((filename + "/" + device).c_str());
324    hasDevice = true;
325}
326
327float Plotter2::getViewSurfaceWidth() {
328    return width;
329}
330
331float Plotter2::getViewSurfaceAspect() {
332    return aspect;
333}
334
335void Plotter2::setViewSurface(const float inWidth, const float inAspect) {
336    width = inWidth;
337    aspect = inAspect;
338}
339
340int Plotter2::addViewport(const float xmin, const float xmax, const float ymin, const float ymax) {
341    Plotter2ViewportInfo vi;
342
343    vi.vpPosXMin = xmin;
344    vi.vpPosXMax = xmax;
345    vi.vpPosYMin = ymin;
346    vi.vpPosYMax = ymax;
347
348    vInfo.push_back(vi);
349    currentViewportId = vInfo.size() - 1;
350
351    return currentViewportId;
352}
353
354void Plotter2::setViewport(const float xmin, const float xmax, const float ymin, const float ymax, const int id) {
355    Plotter2ViewportInfo* vi = &vInfo[id];
356
357    vi->vpPosXMin = xmin;
358    vi->vpPosXMax = xmax;
359    vi->vpPosYMin = ymin;
360    vi->vpPosYMax = ymax;
361
362    hasDefaultViewport = false;
363}
364
365void Plotter2::showViewport(const int inVpid) {
366    int vpid = inVpid;
367    if (vpid < 0) {
368        vpid = vInfo.size() - 1;
369    }
370    if (vpid < 0) {
371        exit(0);
372    }
373
374    Plotter2ViewportInfo* vi = &vInfo[vpid];
375    vi->showViewport = true;
376}
377
378void Plotter2::hideViewport(const int inVpid) {
379    int vpid = inVpid;
380    if (vpid < 0) {
381        vpid = vInfo.size() - 1;
382    }
383    if (vpid < 0) {
384        exit(0);
385    }
386
387    Plotter2ViewportInfo* vi = &vInfo[vpid];
388    vi->showViewport = false;
389}
390
391bool Plotter2::getHasDefaultViewport() {
392    return hasDefaultViewport;
393}
394
395int Plotter2::getCurrentViewportId() {
396    return currentViewportId;
397}
398
399void Plotter2::getViewInfo() {
400    std::string colorNames[16] = {"white", "black", "red", "green",
401                                  "blue", "cyan", "magenta", "yellow",
402                                  "orange", "yellowgreen", "emerald", "skyblue",
403                                  "purple", "pink", "gray", "lightgray"};
404    std::string lstyleNames[6] = {"", "solid", "dashed", "dash-dotted", "dotted", "dash-dot-dot-dotted"};
405    std::string fstyleNames[5] = {"", "solid", "outline", "hatched", "crosshatched"};
406
407    for (unsigned int i = 0; i < vInfo.size(); ++i) {
408        std::cout << "Viewport [ID = " << i << "] (" << (i+1) << "/" << vInfo.size() << ") ";
409        std::cout << "=============================================================" << std::endl;
410
411        std::cout << "  Visible: " << (vInfo[i].showViewport ? "Yes" : "No") << std::endl;
412
413        std::cout << "  Position in Window Coordinate: ";
414        std::cout << "X(left=" << vInfo[i].vpPosXMin << ",right=" << vInfo[i].vpPosXMax << "), ";
415        std::cout << "Y(bottom=" << vInfo[i].vpPosYMin << ",top=" << vInfo[i].vpPosYMax << ")" << std::endl;
416
417        std::cout << "  Display Range: ";
418        std::cout << "X(" << (vInfo[i].isAutoRangeX ? "automatic" : "manual") << ", ";
419        std::cout << "min=" << vInfo[i].vpRangeXMin << ", max=" << vInfo[i].vpRangeXMax << "), ";
420        std::cout << "Y(" << (vInfo[i].isAutoRangeY ? "automatic" : "manual") << ", ";
421        std::cout << "min=" << vInfo[i].vpRangeYMin << ", max=" << vInfo[i].vpRangeYMax << ")" << std::endl;
422
423        std::cout << "  Numbering/Ticks:" << std::endl;
424        std::cout << "    X(" << ((vInfo[i].numLocationX == "b") ? "bottom" : ((vInfo[i].numLocationX == "t") ? "top" : (vInfo[i].numLocationX + " [*INVAILD*]"))) << ", interval[" << (vInfo[i].isAutoTickIntervalX ? "automatic" : "manual") << ", ";
425        std::cout << "numbering=" << (vInfo[i].majorTickIntervalX * vInfo[i].nMajorTickWithinTickNumsX) << ", ";
426        std::cout << "majortick=" << vInfo[i].majorTickIntervalX << ", ";
427        std::cout << "minortick=" << (vInfo[i].majorTickIntervalX / vInfo[i].nMinorTickWithinMajorTicksX) << "])" << std::endl;
428        std::cout << "    Y(" << ((vInfo[i].numLocationY == "l") ? "left" : ((vInfo[i].numLocationY == "r") ? "right" : (vInfo[i].numLocationY + " [*INVAILD*]"))) << ", interval[" << (vInfo[i].isAutoTickIntervalY ? "automatic" : "manual") << ", ";
429        std::cout << "numbering=" << (vInfo[i].majorTickIntervalY * vInfo[i].nMajorTickWithinTickNumsY) << ", ";
430        std::cout << "majortick=" << vInfo[i].majorTickIntervalY << ", ";
431        std::cout << "minortick=" << (vInfo[i].majorTickIntervalY / vInfo[i].nMinorTickWithinMajorTicksY) << "])" << std::endl;
432
433        std::cout << "  X Label: ";
434        if (vInfo[i].labelXString != "") {
435            std::cout << "\"" << vInfo[i].labelXString << "\"" << std::endl;
436            std::cout << "    position=(" << vInfo[i].labelXPosX << "," << vInfo[i].labelXPosY << "), ";
437            std::cout << "justification=" << vInfo[i].labelXFJust << ", ";
438            std::cout << "angle=" << vInfo[i].labelXAngle << "deg, ";
439            std::cout << "fontsize=" << vInfo[i].labelXSize << std::endl;
440        } else {
441            std::cout << "No" << std::endl;
442        }
443
444        std::cout << "  Y Label: ";
445        if (vInfo[i].labelYString != "") {
446            std::cout << "\"" << vInfo[i].labelYString << "\"" << std::endl;
447            std::cout << "    position=(" << vInfo[i].labelYPosX << "," << vInfo[i].labelYPosY << "), ";
448            std::cout << "justification=" << vInfo[i].labelYFJust << ", ";
449            std::cout << "angle=" << vInfo[i].labelYAngle << "deg, ";
450            std::cout << "fontsize=" << vInfo[i].labelYSize << std::endl;
451        } else {
452            std::cout << "No" << std::endl;
453        }
454
455        std::cout << "  Title: ";
456        if (vInfo[i].titleString != "") {
457            std::cout << "\"" << vInfo[i].titleString << "\"" << std::endl;
458            std::cout << "    position=(" << vInfo[i].titlePosX << "," << vInfo[i].titlePosY << "), ";
459            std::cout << "justification=" << vInfo[i].titleFJust << ", ";
460            std::cout << "angle=" << vInfo[i].titleAngle << "deg, ";
461            std::cout << "fontsize=" << vInfo[i].titleSize << std::endl;
462        } else {
463            std::cout << "No" << std::endl;
464        }
465
466        std::cout << "  Background Color = ";
467        if (vInfo[i].vpBColor < 0) {
468            std::cout << "transparent" << std::endl;
469        } else if (vInfo[i].vpBColor < 16) {
470            std::cout << colorNames[vInfo[i].vpBColor] << std::endl;
471        } else {
472            std::cout << "index:" << vInfo[i].vpBColor << " [INVAILD VALUE!]" << std::endl;
473        }
474
475        for (unsigned int j = 0; j < vInfo[i].vData.size(); ++j) {
476            std::cout << "  Dataset [ID = " << j << "] (" << (j+1) << "/" << vInfo[i].vData.size() << ") ";
477            std::cout << "----------------------------------------------" << std::endl;
478
479            bool showDataset = (vInfo[i].vData[j].drawLine || vInfo[i].vData[j].drawMarker);
480            bool showViewport = vInfo[i].showViewport;
481            std::cout << "    Visible: " << (showViewport ? "" : "(");
482            std::cout << (showDataset ? "Yes" : "No") << (showViewport ? "" : ")") << std::endl;
483            std::cout << "    Number of Data Points: " << vInfo[i].vData[j].xData.size() << std::endl;
484            if (vInfo[i].vData[j].drawLine) {
485                std::cout << "    Line: color=";
486                if (vInfo[i].vData[j].lineColor < 0) {
487                  int defaultColorIdx = (j + 1) % 15 + 1;
488                    std::cout << "default(" << colorNames[defaultColorIdx] << ")";
489                } else if (vInfo[i].vData[j].lineColor < 16) {
490                    std::cout << colorNames[vInfo[i].vData[j].lineColor];
491                } else {
492                    std::cout << "index:" << vInfo[i].vData[j].lineColor << " [*INVAILD*]";
493                }
494                std::cout << ", width=" << vInfo[i].vData[j].lineWidth;
495                std::cout << ", style=" << lstyleNames[vInfo[i].vData[j].lineStyle] << std::endl;
496            }
497            if (vInfo[i].vData[j].drawMarker) {
498                std::cout << "    Marker: color=";
499                if (vInfo[i].vData[j].markerColor < 0) {
500                    std::cout << "default";
501                } else if (vInfo[i].vData[j].markerColor < 16) {
502                    std::cout << colorNames[vInfo[i].vData[j].markerColor];
503                } else {
504                    std::cout << "index:" << vInfo[i].vData[j].markerColor << " [*INVAILD*]";
505                }
506                std::cout << ", shape=" << vInfo[i].vData[j].markerType;
507                std::cout << ", size=" << vInfo[i].vData[j].markerSize << std::endl;
508            }
509
510        }
511
512        for (unsigned int j = 0; j < vInfo[i].vRect.size(); ++j) {
513            std::cout << "  XMask [ID = " << j << "] (" << (j+1) << "/" << vInfo[i].vRect.size() << ") ";
514            std::cout << "----------------------------------------------" << std::endl;
515            std::cout << "    Range: (min=" << vInfo[i].vRect[j].xmin << ", max=" << vInfo[i].vRect[j].xmax << ")" << std::endl;
516            std::cout << "    Attributes: (color=" << colorNames[vInfo[i].vRect[j].color];
517            std::string fstyle = fstyleNames[vInfo[i].vRect[j].fill];
518            std::cout << ", fillstyle=" << fstyle;
519            if (fstyle == "outline") {
520                std::cout << ", outlinewidth=" << vInfo[i].vRect[j].width;
521            }
522            if ((fstyle == "hatched")||(fstyle == "crosshatched")) {
523                std::cout << ", hatchspacing=" << vInfo[i].vRect[j].hsep;
524            }
525            std::cout << ")" << std::endl;
526        }
527    }
528    std::cout << "=====================================================================================" << std::endl << std::flush;
529}
530
531void Plotter2::setRange(const float xmin, const float xmax, const float ymin, const float ymax, const int inVpid) {
532    setRangeX(xmin, xmax, inVpid);
533    setRangeY(ymin, ymax, inVpid);
534}
535
536void Plotter2::setRangeX(const float xmin, const float xmax, const int inVpid) {
537    int vpid = inVpid;
538    if (vpid < 0) {
539        vpid = vInfo.size() - 1;
540    }
541    if (vpid < 0) {
542        Plotter2ViewportInfo vi;
543        vInfo.push_back(vi);
544        vpid = 0;
545    }
546
547    Plotter2ViewportInfo* vi = &vInfo[vpid];
548    vi->vpRangeXMin = xmin;
549    vi->vpRangeXMax = xmax;
550    vi->isAutoRangeX = false;
551}
552
553void Plotter2::setRangeY(const float ymin, const float ymax, const int inVpid) {
554    int vpid = inVpid;
555    if (vpid < 0) {
556        vpid = vInfo.size() - 1;
557    }
558    if (vpid < 0) {
559        Plotter2ViewportInfo vi;
560        vInfo.push_back(vi);
561        vpid = 0;
562    }
563
564    Plotter2ViewportInfo* vi = &vInfo[vpid];
565    vi->vpRangeYMin = ymin;
566    vi->vpRangeYMax = ymax;
567    vi->isAutoRangeY = false;
568}
569
570std::vector<float> Plotter2::getRangeX(const int inVpid) {
571    int vpid = inVpid;
572    if (vpid < 0) {
573        vpid = vInfo.size() - 1;
574    }
575    if (vpid < 0) {
576        exit(0);
577    }
578
579    return vInfo[vpid].getRangeX();
580}
581
582std::vector<float> Plotter2::getRangeY(const int inVpid) {
583    int vpid = inVpid;
584    if (vpid < 0) {
585        vpid = vInfo.size() - 1;
586    }
587    if (vpid < 0) {
588        exit(0);
589    }
590
591    return vInfo[vpid].getRangeY();
592}
593
594void Plotter2::setAutoRange(const int inVpid) {
595    setAutoRangeX(inVpid);
596    setAutoRangeY(inVpid);
597}
598
599void Plotter2::setAutoRangeX(const int inVpid) {
600    int vpid = inVpid;
601    if (vpid < 0) {
602        vpid = vInfo.size() - 1;
603    }
604    if (vpid < 0) {
605        Plotter2ViewportInfo vi;
606        vInfo.push_back(vi);
607        vpid = 0;
608    }
609
610    Plotter2ViewportInfo* vi = &vInfo[vpid];
611    vi->isAutoRangeX = true;
612}
613
614void Plotter2::setAutoRangeY(const int inVpid) {
615    int vpid = inVpid;
616    if (vpid < 0) {
617        vpid = vInfo.size() - 1;
618    }
619    if (vpid < 0) {
620        Plotter2ViewportInfo vi;
621        vInfo.push_back(vi);
622        vpid = 0;
623    }
624
625    Plotter2ViewportInfo* vi = &vInfo[vpid];
626    vi->isAutoRangeY = true;
627}
628
629void Plotter2::setFontSizeDef(const float size, const int inVpid) {
630    int vpid = inVpid;
631    if (vpid < 0) {
632        vpid = vInfo.size() - 1;
633    }
634    if (vpid < 0) {
635        Plotter2ViewportInfo vi;
636        vInfo.push_back(vi);
637        vpid = 0;
638    }
639
640    Plotter2ViewportInfo* vi = &vInfo[vpid];
641    vi->fontSizeDef = size;
642}
643
644void Plotter2::setTicksX(const float interval, const int num, const int inVpid) {
645    int vpid = inVpid;
646    if (vpid < 0) {
647        vpid = vInfo.size() - 1;
648    }
649    if (vpid < 0) {
650        Plotter2ViewportInfo vi;
651        vInfo.push_back(vi);
652        vpid = 0;
653    }
654
655    Plotter2ViewportInfo* vi = &vInfo[vpid];
656    vi->majorTickIntervalX = interval;
657    vi->nMinorTickWithinMajorTicksX = num;
658    vi->isAutoTickIntervalX = false;
659}
660
661void Plotter2::setTicksY(const float interval, const int num, const int inVpid) {
662    int vpid = inVpid;
663    if (vpid < 0) {
664        vpid = vInfo.size() - 1;
665    }
666    if (vpid < 0) {
667        Plotter2ViewportInfo vi;
668        vInfo.push_back(vi);
669        vpid = 0;
670    }
671
672    Plotter2ViewportInfo* vi = &vInfo[vpid];
673    vi->majorTickIntervalY = interval;
674    vi->nMinorTickWithinMajorTicksY = num;
675    vi->isAutoTickIntervalY = false;
676}
677
678void Plotter2::setAutoTicks(const int inVpid) {
679    setAutoTicksX(inVpid);
680    setAutoTicksY(inVpid);
681}
682
683void Plotter2::setAutoTicksX(const int inVpid) {
684    int vpid = inVpid;
685    if (vpid < 0) {
686        vpid = vInfo.size() - 1;
687    }
688    if (vpid < 0) {
689        Plotter2ViewportInfo vi;
690        vInfo.push_back(vi);
691        vpid = 0;
692    }
693
694    Plotter2ViewportInfo* vi = &vInfo[vpid];
695    vi->isAutoTickIntervalX = true;
696}
697
698void Plotter2::setAutoTicksY(const int inVpid) {
699    int vpid = inVpid;
700    if (vpid < 0) {
701        vpid = vInfo.size() - 1;
702    }
703    if (vpid < 0) {
704        Plotter2ViewportInfo vi;
705        vInfo.push_back(vi);
706        vpid = 0;
707    }
708
709    Plotter2ViewportInfo* vi = &vInfo[vpid];
710    vi->isAutoTickIntervalY = true;
711}
712
713void Plotter2::setNumIntervalX(const float interval, const int inVpid) {
714    int vpid = inVpid;
715    if (vpid < 0) {
716        vpid = vInfo.size() - 1;
717    }
718    if (vpid < 0) {
719        Plotter2ViewportInfo vi;
720        vInfo.push_back(vi);
721        vpid = 0;
722    }
723
724    Plotter2ViewportInfo* vi = &vInfo[vpid];
725    vi->nMajorTickWithinTickNumsX = (int)(interval / vi->majorTickIntervalX);
726}
727
728void Plotter2::setNumIntervalY(const float interval, const int inVpid) {
729    int vpid = inVpid;
730    if (vpid < 0) {
731        vpid = vInfo.size() - 1;
732    }
733    if (vpid < 0) {
734        Plotter2ViewportInfo vi;
735        vInfo.push_back(vi);
736        vpid = 0;
737    }
738
739    Plotter2ViewportInfo* vi = &vInfo[vpid];
740    vi->nMajorTickWithinTickNumsY = (int)(interval / vi->majorTickIntervalY);
741}
742
743void Plotter2::setNumLocationX(const std::string& side, const int inVpid) {
744    int vpid = inVpid;
745    if (vpid < 0) {
746        vpid = vInfo.size() - 1;
747    }
748    if (vpid < 0) {
749        Plotter2ViewportInfo vi;
750        vInfo.push_back(vi);
751        vpid = 0;
752    }
753
754    Plotter2ViewportInfo* vi = &vInfo[vpid];
755    vi->numLocationX = side;
756}
757
758void Plotter2::setNumLocationY(const std::string& side, const int inVpid) {
759    int vpid = inVpid;
760    if (vpid < 0) {
761        vpid = vInfo.size() - 1;
762    }
763    if (vpid < 0) {
764        Plotter2ViewportInfo vi;
765        vInfo.push_back(vi);
766        vpid = 0;
767    }
768
769    Plotter2ViewportInfo* vi = &vInfo[vpid];
770    vi->numLocationY = side;
771}
772
773void Plotter2::setData(const std::vector<float>& xdata, const std::vector<float>& ydata, const int inVpid, const int inDataid) {
774    int vpid = inVpid;
775    if (vpid < 0) {
776        vpid = vInfo.size() - 1;
777    }
778    if (vpid < 0) {
779        Plotter2ViewportInfo vi;
780        vInfo.push_back(vi);
781        vpid = 0;
782    }
783
784    Plotter2ViewportInfo* vi = &vInfo[vpid];
785
786    int dataid = inDataid;
787    if (dataid < 0) {
788        Plotter2DataInfo di;
789        vi->vData.push_back(di);
790        dataid = vi->vData.size() - 1;
791    }
792
793    vi->setData(xdata, ydata, dataid);
794}
795
796void Plotter2::setLine(const int color, const int width, const int style, const int inVpid, const int inDataid) {
797    int vpid = inVpid;
798    if (vpid < 0) {
799        vpid = vInfo.size() - 1;
800    }
801    if (vpid < 0) {
802        Plotter2ViewportInfo vi;
803        vInfo.push_back(vi);
804        vpid = 0;
805    }
806
807    int dataid = inDataid;
808    if (dataid < 0) {
809        dataid = vInfo[vpid].vData.size() - 1;
810    }
811
812    Plotter2ViewportInfo* vi = &vInfo[vpid];
813    vi->vData[dataid].drawLine  = true;
814    vi->vData[dataid].lineColor = color;
815    vi->vData[dataid].lineWidth = width;
816    vi->vData[dataid].lineStyle = style;
817}
818
819void Plotter2::showLine(const int inVpid, const int inDataid) {
820    int vpid = inVpid;
821    if (vpid < 0) {
822        vpid = vInfo.size() - 1;
823    }
824    if (vpid < 0) {
825        exit(0);
826    }
827
828    int dataid = inDataid;
829    if (dataid < 0) {
830        dataid = vInfo[vpid].vData.size() - 1;
831    }
832    if (dataid < 0) {
833        exit(0);
834    }
835
836    Plotter2ViewportInfo* vi = &vInfo[vpid];
837    vi->vData[dataid].drawLine  = true;
838}
839
840void Plotter2::hideLine(const int inVpid, const int inDataid) {
841    int vpid = inVpid;
842    if (vpid < 0) {
843        vpid = vInfo.size() - 1;
844    }
845    if (vpid < 0) {
846        exit(0);
847    }
848
849    int dataid = inDataid;
850    if (dataid < 0) {
851        dataid = vInfo[vpid].vData.size() - 1;
852    }
853    if (dataid < 0) {
854        exit(0);
855    }
856
857    Plotter2ViewportInfo* vi = &vInfo[vpid];
858    vi->vData[dataid].drawLine  = false;
859}
860
861void Plotter2::setPoint(const int type, const float size, const int color, const int inVpid, const int inDataid) {
862    int vpid = inVpid;
863    if (vpid < 0) {
864        vpid = vInfo.size() - 1;
865    }
866    if (vpid < 0) {
867        Plotter2ViewportInfo vi;
868        vInfo.push_back(vi);
869        vpid = 0;
870    }
871
872    int dataid = inDataid;
873    if (dataid < 0) {
874        dataid = vInfo[vpid].vData.size() - 1;
875    }
876
877    Plotter2ViewportInfo* vi = &vInfo[vpid];
878    vi->vData[dataid].drawMarker  = true;
879    vi->vData[dataid].markerType  = type;
880    vi->vData[dataid].markerSize  = size;
881    vi->vData[dataid].markerColor = color;
882}
883
884void Plotter2::showPoint(const int inVpid, const int inDataid) {
885    int vpid = inVpid;
886    if (vpid < 0) {
887        vpid = vInfo.size() - 1;
888    }
889    if (vpid < 0) {
890        exit(0);
891    }
892
893    int dataid = inDataid;
894    if (dataid < 0) {
895        dataid = vInfo[vpid].vData.size() - 1;
896    }
897    if (dataid < 0) {
898        exit(0);
899    }
900
901    Plotter2ViewportInfo* vi = &vInfo[vpid];
902    vi->vData[dataid].drawMarker  = true;
903}
904
905void Plotter2::hidePoint(const int inVpid, const int inDataid) {
906    int vpid = inVpid;
907    if (vpid < 0) {
908        vpid = vInfo.size() - 1;
909    }
910    if (vpid < 0) {
911        exit(0);
912    }
913
914    int dataid = inDataid;
915    if (dataid < 0) {
916        dataid = vInfo[vpid].vData.size() - 1;
917    }
918    if (dataid < 0) {
919        exit(0);
920    }
921
922    Plotter2ViewportInfo* vi = &vInfo[vpid];
923    vi->vData[dataid].drawMarker  = false;
924}
925
926void Plotter2::setMaskX(const float xmin, const float xmax, const int color, const int fill, const int width, const float hsep, const int inVpid) {
927    int vpid = inVpid;
928    if (vpid < 0) {
929        vpid = vInfo.size() - 1;
930    }
931    if (vpid < 0) {
932        Plotter2ViewportInfo vi;
933        vInfo.push_back(vi);
934        vpid = 0;
935    }
936
937    Plotter2ViewportInfo* vi = &vInfo[vpid];
938
939    Plotter2RectInfo ri;
940    ri.xmin  = xmin;
941    ri.xmax  = xmax;
942    //y-range of xmask should be calculated in plot().
943    //std::vector<float> yrange = vi->getRangeY();
944    //float yexcess = 0.1*(yrange[1] - yrange[0]);
945    //ri.ymin  = yrange[0] - yexcess;
946    //ri.ymax  = yrange[1] + yexcess;
947    ri.color = color;
948    ri.fill  = fill;
949    ri.width = width;
950    ri.hsep  = hsep;
951
952    vi->vRect.push_back(ri);
953}
954
955void Plotter2::setLabelX(const std::string& label, const float inPosx, const float inPosy, const float size, const std::string& style, const int color, const int bgcolor, const int inVpid) {
956    int vpid = inVpid;
957    if (vpid < 0) {
958        vpid = vInfo.size() - 1;
959    }
960    if (vpid < 0) {
961        Plotter2ViewportInfo vi;
962        vInfo.push_back(vi);
963        vpid = 0;
964    }
965
966    Plotter2ViewportInfo* vi = &vInfo[vpid];
967
968    std::string styleString;
969    if (style == "") {
970      styleString = "";
971    } else if (style == "roman") {
972      styleString = "\\fr";
973    } else if (style == "italic") {
974      styleString = "\\fi";
975    } else if (style == "script") {
976      styleString = "\\fs";
977    }
978    vi->labelXString = styleString + label;
979
980    float posx = inPosx;
981    if (posx < 0.0) {
982        posx = 0.5*(vi->vpPosXMin + vi->vpPosXMax);
983    }
984    vi->labelXPosX   = posx;
985
986    float posy = inPosy;
987    if (posy < 0.0) {
988        posy = 0.35*vi->vpPosYMin;
989    }
990    vi->labelXPosY   = posy;
991
992    vi->labelXAngle  = 0.0;
993    vi->labelXFJust  = 0.5;
994    vi->labelXSize   = size;
995    vi->labelXColor  = color;
996    vi->labelXBColor = bgcolor;
997}
998
999void Plotter2::setLabelY(const std::string& label, const float inPosx, const float inPosy, const float size, const std::string& style, const int color, const int bgcolor, const int inVpid) {
1000    int vpid = inVpid;
1001    if (vpid < 0) {
1002        vpid = vInfo.size() - 1;
1003    }
1004    if (vpid < 0) {
1005        Plotter2ViewportInfo vi;
1006        vInfo.push_back(vi);
1007        vpid = 0;
1008    }
1009
1010    Plotter2ViewportInfo* vi = &vInfo[vpid];
1011
1012    std::string styleString;
1013    if (style == "") {
1014      styleString = "";
1015    } else if (style == "roman") {
1016      styleString = "\\fr";
1017    } else if (style == "italic") {
1018      styleString = "\\fi";
1019    } else if (style == "script") {
1020      styleString = "\\fs";
1021    }
1022    vi->labelYString = styleString + label;
1023
1024    float posx = inPosx;
1025    if (posx < 0.0) {
1026        posx = 0.35*vi->vpPosXMin;
1027    }
1028    vi->labelYPosX   = posx;
1029
1030    float posy = inPosy;
1031    if (posy < 0.0) {
1032        posy = 0.5*(vi->vpPosYMin + vi->vpPosYMax);
1033    }
1034    vi->labelYPosY   = posy;
1035
1036    vi->labelYAngle  = 90.0;
1037    vi->labelYFJust  = 0.5;
1038    vi->labelYSize   = size;
1039    vi->labelYColor  = color;
1040    vi->labelYBColor = bgcolor;
1041}
1042
1043void Plotter2::setTitle(const std::string& label, const float inPosx, const float inPosy, const float size, const std::string& style, const int color, const int bgcolor, const int inVpid) {
1044    int vpid = inVpid;
1045    if (vpid < 0) {
1046        vpid = vInfo.size() - 1;
1047    }
1048    if (vpid < 0) {
1049        Plotter2ViewportInfo vi;
1050        vInfo.push_back(vi);
1051        vpid = 0;
1052    }
1053
1054    Plotter2ViewportInfo* vi = &vInfo[vpid];
1055
1056    std::string styleString;
1057    if (style == "") {
1058      styleString = "";
1059    } else if (style == "roman") {
1060      styleString = "\\fr";
1061    } else if (style == "italic") {
1062      styleString = "\\fi";
1063    } else if (style == "script") {
1064      styleString = "\\fs";
1065    }
1066    vi->titleString = styleString + label;
1067
1068    float posx = inPosx;
1069    if (posx < 0.0) {
1070        posx = 0.5*(vi->vpPosXMin + vi->vpPosXMax);
1071    }
1072    vi->titlePosX   = posx;
1073
1074    float posy = inPosy;
1075    if (posy < 0.0) {
1076        posy = vi->vpPosYMax + 0.25*(1.0 - vi->vpPosYMax);
1077    }
1078    vi->titlePosY   = posy;
1079
1080    vi->titleAngle  = 0.0;
1081    vi->titleFJust  = 0.5;
1082    vi->titleSize   = size;
1083    vi->titleColor  = color;
1084    vi->titleBColor = bgcolor;
1085}
1086
1087void Plotter2::setViewportBackgroundColor(const int bgcolor, const int inVpid) {
1088    int vpid = inVpid;
1089    if (vpid < 0) {
1090        vpid = vInfo.size() - 1;
1091    }
1092    if (vpid < 0) {
1093        exit(0);
1094    }
1095
1096    Plotter2ViewportInfo* vi = &vInfo[vpid];
1097    vi->vpBColor = bgcolor;
1098}
1099
1100/*
1101void Plotter2::setAnnotation(const std::string& label, const float posx, const float posy, const float angle, const float fjust, const float size, const std::string& style, const int color, const int bgcolor, const int inVpid) {
1102    int vpid = inVpid;
1103    if (vpid < 0) {
1104        vpid = vInfo.size() - 1;
1105    }
1106    if (vpid < 0) {
1107        Plotter2ViewportInfo vi;
1108        vInfo.push_back(vi);
1109        vpid = 0;
1110    }
1111
1112    std::string styleString;
1113    if (style == "") {
1114      styleString = "";
1115    } else if (style == "roman") {
1116      styleString = "\\fr";
1117    } else if (style == "italic") {
1118      styleString = "\\fi";
1119    } else if (style == "script") {
1120      styleString = "\\fs";
1121    }
1122
1123    Plotter2ViewportInfo* vi = &vInfo[vpid];
1124    //vi->titleString = styleString + label;
1125    //vi->titlePosX   = posx;
1126    //vi->titlePosY   = posy;
1127    //vi->titleAngle  = angle;
1128    //vi->titleFJust  = fjust;
1129    //vi->titleSize   = size;
1130    //vi->titleColor  = color;
1131    //vi->titleBColor = bgcolor;
1132}
1133*/
1134
1135void Plotter2::close() {
1136    if (hasDevice) {
1137        cpgclos();
1138        hasDevice = false;
1139    }
1140}
1141
1142void Plotter2::plot() {
1143    open();
1144
1145    if ((width > 0.0) && (aspect > 0.0)) {
1146        cpgpap(width, aspect);
1147    }
1148
1149    cpgscr(0, 1.0, 1.0, 1.0); // set background color white
1150    cpgscr(1, 0.0, 0.0, 0.0); // set foreground color black
1151
1152    for (unsigned int i = 0; i < vInfo.size(); ++i) {
1153        Plotter2ViewportInfo vi = vInfo[i];
1154
1155        if (vi.showViewport) {
1156            cpgstbg(0); // reset background colour to the initial one (white)
1157            cpgsci(1);  // reset foreground colour to the initial one (black)
1158            cpgsls(1);  // reset line style to solid
1159            cpgslw(1);  // reset line width to 1
1160            cpgscf(1);  // reset font style to normal
1161            cpgsch(vi.fontSizeDef);// reset font size
1162            cpgsfs(1);  // reset fill style (solid)
1163
1164            // setup viewport
1165            cpgsvp(vi.vpPosXMin, vi.vpPosXMax, vi.vpPosYMin, vi.vpPosYMax);
1166            cpgswin(vi.vpRangeXMin, vi.vpRangeXMax, vi.vpRangeYMin, vi.vpRangeYMax);
1167
1168            // background color (default is transparent)
1169            if (vi.vpBColor >= 0) {
1170                cpgsci(vi.vpBColor);
1171                cpgrect(vi.vpRangeXMin, vi.vpRangeXMax, vi.vpRangeYMin, vi.vpRangeYMax);
1172                cpgsci(1);  // reset foreground colour to the initial one (black)
1173            }
1174
1175            // data
1176            for (unsigned int j = 0; j < vi.vData.size(); ++j) {
1177                cpgstbg(0); // reset background colour to the initial one (white)
1178                cpgsci(1);  // reset foreground colour to the initial one (black)
1179                cpgsls(1);  // reset line style to solid
1180                cpgslw(1);  // reset line width to 1
1181                cpgscf(1);  // reset font style to normal
1182                cpgsch(vi.fontSizeDef);// reset font size
1183
1184                Plotter2DataInfo di = vi.vData[j];
1185                std::vector<float> vxdata = di.xData;
1186                int ndata = vxdata.size();
1187                float* pxdata = new float[ndata];
1188                float* pydata = new float[ndata];
1189                for (int k = 0; k < ndata; ++k) {
1190                    pxdata[k] = di.xData[k];
1191                    pydata[k] = di.yData[k];
1192                }
1193
1194                if (di.drawLine) {
1195                    cpgsls(di.lineStyle);
1196                    cpgslw(di.lineWidth);
1197                    int colorIdx = di.lineColor;
1198                    if (colorIdx < 0) {
1199                        colorIdx = (j + 1) % 15 + 1;
1200                    }
1201                    cpgsci(colorIdx);
1202                    cpgline(ndata, pxdata, pydata);
1203                }
1204
1205                if (di.drawMarker) {
1206                    cpgsch(di.markerSize);
1207                    cpgsci(di.markerColor);
1208                    cpgpt(ndata, pxdata, pydata, di.markerType);
1209                }
1210
1211                delete [] pxdata;
1212                delete [] pydata;
1213            }
1214
1215            //calculate y-range of xmasks
1216            std::vector<float> yrange = vi.getRangeY();
1217            float yexcess = 0.1*(yrange[1] - yrange[0]);
1218            float xmaskymin = yrange[0] - yexcess;
1219            float xmaskymax = yrange[1] + yexcess;
1220
1221            // masks
1222            for (unsigned int j = 0; j < vi.vRect.size(); ++j) {
1223                cpgstbg(0); // reset background colour to the initial one (white)
1224                cpgsci(1);  // reset foreground colour to the initial one (black)
1225                cpgsls(1);  // reset line style to solid
1226                cpgslw(1);  // reset line width to 1
1227                cpgscf(1);  // reset font style to normal
1228                cpgsch(vi.fontSizeDef);// reset font size
1229                cpgsfs(1);  // reset fill style (solid)
1230
1231                Plotter2RectInfo ri = vi.vRect[j];
1232                cpgsci(ri.color);
1233                cpgsfs(ri.fill);
1234                cpgslw(ri.width);
1235                cpgshs(45.0, ri.hsep, 0.0);
1236                float* mxdata = new float[4];
1237                float* mydata = new float[4];
1238                mxdata[0] = ri.xmin;
1239                mxdata[1] = ri.xmax;
1240                mxdata[2] = ri.xmax;
1241                mxdata[3] = ri.xmin;
1242                mydata[0] = xmaskymin;
1243                mydata[1] = xmaskymin;
1244                mydata[2] = xmaskymax;
1245                mydata[3] = xmaskymax;
1246                cpgpoly(4, mxdata, mydata);
1247            }
1248
1249            cpgstbg(0); // reset background colour to the initial one (white)
1250            cpgsci(1);  // reset foreground colour to the initial one (black)
1251            cpgsls(1);  // reset line style to solid
1252            cpgslw(1);  // reset line width to 1
1253            cpgscf(1);  // reset font style to normal
1254            cpgsch(vi.fontSizeDef);// reset font size
1255            cpgsfs(1);  // reset fill style (solid)
1256
1257            cpgbox("BCTS",  vi.majorTickIntervalX, vi.nMinorTickWithinMajorTicksX,
1258                   "BCTSV", vi.majorTickIntervalY, vi.nMinorTickWithinMajorTicksY);
1259
1260            // viewport outline, ticks and number labels
1261            std::string numformatx, numformaty;
1262            if (vi.numLocationX == "b") {
1263                numformatx = "N";
1264            } else if (vi.numLocationX == "t") {
1265                numformatx = "M";
1266            } else if (vi.numLocationX == "") {
1267                numformatx = "";
1268            }
1269            if (vi.numLocationY == "l") {
1270                numformaty = "NV";
1271            } else if (vi.numLocationY == "r") {
1272                numformaty = "MV";
1273            } else if (vi.numLocationY == "") {
1274                numformaty = "";
1275            }
1276
1277            cpgbox(numformatx.c_str(), vi.majorTickIntervalX * vi.nMajorTickWithinTickNumsX, 0,
1278                   numformaty.c_str(), vi.majorTickIntervalY * vi.nMajorTickWithinTickNumsY, 0);
1279
1280            float xpos, ypos;
1281
1282            // x-label
1283            vi.getWorldCoordByWindowCoord(vi.labelXPosX, vi.labelXPosY, &xpos, &ypos);
1284            cpgsch(vi.labelXSize);
1285            cpgsci(vi.labelXColor);
1286            cpgstbg(vi.labelXBColor); //outside viewports, works ONLY with /xwindow
1287            cpgptxt(xpos, ypos, vi.labelXAngle, vi.labelXFJust, vi.labelXString.c_str());
1288
1289            // y-label
1290            vi.getWorldCoordByWindowCoord(vi.labelYPosX, vi.labelYPosY, &xpos, &ypos);
1291            cpgsch(vi.labelYSize);
1292            cpgsci(vi.labelYColor);
1293            cpgstbg(vi.labelYBColor); //outside viewports, works ONLY with /xwindow
1294            cpgptxt(xpos, ypos, vi.labelYAngle, vi.labelYFJust, vi.labelYString.c_str());
1295
1296            // title
1297            vi.getWorldCoordByWindowCoord(vi.titlePosX, vi.titlePosY, &xpos, &ypos);
1298            cpgsch(vi.titleSize);
1299            cpgsci(vi.titleColor);
1300            cpgstbg(vi.titleBColor); //outside viewports, works ONLY with /xwindow
1301            cpgptxt(xpos, ypos, vi.titleAngle, vi.titleFJust, vi.titleString.c_str());
1302        }
1303
1304    }
1305
1306    close();
1307}
1308
1309} // namespace asap
Note: See TracBrowser for help on using the repository browser.