24 #include "KDChartAbstractDiagram_p.h" 28 #include <QApplication> 29 #include <QAbstractProxyModel> 39 #include "KDChartPainterSaver_p.h" 41 #include <KDABLibFakes> 62 void AbstractDiagram::init()
65 d->reverseMapper.setDiagram(
this );
71 if ( other ==
this )
return true;
76 (horizontalScrollBarPolicy() == other->horizontalScrollBarPolicy()) &&
77 (verticalScrollBarPolicy() == other->verticalScrollBarPolicy()) &&
79 (frameShadow() == other->frameShadow()) &&
80 (frameShape() == other->frameShape()) &&
83 (lineWidth() == other->lineWidth()) &&
84 (midLineWidth() == other->midLineWidth()) &&
86 (alternatingRowColors() == other->alternatingRowColors()) &&
87 (hasAutoScroll() == other->hasAutoScroll()) &&
88 #
if QT_VERSION > 0x040199
89 (dragDropMode() == other->dragDropMode()) &&
90 (dragDropOverwriteMode() == other->dragDropOverwriteMode()) &&
91 (horizontalScrollMode() == other->horizontalScrollMode ()) &&
92 (verticalScrollMode() == other->verticalScrollMode()) &&
94 (dragEnabled() == other->dragEnabled()) &&
95 (editTriggers() == other->editTriggers()) &&
96 (iconSize() == other->iconSize()) &&
97 (selectionBehavior() == other->selectionBehavior()) &&
98 (selectionMode() == other->selectionMode()) &&
99 (showDropIndicator() == other->showDropIndicator()) &&
100 (tabKeyNavigation() == other->tabKeyNavigation()) &&
101 (textElideMode() == other->textElideMode()) &&
105 (rootIndex().column() == other->rootIndex().column()) &&
106 (rootIndex().row() == other->rootIndex().row()) &&
120 if (
d->databoundariesDirty ) {
122 d->databoundariesDirty =
false;
124 return d->databoundaries;
129 d->databoundariesDirty =
true;
135 if ( newModel == model() ) {
141 d->setAttributesModel(amodel);
143 QAbstractItemView::setModel( newModel );
145 scheduleDelayedItemsLayout();
152 if ( selectionModel() )
154 disconnect( selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ),
this, SIGNAL(
modelsChanged() ) );
155 disconnect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ),
this, SIGNAL(
modelsChanged() ) );
157 QAbstractItemView::setSelectionModel( newSelectionModel );
158 if ( selectionModel() )
160 connect( selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ),
this, SIGNAL(
modelsChanged() ) );
161 connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ),
this, SIGNAL(
modelsChanged() ) );
175 if ( amodel->sourceModel() != model() ) {
176 qWarning(
"KDChart::AbstractDiagram::setAttributesModel() failed: " 177 "Trying to set an attributesmodel which works on a different " 178 "model than the diagram.");
181 if ( qobject_cast<PrivateAttributesModel*>(amodel) ) {
182 qWarning(
"KDChart::AbstractDiagram::setAttributesModel() failed: " 183 "Trying to set an attributesmodel that is private to another diagram.");
187 d->setAttributesModel( amodel );
188 scheduleDelayedItemsLayout();
195 return d->usesExternalAttributesModel();
200 return d->attributesModel;
203 QModelIndex AbstractDiagram::conditionallyMapFromSource(
const QModelIndex & index )
const 212 QAbstractItemView::setRootIndex( idx );
219 d->attributesModelRootIndex = idx;
221 scheduleDelayedItemsLayout();
228 if ( !
d->attributesModelRootIndex.isValid() )
229 d->attributesModelRootIndex =
d->attributesModel->mapFromSource( rootIndex() );
230 return d->attributesModelRootIndex;
241 d->plane->layoutDiagrams();
244 QAbstractItemView::doItemsLayout();
247 #if QT_VERSION < 0x050000 249 const QModelIndex &bottomRight )
252 const QModelIndex &bottomRight,
257 Q_UNUSED( bottomRight );
260 scheduleDelayedItemsLayout();
266 d->attributesModel->setData(
267 conditionallyMapFromSource( index ),
268 qVariantFromValue( hidden ),
275 d->setDatasetAttrs( dataset, qVariantFromValue( hidden ),
DataHiddenRole );
281 d->attributesModel->setModelData( qVariantFromValue( hidden ),
DataHiddenRole );
293 if ( boolFlag.isValid() )
294 return boolFlag.value<
bool >();
300 const QVariant boolFlag(
attributesModel()->data( conditionallyMapFromSource( index ),
302 if ( boolFlag.isValid() ) {
303 return boolFlag.value<
bool >();
305 int dataset = index.column() /
d->datasetDimension;
313 d->attributesModel->setData( conditionallyMapFromSource( index ), qVariantFromValue( a ),
343 const QVariant headerAttrs(
345 if ( headerAttrs.isValid() )
353 conditionallyMapFromSource( index ),
368 d->allowOverlappingDataValueTexts = allow;
374 return d->allowOverlappingDataValueTexts;
379 d->antiAliasing = enabled;
385 return d->antiAliasing;
390 d->percent = percent;
401 const QModelIndex& index,
405 d->paintDataValueText( painter, index, pos, value );
415 d->forgetAlreadyPaintedDataValues();
416 const int rowCount = model()->rowCount( rootIndex() );
417 const int columnCount = model()->columnCount( rootIndex() );
418 for (
int column = 0; column < columnCount; column +=
datasetDimension() ) {
419 for (
int row = 0; row < rowCount; ++row ) {
420 QModelIndex index = model()->index( row, column, rootIndex() );
425 y = index.data().toReal();
427 x = index.data().toReal();
428 y = model()->index( row, column + 1, rootIndex() ).data().toReal();
438 const QModelIndex& index,
445 const PainterSaver painterSaver( painter );
447 const QSizeF maSize( ma.
markerSize().width() / painter->matrix().m11(),
448 ma.
markerSize().height() / painter->matrix().m22() );
449 QBrush indexBrush(
brush( index ) );
450 QPen indexPen( ma.
pen() );
454 paintMarker( painter, ma, indexBrush, indexPen, pos, maSize );
461 d->reverseMapper.addCircle( index.row(), index.column(), pos, 2 * maSize );
465 const QModelIndex& index,
477 const QSizeF& maSize )
479 const QPen oldPen( painter->pen() );
486 if ( isFourPixels ) {
487 const qreal x = pos.x();
488 const qreal y = pos.y();
489 painter->drawLine( QPointF(x-1.0,y-1.0),
490 QPointF(x+1.0,y-1.0) );
491 painter->drawLine( QPointF(x-1.0,y),
493 painter->drawLine( QPointF(x-1.0,y+1.0),
494 QPointF(x+1.0,y+1.0) );
496 painter->drawPoint( pos );
498 const PainterSaver painterSaver( painter );
499 QPen painterPen( pen );
501 painter->setBrush( brush );
502 painter->setRenderHint ( QPainter::Antialiasing );
503 painter->translate( pos );
507 if ( markerAttributes.
threeD() ) {
508 QRadialGradient grad;
509 grad.setCoordinateMode( QGradient::ObjectBoundingMode );
510 QColor drawColor = brush.color();
511 grad.setCenter( 0.5, 0.5 );
512 grad.setRadius( 1.0 );
513 grad.setFocalPoint( 0.35, 0.35 );
514 grad.setColorAt( 0.00, drawColor.lighter( 150 ) );
515 grad.setColorAt( 0.20, drawColor );
516 grad.setColorAt( 0.50, drawColor.darker( 150 ) );
517 grad.setColorAt( 0.75, drawColor.darker( 200 ) );
518 grad.setColorAt( 0.95, drawColor.darker( 250 ) );
519 grad.setColorAt( 1.00, drawColor.darker( 200 ) );
520 QBrush newBrush( grad );
521 newBrush.setMatrix( brush.matrix() );
522 painter->setBrush( newBrush );
524 painter->drawEllipse( QRectF( 0 - maSize.height()/2, 0 - maSize.width()/2,
525 maSize.height(), maSize.width()) );
530 QRectF rect( 0 - maSize.width()/2, 0 - maSize.height()/2,
531 maSize.width(), maSize.height() );
532 painter->drawRect( rect );
538 QPointF top, left, bottom, right;
539 top = QPointF( 0, 0 - maSize.height()/2 );
540 left = QPointF( 0 - maSize.width()/2, 0 );
541 bottom = QPointF( 0, maSize.height()/2 );
542 right = QPointF( maSize.width()/2, 0 );
543 diamondPoints << top << left << bottom << right;
544 painter->drawPolygon( diamondPoints );
553 painter->setBrush( Qt::NoBrush );
555 painter->drawEllipse( QRectF( 0 - maSize.height()/2, 0 - maSize.width()/2,
556 maSize.height(), maSize.width()) );
563 const qreal w02 = maSize.width() * 0.2;
564 const qreal w05 = maSize.width() * 0.5;
565 const qreal h02 = maSize.height()* 0.2;
566 const qreal h05 = maSize.height()* 0.5;
569 p[ 0] = QPointF( -w02, -h05 );
570 p[ 1] = QPointF( w02, -h05 );
571 p[ 2] = QPointF( w02, -h02 );
572 p[ 3] = QPointF( w05, -h02 );
573 p[ 4] = QPointF( w05, h02 );
574 p[ 5] = QPointF( w02, h02 );
575 p[ 6] = QPointF( w02, h05 );
576 p[ 7] = QPointF( -w02, h05 );
577 p[ 8] = QPointF( -w02, h02 );
578 p[ 9] = QPointF( -w05, h02 );
579 p[10] = QPointF( -w05, -h02 );
580 p[11] = QPointF( -w02, -h02 );
581 for (
int i=0; i<12; ++i )
584 painter->drawPolygon( crossPoints );
589 QPointF left, right, top, bottom;
590 left = QPointF( -maSize.width()/2, 0 );
591 right = QPointF( maSize.width()/2, 0 );
592 top = QPointF( 0, -maSize.height()/2 );
593 bottom= QPointF( 0, maSize.height()/2 );
595 painter->drawLine( left, right );
596 painter->drawLine( top, bottom );
604 const QRectF pathBoundingRect = path.boundingRect();
605 const qreal xScaling = maSize.height() / pathBoundingRect.height();
606 const qreal yScaling = maSize.width() / pathBoundingRect.width();
607 const qreal scaling = qMin( xScaling, yScaling );
608 painter->scale( scaling, scaling );
610 painter->drawPath(path);
614 Q_ASSERT_X (
false,
"paintMarkers()",
615 "Type item does not match a defined Marker Type." );
618 painter->setPen( oldPen );
627 const int rowCount = model()->rowCount( rootIndex() );
628 const int columnCount = model()->columnCount( rootIndex() );
629 for (
int column = 0; column < columnCount; column +=
datasetDimension() ) {
630 for (
int row = 0; row < rowCount; ++row ) {
631 QModelIndex index = model()->index( row, column, rootIndex() );
636 y = index.data().toReal();
638 x = index.data().toReal();
639 y = model()->index( row, column + 1, rootIndex() ).data().toReal();
650 conditionallyMapFromSource( index ),
664 d->setDatasetAttrs( dataset, qVariantFromValue( pen ),
DatasetPenRole );
675 const QVariant penSettings(
d->datasetAttrs( dataset,
DatasetPenRole ) );
676 if ( penSettings.isValid() )
677 return penSettings.value< QPen >();
684 conditionallyMapFromSource( index ),
691 conditionallyMapFromSource( index ),
717 if ( brushSettings.isValid() )
718 return brushSettings.value< QBrush >();
736 d->unitPrefixMap[ column ][ orientation ]= prefix;
746 d->unitPrefix[ orientation ] = prefix;
757 d->unitSuffixMap[ column ][ orientation ]= suffix;
767 d->unitSuffix[ orientation ] = suffix;
779 if ( !fallback ||
d->unitPrefixMap[ column ].contains( orientation ) )
780 return d->unitPrefixMap[ column ][ orientation ];
781 return d->unitPrefix[ orientation ];
790 return d->unitPrefix[ orientation ];
802 if ( !fallback ||
d->unitSuffixMap[ column ].contains( orientation ) )
803 return d->unitSuffixMap[ column ][ orientation ];
804 return d->unitSuffix[ orientation ];
813 return d->unitSuffix[ orientation ];
819 return d->reverseMapper.boundingRect( index.row(), index.column() ).toRect();
828 {
return QModelIndex(); }
841 const QModelIndexList indexes =
d->indexesIn( rect );
842 QItemSelection selection;
843 KDAB_FOREACH(
const QModelIndex& index, indexes )
845 selection.append( QItemSelectionRange( index ) );
847 selectionModel()->select( selection, command );
853 KDAB_FOREACH(
const QModelIndex& index, selection.indexes() )
855 polygon <<
d->reverseMapper.polygon(index.row(), index.column());
857 return polygon.isEmpty() ? QRegion() : QRegion( polygon.toPolygon() );
862 QPolygonF polygon =
d->reverseMapper.polygon(index.row(), index.column());
863 return polygon.isEmpty() ? QRegion() : QRegion( polygon.toPolygon() );
887 for (
int i = 0; i < rowCount; ++i ) {
889 ret <<
unitPrefix( i, Qt::Horizontal,
true ) +
903 const int datasetCount =
d->datasetCount();
904 for (
int i = 0; i < datasetCount; ++i ) {
905 ret <<
d->datasetAttrs( i, Qt::DisplayRole ).toString();
916 const int datasetCount =
d->datasetCount();
917 for (
int i = 0; i < datasetCount; ++i ) {
929 const int datasetCount =
d->datasetCount();
930 for (
int i = 0; i < datasetCount; ++i ) {
942 const int datasetCount =
d->datasetCount();
943 for (
int i = 0; i < datasetCount; ++i ) {
951 if ( ! justReturnTheStatus ) {
952 Q_ASSERT_X ( model(),
"AbstractDiagram::checkInvariants()",
953 "There is no usable model set, for the diagram." );
956 "There is no usable coordinate plane set, for the diagram." );
963 return d->datasetDimension;
968 Q_UNUSED( dimension );
969 qDebug() <<
"Setting the dataset dimension using AbstractDiagram::setDatasetDimension is " 970 "obsolete. Use the specific diagram types instead.";
975 Q_ASSERT( dimension != 0 );
976 if (
d->datasetDimension == dimension ) {
979 d->datasetDimension = dimension;
980 d->attributesModel->setDatasetDimension( dimension );
988 qWarning() <<
"AbstractDiagram::valueForCell(): Requesting value for invalid index!";
989 return std::numeric_limits<qreal>::quiet_NaN();
991 return d->attributesModel->data(
1004 return d->indexAt( point );
1009 return d->indexesAt( point );
1014 return d->indexesIn( rect );
void useRainbowColors()
Set the palette to be used, for painting datasets to the rainbow palette.
DataValueAttributes dataValueAttributes() const
Retrieve the DataValueAttributes specified globally.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
QModelIndexList indexesAt(const QPoint &point) const
This method is added alongside with indexAt from QAIM, since in kdchart multiple indexes can be displ...
void dataHidden()
This signal is emitted, when the hidden status of at least one data cell was (un)set.
void useDefaultColors()
Set the palette to be used, for painting datasets to the default palette.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
[reimplemented]
MarkerAttributes markerAttributes() const
void setDataBoundariesDirty() const
virtual bool checkInvariants(bool justReturnTheStatus=false) const
Diagram attributes dealing with data value labels.
~AbstractDiagram() override
int rowCount(const QModelIndex &) const override
[reimplemented]
void setSelectionModel(QItemSelectionModel *selectionModel) override
Associate a seleection model with the diagrom.
virtual bool usesExternalAttributesModel() const
Returns whether the diagram is using its own built-in attributes model or an attributes model that wa...
Declaring the class KDChart::DataValueAttributes.
QRegion visualRegionForSelection(const QItemSelection &selection) const override
[reimplemented]
void useSubduedColors()
Set the palette to be used, for painting datasets to the subdued palette.
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
void setHidden(const QModelIndex &index, bool hidden)
Hide (or unhide, resp.) a data cell.
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
qreal valueForCell(int row, int column) const
Helper method, retrieving the data value (DisplayRole) for a given row and column.
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
QStringList datasetLabels() const
The set of dataset labels currently displayed, for use in legends, etc.
void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible) override
[reimplemented]
QVariant modelData(int role) const
void setDatasetDimensionInternal(int dimension)
void setBrush(const QModelIndex &index, const QBrush &brush)
Set the brush to be used, for painting the datapoint at the given index.
QString unitSuffix(int column, Qt::Orientation orientation, bool fallback=false) const
Retrieves the axis unit suffix for a specific column.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
[reimplemented]
void setAllowOverlappingDataValueTexts(bool allow)
Set whether data value labels are allowed to overlap.
void setRootIndex(const QModelIndex &idx) override
Set the root index in the model, where the diagram starts referencing data for display.
QString unitPrefix(int column, Qt::Orientation orientation, bool fallback=false) const
Retrieves the axis unit prefix for a specific column.
AbstractDiagram defines the interface for diagram classes.
QVariant data(int role) const
Returns the data that were specified at global level, or the default data, or QVariant().
QBrush brush() const
Retrieve the brush to be used for painting datapoints globally.
QPainterPath customMarkerPath() const
void setPen(const QModelIndex &index, const QPen &pen)
Set the pen to be used, for painting the datapoint at the given index.
void setDatasetDimension(int dimension)
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
void aboutToBeDestroyed()
This signal is emitted when this diagram is being destroyed, but before all the data, i.e.
void setAntiAliasing(bool enabled)
Set whether anti-aliasing is to be used while rendering this diagram.
Class only listed here to document inheritance of some KDChart classes.
virtual void paintMarker(QPainter *painter, const MarkerAttributes &markerAttributes, const QBrush &brush, const QPen &, const QPointF &point, const QSizeF &size)
bool isIndexHidden(const QModelIndex &index) const override
[reimplemented]
bool compare(const AttributesModel *other) const
Returns true if both, all of the attributes set, and the palette set is equal in both of the Attribut...
QColor markerColor() const
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
[reimplemented]
void propertiesChanged()
Emitted upon change of a property of the Diagram.
bool percentMode() const
Returns whether this diagram is drawn in percent mode.
A proxy model used for decorating data with attributes.
QList< QBrush > datasetBrushes() const
The set of dataset brushes currently used, for use in legends, etc.
bool antiAliasing() const
virtual void setAttributesModel(AttributesModel *model)
Associate an AttributesModel with this diagram.
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
Set the coordinate plane associated with the diagram.
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
[reimplemented]
QSizeF markerSize() const
QList< QPen > datasetPens() const
The set of dataset pens currently used, for use in legends, etc.
void setAttributesModelRootIndex(const QModelIndex &)
void setModel(QAbstractItemModel *model) override
Associate a model with the diagram.
int horizontalOffset() const override
[reimplemented]
bool allowOverlappingDataValueTexts() const
void doItemsLayout() override
[reimplemented]
void setUnitSuffix(const QString &suffix, int column, Qt::Orientation orientation)
Set the unit prefix to be used on axes for one specific column.
int verticalOffset() const override
[reimplemented]
virtual void paintMarkers(QPainter *painter)
QPointF translate(const TernaryPoint &point)
void setUnitPrefix(const QString &prefix, int column, Qt::Orientation orientation)
Set the unit prefix to be used on axes for one specific column.
bool compare(const AbstractDiagram *other) const
Returns true if both diagrams have the same settings.
void paintDataValueText(QPainter *painter, const QModelIndex &index, const QPointF &pos, qreal value)
A set of attributes controlling the appearance of data set markers.
QPen pen() const
Retrieve the pen to be used for painting datapoints globally.
void setShowOverlappingDataLabels(bool showOverlappingDataLabels)
Set whether data value texts overlapping other data value texts of the same diagram should be drawn...
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) override
[reimplemented]
void layoutChanged(AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes...
QRect visualRect(const QModelIndex &index) const override
[reimplemented]
QStringList itemRowLabels() const
The set of item row labels currently displayed, for use in Abscissa axes, etc.
QModelIndex attributesModelRootIndex() const
virtual QRegion visualRegion(const QModelIndex &index) const
void initFrom(const AttributesModel *other)
Copies the internal data (maps and palette) of another AttributesModel* into this one...
virtual void paintDataValueTexts(QPainter *painter)
static QPen scalePen(const QPen &pen)
bool isHidden() const
Retrieve the hidden status specified globally.
QList< MarkerAttributes > datasetMarkers() const
The set of dataset markers currently used, for use in legends, etc.
virtual const QPair< QPointF, QPointF > calculateDataBoundaries() const =0
QModelIndexList indexesIn(const QRect &rect) const
bool setModelData(const QVariant value, int role)
void setDataValueAttributes(const QModelIndex &index, const DataValueAttributes &a)
Set the DataValueAttributes for the given index.
int datasetDimension() const
The dataset dimension of a diagram determines how many value dimensions it expects each datapoint to ...
AbstractDiagram(Private *p, QWidget *parent, AbstractCoordinatePlane *plane)
QModelIndex indexAt(const QPoint &point) const override
[reimplemented]
Internally used class just adding a special constructor used by AbstractDiagram.
void modelsChanged()
This signal is emitted when either the model or the AttributesModel is replaced.