PDA

View Full Version : Bar chart plotting using 2D graphics QPainter class



babygal
1st November 2010, 08:18
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.

tbscope
1st November 2010, 08:24
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, ...

babygal
30th December 2010, 06:57
Any sample code would be helpful to me.
Thank you.


S.O.S

tbscope
31st December 2010, 15:03
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.

5670

datapoint.h

#ifndef DATAPOINT_H
#define DATAPOINT_H

#include <QtGlobal>
#include <QColor>
#include <QList>
#include <QMetaType>

class DataPoint
{
public:
DataPoint();
DataPoint(qreal x, qreal Y);

void setX(qreal x);
void setY(qreal y);

void setColor(const QColor &color);
void setWidth(int width);

qreal x() const;
qreal y() const;

QColor color() const;
int width() const;

private:
qreal m_x;
qreal m_y;
QColor m_color;
int m_width;
};

typedef QList<DataPoint*> DataPointList;

#endif // DATAPOINT_H


datapoint.cpp

#include "datapoint.h"

DataPoint::DataPoint() :
m_x(0),
m_y(0),
m_color(QColor(qRgb(200, 200, 200))),
m_width(10)
{
}

DataPoint::DataPoint(qreal x, qreal y) :
m_x(x),
m_y(y),
m_color(QColor(qRgb(200, 200, 200))),
m_width(10)
{
}

void DataPoint::setX(qreal x)
{
m_x = x;
}

void DataPoint::setY(qreal y)
{
m_y = y;
}

void DataPoint::setColor(const QColor &color)
{
m_color = color;
}

void DataPoint::setWidth(int width)
{
m_width = width;
}

qreal DataPoint::x() const
{
return m_x;
}

qreal DataPoint::y() const
{
return m_y;
}

QColor DataPoint::color() const
{
return m_color;
}

int DataPoint::width() const
{
return m_width;
}



barchart.h

#ifndef BARCHART_H
#define BARCHART_H

#include <QWidget>
#include <QPaintEvent>
#include <QtGlobal>

#include "datapoint.h"

class BarChart : public QWidget
{
Q_OBJECT
public:
explicit BarChart(QWidget *parent = 0);

void setDataPointList(const DataPointList &pointList);

protected:
void paintEvent(QPaintEvent *event);

signals:

public slots:

private:
DataPointList m_dataPointList;

qreal maximumHeight();
qreal maximumWidth();

qreal yAxisWidth();
qreal xAxisHeight();

qreal spaceBetweenBars;
qreal chartOuterMargin;

qreal dataPointHeight(qreal y);

void drawEmptyBarChart(QPainter *painter);
void drawYAxis(QPainter *painter);
void drawXAxis(QPainter *painter);
void drawDataPoints(QPainter *painter);
};

#endif // BARCHART_H



barchart.cpp

#include "barchart.h"

#include <QPainter>
#include <QFontMetricsF>
#include <QPointF>
#include <QPen>
#include <QBrush>

BarChart::BarChart(QWidget *parent) :
QWidget(parent)
{
spaceBetweenBars = 5;
chartOuterMargin = 10;
}

void BarChart::setDataPointList(const DataPointList &pointList)
{
m_dataPointList = pointList;
update();
}

void BarChart::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);

QPainter painter(this);

if (m_dataPointList.isEmpty())
drawEmptyBarChart(&painter);
else {
drawXAxis(&painter);
drawYAxis(&painter);
drawDataPoints(&painter);
}
}

qreal BarChart::maximumHeight()
{
qreal height = 0;

foreach(DataPoint *point, m_dataPointList) {
if (point->y() > height)
height = point->y();
}

return height;
}

qreal BarChart::maximumWidth()
{
qreal width = 0;

foreach(DataPoint *point, m_dataPointList) {
width += point->width() + spaceBetweenBars;
}

return width;
}

qreal BarChart::yAxisWidth()
{
QString maximumValue = QString::number(maximumHeight());
QFontMetrics fm(font());
qreal textWidth = fm.width(maximumValue);

return textWidth + 5;
}

qreal BarChart::xAxisHeight()
{
QFontMetrics fm(font());
qreal textHeight = fm.height();

return textHeight + 5;
}

qreal BarChart::dataPointHeight(qreal y)
{
QFontMetrics fm(font());
qreal textHeight = fm.height();

return y * ((height() - (2 * (chartOuterMargin + (textHeight / 2))) - xAxisHeight()) / maximumHeight());
}

