QChart + QDateTiemAxis, mapTo and mapFrom
Hello Everybody,
I'd like to add some describing text to a given QPointF on a chart. I really spent a lot of time trying all of the mapToX's and mapFromX's to map coordinates.
Here's a short wrap up about what I'm doing:
Code:
// create Chart
chart = new QChart();
chart->createDefaultAxes();
// costumize chart
dateTimeAxis = new QDateTimeAxis;
categoryAxis = new QBarCategoryAxis();
categoryAxis->append(categoriesList);
chart->addAxis(dateTimeAxis,Qt::AlignBottom);
chart->addAxis(categoryAxis, Qt::AlignLeft);
// hide casual axes
chart->axisX()->hide();
chart->axisY()->hide();
// use QChartView
myChartView = new QChartView(chart);
// promote to QMainWindow
layout->addWidget(myChartView);
myWidget->setLayout(layout);
setCentralWidget(myWidget);
///////////////////
// generate some life
lowerSeries = new QLineSeries();
upperSeries = new QLineSeries();
area = new QAreaSeries(upperSeries, lowerSeries);
area->attachAxis(dateTimeAxis);
area->attachAxis(chart->axisY());
p2
= QPointF(QDateTime::currentTime.
addSecs(rand_N_ofSec
).
toMSecsSinceEpoch(),
1);
p4
= QPointF(QDateTime::currentTime.
addSecs(rand_N_ofSec
).
toMSecsSinceEpoch(),
5);
lowerSeries << p1 << p2;
upperSeries << p3 << p4;
// now the problem:
tag->setText("any text to describe the point");
// how toset the location of the tag properly (near the point)?
i.e. the point is at (30,60) I'd like to set the tag on (31,61)
a typical QPointF on the chart would look like
Code:
qDebug() << "p:" << p;
p
: QPointF(1.51138e
+12,
3) // strange numbers due to toMSecSinceEpoche()
Thanks in advance, Lars
Re: QChart + QDateTiemAxis, mapTo and mapFrom
What's wrong with "tag->setPos(1.51138e+12, 3);" ? Those are the world coordinates of your axes. And if that doesn't work, then use the QPointF returned by mapToValue(), using the world coordinates and the series as arguments to the method.
Re: QChart + QDateTiemAxis, mapTo and mapFrom
Hey d_stranz,
very glad to hearing from you. One of your replies brought me here.
That is exactely my question. No, unfortunately it doesn't work like this. To me it seems that p=(1.51138e+12, 3) are the "inside-chart-coordinates". I can obtain them using mapFromScene(). I tried a little bit around and I approach the point doing tag->setPos(400, 300); Now: how to map from (1.51138e+12, 3) to (400, 300). I didn't find a way after all.
The "why" is more than clear due to http://www.qtcentre.org/threads/6145...light=d_stranz
cheers, Lars
Re: QChart + QDateTiemAxis, mapTo and mapFrom
Hey d_stranz,
very glad to hearing from you. One of your replies brought me here.
That is exactely my question. No, unfortunately it doesn't work like this. To me it seems that p=(1.51138e+12, 3) are the "inside-chart-coordinates". I can obtain them using mapFromScene(). I tried a little bit around and I approach the point doing tag->setPos(400, 300); Now: how to map from (1.51138e+12, 3) to (400, 300). I didn't find a way after all.
The "why" is more than clear due to http://www.qtcentre.org/threads/6145...light=d_stranz
cheers, Lars
Added after 1 55 minutes:
Hey d_stranz,
I fixed the code a littel so you perhaps can try out.
Code:
// PRO-File
QT += core gui \
widgets \
charts
TEMPLATE = app
SOURCES += main.cpp\
// cpp-file
#include <QApplication>
#include <QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QDateTimeAxis>
#include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis>
#include <QtCharts/QAreaSeries>
#include <QtWidgets/QGraphicsView>
#include <QtCharts/QChartGlobal>
#include <QTime>
#include <QDebug>
#include <QHBoxLayout>
QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
// obtain time first
// create Chart
QChart *chart = new QChart();
chart->legend()->hide();
chart->setMinimumSize(640, 480);
chart->createDefaultAxes();
// costumize chart a little
QDateTimeAxis *dateTimeAxis = new QDateTimeAxis;
dateTimeAxis->setTickCount(7);
dateTimeAxis->setFormat("hh:mm");
dateTimeAxis->setTitleText("Time");
dateTimeAxis->setMin(currentTime.addSecs(-3600));
dateTimeAxis->setMax(currentTime.addSecs( 3600));
// config axes
categories << "Paris" << "London" << "Berlin" << "Madrid";
QBarCategoryAxis *categoryAxis = new QBarCategoryAxis();
categoryAxis->append(categories);
chart->addAxis(dateTimeAxis,Qt::AlignBottom);
chart->addAxis(categoryAxis, Qt::AlignLeft);
chart->axisY()->setRange(0, categories.length());
// use QChartView
QChartView *myChartView = new QChartView(chart);
// promote to QMainWindow
layout->addWidget(myChartView);
window->setLayout(layout);
mainwindow->setCentralWidget(window);
///////////////////
// add some life
QLineSeries *lowerSeries = new QLineSeries();
QLineSeries *upperSeries = new QLineSeries();
QAreaSeries *area = new QAreaSeries(upperSeries, lowerSeries);
area
->setBrush
(QColor(100,
100,
100,
100));
chart->addSeries(area);
area->attachAxis(dateTimeAxis);
area->attachAxis(chart->axisY());
QPointF p2
= QPointF(currentTime.
addSecs(2400).
toMSecsSinceEpoch(),
1);
QPointF p4
= QPointF(currentTime.
addSecs(2400).
toMSecsSinceEpoch(),
2);
lowerSeries->append(p1);
lowerSeries->append(p2);
upperSeries->append(p3);
upperSeries->append(p4);
// now the problem:
// first try
position = chart->mapToPosition(p1, lowerSeries);
x = x.setNum(position.x());
y = y.setNum(position.y());
tag1->setText(x + " " + y);
tag1->setPos(position);
// approach randomly
x = x.setNum(position.x());
y = y.setNum(position.y());
tag2->setText(x + " " + y);
tag2->setPos(position);
mainwindow->show();
return a.exec();
}
Should work out of the box.
As you, or of course anybody else, might figure out this is supposed to be something like a timeline. I'd like to label the shown elements. If you (or anybody else) know a better way, the input would be highly appreciatet. QAreaSeries unfortunately has no setText(). I really struggled a lot.
Regards, Lars
Re: QChart + QDateTiemAxis, mapTo and mapFrom
OK, here it is:
Code:
QPointF position
= tag1
->mapFromParent
( chart
->mapToPosition
( p1
) );
tag1->setPos( position );
Note that when you resize the window, the label doesn't move because it has been put into a fixed pixel position on the chart. You will need to implement resizeEvent() for the view and in that method you must recalculate the positions and move all the labels.
Also note that the origin (0,0) for the text is the upper left corner of the text's bounding rect. If you want the text to be closer to the actual series point, you'll need to adjust this. For example, this roughly centers the text on the point:
Code:
QPointF position
= tag1
->mapFromParent
( chart
->mapToPosition
( p1
) );
QRectF tagRect
= tag1
->boundingRect
();
position.setX( position.x() - tagRect.width() / 2 );
position.setY( position.y() - tagRect.height() / 2 );
tag1->setPos( position );
Re: QChart + QDateTiemAxis, mapTo and mapFrom
Oh Yeahhhhh,
that is pretty much what I needed. Thanks a million d_stranz. I am aware of the resize problem. Now I am at that stage to take care about that. Also thank you for the 2nd snippet. Very useful.
Most likely I'll use qlabel anyway since this can carry a pixmap.
cheers, Lars