source: trunk/src/Plotter2.cpp @ 2861

Last change on this file since 2861 was 2861, checked in by WataruKawasaki, 11 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs:

Put in Release Notes: Yes

Module(s): sd

Description: (1) bugfix in setting masks

(2) finished implementation of get_vinfo()
(3) change get_*index() to class methods
(4) modify get_*index() to raise exception when invalid value given


File size: 35.2 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
298Plotter2::~Plotter2() {
299    close();
300    vInfo.clear();
301}
302
303std::string Plotter2::getFileName() {
304    return filename;
305}
306
307void Plotter2::setFileName(const std::string& inFilename) {
308    filename = inFilename;
309}
310
311std::string Plotter2::getDevice() {
312    return device;
313}
314
315void Plotter2::setDevice(const std::string& inDevice) {
316    device = inDevice;
317}
318
319void Plotter2::open() {
320    cpgopen((filename + "/" + device).c_str());
321    hasDevice = true;
322}
323
324int Plotter2::addViewport(const float xmin, const float xmax, const float ymin, const float ymax) {
325    Plotter2ViewportInfo vi;
326
327    vi.vpPosXMin = xmin;
328    vi.vpPosXMax = xmax;
329    vi.vpPosYMin = ymin;
330    vi.vpPosYMax = ymax;
331
332    vInfo.push_back(vi);
333    currentViewportId = vInfo.size() - 1;
334
335    return currentViewportId;
336}
337
338void Plotter2::setViewport(const float xmin, const float xmax, const float ymin, const float ymax, const int id) {
339    Plotter2ViewportInfo* vi = &vInfo[id];
340
341    vi->vpPosXMin = xmin;
342    vi->vpPosXMax = xmax;
343    vi->vpPosYMin = ymin;
344    vi->vpPosYMax = ymax;
345
346    hasDefaultViewport = false;
347}
348
349void Plotter2::showViewport(const int inVpid) {
350    int vpid = inVpid;
351    if (vpid < 0) {
352        vpid = vInfo.size() - 1;
353    }
354    if (vpid < 0) {
355        exit(0);
356    }
357
358    Plotter2ViewportInfo* vi = &vInfo[vpid];
359    vi->showViewport = true;
360}
361
362void Plotter2::hideViewport(const int inVpid) {
363    int vpid = inVpid;
364    if (vpid < 0) {
365        vpid = vInfo.size() - 1;
366    }
367    if (vpid < 0) {
368        exit(0);
369    }
370
371    Plotter2ViewportInfo* vi = &vInfo[vpid];
372    vi->showViewport = false;
373}
374
375bool Plotter2::getHasDefaultViewport() {
376    return hasDefaultViewport;
377}
378
379int Plotter2::getCurrentViewportId() {
380    return currentViewportId;
381}
382
383void Plotter2::getViewInfo() {
384    std::string colorNames[16] = {"white", "black", "red", "green",
385                                  "blue", "cyan", "magenta", "yellow",
386                                  "orange", "yellowgreen", "emerald", "skyblue",
387                                  "purple", "pink", "gray", "lightgray"};
388    std::string lstyleNames[6] = {"", "solid", "dashed", "dash-dotted", "dotted", "dash-dot-dot-dotted"};
389    std::string fstyleNames[5] = {"", "solid", "outline", "hatched", "crosshatched"};
390
391    for (unsigned int i = 0; i < vInfo.size(); ++i) {
392        std::cout << "Viewport [ID = " << i << "] (" << (i+1) << "/" << vInfo.size() << ") ";
393        std::cout << "=============================================================" << std::endl;
394
395        std::cout << "  Visible: " << (vInfo[i].showViewport ? "Yes" : "No") << std::endl;
396
397        std::cout << "  Position in Window Coordinate: ";
398        std::cout << "X(left=" << vInfo[i].vpPosXMin << ",right=" << vInfo[i].vpPosXMax << "), ";
399        std::cout << "Y(bottom=" << vInfo[i].vpPosYMin << ",top=" << vInfo[i].vpPosYMax << ")" << std::endl;
400
401        std::cout << "  Display Range: ";
402        std::cout << "X(" << (vInfo[i].isAutoRangeX ? "automatic" : "manual") << ", ";
403        std::cout << "min=" << vInfo[i].vpRangeXMin << ", max=" << vInfo[i].vpRangeXMax << "), ";
404        std::cout << "Y(" << (vInfo[i].isAutoRangeY ? "automatic" : "manual") << ", ";
405        std::cout << "min=" << vInfo[i].vpRangeYMin << ", max=" << vInfo[i].vpRangeYMax << ")" << std::endl;
406
407        std::cout << "  Numbering/Ticks:" << std::endl;
408        std::cout << "    X(" << ((vInfo[i].numLocationX == "b") ? "bottom" : ((vInfo[i].numLocationX == "t") ? "top" : (vInfo[i].numLocationX + " [*INVAILD*]"))) << ", interval[" << (vInfo[i].isAutoTickIntervalX ? "automatic" : "manual") << ", ";
409        std::cout << "numbering=" << (vInfo[i].majorTickIntervalX * vInfo[i].nMajorTickWithinTickNumsX) << ", ";
410        std::cout << "majortick=" << vInfo[i].majorTickIntervalX << ", ";
411        std::cout << "minortick=" << (vInfo[i].majorTickIntervalX / vInfo[i].nMinorTickWithinMajorTicksX) << "])" << std::endl;
412        std::cout << "    Y(" << ((vInfo[i].numLocationY == "l") ? "left" : ((vInfo[i].numLocationY == "r") ? "right" : (vInfo[i].numLocationY + " [*INVAILD*]"))) << ", interval[" << (vInfo[i].isAutoTickIntervalY ? "automatic" : "manual") << ", ";
413        std::cout << "numbering=" << (vInfo[i].majorTickIntervalY * vInfo[i].nMajorTickWithinTickNumsY) << ", ";
414        std::cout << "majortick=" << vInfo[i].majorTickIntervalY << ", ";
415        std::cout << "minortick=" << (vInfo[i].majorTickIntervalY / vInfo[i].nMinorTickWithinMajorTicksY) << "])" << std::endl;
416
417        std::cout << "  X Label: ";
418        if (vInfo[i].labelXString != "") {
419            std::cout << "\"" << vInfo[i].labelXString << "\"" << std::endl;
420            std::cout << "    position=(" << vInfo[i].labelXPosX << "," << vInfo[i].labelXPosY << "), ";
421            std::cout << "justification=" << vInfo[i].labelXFJust << ", ";
422            std::cout << "angle=" << vInfo[i].labelXAngle << "deg, ";
423            std::cout << "fontsize=" << vInfo[i].labelXSize << std::endl;
424        } else {
425            std::cout << "No" << std::endl;
426        }
427
428        std::cout << "  Y Label: ";
429        if (vInfo[i].labelYString != "") {
430            std::cout << "\"" << vInfo[i].labelYString << "\"" << std::endl;
431            std::cout << "    position=(" << vInfo[i].labelYPosX << "," << vInfo[i].labelYPosY << "), ";
432            std::cout << "justification=" << vInfo[i].labelYFJust << ", ";
433            std::cout << "angle=" << vInfo[i].labelYAngle << "deg, ";
434            std::cout << "fontsize=" << vInfo[i].labelYSize << std::endl;
435        } else {
436            std::cout << "No" << std::endl;
437        }
438
439        std::cout << "  Title: ";
440        if (vInfo[i].titleString != "") {
441            std::cout << "\"" << vInfo[i].titleString << "\"" << std::endl;
442            std::cout << "    position=(" << vInfo[i].titlePosX << "," << vInfo[i].titlePosY << "), ";
443            std::cout << "justification=" << vInfo[i].titleFJust << ", ";
444            std::cout << "angle=" << vInfo[i].titleAngle << "deg, ";
445            std::cout << "fontsize=" << vInfo[i].titleSize << std::endl;
446        } else {
447            std::cout << "No" << std::endl;
448        }
449
450        std::cout << "  Background Color = ";
451        if (vInfo[i].vpBColor < 0) {
452            std::cout << "transparent" << std::endl;
453        } else if (vInfo[i].vpBColor < 16) {
454            std::cout << colorNames[vInfo[i].vpBColor] << std::endl;
455        } else {
456            std::cout << "index:" << vInfo[i].vpBColor << " [INVAILD VALUE!]" << std::endl;
457        }
458
459        for (unsigned int j = 0; j < vInfo[i].vData.size(); ++j) {
460            std::cout << "  Dataset [ID = " << j << "] (" << (j+1) << "/" << vInfo[i].vData.size() << ") ";
461            std::cout << "----------------------------------------------" << std::endl;
462
463            bool showDataset = (vInfo[i].vData[j].drawLine || vInfo[i].vData[j].drawMarker);
464            bool showViewport = vInfo[i].showViewport;
465            std::cout << "    Visible: " << (showViewport ? "" : "(");
466            std::cout << (showDataset ? "Yes" : "No") << (showViewport ? "" : ")") << std::endl;
467            std::cout << "    Number of Data Points: " << vInfo[i].vData[j].xData.size() << std::endl;
468            if (vInfo[i].vData[j].drawLine) {
469                std::cout << "    Line: color=";
470                if (vInfo[i].vData[j].lineColor < 0) {
471                  int defaultColorIdx = (j + 1) % 15 + 1;
472                    std::cout << "default(" << colorNames[defaultColorIdx] << ")";
473                } else if (vInfo[i].vData[j].lineColor < 16) {
474                    std::cout << colorNames[vInfo[i].vData[j].lineColor];
475                } else {
476                    std::cout << "index:" << vInfo[i].vData[j].lineColor << " [*INVAILD*]";
477                }
478                std::cout << ", width=" << vInfo[i].vData[j].lineWidth;
479                std::cout << ", style=" << lstyleNames[vInfo[i].vData[j].lineStyle] << std::endl;
480            }
481            if (vInfo[i].vData[j].drawMarker) {
482                std::cout << "    Marker: color=";
483                if (vInfo[i].vData[j].markerColor < 0) {
484                    std::cout << "default";
485                } else if (vInfo[i].vData[j].markerColor < 16) {
486                    std::cout << colorNames[vInfo[i].vData[j].markerColor];
487                } else {
488                    std::cout << "index:" << vInfo[i].vData[j].markerColor << " [*INVAILD*]";
489                }
490                std::cout << ", shape=" << vInfo[i].vData[j].markerType;
491                std::cout << ", size=" << vInfo[i].vData[j].markerSize << std::endl;
492            }
493
494        }
495
496        for (unsigned int j = 0; j < vInfo[i].vRect.size(); ++j) {
497            std::cout << "  XMask [ID = " << j << "] (" << (j+1) << "/" << vInfo[i].vRect.size() << ") ";
498            std::cout << "----------------------------------------------" << std::endl;
499            std::cout << "    Range: (min=" << vInfo[i].vRect[j].xmin << ", max=" << vInfo[i].vRect[j].xmax << ")" << std::endl;
500            std::cout << "    Attributes: (color=" << colorNames[vInfo[i].vRect[j].color];
501            std::string fstyle = fstyleNames[vInfo[i].vRect[j].fill];
502            std::cout << ", fillstyle=" << fstyle;
503            if (fstyle == "outline") {
504                std::cout << ", outlinewidth=" << vInfo[i].vRect[j].width;
505            }
506            if ((fstyle == "hatched")||(fstyle == "crosshatched")) {
507                std::cout << ", hatchspacing=" << vInfo[i].vRect[j].hsep;
508            }
509            std::cout << ")" << std::endl;
510        }
511    }
512    std::cout << "=====================================================================================" << std::endl << std::flush;
513}
514
515void Plotter2::setRange(const float xmin, const float xmax, const float ymin, const float ymax, const int inVpid) {
516    setRangeX(xmin, xmax, inVpid);
517    setRangeY(ymin, ymax, inVpid);
518}
519
520void Plotter2::setRangeX(const float xmin, const float xmax, const int inVpid) {
521    int vpid = inVpid;
522    if (vpid < 0) {
523        vpid = vInfo.size() - 1;
524    }
525    if (vpid < 0) {
526        Plotter2ViewportInfo vi;
527        vInfo.push_back(vi);
528        vpid = 0;
529    }
530
531    Plotter2ViewportInfo* vi = &vInfo[vpid];
532    vi->vpRangeXMin = xmin;
533    vi->vpRangeXMax = xmax;
534    vi->isAutoRangeX = false;
535}
536
537void Plotter2::setRangeY(const float ymin, const float ymax, const int inVpid) {
538    int vpid = inVpid;
539    if (vpid < 0) {
540        vpid = vInfo.size() - 1;
541    }
542    if (vpid < 0) {
543        Plotter2ViewportInfo vi;
544        vInfo.push_back(vi);
545        vpid = 0;
546    }
547
548    Plotter2ViewportInfo* vi = &vInfo[vpid];
549    vi->vpRangeYMin = ymin;
550    vi->vpRangeYMax = ymax;
551    vi->isAutoRangeY = false;
552}
553
554std::vector<float> Plotter2::getRangeX(const int inVpid) {
555    int vpid = inVpid;
556    if (vpid < 0) {
557        vpid = vInfo.size() - 1;
558    }
559    if (vpid < 0) {
560        exit(0);
561    }
562
563    return vInfo[vpid].getRangeX();
564}
565
566std::vector<float> Plotter2::getRangeY(const int inVpid) {
567    int vpid = inVpid;
568    if (vpid < 0) {
569        vpid = vInfo.size() - 1;
570    }
571    if (vpid < 0) {
572        exit(0);
573    }
574
575    return vInfo[vpid].getRangeY();
576}
577
578void Plotter2::setAutoRange(const int inVpid) {
579    setAutoRangeX(inVpid);
580    setAutoRangeY(inVpid);
581}
582
583void Plotter2::setAutoRangeX(const int inVpid) {
584    int vpid = inVpid;
585    if (vpid < 0) {
586        vpid = vInfo.size() - 1;
587    }
588    if (vpid < 0) {
589        Plotter2ViewportInfo vi;
590        vInfo.push_back(vi);
591        vpid = 0;
592    }
593
594    Plotter2ViewportInfo* vi = &vInfo[vpid];
595    vi->isAutoRangeX = true;
596}
597
598void Plotter2::setAutoRangeY(const int inVpid) {
599    int vpid = inVpid;
600    if (vpid < 0) {
601        vpid = vInfo.size() - 1;
602    }
603    if (vpid < 0) {
604        Plotter2ViewportInfo vi;
605        vInfo.push_back(vi);
606        vpid = 0;
607    }
608
609    Plotter2ViewportInfo* vi = &vInfo[vpid];
610    vi->isAutoRangeY = true;
611}
612
613void Plotter2::setFontSizeDef(const float size, const int inVpid) {
614    int vpid = inVpid;
615    if (vpid < 0) {
616        vpid = vInfo.size() - 1;
617    }
618    if (vpid < 0) {
619        Plotter2ViewportInfo vi;
620        vInfo.push_back(vi);
621        vpid = 0;
622    }
623
624    Plotter2ViewportInfo* vi = &vInfo[vpid];
625    vi->fontSizeDef = size;
626}
627
628void Plotter2::setTicksX(const float interval, const int num, const int inVpid) {
629    int vpid = inVpid;
630    if (vpid < 0) {
631        vpid = vInfo.size() - 1;
632    }
633    if (vpid < 0) {
634        Plotter2ViewportInfo vi;
635        vInfo.push_back(vi);
636        vpid = 0;
637    }
638
639    Plotter2ViewportInfo* vi = &vInfo[vpid];
640    vi->majorTickIntervalX = interval;
641    vi->nMinorTickWithinMajorTicksX = num;
642    vi->isAutoTickIntervalX = false;
643}
644
645void Plotter2::setTicksY(const float interval, const int num, const int inVpid) {
646    int vpid = inVpid;
647    if (vpid < 0) {
648        vpid = vInfo.size() - 1;
649    }
650    if (vpid < 0) {
651        Plotter2ViewportInfo vi;
652        vInfo.push_back(vi);
653        vpid = 0;
654    }
655
656    Plotter2ViewportInfo* vi = &vInfo[vpid];
657    vi->majorTickIntervalY = interval;
658    vi->nMinorTickWithinMajorTicksY = num;
659    vi->isAutoTickIntervalY = false;
660}
661
662void Plotter2::setAutoTicks(const int inVpid) {
663    setAutoTicksX(inVpid);
664    setAutoTicksY(inVpid);
665}
666
667void Plotter2::setAutoTicksX(const int inVpid) {
668    int vpid = inVpid;
669    if (vpid < 0) {
670        vpid = vInfo.size() - 1;
671    }
672    if (vpid < 0) {
673        Plotter2ViewportInfo vi;
674        vInfo.push_back(vi);
675        vpid = 0;
676    }
677
678    Plotter2ViewportInfo* vi = &vInfo[vpid];
679    vi->isAutoTickIntervalX = true;
680}
681
682void Plotter2::setAutoTicksY(const int inVpid) {
683    int vpid = inVpid;
684    if (vpid < 0) {
685        vpid = vInfo.size() - 1;
686    }
687    if (vpid < 0) {
688        Plotter2ViewportInfo vi;
689        vInfo.push_back(vi);
690        vpid = 0;
691    }
692
693    Plotter2ViewportInfo* vi = &vInfo[vpid];
694    vi->isAutoTickIntervalY = true;
695}
696
697void Plotter2::setNumIntervalX(const float interval, const int inVpid) {
698    int vpid = inVpid;
699    if (vpid < 0) {
700        vpid = vInfo.size() - 1;
701    }
702    if (vpid < 0) {
703        Plotter2ViewportInfo vi;
704        vInfo.push_back(vi);
705        vpid = 0;
706    }
707
708    Plotter2ViewportInfo* vi = &vInfo[vpid];
709    vi->nMajorTickWithinTickNumsX = (int)(interval / vi->majorTickIntervalX);
710}
711
712void Plotter2::setNumIntervalY(const float interval, const int inVpid) {
713    int vpid = inVpid;
714    if (vpid < 0) {
715        vpid = vInfo.size() - 1;
716    }
717    if (vpid < 0) {
718        Plotter2ViewportInfo vi;
719        vInfo.push_back(vi);
720        vpid = 0;
721    }
722
723    Plotter2ViewportInfo* vi = &vInfo[vpid];
724    vi->nMajorTickWithinTickNumsY = (int)(interval / vi->majorTickIntervalY);
725}
726
727void Plotter2::setNumLocationX(const std::string& side, const int inVpid) {
728    int vpid = inVpid;
729    if (vpid < 0) {
730        vpid = vInfo.size() - 1;
731    }
732    if (vpid < 0) {
733        Plotter2ViewportInfo vi;
734        vInfo.push_back(vi);
735        vpid = 0;
736    }
737
738    Plotter2ViewportInfo* vi = &vInfo[vpid];
739    vi->numLocationX = side;
740}
741
742void Plotter2::setNumLocationY(const std::string& side, const int inVpid) {
743    int vpid = inVpid;
744    if (vpid < 0) {
745        vpid = vInfo.size() - 1;
746    }
747    if (vpid < 0) {
748        Plotter2ViewportInfo vi;
749        vInfo.push_back(vi);
750        vpid = 0;
751    }
752
753    Plotter2ViewportInfo* vi = &vInfo[vpid];
754    vi->numLocationY = side;
755}
756
757void Plotter2::setData(const std::vector<float>& xdata, const std::vector<float>& ydata, const int inVpid, const int inDataid) {
758    int vpid = inVpid;
759    if (vpid < 0) {
760        vpid = vInfo.size() - 1;
761    }
762    if (vpid < 0) {
763        Plotter2ViewportInfo vi;
764        vInfo.push_back(vi);
765        vpid = 0;
766    }
767
768    Plotter2ViewportInfo* vi = &vInfo[vpid];
769
770    int dataid = inDataid;
771    if (dataid < 0) {
772        Plotter2DataInfo di;
773        vi->vData.push_back(di);
774        dataid = vi->vData.size() - 1;
775    }
776
777    vi->setData(xdata, ydata, dataid);
778}
779
780void Plotter2::setLine(const int color, const int width, const int style, const int inVpid, const int inDataid) {
781    int vpid = inVpid;
782    if (vpid < 0) {
783        vpid = vInfo.size() - 1;
784    }
785    if (vpid < 0) {
786        Plotter2ViewportInfo vi;
787        vInfo.push_back(vi);
788        vpid = 0;
789    }
790
791    int dataid = inDataid;
792    if (dataid < 0) {
793        dataid = vInfo[vpid].vData.size() - 1;
794    }
795
796    Plotter2ViewportInfo* vi = &vInfo[vpid];
797    vi->vData[dataid].drawLine  = true;
798    vi->vData[dataid].lineColor = color;
799    vi->vData[dataid].lineWidth = width;
800    vi->vData[dataid].lineStyle = style;
801}
802
803void Plotter2::showLine(const int inVpid, const int inDataid) {
804    int vpid = inVpid;
805    if (vpid < 0) {
806        vpid = vInfo.size() - 1;
807    }
808    if (vpid < 0) {
809        exit(0);
810    }
811
812    int dataid = inDataid;
813    if (dataid < 0) {
814        dataid = vInfo[vpid].vData.size() - 1;
815    }
816    if (dataid < 0) {
817        exit(0);
818    }
819
820    Plotter2ViewportInfo* vi = &vInfo[vpid];
821    vi->vData[dataid].drawLine  = true;
822}
823
824void Plotter2::hideLine(const int inVpid, const int inDataid) {
825    int vpid = inVpid;
826    if (vpid < 0) {
827        vpid = vInfo.size() - 1;
828    }
829    if (vpid < 0) {
830        exit(0);
831    }
832
833    int dataid = inDataid;
834    if (dataid < 0) {
835        dataid = vInfo[vpid].vData.size() - 1;
836    }
837    if (dataid < 0) {
838        exit(0);
839    }
840
841    Plotter2ViewportInfo* vi = &vInfo[vpid];
842    vi->vData[dataid].drawLine  = false;
843}
844
845void Plotter2::setPoint(const int type, const float size, const int color, const int inVpid, const int inDataid) {
846    int vpid = inVpid;
847    if (vpid < 0) {
848        vpid = vInfo.size() - 1;
849    }
850    if (vpid < 0) {
851        Plotter2ViewportInfo vi;
852        vInfo.push_back(vi);
853        vpid = 0;
854    }
855
856    int dataid = inDataid;
857    if (dataid < 0) {
858        dataid = vInfo[vpid].vData.size() - 1;
859    }
860
861    Plotter2ViewportInfo* vi = &vInfo[vpid];
862    vi->vData[dataid].drawMarker  = true;
863    vi->vData[dataid].markerType  = type;
864    vi->vData[dataid].markerSize  = size;
865    vi->vData[dataid].markerColor = color;
866}
867
868void Plotter2::showPoint(const int inVpid, const int inDataid) {
869    int vpid = inVpid;
870    if (vpid < 0) {
871        vpid = vInfo.size() - 1;
872    }
873    if (vpid < 0) {
874        exit(0);
875    }
876
877    int dataid = inDataid;
878    if (dataid < 0) {
879        dataid = vInfo[vpid].vData.size() - 1;
880    }
881    if (dataid < 0) {
882        exit(0);
883    }
884
885    Plotter2ViewportInfo* vi = &vInfo[vpid];
886    vi->vData[dataid].drawMarker  = true;
887}
888
889void Plotter2::hidePoint(const int inVpid, const int inDataid) {
890    int vpid = inVpid;
891    if (vpid < 0) {
892        vpid = vInfo.size() - 1;
893    }
894    if (vpid < 0) {
895        exit(0);
896    }
897
898    int dataid = inDataid;
899    if (dataid < 0) {
900        dataid = vInfo[vpid].vData.size() - 1;
901    }
902    if (dataid < 0) {
903        exit(0);
904    }
905
906    Plotter2ViewportInfo* vi = &vInfo[vpid];
907    vi->vData[dataid].drawMarker  = false;
908}
909
910void Plotter2::setMaskX(const float xmin, const float xmax, const int color, const int fill, const int width, const float hsep, const int inVpid) {
911    int vpid = inVpid;
912    if (vpid < 0) {
913        vpid = vInfo.size() - 1;
914    }
915    if (vpid < 0) {
916        Plotter2ViewportInfo vi;
917        vInfo.push_back(vi);
918        vpid = 0;
919    }
920
921    Plotter2ViewportInfo* vi = &vInfo[vpid];
922
923    Plotter2RectInfo ri;
924    ri.xmin  = xmin;
925    ri.xmax  = xmax;
926    //y-range of xmask should be calculated in plot().
927    //std::vector<float> yrange = vi->getRangeY();
928    //float yexcess = 0.1*(yrange[1] - yrange[0]);
929    //ri.ymin  = yrange[0] - yexcess;
930    //ri.ymax  = yrange[1] + yexcess;
931    ri.color = color;
932    ri.fill  = fill;
933    ri.width = width;
934    ri.hsep  = hsep;
935
936    vi->vRect.push_back(ri);
937}
938
939void 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) {
940    int vpid = inVpid;
941    if (vpid < 0) {
942        vpid = vInfo.size() - 1;
943    }
944    if (vpid < 0) {
945        Plotter2ViewportInfo vi;
946        vInfo.push_back(vi);
947        vpid = 0;
948    }
949
950    Plotter2ViewportInfo* vi = &vInfo[vpid];
951
952    std::string styleString;
953    if (style == "") {
954      styleString = "";
955    } else if (style == "roman") {
956      styleString = "\\fr";
957    } else if (style == "italic") {
958      styleString = "\\fi";
959    } else if (style == "script") {
960      styleString = "\\fs";
961    }
962    vi->labelXString = styleString + label;
963
964    float posx = inPosx;
965    if (posx < 0.0) {
966        posx = 0.5*(vi->vpPosXMin + vi->vpPosXMax);
967    }
968    vi->labelXPosX   = posx;
969
970    float posy = inPosy;
971    if (posy < 0.0) {
972        posy = 0.35*vi->vpPosYMin;
973    }
974    vi->labelXPosY   = posy;
975
976    vi->labelXAngle  = 0.0;
977    vi->labelXFJust  = 0.5;
978    vi->labelXSize   = size;
979    vi->labelXColor  = color;
980    vi->labelXBColor = bgcolor;
981}
982
983void 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) {
984    int vpid = inVpid;
985    if (vpid < 0) {
986        vpid = vInfo.size() - 1;
987    }
988    if (vpid < 0) {
989        Plotter2ViewportInfo vi;
990        vInfo.push_back(vi);
991        vpid = 0;
992    }
993
994    Plotter2ViewportInfo* vi = &vInfo[vpid];
995
996    std::string styleString;
997    if (style == "") {
998      styleString = "";
999    } else if (style == "roman") {
1000      styleString = "\\fr";
1001    } else if (style == "italic") {
1002      styleString = "\\fi";
1003    } else if (style == "script") {
1004      styleString = "\\fs";
1005    }
1006    vi->labelYString = styleString + label;
1007
1008    float posx = inPosx;
1009    if (posx < 0.0) {
1010        posx = 0.35*vi->vpPosXMin;
1011    }
1012    vi->labelYPosX   = posx;
1013
1014    float posy = inPosy;
1015    if (posy < 0.0) {
1016        posy = 0.5*(vi->vpPosYMin + vi->vpPosYMax);
1017    }
1018    vi->labelYPosY   = posy;
1019
1020    vi->labelYAngle  = 90.0;
1021    vi->labelYFJust  = 0.5;
1022    vi->labelYSize   = size;
1023    vi->labelYColor  = color;
1024    vi->labelYBColor = bgcolor;
1025}
1026
1027void 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) {
1028    int vpid = inVpid;
1029    if (vpid < 0) {
1030        vpid = vInfo.size() - 1;
1031    }
1032    if (vpid < 0) {
1033        Plotter2ViewportInfo vi;
1034        vInfo.push_back(vi);
1035        vpid = 0;
1036    }
1037
1038    Plotter2ViewportInfo* vi = &vInfo[vpid];
1039
1040    std::string styleString;
1041    if (style == "") {
1042      styleString = "";
1043    } else if (style == "roman") {
1044      styleString = "\\fr";
1045    } else if (style == "italic") {
1046      styleString = "\\fi";
1047    } else if (style == "script") {
1048      styleString = "\\fs";
1049    }
1050    vi->titleString = styleString + label;
1051
1052    float posx = inPosx;
1053    if (posx < 0.0) {
1054        posx = 0.5*(vi->vpPosXMin + vi->vpPosXMax);
1055    }
1056    vi->titlePosX   = posx;
1057
1058    float posy = inPosy;
1059    if (posy < 0.0) {
1060        posy = vi->vpPosYMax + 0.25*(1.0 - vi->vpPosYMax);
1061    }
1062    vi->titlePosY   = posy;
1063
1064    vi->titleAngle  = 0.0;
1065    vi->titleFJust  = 0.5;
1066    vi->titleSize   = size;
1067    vi->titleColor  = color;
1068    vi->titleBColor = bgcolor;
1069}
1070
1071void Plotter2::setViewportBackgroundColor(const int bgcolor, const int inVpid) {
1072    int vpid = inVpid;
1073    if (vpid < 0) {
1074        vpid = vInfo.size() - 1;
1075    }
1076    if (vpid < 0) {
1077        exit(0);
1078    }
1079
1080    Plotter2ViewportInfo* vi = &vInfo[vpid];
1081    vi->vpBColor = bgcolor;
1082}
1083
1084/*
1085void 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) {
1086    int vpid = inVpid;
1087    if (vpid < 0) {
1088        vpid = vInfo.size() - 1;
1089    }
1090    if (vpid < 0) {
1091        Plotter2ViewportInfo vi;
1092        vInfo.push_back(vi);
1093        vpid = 0;
1094    }
1095
1096    std::string styleString;
1097    if (style == "") {
1098      styleString = "";
1099    } else if (style == "roman") {
1100      styleString = "\\fr";
1101    } else if (style == "italic") {
1102      styleString = "\\fi";
1103    } else if (style == "script") {
1104      styleString = "\\fs";
1105    }
1106
1107    Plotter2ViewportInfo* vi = &vInfo[vpid];
1108    //vi->titleString = styleString + label;
1109    //vi->titlePosX   = posx;
1110    //vi->titlePosY   = posy;
1111    //vi->titleAngle  = angle;
1112    //vi->titleFJust  = fjust;
1113    //vi->titleSize   = size;
1114    //vi->titleColor  = color;
1115    //vi->titleBColor = bgcolor;
1116}
1117*/
1118
1119void Plotter2::close() {
1120    if (hasDevice) {
1121        cpgclos();
1122        hasDevice = false;
1123    }
1124}
1125
1126void Plotter2::plot() {
1127    open();
1128
1129    cpgscr(0, 1.0, 1.0, 1.0); // set background color white
1130    cpgscr(1, 0.0, 0.0, 0.0); // set foreground color black
1131
1132    for (unsigned int i = 0; i < vInfo.size(); ++i) {
1133        Plotter2ViewportInfo vi = vInfo[i];
1134
1135        if (vi.showViewport) {
1136            cpgstbg(0); // reset background colour to the initial one (white)
1137            cpgsci(1);  // reset foreground colour to the initial one (black)
1138            cpgsls(1);  // reset line style to solid
1139            cpgslw(1);  // reset line width to 1
1140            cpgscf(1);  // reset font style to normal
1141            cpgsch(vi.fontSizeDef);// reset font size
1142            cpgsfs(1);  // reset fill style (solid)
1143
1144            // setup viewport
1145            cpgsvp(vi.vpPosXMin, vi.vpPosXMax, vi.vpPosYMin, vi.vpPosYMax);
1146            cpgswin(vi.vpRangeXMin, vi.vpRangeXMax, vi.vpRangeYMin, vi.vpRangeYMax);
1147
1148            // background color (default is transparent)
1149            if (vi.vpBColor >= 0) {
1150                cpgsci(vi.vpBColor);
1151                cpgrect(vi.vpRangeXMin, vi.vpRangeXMax, vi.vpRangeYMin, vi.vpRangeYMax);
1152                cpgsci(1);  // reset foreground colour to the initial one (black)
1153            }
1154
1155            // data
1156            for (unsigned int j = 0; j < vi.vData.size(); ++j) {
1157                cpgstbg(0); // reset background colour to the initial one (white)
1158                cpgsci(1);  // reset foreground colour to the initial one (black)
1159                cpgsls(1);  // reset line style to solid
1160                cpgslw(1);  // reset line width to 1
1161                cpgscf(1);  // reset font style to normal
1162                cpgsch(vi.fontSizeDef);// reset font size
1163
1164                Plotter2DataInfo di = vi.vData[j];
1165                std::vector<float> vxdata = di.xData;
1166                int ndata = vxdata.size();
1167                float* pxdata = new float[ndata];
1168                float* pydata = new float[ndata];
1169                for (int k = 0; k < ndata; ++k) {
1170                    pxdata[k] = di.xData[k];
1171                    pydata[k] = di.yData[k];
1172                }
1173
1174                if (di.drawLine) {
1175                    cpgsls(di.lineStyle);
1176                    cpgslw(di.lineWidth);
1177                    int colorIdx = di.lineColor;
1178                    if (colorIdx < 0) {
1179                        colorIdx = (j + 1) % 15 + 1;
1180                    }
1181                    cpgsci(colorIdx);
1182                    cpgline(ndata, pxdata, pydata);
1183                }
1184
1185                if (di.drawMarker) {
1186                    cpgsch(di.markerSize);
1187                    cpgsci(di.markerColor);
1188                    cpgpt(ndata, pxdata, pydata, di.markerType);
1189                }
1190
1191                delete [] pxdata;
1192                delete [] pydata;
1193            }
1194
1195            //calculate y-range of xmasks
1196            std::vector<float> yrange = vi.getRangeY();
1197            float yexcess = 0.1*(yrange[1] - yrange[0]);
1198            float xmaskymin = yrange[0] - yexcess;
1199            float xmaskymax = yrange[1] + yexcess;
1200
1201            // masks
1202            for (unsigned int j = 0; j < vi.vRect.size(); ++j) {
1203                cpgstbg(0); // reset background colour to the initial one (white)
1204                cpgsci(1);  // reset foreground colour to the initial one (black)
1205                cpgsls(1);  // reset line style to solid
1206                cpgslw(1);  // reset line width to 1
1207                cpgscf(1);  // reset font style to normal
1208                cpgsch(vi.fontSizeDef);// reset font size
1209                cpgsfs(1);  // reset fill style (solid)
1210
1211                Plotter2RectInfo ri = vi.vRect[j];
1212                cpgsci(ri.color);
1213                cpgsfs(ri.fill);
1214                cpgslw(ri.width);
1215                cpgshs(45.0, ri.hsep, 0.0);
1216                float* mxdata = new float[4];
1217                float* mydata = new float[4];
1218                mxdata[0] = ri.xmin;
1219                mxdata[1] = ri.xmax;
1220                mxdata[2] = ri.xmax;
1221                mxdata[3] = ri.xmin;
1222                mydata[0] = xmaskymin;
1223                mydata[1] = xmaskymin;
1224                mydata[2] = xmaskymax;
1225                mydata[3] = xmaskymax;
1226                cpgpoly(4, mxdata, mydata);
1227            }
1228
1229            cpgstbg(0); // reset background colour to the initial one (white)
1230            cpgsci(1);  // reset foreground colour to the initial one (black)
1231            cpgsls(1);  // reset line style to solid
1232            cpgslw(1);  // reset line width to 1
1233            cpgscf(1);  // reset font style to normal
1234            cpgsch(vi.fontSizeDef);// reset font size
1235            cpgsfs(1);  // reset fill style (solid)
1236
1237            cpgbox("BCTS",  vi.majorTickIntervalX, vi.nMinorTickWithinMajorTicksX,
1238                   "BCTSV", vi.majorTickIntervalY, vi.nMinorTickWithinMajorTicksY);
1239
1240            // viewport outline, ticks and number labels
1241            std::string numformatx, numformaty;
1242            if (vi.numLocationX == "b") {
1243                numformatx = "N";
1244            } else if (vi.numLocationX == "t") {
1245                numformatx = "M";
1246            } else if (vi.numLocationX == "") {
1247                numformatx = "";
1248            }
1249            if (vi.numLocationY == "l") {
1250                numformaty = "NV";
1251            } else if (vi.numLocationY == "r") {
1252                numformaty = "MV";
1253            } else if (vi.numLocationY == "") {
1254                numformaty = "";
1255            }
1256
1257            cpgbox(numformatx.c_str(), vi.majorTickIntervalX * vi.nMajorTickWithinTickNumsX, 0,
1258                   numformaty.c_str(), vi.majorTickIntervalY * vi.nMajorTickWithinTickNumsY, 0);
1259
1260            float xpos, ypos;
1261
1262            // x-label
1263            vi.getWorldCoordByWindowCoord(vi.labelXPosX, vi.labelXPosY, &xpos, &ypos);
1264            cpgsch(vi.labelXSize);
1265            cpgsci(vi.labelXColor);
1266            cpgstbg(vi.labelXBColor); //outside viewports, works ONLY with /xwindow
1267            cpgptxt(xpos, ypos, vi.labelXAngle, vi.labelXFJust, vi.labelXString.c_str());
1268
1269            // y-label
1270            vi.getWorldCoordByWindowCoord(vi.labelYPosX, vi.labelYPosY, &xpos, &ypos);
1271            cpgsch(vi.labelYSize);
1272            cpgsci(vi.labelYColor);
1273            cpgstbg(vi.labelYBColor); //outside viewports, works ONLY with /xwindow
1274            cpgptxt(xpos, ypos, vi.labelYAngle, vi.labelYFJust, vi.labelYString.c_str());
1275
1276            // title
1277            vi.getWorldCoordByWindowCoord(vi.titlePosX, vi.titlePosY, &xpos, &ypos);
1278            cpgsch(vi.titleSize);
1279            cpgsci(vi.titleColor);
1280            cpgstbg(vi.titleBColor); //outside viewports, works ONLY with /xwindow
1281            cpgptxt(xpos, ypos, vi.titleAngle, vi.titleFJust, vi.titleString.c_str());
1282        }
1283
1284    }
1285
1286    close();
1287}
1288
1289} // namespace asap
Note: See TracBrowser for help on using the repository browser.