void BarChart::drawEmptyBarChart(QPainter *painter)
{
QString text("No datapoints available!");

qreal centreX = width() / 2;
qreal centreY = height() / 2;

QFontMetricsF fontMetrics(font());
qreal textWidth = fontMetrics.width(text);
qreal textHeight = fontMetrics.height();

qreal textX = centreX - (textWidth / 2);
qreal textY = centreY - (textHeight / 2);

painter->drawText(QPointF(textX, textY), text);
}

void BarChart::drawYAxis(QPainter *painter)
{
QPen yAxisPen(QColor(qRgb(0, 0, 0)));

QString maximumValue = QString::number(maximumHeight());
QFontMetrics fm(font());
qreal textWidth = fm.width(maximumValue);
qreal textHeight = fm.height();

qreal yAxisX = chartOuterMargin + textWidth + 5;
qreal yAxisY = chartOuterMargin + (textHeight / 2);
qreal yAxisHeight = height() - yAxisY - xAxisHeight();

painter->save();

painter->setPen(yAxisPen);
painter->drawLine(QPointF(yAxisX, yAxisY), QPointF(yAxisX, yAxisHeight));

painter->drawLine(QPointF(yAxisX - 3, yAxisY), QPointF(yAxisX, yAxisY));
painter->drawLine(QPointF(yAxisX - 3, yAxisHeight), QPointF(yAxisX, yAxisHeight));

painter->drawText(QPointF(chartOuterMargin, chartOuterMargin + textHeight), maximumValue);
painter->drawText(QPointF(chartOuterMargin, height() - chartOuterMargin - xAxisHeight()), "0");

painter->restore();
}

void BarChart::drawXAxis(QPainter *painter)
{
QPen xAxisPen(QColor(qRgb(0, 0, 0)));

QFontMetrics fm(font());
qreal textHeight = fm.height();

qreal xAxisX = chartOuterMargin + yAxisWidth();
qreal xAxisY = height() - xAxisHeight() - chartOuterMargin - (textHeight/2);
qreal xAxisWidth = xAxisX + maximumWidth() + spaceBetweenBars;
painter->save();

painter->setPen(xAxisPen);
painter->drawLine(QPointF(xAxisX, xAxisY), QPointF(xAxisWidth, xAxisY));

qreal xAxisMark = xAxisX + spaceBetweenBars; // Keep some space between the first bar and the Y axis

foreach(DataPoint *point, m_dataPointList) {
xAxisMark += point->width()/2;

painter->drawLine(QPointF(xAxisMark, xAxisY), QPointF(xAxisMark, xAxisY + 3));

QFontMetrics fm(font());
qreal markTextWidth = fm.width(QString::number(point->x()));
qreal markTextHeight = fm.height();

painter->drawText(QPointF(xAxisMark - (markTextWidth/2), xAxisY + markTextHeight + 5), QString::number(point->x()));

xAxisMark += (point->width() / 2) + spaceBetweenBars;
}

painter->restore();
}

void BarChart::drawDataPoints(QPainter *painter)
{
qreal dataPointCentre = chartOuterMargin + yAxisWidth() + spaceBetweenBars;

QFontMetrics fm(font());
qreal textHeight = fm.height();

foreach(DataPoint *point, m_dataPointList) {
QBrush dataPointBrush(point->color());
QPen dataPointPen(QColor(qRgb(0, 0, 0)));

dataPointCentre += point->width()/2;

painter->save();

painter->setBrush(dataPointBrush);
painter->setPen(dataPointPen);

qreal dpHeight = dataPointHeight(point->y());

painter->drawRect(QRectF(dataPointCentre - (point->width()/2), height() - xAxisHeight() - chartOuterMargin - (textHeight/2), point->width(), -dpHeight));

painter->restore();

dataPointCentre += (point->width() / 2) + spaceBetweenBars;
}
}


Usage:

dataPoints.append(new DataPoint(1, 1));
dataPoints.append(new DataPoint(2, 2));

DataPoint *colorPoint = new DataPoint(3, 3);
colorPoint->setColor(QColor(qRgb(255, 0, 0)));
dataPoints.append(colorPoint);

dataPoints.append(new DataPoint(4, 4));

DataPoint *widthPoint = new DataPoint(5, 5);
widthPoint->setWidth(20);
dataPoints.append(widthPoint);

