@@ -1,208 +1,215 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2013 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Enterprise Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Enterprise licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Enterprise License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #include "boxplotchartitem_p.h" |
|
22 | 22 | #include "qboxplotseries_p.h" |
|
23 | 23 | #include "bar_p.h" |
|
24 | 24 | #include "qboxset_p.h" |
|
25 | 25 | #include "qabstractbarseries_p.h" |
|
26 | 26 | #include "qboxset.h" |
|
27 | 27 | #include "boxwhiskers_p.h" |
|
28 | 28 | #include <QPainter> |
|
29 | 29 | |
|
30 | 30 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
31 | 31 | |
|
32 | 32 | BoxPlotChartItem::BoxPlotChartItem(QBoxPlotSeries *series, QGraphicsItem *item) : |
|
33 | 33 | ChartItem(series->d_func(), item), |
|
34 | 34 | m_series(series), |
|
35 | 35 | m_animation(0) |
|
36 | 36 | { |
|
37 | 37 | connect(series, SIGNAL(boxsetsRemoved(QList<QBoxSet *>)), this, SLOT(handleBoxsetRemove(QList<QBoxSet *>))); |
|
38 | 38 | connect(series->d_func(), SIGNAL(restructuredBoxes()), this, SLOT(handleDataStructureChanged())); |
|
39 | 39 | connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged())); |
|
40 | 40 | connect(series->d_func(), SIGNAL(updatedBoxes()), this, SLOT(handleUpdatedBars())); |
|
41 | 41 | connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdatedBars())); |
|
42 | 42 | // QBoxPlotSeriesPrivate calls handleDataStructureChanged(), don't do it here |
|
43 | 43 | setZValue(ChartPresenter::BoxPlotSeriesZValue); |
|
44 | 44 | } |
|
45 | 45 | |
|
46 | 46 | BoxPlotChartItem::~BoxPlotChartItem() |
|
47 | 47 | { |
|
48 | 48 | } |
|
49 | 49 | |
|
50 | 50 | void BoxPlotChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
51 | 51 | { |
|
52 | 52 | Q_UNUSED(painter); |
|
53 | 53 | Q_UNUSED(option); |
|
54 | 54 | Q_UNUSED(widget); |
|
55 | 55 | } |
|
56 | 56 | |
|
57 | 57 | void BoxPlotChartItem::setAnimation(BoxPlotAnimation *animation) |
|
58 | 58 | { |
|
59 | 59 | m_animation = animation; |
|
60 | 60 | if (m_animation) { |
|
61 | 61 | foreach (BoxWhiskers *item, m_boxTable.values()) |
|
62 | 62 | m_animation->addBox(item); |
|
63 | 63 | handleDomainUpdated(); |
|
64 | 64 | } |
|
65 | 65 | } |
|
66 | 66 | |
|
67 | 67 | void BoxPlotChartItem::handleDataStructureChanged() |
|
68 | 68 | { |
|
69 | 69 | int setCount = m_series->count(); |
|
70 | 70 | |
|
71 | 71 | for (int s = 0; s < setCount; s++) { |
|
72 | 72 | QBoxSet *set = m_series->d_func()->boxSetAt(s); |
|
73 | 73 | |
|
74 | 74 | BoxWhiskers *box = m_boxTable.value(set); |
|
75 | 75 | if (!box) { |
|
76 | 76 | // Item is not yet created, make a box and add it to hash table |
|
77 | 77 | box = new BoxWhiskers(set, domain(), this); |
|
78 | 78 | m_boxTable.insert(set, box); |
|
79 | 79 | connect(box, SIGNAL(clicked(QBoxSet *)), m_series, SIGNAL(clicked(QBoxSet *))); |
|
80 | 80 | connect(box, SIGNAL(hovered(bool, QBoxSet *)), m_series, SIGNAL(hovered(bool, QBoxSet *))); |
|
81 | 81 | connect(box, SIGNAL(clicked(QBoxSet *)), set, SIGNAL(clicked())); |
|
82 | 82 | connect(box, SIGNAL(hovered(bool, QBoxSet *)), set, SIGNAL(hovered(bool))); |
|
83 | 83 | |
|
84 | 84 | // Set the decorative issues for the newly created box |
|
85 | box->setBrush(m_series->brush()); | |
|
86 | box->setPen(m_series->pen()); | |
|
85 | // so that the brush and pen already defined for the set are kept. | |
|
86 | if (set->brush() == Qt::NoBrush) | |
|
87 | box->setBrush(m_series->brush()); | |
|
88 | else | |
|
89 | box->setBrush(set->brush()); | |
|
90 | if (set->pen() == Qt::NoPen) | |
|
91 | box->setPen(m_series->pen()); | |
|
92 | else | |
|
93 | box->setPen(set->pen()); | |
|
87 | 94 | box->setBoxOutlined(m_series->boxOutlineVisible()); |
|
88 | 95 | box->setBoxWidth(m_series->boxWidth()); |
|
89 | 96 | } |
|
90 | 97 | updateBoxGeometry(box, s); |
|
91 | 98 | |
|
92 | 99 | box->updateGeometry(domain()); |
|
93 | 100 | |
|
94 | 101 | if (m_animation) |
|
95 | 102 | m_animation->addBox(box); |
|
96 | 103 | } |
|
97 | 104 | |
|
98 | 105 | handleDomainUpdated(); |
|
99 | 106 | } |
|
100 | 107 | |
|
101 | 108 | void BoxPlotChartItem::handleUpdatedBars() |
|
102 | 109 | { |
|
103 | 110 | foreach (BoxWhiskers *item, m_boxTable.values()) { |
|
104 | 111 | item->setBrush(m_series->brush()); |
|
105 | 112 | item->setPen(m_series->pen()); |
|
106 | 113 | item->setBoxOutlined(m_series->boxOutlineVisible()); |
|
107 | 114 | item->setBoxWidth(m_series->boxWidth()); |
|
108 | 115 | } |
|
109 | 116 | // Override with QBoxSet specific settings |
|
110 | 117 | foreach (QBoxSet *set, m_boxTable.keys()) { |
|
111 | 118 | if (set->brush().style() != Qt::NoBrush) |
|
112 | 119 | m_boxTable.value(set)->setBrush(set->brush()); |
|
113 | 120 | if (set->pen().style() != Qt::NoPen) |
|
114 | 121 | m_boxTable.value(set)->setPen(set->pen()); |
|
115 | 122 | } |
|
116 | 123 | } |
|
117 | 124 | |
|
118 | 125 | void BoxPlotChartItem::handleBoxsetRemove(QList<QBoxSet*> barSets) |
|
119 | 126 | { |
|
120 | 127 | foreach (QBoxSet *set, barSets) { |
|
121 | 128 | BoxWhiskers *boxItem = m_boxTable.value(set); |
|
122 | 129 | m_boxTable.remove(set); |
|
123 | 130 | delete boxItem; |
|
124 | 131 | } |
|
125 | 132 | } |
|
126 | 133 | |
|
127 | 134 | void BoxPlotChartItem::handleDomainUpdated() |
|
128 | 135 | { |
|
129 | 136 | if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0)) |
|
130 | 137 | return; |
|
131 | 138 | |
|
132 | 139 | // Set my bounding rect to same as domain size. Add one pixel at the top (-1.0) and the bottom as 0.0 would |
|
133 | 140 | // snip a bit off from the whisker at the grid line |
|
134 | 141 | m_boundingRect.setRect(0.0, -1.0, domain()->size().width(), domain()->size().height() + 1.0); |
|
135 | 142 | |
|
136 | 143 | foreach (BoxWhiskers *item, m_boxTable.values()) { |
|
137 | 144 | item->updateGeometry(domain()); |
|
138 | 145 | |
|
139 | 146 | // If the animation is set, start the animation for each BoxWhisker item |
|
140 | 147 | if (m_animation) |
|
141 | 148 | presenter()->startAnimation(m_animation->boxAnimation(item)); |
|
142 | 149 | } |
|
143 | 150 | } |
|
144 | 151 | |
|
145 | 152 | void BoxPlotChartItem::handleLayoutChanged() |
|
146 | 153 | { |
|
147 | 154 | foreach (BoxWhiskers *item, m_boxTable.values()) { |
|
148 | 155 | if (m_animation) |
|
149 | 156 | m_animation->setAnimationStart(item); |
|
150 | 157 | |
|
151 | 158 | item->setBoxWidth(m_series->boxWidth()); |
|
152 | 159 | |
|
153 | 160 | bool dirty = updateBoxGeometry(item, item->m_data.m_index); |
|
154 | 161 | if (dirty && m_animation) |
|
155 | 162 | presenter()->startAnimation(m_animation->boxChangeAnimation(item)); |
|
156 | 163 | else |
|
157 | 164 | item->updateGeometry(domain()); |
|
158 | 165 | } |
|
159 | 166 | } |
|
160 | 167 | |
|
161 | 168 | QRectF BoxPlotChartItem::boundingRect() const |
|
162 | 169 | { |
|
163 | 170 | return m_boundingRect; |
|
164 | 171 | } |
|
165 | 172 | |
|
166 | 173 | void BoxPlotChartItem::initializeLayout() |
|
167 | 174 | { |
|
168 | 175 | } |
|
169 | 176 | |
|
170 | 177 | QVector<QRectF> BoxPlotChartItem::calculateLayout() |
|
171 | 178 | { |
|
172 | 179 | return QVector<QRectF>(); |
|
173 | 180 | } |
|
174 | 181 | |
|
175 | 182 | bool BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index) |
|
176 | 183 | { |
|
177 | 184 | bool changed = false; |
|
178 | 185 | |
|
179 | 186 | QBoxSet *set = m_series->d_func()->boxSetAt(index); |
|
180 | 187 | BoxWhiskersData &data = box->m_data; |
|
181 | 188 | |
|
182 | 189 | if ((data.m_lowerExtreme != set->at(0)) || (data.m_lowerQuartile != set->at(1)) || |
|
183 | 190 | (data.m_median != set->at(2)) || (data.m_upperQuartile != set->at(3)) || (data.m_upperExtreme != set->at(4))) { |
|
184 | 191 | changed = true; |
|
185 | 192 | } |
|
186 | 193 | |
|
187 | 194 | data.m_lowerExtreme = set->at(0); |
|
188 | 195 | data.m_lowerQuartile = set->at(1); |
|
189 | 196 | data.m_median = set->at(2); |
|
190 | 197 | data.m_upperQuartile = set->at(3); |
|
191 | 198 | data.m_upperExtreme = set->at(4); |
|
192 | 199 | data.m_index = index; |
|
193 | 200 | data.m_boxItems = m_series->count(); |
|
194 | 201 | |
|
195 | 202 | data.m_maxX = domain()->maxX(); |
|
196 | 203 | data.m_minX = domain()->minX(); |
|
197 | 204 | data.m_maxY = domain()->maxY(); |
|
198 | 205 | data.m_minY = domain()->minY(); |
|
199 | 206 | |
|
200 | 207 | data.m_seriesIndex = m_seriesIndex; |
|
201 | 208 | data.m_seriesCount = m_seriesCount; |
|
202 | 209 | |
|
203 | 210 | return changed; |
|
204 | 211 | } |
|
205 | 212 | |
|
206 | 213 | #include "moc_boxplotchartitem_p.cpp" |
|
207 | 214 | |
|
208 | 215 | QTCOMMERCIALCHART_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now