1 /***************************************************************************
2 File : QwtPieCurve.cpp
3 Project : SciDAVis
4 --------------------------------------------------------------------
5 Copyright : (C) 2006 by Ion Vasilief, Tilman Benkert
6 Email (use @ for *) : ion_vasilief*yahoo.fr, thzs*gmx.net
7 Description : Pie plot class
8
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26 * Boston, MA 02110-1301 USA *
27 * *
28 ***************************************************************************/
29 #include "QwtPieCurve.h"
30 #include "ColorButton.h"
31 #include "Table.h"
32 #include "core/column/Column.h"
33
34 #include <QPaintDevice>
35 #include <QPainter>
36 #include <QVarLengthArray>
37 #include <QLocale>
38
39 #include <qwt_plot_layout.h>
40
QwtPieCurve(Table * t,const QString & name,int startRow,int endRow)41 QwtPieCurve::QwtPieCurve(Table *t, const QString &name, int startRow, int endRow)
42 : DataCurve(t, QString(), name, startRow, endRow)
43 {
44 d_pie_ray = 100;
45 d_first_color = 0;
46 setPen(QPen(QColor(Qt::black), 1, Qt::SolidLine));
47 setBrush(QBrush(Qt::black, Qt::SolidPattern));
48
49 setType(Graph::Pie);
50 }
51
draw(QPainter * painter,const QwtScaleMap & xMap,const QwtScaleMap & yMap,int from,int to) const52 void QwtPieCurve::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap,
53 int from, int to) const
54 {
55 if (!painter || dataSize() <= 0)
56 return;
57
58 if (to < 0)
59 to = dataSize() - 1;
60
61 drawPie(painter, xMap, yMap, from, to);
62 }
63
drawPie(QPainter * painter,const QwtScaleMap &,const QwtScaleMap &,int from,int to) const64 void QwtPieCurve::drawPie(QPainter *painter, const QwtScaleMap &, const QwtScaleMap &, int from,
65 int to) const
66 {
67 // This has to be synced with Graph::plotPie() for now... until we have a clean solution.
68 QRect canvas_rect = plot()->plotLayout()->canvasRect();
69 int radius = 0.4 * qMin(canvas_rect.width(), canvas_rect.height());
70
71 QRect pieRect;
72 pieRect.setX(canvas_rect.center().x() - radius);
73 pieRect.setY(canvas_rect.center().y() - radius);
74 pieRect.setWidth(2 * radius);
75 pieRect.setHeight(2 * radius);
76
77 double sum = 0.0;
78 for (int i = from; i <= to; i++) {
79 const double yi = y(i);
80 sum += yi;
81 }
82
83 int angle = (int)(5760 * 0.75);
84 painter->save();
85 for (int i = from; i <= to; i++) {
86 const double yi = y(i);
87 const int value = (int)(yi / sum * 5760);
88
89 painter->setPen(QwtPlotCurve::pen());
90 painter->setBrush(QBrush(color(i), QwtPlotCurve::brush().style()));
91 painter->drawPie(pieRect, -angle, -value);
92
93 angle += value;
94 }
95 painter->restore();
96 }
97
color(int i) const98 QColor QwtPieCurve::color(int i) const
99 {
100 int index = (d_first_color + i) % ColorButton::colors_count;
101 return ColorButton::color(index);
102 }
103
setBrushStyle(const Qt::BrushStyle & style)104 void QwtPieCurve::setBrushStyle(const Qt::BrushStyle &style)
105 {
106 QBrush br = QwtPlotCurve::brush();
107 if (br.style() == style)
108 return;
109
110 br.setStyle(style);
111 setBrush(br);
112 }
113
loadData()114 bool QwtPieCurve::loadData()
115 {
116 QVarLengthArray<double> Y(abs(d_end_row - d_start_row) + 1);
117 int size = 0;
118 int ycol = d_table->colIndex(title().text());
119 Column *y_col_ptr = d_table->column(ycol);
120 auto yColType = d_table->columnType(ycol);
121
122 for (int row = d_start_row; row <= d_end_row && row < y_col_ptr->rowCount(); row++) {
123 if (!y_col_ptr->isInvalid(row)) {
124 if (yColType == SciDAVis::ColumnMode::Text) {
125 QString yval = y_col_ptr->textAt(row);
126 bool valid_data = true;
127 Y[size] = QLocale().toDouble(yval, &valid_data);
128 if (!valid_data)
129 continue;
130 } else
131 Y[size] = y_col_ptr->valueAt(row);
132
133 size++;
134 }
135 }
136 Y.resize(size);
137 setData(Y.data(), Y.data(), size);
138
139 return true;
140 }
141
updateBoundingRect()142 void QwtPieCurve::updateBoundingRect()
143 {
144 if (!plot())
145 return;
146
147 QwtScaleMap xMap = plot()->canvasMap(xAxis());
148 int x_center = (xMap.p1() + xMap.p2()) / 2;
149 int x_left = x_center - d_pie_ray;
150 d_left_coord = xMap.invTransform(x_left);
151 }
152