All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HistogramChart.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2010-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file HistogramChart.cpp
22 
23  \brief A class to represent a histogram chart.
24 */
25 
26 //Terralib
27 #include "../../../dataaccess/dataset/ObjectId.h"
28 #include "../../../dataaccess/dataset/ObjectIdSet.h"
29 #include "../../../qt/widgets/se/Utils.h"
30 #include "Enums.h"
31 #include "Histogram.h"
32 #include "HistogramChart.h"
33 #include "HistogramStyle.h"
34 #include "StringScaleDraw.h"
35 
36 
37 //QT
38 #include <qbrush.h>
39 #include <qpen.h>
40 
41 //QWT
42 #include <qwt_column_symbol.h>
43 #include <qwt_plot.h>
44 
45 //STL
46 #include <limits>
47 
49  QwtPlotHistogram(),
50  m_histogram(histogram),
51  m_histogramStyle(style)
52 {
53 
54  //Vector that will be populated by the histogram's data
55  QVector<QwtIntervalSample> samples;
56 
57  if((histogram->getType() >= te::dt::INT16_TYPE && histogram->getType() <= te::dt::UINT64_TYPE) ||
58  histogram->getType() == te::dt::FLOAT_TYPE || histogram->getType() == te::dt::DOUBLE_TYPE ||
59  histogram->getType() == te::dt::NUMERIC_TYPE)
60  {
61  std::map<double, unsigned int> values;
62  values = histogram->getValues();
63 
64  std::map<double, unsigned int>::const_iterator it;
65  it = values.begin();
66 
67  std::map<int, unsigned int> vmap;
68 
69  int i = 0;
70 
71  double ini = histogram->getMinValue();
72 
73  double vx = ini + histogram->getInterval();
74 
75  while(vx <= values.rbegin()->first)
76  {
77  vmap[i] = 0;
78  if(fabs(vx) < 0.000000000001)
79  vx = 0.;
80  while(it != values.end())
81  {
82  if(it->first >= ini && it->first < vx)
83  vmap[i] += it->second;
84  else
85  break;
86  ++it;
87  }
88 
89  QwtInterval qinterval(ini, vx);
90  qinterval.setBorderFlags(QwtInterval::ExcludeMaximum);
91  samples.push_back(QwtIntervalSample(vmap[i], qinterval));
92 
93  ini = vx;
94  vx += histogram->getInterval();
95  ++i;
96  }
97 
98  setData(new QwtIntervalSeriesData(samples));
99  }
100 
101  else if (histogram->getType() == te::dt::DATETIME_TYPE || histogram->getType() == te::dt::STRING_TYPE)
102  {
103  std::map<std::string, unsigned int> values;
104  values = histogram->getStringValues();
105 
106  std::map<std::string, unsigned int>::iterator it;
107  it = values.begin();
108 
110  QVector<QwtIntervalSample> samples(values.size());
111  double LabelInterval = 0.0;
112 
113  while (it != values.end())
114  {
115  QwtInterval qwtInterval(LabelInterval, LabelInterval+1);
116  qwtInterval.setBorderFlags(QwtInterval::ExcludeMaximum);
117  samples[LabelInterval] = QwtIntervalSample(it->second, qwtInterval);
118  LabelInterval++;
119  it++;
120  }
121 
122  setData(new QwtIntervalSeriesData(samples));
123  }
124  else
125  {
126  std::map<double, unsigned int> values;
127  std::map<double, unsigned int>::const_iterator it;
128  values = histogram->getValues();
129  it = values.begin();
130  double interval = 0.0;
131 
132  while (it != values.end())
133  {
134  QwtInterval qwtInterval(interval, interval+1);
135  samples.push_back(QwtIntervalSample(it->second, qwtInterval));
136  interval++;
137  it++;
138  }
139 
140  setData(new QwtIntervalSeriesData(samples));
141  }
142 
143  if(!m_histogramStyle)
144  {
146  QPen barPen;
147  QBrush barBrush;
148 
151  barBrush.setStyle(Qt::SolidPattern);
152 
153  setPen(barPen);
154  setBrush(barBrush);
155  }
156 
157  m_selection = new QwtPlotHistogram();
158  m_selection->setStyle(QwtPlotHistogram::Columns);
159 
160  //The default selection color is green
161  m_selection->setBrush(QColor("#00FF00"));
162  m_selection->attach(plot());
163 
164 }
165 
167 {
168  delete m_histogram;
169  delete m_histogramStyle;
170  delete m_selection;
171  if(m_histogram->getType() == te::dt::DATETIME_TYPE || m_histogram->getType() == te::dt::STRING_TYPE)
172  delete m_histogramScaleDraw;
173 }
174 
176 {
178 }
179 
181 {
182  return m_histogramScaleDraw;
183 }
184 
186 {
187  delete m_histogramScaleDraw;
188  m_histogramScaleDraw = newScaleDraw;
189 }
190 
192 {
193  if (m_histogram->getType() == te::dt::DATETIME_TYPE || m_histogram->getType() == te::dt::STRING_TYPE)
194  {
195  plot->setAxisScaleDraw(QwtPlot::xBottom, m_histogramScaleDraw);
196  plot->axisScaleDraw(QwtPlot::xBottom)->setLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter);
197  plot->axisScaleDraw(QwtPlot::xBottom)->setLabelRotation(-60);
198  }
199 
200  QwtPlotHistogram::attach(plot);
201 }
202 
204 {
205  return m_histogram;
206 }
207 
209 {
210  delete m_histogram;
211  m_histogram = newHistogram;
212 }
213 
215 {
216  return m_histogramStyle->clone();
217 }
218 
220 {
221  delete m_histogramStyle;
222  m_histogramStyle = newStyle;
223 
224  //The pen and brush that will be used
225  QPen barPen;
226  QBrush barBrush;
227 
228  //Configuring the pen and brush based on the current style
229  te::qt::widgets::Config(barPen, m_histogramStyle->getStroke());
230  te::qt::widgets::Config(barBrush, m_histogramStyle->getFill());
231  barBrush.setStyle(Qt::SolidPattern);
232 
233  //Updating the chart's pen and brush.
234  setPen(barPen);
235  setBrush(barBrush);
236 }
237 
239 {
240  //Removing the previous selection, if there was any.
241  m_selection->detach();
242 
243  std::set<te::da::ObjectId*, te::common::LessCmp<te::da::ObjectId*> >::const_iterator itObjSet;
244  QwtSeriesData<QwtIntervalSample>* values = data();
245 
246  //Acquiring all selected intervals:
247 
248  if((m_histogram->getType() >= te::dt::INT16_TYPE && m_histogram->getType() <= te::dt::UINT64_TYPE) ||
249  m_histogram->getType() == te::dt::FLOAT_TYPE || m_histogram->getType() == te::dt::DOUBLE_TYPE ||
250  m_histogram->getType() == te::dt::NUMERIC_TYPE)
251  {
252 
253  std::map<double, unsigned int> highlightedIntervals;
254 
255  //Acquiring the slected intervals
256  for(itObjSet = oids->begin(); itObjSet != oids->end(); ++itObjSet)
257  {
258  double interval = static_cast< const te::dt::Double*>(m_histogram->find((*itObjSet)))->getValue();
259  highlightedIntervals.insert(std::make_pair(interval, 0));
260  }
261 
262  //Acquiring the selected values' frequency
263  for(itObjSet = oids->begin(); itObjSet != oids->end(); ++itObjSet)
264  {
265  double interval = static_cast< const te::dt::Double*>(m_histogram->find((*itObjSet)))->getValue();
266  ++highlightedIntervals.at(interval);
267  }
268 
269  QVector<QwtIntervalSample> highlightedSamples(highlightedIntervals.size());
270 
271  //Acquiring all selected samples:
272  for(size_t i = 0; i < values->size(); ++i)
273  {
274  for (std::map<double, unsigned int>::iterator it = highlightedIntervals.begin(); it != highlightedIntervals.end(); ++it)
275  {
276  //Comparing with the minimum value. Our histogram is created based on the exclude maximum policy.
277  if(values->sample(i).interval.minValue() == it->first)
278  {
279  QwtInterval qwtInterval(values->sample(i).interval.minValue(), values->sample(i).interval.maxValue());
280  highlightedSamples.push_back(QwtIntervalSample(it->second, qwtInterval));
281  }
282  }
283  }
284  m_selection->setData(new QwtIntervalSeriesData(highlightedSamples));
285  }
286 
287  else if (m_histogram->getType() == te::dt::DATETIME_TYPE || m_histogram->getType() == te::dt::STRING_TYPE)
288  {
289 
290  //A vector that will contain the selected strings
291  std::map<std::string, unsigned int> highlightedIntervals;
292 
293  //Acquiring the slected intervals
294  for(itObjSet = oids->begin(); itObjSet != oids->end(); ++itObjSet)
295  {
296  std::string interval = m_histogram->find((*itObjSet))->toString();
297  highlightedIntervals.insert(std::make_pair(interval,0));
298  }
299 
300  //Acquiring the selected values' frequency
301  for(itObjSet = oids->begin(); itObjSet != oids->end(); ++itObjSet)
302  {
303  std::string interval = m_histogram->find((*itObjSet))->toString();
304  ++highlightedIntervals.at(interval);
305  }
306 
307 
308  //A vector containing that will be populated with the samples that match the selected strings
309  QVector<QwtIntervalSample> highlightedSamples(highlightedIntervals.size());
310 
311  //Acquiring all selected samples:
312  for(size_t i = 0; i < values->size(); ++i)
313  {
314  for (std::map<std::string, unsigned int>::iterator it = highlightedIntervals.begin(); it != highlightedIntervals.end(); ++it)
315  {
316  //Comparing label by label.
317  if(m_histogramScaleDraw->label(i).text().toStdString() == it->first)
318  {
319  QwtInterval qwtInterval(values->sample(i).interval.minValue(), values->sample(i).interval.maxValue());
320  highlightedSamples.push_back(QwtIntervalSample(it->second, qwtInterval));
321  }
322  }
323  }
324  m_selection->setData(new QwtIntervalSeriesData(highlightedSamples));
325  }
326 
327  m_selection->attach(plot());
328  plot()->replot();
329 }
330 
332 {
333  QwtSeriesData<QwtIntervalSample>* values = data();
334 
335  if (m_histogram->getType() == te::dt::DATETIME_TYPE || m_histogram->getType() == te::dt::STRING_TYPE)
336  {
337  std::auto_ptr<te::dt::String> data(new te::dt::String(""));
338  for(size_t i = 0; i < values->size(); ++i)
339  {
340  if(values->sample(i).interval.minValue() < point.rx() && values->sample(i).interval.maxValue() > point.rx() && values->sample(i).value > point.ry())
341  data.reset(new te::dt::String(m_histogramScaleDraw->label(i).text().toStdString()));
342  }
343 
344  return m_histogram->find(data.get());
345  }
346  else
347  {
348  std::auto_ptr<te::dt::Double> data(new te::dt::Double(std::numeric_limits<double>::max()));
349 
350  for(size_t i = 0; i < values->size(); ++i)
351  {
352  if(values->sample(i).interval.minValue() < point.rx() && values->sample(i).interval.maxValue() > point.rx() && values->sample(i).value > point.ry())
353  data.reset(new te::dt::Double(values->sample(i).interval.minValue()));
354  }
355 
356  return m_histogram->find(data.get());
357  }
358 }
359 
361 {
362  m_selection->setBrush(selColor);
363 }
HistogramStyle * clone()
Returns a pointer to a clone of this HistogramStyle.
double & getInterval()
It returns the histogram&#39;s interval. Will be invalid if the histogram was created based on string int...
Definition: Histogram.cpp:93
void highlight(const te::da::ObjectIdSet *oids)
Highlights the objects identified by oids.
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:53
void Config(QPen &pen, const te::se::Stroke *stroke)
It configs the given pen based on Symbology Enconding Stroke element.
Definition: Utils.cpp:38
te::qt::widgets::Histogram * getHistogram()
It returns the chart&#39;s histogram.
double & getMinValue()
It returns the histogram&#39;s minimum value. Will be invalid if the histogram was created based on strin...
Definition: Histogram.cpp:83
A class to represent a Histogram.
Definition: Histogram.h:56
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
A class used to define the style of a histogram&#39;s chart.
A class to represent a histogram.
void setScaleDraw(StringScaleDraw *newScaleDraw)
It sets the chart&#39;s scale draw.
virtual int rtti() const
Returns the chart&#39;s type.
StringScaleDraw * getScaleDraw()
It returns the chart&#39;s scale draw.
HistogramChart(Histogram *data, te::qt::widgets::HistogramStyle *style=0)
Constructor.
int & getType()
It returns the histogram&#39;s type.
Definition: Histogram.cpp:53
te::qt::widgets::HistogramStyle * m_histogramStyle
The histogram&#39;s style as displayed by this widget.
StringScaleDraw * m_histogramScaleDraw
Scale draw that defines how a label will be displayed on this chart.
A class to represent a set of labels to be used on a histogram&#39;s chart.
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator begin() const
Returns an iterator for the object ids in container.
std::set< ObjectId *, te::common::LessCmp< ObjectId * > >::const_iterator end() const
Returns an iterator for the object ids in container.
A class to represent a histogram chart.
QwtPlotHistogram * m_selection
The PlotItems to be highlighted when a selection occurs;.
te::qt::widgets::HistogramStyle * getHistogramStyle()
Returns a clone of the pointer to the histogram&#39;s style.
void attach(QwtPlot *plot)
It atttaches a QwtPlot to this Cahrt.
te::se::Fill * getFill()
Returns a pointer to the histogram bar&#39;s fill.
virtual std::string toString() const
It returns the data value in a string representation.
Definition: SimpleData.h:126
void setHistogramStyle(te::qt::widgets::HistogramStyle *newStyle)
It sets the chart&#39;s style.
void setSelectionColor(QColor selColor)
color used to hgihlight selected objects on this chart.
te::se::Stroke * getStroke()
Returns a pointer to the histogram bar&#39;s stroke.
std::map< std::string, unsigned int > getStringValues()
It returns the map containing the histogram String values. The key is a unique string that represents...
Definition: Histogram.cpp:74
void setHistogram(te::qt::widgets::Histogram *newHistogram)
It sets the chart&#39;s histogram.
std::set< std::string > & getStringInterval()
It returns the histogram&#39;s string set of intervals. Will be invalid if the histogram was created base...
Definition: Histogram.cpp:103
std::map< double, unsigned int > getValues()
It returns the map containing the histogram values. The key is the minimum values of the histogram&#39;s ...
Definition: Histogram.cpp:63