12 #include "KDChartAbstractDiagram_p.h" 
   14 #include <QAbstractProxyModel> 
   15 #include <QApplication> 
   25 #include "KDChartPainterSaver_p.h" 
   29 #include <KDABLibFakes> 
   38     : QAbstractItemView(parent)
 
   51 void AbstractDiagram::init()
 
   54     d->reverseMapper.setDiagram(
this);
 
   65         (horizontalScrollBarPolicy() == other->horizontalScrollBarPolicy()) && (verticalScrollBarPolicy() == other->verticalScrollBarPolicy()) &&
 
   67         (frameShadow() == other->frameShadow()) && (frameShape() == other->frameShape()) &&
 
   70         (lineWidth() == other->lineWidth()) && (midLineWidth() == other->midLineWidth()) &&
 
   72         (alternatingRowColors() == other->alternatingRowColors()) && (hasAutoScroll() == other->hasAutoScroll()) && (dragDropMode() == other->dragDropMode()) && (dragDropOverwriteMode() == other->dragDropOverwriteMode()) && (horizontalScrollMode() == other->horizontalScrollMode()) && (verticalScrollMode() == other->verticalScrollMode()) && (dragEnabled() == other->dragEnabled()) && (editTriggers() == other->editTriggers()) && (iconSize() == other->iconSize()) && (selectionBehavior() == other->selectionBehavior()) && (selectionMode() == other->selectionMode()) && (showDropIndicator() == other->showDropIndicator()) && (tabKeyNavigation() == other->tabKeyNavigation()) && (textElideMode() == other->textElideMode()) &&
 
   86     if (
d->databoundariesDirty) {
 
   88         d->databoundariesDirty = 
false;
 
   90     return d->databoundaries;
 
   95     d->databoundariesDirty = 
true;
 
  101     if (newModel == model()) {
 
  107     d->setAttributesModel(amodel);
 
  109     QAbstractItemView::setModel(newModel);
 
  111     QAbstractItemModel *oldModel = QAbstractItemView::model();
 
  112     if (oldModel != 
nullptr) {
 
  117     scheduleDelayedItemsLayout();
 
  124     if (selectionModel()) {
 
  128     QAbstractItemView::setSelectionModel(newSelectionModel);
 
  129     if (selectionModel()) {
 
  145     if (amodel->sourceModel() != model()) {
 
  146         qWarning(
"KDChart::AbstractDiagram::setAttributesModel() failed: " 
  147                  "Trying to set an attributesmodel which works on a different " 
  148                  "model than the diagram.");
 
  151     if (qobject_cast<PrivateAttributesModel *>(amodel)) {
 
  152         qWarning(
"KDChart::AbstractDiagram::setAttributesModel() failed: " 
  153                  "Trying to set an attributesmodel that is private to another diagram.");
 
  157     d->setAttributesModel(amodel);
 
  158     scheduleDelayedItemsLayout();
 
  165     return d->usesExternalAttributesModel();
 
  170     return d->attributesModel;
 
  173 QModelIndex AbstractDiagram::conditionallyMapFromSource(
const QModelIndex &index)
 const 
  182     QAbstractItemView::setRootIndex(idx);
 
  189     d->attributesModelRootIndex = idx;
 
  191     scheduleDelayedItemsLayout();
 
  198     if (!
d->attributesModelRootIndex.isValid())
 
  199         d->attributesModelRootIndex = 
d->attributesModel->mapFromSource(rootIndex());
 
  200     return d->attributesModelRootIndex;
 
  211         d->plane->layoutDiagrams();
 
  214     QAbstractItemView::doItemsLayout();
 
  218                                   const QModelIndex &bottomRight,
 
  219                                   const QVector<int> &)
 
  222     Q_UNUSED(bottomRight);
 
  225     scheduleDelayedItemsLayout();
 
  230     d->attributesModel->setData(
 
  231         conditionallyMapFromSource(index),
 
  232         QVariant::fromValue(hidden),
 
  239     d->setDatasetAttrs(dataset, QVariant::fromValue(hidden), 
DataHiddenRole);
 
  245     d->attributesModel->setModelData(QVariant::fromValue(hidden), 
DataHiddenRole);
 
  257     if (boolFlag.isValid())
 
  258         return boolFlag.value<
bool>();
 
  264     const QVariant boolFlag(
attributesModel()->data(conditionallyMapFromSource(index),
 
  266     if (boolFlag.isValid()) {
 
  267         return boolFlag.value<
bool>();
 
  269     int dataset = index.column() / 
d->datasetDimension;
 
  276     d->attributesModel->setData(conditionallyMapFromSource(index), QVariant::fromValue(a),
 
  305     const QVariant headerAttrs(
 
  307     if (headerAttrs.isValid())
 
  315                                 conditionallyMapFromSource(index),
 
  331     d->allowOverlappingDataValueTexts = allow;
 
  337     return d->allowOverlappingDataValueTexts;
 
  342     d->antiAliasing = enabled;
 
  348     return d->antiAliasing;
 
  353     d->percent = percent;
 
  363                                          const QModelIndex &index,
 
  367     d->paintDataValueText(painter, index, pos, value);
 
  376     d->forgetAlreadyPaintedDataValues();
 
  377     const int rowCount = model()->rowCount(rootIndex());
 
  378     const int columnCount = model()->columnCount(rootIndex());
 
  380         for (
int row = 0; row < rowCount; ++row) {
 
  381             QModelIndex index = model()->index(row, column, rootIndex()); 
 
  386                 y = index.data().toReal();
 
  388                 x = index.data().toReal();
 
  389                 y = model()->index(row, column + 1, rootIndex()).data().toReal();
 
  398                                   const QModelIndex &index,
 
  407     const PainterSaver painterSaver(painter);
 
  409     const QSizeF maSize(ma.
markerSize().width() / painter->transform().m11(),
 
  410                         ma.
markerSize().height() / painter->transform().m22());
 
  411     QBrush indexBrush(
brush(index));
 
  412     QPen indexPen(ma.
pen());
 
  416     paintMarker(painter, ma, indexBrush, indexPen, pos, maSize);
 
  423     d->reverseMapper.addCircle(index.row(), index.column(), pos, 2 * maSize);
 
  427                                   const QModelIndex &index,
 
  440                                   const QSizeF &maSize)
 
  442     const QPen oldPen(painter->pen());
 
  450             const qreal x = pos.x();
 
  451             const qreal y = pos.y();
 
  452             painter->drawLine(QPointF(x - 1.0, y - 1.0),
 
  453                               QPointF(x + 1.0, y - 1.0));
 
  454             painter->drawLine(QPointF(x - 1.0, y),
 
  455                               QPointF(x + 1.0, y));
 
  456             painter->drawLine(QPointF(x - 1.0, y + 1.0),
 
  457                               QPointF(x + 1.0, y + 1.0));
 
  459         painter->drawPoint(pos);
 
  461         const PainterSaver painterSaver(painter);
 
  462         QPen painterPen(
pen);
 
  464         painter->setBrush(
brush);
 
  465         painter->setRenderHint(QPainter::Antialiasing);
 
  466         painter->translate(pos);
 
  469             if (markerAttributes.
threeD()) {
 
  470                 QRadialGradient grad;
 
  471                 grad.setCoordinateMode(QGradient::ObjectBoundingMode);
 
  472                 QColor drawColor = 
brush.color();
 
  473                 grad.setCenter(0.5, 0.5);
 
  475                 grad.setFocalPoint(0.35, 0.35);
 
  476                 grad.setColorAt(0.00, drawColor.lighter(150));
 
  477                 grad.setColorAt(0.20, drawColor);
 
  478                 grad.setColorAt(0.50, drawColor.darker(150));
 
  479                 grad.setColorAt(0.75, drawColor.darker(200));
 
  480                 grad.setColorAt(0.95, drawColor.darker(250));
 
  481                 grad.setColorAt(1.00, drawColor.darker(200));
 
  482                 QBrush newBrush(grad);
 
  483                 newBrush.setTransform(
brush.transform());
 
  484                 painter->setBrush(newBrush);
 
  486             painter->drawEllipse(QRectF(0 - maSize.height() / 2, 0 - maSize.width() / 2,
 
  487                                         maSize.height(), maSize.width()));
 
  490             QRectF rect(0 - maSize.width() / 2, 0 - maSize.height() / 2,
 
  491                         maSize.width(), maSize.height());
 
  492             painter->drawRect(rect);
 
  496             QVector<QPointF> diamondPoints;
 
  497             QPointF top, left, bottom, right;
 
  498             top = QPointF(0, 0 - maSize.height() / 2);
 
  499             left = QPointF(0 - maSize.width() / 2, 0);
 
  500             bottom = QPointF(0, maSize.height() / 2);
 
  501             right = QPointF(maSize.width() / 2, 0);
 
  502             diamondPoints << top << left << bottom << right;
 
  503             painter->drawPolygon(diamondPoints);
 
  511             painter->setBrush(Qt::NoBrush);
 
  513             painter->drawEllipse(QRectF(0 - maSize.height() / 2, 0 - maSize.width() / 2,
 
  514                                         maSize.height(), maSize.width()));
 
  520             const qreal w02 = maSize.width() * 0.2;
 
  521             const qreal w05 = maSize.width() * 0.5;
 
  522             const qreal h02 = maSize.height() * 0.2;
 
  523             const qreal h05 = maSize.height() * 0.5;
 
  524             QVector<QPointF> crossPoints;
 
  526             p[0] = QPointF(-w02, -h05);
 
  527             p[1] = QPointF(w02, -h05);
 
  528             p[2] = QPointF(w02, -h02);
 
  529             p[3] = QPointF(w05, -h02);
 
  530             p[4] = QPointF(w05, h02);
 
  531             p[5] = QPointF(w02, h02);
 
  532             p[6] = QPointF(w02, h05);
 
  533             p[7] = QPointF(-w02, h05);
 
  534             p[8] = QPointF(-w02, h02);
 
  535             p[9] = QPointF(-w05, h02);
 
  536             p[10] = QPointF(-w05, -h02);
 
  537             p[11] = QPointF(-w02, -h02);
 
  538             for (
int i = 0; i < 12; ++i)
 
  541             painter->drawPolygon(crossPoints);
 
  545             QPointF left, right, top, bottom;
 
  546             left = QPointF(-maSize.width() / 2, 0);
 
  547             right = QPointF(maSize.width() / 2, 0);
 
  548             top = QPointF(0, -maSize.height() / 2);
 
  549             bottom = QPointF(0, maSize.height() / 2);
 
  551             painter->drawLine(left, right);
 
  552             painter->drawLine(top, bottom);
 
  559             const QRectF pathBoundingRect = path.boundingRect();
 
  560             const qreal xScaling = maSize.height() / pathBoundingRect.height();
 
  561             const qreal yScaling = maSize.width() / pathBoundingRect.width();
 
  562             const qreal scaling = qMin(xScaling, yScaling);
 
  563             painter->scale(scaling, scaling);
 
  565             painter->drawPath(path);
 
  569             Q_ASSERT_X(
false, 
"paintMarkers()",
 
  570                        "Type item does not match a defined Marker Type.");
 
  573     painter->setPen(oldPen);
 
  582     const int rowCount = model()->rowCount(rootIndex());
 
  583     const int columnCount = model()->columnCount(rootIndex());
 
  585         for (
int row = 0; row < rowCount; ++row) {
 
  586             QModelIndex index = model()->index(row, column, rootIndex()); 
 
  591                 y = index.data().toReal();
 
  593                 x = index.data().toReal();
 
  594                 y = model()->index(row, column + 1, rootIndex()).data().toReal();
 
  604         conditionallyMapFromSource(index),
 
  630     if (penSettings.isValid())
 
  631         return penSettings.value<QPen>();
 
  638                                 conditionallyMapFromSource(index),
 
  646         conditionallyMapFromSource(index),
 
  672     if (brushSettings.isValid())
 
  673         return brushSettings.value<QBrush>();
 
  690     d->unitPrefixMap[column][orientation] = prefix;
 
  700     d->unitPrefix[orientation] = prefix;
 
  711     d->unitSuffixMap[column][orientation] = suffix;
 
  721     d->unitSuffix[orientation] = suffix;
 
  733     if (!fallback || 
d->unitPrefixMap[column].contains(orientation))
 
  734         return d->unitPrefixMap[column][orientation];
 
  735     return d->unitPrefix[orientation];
 
  744     return d->unitPrefix[orientation];
 
  756     if (!fallback || 
d->unitSuffixMap[column].contains(orientation))
 
  757         return d->unitSuffixMap[column][orientation];
 
  758     return d->unitSuffix[orientation];
 
  767     return d->unitSuffix[orientation];
 
  773     return d->reverseMapper.boundingRect(index.row(), index.column()).toRect();
 
  784     return QModelIndex();
 
  804     const QModelIndexList indexes = 
d->indexesIn(rect);
 
  805     QItemSelection selection;
 
  806     for (
const QModelIndex &index : indexes) {
 
  807         selection.append(QItemSelectionRange(index));
 
  809     selectionModel()->select(selection, command);
 
  815     const auto constIndexes = selection.indexes();
 
  816     for (
const QModelIndex &index : constIndexes) {
 
  817         polygon << 
d->reverseMapper.polygon(index.row(), index.column());
 
  819     return polygon.isEmpty() ? QRegion() : QRegion(polygon.toPolygon());
 
  824     QPolygonF polygon = 
d->reverseMapper.polygon(index.row(), index.column());
 
  825     return polygon.isEmpty() ? QRegion() : QRegion(polygon.toPolygon());
 
  849         for (
int i = 0; i < rowCount; ++i) {
 
  863     const int datasetCount = 
d->datasetCount();
 
  864     for (
int i = 0; i < datasetCount; ++i) {
 
  865         ret << 
d->datasetAttrs(i, Qt::DisplayRole).toString();
 
  876     const int datasetCount = 
d->datasetCount();
 
  877     for (
int i = 0; i < datasetCount; ++i) {
 
  889     const int datasetCount = 
d->datasetCount();
 
  890     for (
int i = 0; i < datasetCount; ++i) {
 
  898     QList<MarkerAttributes> ret;
 
  902     const int datasetCount = 
d->datasetCount();
 
  903     for (
int i = 0; i < datasetCount; ++i) {
 
  911     if (!justReturnTheStatus) {
 
  912         Q_ASSERT_X(model(), 
"AbstractDiagram::checkInvariants()",
 
  913                    "There is no usable model set, for the diagram.");
 
  916                    "There is no usable coordinate plane set, for the diagram.");
 
  923     return d->datasetDimension;
 
  929     qDebug() << 
"Setting the dataset dimension using AbstractDiagram::setDatasetDimension is " 
  930                 "obsolete. Use the specific diagram types instead.";
 
  935     Q_ASSERT(dimension != 0);
 
  936     if (
d->datasetDimension == dimension) {
 
  939     d->datasetDimension = dimension;
 
  940     d->attributesModel->setDatasetDimension(dimension);
 
  948         qWarning() << 
"AbstractDiagram::valueForCell(): Requesting value for invalid index!";
 
  949         return std::numeric_limits<qreal>::quiet_NaN();
 
  951     return d->attributesModel->data(
 
  965     return d->indexAt(point);
 
  970     return d->indexesAt(point);
 
  975     return d->indexesIn(rect);
 
Declaring the class KDChart::DataValueAttributes.
QPointF translate(const TernaryPoint &point)
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
AbstractDiagram defines the interface for diagram classes.
void setModel(QAbstractItemModel *model) override
void setDataValueAttributes(const QModelIndex &index, const DataValueAttributes &a)
virtual Q_DECL_DEPRECATED void paintDataValueTexts(QPainter *painter)
virtual const QPair< QPointF, QPointF > calculateDataBoundaries() const =0
virtual AttributesModel * attributesModel() const
bool compare(const AbstractDiagram *other) const
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) override
int verticalOffset() const override
void setUnitPrefix(const QString &prefix, int column, Qt::Orientation orientation)
virtual bool checkInvariants(bool justReturnTheStatus=false) const
void setPen(const QModelIndex &index, const QPen &pen)
virtual void paintMarker(QPainter *painter, const MarkerAttributes &markerAttributes, const QBrush &brush, const QPen &, const QPointF &point, const QSizeF &size)
int horizontalOffset() const override
~AbstractDiagram() override
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
DataValueAttributes dataValueAttributes() const
void paintDataValueText(QPainter *painter, const QModelIndex &index, const QPointF &pos, qreal value)
void setAntiAliasing(bool enabled)
QStringList datasetLabels() const
QRect visualRect(const QModelIndex &index) const override
void layoutChanged(AbstractDiagram *)
AbstractDiagram(Private *p, QWidget *parent, AbstractCoordinatePlane *plane)
QModelIndex attributesModelRootIndex() const
returns a QModelIndex pointing into the AttributesModel that corresponds to the root index of the dia...
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 scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible) override
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >()) override
QList< QBrush > datasetBrushes() const
virtual void setAttributesModel(AttributesModel *model)
Sets an external AttributesModel on this diagram.
Q_DECL_DEPRECATED qreal valueForCell(int row, int column) const
QString unitPrefix(int column, Qt::Orientation orientation, bool fallback=false) const
bool allowOverlappingDataValueTexts() const
AbstractCoordinatePlane * coordinatePlane() const
void setHidden(const QModelIndex &index, bool hidden)
bool isIndexHidden(const QModelIndex &index) const override
QList< QPen > datasetPens() const
void setDataBoundariesDirty() const
void setUnitSuffix(const QString &suffix, int column, Qt::Orientation orientation)
QModelIndexList indexesIn(const QRect &rect) const
void setBrush(const QModelIndex &index, const QBrush &brush)
Q_DECL_DEPRECATED void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
void setAllowOverlappingDataValueTexts(bool allow)
QStringList itemRowLabels() const
bool percentMode() const
Returns whether this diagram is drawn in percent mode.
void setSelectionModel(QItemSelectionModel *selectionModel) override
Q_DECL_DEPRECATED void setDatasetDimension(int dimension)
virtual bool usesExternalAttributesModel() const
int datasetDimension() const
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
QModelIndex indexAt(const QPoint &point) const override
bool antiAliasing() const
QModelIndexList indexesAt(const QPoint &point) const
void setRootIndex(const QModelIndex &idx) override
Reimplemented for internal purposes.
virtual QRegion visualRegion(const QModelIndex &index) const
virtual Q_DECL_DEPRECATED void paintMarkers(QPainter *painter)
void aboutToBeDestroyed()
QList< MarkerAttributes > datasetMarkers() const
void doItemsLayout() override
QString unitSuffix(int column, Qt::Orientation orientation, bool fallback=false) const
void setAttributesModelRootIndex(const QModelIndex &)
void setDatasetDimensionInternal(int dimension)
QRegion visualRegionForSelection(const QItemSelection &selection) const override
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
Reimplemented for internal purposes.
A proxy model used for decorating data with attributes.
QVariant data(int role) const
int rowCount(const QModelIndex &) const override
QVariant modelData(int role) const
void initFrom(const AttributesModel *other)
bool compare(const AttributesModel *other) const
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
bool setModelData(const QVariant value, int role)
Diagram attributes dealing with data value labels.
MarkerAttributes markerAttributes() const
void setShowOverlappingDataLabels(bool showOverlappingDataLabels)
A set of attributes controlling the appearance of data set markers.
QPainterPath customMarkerPath() const
QColor markerColor() const
QSizeF markerSize() const
static QPen scalePen(const QPen &pen)
Internally used class just adding a special constructor used by AbstractDiagram.
@ DataValueLabelAttributesRole