.. the generic plot didn't register quadtrees if it thought they didn't
contain any nodes, but didn't take into account the fact the root
node could contain up to 25 points.
.. allow data labels for points on the chart, added to User, R and
Python chart addCurve() etc.
.. NOTE: opengl painting ignores this setting so should be disabled
for data series that want labels. We do not do this
automatically, but might consider that later.
.. add annotation labels from within a datafilter, ultimately
gets shown alongside the legend in generic plot.
.. this only works from a user chart, so need to add an equivalent
API to call from Python and R.
.. when adding symbols to lines or lines to a scatter we
need to show/hide the decoration with the main series.
.. in addition if the decoration is the only thing visible
e.g. symbols for line (with no line style) then still
need to show the hover on the symbols.
.. honour both the symbol and line style settigns for curves. This
means you can have a series on a line chart that is dots and a
series on a scatter that is a line.
.. need to think about best way to manage hover, but suspect it should
only apply when a line chart has a series with no line but has
symbols -- we should hover on them. Currently they are ignored.
.. you can now configure if a series is shown on the legend, this is
for lines or curves that are there for illustration but do not
need to be displayed in the legend / hovered.
.. support for axes that are time based, assuming the user has
supplied in seconds starting from 0 (which is true for an
activity).
.. since QT charts requires times to be in MS since Epoch
and we don't know if we need to convert from seconds
until the axis is configured the series data is updated
just before charts are created in GenericChart.
This means that anyone using generic plot directly will
need to do this conversion. For this reason all integration
across the GC codebase should be via GenericChart.
R, Python and now User charts integrate via Generic Chart
so this should not really be an issue.
.. basic user chart only on analysis view. Users can specify
a data filter script to prepare data for the x and y axes.
It uses the generic chart to visualise so one step closer
to a UX where all charts have the same behaviour.
.. will need to update to place on trends view, including
updating the way userdata works and possibly adding a
few new functions to support working with models and mmp
data amongst a few other things.
.. likely contains quite a few nits as most of the code
is related to configuration and is a bit thorny.
Fixup stack view a) minimum height for plots, b) added a
scroll area to manage more plots than fit on the screen
and will layout horizontally or vertically.
Stack charts now when set as an option, in which case all
data series are given their own plot.
Or alternatively, where data series have different x-axis
names, they get a plot for each x-axis.
Need to fixup a) minimum height as can get squashed and
b) scroll area needed as well as c) layout direction.
.. updated to support different linestyles and also legend can
now be placed above, below, left or right of the chart and
orientated to list series vertically or horizontally.
.. the vertical legend is a bit ugly as nothing lines up, will
fix up separately.
Isolate curves by hovering on axis for scatter and line
charts. Also added horizontal guide line and click to
add horizontal annotations (but not added yet).
Annotations will come later, but added as was the right
part of the code.
Also tidied up a bit of the paint code in selection tool
since it was a bit messy.
.. for some reason in earlier version of Qt Charts there are errant
items in the same area as the axes that are blank, these break
the code that derives the axes rectangles in Qt Charts <= 5.10
.. now we have the axis rectangle (previous commit) we can paint
the cursor values in the axis rather than on the canvas. Lots
of work to fix a cosmetic issue, but damn, it was worth it.
.. amongst a few other nits when a plot is resized or the chart is
being finalised we get the scene rectangle for each of the axes.
This is so we can trap when the mouse hovers over an axis and
also so we can paint the current mouse coordinates on the y-axis
in the scatter plot (they are painted on the canvas at present
and paint over each other causing a nasty artefact).
Will fixup y-value cursor tracking shortly.
Use legend to select which series are plotted by clicking to
show hide a series. Hover just shows a hover background and
does not temporarily isolate the series, this may be something
to consider for later.
Applies to scatter and line charts.
.. created separate source files for the legend and selection tool
classes and removed some of the interdependency.
.. partly because GenericPlot.h and GenericPlot.cpp were becoming
unwieldy and partly to support using the generic legend in
other charts (notably CP, LTM and AllPlot).
The scene was being updated unneccessarily when it was active but
not changing (i.e. selection rectangle was stationary etc).
Added a state variable rectchanged to the selection tool to notify
the updateScene() method that nothing has changed since the last
event. So do nothing.
Added selection on line chart, uses a range selector and
works in pretty much the same way as the scatter rectangle
selector.
I've removed a lot of the calculated values from the plot
since it gets very busy very quickly.
I also noticed there is a significant performance problem
when selections are active- suspect there are a large
number of unneccessary scene updates. Will investigate.
.. when no value present was miscalculating the nearest point to the
cursor on the x-axis because distance was calculated as a large
negative by using a series point value of 0 (when no value was
available). Fixed by just ignoring zero values.
Added hover code to line chart, so get legend values on hover
and marker points as you mouse over the series and an x-axis
label at the bottom to show current x value.
Also added Utils::removeDP() to remove decimal places from a
number string e.g. 24.000 becomes 24, 987.3440500 becomes
987.34405. This is a hack to avoid handling decimal places
in the user settings, but will keep as reduces the amount
of "digital ink" regardless.
.. recent fix to check for points on the boundary (checking with >=
and <= instead of > and <) mean't that items on the boundary
would be inserted into multiple quadrants. This wasn't much of
and issue as only using quadtree for mouse hover, but it is a
bug none the less and needed fixing.
.. compile time warning nits also tidied up for new code, to stop
errors spewing on build and hiding real issues.
Added new legend which displays hover over value from the
prior commit. Also fixed up the quadtree issue with some
points being hard to hover.
Need to consider what to do with multiple x-axes; am tempted
to create a new chart for each x-axis since hover and general
interaction gets very messy with multiple x-axes.
Next commit will extend the current functionality onto line
charts before we move onto hover for pie and bar charts.
Hover now wired into the SelectionTool with scatter points
being highlighted as you move the mouse. The code to select
nearest neighbours looks correct, but in practice it can
be hard to select some points (this needs further investigation).
Highlighting the selected point is done in the paint method
of the selection tool (its just one dot), but zorder issues
with opengl accelerated series means it appears underneath
we may need to create a curve with one point to avoid this
(this also needs further investigation).
Need to work next on a legend widget of our own to manage
the hover display and axis interaction (and better aesthetics
than the standard offerings).
When curves are painted via openGL there are a number of limitations
regarding aesthetics, setColor() doesn't work once the series is
created, opacity is ignored etc.
So when we create a selection from an openGL enabled curve we cannot
set it gray etc. Instead, this commit will set the selection curve
to gray and use opengl rendering on the selection (on the assumption
that the user specified opengl rendering for performance and so we
should reflect that in the selection curve).
This has a dramatic improvement in performance on a scatter plot of
activity data where there are 1000s and 10000s of points in some
cases.
We should recommend that opengl is enabled for curves that have large
number of points, and indeed, the default is to enable it unless the
user specifically overrides (e.g. for better aesthetics).
Added Quadtree for identifying points on the plot when
hovering with mouse, but should also be reused for the
rect selection tool (it currently iterates over all points
for a series).
This commit just adds basic algorithm will need to follow
up with a) refactor it into the selection tool and
b) display the hover value somewhere (legend?)
.. the chart was being redrawn as series added because initialiseChart()
was removing axes, be waiting until finaliseChart() to do this we
avoid the flicker.
.. My eyes! My eyes! Tuft would not be impressed with all the
extraneous plotting and noise from the selection tool that
detracted from the data.
Have removed the guide lines, limited the slope line to the
selection rectangle, and toned it down as well as making the
selection rectangle more subtle when its not being manipulated.
SelectionTool now calculates a bunch of useful values
for the selected items (mean, min, max etc) and they
are plotted with guidelines on the scatter plot wehen
a selection is active.
Added a rectangle selection tool for scatter charts. Click on
the canvas and drag to highlight points of interest and click
on rectangle to drag around, resize with wheel events.
Additionally, improved some of the aesthetics on axes and labels
etc to make the chart look and feel similar to the rest of the
qwt based charts.
There are likely to be a large number of commits for part 3, to
cover auto calculation of mean/max/sum/regree for selected points
and extend to other types of selections and apply to other chart
types.
.. the qchart code is now becoming more generic, with interactivity
and generalised rendering so refactored out into its own class
before adding too much more code.
.. this is also because we will be creating a generic chart for users
to plot their own 'userdata' (currently in allplot/trends charts)
using this generic plot and want to have a common widget for this
to get a more consistent and less jarring user experience.