dataPoints.append(new DataPoint(6, 6));

barChart = new BarChart;

//...

barChart->setDataPointList(dataPoints);

babygal
3rd January 2011, 10:24
dataPoints is of which class?
barChart is of which class?





dataPoints.append(new DataPoint(1, 1));
dataPoints.append(new DataPoint(2, 2));

DataPoint *colorPoint = new DataPoint(3, 3);
colorPoint->setColor(QColor(qRgb(255, 0, 0)));
dataPoints.append(colorPoint);

dataPoints.append(new DataPoint(4, 4));

DataPoint *widthPoint = new DataPoint(5, 5);
widthPoint->setWidth(20);
dataPoints.append(widthPoint);

dataPoints.append(new DataPoint(6, 6));

barChart = new BarChart;

//...

barChart->setDataPointList(dataPoints);

tbscope
3rd January 2011, 11:39
dataPoints is of type DataPointList
and barChart is of type BarChart

babygal
4th January 2011, 07:35
dataPoints is of type DataPointList
and barChart is of type BarChart

dataPoints and barChart are of which Qt classes to be declared?

tbscope
4th January 2011, 08:31
Read the code I posted

babygal
14th January 2011, 05:50
SOS. Thanks.

marcvanriet
14th January 2011, 11:52
Maybe you could try this : NightCharts(Draw Charts) (http://qt-apps.org/content/show.php/NightCharts%28Draw+Charts%29?content=132560).
And there is an example, so even you may get it to work.

Regards,
Marc

babygal
31st January 2011, 06:57
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?

tbscope
31st January 2011, 07:06
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.

babygal
2nd February 2011, 04:00
not scaling as in enlarge etc. i mean label scale on y axis...

babygal
17th February 2011, 04:48
Any existing API readily available for plotting the Y axis scale values?

Note: I'm not using QWT.

SOS

babygal
18th February 2011, 09:10
I'm using QPainter

marcvanriet
18th February 2011, 11:41
Maybe this link will help you get an answer : http://www.cplusplus.com/forum/articles/1295/

You may also look into this class : NightCharts (http://qt-apps.org/content/show.php/NightCharts%28Draw+Charts%29?content=132560). 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

babygal
1st March 2011, 10:22
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?

marcvanriet
1st March 2011, 20:07
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

babygal
2nd March 2011, 03:31
hi,

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


Emma

marcvanriet
2nd March 2011, 19:33
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

babygal
11th March 2011, 07:59
60756076

Hi,
I have attached the screenshot. 'histogram' is the original one which is output of the code and what i want to add is in 'histogram Y-axis' (in red mark).

CODE:
datapoint.h:


#ifndef DATAPOINT_H
#define DATAPOINT_H

#include <QtGlobal>
#include <QColor>
#include <QList>
#include <QMetaType>

class DataPoint
{
public:
DataPoint();
DataPoint(qreal x, qreal Y);

void setX(qreal x);
void setY(qreal y);

void setColor(const QColor &color);
void setWidth(int width);

qreal x() const;
qreal y() const;

QColor color() const;
int width() const;

private:
qreal m_x;
qreal m_y;
QColor m_color;
int m_width;
};

typedef QList<DataPoint*> DataPointList;

#endif // DATAPOINT_H

datapoint.cpp:


#include <QtGui>
#include "datapoint.h"

DataPoint::DataPoint() :
m_x(0),
m_y(0),
m_color(QColor(qRgb(200, 200, 200))),
m_width(10)
{
}

DataPoint::DataPoint(qreal x, qreal y) :
m_x(x),
m_y(y),
m_color(QColor(qRgb(200, 200, 200))),
m_width(10)
{
}

void DataPoint::setX(qreal x)
{
m_x = x;
}

void DataPoint::setY(qreal y)
{
m_y = y;
}

void DataPoint::setColor(const QColor &color)
{
m_color = color;
}

void DataPoint::setWidth(int width)
{
m_width = width;
}

qreal DataPoint::x() const
{
return m_x;
}

qreal DataPoint::y() const
{
return m_y;
}

QColor DataPoint::color() const
{
return m_color;
}

int DataPoint::width() const
{
return m_width;
}

barchart.h:


#ifndef BARCHART_H
#define BARCHART_H

#include <QWidget>
#include <QPaintEvent>
#include <QtGlobal>
#include <QtDebug>
#include "datapoint.h"

class BarChart : public QWidget
{
Q_OBJECT
public:
explicit BarChart(QWidget *parent = 0);

void setDataPointList(const DataPointList &pointList);

protected:
void paintEvent(QPaintEvent *event);

signals:

public slots:

private:
DataPointList m_dataPointList;

QString maximumValue ;

qreal textWidth ;
qreal textHeight;

qreal maximumHeight();
qreal maximumWidth();

qreal yAxisWidth();
qreal xAxisHeight();

qreal spaceBetweenBars;
qreal chartOuterMargin;

qreal dataPointHeight(qreal y);

double cX,cY,cW,cH,pW,lX,lY;
public:
void drawEmptyBarChart(QPainter *painter);
void drawYAxis(QPainter *painter);
void drawXAxis(QPainter *painter);
void drawDataPoints(QPainter *painter);
void scaledivideYAxis(QPainter *painter);
void drawYAxisScale(QPainter *painter);
};

#endif // BARCHART_H
barchart.cpp:


#include <QtGui>
#include "barchart.h"
#include <QtGlobal>
#include <QPainter>
#include <QFontMetricsF>
#include <QPointF>
#include <QPen>
#include <QBrush>
#include <QGraphicsItem>

#include <QString>


BarChart::BarChart(QWidget *parent) :
QWidget(parent)
{
spaceBetweenBars = 10;//5;
chartOuterMargin = 10;

cX = 0;
cY = 0;
cW = 100;
cH = 100;
lX = cX+cW+20;
lY = cY;
}

void BarChart::setDataPointList(const DataPointList &pointList)
{
m_dataPointList = pointList;
update();
}

void BarChart::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);

QPainter painter(this);

if (m_dataPointList.isEmpty())
drawEmptyBarChart(&painter);
else {
drawXAxis(&painter);
drawYAxis(&painter);
drawDataPoints(&painter);
scaledivideYAxis(&painter);
//drawYAxisScale(&painter);
}
}

