Solved More flexible chart axis labels
-
I am currently using
ValueAxis
for the X axis of a charting application.The data is updated dynamically to plot the progress of some background activity as new data comes in. The X axis represents something like an iteration count so it should always be integer. Therefore, I have to do some work to set the tick count and the upper range of the axis so that the labels always come out as integers.
In addition, I would like some more flexibility in what I am displaying for the labels. Rather than simply showing an integer value I would like to map it to something more meaningful for the application. This leads me to wonder about using
CategoryAxis
.I have not tried very hard so far but I did do an initial experiment where I replaced my current
ValueAxis
X axis with a hard codedCategoryAxis
(so no attempts to do anything dynamic) and even that is not working for me. I am wondering whether it even makes sense to try to use aCategoryAxis
as an X axis in this way - the example I have seen all use it for a Y axis.However, assuming I have just made a mistake in the above and there is not a fundamental problem, I am concerned that
CategoryAxis
does not seem to be very well suited to dynamic updates in the same way thatValueAxis
is. Although it is possible to append to the labels, it will periodically be necessary to completely respecify the labels (for example, consider that when the iteration count is 10, I might want to show labels at intervals of 2, but when it is 100 I might want to show them at intervals of 20). The API would seem to require that I delete all labels and redefine them each time I wanted to adjust the axis.Before I spend a lot of time on this, I was wondering if anyone had an experience of trying to do anything like this and whether it is likely to work.
-
Well I did spend a little more time on this. I found why my basic attempt with hard coded
CategoryRange
did not work. I also needed to setmin
andmax
on the axis, which is interesting as these properties are currently undocumented, though they are referenced in the code of at least one of the Qt examples I looked at. Perhaps this will be useful information for someone at some point.Having resolved that, I also tried out some "pseudo-dynamic" behaviour, whereby I dynamically added labels as the X range of arriving data increased beyond the current axis range. This seemed to work well performance-wise, though obviously the labels become increasingly bunched up. Next step is to try what I really want to do which is to respecify the complete set of labels when the X range hits certain sizes.
-
For now, I am updating the axis labels when the number of labels reaches some threshold - in my case, 10. At this point, I prune every other label and double the step interval for appended labels. Thus I have between 5 and 9 labels at any one time. This appears to work reasonably well.
CategoryAxis { id: axisX labelsPosition: CategoryAxis.AxisLabelsPositionOnValue startValue: 0 min: 0 max: 10 property var stepInterval: 2 // Hard code initial set of 5 labels CategoryRange { label: "2" endValue: 2 } ... CategoryRange { label: "10" endValue: 10 } } Connections { target: chartData onNpointChanged: { if (chartData.npoint > axisX.max) { // Reached end of axis - extend by current step interval axisX.max += axisX.stepInterval; axisX.append(axisX.max.toString(), axisX.max); } if (axisX.count === 10) { [ ... prune even indexed label using axisX.remove() ] axisX.stepInterval *= 2; } } }