This one is trivial, since everything is there already:
Replace the QGraphicsSimpleTextItem with a ChartTextItem.
Only few functions have to be renamed.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since there are no disk-segment QSG primitives (one could draw
a triangle fan, but that doesn't seem optimal), this draws
into a pixmap and blits that as a QSG node.
Since this is the only series without axis, it needs a function
that returns the size of the plot area. This didn't exist, so
add it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Render the confidence area and the regression line into a pixmap
and show that using a QSGNode.
It is unclear whether it is preferred to do it this way or to
triangulate the confidence area into triangles to be drawn by
the shader.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
So far the items to be recalculated in the drawing thread
had a "dirty" flag and were kept in one array par z-level.
Once the series are implemented in terms of QSGNodes, there
may lots of these items. To make this more efficient when
only one or two of these items change (e.g. highlighting due
to mouseover), keep the dirty items in a linked list.
Of course, this makes the draw first version of the chart
less efficient.
There are more fancy ways of implementing the double-linked
list, but the few ns gained in the render thread are hardly
worth it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Render the labels and the title into a pixmap and render
the ticks and the base line using individual QSGNodes.
Attempting to render the ticks likewise into the pixmap
gave horrible results, because (quite obviously) rendering
with QPainter and the QSG shader gives non-matching ticks
and grid lines.
The memory management had to be changed a bit: The ChartItems
were collected in the root QSGNode. However, the axes are added
before the first plotting, so this node might not exist.
Therefore, store the axes in the StatsView object.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Slowly converting the QGraphicsScene items to QSGNodes to
avoid full replot of the scene.
This adds a new abstraction for line-nodes. Since the render()
function here is fundamentally different from the pixmap-nodes
we had so far, this has to be made virtual.
Also, move the quartile markers to their own source file,
since the StatsView source file is quite huge already.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The chart items were drawn in order of creation. To control this,
add a notion of Z-value. In contrast to QGraphicsScene, make
this a small integer value.
To controll order of drawing, a plain QSGNode is created for
every possible Z-Value and items are added to these nodes.
Thus, items are rendered by Z-value and if the Z-value is equal
by order of creation.
Likewise split the list of chart-items into Z-values, so that
items can be quickly unregistered: The items that will be
removed individually will usuall be part of Z-levels with only
few items (e.g. legend, infobox). Z-levels with many items
(notably the series) will always be fully rebuilt.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
A small step in converting from QGraphicsScene to QQuickItem.
This is the second item to be converted (after the legend)
and for now items are drawn in order of creation, which means
that the infobox is on top of the legend. This will have
to be made deterministic in follow-up commits.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Catch mouse move events and move the legend accordingly.
Currently, this is the only item that can be dragged and
therefore there is no need of doing some kind of fancy
interface. Simply keep a pointer to the legend if it is
dragged.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In order not to waste CPU by constantly rerendering the chart,
we must use these weird OpenGL QSGNode things. The interface
is appallingly low-level and unfriendly.
As a first test, try to convert the legend. Create a wrapper
class that represents a rectangular item with a texture
and that will certainly need some (lots of) optimization.
Make sure that all low-level QSG-objects are only accessed
in the rendering thread. This means that the wrapper has
to maintain a notion of "dirtiness" of the state. I.e.
which part of the QSG-objects have to be modified.
From the low-level wrapper derive a class that draws a rounded
rectangle for every resize. The child class of that must then
paint on the rectangle after every resize.
That looks all not very fortunate, but it displays a
legend and will make it possible to move the legend
without and drawing operations, only shifting around
an OpenGL surface.
The render thread goes through all chart-items and
rerenders them if dirty. Currently, on deletion
of these items, this list is not reset. I.e. currently
it is not supported to remove individual items.
Only the full scene can be cleared!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
I was coninced that that rather than doing an order of
magnitude estimate of the confidence region it's better
to have the correct concave shapes that indicate the
95% confidence level for the regression line.
It also turned out that the previous expression was
missing a factor of 1/sqrt(n).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
The goodness of fit of a regression line is the percentage
of the variance of the y values that is explained by the
dependence on the x values.
Set the alpha value of the regression line to this goodness
of fit.
Further, set the width of the regression line to a standard
deviation of the values from the regression line valies.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
It turns out that the wrong base class was used for the chart.
QQuickWidget can only be used on desktop, not in a mobile UI.
Therefore, turn this into a QQuickItem and move the container
QQuickWidget into desktop-only code.
Currently, this code is insane: The chart is rendered onto a
QGraphicsScene (as it was before), which is then rendered into
a QImage, which is transformed into a QSGTexture, which is then
projected onto the device. This is performed on every mouse
move event, since these events in general change the position
of the info-box.
The plan is to slowly convert elements such as the info-box into
QQuickItems. Browsing the QtQuick documentation, this will
not be much fun.
Also note that the rendering currently tears, flickers and has
antialiasing artifacts, most likely owing to integer (QImage)
to floating point (QGraphicsScene, QQuickItem) conversion
problems. The data flow is
QGraphicsScene (float) -> QImage (int) -> QQuickItem (float).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The coordinates of these were calculated when creating the feature.
This is wrong, because the min/max values of the axes can change
on resize to get "nice" number. Therefore, recalculate after resizing.
This means that the general "LineMarker" class has to be split into
two classes, one for regression lines and one for median/mean
markers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Replace by custom implementation, with the ultimate goal to
remove the QtCharts module. This doesn't yet display axis
titles or a grid.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Since we want to get rid of QtCharts, we have to render our own
title. Simply keep around a QGraphicsSimpleTextItem and put in
the center of the chart. Define the borders to the scene as
constants.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
A steep regression line would shoot out of the chart. Therefore,
clip to the y = minY and y = maxY lines.
QtGraphicsScene has its own clipping routines, but they are
very general, so let's do this trivial case by hand.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The StatsView shows the chart described by the StatsState structure.
It is based on a QML ChartView. This should make it possible to
easily port to mobile. It does not include any of the UI around
the chart, viz. the variable and chart selection, etc.
The code checking for the statistical significance of the regression
line was written by Willem.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: willemferguson <willemferguson@zoology.up.ac.za>