qt - 如何设置 QChart 纵横比
问题描述
我正在尝试实现一种算法来保持 QChart 纵横比。这是一种工作,但我想知道是否有人有更简单的解决方案。
下面是发生在调整大小事件上的代码
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());
}
解决方案
我修改了你所做的一段代码,这就是我最终得到的:
在.h
//! \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
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 的比例,但我确信它可以轻松修改为任何其他比例......
推荐阅读
- java - 选择字符串中 - 之后的字母
- android - Jackson、Kotlin 和 Proguard
- reactjs - 使用 React 组件的代理时查找失败
- vba - VBA:用户表单和用户表单中调用的宏给出不同的结果
- python - 不同超参数配置 sklearn RandomizedSearchCV 的分数值完全相同
- vba - VBA代码在它旁边查找值复制值并粘贴到不同的单元格中
- c++ - C++ libcurl - 无法从 URL 检索整个 html 内容
- quill - 新线路不是所见即所得
- jquery - 当我通过 jquery 发布时,为什么我的表单字段名称带有方括号?
- sql - 在 360 升级之前通过 SQL 查询更新 Excel 表的宏,现在给出错误