From bd26609a29aeefba9a11fc86c345f08ac8a088b7 2012-12-07 10:41:38 From: Marek Rosa Date: 2012-12-07 10:41:38 Subject: [PATCH] QChart mapping functions: return QPoint(0, 0) if series type is Pie Some QLogValueAxis tests added. Most commented out. LogDomain correctly move, zoomin and zoomout when log base is less than 1 --- diff --git a/examples/callout/view.cpp b/examples/callout/view.cpp index be3ec13..9e2c328 100644 --- a/examples/callout/view.cpp +++ b/examples/callout/view.cpp @@ -41,7 +41,7 @@ View::View(QWidget *parent) // chart m_chart = new QChart; - m_chart->setMinimumSize(800, 600); + m_chart->setMinimumSize(640, 480); m_chart->setTitle("Hover the line to show callout. Click the line to make it stay"); m_chart->legend()->hide(); QLineSeries *series = new QLineSeries; @@ -84,8 +84,12 @@ View::View(QWidget *parent) void View::resizeEvent(QResizeEvent *event) { - if (scene()) + if (scene()) { scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); + m_chart->resize(event->size()); + m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height() - 20); + m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height() - 20); + } QGraphicsView::resizeEvent(event); } diff --git a/src/chartdataset.cpp b/src/chartdataset.cpp index 8323248..11adfe6 100644 --- a/src/chartdataset.cpp +++ b/src/chartdataset.cpp @@ -391,8 +391,11 @@ QPointF ChartDataSet::mapToValue(const QPointF &position, QAbstractSeries *serie if (series == 0 && !m_seriesList.isEmpty()) series = m_seriesList.first(); + if (series && series->type() == QAbstractSeries::SeriesTypePie) + return point; + if (series && m_seriesList.contains(series)) - point = series->d_ptr->m_domain->calculateDomainPoint(position); + point = series->d_ptr->m_domain->calculateDomainPoint(position - m_chart->plotArea().topLeft()); return point; } @@ -402,6 +405,9 @@ QPointF ChartDataSet::mapToPosition(const QPointF &value, QAbstractSeries *serie if (series == 0 && !m_seriesList.isEmpty()) series = m_seriesList.first(); + if (series && series->type() == QAbstractSeries::SeriesTypePie) + return QPoint(0, 0); + if (series && m_seriesList.contains(series)) point += series->d_ptr->m_domain->calculateGeometryPoint(value); return point; diff --git a/src/domain/logxlogydomain.cpp b/src/domain/logxlogydomain.cpp index 37f6273..0d98306 100644 --- a/src/domain/logxlogydomain.cpp +++ b/src/domain/logxlogydomain.cpp @@ -27,11 +27,11 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE LogXLogYDomain::LogXLogYDomain(QObject *parent) : AbstractDomain(parent), - m_logMinX(0), - m_logMaxX(1), + m_logLeftX(0), + m_logRightX(1), m_logBaseX(10), - m_logMinY(0), - m_logMaxY(1), + m_logLeftY(0), + m_logRightY(1), m_logBaseY(10) { } @@ -49,8 +49,10 @@ void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) m_minX = minX; m_maxX = maxX; axisXChanged = true; - m_logMinX = log10(m_minX) / log10(m_logBaseX); - m_logMaxX = log10(m_maxX) / log10(m_logBaseX); + qreal logMinX = log10(m_minX) / log10(m_logBaseX); + qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); + m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; + m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; if(!m_signalsBlocked) emit rangeHorizontalChanged(m_minX, m_maxX); } @@ -59,8 +61,10 @@ void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) m_minY = minY; m_maxY = maxY; axisYChanged = true; - m_logMinY = log10(m_minY) / log10(m_logBaseY); - m_logMaxY = log10(m_maxY) / log10(m_logBaseY); + qreal logMinY = log10(m_minY) / log10(m_logBaseY); + qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); + m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; + m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; if(!m_signalsBlocked) emit rangeVerticalChanged(m_minY, m_maxY); } @@ -71,73 +75,82 @@ void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) void LogXLogYDomain::zoomIn(const QRectF &rect) { - qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX; - qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX; - qreal minX = qPow(m_logBaseX, newLogMinX); - qreal maxX = qPow(m_logBaseX, newLogMaxX); + qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; + qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; + qreal leftX = qPow(m_logBaseX, logLeftX); + qreal rightX = qPow(m_logBaseX, logRightX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; - qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height(); - qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height(); - qreal minY = qPow(m_logBaseY, newLogMinY); - qreal maxY = qPow(m_logBaseY, newLogMaxY); + qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); + qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); + qreal leftY = qPow(m_logBaseY, logLeftY); + qreal rightY = qPow(m_logBaseY, logRightY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } void LogXLogYDomain::zoomOut(const QRectF &rect) { - qreal ratioX = m_size.width()/rect.width(); - qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX; - qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX; - qreal minX = qPow(m_logBaseX, newLogMinX); - qreal maxX = qPow(m_logBaseX, newLogMaxX); + const qreal factorX = m_size.width() / rect.width(); + const qreal factorY = m_size.height() / rect.height(); - qreal ratioY = m_size.height()/rect.height(); - qreal newLogMinY = m_logMinY - (m_logMaxY - m_logMinY) / ratioY; - qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY; - qreal minY = qPow(m_logBaseY, newLogMinY); - qreal maxY = qPow(m_logBaseY, newLogMaxY); + qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); + qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); + qreal leftX = qPow(m_logBaseX, logLeftX); + qreal rightX = qPow(m_logBaseX, logRIghtX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; + + qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); + qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); + qreal leftY = qPow(m_logBaseY, newLogMinY); + qreal rightY = qPow(m_logBaseY, newLogMaxY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } void LogXLogYDomain::move(qreal dx, qreal dy) { - qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width(); - qreal minX = qPow(m_logBaseX, m_logMinX + stepX); - qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX); + qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width(); + qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); + qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; - qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height(); - qreal minY = qPow(m_logBaseY, m_logMinY + stepY); - qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY); + qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); + qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); + qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const { - const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); - qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX; - qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height(); + const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); + qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; + qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); return QPointF(x, y); } QVector LogXLogYDomain::calculateGeometryPoints(const QList& vector) const { - const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); + const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); QVector result; result.resize(vector.count()); for (int i = 0; i < vector.count(); ++i) { - qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX; - qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height(); + qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; + qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); result[i].setX(x); result[i].setY(y); } @@ -146,12 +159,10 @@ QVector LogXLogYDomain::calculateGeometryPoints(const QList& v QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const { - const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); - qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX); - qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY); + const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); + qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); + qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); return QPointF(x, y); } @@ -190,16 +201,20 @@ bool LogXLogYDomain::detachAxis(QAbstractAxis* axis) void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) { m_logBaseY = baseY; - m_logMinY = log10(m_minY) / log10(m_logBaseY); - m_logMaxY = log10(m_maxY) / log10(m_logBaseY); + qreal logMinY = log10(m_minY) / log10(m_logBaseY); + qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); + m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; + m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; emit updated(); } void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX) { m_logBaseX = baseX; - m_logMinX = log10(m_minX) / log10(m_logBaseX); - m_logMaxX = log10(m_maxX) / log10(m_logBaseX); + qreal logMinX = log10(m_minX) / log10(m_logBaseX); + qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); + m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; + m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; emit updated(); } diff --git a/src/domain/logxlogydomain_p.h b/src/domain/logxlogydomain_p.h index 32f9e75..0b7b22b 100644 --- a/src/domain/logxlogydomain_p.h +++ b/src/domain/logxlogydomain_p.h @@ -66,11 +66,11 @@ public Q_SLOTS: void handleHorizontalAxisBaseChanged(qreal baseX); private: - qreal m_logMinX; - qreal m_logMaxX; + qreal m_logLeftX; + qreal m_logRightX; qreal m_logBaseX; - qreal m_logMinY; - qreal m_logMaxY; + qreal m_logLeftY; + qreal m_logRightY; qreal m_logBaseY; }; diff --git a/src/domain/logxydomain.cpp b/src/domain/logxydomain.cpp index fd46e66..dca581c 100644 --- a/src/domain/logxydomain.cpp +++ b/src/domain/logxydomain.cpp @@ -27,8 +27,8 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE LogXYDomain::LogXYDomain(QObject *parent) : AbstractDomain(parent), - m_logMinX(0), - m_logMaxX(1), + m_logLeftX(0), + m_logRightX(1), m_logBaseX(10) { } @@ -46,8 +46,10 @@ void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) m_minX = minX; m_maxX = maxX; axisXChanged = true; - m_logMinX = log10(m_minX) / log10(m_logBaseX); - m_logMaxX = log10(m_maxX) / log10(m_logBaseX); + qreal logMinX = log10(m_minX) / log10(m_logBaseX); + qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); + m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; + m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; if(!m_signalsBlocked) emit rangeHorizontalChanged(m_minX, m_maxX); } @@ -66,10 +68,12 @@ void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) void LogXYDomain::zoomIn(const QRectF &rect) { - qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX; - qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX; - qreal minX = qPow(m_logBaseX, newLogMinX); - qreal maxX = qPow(m_logBaseX, newLogMaxX); + qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; + qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; + qreal leftX = qPow(m_logBaseX, logLeftX); + qreal rightX = qPow(m_logBaseX, logRightX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; qreal dy = spanY() / m_size.height(); qreal minY = m_minY; @@ -83,11 +87,14 @@ void LogXYDomain::zoomIn(const QRectF &rect) void LogXYDomain::zoomOut(const QRectF &rect) { - qreal ratioX = m_size.width()/rect.width(); - qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX; - qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX; - qreal minX = qPow(m_logBaseX, newLogMinX); - qreal maxX = qPow(m_logBaseX, newLogMaxX); + const qreal factorX = m_size.width() / rect.width(); + + qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); + qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); + qreal leftX = qPow(m_logBaseX, logLeftX); + qreal rightX = qPow(m_logBaseX, logRIghtX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; qreal dy = spanY() / rect.height(); qreal minY = m_minY; @@ -101,9 +108,11 @@ void LogXYDomain::zoomOut(const QRectF &rect) void LogXYDomain::move(qreal dx, qreal dy) { - qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width(); - qreal minX = qPow(m_logBaseX, m_logMinX + stepX); - qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX); + qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); + qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); + qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); + qreal minX = leftX < rightX ? leftX : rightX; + qreal maxX = leftX > rightX ? leftX : rightX; qreal y = spanY() / m_size.height(); qreal minY = m_minY; @@ -118,26 +127,24 @@ void LogXYDomain::move(qreal dx, qreal dy) QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const { - const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); + const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); const qreal deltaY = m_size.height() / (m_maxY - m_minY); - qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX; + qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; qreal y = (point.y() - m_minY) * -deltaY + m_size.height(); return QPointF(x, y); } QVector LogXYDomain::calculateGeometryPoints(const QList& vector) const { - const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); + const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); const qreal deltaY = m_size.height() / (m_maxY - m_minY); QVector result; result.resize(vector.count()); for (int i = 0; i < vector.count(); ++i) { - qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX; + qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height(); result[i].setX(x); result[i].setY(y); @@ -147,10 +154,9 @@ QVector LogXYDomain::calculateGeometryPoints(const QList& vect QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const { - const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX; - const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX); + const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); const qreal deltaY = m_size.height() / (m_maxY - m_minY); - qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX); + qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY; return QPointF(x, y); } @@ -182,8 +188,10 @@ bool LogXYDomain::detachAxis(QAbstractAxis* axis) void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX) { m_logBaseX = baseX; - m_logMinX = log10(m_minX) / log10(m_logBaseX); - m_logMaxX = log10(m_maxX) / log10(m_logBaseX); + qreal logMinX = log10(m_minX) / log10(m_logBaseX); + qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); + m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; + m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; emit updated(); } diff --git a/src/domain/logxydomain_p.h b/src/domain/logxydomain_p.h index 91a55e3..c127d13 100644 --- a/src/domain/logxydomain_p.h +++ b/src/domain/logxydomain_p.h @@ -65,8 +65,8 @@ public Q_SLOTS: void handleHorizontalAxisBaseChanged(qreal baseX); private: - qreal m_logMinX; - qreal m_logMaxX; + qreal m_logLeftX; + qreal m_logRightX; qreal m_logBaseX; }; diff --git a/src/domain/xlogydomain.cpp b/src/domain/xlogydomain.cpp index 28f9952..61ae88d 100644 --- a/src/domain/xlogydomain.cpp +++ b/src/domain/xlogydomain.cpp @@ -27,8 +27,8 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE XLogYDomain::XLogYDomain(QObject *parent) : AbstractDomain(parent), - m_logMinY(0), - m_logMaxY(1), + m_logLeftY(0), + m_logRightY(1), m_logBaseY(10) { } @@ -54,8 +54,10 @@ void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) m_minY = minY; m_maxY = maxY; axisYChanged = true; - m_logMinY = log10(m_minY) / log10(m_logBaseY); - m_logMaxY = log10(m_maxY) / log10(m_logBaseY); + qreal logMinY = log10(m_minY) / log10(m_logBaseY); + qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); + m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; + m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; if(!m_signalsBlocked) emit rangeVerticalChanged(m_minY, m_maxY); } @@ -73,10 +75,12 @@ void XLogYDomain::zoomIn(const QRectF &rect) maxX = minX + dx * rect.right(); minX = minX + dx * rect.left(); - qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height(); - qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height(); - qreal minY = qPow(m_logBaseY, newLogMinY); - qreal maxY = qPow(m_logBaseY, newLogMaxY); + qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); + qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); + qreal leftY = qPow(m_logBaseY, logLeftY); + qreal rightY = qPow(m_logBaseY, logRightY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } @@ -90,11 +94,13 @@ void XLogYDomain::zoomOut(const QRectF &rect) minX = maxX - dx * rect.right(); maxX = minX + dx * m_size.width(); - qreal ratioY = m_size.height()/rect.height(); - qreal newLogMinY = m_logMinY - (m_logMaxY - m_logMinY) / ratioY; - qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY; - qreal minY = qPow(m_logBaseY, newLogMinY); - qreal maxY = qPow(m_logBaseY, newLogMaxY); + const qreal factorY = m_size.height() / rect.height(); + qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); + qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); + qreal leftY = qPow(m_logBaseY, newLogMinY); + qreal rightY = qPow(m_logBaseY, newLogMaxY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } @@ -110,36 +116,36 @@ void XLogYDomain::move(qreal dx, qreal dy) maxX = maxX + x * dx; } - qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height(); - qreal minY = qPow(m_logBaseY, m_logMinY + stepY); - qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY); + qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); + qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); + qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); + qreal minY = leftY < rightY ? leftY : rightY; + qreal maxY = leftY > rightY ? leftY : rightY; setRange(minX, maxX, minY, maxY); } QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const { - const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; const qreal deltaX = m_size.width() / (m_maxX - m_minX); - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); qreal x = (point.x() - m_minX) * deltaX; - qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height(); + qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); return QPointF(x, y); } QVector XLogYDomain::calculateGeometryPoints(const QList& vector) const { - const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; const qreal deltaX = m_size.width() / (m_maxX - m_minX); - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); QVector result; result.resize(vector.count()); for (int i = 0; i < vector.count(); ++i) { qreal x = (vector[i].x() - m_minX) * deltaX; - qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height(); + qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); result[i].setX(x); result[i].setY(y); } @@ -149,10 +155,9 @@ QVector XLogYDomain::calculateGeometryPoints(const QList& vect QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const { const qreal deltaX = m_size.width() / (m_maxX - m_minX); - const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY; - const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY); + const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); qreal x = point.x() / deltaX + m_minX; - qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY); + qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); return QPointF(x, y); } @@ -180,8 +185,10 @@ bool XLogYDomain::detachAxis(QAbstractAxis* axis) void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) { m_logBaseY = baseY; - m_logMinY = log10(m_minY) / log10(m_logBaseY); - m_logMaxY = log10(m_maxY) / log10(m_logBaseY); + qreal logMinY = log10(m_minY) / log10(m_logBaseY); + qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); + m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; + m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; emit updated(); } diff --git a/src/domain/xlogydomain_p.h b/src/domain/xlogydomain_p.h index e39daaf..c13ea36 100644 --- a/src/domain/xlogydomain_p.h +++ b/src/domain/xlogydomain_p.h @@ -65,8 +65,8 @@ public Q_SLOTS: void handleVerticalAxisBaseChanged(qreal baseY); private: - qreal m_logMinY; - qreal m_logMaxY; + qreal m_logLeftY; + qreal m_logRightY; qreal m_logBaseY; }; diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 6724982..18c6b8d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -21,6 +21,7 @@ SUBDIRS += \ qhorizontalstackedbarseries \ qhorizontalpercentbarseries \ qvalueaxis \ + qlogvalueaxis \ qcategoryaxis \ qbarcategoryaxis \ domain \ diff --git a/tests/auto/qlogvalueaxis/qlogvalueaxis.pro b/tests/auto/qlogvalueaxis/qlogvalueaxis.pro new file mode 100644 index 0000000..e52567a --- /dev/null +++ b/tests/auto/qlogvalueaxis/qlogvalueaxis.pro @@ -0,0 +1,5 @@ +!include( ../auto.pri ) { + error( "Couldn't find the auto.pri file!" ) +} +HEADERS += ../qabstractaxis/tst_qabstractaxis.h +SOURCES += tst_qlogvalueaxis.cpp ../qabstractaxis/tst_qabstractaxis.cpp diff --git a/tests/auto/qlogvalueaxis/tst_qlogvalueaxis.cpp b/tests/auto/qlogvalueaxis/tst_qlogvalueaxis.cpp new file mode 100644 index 0000000..c93e199 --- /dev/null +++ b/tests/auto/qlogvalueaxis/tst_qlogvalueaxis.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** + ** + ** Copyright (C) 2012 Digia Plc + ** All rights reserved. + ** For any questions to Digia, please use contact form at http://qt.digia.com + ** + ** This file is part of the Qt Commercial Charts Add-on. + ** + ** $QT_BEGIN_LICENSE$ + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Digia. + ** + ** If you have questions regarding the use of this file, please use + ** contact form at http://qt.digia.com + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include "../qabstractaxis/tst_qabstractaxis.h" +#include "qlogvalueaxis.h" +#include +#include + +class tst_QLogValueAxis: public tst_QAbstractAxis +{ +Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: +// void qlogvalueaxis_data(); +// void qlogvalueaxis(); +// void max_raw_data(); +// void max_raw(); +// void max_data(); +// void max(); +// void max_animation_data(); +// void max_animation(); + void min_raw_data(); + void min_raw(); + void min_data(); + void min(); + void min_animation_data(); + void min_animation(); +// void range_raw_data(); +// void range_raw(); +// void range_data(); +// void range(); +// void range_animation_data(); +// void range_animation(); +// void noautoscale_data(); +// void noautoscale(); +// void autoscale_data(); +// void autoscale(); + void zoomIn(); +// void zoomOut(); + +private: + QLogValueAxis* m_logvaluesaxis; + QLineSeries* m_series; +}; + +void tst_QLogValueAxis::initTestCase() +{ +} + +void tst_QLogValueAxis::cleanupTestCase() +{ +} + +void tst_QLogValueAxis::init() +{ + m_logvaluesaxis = new QLogValueAxis(); + m_series = new QLineSeries(); + *m_series << QPointF(1, 1) << QPointF(100, 100); + tst_QAbstractAxis::init(m_logvaluesaxis,m_series); + m_chart->addSeries(m_series); + m_chart->createDefaultAxes(); +} + +void tst_QLogValueAxis::cleanup() +{ + delete m_series; + delete m_logvaluesaxis; + m_series = 0; + m_logvaluesaxis = 0; + tst_QAbstractAxis::cleanup(); +} + +//void tst_QLogValueAxis::qlogvalueaxis_data() +//{ +//} + +//void tst_QLogValueAxis::qlogvalueaxis() +//{ +// qabstractaxis(); + +// QVERIFY(qFuzzyCompare(m_logvaluesaxis->max(), 1)); +// QVERIFY(qFuzzyCompare(m_logvaluesaxis->min(), 1)); +// QCOMPARE(m_logvaluesaxis->type(), QAbstractAxis::AxisTypeLogValue); + +// m_chart->setAxisX(m_logvaluesaxis, m_series); +// m_view->show(); +// QTest::qWaitForWindowShown(m_view); + +// QVERIFY(!qFuzzyCompare(m_logvaluesaxis->max(), 100)); +// QVERIFY(!qFuzzyCompare(m_logvaluesaxis->min(), 0.1)); +//} + +//void tst_QLogValueAxis::max_raw_data() +//{ +// QTest::addColumn("max"); +// QTest::addColumn("expected"); +// QTest::addColumn("minChanged"); +// QTest::addColumn("maxChanged"); +// QTest::newRow("-1.0") << (qreal)-1.0 << (qreal)1.0 << false << false; +// QTest::newRow("0.0") << (qreal)0.0 << (qreal)1.0 << false << false; +// QTest::newRow("0.5") << (qreal)0.5 << (qreal)0.5 << true << true; +// QTest::newRow("101.0") << (qreal)101.0 << (qreal)101.0 << false << true; +//} + +//void tst_QLogValueAxis::max_raw() +//{ +// QFETCH(qreal, max); +// QFETCH(qreal, expected); +// QFETCH(bool, minChanged); +// QFETCH(bool, maxChanged); + +// QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal))); +// QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal))); +// QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal))); + +// m_logvaluesaxis->setMax(max); +// QCOMPARE(m_logvaluesaxis->max(), expected); + +// QCOMPARE(spy0.count(), (int)maxChanged); +// QCOMPARE(spy1.count(), (int)minChanged); +// QCOMPARE(spy2.count(), (int)maxChanged); + +//} + +//void tst_QLogValueAxis::max_data() +//{ +// max_raw_data(); +//} + +//void tst_QLogValueAxis::max() +//{ +// m_chart->setAxisX(m_logvaluesaxis, m_series); +// m_view->show(); +// QTest::qWaitForWindowShown(m_view); +// max_raw(); +//} + +//void tst_QLogValueAxis::max_animation_data() +//{ +// max_data(); +//} + +//void tst_QLogValueAxis::max_animation() +//{ +// m_chart->setAnimationOptions(QChart::GridAxisAnimations); +// max(); +//} + +void tst_QLogValueAxis::min_raw_data() +{ + QTest::addColumn("min"); + QTest::addColumn("expected"); + QTest::addColumn("minChanged"); + QTest::addColumn("maxChanged"); + QTest::newRow("-1.0") << (qreal)-1.0 << (qreal)1.0 << false << false; + QTest::newRow("0.0") << (qreal)0.0 << (qreal)1.0 << false << false; + QTest::newRow("0.5") << (qreal)0.5 << (qreal)0.5 << true << false; + QTest::newRow("101.0") << (qreal)101.0 << (qreal)101.0 << true << true; +} + +void tst_QLogValueAxis::min_raw() +{ + QFETCH(qreal, min); + QFETCH(qreal, expected); + QFETCH(bool, minChanged); + QFETCH(bool, maxChanged); + + QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal))); + QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal))); + QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal))); + + m_logvaluesaxis->setMin(min); + QCOMPARE(m_logvaluesaxis->min(), expected); + + QCOMPARE(spy0.count(), (int)maxChanged); + QCOMPARE(spy1.count(), (int)minChanged); + QCOMPARE(spy2.count(), (int)minChanged); +} + +void tst_QLogValueAxis::min_data() +{ + min_raw_data(); +} + +void tst_QLogValueAxis::min() +{ + m_chart->setAxisX(m_logvaluesaxis, m_series); + m_view->show(); + QTest::qWaitForWindowShown(m_view); + min_raw(); +} + +void tst_QLogValueAxis::min_animation_data() +{ + min_data(); +} + +void tst_QLogValueAxis::min_animation() +{ + m_chart->setAnimationOptions(QChart::GridAxisAnimations); + min(); +} + +//void tst_QLogValueAxis::range_raw_data() +//{ +// QTest::addColumn("min"); +// QTest::addColumn("max"); +// QTest::newRow("1.0 - 101.0") << (qreal)1.0 << (qreal)101.0; +// QTest::newRow("25.0 - 75.0") << (qreal)25.0 << (qreal)75.0; +// QTest::newRow("101.0") << (qreal)40.0 << (qreal)60.0; +//} + +//void tst_QLogValueAxis::range_raw() +//{ +// QFETCH(qreal, min); +// QFETCH(qreal, max); + +// QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal))); +// QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal))); +// QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal))); + +// m_logvaluesaxis->setRange(min, max); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal"); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal"); + +// QCOMPARE(spy0.count(), 1); +// QCOMPARE(spy1.count(), 1); +// QCOMPARE(spy2.count(), 1); +//} + +//void tst_QLogValueAxis::range_data() +//{ +// range_raw_data(); +//} + +//void tst_QLogValueAxis::range() +//{ +// m_chart->setAxisX(m_logvaluesaxis, m_series); +// m_view->show(); +// QTest::qWaitForWindowShown(m_view); +// range_raw(); +//} + +//void tst_QLogValueAxis::range_animation_data() +//{ +// range_data(); +//} + +//void tst_QLogValueAxis::range_animation() +//{ +// m_chart->setAnimationOptions(QChart::GridAxisAnimations); +// range(); +//} + +//void tst_QLogValueAxis::noautoscale_data() +//{ +// QTest::addColumn("min"); +// QTest::addColumn("max"); +// QTest::newRow("1.0 - 101.0") << (qreal)-1.0 << (qreal)101.0; +// QTest::newRow("25.0 - 75.0") << (qreal)25.0 << (qreal)75.0; +// QTest::newRow("101.0") << (qreal)40.0 << (qreal)60.0; +//} + +//void tst_QLogValueAxis::noautoscale() +//{ +// QFETCH(qreal, min); +// QFETCH(qreal, max); + +// QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal))); +// QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal))); +// QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal))); + +// m_logvaluesaxis->setRange(min, max); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal"); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal"); + +// QCOMPARE(spy0.count(), 1); +// QCOMPARE(spy1.count(), 1); +// QCOMPARE(spy2.count(), 1); + +// m_chart->setAxisX(m_logvaluesaxis, m_series); +// m_view->show(); +// QTest::qWaitForWindowShown(m_view); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal"); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal"); +//} + +//void tst_QLogValueAxis::autoscale_data() +//{ + +//} + +//void tst_QLogValueAxis::autoscale() +//{ +// QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal))); +// QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal))); +// QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal))); + +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), 0), "Min not equal"); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), 0), "Max not equal"); +// m_chart->setAxisX(m_logvaluesaxis, m_series); + +// QCOMPARE(spy0.count(), 1); +// QCOMPARE(spy1.count(), 1); +// QCOMPARE(spy2.count(), 1); + +// m_view->show(); +// QTest::qWaitForWindowShown(m_view); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), -100), "Min not equal"); +// QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), 100), "Max not equal"); +//} + +void tst_QLogValueAxis::zoomIn() +{ + m_chart->setAxisX(m_logvaluesaxis, m_series); + m_view->show(); + QTest::qWaitForWindowShown(m_view); + m_logvaluesaxis->setBase(2); + m_logvaluesaxis->setRange(0.5, 2); + + QCOMPARE(m_logvaluesaxis->min(), (qreal)0.5); + QCOMPARE(m_logvaluesaxis->max(), (qreal)2.0); + + m_chart->zoomOut(); + + QCOMPARE(m_logvaluesaxis->min(), (qreal)0.25); + QCOMPARE(m_logvaluesaxis->max(), (qreal)4.0); + + m_chart->zoomIn(); + + QCOMPARE(m_logvaluesaxis->min(), (qreal)0.5); + QCOMPARE(m_logvaluesaxis->max(), (qreal)2.0); + + m_logvaluesaxis->setRange(0.5, 1024); + m_chart->zoom(11.0); + + QCOMPARE(m_logvaluesaxis->min(), (qreal)16.0); + QCOMPARE(m_logvaluesaxis->max(), (qreal)32.0); + + m_logvaluesaxis->setRange(16, 64); + m_chart->zoom(1/3.0); + + QCOMPARE(m_logvaluesaxis->min(), (qreal)4); + QCOMPARE(m_logvaluesaxis->max(), (qreal)256.0); + +} + +//void tst_QLogValueAxis::zoomOut() +//{ + +//} + +QTEST_MAIN(tst_QLogValueAxis) +#include "tst_qlogvalueaxis.moc" +