File indexing completed on 2024-05-12 16:33:33

0001 /* This file is part of the KDE project
0002 
0003    Copyright 2008 Johannes Simon <johannes.simon@gmail.com>
0004    Copyright (C) 2010 Carlos Licea <carlos@kdab.com>
0005    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
0006      Contact: Suresh Chande suresh.chande@nokia.com
0007 
0008    This library is free software; you can redistribute it and/or
0009    modify it under the terms of the GNU Library General Public
0010    License as published by the Free Software Foundation; either
0011    version 2 of the License, or (at your option) any later version.
0012 
0013    This library is distributed in the hope that it will be useful,
0014    but WITHOUT ANY WARRANTY; without even the implied warranty of
0015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016    Library General Public License for more details.
0017 
0018    You should have received a copy of the GNU Library General Public License
0019    along with this library; see the file COPYING.LIB.  If not, write to
0020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021    Boston, MA 02110-1301, USA.
0022 */
0023 
0024 #ifndef KCHART_KDCHARTMODEL_H
0025 #define KCHART_KDCHARTMODEL_H
0026 
0027 
0028 // Qt
0029 #include <QAbstractItemModel>
0030 
0031 // KoChart
0032 #include "ChartShape.h"
0033 
0034 
0035 namespace KoChart {
0036 
0037 class DataSet;
0038 
0039 /**
0040  * Takes a list of DataSet's and compiles them into a
0041  * QAbstractItemModel for use with KChart.
0042  *
0043  * Data sets in this model are aligned column-wise. Each column
0044  * occupies dimension() columns. For example, for an X/Y chart,
0045  * the data of this model would be structured as follows:
0046  *
0047  *             Brush 0       Brush 1
0048  *             Pen 0         Pen 1
0049  *             Label 0       Label 1
0050  * -----------|------|------|------|------|
0051  * Category 1 | x0,0 | y0,0 | x1,0 | x1,0 |
0052  * -----------|------|------|------|------|
0053  * Category 2 | x0,1 | y0,1 | x1,1 | x1,1 |
0054  * -----------|------|------|------|------|
0055  * Category 3 | x0,2 | y0,2 | x1,2 | x1,2 |
0056  * -----------|------|------|------|------|
0057  *
0058  */
0059 
0060  /**
0061   * Note on data directions in KChart's models:
0062   *
0063   * For circular (polar) charts, items shown in the legend should not be the
0064   * data set labels, but the category labels instead. For example, a pie chart
0065   * contains exactly one data set (if there's more series in the table, they are
0066   * ignored). Obviously showing the title of the data set wouldn't be very useful
0067   * in the legend. So the categories are shown instead.
0068   *
0069   * Since KChart extracts the legend items from horizontal header data (the headers
0070   * in each column) data sets have to be inserted row-wise instead of column-wise for
0071   * these charts. To do so, KChartModel::setDataDirection(Qt::Horizontal) is used.
0072   *
0073   * In all other cases, we show the data set labels in the legend. Therefore we insert
0074   * data sets column-wise, which is done by calling setDataDirection(Qt::Vertical).
0075   */
0076 
0077 class KChartModel : public QAbstractItemModel
0078 {
0079     Q_OBJECT
0080 
0081 public:
0082     explicit KChartModel(PlotArea *plotArea, QObject *parent = 0);
0083     ~KChartModel();
0084 
0085     enum DataRole {
0086         XDataRole,
0087         YDataRole,
0088         ZDataRole,
0089         LabelDataRole,
0090         CategoryDataRole,
0091         CustomDataRole,
0092         BrushDataRole,
0093         PenDataRole,
0094         PieAttributesRole,
0095         DataValueAttributesRole
0096     };
0097 
0098     /**
0099      * Specifies in what direction a data set 'points'. More specifically,
0100      * if the data direction is Qt::Vertical, a data set occupies one
0101      * column (in case only one data dimension is being used).
0102      *
0103      * See "Note on data directions in KChart's models" above.
0104      */
0105     void setDataDirection(Qt::Orientation direction);
0106     /**
0107      * See \a setDataDirection
0108      */
0109     Qt::Orientation dataDirection() const;
0110     /**
0111      * Returns the opposite of dataDirection().
0112      */
0113     Qt::Orientation categoryDirection() const;
0114 
0115 public Q_SLOTS:
0116     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0117     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
0118 
0119     void slotColumnsInserted(const QModelIndex& parent, int start, int end);
0120 
0121     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
0122     QModelIndex parent(const QModelIndex &index) const override;
0123 
0124     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0125     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
0126 
0127     void setDataDimensions(int dataDimensions);
0128     int dataDimensions() const;
0129 
0130     void addDataSet(DataSet *dataSet);
0131     void removeDataSet(DataSet *dataSet, bool silent = false);
0132     QList<DataSet*> dataSets() const;
0133 
0134     /**
0135      * Called by DataSet whenever a property that is global to all its data
0136      * points changes, e.g. its label or its pen
0137      */
0138     void dataSetChanged(DataSet *dataSet);
0139 
0140     /**
0141      * Called by DataSet whenever one or more of its data points changes,
0142      * e.g. the x value of a data point.
0143      *
0144      * FIXME: @a role doesn't make sense here, it's not needed for emitting
0145      *        the dataChanged() signal. Removing it would conflict with
0146      *        dataSetChanged(DataSet*), that's why it's still there.
0147      *
0148      * @param first First data point that changed. If -1 it is assumed that
0149      *              all data points in this series changed.
0150      * @param last Last data point that changed. If -1 it is assumed that
0151      *             only a single data point changed.
0152      */
0153     void dataSetChanged(DataSet *dataSet, DataRole role, int first = -1, int last = -1);
0154 
0155     /**
0156      * Called by DataSet when the total number of data points it has changed.
0157      */
0158     void dataSetSizeChanged(DataSet *dataSet, int newSize);
0159 
0160 private:
0161     class Private;
0162     Private *const d;
0163 };
0164 
0165 } // namespace KoChart
0166 
0167 #endif // KCHART_KDCHARTMODEL_H