qreal BarChart::maximumHeight()
{
qreal height = 0;

foreach(DataPoint *point, m_dataPointList) {
if (point->y() > height)
height = point->y();
}

return height;
}

qreal BarChart::maximumWidth()
{
qreal width = 0;

foreach(DataPoint *point, m_dataPointList) {
width += point->width() + spaceBetweenBars;
}

return width;
}

qreal BarChart::yAxisWidth()
{
QString maximumValue = QString::number(maximumHeight());
QFontMetrics fm(font());
qreal textWidth = fm.width(maximumValue);

return textWidth + 5;
}

qreal BarChart::xAxisHeight()
{
QFontMetrics fm(font());
qreal textHeight = fm.height();

return textHeight + 5;
}

qreal BarChart::dataPointHeight(qreal y)
{
QFontMetrics fm(font());
qreal textHeight = fm.height();

return y * ((height() - (2 * (chartOuterMargin + (textHeight / 2))) - xAxisHeight()) / maximumHeight());
}

void BarChart::drawEmptyBarChart(QPainter *painter)
{
QString text("No datapoints available!");

qreal centreX = width() / 2;
qreal centreY = height() / 2;

QFontMetricsF fontMetrics(font());
qreal textWidth = fontMetrics.width(text);
qreal textHeight = fontMetrics.height();

qreal textX = centreX - (textWidth / 2);
qreal textY = centreY - (textHeight / 2);

painter->drawText(QPointF(textX, textY), text);
}

void BarChart::drawYAxis(QPainter *painter)
{
QPen yAxisPen(QColor(qRgb(0, 0, 0)));

maximumValue = QString::number(maximumHeight());
QFontMetrics fm(font());

textWidth = fm.width(maximumValue);
textHeight = fm.height();

qreal yAxisX = chartOuterMargin + textWidth + 5;
qreal yAxisY = chartOuterMargin + (textHeight / 2);
qreal yAxisHeight = height() - yAxisY - xAxisHeight();
qreal yAxisLabel = 15;
painter->save();

painter->setPen(yAxisPen);

painter->drawLine(QPointF(yAxisX, yAxisY), QPointF(yAxisX, yAxisHeight));

painter->drawLine(QPointF(yAxisX - 3, yAxisY), QPointF(yAxisX, yAxisY));
painter->drawLine(QPointF(yAxisX - 3, yAxisHeight), QPointF(yAxisX, yAxisHeight));

painter->drawText(QPointF(chartOuterMargin, chartOuterMargin + textHeight), maximumValue);
painter->drawText(QPointF(chartOuterMargin, chartOuterMargin + textHeight - yAxisLabel ), "Mean values");
painter->drawText(QPointF(chartOuterMargin, height() - chartOuterMargin - xAxisHeight()), "0");

//draw the text label of y-axis
painter->restore();
}

