See More

#include "wplot/CartesianGrid2D.h" #include "wplot/Plot2D.h" #include "wplot/Private/LinearTicksCalculator.h" #include #include namespace WPlot { /////////////////////////////////////////////////////////////////////////////// // USING SECTION // /////////////////////////////////////////////////////////////////////////////// using Private::LinearTicksCalculator; /////////////////////////////////////////////////////////////////////////////// // PUBLIC SECTION // /////////////////////////////////////////////////////////////////////////////// CartesianGrid2D::CartesianGrid2D() : Layer2D(), m_upperLeftCorner(-1.0, 1.0), m_lowerRightCorner(1.0, -1.0), m_primaryXStep(1.0), m_secondaryXStep(0.5), m_primaryYStep(1.0), m_secondaryYStep(0.5), m_primaryXColor(Qt::black), m_secondaryXColor(Qt::black), m_primaryYColor(Qt::black), m_secondaryYColor(Qt::black), m_boundaryColor(Qt::black), m_primaryXStyle(Qt::SolidLine), m_secondaryXStyle(Qt::DashLine), m_primaryYStyle(Qt::SolidLine), m_secondaryYStyle(Qt::DashLine), m_boundaryStyle(Qt::SolidLine), m_primaryXWidth(1.0), m_secondaryXWidth(1.0), m_primaryYWidth(1.0), m_secondaryYWidth(1.0), m_boundaryWidth(2.0), m_primaryXPen(), m_secondaryXPen(), m_primaryYPen(), m_secondaryYPen(), m_boundaryPen() { m_primaryXPen.setWidthF(m_primaryXWidth); m_primaryXPen.setStyle(m_primaryXStyle); m_primaryXPen.setColor(m_primaryXColor); m_secondaryXPen.setWidthF(m_secondaryXWidth); m_secondaryXPen.setStyle(m_secondaryXStyle); m_secondaryXPen.setColor(m_secondaryXColor); m_primaryYPen.setWidthF(m_primaryYWidth); m_primaryYPen.setStyle(m_primaryYStyle); m_primaryYPen.setColor(m_primaryYColor); m_secondaryYPen.setWidthF(m_secondaryYWidth); m_secondaryYPen.setStyle(m_secondaryYStyle); m_secondaryYPen.setColor(m_secondaryYColor); m_boundaryPen.setWidthF(m_boundaryWidth); m_boundaryPen.setStyle(m_boundaryStyle); m_boundaryPen.setColor(m_boundaryColor); m_boundaryPen.setJoinStyle(Qt::RoundJoin); } /** * Set the step for primary grid lines of the \f$X\f$ axis. * * @param[in] step Step. */ void CartesianGrid2D::setPrimaryXStep(const double &step) { m_primaryXStep = step; } /** * Set the step for secondary grid lines of the \f$X\f$ axis. * * @param[in] step Step. */ void CartesianGrid2D::setSecondaryXStep(const double &step) { m_secondaryXStep = step; } /** * Set the step for primary grid lines of the \f$Y\f$ axis. * * @param[in] step Step. */ void CartesianGrid2D::setPrimaryYStep(const double &step) { m_primaryYStep = step; } /** * Set the step for secondary grid lines of the \f$Y\f$ axis. * * @param[in] step Step. */ void CartesianGrid2D::setSecondaryYStep(const double &step) { m_secondaryYStep = step; } /** * Set the primay step for both axis. * * @param[in] step Step. */ void CartesianGrid2D::setPrimaryStep(const double &step) { setPrimaryXStep(step); setPrimaryYStep(step); } /** * Set the secondary step for both axis. * * @param[in] step Step. */ void CartesianGrid2D::setSecondaryStep(const double &step) { setSecondaryXStep(step); setSecondaryYStep(step); } /** * Set the color for primary grid lines of the \f$X\f$ axis. * * @param[in] color Color. */ void CartesianGrid2D::setPrimaryXColor(const QColor &color) { m_primaryXColor = color; m_primaryXPen.setColor(color); } /** * Set the color for secondary grid lines of the \f$X\f$ axis. * * @param[in] color Color. */ void CartesianGrid2D::setSecondaryXColor(const QColor &color) { m_secondaryXColor = color; m_secondaryXPen.setColor(color); } /** * Set the color for primary grid lines of the \f$Y\f$ axis. * * @param[in] color Color. */ void CartesianGrid2D::setPrimaryYColor(const QColor &color) { m_primaryYColor = color; m_primaryYPen.setColor(color); } /** * Set the color for secondary grid lines of the \f$Y\f$ axis. * * @param[in] color Color. */ void CartesianGrid2D::setSecondaryYColor(const QColor &color) { m_secondaryYColor = color; m_secondaryYPen.setColor(color); } /** * Set the color for primary grid lines in both axis. * * @param[in] color Color. */ void CartesianGrid2D::setPrimaryColor(const QColor &color) { setPrimaryXColor(color); setPrimaryYColor(color); } /** * Set the color for secondary grid lines in both axis. * * @param[in] color Color. */ void CartesianGrid2D::setSecondaryColor(const QColor &color) { setSecondaryXColor(color); setSecondaryYColor(color); } /** * Set the color for primary and secondary grid lines in both axis. * * @param[in] color Color. */ void CartesianGrid2D::setGridColor(const QColor &color) { setPrimaryColor(color); setSecondaryColor(color); } /** * Set the color for boundary rectangle. * * @param[in] color Color. */ void CartesianGrid2D::setBoundaryColor(const QColor &color) { m_boundaryColor = color; m_boundaryPen.setColor(color); } /** * Set the color for the entire grid. * * @param[in] color Color. */ void CartesianGrid2D::setColor(const QColor &color) { setGridColor(color); setBoundaryColor(color); } /** * Set the style for primary grid lines of the \f$X\f$ axis. * * @param[in] style Style. */ void CartesianGrid2D::setPrimaryXStyle(const Qt::PenStyle &style) { m_primaryXStyle = style; m_primaryXPen.setStyle(style); } /** * Set the style for secondary grid lines of the \f$X\f$ axis. * * @param[in] style Style. */ void CartesianGrid2D::setSecondaryXStyle(const Qt::PenStyle &style) { m_secondaryXStyle = style; m_secondaryXPen.setStyle(style); } /** * Set the style for primary grid lines of the \f$Y\f$ axis. * * @param[in] style Style. */ void CartesianGrid2D::setPrimaryYStyle(const Qt::PenStyle &style) { m_primaryYStyle = style; m_primaryYPen.setStyle(style); } /** * Set the style for secondary grid lines of the \f$Y\f$ axis. * * @param[in] style Style. */ void CartesianGrid2D::setSecondaryYStyle(const Qt::PenStyle &style) { m_secondaryYStyle = style; m_secondaryYPen.setStyle(style); } /** * Set the style for primary lines. * * @param[in] style Style. */ void CartesianGrid2D::setPrimaryStyle(const Qt::PenStyle &style) { setPrimaryXStyle(style); setPrimaryYStyle(style); } /** * Set the style for secondary lines. * * @param[in] style Style. */ void CartesianGrid2D::setSecondaryStyle(const Qt::PenStyle &style) { setSecondaryXStyle(style); setSecondaryYStyle(style); } /** * Set the style for all grid lines. * * @param[in] style Style. */ void CartesianGrid2D::setGridStyle(const Qt::PenStyle &style) { setPrimaryStyle(style); setSecondaryStyle(style); } /** * Set the style for boundary rectangle. * * @param[in] style Style. */ void CartesianGrid2D::setBoundaryStyle(const Qt::PenStyle &style) { m_boundaryStyle = style; m_boundaryPen.setStyle(style); } /** * Set the style for entire grid. * * @param[in] style Style. */ void CartesianGrid2D::setStyle(const Qt::PenStyle &style) { setGridStyle(style); setBoundaryStyle(style); } /** * Set the width in pixels for primary grid lines of the \f$X\f$ axis. * * @param[in] width Width. */ void CartesianGrid2D::setPrimaryXWidth(const double &width) { m_primaryXWidth = width; m_primaryXPen.setWidthF(width); } /** * Set the width in pixels for secondary grid lines of the \f$X\f$ axis. * * @param[in] width Width. */ void CartesianGrid2D::setSecondaryXWidth(const double &width) { m_secondaryXWidth = width; m_secondaryXPen.setWidthF(width); } /** * Set the width in pixels for primary grid lines of the \f$Y\f$ axis. * * @param[in] width Width. */ void CartesianGrid2D::setPrimaryYWidth(const double &width) { m_primaryYWidth = width; m_primaryYPen.setWidthF(width); } /** * Set the width in pixels for secondary grid lines of the \f$Y\f$ axis. * * @param[in] width Width. */ void CartesianGrid2D::setSecondaryYWidth(const double &width) { m_secondaryYWidth = width; m_secondaryYPen.setWidthF(width); } /** * Set the width for primary lines in both axis. * * @param[in] width Width. */ void CartesianGrid2D::setPrimaryWidth(const double &width) { setPrimaryXWidth(width); setPrimaryYWidth(width); } /** * Set the width for secondary lines in both axis. * * @param[in] width Width. */ void CartesianGrid2D::setSecondaryWidth(const double &width) { setSecondaryXWidth(width); setSecondaryYWidth(width); } /** * Set the width for grid lines. * * @param[in] width Width. */ void CartesianGrid2D::setGridWidth(const double &width) { setPrimaryWidth(width); setSecondaryWidth(width); } /** * Set the width in pixels for boundary rectangle. * * @param[in] width Width. */ void CartesianGrid2D::setBoundaryWidth(const double &width) { m_boundaryWidth = width; m_boundaryPen.setWidthF(width); } /** * Set the width for the entire grid. * * @param[in] width Width. */ void CartesianGrid2D::setWidth(const double &width) { setGridWidth(width); setBoundaryWidth(width); } /////////////////////////////////////////////////////////////////////////////// // VIRTUAL PUBLIC SECTION // /////////////////////////////////////////////////////////////////////////////// /** * Draw the grid. * * @param[inout] plot Plot. */ void CartesianGrid2D::draw(Plot2D *plot) { drawGridX(plot); drawGridY(plot); drawGridBoundary(plot); } void CartesianGrid2D::drawLines(Plot2D *plot) { drawGridX(plot); drawGridY(plot); } void CartesianGrid2D::drawBoundary(Plot2D *plot) { drawGridBoundary(plot); } /////////////////////////////////////////////////////////////////////////////// // PRIVATE SECTION // /////////////////////////////////////////////////////////////////////////////// /** * Draw grid lines for \f$X\f$ axis. * * @param[inout] plot Plot. */ void CartesianGrid2D::drawGridX(Plot2D *plot) { QPainter painter(plot); const auto upperLeftLimits = plot->getUpperLeftCorner(); const auto lowerRightLimits = plot->getLowerRightCorner(); const auto upperLeftCorner = plot->scalePoint(upperLeftLimits); const auto lowerRightCorner = plot->scalePoint(lowerRightLimits); painter.setPen(m_secondaryXPen); LinearTicksCalculator ticksCalculator; ticksCalculator.setStep(m_secondaryXStep); ticksCalculator.setLimits(upperLeftLimits.x(), lowerRightLimits.x()); const auto secondaryTicks = ticksCalculator.getTicks(); for (const auto& x : secondaryTicks) { const double scaledX = plot->scalePointX(x); painter.drawLine(scaledX, upperLeftCorner.y(), scaledX, lowerRightCorner.y()); } painter.setPen(m_primaryXPen); ticksCalculator.setStep(m_primaryXStep); const auto primaryTicks = ticksCalculator.getTicks(); for (const auto& x : primaryTicks) { const double scaledX = plot->scalePointX(x); painter.drawLine(scaledX, upperLeftCorner.y(), scaledX, lowerRightCorner.y()); } } /** * Draw grid lines for \f$Y\f$ axis. * * @param[inout] plot Plot. */ void CartesianGrid2D::drawGridY(Plot2D *plot) { QPainter painter(plot); const auto upperLeftLimits = plot->getUpperLeftCorner(); const auto lowerRightLimits = plot->getLowerRightCorner(); const auto upperLeftCorner = plot->scalePoint(upperLeftLimits); const auto lowerRightCorner = plot->scalePoint(lowerRightLimits); painter.setPen(m_secondaryYPen); LinearTicksCalculator ticksCalculator; ticksCalculator.setStep(m_secondaryYStep); ticksCalculator.setLimits(lowerRightLimits.y(), upperLeftLimits.y()); const auto secondaryTicks = ticksCalculator.getTicks(); for (const auto& y : secondaryTicks) { const double scaledY = plot->scalePointY(y); painter.drawLine(upperLeftCorner.x(), scaledY, lowerRightCorner.x(), scaledY); } painter.setPen(m_primaryYPen); ticksCalculator.setStep(m_primaryYStep); const auto primaryTicks = ticksCalculator.getTicks(); for (const auto& y : primaryTicks) { const double scaledY = plot->scalePointY(y); painter.drawLine(upperLeftCorner.x(), scaledY, lowerRightCorner.x(), scaledY); } } /** * Draw grid lines for boundary rectangle. * * @param[inout] plot Plot. */ void CartesianGrid2D::drawGridBoundary(Plot2D *plot) { QPainter painter(plot); painter.setPen(m_boundaryPen); auto upperLeftCorner = plot->scalePoint(plot->getUpperLeftCorner()); auto lowerRightCorner = plot->scalePoint(plot->getLowerRightCorner()); const double w = lowerRightCorner.x() - upperLeftCorner.x(); const double h = upperLeftCorner.y() - lowerRightCorner.y(); painter.drawRect(upperLeftCorner.x(), lowerRightCorner.y(), w, h); } } // namespace WPlot