PDA

View Full Version : Gantt charts with QWT ?



thejester
7th April 2011, 10:21
Has anyone ever tried to create a Gannt like chart with QWT ?

See also this thread: http://www.qtcentre.org/threads/31753-Mouse-Interactive-Gantt-Chart-in-Qt

Uwe
8th April 2011, 07:39
A QwtPlotIntervalCurve with a symbol in QwtIntervalSymbol::Box style should be pretty close to the screenshot of your linked thread. But I guess you want to display more than the interval bars only.

Uwe

thejester
11th April 2011, 08:04
Hi Uwe,

Thanks for your reply.
I will give your idea a try.

The bars are fine. If i can show some 'name' of the tasks that was running on the Y-axis that would be great.

The input of my chart would be (still guessing, dont have anythng yet):

<task>
<id>waiting for trigger</id>
<starttime> 123123123123 </starttime>
<stoptime> 123123123223 </stoptime>
</task>

I can browse the file, and collect all events of the same id, and display them on the same curve, if i can then display the "waiting for trigger" on the y asis label, were good.

Thanks, sorry for the extra info.

thejester
13th April 2011, 12:53
Hi Uwe,

I've tried to follow your lead:

QVector<QwtIntervalSample> samples;
samples.append( QwtIntervalSample( 10, 8, 12 ) );
samples.append( QwtIntervalSample( 2, 3, 7 ) );
samples.append( QwtIntervalSample( 18, 17, 20 ) );

QwtIntervalSymbol symbol( QwtIntervalSymbol::Box );
QwtPlot *myPlot = new QwtPlot( NULL );

QwtPlotIntervalCurve *curve1 = new QwtPlotIntervalCurve("Curve 1");
curve1->setSymbol( &symbol );
curve1->setSamples( samples );
curve1->attach( myPlot );
curve1->setStyle( QwtPlotIntervalCurve::NoCurve );


for example : samples.append( QwtIntervalSample( 10, 8, 12 ) );
draws a box on X position 10, ranging from Y value 8 to 12. (e.g. a vertical box).
The interval is defined as [y1-y2]=f(x).

Any way to swap the x and y axis ?
Better idea ?

Thanks for any help.

Uwe
13th April 2011, 13:10
Any way to swap the x and y axis ?

curve1->setOrientation( Qt::Horizontal );

Uwe

thejester
13th April 2011, 14:07
Thanks, got it up and running !

Uwe, you're the best !

thejester
20th April 2011, 10:43
Uwe,

Couple more questions...

1) i have created a TaskNamesDraw derived from QwtScaleDraw that draws the names on the y-axis, to get the same as in the other gannt thread (http://www.qtcentre.org/threads/31753-Mouse-Interactive-Gantt-Chart-in-Qt). This is working as expected, except that only major ticks are drawn. For example if Yvalues range from 0 to 10, then only 0, 2, 4 etc. are drawn, but not the 1, 3, etc. How can i make it draw ALL labels ?

2) In stuff we talked about earlier we had the samples we provided to the plot defined as :
samples.append( QwtIntervalSample( 10, 8, 12 ) );
samples.append( QwtIntervalSample( 2, 3, 7 ) );
samples.append( QwtIntervalSample( 18, 17, 20 ) );

if i change this to :

samples.append( QwtIntervalSample( 10, 800000, 800100 ) );
samples.append( QwtIntervalSample( 2, 800400, 800500 ) );
samples.append( QwtIntervalSample( 18, 800600, 800700 ) );

i get 3 beautiful bars on the initial draw. If i zoom it it works perfectly;
When i zoom out (all the way to empty zoom stack), then the x-axis values are
somehow reset to 0...1000 and i loose my bars in the plot.
Is there some way to 'define' the overview x and y ranges ?

3) when zooming in, i only want x-axis zoom, not y-axis zoom.
How can i enforce this ?

Hope you can point me in the right directions that would be great.

Uwe
20th April 2011, 11:22
This is working as expected, except that only major ticks are drawn.
No all ticks are painted, but maybe you didn't define the ticks you are missing.


i get 3 beautiful bars on the initial draw. If i zoom it it works perfectly;
When i zoom out (all the way to empty zoom stack), then the x-axis values are
somehow reset to 0...1000 and i loose my bars in the plot.
This is a question you find many, many times answered in this forum:

The zoomer is initialized with the current state of the scales and 0.0->1000.0 is the default setting. Obviously you are changing the scales later and forgot to reinitialize the zoomer: See http://qwt.sourceforge.net/class_qwt_plot_zoomer.html#a7ee4f2a0606df6e85258c5 2f0b5c7bc2



when zooming in, i only want x-axis zoom, not y-axis zoom.
How can i enforce this ?
If you need one y axis only you can simply assign the other one to the zoomer: http://qwt.sourceforge.net/class_qwt_plot_picker.html#aa901c86543585c7056133a 5cb6652e3d

