Page 1 of 2 12 LastLast
Results 1 to 20 of 31

Thread: Bar chart plotting using 2D graphics QPainter class

  1. #1
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Bar chart plotting using 2D graphics QPainter class

    I'm looking for examples of source code on 2D bar charts.
    Using Qt's 2D graphics engine which is based on the QPainter class.

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Create a QWidget subclass.
    Make it accept a list of numbers (the values of your chart).
    In the paint event, use a QPainter.
    Go over each number in the list, draw a rectangle based on that number and a predefined width.

    To fine tune it, create setters to change colors, widths, ...

  3. #3
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Any sample code would be helpful to me.
    Thank you.


    S.O.S

  4. #4
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Bar chart plotting using 2D graphics QPainter class

    All depends on what you want of course.
    But here's an example.

    Note: this example demonstrates how to draw a series of bars in a chart like style using a custom widget.

    This, however, will not scale and is very very inefficient.

    To create a better charting system, make full use of the model view design.
    Datapoints should not contain any more information than their actual values. In the example below, it also contains view parameters.

    Take for example the width of a bar. I added this parameter to the datapoint. I'm sure you can imagine another kind of chart that doesn't use the width to draw a datapoint.

    You might think, why not add it to the widget itself? That too is not a good idea because then it would be a lot of work to add new kinds of charts.

    Better is to make use of some kind of delegate.
    Your datapoints contain the usefull point information.
    The view handles the drawing.
    How things are drawn is the task of this delegate. You can have a barchart delegate, a piechart delegate etc...

    But, to keep things simple, here's an inefficient way to draw barcharts.

    screenshot.PNG

    datapoint.h
    Qt Code:
    1. #ifndef DATAPOINT_H
    2. #define DATAPOINT_H
    3.  
    4. #include <QtGlobal>
    5. #include <QColor>
    6. #include <QList>
    7. #include <QMetaType>
    8.  
    9. class DataPoint
    10. {
    11. public:
    12. DataPoint();
    13. DataPoint(qreal x, qreal Y);
    14.  
    15. void setX(qreal x);
    16. void setY(qreal y);
    17.  
    18. void setColor(const QColor &color);
    19. void setWidth(int width);
    20.  
    21. qreal x() const;
    22. qreal y() const;
    23.  
    24. QColor color() const;
    25. int width() const;
    26.  
    27. private:
    28. qreal m_x;
    29. qreal m_y;
    30. QColor m_color;
    31. int m_width;
    32. };
    33.  
    34. typedef QList<DataPoint*> DataPointList;
    35.  
    36. #endif // DATAPOINT_H
    To copy to clipboard, switch view to plain text mode 


    datapoint.cpp
    Qt Code:
    1. #include "datapoint.h"
    2.  
    3. DataPoint::DataPoint() :
    4. m_x(0),
    5. m_y(0),
    6. m_color(QColor(qRgb(200, 200, 200))),
    7. m_width(10)
    8. {
    9. }
    10.  
    11. DataPoint::DataPoint(qreal x, qreal y) :
    12. m_x(x),
    13. m_y(y),
    14. m_color(QColor(qRgb(200, 200, 200))),
    15. m_width(10)
    16. {
    17. }
    18.  
    19. void DataPoint::setX(qreal x)
    20. {
    21. m_x = x;
    22. }
    23.  
    24. void DataPoint::setY(qreal y)
    25. {
    26. m_y = y;
    27. }
    28.  
    29. void DataPoint::setColor(const QColor &color)
    30. {
    31. m_color = color;
    32. }
    33.  
    34. void DataPoint::setWidth(int width)
    35. {
    36. m_width = width;
    37. }
    38.  
    39. qreal DataPoint::x() const
    40. {
    41. return m_x;
    42. }
    43.  
    44. qreal DataPoint::y() const
    45. {
    46. return m_y;
    47. }
    48.  
    49. QColor DataPoint::color() const
    50. {
    51. return m_color;
    52. }
    53.  
    54. int DataPoint::width() const
    55. {
    56. return m_width;
    57. }
    To copy to clipboard, switch view to plain text mode 


    barchart.h
    Qt Code:
    1. #ifndef BARCHART_H
    2. #define BARCHART_H
    3.  
    4. #include <QWidget>
    5. #include <QPaintEvent>
    6. #include <QtGlobal>
    7.  
    8. #include "datapoint.h"
    9.  
    10. class BarChart : public QWidget
    11. {
    12. Q_OBJECT
    13. public:
    14. explicit BarChart(QWidget *parent = 0);
    15.  
    16. void setDataPointList(const DataPointList &pointList);
    17.  
    18. protected:
    19. void paintEvent(QPaintEvent *event);
    20.  
    21. signals:
    22.  
    23. public slots:
    24.  
    25. private:
    26. DataPointList m_dataPointList;
    27.  
    28. qreal maximumHeight();
    29. qreal maximumWidth();
    30.  
    31. qreal yAxisWidth();
    32. qreal xAxisHeight();
    33.  
    34. qreal spaceBetweenBars;
    35. qreal chartOuterMargin;
    36.  
    37. qreal dataPointHeight(qreal y);
    38.  
    39. void drawEmptyBarChart(QPainter *painter);
    40. void drawYAxis(QPainter *painter);
    41. void drawXAxis(QPainter *painter);
    42. void drawDataPoints(QPainter *painter);
    43. };
    44.  
    45. #endif // BARCHART_H
    To copy to clipboard, switch view to plain text mode 


    barchart.cpp
    Qt Code:
    1. #include "barchart.h"
    2.  
    3. #include <QPainter>
    4. #include <QFontMetricsF>
    5. #include <QPointF>
    6. #include <QPen>
    7. #include <QBrush>
    8.  
    9. BarChart::BarChart(QWidget *parent) :
    10. QWidget(parent)
    11. {
    12. spaceBetweenBars = 5;
    13. chartOuterMargin = 10;
    14. }
    15.  
    16. void BarChart::setDataPointList(const DataPointList &pointList)
    17. {
    18. m_dataPointList = pointList;
    19. update();
    20. }
    21.  
    22. void BarChart::paintEvent(QPaintEvent *event)
    23. {
    24. QWidget::paintEvent(event);
    25.  
    26. QPainter painter(this);
    27.  
    28. if (m_dataPointList.isEmpty())
    29. drawEmptyBarChart(&painter);
    30. else {
    31. drawXAxis(&painter);
    32. drawYAxis(&painter);
    33. drawDataPoints(&painter);
    34. }
    35. }
    36.  
    37. qreal BarChart::maximumHeight()
    38. {
    39. qreal height = 0;
    40.  
    41. foreach(DataPoint *point, m_dataPointList) {
    42. if (point->y() > height)
    43. height = point->y();
    44. }
    45.  
    46. return height;
    47. }
    48.  
    49. qreal BarChart::maximumWidth()
    50. {
    51. qreal width = 0;
    52.  
    53. foreach(DataPoint *point, m_dataPointList) {
    54. width += point->width() + spaceBetweenBars;
    55. }
    56.  
    57. return width;
    58. }
    59.  
    60. qreal BarChart::yAxisWidth()
    61. {
    62. QString maximumValue = QString::number(maximumHeight());
    63. QFontMetrics fm(font());
    64. qreal textWidth = fm.width(maximumValue);
    65.  
    66. return textWidth + 5;
    67. }
    68.  
    69. qreal BarChart::xAxisHeight()
    70. {
    71. QFontMetrics fm(font());
    72. qreal textHeight = fm.height();
    73.  
    74. return textHeight + 5;
    75. }
    76.  
    77. qreal BarChart::dataPointHeight(qreal y)
    78. {
    79. QFontMetrics fm(font());
    80. qreal textHeight = fm.height();
    81.  
    82. return y * ((height() - (2 * (chartOuterMargin + (textHeight / 2))) - xAxisHeight()) / maximumHeight());
    83. }
    84.  
    85. void BarChart::drawEmptyBarChart(QPainter *painter)
    86. {
    87. QString text("No datapoints available!");
    88.  
    89. qreal centreX = width() / 2;
    90. qreal centreY = height() / 2;
    91.  
    92. QFontMetricsF fontMetrics(font());
    93. qreal textWidth = fontMetrics.width(text);
    94. qreal textHeight = fontMetrics.height();
    95.  
    96. qreal textX = centreX - (textWidth / 2);
    97. qreal textY = centreY - (textHeight / 2);
    98.  
    99. painter->drawText(QPointF(textX, textY), text);
    100. }
    101.  
    102. void BarChart::drawYAxis(QPainter *painter)
    103. {
    104. QPen yAxisPen(QColor(qRgb(0, 0, 0)));
    105.  
    106. QString maximumValue = QString::number(maximumHeight());
    107. QFontMetrics fm(font());
    108. qreal textWidth = fm.width(maximumValue);
    109. qreal textHeight = fm.height();
    110.  
    111. qreal yAxisX = chartOuterMargin + textWidth + 5;
    112. qreal yAxisY = chartOuterMargin + (textHeight / 2);
    113. qreal yAxisHeight = height() - yAxisY - xAxisHeight();
    114.  
    115. painter->save();
    116.  
    117. painter->setPen(yAxisPen);
    118. painter->drawLine(QPointF(yAxisX, yAxisY), QPointF(yAxisX, yAxisHeight));
    119.  
    120. painter->drawLine(QPointF(yAxisX - 3, yAxisY), QPointF(yAxisX, yAxisY));
    121. painter->drawLine(QPointF(yAxisX - 3, yAxisHeight), QPointF(yAxisX, yAxisHeight));
    122.  
    123. painter->drawText(QPointF(chartOuterMargin, chartOuterMargin + textHeight), maximumValue);
    124. painter->drawText(QPointF(chartOuterMargin, height() - chartOuterMargin - xAxisHeight()), "0");
    125.  
    126. painter->restore();
    127. }
    128.  
    129. void BarChart::drawXAxis(QPainter *painter)
    130. {
    131. QPen xAxisPen(QColor(qRgb(0, 0, 0)));
    132.  
    133. QFontMetrics fm(font());
    134. qreal textHeight = fm.height();
    135.  
    136. qreal xAxisX = chartOuterMargin + yAxisWidth();
    137. qreal xAxisY = height() - xAxisHeight() - chartOuterMargin - (textHeight/2);
    138. qreal xAxisWidth = xAxisX + maximumWidth() + spaceBetweenBars;
    139. painter->save();
    140.  
    141. painter->setPen(xAxisPen);
    142. painter->drawLine(QPointF(xAxisX, xAxisY), QPointF(xAxisWidth, xAxisY));
    143.  
    144. qreal xAxisMark = xAxisX + spaceBetweenBars; // Keep some space between the first bar and the Y axis
    145.  
    146. foreach(DataPoint *point, m_dataPointList) {
    147. xAxisMark += point->width()/2;
    148.  
    149. painter->drawLine(QPointF(xAxisMark, xAxisY), QPointF(xAxisMark, xAxisY + 3));
    150.  
    151. QFontMetrics fm(font());
    152. qreal markTextWidth = fm.width(QString::number(point->x()));
    153. qreal markTextHeight = fm.height();
    154.  
    155. painter->drawText(QPointF(xAxisMark - (markTextWidth/2), xAxisY + markTextHeight + 5), QString::number(point->x()));
    156.  
    157. xAxisMark += (point->width() / 2) + spaceBetweenBars;
    158. }
    159.  
    160. painter->restore();
    161. }
    162.  
    163. void BarChart::drawDataPoints(QPainter *painter)
    164. {
    165. qreal dataPointCentre = chartOuterMargin + yAxisWidth() + spaceBetweenBars;
    166.  
    167. QFontMetrics fm(font());
    168. qreal textHeight = fm.height();
    169.  
    170. foreach(DataPoint *point, m_dataPointList) {
    171. QBrush dataPointBrush(point->color());
    172. QPen dataPointPen(QColor(qRgb(0, 0, 0)));
    173.  
    174. dataPointCentre += point->width()/2;
    175.  
    176. painter->save();
    177.  
    178. painter->setBrush(dataPointBrush);
    179. painter->setPen(dataPointPen);
    180.  
    181. qreal dpHeight = dataPointHeight(point->y());
    182.  
    183. painter->drawRect(QRectF(dataPointCentre - (point->width()/2), height() - xAxisHeight() - chartOuterMargin - (textHeight/2), point->width(), -dpHeight));
    184.  
    185. painter->restore();
    186.  
    187. dataPointCentre += (point->width() / 2) + spaceBetweenBars;
    188. }
    189. }
    To copy to clipboard, switch view to plain text mode 

    Usage:
    Qt Code:
    1. dataPoints.append(new DataPoint(1, 1));
    2. dataPoints.append(new DataPoint(2, 2));
    3.  
    4. DataPoint *colorPoint = new DataPoint(3, 3);
    5. colorPoint->setColor(QColor(qRgb(255, 0, 0)));
    6. dataPoints.append(colorPoint);
    7.  
    8. dataPoints.append(new DataPoint(4, 4));
    9.  
    10. DataPoint *widthPoint = new DataPoint(5, 5);
    11. widthPoint->setWidth(20);
    12. dataPoints.append(widthPoint);
    13.  
    14. dataPoints.append(new DataPoint(6, 6));
    15.  
    16. barChart = new BarChart;
    17.  
    18. //...
    19.  
    20. barChart->setDataPointList(dataPoints);
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    dataPoints is of which class?
    barChart is of which class?

    Qt Code:
    1. dataPoints.append(new DataPoint(1, 1));
    2. dataPoints.append(new DataPoint(2, 2));
    3.  
    4. DataPoint *colorPoint = new DataPoint(3, 3);
    5. colorPoint->setColor(QColor(qRgb(255, 0, 0)));
    6. dataPoints.append(colorPoint);
    7.  
    8. dataPoints.append(new DataPoint(4, 4));
    9.  
    10. DataPoint *widthPoint = new DataPoint(5, 5);
    11. widthPoint->setWidth(20);
    12. dataPoints.append(widthPoint);
    13.  
    14. dataPoints.append(new DataPoint(6, 6));
    15.  
    16. barChart = new BarChart;
    17.  
    18. //...
    19.  
    20. barChart->setDataPointList(dataPoints);
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Bar chart plotting using 2D graphics QPainter class

    dataPoints is of type DataPointList
    and barChart is of type BarChart

  7. #7
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Quote Originally Posted by tbscope View Post
    dataPoints is of type DataPointList
    and barChart is of type BarChart
    dataPoints and barChart are of which Qt classes to be declared?

  8. #8
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Read the code I posted

  9. #9
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    SOS. Thanks.

  10. #10
    Join Date
    Aug 2009
    Location
    Belgium
    Posts
    310
    Thanks
    10
    Thanked 31 Times in 25 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Maybe you could try this : NightCharts(Draw Charts).
    And there is an example, so even you may get it to work.

    Regards,
    Marc

  11. #11
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Thank you tbscope. I could make the code to work. And now I would like to know how do I add scale for y-axis?

  12. #12
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Bar chart plotting using 2D graphics QPainter class

    As suggested above, there exist ready made tools that are easy to use.
    Did you try them already?

    If it is your goal to create a bar chart yourself, read on...

    For the scaling, what did you try yourself already?
    I hope you don't mind if I say that I will not write a complete component for you (that's already done, see the ready made solutions).
    I don't have the time nor the will to do that. But I will help you if you have specific problems that you don't know how to solve.

    My suggestion is that you try to work out the scaling yourself first. Maybe take a piece of paper, clear your head and think about possible ways to solve the problem.
    Then try to put the solution(s) into code. In the mean time and afterwards, you can ask specific questions.

  13. #13
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    not scaling as in enlarge etc. i mean label scale on y axis...

  14. #14
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Any existing API readily available for plotting the Y axis scale values?

    Note: I'm not using QWT.

    SOS
    Last edited by babygal; 17th February 2011 at 09:23.

  15. #15
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    I'm using QPainter

  16. #16
    Join Date
    Aug 2009
    Location
    Belgium
    Posts
    310
    Thanks
    10
    Thanked 31 Times in 25 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Maybe this link will help you get an answer : http://www.cplusplus.com/forum/articles/1295/

    You may also look into this class : NightCharts. You can see how different elements of a graph are drawn there. And putting a label next to an axis may be as simple as using a drawTexT() function.

    Best regards,
    Marc

  17. #17
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    The NightCharts example is a good one. However the chart has no display of values on its Y axis, which is what I'm looking for.
    Is there any formula that can be used to calculate the Y axis scale division values?

  18. #18
    Join Date
    Aug 2009
    Location
    Belgium
    Posts
    310
    Thanks
    10
    Thanked 31 Times in 25 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    So you need to know at what position a value on the Y axis must be drawn ?
    Well... I guess that's the same formula as for calculating the height of a bar graph.

    Regards,
    Marc

  19. #19
    Join Date
    Apr 2010
    Location
    Singapore
    Posts
    156
    Thanks
    47
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    hi,

    no.not the position . but the values. i need to know how to calculate the values.


    Emma
    Last edited by babygal; 2nd March 2011 at 05:21.

  20. #20
    Join Date
    Aug 2009
    Location
    Belgium
    Posts
    310
    Thanks
    10
    Thanked 31 Times in 25 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Bar chart plotting using 2D graphics QPainter class

    Hi,
    I'm not sure what you mean. Normally the maximum Y value is just the highest value of all your bar charts. Then you decide on a 'step', e.g. draw an axis with a step of 100, so you draw the values 100, 200, 300, ... You just take a simple for loop to draw these.

    Maybe you could take a screenshot of what you already have, and paint on it what you would like to add.

    Regards,
    Marc

Similar Threads

  1. Bull's Eye plotting/chart
    By babygal in forum Newbie
    Replies: 5
    Last Post: 21st September 2010, 07:01
  2. Best class for graphics-animation
    By Aspras in forum Qt Programming
    Replies: 1
    Last Post: 17th February 2010, 13:10
  3. Error while redrawing using QPainter Class
    By sosanjay in forum Qt Programming
    Replies: 5
    Last Post: 28th December 2009, 11:48
  4. Replies: 4
    Last Post: 14th April 2008, 16:39
  5. suitable class for plotting pixels
    By babu198649 in forum Newbie
    Replies: 19
    Last Post: 11th December 2007, 06:41

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.