PDA

View Full Version : QwPlottMultiBarChart determining legend title of bar segment under cursor



Buffy
23rd September 2014, 08:14
Some of my users QwtPlotMultiBarCharts are very complicated and it's not always easy to determine the legend title for each small section of each bar. They would like to be able to hover over a bar section and have the program show the legend title as a tool tip. If the performance is too slow, I can change the implementation to having the user click first and then display the text.

I'm overloading QwtPlotPicker::trackerTextF() trying to display the legend title of the bar section that is under the cursor.

I've successfully overloaded the trackerTextF() so that my method is being called rather than the QwtPlotPicker version.
I've successfully accessed the QwtPlotMultiBarChart::legendData & I see all my legend titles.

My problem is determining what section of the bar is under the cursor. I thought at first I could loop through the series data and find what is under the cursor based on the x and y coordinates but this doesn't work since sometimes the multi bars are stacked and sometimes they are grouped. Is there a way to ask qwt what is under the cursor? What am I missing?

Any help in accomplishing this task would be greatly appreciated.

Uwe
23rd September 2014, 08:44
I've successfully accessed the QwtPlotMultiBarChart::legendData & I see all my legend titles.
So far you did what I would recommend - beside that you could also use QwtPlotMultiBarChart::barTitles() directly.


My problem is determining what section of the bar is under the cursor. I thought at first I could loop through the series data and find what is under the cursor based on the x and y coordinates but this doesn't work since sometimes the multi bars are stacked and sometimes they are grouped.
As you already found a way to identify the chart below the mouse you can easily identify if its current state is Grouped or Stacked. Not sure why this is a problem - beside, that you need different implementations for both modes ?

But maybe it is a better idea to introduce a lookup table with the geometries of each bar:


class YourChart: public QwtPlotMultiBarChart
{
virtual void draw( QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &canvasRect ) const
{
m_barGeometries.clear();
QwtPlotMultiBarChart::draw( painter, xMap, yMap, canvasRect );
}

virtual void drawBar( QPainter *painter,
int sampleIndex, int valueIndex, const QwtColumnRect &rect ) const
{
m_barGeometries.store( sampleIndex, valueIndex, rect );
QwtPlotMultiBarChart::drawBar( painter, sampleIndex, valueIndex, rect );
}

QwtText barTitleAt( QPoint &pos ) const
{
// find sampleIndex/valueIndex from m_barGeometries
// and return the title using barTitles()
...
}
private:
LookUpTable m_barGeometries;
};

As you need widget coordinates fro barTitleAt() you would have to overload QwtPlotPicker::trackerText() instead of QwtPlotPicker::trackerTextF().

Uwe

Buffy
23rd September 2014, 19:31
Uwe,
Thanks so much for the quick response. Now it's making more sense and I like the idea of the lookup table and saving this information during creation. This will remove my problems with the current state and will also help me when things are zoomed and/or panned in. I'll give it a try.
Buffy

tcw321
31st July 2015, 15:49
I have a similar need but to display the y value of the bar when hovering. I am trying to use the hint from Uwe, but am a little lost. How does the m_barGeometries know if a QPointF is in a given bar? The LookUpTable class has the sampleIndex, valueIndex and QwtColumnRect. I thought I could get the QRect from QwtColumnRect and check if the rect contains point. However, rect seems to have only a relative size and not tied to the plot. All my stored QRect objects all have the same size 9x13 with xp and yp equal zero.

I am new to Qwt and any help on how to determine if mouse location is over a specific bar would be greatly appreciated.

Thanks

Tim

tcw321
31st July 2015, 20:26
I found a few problems with my solution. First of all, if sampleIndex was -1 then I should not store it in the look up table. I guess that draw call is for the legend. Second, the coordinate system that the QwtColumnRect contains is the same as the output of trackerPosition(). So I don't need to inverse transform it. I can use it directly in the QRectF object returned by QwtColumnRect. I just call QRectF::contains(pos) and it works.

Regards

Tim

gjmontagner
10th November 2015, 22:08
class YourChart: public QwtPlotMultiBarChart
{
virtual void draw( QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &canvasRect ) const
{
m_barGeometries.clear();
QwtPlotMultiBarChart::draw( painter, xMap, yMap, canvasRect );
}
};

Uwe

Hi Uwe!
Uh, I might be missing something. But how can I clear the lookup table if the method is const?
btw, thank you for your responses at qt forums, which I have been coming back to every once and again for the past weeks.

Uwe
13th November 2015, 10:43
Well this more a C++ question: check the "mutable" keyword.

Uwe