首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置QChart纵横比

如何设置QChart纵横比
EN

Stack Overflow用户
提问于 2020-02-18 16:50:02
回答 1查看 427关注 0票数 0

我正在尝试实现一个保持QChart纵横比的算法。这是一种工作,但我想知道是否有人有一个更简单的解决方案。

下面是在调整大小事件中发生的代码

代码语言:javascript
复制
void TrainChartView::maintainAspectRatio(QSizeF eventSize) {

    int aspect = 8;
    QSizeF chartSize = m_chart->size();

    QValueAxis* axisX = qobject_cast<QValueAxis*>(m_chart->axisX());
    QValueAxis* axisY = qobject_cast<QValueAxis*>(m_chart->axisY());

    // get Min Max X-axis Value
    double minAxisX = axisX->min();
    double maxAxisX = axisX->max();
    double minAxisY = axisY->min();
    double maxAxisY = axisY->max();

    // Get Coordinates in scene of min and max X-axis value
    QPointF minAxisXPosition = m_chart->mapToPosition(QPointF(minAxisX, 0));
    QPointF maxAxisXPosition = m_chart->mapToPosition(QPointF(maxAxisX, 0));
    QPointF minAxisYPosition = m_chart->mapToPosition(QPointF(0, minAxisY));
    QPointF maxAxisYPosition = m_chart->mapToPosition(QPointF(0, maxAxisY));

    double axisXSize = abs(maxAxisXPosition.x() - minAxisXPosition.x());
    double axisYSize = abs(maxAxisXPosition.y() - minAxisYPosition.y());

    // get the size of axis x in the coordinate system
    double deltaAxisXSize = maxAxisXPosition.x() - minAxisXPosition.x();

    if (chartSize.width() != eventSize.width()) {
        QPointF maxAxisValue = m_chart->mapToValue(QPointF(0, (minAxisYPosition.y() - deltaAxisXSize)));
        axisY->setRange(minAxisY, maxAxisValue.y() / aspect);
    }

    if (chartSize.height() != eventSize.height() && m_chart->minimumSize().height() >= eventSize.height()) {
        double deltaHeight = eventSize.height() - chartSize.height();
        maxAxisYPosition.setY(maxAxisYPosition.y() - deltaHeight);
        QPointF maxAxisValue = m_chart->mapToValue(QPointF(maxAxisYPosition));

        axisY->setRange(minAxisY, maxAxisValue.y());

    }
EN

回答 1

Stack Overflow用户

发布于 2020-06-12 15:14:08

我对你所做的代码做了一些修改,下面是我最终得到的结果:

在.h中

代码语言:javascript
复制
//! \brief The QChartView_scaledAxis class extends the QChartView class but force the graph to be normalized
//! (i.e.) 1 pixel on the x-axis represent the same amount as 1 pixel on the y-axis.
class QChartView_scaledAxis : public QChartView {
public:
    void resizeEvent(QResizeEvent *event) override;
};

在.cpp中

代码语言:javascript
复制
void QChartView_scaledAxis::resizeEvent(QResizeEvent *event) {
    QChartView::resizeEvent(event);

    // Get the axis of the graph
    QValueAxis* axisX = qobject_cast<QValueAxis*>(this->chart()->axes(Qt::Horizontal)[0]);
    QValueAxis* axisY = qobject_cast<QValueAxis*>(this->chart()->axes(Qt::Vertical)[0]);

    // Get the series displayed on the graph
    const QList<QAbstractSeries*> series = this->chart()->series();

    // get Min Max values (on X and Y) of all the points plotted on the graph
    float minX = std::numeric_limits<double>::max();
    float maxX = std::numeric_limits<double>::min();
    float minY = std::numeric_limits<double>::max();
    float maxY = std::numeric_limits<double>::min();
    for(QAbstractSeries *p_serie : series) { //iterate on all the series in the graph
        //Assuming all the series in the graph are QXYSeries...
        for(QPointF p : qobject_cast<QXYSeries*>(p_serie)->points()) { //iterate on each point of each serie
            minX = fmin(minX, p.x());
            maxX = fmax(maxX, p.x());
            minY = fmin(minY, p.y());
            maxY = fmax(maxY, p.y());
        }
    }

    // Get the points at both ends of the axis (will help to determine the plottable area in pixel)
    const QPointF minPosition = this->chart()->mapToPosition(QPointF(axisX->min(), axisY->min()));
    const QPointF maxPosition = this->chart()->mapToPosition(QPointF(axisX->max(), axisY->max()));

    // Ration between the size of the axis in pixel and in term of represented value
    const double axisX_PixToValue = (maxX - minX) / (maxPosition.x() - minPosition.x());
    const double axisY_PixToValue = (maxY - minY) / (maxPosition.y() - minPosition.y());

    // The smallest ratio must be 'kept' and applied to the other axis
    if(abs(axisX_PixToValue) > abs(axisY_PixToValue)) {
        axisY->setMin(minY);
        axisY->setMax(minY + (maxPosition.y() - minPosition.y()) * std::copysign(axisX_PixToValue, axisY_PixToValue));
    } else {
        axisX->setMin(minX);
        axisX->setMax(minX + (maxPosition.x() - minPosition.x()) * std::copysign(axisY_PixToValue, axisX_PixToValue));
    }
}

这段代码是1:1的比例,但我相信它可以很容易地修改为任何其他比例…

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60276971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档