00001 #pragma ident "$Id: SeriesList.cpp 3140 2012-06-18 15:03:02Z susancummins $"
00002
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <algorithm>
00029
00030 #include "SeriesList.hpp"
00031 #include "Splitter.hpp"
00032
00033 using namespace std;
00034 using namespace vdraw;
00035
00036 namespace vplot
00037 {
00038 void SeriesList::findMinMax(double& minX, double &maxX, double& minY, double& maxY)
00039 {
00040 minX = DBL_MAX;
00041 maxX = DBL_MIN;
00042 minY = DBL_MAX;
00043 maxY = DBL_MIN;
00044
00045 for(unsigned int i=0; i<pointlists.size(); i++)
00046 {
00047 vector<pair<double, double> >& series = pointlists[i];
00048 vector<pair<double, double> >::iterator it;
00049 for (it = series.begin(); it!=series.end(); it++)
00050 {
00051 double x = it->first;
00052 double y = it->second;
00053 maxX = (x>maxX ? x : maxX);
00054 minX = (x<minX ? x : minX);
00055 maxY = (y>maxY ? y : maxY);
00056 minY = (y<minY ? y : minY);
00057 }
00058 }
00059 }
00060
00061 void SeriesList::drawInFrame(Frame& innerFrame, double minX, double maxX, double minY, double maxY)
00062 {
00063 double multX = innerFrame.getWidth()/(maxX-minX);
00064 double multY = innerFrame.getHeight()/(maxY-minY);
00065
00066
00067 for(int i=0;i<getNumSeries();i++)
00068 {
00069 innerFrame.push_state();
00070
00071 StrokeStyle s = getStyle(i);
00072 Marker m = getMarker(i);
00073
00074 if(m.getColor().isClear() && s.getColor().isClear())
00075 {
00076 innerFrame << Comment("Plot contained data with clear stroke and marker. Skipping.");
00077 continue;
00078 }
00079
00080 vector< pair<double,double> >& vec = getPointList(i);
00081 Path curve(vec,innerFrame.lx(), innerFrame.ly());
00082
00083
00084
00085 map_object map_instance(multX,minX,multY,minY);
00086
00087 innerFrame.setMarker(m);
00088 innerFrame.setLineStyle(s);
00089
00090 if(s.getColor().isClear())
00091 {
00092
00093 auto_ptr< Path > cropX = Splitter::cropToBox(minX,maxX,minY,maxY,curve);
00094
00095
00096 std::for_each(cropX->begin(), cropX->end(), map_instance);
00097
00098
00099 innerFrame.line(*cropX);
00100 }
00101 else
00102 {
00103
00104 auto_ptr< std::list<Path> > interpX = Splitter::interpToBox(minX,maxX,minY,maxY,curve);
00105
00106 for(std::list<Path>::iterator i=interpX->begin();i!=interpX->end();i++)
00107 {
00108
00109 std::for_each(i->begin(), i->end(), map_instance);
00110
00111
00112 innerFrame.line(*i);
00113 }
00114 }
00115 innerFrame.pop_state();
00116 }
00117 }
00118
00119 void SeriesList::drawLegend(Frame& frame, double pointsize, unsigned int columns)
00120 {
00121 if(columns <= 1)
00122 drawLegendSegment(frame,pointsize,0,titles.size());
00123 else
00124 {
00125
00126 GridLayout gl(frame,1,columns);
00127
00128
00129 unsigned int n = (titles.size()/columns) + (titles.size()%columns?1:0);
00130
00131 for(int i=0; i<columns; i++)
00132 {
00133 Frame t(gl.getFrame(0,i));
00134 drawLegendSegment(t,pointsize,i*n,min(n,(unsigned int)(titles.size()-i*n)));
00135 }
00136 }
00137 }
00138
00139 void SeriesList::drawLegendSegment(Frame& frame, double pointsize,
00140 unsigned int begin, unsigned int n)
00141 {
00142
00143 if(n == 0)
00144 return;
00145
00146
00147
00148 double spacer = 5;
00149
00150
00151 bool lines = false;
00152 double mwidth = 0;
00153 double height = pointsize;
00154 for(unsigned int i=0;i<styles.size();i++)
00155 {
00156 if(!markers[i].getColor().isClear())
00157 {
00158 mwidth = max(mwidth,markers[i].getRange()*2);
00159 height = max(height,mwidth);
00160 }
00161
00162 if(!styles[i].getColor().isClear())
00163 lines = true;
00164 }
00165
00166 height += spacer;
00167
00168
00169
00170 double width = 30;
00171 double lbegin = 0;
00172 double lwidth = 30;
00173 if(mwidth)
00174 {
00175 lbegin = mwidth/2;
00176 if(lines)
00177 {
00178 width = mwidth*3;
00179 lwidth = mwidth*2;
00180 }
00181 else
00182 {
00183 width = mwidth;
00184 lwidth = 0;
00185 }
00186 }
00187
00188 TextStyle style;
00189 style.setPointSize(pointsize);
00190
00191
00192 for(unsigned int i=begin;i<begin+n;i++)
00193 {
00194
00195 double y = frame.getHeight() - height/2.0 - height*i;
00196 Line l(lbegin+spacer,y,lbegin+lwidth+spacer,y);
00197 l.setStrokeStyle(styles[i]);
00198 l.setMarker(markers[i]);
00199 frame << l;
00200
00201
00202 frame << Text(titles[i].c_str(),width+spacer*2,(y-(pointsize/2.0)),style,Text::LEFT);
00203 }
00204 }
00205 }