Как установить собственный формат меток точек для QLineSeries / QXYSeries? - PullRequest
0 голосов
/ 05 ноября 2019

Контекст: Я пытаюсь нанести QLineSeries на QChart, чтобы напечатать последовательность значений во времени. Поэтому ось X (абсцисса) - QDateTimeAxis, а ось Y (ордината) - QValueAxis.

Проблема: Я хочу отобразить метки точек. Но я не могу найти, как установить желаемый формат для даты и времени. По умолчанию метки могут рисовать только целочисленные значения точки, что я хочу для значения ординаты. Но для значения абсциссы (datetime) он печатает количество миллисекунд, прошедших с последней эпохи ( 1970-01-01T00: 00: 00.000 ). Я хочу изменить формат даты и времени так, чтобы они соответствовали "чч: мм: сс" (это формат, который я использую для отображения отметок на QDateTimeAxis).

Я знаюсуществует QXYSeries::setPointlabelsFormat(), который позволяет указать формат, но он принимает только теги формата @xPoint и @yPoint (как вы можете видеть в документации).

  • Здесь вы можете найти картину проблемы: enter image description here

Как видите, я могу установить формат для QDateTimeAxis, но не на ярлыках точек.

Пример кода, который генерирует этот вывод, основан на предоставленном здесь . Я просто добавил больше точек и раскомментировал строку //ls->setPointLabelsVisible(true);.

Вопрос: Есть ли способ печати @xPoint этикеток в произвольном формате (в идеале, чтобы соответствовать QDateTime::toString("hh:mm:ss"))? Если да, то как?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2019

Как отметил Сохейм, формат меток точек, предоставляемый QtCharts, слишком ограничен для этого.

Если вы не хотите испачкать руки внутренностями QtCharts, вы можете решить свою проблему другим способом: Нарисуйте текстовые метки самостоятельно.

Извлекайте пользовательский графический элемент из QGraphicsObject:

class PointLabelsItem : public QGraphicsObject
{
    Q_OBJECT
public:
    PointLabelsItem(QtCharts::QChart *parent = nullptr);
    virtual QRectF boundingRect() const;
    virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);

public slots:
    void setRect(const QRectF &area);
    void setAxis(const QAbstractAxis *axis, Qt::Alignment alignment);
    // setter for either source Q*Series or points / point labels

protected:
    QRectF area;
    // const axes*
    // const series* or points/labels
};

В реализации:

PointLabelsItem::PointLabelsItem(QtCharts::QChart *parent)
    : QGraphicsObject(parent)
{
    setZValue(10); // put above series
    connect(parent, &QtCharts::QChart::plotAreaChanged,
        this, &PointLabelsItem::setRect);
}

QRectF PointLabelsItem::boundingRect() const
{
    return area;
}

void PointLabelsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    // translate between data coordinates and scene coordinates
    // by making use of `area` and the axes' ranges, OR via
    // qobject_cast<QtCharts::QChart>(parent())->mapToPosition()
    // then draw custom point label texts at the corresp. positions
}

void PointLabelsItem::setRect(const QRectF &newArea)
{
    area = newArea;
    update();
}

void setAxis(const QAbstractAxis *axis, Qt::Alignment alignment)
{
    disconnect(/* old axis member variable */);
    // set corresp. axis member variable here
    connect(axis, &QtCharts::QValueAxis::rangeChanged, this, [this] { update(); });
}

Снаружи:

auto pointLabels = new PointLabelsItem(chart);
// set axes, series

Это скелет.

Вы также можете принять решение о том, чтобы QGRaphicsTextItem s были детьми вашего PointLabelsItem (т. Е. Членов, для которых this установлено в качестве parent). Таким образом, вы можете включить взаимодействие пользователя с метками.

0 голосов
/ 05 ноября 2019

Это не поддерживается QXYSeries . Вы можете получить новый класс из QAbstractSeries для вашего так называемого QXYDatetimeSeries, следуя тому же, что реализовано в QXYSeries , просмотревкод. Вы также можете изменить исходный код QXYSeriesPrivate::drawSeriesPointLabels для поддержки вашего поведения. Не забудьте отправить свои изменения в репозиторий Qt git, чтобы другие люди также могли его использовать.

...