##// END OF EJS Templates
Fix label clipping issues using QOpenGLWidget as ChartView viewport...
Miikka Heikkinen -
r2828:7557d1ea51b5
parent child
Show More
@@ -141,9 +141,10 void HorizontalAxis::updateGeometry()
141 qreal widthDiff = rect.width() - boundingRect.width();
141 qreal widthDiff = rect.width() - boundingRect.width();
142
142
143 //ticks and label position
143 //ticks and label position
144 QPointF labelPos;
144 if (axis()->alignment() == Qt::AlignTop) {
145 if (axis()->alignment() == Qt::AlignTop) {
145 if (axis()->isReverse()) {
146 if (axis()->isReverse()) {
146 labelItem->setPos(gridRect.right() - layout[layout.size() - i - 1]
147 labelPos = QPointF(gridRect.right() - layout[layout.size() - i - 1]
147 + gridRect.left() - center.x(),
148 + gridRect.left() - center.x(),
148 axisRect.bottom() - rect.height()
149 axisRect.bottom() - rect.height()
149 + (heightDiff / 2.0) - labelPadding());
150 + (heightDiff / 2.0) - labelPadding());
@@ -152,21 +153,21 void HorizontalAxis::updateGeometry()
152 gridRect.right() + gridRect.left() - layout[i],
153 gridRect.right() + gridRect.left() - layout[i],
153 axisRect.bottom() - labelPadding());
154 axisRect.bottom() - labelPadding());
154 } else {
155 } else {
155 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height()
156 labelPos = QPointF(layout[i] - center.x(), axisRect.bottom() - rect.height()
156 + (heightDiff / 2.0) - labelPadding());
157 + (heightDiff / 2.0) - labelPadding());
157 tickItem->setLine(layout[i], axisRect.bottom(),
158 tickItem->setLine(layout[i], axisRect.bottom(),
158 layout[i], axisRect.bottom() - labelPadding());
159 layout[i], axisRect.bottom() - labelPadding());
159 }
160 }
160 } else if (axis()->alignment() == Qt::AlignBottom) {
161 } else if (axis()->alignment() == Qt::AlignBottom) {
161 if (axis()->isReverse()) {
162 if (axis()->isReverse()) {
162 labelItem->setPos(gridRect.right() - layout[layout.size() - i - 1]
163 labelPos = QPointF(gridRect.right() - layout[layout.size() - i - 1]
163 + gridRect.left() - center.x(),
164 + gridRect.left() - center.x(),
164 axisRect.top() - (heightDiff / 2.0) + labelPadding());
165 axisRect.top() - (heightDiff / 2.0) + labelPadding());
165 tickItem->setLine(gridRect.right() + gridRect.left() - layout[i], axisRect.top(),
166 tickItem->setLine(gridRect.right() + gridRect.left() - layout[i], axisRect.top(),
166 gridRect.right() + gridRect.left() - layout[i],
167 gridRect.right() + gridRect.left() - layout[i],
167 axisRect.top() + labelPadding());
168 axisRect.top() + labelPadding());
168 } else {
169 } else {
169 labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0)
170 labelPos = QPointF(layout[i] - center.x(), axisRect.top() - (heightDiff / 2.0)
170 + labelPadding());
171 + labelPadding());
171 tickItem->setLine(layout[i], axisRect.top(),
172 tickItem->setLine(layout[i], axisRect.top(),
172 layout[i], axisRect.top() + labelPadding());
173 layout[i], axisRect.top() + labelPadding());
@@ -193,7 +194,7 void HorizontalAxis::updateGeometry()
193 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
194 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
194 forceHide = true;
195 forceHide = true;
195 } else {
196 } else {
196 labelItem->setPos(leftBound + (delta / 2.0) - center.x(), labelItem->pos().y());
197 labelPos.setX(leftBound + (delta / 2.0) - center.x());
197 }
198 }
198 } else {
199 } else {
199 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
200 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
@@ -202,19 +203,21 void HorizontalAxis::updateGeometry()
202 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
203 && (leftBound == gridRect.left() || rightBound == gridRect.right())) {
203 forceHide = true;
204 forceHide = true;
204 } else {
205 } else {
205 labelItem->setPos(leftBound + (delta / 2.0) - center.x(),
206 labelPos.setX(leftBound + (delta / 2.0) - center.x());
206 labelItem->pos().y());
207 }
207 }
208 } else if (categoryAxis->labelsPosition()
208 } else if (categoryAxis->labelsPosition()
209 == QCategoryAxis::AxisLabelsPositionOnValue) {
209 == QCategoryAxis::AxisLabelsPositionOnValue) {
210 if (axis()->isReverse())
210 if (axis()->isReverse())
211 labelItem->setPos(leftBound - center.x(), labelItem->pos().y());
211 labelPos.setX(leftBound - center.x());
212 else
212 else
213 labelItem->setPos(rightBound - center.x(), labelItem->pos().y());
213 labelPos.setX(rightBound - center.x());
214 }
214 }
215 }
215 }
216 }
216 }
217
217
218 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
219 labelItem->setPos(labelPos.toPoint());
220
218 //label overlap detection - compensate one pixel for rounding errors
221 //label overlap detection - compensate one pixel for rounding errors
219 if ((labelItem->pos().x() < width && labelItem->toPlainText() == ellipsis) || forceHide ||
222 if ((labelItem->pos().x() < width && labelItem->toPlainText() == ellipsis) || forceHide ||
220 (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) ||
223 (labelItem->pos().x() + (widthDiff / 2.0)) < (axisRect.left() - 1.0) ||
@@ -143,9 +143,10 void VerticalAxis::updateGeometry()
143 qreal heightDiff = rect.height() - boundingRect.height();
143 qreal heightDiff = rect.height() - boundingRect.height();
144
144
145 //ticks and label position
145 //ticks and label position
146 QPointF labelPos;
146 if (axis()->alignment() == Qt::AlignLeft) {
147 if (axis()->alignment() == Qt::AlignLeft) {
147 if (axis()->isReverse()) {
148 if (axis()->isReverse()) {
148 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0)
149 labelPos = QPointF(axisRect.right() - rect.width() + (widthDiff / 2.0)
149 - labelPadding(),
150 - labelPadding(),
150 gridRect.top() + gridRect.bottom()
151 gridRect.top() + gridRect.bottom()
151 - layout[layout.size() - i - 1] - center.y());
152 - layout[layout.size() - i - 1] - center.y());
@@ -154,7 +155,7 void VerticalAxis::updateGeometry()
154 axisRect.right(),
155 axisRect.right(),
155 gridRect.top() + gridRect.bottom() - layout[i]);
156 gridRect.top() + gridRect.bottom() - layout[i]);
156 } else {
157 } else {
157 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0)
158 labelPos = QPointF(axisRect.right() - rect.width() + (widthDiff / 2.0)
158 - labelPadding(),
159 - labelPadding(),
159 layout[i] - center.y());
160 layout[i] - center.y());
160 tickItem->setLine(axisRect.right() - labelPadding(), layout[i],
161 tickItem->setLine(axisRect.right() - labelPadding(), layout[i],
@@ -166,11 +167,11 void VerticalAxis::updateGeometry()
166 gridRect.top() + gridRect.bottom() - layout[i],
167 gridRect.top() + gridRect.bottom() - layout[i],
167 axisRect.left() + labelPadding(),
168 axisRect.left() + labelPadding(),
168 gridRect.top() + gridRect.bottom() - layout[i]);
169 gridRect.top() + gridRect.bottom() - layout[i]);
169 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0),
170 labelPos = QPointF(axisRect.left() + labelPadding() - (widthDiff / 2.0),
170 gridRect.top() + gridRect.bottom()
171 gridRect.top() + gridRect.bottom()
171 - layout[layout.size() - i - 1] - center.y());
172 - layout[layout.size() - i - 1] - center.y());
172 } else {
173 } else {
173 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0),
174 labelPos = QPointF(axisRect.left() + labelPadding() - (widthDiff / 2.0),
174 layout[i] - center.y());
175 layout[i] - center.y());
175 tickItem->setLine(axisRect.left(), layout[i],
176 tickItem->setLine(axisRect.left(), layout[i],
176 axisRect.left() + labelPadding(), layout[i]);
177 axisRect.left() + labelPadding(), layout[i]);
@@ -199,8 +200,7 void VerticalAxis::updateGeometry()
199 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
200 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
200 forceHide = true;
201 forceHide = true;
201 } else {
202 } else {
202 labelItem->setPos(labelItem->pos().x(),
203 labelPos.setY(lowerBound - (delta / 2.0) - center.y());
203 lowerBound - (delta / 2.0) - center.y());
204 }
204 }
205 } else {
205 } else {
206 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
206 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
@@ -209,22 +209,24 void VerticalAxis::updateGeometry()
209 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
209 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
210 forceHide = true;
210 forceHide = true;
211 } else {
211 } else {
212 labelItem->setPos(labelItem->pos().x(),
212 labelPos.setY(lowerBound - (delta / 2.0) - center.y());
213 lowerBound - (delta / 2.0) - center.y());
214 }
213 }
215 } else if (categoryAxis->labelsPosition()
214 } else if (categoryAxis->labelsPosition()
216 == QCategoryAxis::AxisLabelsPositionOnValue) {
215 == QCategoryAxis::AxisLabelsPositionOnValue) {
217 labelOnValue = true;
216 labelOnValue = true;
218 if (axis()->isReverse()) {
217 if (axis()->isReverse()) {
219 labelItem->setPos(labelItem->pos().x(), gridRect.top() + gridRect.bottom()
218 labelPos.setY(gridRect.top() + gridRect.bottom()
220 - layout[i + 1] - center.y());
219 - layout[i + 1] - center.y());
221 } else {
220 } else {
222 labelItem->setPos(labelItem->pos().x(), upperBound - center.y());
221 labelPos.setY(upperBound - center.y());
223 }
222 }
224 }
223 }
225 }
224 }
226 }
225 }
227
226
227 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
228 labelItem->setPos(labelPos.toPoint());
229
228 //label overlap detection - compensate one pixel for rounding errors
230 //label overlap detection - compensate one pixel for rounding errors
229 if (axis()->isReverse()) {
231 if (axis()->isReverse()) {
230 if (forceHide)
232 if (forceHide)
@@ -156,7 +156,9 QRectF AbstractChartLayout::calculateLegendMinimum(const QRectF &geometry, QLege
156 QRectF AbstractChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
156 QRectF AbstractChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
157 {
157 {
158 title->setGeometry(geometry);
158 title->setGeometry(geometry);
159 QPointF center = geometry.center() - title->boundingRect().center();
159 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
160 QPointF center((geometry.center() - title->boundingRect().center()).toPoint());
161
160 title->setPos(center.x(), title->pos().y());
162 title->setPos(center.x(), title->pos().y());
161 return geometry.adjusted(0, title->boundingRect().height()+1, 0, 0);
163 return geometry.adjusted(0, title->boundingRect().height()+1, 0, 0);
162 }
164 }
@@ -233,10 +233,13 void LegendLayout::setAttachedGeometry(const QRectF &rect)
233 // Delete structs from the container
233 // Delete structs from the container
234 qDeleteAll(legendWidthList);
234 qDeleteAll(legendWidthList);
235
235
236 if (m_width < geometry.width())
236 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
237 m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
237 if (m_width < geometry.width()) {
238 else
238 m_legend->d_ptr->items()->setPos(QPoint(geometry.width() / 2 - m_width / 2,
239 m_legend->d_ptr->items()->setPos(geometry.topLeft());
239 geometry.top()));
240 } else {
241 m_legend->d_ptr->items()->setPos(geometry.topLeft().toPoint());
242 }
240 m_height = size.height();
243 m_height = size.height();
241 }
244 }
242 break;
245 break;
@@ -262,10 +265,13 void LegendLayout::setAttachedGeometry(const QRectF &rect)
262 }
265 }
263 }
266 }
264
267
265 if (m_height < geometry.height())
268 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
266 m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2);
269 if (m_height < geometry.height()) {
267 else
270 m_legend->d_ptr->items()->setPos(QPoint(geometry.left(),
268 m_legend->d_ptr->items()->setPos(geometry.topLeft());
271 geometry.height() / 2 - m_height / 2));
272 } else {
273 m_legend->d_ptr->items()->setPos(geometry.topLeft().toPoint());
274 }
269 m_width = size.width();
275 m_width = size.width();
270 break;
276 break;
271 }
277 }
@@ -3,7 +3,6
3 }
3 }
4 include(charts/charts.pri)
4 include(charts/charts.pri)
5 TARGET = chartviewer
5 TARGET = chartviewer
6 QT += opengl
7 INCLUDEPATH += .
6 INCLUDEPATH += .
8 SOURCES += main.cpp window.cpp view.cpp grid.cpp
7 SOURCES += main.cpp window.cpp view.cpp grid.cpp
9 HEADERS += window.h view.h charts.h model.h grid.h
8 HEADERS += window.h view.h charts.h model.h grid.h
@@ -34,7 +34,7
34 #include <QtWidgets/QGraphicsScene>
34 #include <QtWidgets/QGraphicsScene>
35 #include <QtWidgets/QGraphicsLinearLayout>
35 #include <QtWidgets/QGraphicsLinearLayout>
36 #include <QtWidgets/QGraphicsProxyWidget>
36 #include <QtWidgets/QGraphicsProxyWidget>
37 #include <QtOpenGL/QGLWidget>
37 #include <QtWidgets/QOpenGLWidget>
38 #include <QtWidgets/QApplication>
38 #include <QtWidgets/QApplication>
39 #include <QtCore/QDebug>
39 #include <QtCore/QDebug>
40 #include <QtWidgets/QMenu>
40 #include <QtWidgets/QMenu>
@@ -398,11 +398,11 void Window::checkLegend()
398 void Window::checkOpenGL()
398 void Window::checkOpenGL()
399 {
399 {
400 bool opengl = m_openGLCheckBox->isChecked();
400 bool opengl = m_openGLCheckBox->isChecked();
401 bool isOpengl = qobject_cast<QGLWidget *>(m_view->viewport());
401 bool isOpengl = qobject_cast<QOpenGLWidget *>(m_view->viewport());
402 if ((isOpengl && !opengl) || (!isOpengl && opengl)) {
402 if ((isOpengl && !opengl) || (!isOpengl && opengl)) {
403 m_view->deleteLater();
403 m_view->deleteLater();
404 m_view = new View(m_scene, m_form);
404 m_view = new View(m_scene, m_form);
405 m_view->setViewport(!opengl ? new QWidget() : new QGLWidget());
405 m_view->setViewport(!opengl ? new QWidget() : new QOpenGLWidget());
406 setCentralWidget(m_view);
406 setCentralWidget(m_view);
407 }
407 }
408
408
@@ -4,7 +4,7
4
4
5 TEMPLATE = app
5 TEMPLATE = app
6
6
7 QT += core gui opengl widgets
7 QT += core gui widgets
8
8
9 SOURCES += main.cpp \
9 SOURCES += main.cpp \
10 mainwidget.cpp \
10 mainwidget.cpp \
@@ -41,7 +41,7
41 #include <QtCore/QDebug>
41 #include <QtCore/QDebug>
42 #include <QtGui/QStandardItemModel>
42 #include <QtGui/QStandardItemModel>
43 #include <QtCharts/QBarCategoryAxis>
43 #include <QtCharts/QBarCategoryAxis>
44 #include <QtOpenGL/QGLWidget>
44 #include <QtWidgets/QOpenGLWidget>
45
45
46 QT_CHARTS_USE_NAMESPACE
46 QT_CHARTS_USE_NAMESPACE
47
47
@@ -164,7 +164,7 void MainWidget::initCheckboxes(QGridLayout *grid)
164 aliasCheckBox->setChecked(false);
164 aliasCheckBox->setChecked(false);
165 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
165 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
166
166
167 QCheckBox *openGLCheckBox = new QCheckBox("Use QGLWidget");
167 QCheckBox *openGLCheckBox = new QCheckBox("Use QOpenGLWidget");
168 connect(openGLCheckBox, SIGNAL(toggled(bool)), this, SLOT(openGLToggled(bool)));
168 connect(openGLCheckBox, SIGNAL(toggled(bool)), this, SLOT(openGLToggled(bool)));
169 openGLCheckBox->setChecked(false);
169 openGLCheckBox->setChecked(false);
170 grid->addWidget(openGLCheckBox, grid->rowCount(), 0);
170 grid->addWidget(openGLCheckBox, grid->rowCount(), 0);
@@ -178,11 +178,10 void MainWidget::antiAliasToggled(bool enabled)
178 void MainWidget::openGLToggled(bool enabled)
178 void MainWidget::openGLToggled(bool enabled)
179 {
179 {
180 if (enabled) {
180 if (enabled) {
181 QGLFormat f = QGLFormat::defaultFormat();
181 QSurfaceFormat f = QSurfaceFormat::defaultFormat();
182 f.setSampleBuffers(true);
183 f.setSamples(4);
182 f.setSamples(4);
184 QGLFormat::setDefaultFormat(f);
183 QSurfaceFormat::setDefaultFormat(f);
185 QGLWidget *g = new QGLWidget();
184 QOpenGLWidget *g = new QOpenGLWidget();
186 m_chartView->setViewport(g);
185 m_chartView->setViewport(g);
187 } else {
186 } else {
188 m_chartView->setViewport(0);
187 m_chartView->setViewport(0);
@@ -19,7 +19,7
19 #include "wavechart.h"
19 #include "wavechart.h"
20 #include <QtWidgets/QApplication>
20 #include <QtWidgets/QApplication>
21 #include <QtWidgets/QMainWindow>
21 #include <QtWidgets/QMainWindow>
22 #include <QtOpenGL/QGLWidget>
22 #include <QtWidgets/QOpenGLWidget>
23
23
24 int main(int argc, char *argv[])
24 int main(int argc, char *argv[])
25 {
25 {
@@ -29,7 +29,7 int main(int argc, char *argv[])
29 QChart *chart = new QChart();
29 QChart *chart = new QChart();
30 WaveChart *waveChart = new WaveChart(chart,&window);
30 WaveChart *waveChart = new WaveChart(chart,&window);
31
31
32 waveChart->setViewport( new QGLWidget() );
32 waveChart->setViewport( new QOpenGLWidget() );
33 waveChart->setRenderHint(QPainter::Antialiasing);
33 waveChart->setRenderHint(QPainter::Antialiasing);
34 chart->setAnimationOptions(QChart::AllAnimations);
34 chart->setAnimationOptions(QChart::AllAnimations);
35 chart->setTitle("This is wave generator.");
35 chart->setTitle("This is wave generator.");
@@ -2,7 +2,6
2 error( "Couldn't find the test.pri file!" )
2 error( "Couldn't find the test.pri file!" )
3 }
3 }
4
4
5 QT+=opengl
6 TARGET = wavechart
5 TARGET = wavechart
7 SOURCES += main.cpp wavechart.cpp
6 SOURCES += main.cpp wavechart.cpp
8 HEADERS += wavechart.h
7 HEADERS += wavechart.h
General Comments 0
You need to be logged in to leave comments. Login now