If not you have to reimplement QwtPlotZoomer::zoom( const QRectF & ), where you adjust the y coordinates and then call the base class.

Uwe

thejester
20th April 2011, 11:38
With the first question, i meant that the derived virtual QwtText label(double v) const of the special QwtScaleDraw is only called for values 0, 2, 4 etc. but not for 1, 3, etc. What do you mean by "but maybe you didn't define the ticks you are missing" ?

Uwe
20th April 2011, 11:43
When you are talking about the tick labels - not the ticks: yes, the labels are for major ticks only.

Uwe

thejester
20th April 2011, 12:34
ok, thanks.

Got the fixed y-axis zoom, independent of the x-axis zoom working, indeed by reimplementing the QwtPlotZoomer::zoom.
Also got the init of the zoomBase working.

The first problem is still giving me problems.
When i do : setAxisScale( QwtPlot::yLeft, 0, max, 1 ); and have the max set to the number of horizontal gannt lines it works.
But after a zoom in and out, they are gone again, and i end up with the labels on the major ticks.

How can i fix this ? connect the zoomed signal to a slot in the plot and call setAxisScale( QwtPlot::yLeft, 0, max, 1 ); again ?

Uwe
20th April 2011, 13:04
When i do : setAxisScale( QwtPlot::yLeft, 0, max, 1 ); and have the max set to the number of horizontal gannt lines it works.
But after a zoom in and out, they are gone again, and i end up with the labels on the major ticks.
In the end QwtPlotZoomer is a class that manipulates the scales using the same setAxisScale method you do in your application. That's why your scale is gone.

I recommend to overload QwtPlotZoomer::rescale to have complete control over the scale ticks. Simply copy the default implementation into your derived zoomer class, replace the internal stuff by using public getters and adjust the code to your needs.

Uwe

thejester
20th April 2011, 13:31
In the end QwtPlotZoomer is a class that manipulates the scales using the same setAxisScale method you do in your application. That's why your scale is gone.

I recommend to overload QwtPlotZoomer::rescale to have complete control over the scale ticks. Simply copy the default implementation into your derived zoomer class, replace the internal stuff by using public getters and adjust the code to your needs.

Uwe

Working, thanks !

Another problem is the dissapearing of boxes.

When you zoom in to the horizontal interval [ 20, 50 ], then boxes of interval [10, 22] are partially drawn, a box that belongs to interval [45, 60] is not drawn. Any idea ?

thejester
21st April 2011, 08:02
Hi Uwe,

Any idea on the dissapearing boxes ?

Thanks for all help !

thejester
21st April 2011, 12:05
Does QWT support a measurement tool ?

For instance if you press a mouse button at some location, move cursor somewhere else, it would be usefull to have an indication of the delta X and delta Y the user moved the mouse..

corrado1972
23rd April 2011, 10:29
Hi thejester
would you like to share your code with gantt charts that you implemented?

It could help us to understand in which code are you working on.

thanks

Uwe
25th April 2011, 21:15
Does QWT support a measurement tool ?
Use QwtPlotPicker.

Uwe

thejester
4th May 2011, 16:09
Thanks uwe, will look into that one. Does that support measuring distances between any two points in plot ? or can it be modified to do that ?

Another question.

We want to optimise the number of horizontal lines on the Gannt chart.
Each curve in our plot has a fixed y value. This Y value is simply an integer. It would be nice (at least for our implementation) if the distance between for instance 2.0 and 3.0 could be set to the height of the text label.

Is that somehow possible ?

Uwe
5th May 2011, 08:11
Does that support measuring distances between any two points in plot ? or can it be modified to do that ?
It controls and propagates the selection of points on the plot canvas and supports the selection with some sort of visual feedback. It is very configurable, what makes it sometimes hard to understand.

We want to optimise the number of horizontal lines on the Gannt chart.
Each curve in our plot has a fixed y value. This Y value is simply an integer. It would be nice (at least for our implementation) if the distance between for instance 2.0 and 3.0 could be set to the height of the text label.
The layout system works the other way round: the size for the plot is given and the rest is calculated from it. So what you need to do is to implement a sizeHint for your plot widget, that somehow calculates its height from the font metrics of your text labels, so that the plot gets the size you want to have.

Another option is of course to adjust your y axis scales according to the current height of the plot canvas. For this you have to install an event filter for the plot canvas and catch the resize events. But be careful with such an implementation because changing the scales might trigger additional resize events und you might run into recursions or ping-pong situations ( QwtPlotRescaler does something similar ).

Hm ... have a look at QwtPlotRescaler::Expanding and check the navigation example to see how it works. This might be a solution if you decide to adjust the scales of your y axis.

Uwe

thejester
5th May 2011, 08:52
Hi Uwe, thanks for the quick response!

For the distance measuring, I have started a separate thread since more people can find it and since it has nothing to do with Gannt.
See http://www.qtcentre.org/threads/41285-Distance-measuring-in-plot.

The other problem seems more difficult then expected. Have to think about that some more.