void BarChart::drawYAxisScale(QPainter *painter)
{
/*********from DrawCharts********/

painter->setPen(Qt::SolidLine);
for (int i=1;i<10;i++)
{
painter->drawLine(cX-3,cY+cH/10*i,cX+3,cY+cH/10*i); //äåëåÃ*èÿ ïî îñè Y
//painter->drawText(cX-20,cY+cH/10*i,QString::number((10-i)*10)+"%");
}

/*painter->drawLine(cX,cY+cH,cX,cY); //îñü Y
painter->drawLine(cX,cY,cX+4,cY+10); //ñòðåëêè
painter->drawLine(cX,cY,cX-4,cY+10);
painter->drawLine(cX,cY+cH,cX+cW,cY+cH); //îñü Õ
*/
}

void BarChart::scaledivideYAxis(QPainter *painter)
{


}

void BarChart::drawXAxis(QPainter *painter)
{
QPen xAxisPen(QColor(qRgb(0, 0, 0)));

QFontMetrics fm(font());
qreal textHeight = fm.height();

qreal xAxisX = chartOuterMargin + yAxisWidth();
qreal xAxisY = height() - xAxisHeight() - chartOuterMargin - (textHeight/2);
qreal xAxisWidth = xAxisX + maximumWidth() + spaceBetweenBars;
qreal xAxisLabel = 10;
painter->save();

painter->setPen(xAxisPen);
painter->drawLine(QPointF(xAxisX, xAxisY), QPointF(xAxisWidth, xAxisY));
painter->drawText(QPointF(xAxisWidth + xAxisLabel, xAxisY), "Region");
qreal xAxisMark = xAxisX + spaceBetweenBars; // Keep some space between the first bar and the Y axis

foreach(DataPoint *point, m_dataPointList) {
xAxisMark += point->width()/2;

painter->drawLine(QPointF(xAxisMark, xAxisY), QPointF(xAxisMark, xAxisY + 3));

QFontMetrics fm(font());
qreal markTextWidth = fm.width(QString::number(point->x()));
qreal markTextHeight = fm.height();

painter->drawText(QPointF(xAxisMark - (markTextWidth/2), xAxisY + markTextHeight + 5), QString::number(point->x()));


//draw text label
xAxisMark += (point->width() / 2) + spaceBetweenBars;
}

painter->restore();
}

void BarChart::drawDataPoints(QPainter *painter)
{
qreal dataPointCentre = chartOuterMargin + yAxisWidth() + spaceBetweenBars;

QFontMetrics fm(font());
qreal textHeight = fm.height();

foreach(DataPoint *point, m_dataPointList) {
QBrush dataPointBrush(point->color());
QPen dataPointPen(QColor(qRgb(0, 0, 0)));

dataPointCentre += point->width()/2;

painter->save();

painter->setBrush(dataPointBrush);
painter->setPen(dataPointPen);

qreal dpHeight = dataPointHeight(point->y());


painter->drawRect(QRectF(dataPointCentre - (point->width()/2), height() - xAxisHeight() - chartOuterMargin - (textHeight/2), point->width(), -dpHeight));
//drawline ( region X,ymin, region X, y max)
//painter->drawLine(QPointF(dataPointCentre,dpHeight ), QPointF(dataPointCentre, dpHeight + 10 ));
painter->restore();

//qDebug() << "dpHeight: " << dpHeight;
//qDebug() << "point->width(): " << point->width();

dataPointCentre += (point->width() / 2) + spaceBetweenBars;
}
}

mainwindow.cpp:



