我有一个带有常规值轴的QT图表。切换复选框时,我想将X轴从QValueAxis更改为QLogValueAxis。问题是,当我这样做时,我的数据将不再绘制到正确的位置。
我尝试了两种方法(以及它们上的许多变化)来使日志刻度起作用,但是我没有尝试过,似乎数据刻度本身线性地适合窗口并且忽略了日志轴完全。
方法1-替换旧轴:
QLogValueAxis* xLogAxis = new QLogValueAxis();
xLogAxis->setBase(10);
xLogAxis->setMinorTickCount(10);
dataSeries->attachedAxes()[0] = xLogAxis; //Replace the old X Axis on the series
chart->setAxisX(xLogAxis);
方法2-制作全新的图表:
chart->removeSeries(data); //release the data so you don't destroy it
QChart* newChart = new QChart();
ui->graphView->setChart(newChart); //Swap the old chart out then delete it
delete chart;
chart = newChart;
//get rid of the old axes on the data
for(QAbstractAxis* axis : data->attachedAxes()){
data->detachAxis(axis);
}
QValueAxis* yAxis = new QValueAxis();
data->attachAxis(xLogAxis);
data->attachAxis(yAxis);
chart->addAxis(xLogAxis, Qt::AlignBottom);
chart->addAxis(yAxis, Qt::AlignLeft);
chart->addSeries(data);
chart->legend()->setVisible(false);
关于如何在运行时热交换到日志轴的任何想法?预先感谢!
答案 0 :(得分:1)
在以下示例中,如何交换轴类型:
#include <QtWidgets>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
typedef std::function<qreal (const qreal &)> function;
static std::vector<std::pair<function, std::string>> functions{
{[](const qreal & v){ return v;}, "linear"},
{[](const qreal & v){ return v*v; }, "quadratic"},
{[](const qreal & v){ return std::exp(0.01*v);}, "exponential"},
{[](const qreal & v){ return std::sqrt(1 + std::abs(v));}, "square root"}
};
class Widget: public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent=nullptr):
QWidget(parent),
xLogAxis(new QLogValueAxis),
xLinAxis(new QValueAxis),
yAxis(new QValueAxis)
{
xLogAxis->setBase(10);
xLogAxis->setMinorTickCount(10);
view.setChart(&chart);
checkbox.setText("Log Axis");
connect(&checkbox, &QCheckBox::stateChanged, this, &Widget::onStateChanged);
QVBoxLayout *lay = new QVBoxLayout(this);
lay->addWidget(&checkbox);
lay->addWidget(&view);
chart.addAxis(yAxis, Qt::AlignLeft);
// chart.legend()->hide();
// create series
for(const std::pair<function, std::string> & func: functions){
QLineSeries *serie = new QLineSeries;
serie->setName(QString::fromStdString(func.second));
for(int i=0; i< 1000; ++i){
*serie << QPointF(i+1, func.first(i));
}
chart.addSeries(serie);
serie->attachAxis(yAxis);
}
onStateChanged(checkbox.checkState());
}
private slots:
void onStateChanged(int state){
QAbstractAxis *removeaxis, *insertaxis;
if(state == Qt::Checked){
removeaxis = xLinAxis;
insertaxis = xLogAxis;;
}
else{
removeaxis = xLogAxis;
insertaxis = xLinAxis;
}
if(chart.axes(Qt::Horizontal).contains(removeaxis))
chart.removeAxis(removeaxis);
chart.addAxis(insertaxis, Qt::AlignBottom);
for(auto serie: chart.series()){
if(serie->attachedAxes().contains(removeaxis))
serie->detachAxis(removeaxis);
serie->attachAxis(insertaxis);
}
}
private:
QCheckBox checkbox;
QChartView view;
QChart chart;
QLogValueAxis *xLogAxis;
QValueAxis *xLinAxis;
QValueAxis *yAxis;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(640, 480);
w.show();
return a.exec();
}
#include "main.moc"