All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ChartRenderer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2011 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 terralib/qt/widgets/charts/ChartRenderer.cpp
22 
23  \brief A concrete chart renderer based on Qt4.
24 */
25 
26 // TerraLib
27 #include "../../../dataaccess/dataset/DataSet.h"
28 #include "../../../maptools/Chart.h"
29 #include "../Utils.h"
30 #include "ChartRenderer.h"
31 
32 // Boost
33 #include <boost/lexical_cast.hpp>
34 
35 // STL
36 #include <cassert>
37 
39  : te::map::AbstractChartRenderer()
40 {
41  m_pen.setStyle(Qt::SolidLine);
42  m_brush.setStyle(Qt::SolidPattern);
43 }
44 
46 {
47 }
48 
50 {
51  assert(chart);
52  assert(dataset);
53 
54  QImage* result = 0;
55 
56  switch(chart->getType())
57  {
58  case te::map::Pie:
59  result = drawPies(chart, dataset, width);
60  break;
61 
62  case te::map::Bar:
63  result = drawBars(chart, dataset, width);
64  break;
65  }
66 
67  // Converts QImage to te::color::RGBAColor**
69 
70  delete result;
71 
72  return rgba;
73 }
74 
76 {
77  m_painter.begin(img);
78  m_painter.setRenderHints(QPainter::Antialiasing);
79 }
80 
82 {
83  m_painter.end();
84 }
85 
86 QImage* te::qt::widgets::ChartRenderer::drawPies(const te::map::Chart* chart, const te::da::DataSet* dataset, std::size_t& width)
87 {
88  // Creates the image that will represent the chart
89  QImage* img = new QImage(chart->getWidth(), chart->getHeight(), QImage::Format_ARGB32_Premultiplied);
90  img->fill(Qt::transparent);
91 
92  setup(img);
93 
94  m_pen.setColor(Convert2Qt(chart->getContourColor()));
95  m_pen.setWidth(static_cast<int>(chart->getContourWidth()));
96 
97  std::vector<double> values;
98  getValues(chart, dataset, values);
99 
100  double sum = computeSum(values);
101 
102  int lastAngle = 0;
103 
104  // Draw each pie slice
105  for(std::size_t i = 0; i < values.size(); ++i)
106  {
107  int currentAngle = static_cast<int>((values[i] * 5760) / sum);
108 
109  // Test: Try shadow to help the chart svisualization
110  QColor shadowColor = Convert2Qt(chart->getColor(i));
111  shadowColor.setAlpha(128);
112  //QColor shadowColor = QColorQColor(128, 128, 128, 128);
113  QPen shadowPen(shadowColor);
114  shadowPen.setWidth(2);
115  m_painter.setPen(shadowPen);
116  m_painter.drawPie(img->rect(), lastAngle, currentAngle);
117 
118  // Configs a new color for this slice
119  m_painter.setPen(m_pen);
120  m_painter.setBrush(Convert2Qt(chart->getColor(i)));
121 
122  m_painter.drawPie(img->rect(), lastAngle, currentAngle);
123 
124  lastAngle += currentAngle;
125  }
126 
127  end();
128 
129  return img;
130 }
131 
132 QImage* te::qt::widgets::ChartRenderer::drawBars(const te::map::Chart* chart, const te::da::DataSet* dataset, std::size_t& width)
133 {
134  // Creates the image that will represent the chart
135  QImage* img = new QImage(chart->getWidth(), chart->getHeight(), QImage::Format_ARGB32_Premultiplied);
136  img->fill(Qt::transparent);
137 
138  setup(img);
139 
140  m_pen.setColor(Convert2Qt(chart->getContourColor()));
141  m_pen.setWidth(static_cast<int>(chart->getContourWidth()));
142  m_painter.setPen(m_pen);
143 
144  std::vector<double> values;
145  getValues(chart, dataset, values);
146 
147  // Gets the previous computed max value
148  double maxValue = chart->getMaxValue();
149  assert(maxValue > 0.0);
150 
151  int lastx = 0;
152 
153  int shadowOffset = 2;
154 
155  // Draw each bar
156  for(std::size_t i = 0; i < values.size(); ++i)
157  {
158  int barHeight = static_cast<int>((values[i] * chart->getHeight()) / maxValue);
159 
160  // Test: Try shadow to help the chart svisualization
161  QRect shadowBar(lastx - shadowOffset, -shadowOffset, chart->getBarWidth() + shadowOffset, barHeight + shadowOffset);
162  QColor shadowColor = Convert2Qt(chart->getColor(i));
163  shadowColor.setAlpha(128);
164  m_painter.setBrush(shadowColor);
165  //m_painter.setBrush(QColor(128, 128, 128, 128));
166  m_painter.setPen(Qt::NoPen);
167  m_painter.drawRect(shadowBar);
168 
169  // Current bar
170  QRect bar(lastx, 0, chart->getBarWidth(), barHeight);
171 
172  // Configs a new color for this bar
173  m_painter.setPen(m_pen);
174  m_painter.setBrush(Convert2Qt(chart->getColor(i)));
175 
176  m_painter.drawRect(bar);
177 
178  lastx += chart->getBarWidth();
179  }
180 
181  end();
182 
183  // TODO: Need review! Draw the bar on right place! ... For while, return the mirrored image.
184  QImage* mirroed = new QImage(img->mirrored());
185 
186  delete img;
187 
188  return mirroed;
189 }
190 
191 void te::qt::widgets::ChartRenderer::getValues(const te::map::Chart* chart, const te::da::DataSet* dataset, std::vector<double>& values)
192 {
193  std::size_t precision = 5;
194 
195  const std::vector<std::string>& properties = chart->getProperties();
196 
197  for(std::size_t i = 0; i < properties.size(); ++i)
198  {
199  std::string value = dataset->getAsString(properties[i], precision);
200  values.push_back(boost::lexical_cast<double>(value));
201  }
202 }
203 
204 double te::qt::widgets::ChartRenderer::computeSum(const std::vector<double>& values)
205 {
206  double sum = 0.0;
207 
208  for(std::size_t i = 0; i < values.size(); ++i)
209  sum += values[i];
210 
211  return sum;
212 }
213 
214 double te::qt::widgets::ChartRenderer::getMaxValue(const std::vector<double>& values)
215 {
216  double max = 0.0;
217 
218  for(std::size_t i = 0; i < values.size(); ++i)
219  if(std::abs(values[i]) > max)
220  max = values[i];
221 
222  return max;
223 }
QPen m_pen
The pen used to draw the chart.
Definition: ChartRenderer.h:95
te::color::RGBAColor ** render(const te::map::Chart *chart, const te::da::DataSet *dataset, std::size_t &width)
It generates the image pattern from the given chart and the current element of dataset.
const te::color::RGBAColor & getContourColor() const
Definition: Chart.cpp:98
std::size_t getWidth() const
Definition: Chart.cpp:128
std::size_t getContourWidth() const
Definition: Chart.cpp:108
ChartType getType() const
Definition: Chart.cpp:74
virtual std::string getAsString(std::size_t i, int precision=0) const
Method for retrieving a data value as a string plain representation.
Definition: DataSet.cpp:218
double computeSum(const std::vector< double > &values)
double getMaxValue(const std::vector< double > &values)
void getValues(const te::map::Chart *chart, const te::da::DataSet *dataset, std::vector< double > &values)
A concrete chart renderer based on Qt4.
ChartRenderer()
Default constructor.
const std::vector< std::string > & getProperties() const
Definition: Chart.cpp:79
QBrush m_brush
The pen used to draw the chart.
Definition: ChartRenderer.h:96
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
QImage * drawBars(const te::map::Chart *chart, const te::da::DataSet *dataset, std::size_t &width)
const te::color::RGBAColor & getColor(std::size_t i) const
Definition: Chart.cpp:84
TEQTWIDGETSEXPORT QColor Convert2Qt(const te::color::RGBAColor &color)
It converts a TerraLib Color to Qt Color.
Definition: Utils.cpp:216
QImage * drawPies(const te::map::Chart *chart, const te::da::DataSet *dataset, std::size_t &width)
This class represents the informations needed to build map charts.
Definition: Chart.h:51
void end()
Finalizes the internal QPainter resources.
std::size_t getHeight() const
Definition: Chart.cpp:118
double getMaxValue() const
Definition: Chart.cpp:158
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
void setup(QImage *img)
Setups the internal QPainter and associates it with the given paint device (QImage).
std::size_t getBarWidth() const
Definition: Chart.cpp:143
TEQTWIDGETSEXPORT QImage * GetImage(te::color::RGBAColor **img, int width, int height)
It creates a QImage from an RGBA color array.
Definition: Utils.cpp:63