source: trunk/src/Plotter2.cpp @ 2896

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

New Development: Yes

JIRA Issue: Yes CAS-6216/6217

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: added new methods in sd.plotter2

Test Programs:

Put in Release Notes:

Module(s): sd

Description: arrows and annotation texts become available in sd.plotter2.


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