1
/****************************************************************************
2
** Copyright (C) 2006 Klarälvdalens Datakonsult AB. All rights reserved.
4
** This file is part of the KD Chart library.
6
** This file may be used under the terms of the GNU General Public
7
** License versions 2.0 or 3.0 as published by the Free Software
8
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
9
** included in the packaging of this file. Alternatively you may (at
10
** your option) use any later version of the GNU General Public
11
** License if such license has been publicly approved by
12
** Klarälvdalens Datakonsult AB (or its successors, if any).
14
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
15
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
16
** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
17
** not expressly granted herein.
19
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
**********************************************************************/
24
#include "mainwindow.h"
26
#include <KDChartChart>
27
#include <KDChartLineDiagram>
28
#include <KDChartDataValueAttributes>
29
#include <KDChartTextAttributes>
30
#include <KDChartMarkerAttributes>
32
#include <QStandardItemModel>
36
using namespace KDChart;
40
static const int nBubbles = 7;
41
// we display seven bubbles using the following data structure:
45
// 3: color as returned by QColor::name()
46
// 4: style of surrounding line, can be one of these:
47
// "NoPen", "SolidLine", "DashLine", "DotLine", "DashDotLine", "DashDotDotLine"
66
static const DataType bubblesData[nBubbles] = {
67
DataType(0.5, 1.0, 100,"#FF0000", "NoPen"),
68
DataType(1.0, 0.5, 60, "#00FF00", "SolidLine"),
69
DataType(1.6, 2.0, 28, "#0000FF", "DotLine"),
70
DataType(0.7, 0.3, 55, "#FFFF00", "DashLine"),
71
DataType(1.3, 2.0, 95, "#FF00FF", "DashDotLine"),
72
DataType(2.0, 1.0, 75, "#00FFFF", "DashDotDotLine"),
73
DataType(1.4, 1.1, 85, "#FFFFFF", "DotLine")
76
#define ROLE_SIZE Qt::UserRole + 1
77
#define ROLE_COLOR Qt::UserRole + 2
78
#define ROLE_STYLE Qt::UserRole + 3
82
MainWindow::MainWindow( QWidget* parent ) :
88
QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame );
89
m_chart = new Chart();
90
chartLayout->addWidget( m_chart );
92
initializeDataModel();
94
m_lines = new LineDiagram();
95
m_lines->setDatasetDimension(2);
96
// Register the data model at the diagram
97
m_lines->setModel( m_model );
98
// Add axes to the diagram
99
CartesianAxis *xAxis = new CartesianAxis( m_lines );
100
CartesianAxis *xAxis2 = new CartesianAxis( m_lines );
101
CartesianAxis *yAxis = new CartesianAxis ( m_lines );
102
CartesianAxis *yAxis2 = new CartesianAxis ( m_lines );
103
xAxis->setPosition ( KDChart::CartesianAxis::Bottom );
104
xAxis2->setPosition( KDChart::CartesianAxis::Top );
105
yAxis->setPosition ( KDChart::CartesianAxis::Left );
106
yAxis2->setPosition( KDChart::CartesianAxis::Right );
107
m_lines->addAxis( xAxis );
108
m_lines->addAxis( xAxis2 );
109
m_lines->addAxis( yAxis );
110
m_lines->addAxis( yAxis2 );
112
m_chart->coordinatePlane()->replaceDiagram( m_lines );
113
m_chart->setGlobalLeading( 20, 20, 20, 20 );
115
setMarkerAttributes();
117
//adjustSizeOfDataArea();
118
QTimer::singleShot(200, this, SLOT(adjustSizeOfDataArea()));
122
void MainWindow::initializeDataModel()
124
m_model = new QStandardItemModel( nBubbles, 2, this );
125
m_model->setHeaderData(0, Qt::Horizontal, tr("Some Bubbles"));
126
for( int i=0; i < nBubbles; ++i ){
127
const QModelIndex indexX = m_model->index(i, 0);
128
const QModelIndex indexY = m_model->index(i, 1);
130
m_model->setData(indexX, bubblesData[i].x, Qt::DisplayRole);
132
m_model->setData(indexY, bubblesData[i].y, Qt::DisplayRole);
133
m_model->setData(indexY, bubblesData[i].size, ROLE_SIZE );
134
m_model->setData(indexY, bubblesData[i].color, ROLE_COLOR);
135
m_model->setData(indexY, bubblesData[i].style, ROLE_STYLE);
140
void MainWindow::setMarkerAttributes()
142
TextAttributes ta( m_lines->dataValueAttributes().textAttributes() );
144
ta.setFont( QFont( "Courier", 0, QFont::DemiBold ) );
145
Measure m(10, KDChartEnums::MeasureCalculationModeAbsolute);
147
ta.setMinimalFontSize(m);
149
// disable the connecting line
150
m_lines->setPen( Qt::NoPen );
152
for ( int iRow = 0; iRow<nBubbles; ++iRow ) {
153
const QModelIndex indexX = m_lines->model()->index(iRow, 0);
154
const QModelIndex indexY = m_lines->model()->index(iRow, 1);
155
DataValueAttributes dva( m_lines->dataValueAttributes( indexX ) );
156
dva.setVisible( true );
157
MarkerAttributes ma( dva.markerAttributes() );
158
ma.setVisible( true );
159
ma.setMarkerStyle( MarkerAttributes::MarkerCircle );
162
const qreal d = m_model->data( indexY, ROLE_SIZE ).toDouble();
163
ma.setMarkerSize( QSizeF(d,d) );
166
ma.setMarkerColor( m_model->data( indexY, ROLE_COLOR ).toString() );
168
// set the surrounding line's style
169
Qt::PenStyle style = Qt::SolidLine;
170
const QString sPen = m_model->data( indexY, ROLE_STYLE ).toString();
171
if( sPen.compare("NoPen") == 0 )
173
else if( sPen.compare("SolidLine") == 0 )
174
style = Qt::SolidLine;
175
else if( sPen.compare("DashLine") == 0 )
176
style = Qt::DashLine;
177
else if( sPen.compare("DotLine") == 0 )
179
else if( sPen.compare("DashDotLine") == 0 )
180
style = Qt::DashDotLine;
181
else if( sPen.compare("DashDotDotLine") == 0 )
182
style = Qt::DashDotDotLine;
187
RelativePosition pos( dva.positivePosition() );
188
pos.setAlignment( Qt::AlignCenter );
189
pos.setHorizontalPadding(0);
191
dva.setPositivePosition( pos );
192
dva.setMarkerAttributes( ma );
193
dva.setTextAttributes( ta );
194
m_lines->setDataValueAttributes( indexX, dva );
195
m_lines->setDataValueAttributes( indexY, dva );
201
void MainWindow::resizeEvent ( QResizeEvent * )
203
adjustSizeOfDataArea();
204
QTimer::singleShot(200, this, SLOT(adjustSizeOfDataArea()));
208
void MainWindow::adjustSizeOfDataArea()
210
// find the transformation factors
211
// currently used by the coordinate plane
212
CartesianCoordinatePlane* plane =
213
static_cast<CartesianCoordinatePlane*>(m_chart->coordinatePlane());
214
const QPointF pt0 = plane->translate( QPointF(0.0, 0.0) );
215
const QPointF pt1 = plane->translate( QPointF(1.0, 1.0) );
216
const qreal divX = pt1.x() - pt0.x();
217
const qreal divY = pt0.y() - pt1.y();
219
qreal x1, x2, y1, y2;
220
// find the four most-external bubble edges
221
const int nFirstRow=0;
222
const int nLastRow=nBubbles-1;
224
for ( int iRow = nFirstRow; iRow <= nLastRow; ++iRow ) {
225
const QModelIndex indexX = m_lines->model()->index(iRow, 0);
226
const QModelIndex indexY = m_lines->model()->index(iRow, 1);
227
const QSizeF siz( m_lines->dataValueAttributes( indexX ).markerAttributes().markerSize() );
228
const qreal dX = siz.width()/2.0/divX;
229
const qreal dY = siz.height()/2.0/divY;
230
const qreal x( m_model->data( indexX, Qt::DisplayRole ).toDouble() );
231
const qreal y( m_model->data( indexY, Qt::DisplayRole ).toDouble() );
232
if( iRow == nFirstRow ){
238
x1 = qMin(x1, x - dX);
239
x2 = qMax(x2, x + dX);
240
y1 = qMin(y1, y - dY);
241
y2 = qMax(y2, y + dY);
243
//qDebug() << "x:" << x << "y:" << y << " dx:" << dX << " dy:" << dY << " x-range:" << x1 << x2 << " y-range:" << y1 << y2;
246
// adjust the data area, so none of the bubbles will reach
247
// out of its borders
248
plane->setHorizontalRange( qMakePair(x1, x2) );
249
plane->setVerticalRange( qMakePair(y1, y2) );