This should be simple; is there a way to show all labels on xBottom axis? I'm currently doing some stuff with QwtPlotHistogram and some labels are hidden when I have lots of columns
This should be simple; is there a way to show all labels on xBottom axis? I'm currently doing some stuff with QwtPlotHistogram and some labels are hidden when I have lots of columns
I think you (and others) might be confusing QwtPlotHistogram with a bar chart (like Microsoft Excel creates). A QwtPlotHistogram is a way to display x-y data as a series of sticks, so all the normal rules for axis labels are applied: choose a set of major tick divisions that creates a "nice" numerical series, and don't plot a label if it would overlap with another label.
This is not the kind of behavior desired for a bar chart, because the x-axis isn't a numerical axis, it is a category axis, and you want to see all the labels for the categories.
If you want to change this behavior, then you will have to implement your own axis scale classes for the x axis. This is not really an easy job; you will have to implement a QwtScaleEngine::divideScale() that returns a QwtScaleDiv with a QwtValueList containing a value for every tick label you want to show. You may also need to implement a custom QwtScaleDraw class that will force labels to overlap (or do something fancier like stack them in a staggered fashion).
It can be done; I did this once for an application that plotted dendrograms inside a QwtPlot. The axis at the leaf end of the dendrogram had to label each leaf with its name. It took a long time to understand how the QwtScale... classes are implemented, how they work together, and how to get them to work correctly along with zooming, panning, and magnification.
In the attached ZIP file are the classes derived from QwtScaleEngine and QwtScaleDraw. The QwtScaleDraw class was needed to ensure all of the leaf labels were cached and would be drawn, as well as giving individual labels different colors depending on the color-coding of the dendrogram sub-trees. The axis is defined to have a real interval equal to the number of leaves in the dendrogram; if there are 100 leaf nodes, the axis scale goes from 0 - 100 (or maybe -0.5 - 100.5 to make sure the end-most leaf labels are within the ends of the axis). So, the scale engine class takes this range, turns it into an integer range, then creates a scale division for each integer.
This is basically the same thing you will have to do to make a label visible for every stick in the QwtPlotHistogram. Substitute "stick" for "leaf", and it's all the same.
Thank you, I had already implemented a QwtScaleDraw derivate class that places text labels where I want
Qt Code:
{ public: BarChartScaleDraw(QMap<double,QString> *x) : ids(x) { enableComponent(QwtAbstractScaleDraw::Ticks, false); } { if (ids->contains(v)) return ids->find(v).value(); else return ""; } private: QMap<double,QString> *ids; };To copy to clipboard, switch view to plain text mode
Apparently combining my class with your scale engine did the trick
One more question, how can I reset the scale engine?
Last edited by Patrik; 18th January 2011 at 10:42.
I am not sure I know what you mean by "reset". When the axis scale is changed (by a zoom/pan/magnify or by an appplication call to QwtPlot::setAxisScale()), the scale engine's divideScale() should automatically be called by the framework when the plot is updated.
Perhaps you are having a problem because the QwtAbstractScaleDraw class caches the labels. In your QtScaleDraw class, after you change the label values call the invalidateCache() method (a protected method in QwtAbstractScaleDraw). This will force a recalculation of the labels. See my example code posted earlier.
You don't show it in your code, but if your scale draw class has a method for updating your label map (other than in the constructor), you should call invalidateCache() before exiting that method. Probably wouldn't hurt to do it in the constructor as well.
Bookmarks