1 | #include "canvastext.h"
|
---|
2 | #include "chartform.h"
|
---|
3 |
|
---|
4 | #include <qbrush.h>
|
---|
5 | #include <qcanvas.h>
|
---|
6 |
|
---|
7 | #include <math.h> // sin, cos
|
---|
8 |
|
---|
9 | #ifndef M_PI
|
---|
10 | #define M_PI 3.1415
|
---|
11 | #endif
|
---|
12 |
|
---|
13 | void ChartForm::drawElements()
|
---|
14 | {
|
---|
15 | QCanvasItemList list = m_canvas->allItems();
|
---|
16 | for ( QCanvasItemList::iterator it = list.begin(); it != list.end(); ++it )
|
---|
17 | delete *it;
|
---|
18 |
|
---|
19 | // 360 * 16 for pies; Qt works with 16ths of degrees
|
---|
20 | int scaleFactor = m_chartType == PIE ? 5760 :
|
---|
21 | m_chartType == VERTICAL_BAR ? m_canvas->height() :
|
---|
22 | m_canvas->width();
|
---|
23 | double biggest = 0.0;
|
---|
24 | int count = 0;
|
---|
25 | double total = 0.0;
|
---|
26 | static double scales[MAX_ELEMENTS];
|
---|
27 |
|
---|
28 | for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
|
---|
29 | if ( m_elements[i].isValid() ) {
|
---|
30 | double value = m_elements[i].value();
|
---|
31 | count++;
|
---|
32 | total += value;
|
---|
33 | if ( value > biggest )
|
---|
34 | biggest = value;
|
---|
35 | scales[i] = m_elements[i].value() * scaleFactor;
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | if ( count ) {
|
---|
40 | // 2nd loop because of total and biggest
|
---|
41 | for ( int i = 0; i < MAX_ELEMENTS; ++i )
|
---|
42 | if ( m_elements[i].isValid() )
|
---|
43 | if ( m_chartType == PIE )
|
---|
44 | scales[i] = (m_elements[i].value() * scaleFactor) / total;
|
---|
45 | else
|
---|
46 | scales[i] = (m_elements[i].value() * scaleFactor) / biggest;
|
---|
47 |
|
---|
48 | switch ( m_chartType ) {
|
---|
49 | case PIE:
|
---|
50 | drawPieChart( scales, total, count );
|
---|
51 | break;
|
---|
52 | case VERTICAL_BAR:
|
---|
53 | drawVerticalBarChart( scales, total, count );
|
---|
54 | break;
|
---|
55 | case HORIZONTAL_BAR:
|
---|
56 | drawHorizontalBarChart( scales, total, count );
|
---|
57 | break;
|
---|
58 | }
|
---|
59 | }
|
---|
60 |
|
---|
61 | m_canvas->update();
|
---|
62 | }
|
---|
63 |
|
---|
64 |
|
---|
65 | void ChartForm::drawPieChart( const double scales[], double total, int )
|
---|
66 | {
|
---|
67 | double width = m_canvas->width();
|
---|
68 | double height = m_canvas->height();
|
---|
69 | int size = int(width > height ? height : width);
|
---|
70 | int x = int(width / 2);
|
---|
71 | int y = int(height / 2);
|
---|
72 | int angle = 0;
|
---|
73 |
|
---|
74 | for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
|
---|
75 | if ( m_elements[i].isValid() ) {
|
---|
76 | int extent = int(scales[i]);
|
---|
77 | QCanvasEllipse *arc = new QCanvasEllipse(
|
---|
78 | size, size, angle, extent, m_canvas );
|
---|
79 | arc->setX( x );
|
---|
80 | arc->setY( y );
|
---|
81 | arc->setZ( 0 );
|
---|
82 | arc->setBrush( QBrush( m_elements[i].valueColor(),
|
---|
83 | BrushStyle(m_elements[i].valuePattern()) ) );
|
---|
84 | arc->show();
|
---|
85 | angle += extent;
|
---|
86 | QString label = m_elements[i].label();
|
---|
87 | if ( !label.isEmpty() || m_addValues != NO ) {
|
---|
88 | label = valueLabel( label, m_elements[i].value(), total );
|
---|
89 | CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
|
---|
90 | double proX = m_elements[i].proX( PIE );
|
---|
91 | double proY = m_elements[i].proY( PIE );
|
---|
92 | if ( proX < 0 || proY < 0 ) {
|
---|
93 | // Find the centre of the pie segment
|
---|
94 | QRect rect = arc->boundingRect();
|
---|
95 | proX = ( rect.width() / 2 ) + rect.x();
|
---|
96 | proY = ( rect.height() / 2 ) + rect.y();
|
---|
97 | // Centre text over the centre of the pie segment
|
---|
98 | rect = text->boundingRect();
|
---|
99 | proX -= ( rect.width() / 2 );
|
---|
100 | proY -= ( rect.height() / 2 );
|
---|
101 | // Make proportional
|
---|
102 | proX /= width;
|
---|
103 | proY /= height;
|
---|
104 | }
|
---|
105 | text->setColor( m_elements[i].labelColor() );
|
---|
106 | text->setX( proX * width );
|
---|
107 | text->setY( proY * height );
|
---|
108 | text->setZ( 1 );
|
---|
109 | text->show();
|
---|
110 | m_elements[i].setProX( PIE, proX );
|
---|
111 | m_elements[i].setProY( PIE, proY );
|
---|
112 | }
|
---|
113 | }
|
---|
114 | }
|
---|
115 | }
|
---|
116 |
|
---|
117 |
|
---|
118 | void ChartForm::drawVerticalBarChart(
|
---|
119 | const double scales[], double total, int count )
|
---|
120 | {
|
---|
121 | double width = m_canvas->width();
|
---|
122 | double height = m_canvas->height();
|
---|
123 | int prowidth = int(width / count);
|
---|
124 | int x = 0;
|
---|
125 | QPen pen;
|
---|
126 | pen.setStyle( NoPen );
|
---|
127 |
|
---|
128 | for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
|
---|
129 | if ( m_elements[i].isValid() ) {
|
---|
130 | int extent = int(scales[i]);
|
---|
131 | int y = int(height - extent);
|
---|
132 | QCanvasRectangle *rect = new QCanvasRectangle(
|
---|
133 | x, y, prowidth, extent, m_canvas );
|
---|
134 | rect->setBrush( QBrush( m_elements[i].valueColor(),
|
---|
135 | BrushStyle(m_elements[i].valuePattern()) ) );
|
---|
136 | rect->setPen( pen );
|
---|
137 | rect->setZ( 0 );
|
---|
138 | rect->show();
|
---|
139 | QString label = m_elements[i].label();
|
---|
140 | if ( !label.isEmpty() || m_addValues != NO ) {
|
---|
141 | double proX = m_elements[i].proX( VERTICAL_BAR );
|
---|
142 | double proY = m_elements[i].proY( VERTICAL_BAR );
|
---|
143 | if ( proX < 0 || proY < 0 ) {
|
---|
144 | proX = x / width;
|
---|
145 | proY = y / height;
|
---|
146 | }
|
---|
147 | label = valueLabel( label, m_elements[i].value(), total );
|
---|
148 | CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
|
---|
149 | text->setColor( m_elements[i].labelColor() );
|
---|
150 | text->setX( proX * width );
|
---|
151 | text->setY( proY * height );
|
---|
152 | text->setZ( 1 );
|
---|
153 | text->show();
|
---|
154 | m_elements[i].setProX( VERTICAL_BAR, proX );
|
---|
155 | m_elements[i].setProY( VERTICAL_BAR, proY );
|
---|
156 | }
|
---|
157 | x += prowidth;
|
---|
158 | }
|
---|
159 | }
|
---|
160 | }
|
---|
161 |
|
---|
162 |
|
---|
163 | void ChartForm::drawHorizontalBarChart(
|
---|
164 | const double scales[], double total, int count )
|
---|
165 | {
|
---|
166 | double width = m_canvas->width();
|
---|
167 | double height = m_canvas->height();
|
---|
168 | int proheight = int(height / count);
|
---|
169 | int y = 0;
|
---|
170 | QPen pen;
|
---|
171 | pen.setStyle( NoPen );
|
---|
172 |
|
---|
173 | for ( int i = 0; i < MAX_ELEMENTS; ++i ) {
|
---|
174 | if ( m_elements[i].isValid() ) {
|
---|
175 | int extent = int(scales[i]);
|
---|
176 | QCanvasRectangle *rect = new QCanvasRectangle(
|
---|
177 | 0, y, extent, proheight, m_canvas );
|
---|
178 | rect->setBrush( QBrush( m_elements[i].valueColor(),
|
---|
179 | BrushStyle(m_elements[i].valuePattern()) ) );
|
---|
180 | rect->setPen( pen );
|
---|
181 | rect->setZ( 0 );
|
---|
182 | rect->show();
|
---|
183 | QString label = m_elements[i].label();
|
---|
184 | if ( !label.isEmpty() || m_addValues != NO ) {
|
---|
185 | double proX = m_elements[i].proX( HORIZONTAL_BAR );
|
---|
186 | double proY = m_elements[i].proY( HORIZONTAL_BAR );
|
---|
187 | if ( proX < 0 || proY < 0 ) {
|
---|
188 | proX = 0;
|
---|
189 | proY = y / height;
|
---|
190 | }
|
---|
191 | label = valueLabel( label, m_elements[i].value(), total );
|
---|
192 | CanvasText *text = new CanvasText( i, label, m_font, m_canvas );
|
---|
193 | text->setColor( m_elements[i].labelColor() );
|
---|
194 | text->setX( proX * width );
|
---|
195 | text->setY( proY * height );
|
---|
196 | text->setZ( 1 );
|
---|
197 | text->show();
|
---|
198 | m_elements[i].setProX( HORIZONTAL_BAR, proX );
|
---|
199 | m_elements[i].setProY( HORIZONTAL_BAR, proY );
|
---|
200 | }
|
---|
201 | y += proheight;
|
---|
202 | }
|
---|
203 | }
|
---|
204 | }
|
---|
205 |
|
---|
206 |
|
---|
207 | QString ChartForm::valueLabel(
|
---|
208 | const QString& label, double value, double total )
|
---|
209 | {
|
---|
210 | if ( m_addValues == NO )
|
---|
211 | return label;
|
---|
212 |
|
---|
213 | QString newLabel = label;
|
---|
214 | if ( !label.isEmpty() )
|
---|
215 | if ( m_chartType == VERTICAL_BAR )
|
---|
216 | newLabel += '\n';
|
---|
217 | else
|
---|
218 | newLabel += ' ';
|
---|
219 | if ( m_addValues == YES )
|
---|
220 | newLabel += QString::number( value, 'f', m_decimalPlaces );
|
---|
221 | else if ( m_addValues == AS_PERCENTAGE )
|
---|
222 | newLabel += QString::number( (value / total) * 100, 'f', m_decimalPlaces )
|
---|
223 | + '%';
|
---|
224 | return newLabel;
|
---|
225 | }
|
---|
226 |
|
---|