更改轴刻度和标签以在 QWT 图中在毫米和英寸之间切换

bka*_*sbk 3 plot qt scale qwt

我想要的是切换轴标签和刻度以最适合显示英寸和毫米而不改变曲线点。我创建了一个自定义 QwtScaleDraw 并覆盖了 label() 方法,但这不会改变刻度。

class QwtMyScaleDraw : public QwtScaleDraw {
public:
    QwtMyScaleDraw() : QwtScaleDraw() {
    }
protected:
    QwtText label(double value) const {
           // global conversion routine that creates a display string either as millimeter or inch
           return ConvertToString(value, ConversionFromMillimeter);
    }
};
Run Code Online (Sandbox Code Playgroud)

您可以在下图中看到此行为: Qwt 绘图比例演示

左边的比例是原始比例,中间的比例是我的自定义标签,右边是所需的比例。

获得所需结果的最佳方法是什么,而无需使用手动转换的值再次添加整个曲线?

bka*_*sbk 5

在 qwt 库的作者的帮助下,我找到了解决方案。答案是从QwtLinearScaleEngine类、重载autoScaledivideScale方法派生。

在我的实现中,可以选择任何转换因子(默认为 1 = 无转换)。这是我的代码:

class QwtUnitScaleDraw : public QwtScaleDraw {
public:
    QwtUnitScaleDraw(double ConversionFactor = 1.0) : QwtScaleDraw(), _ConversionFactor(ConversionFactor) {
    }
protected:
    QwtText label(double value) const {
        return QwtScaleDraw::label(value * _ConversionFactor);
    }
protected:
    double _ConversionFactor;
};

class QwtUnitScaleEngine: public QwtLinearScaleEngine {
public:
    QwtUnitScaleEngine(double ConversionFactor = 1.0) : QwtLinearScaleEngine(10), _ConversionFactor(ConversionFactor) {
    }

    void autoScale(int maxSteps, double &x1, double &x2, double &stepSize) const {
        x1 *= _ConversionFactor;
        x2 *= _ConversionFactor;
        stepSize *= _ConversionFactor;
        QwtLinearScaleEngine::autoScale(maxSteps, x1, x2, stepSize);
        x1 /= _ConversionFactor;
        x2 /= _ConversionFactor;
        stepSize /= _ConversionFactor;

    }

    QwtScaleDiv divideScale(double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize = 0.0) const {
        x1 *= _ConversionFactor;
        x2 *= _ConversionFactor;
        stepSize *= _ConversionFactor;

        QwtScaleDiv Div = QwtLinearScaleEngine::divideScale(x1, x2, numMajorSteps, numMinorSteps, stepSize);

        QList<double> Ticks[QwtScaleDiv::NTickTypes];

        Ticks[QwtScaleDiv::MajorTick] = Div.ticks(QwtScaleDiv::MajorTick);
        for (unsigned int i = 0; i < Ticks[QwtScaleDiv::MajorTick].count(); i++) {
            Ticks[QwtScaleDiv::MajorTick][i] /= _ConversionFactor;
        }
        Ticks[QwtScaleDiv::MediumTick] = Div.ticks(QwtScaleDiv::MediumTick);
        for (unsigned int i = 0; i < Ticks[QwtScaleDiv::MediumTick].count(); i++) {
            Ticks[QwtScaleDiv::MediumTick][i] /= _ConversionFactor;
        }
        Ticks[QwtScaleDiv::MinorTick] = Div.ticks(QwtScaleDiv::MinorTick);
        for (unsigned int i = 0; i < Ticks[QwtScaleDiv::MinorTick].count(); i++) {
            Ticks[QwtScaleDiv::MinorTick][i] /= _ConversionFactor;
        }

        return QwtScaleDiv(QwtInterval(x1 / _ConversionFactor, x2 / _ConversionFactor), Ticks);
    }
protected:
    double _ConversionFactor;
};
Run Code Online (Sandbox Code Playgroud)