7

I am using the QtCharts class to make a line graph. I want to be able to add note/text on the graph itself. How can I do this? I found a example similar to what I want " https://doc.qt.io/qt-5/qtcharts-callout-example.html" is there a easier way?

amanda45
  • 535
  • 10
  • 29

2 Answers2

0

This is my version. There may be errors

textitem.h

#pragma once

#include <QtCharts/QChartGlobal>
#include <QtWidgets/QGraphicsItem>

QT_CHARTS_BEGIN_NAMESPACE
class QChart;
class QAbstractSeries;
QT_CHARTS_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE


class TextItem : public QGraphicsItem {
public:
    TextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series);
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

    void setText(const QString &text);
    void setAnchor(QPointF point);
private:
    QChart *_chart;
    QAbstractSeries *_series;
    QString _text;
    QRectF _textRect;
    QPointF _anchor;
};

textitem.cpp

#include "textitem.h"
#include <QtCharts/QChart>
#include <QPainter>
#include <QRect>

TextItem::TextItem(QString text, QPoint pos, QChart *chart, QAbstractSeries *series)
    : QGraphicsItem(chart), _chart(chart), _series(series), _anchor(pos) {
    setText(text);
}

QRectF TextItem::boundingRect() const {
    QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor, _series));
    QRectF rect;
    rect.setLeft(qMin(_textRect.left(), anchor.x()));
    rect.setRight(qMax(_textRect.right(), anchor.x()));
    rect.setTop(qMin(_textRect.top(), anchor.y()));
    rect.setBottom(qMax(_textRect.bottom(), anchor.y()));
    return rect;
}

void TextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    Q_UNUSED(option)
    Q_UNUSED(widget)
    QPointF anchor = mapFromParent(_chart->mapToPosition(_anchor, _series));
    painter->drawText(anchor, _text);
}

void TextItem::setText(const QString &text) {
  _text = text;
  QFontMetrics metrics((QFont()));
  _textRect = metrics.boundingRect(QRect(0, 0, 150, 150),
                                   Qt::AlignLeft, _text);
  _textRect.translate(5, 5);
  prepareGeometryChange();
}

void TextItem::setAnchor(QPointF point) { _anchor = point; }
Kto To
  • 434
  • 5
  • 11
0

I know it's a late reply and not anymore relevant for you, though it might be for others:

As far as I can see, they already use a pretty easy way of doing this. In their example, they use the QGraphicsTextItem to add text at a specific position in a chart.

Assume you have a series and want to add text to each point in this series which is visible in the chart. Here is an (python PySide6) example of how you can do it (you can do it the same way in c++):

chart = QChart()  # some chart
series = QScatterSeries()  # some series which has been added to the chart

# create text items and add to chart
my_text_items = []
for i in range(series.count()):
    text_item = QGraphicsTextItem("point with idx: {}".format(i), parent=chart)
    my_text_items.append(text_item)


# define function to set/update the position of the text items (has to be called during resize)
def update_position_of_text_items(text_items, series):
    for i, text_item in enumerate(text_items):
        # get point at index i
        point = series.at(i)

        # map its position of the series to the position in the chart
        position_in_chart = series.chart().mapToPosition(point, series)

        # set the position of the text item at index i accordingly
        text_item.setPos(position_in_chart)


update_position_of_text_items(my_text_items, series)

Make sure to call the update_position_of_text_items(..) when resizing your widget.

Ruben
  • 38
  • 1
  • 6