dataPoints.clear();
QSqlQuery query;
query.exec("SELECT v.region_no,v.analysis_mean_val,v.analysis_sd_val FROM REGIONAL_ANALYSIS_DATA d,ANALYSIS_TYPE a JOIN REGIONAL_ANALYSIS_VALUES v WHERE d.analysis_type = a.analysis_type AND d.analysis_val_id = v.analysis_val_id AND d.scan_id = " + QString::number(MainWindow::scan_id) + " AND d.heart_state = 'ED' AND d.analysis_type=1");
double j;
int i;
for ( i= 1 ; i<=16 ; i++)
{
qDebug() << "for loop i: " << i;

while(query.next())
{

regionNumber[i] = query.value(0).toDouble();
j = regionNumber[i];

qDebug() << "regionNumber :" << regionNumber[i];


qDebug() << "while loop i: " << i;
qDebug() << "while loop j: " << j;

analysismeanVal[i] = query.value(1).toFloat(); //toDouble();

qDebug() << "analysismeanVal: " << analysismeanVal[i];

DataPoint *widthPoint = (new DataPoint( j, analysismeanVal[i]));
widthPoint->setWidth(20);
dataPoints.append(widthPoint);
}


}
barChart = new BarChart;

QPainter painter(this);

//if (barChart->m_dataPointList.isEmpty())
barChart->drawEmptyBarChart(&painter);
//barChart->drawEmptyBarChart();
barChart->show();
barChart->resize(630,575);
barChart->setWindowTitle(tr("Regional Curvedness - ED - Barchart"));

//...

barChart->setDataPointList(dataPoints);

marcvanriet
11th March 2011, 23:36
Something like this :

void BarChart::drawYAxisScale(QPainter *painter)
{
QPen yAxisPen(QColor(qRgb(0, 0, 0)));

maximumValue = QString::number(maximumHeight());
QFontMetrics fm(font());

textWidth = fm.width(maximumValue);
textHeight = fm.height();

qreal yAxisX = chartOuterMargin + textWidth + 5;
qreal yAxisY = chartOuterMargin + (textHeight / 2);
qreal yAxisHeight = height() - yAxisY - xAxisHeight();
qreal yAxisLabel = 15;

qreal fYpos = yAxisY + yAxisHeight;
qreal fStepYpos = yAxisHeight / 10;
qreal fYval = 0.0;
qreal fYStepVal = maximumHeight() / 10;

for( int i=0; i<10; i++)
{
painter->drawLine(QPointF(yAxisX - 3, fYpos), QPointF(yAxisX, fYpos));
painter->drawText(QPointF(chartOuterMargin-10, fYpos), QString("%1").arg(fYval, 0, 'f', 1) );

fYval += fYStepVal;
fYpos -= fStepYpos;
}
}
It's not entirely correct, but you'll get the idea.

Best regards,
Marc

babygal
15th March 2011, 07:11
6089

Hi Marc,

What if the precision is not 1 and cannot be determined?


painter->drawText(QPointF(chartOuterMargin, fYpos), QString("%1").arg(fYval,0,'f',1));

marcvanriet
15th March 2011, 17:24
Hi,
You could add a property to you barclass object so that you can say in code what the format of the number should look like.
It's like in Excel or other programs that make charts : you can set the numbering format for the values that are displayed.

Regards,
Marc

babygal
17th March 2011, 03:35
Hi,

Any example or sample code on this?

Thank you.
Emma

marcvanriet
17th March 2011, 21:56
It's just like the properties in your datapoints class :

void setX(qreal x);
qreal x() const;
Only instead of a floating point number 'x' it would be an integer with the precision, or any other way you can think of to describe the format of the number. Really, this is just basic C++.
Regards,
Marc

babygal
23rd March 2011, 10:10
can you give an example, please?

marcvanriet
23rd March 2011, 22:42
Try this LINK (http://www.dummies.com/store/product/C-For-Dummies-6th-Edition.productCd-0470317264.html)

It is full of examples

babygal
25th March 2011, 08:12
It's just like the properties in your datapoints class :

void setX(qreal x);
qreal x() const;
Only instead of a floating point number 'x' it would be an integer with the precision, or any other way you can think of to describe the format of the number. Really, this is just basic C++.
Regards,
Marc

Hi Marc,

Can you elaborate? I want the y values to cover both integer and floating values as well..


Thank you.
regards,
Emma

marcvanriet
25th March 2011, 11:35
You started this thread on November 1st 2010. Are you really still working on this chart thing ? In 5 months, you could have checked out dozens of other barchart widgets and see how they do it.

To elaborate :
- first find out how you can convert the Y values to a string
- see what the difference is for converting floating point values and values without decimals
- think of a way to handle both cases in code
- think of a way to specify the format as a property of your class

Unless you are only 15 years old, you should be able to find all of this yourself.

Good luck,
Marc

babygal
12th April 2011, 08:39
Yes I am doing improvisation on it. Thanks.