1 /***************************************************************************
2  * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr
3  * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr
4  * SPDX-License-Identifier: GPL-3.0-or-later
5  ***************************************************************************/
6 #ifndef SKGTABLEWITHGRAPH_H
7 #define SKGTABLEWITHGRAPH_H
8 /** @file
9  * A table with graph with more features.
10  *
11  * @author Stephane MANKOWSKI / Guillaume DE BURE
12  */
13 #include <qwidget.h>
14 
15 
16 
17 #include "skgbasegui_export.h"
18 #include "skgcombobox.h"
19 #include "skgservices.h"
20 #include "ui_skgtablewithgraph.h"
21 
22 class SKGGraphicsScene;
23 class QMenu;
24 class QTimer;
25 class QWidgetAction;
26 class QGraphicsItem;
27 
28 /**
29  * This file is a table with graph with more features
30  */
31 class SKGBASEGUI_EXPORT SKGTableWithGraph : public QWidget
32 {
33     Q_OBJECT
34 
35 public:
36     /**
37      * Graph type
38      */
39     enum GraphType {STACK,
40                     HISTOGRAM,
41                     PIE,
42                     CONCENTRICPIE,
43                     POINT,
44                     LINE,
45                     STACKAREA,
46                     BUBBLE,
47                     STACKCOLUMNS,
48                     TREEMAP
49                    };
50     /**
51      * Graph type
52      */
53     Q_ENUM(GraphType)
54 
55     /**
56      * Additional information to display
57      */
58     enum DisplayAdditional {NONE      = 0x0,
59                             SUM       = 0x1,
60                             AVERAGE   = 0x2,
61                             LIMITS    = 0x4,
62                             ALL       = 255
63                            };
64     /**
65      * Additional information to display
66      */
67     Q_ENUM(DisplayAdditional)
68 
69     /**
70      * Additional information to display
71      */
72     Q_DECLARE_FLAGS(DisplayAdditionalFlag, DisplayAdditional)
73 
74     /**
75      * Graph Type widget visibility
76      */
77     Q_PROPERTY(bool graphTypeSelectorVisible READ isGraphTypeSelectorVisible WRITE setGraphTypeSelectorVisible NOTIFY modified)
78     /**
79      * Items selectable or not
80      */
81     Q_PROPERTY(bool selectable READ isSelectable WRITE setSelectable NOTIFY modified)
82     /**
83      * Items with shadow or not
84      */
85     Q_PROPERTY(bool shadow READ isShadowVisible WRITE setShadowVisible NOTIFY modified)
86     /**
87      * Graph Type
88      */
89     Q_PROPERTY(GraphType graphType READ getGraphType WRITE setGraphType NOTIFY modified)
90     /**
91      * Default Constructor
92      */
93     SKGTableWithGraph();
94 
95     /**
96      * Constructor
97      * @param iParent the parent
98      */
99     explicit SKGTableWithGraph(QWidget* iParent);
100 
101     /**
102      * Default Destructor
103      */
104     ~SKGTableWithGraph() override;
105 
106     /**
107     * Get the current state
108     * MUST BE OVERWRITTEN
109     * @return a string containing all information needed to set the same state.
110     * Could be an XML stream
111      */
112     QString getState();
113 
114     /**
115      * Returns the table.
116      * @return table
117      */
118     QTableWidget* table() const;
119 
120     /**
121      * Returns the graph.
122      * @return graph
123      */
124     SKGGraphicsView* graph() const;
125 
126     /**
127      * Returns the text report.
128      * @return text report
129      */
130     SKGWebView* textReport() const;
131 
132     /**
133      * Get the mode for the additional display
134      * @return the mode
135      */
136     SKGTableWithGraph::DisplayAdditionalFlag getAdditionalDisplayMode() const;
137 
138     /**
139      * Get the table content
140      * @return the table content
141      */
142     SKGStringListList getTable();
143 
144     /**
145      * Get a pointer on the contextual menu of the table
146      * @return contextual menu
147      */
148     QMenu* getTableContextualMenu() const;
149 
150     /**
151      * Get a pointer on the contextual menu of the graph
152      * @return contextual menu
153      */
154     QMenu* getGraphContextualMenu() const;
155 
156     /**
157      * Get the visibility of the graph type selector zone
158      * @return the visibility
159      */
160     bool isGraphTypeSelectorVisible() const;
161 
162     /**
163      * Get the selectability of items
164      * @return the selectability
165      */
166     bool isSelectable() const;
167 
168     /**
169      * Get the shadows visibility
170      * @return the visibility
171      */
172     bool isShadowVisible() const;
173 
174     /**
175      * Get the graph type
176      *  @return the type of graph
177      */
178     SKGTableWithGraph::GraphType getGraphType() const;
179 
180     /**
181      * Get the number of columns
182      * @param iWithComputed with compute columns (average, sum, forecast, ...) or not
183      * @return the number of columns
184      */
185     int getNbColumns(bool iWithComputed = false) const;
186 
187     /**
188      * @brief Get show widget
189      *
190      * @return SKGShow*
191      **/
192     SKGShow* getShowWidget() const;
193 
194     /**
195      * To know if the table is visible
196      * @return the visibility
197      */
198     bool isTableVisible() const;
199 
200     /**
201      * To know if the graph is visible
202      * @return the visibility
203      */
204     bool isGraphVisible() const;
205 
206     /**
207      * To know if the text report is visible
208      * @return the visibility
209      */
210     bool isTextReportVisible() const;
211 
212 public Q_SLOTS:
213 
214     /**
215      * Set the current state
216      * MUST BE OVERWRITTEN
217      * @param iState must be interpreted to set the state of the widget
218      */
219     void setState(const QString& iState);
220 
221     /**
222      * Set Data
223      * @param iData the data
224      * @param iPrimaryUnit the primary unit
225      * @param iSecondaryUnit the secondary unit
226      * @param iAdditionalInformation show sum and average columns
227      * @param iNbVirtualColumn number of columns
228      */
229     void setData(const SKGStringListList& iData,
230                  const SKGServices::SKGUnitInfo& iPrimaryUnit,
231                  const SKGServices::SKGUnitInfo& iSecondaryUnit,
232                  SKGTableWithGraph::DisplayAdditionalFlag iAdditionalInformation = SKGTableWithGraph::ALL,
233                  int iNbVirtualColumn = 0);
234 
235 
236     /**
237      * Set the visibility of the graph type selector zone
238      * @param iVisible the visibility
239      */
240     void setGraphTypeSelectorVisible(bool iVisible);
241 
242     /**
243      * Enable / disable the selectability of items
244      * @param iSelectable the selectability
245      */
246     void setSelectable(bool iSelectable);
247 
248     /**
249      * Enable / disable the shadows
250      * @param iShadow the shadows
251      */
252     void setShadowVisible(bool iShadow);
253 
254     /**
255      * Set the graph type
256      * @param iType the type of graph
257      */
258     void setGraphType(SKGTableWithGraph::GraphType iType);
259 
260     /**
261      * Set tool bar visibility
262      * @param iVisibility the visibility
263      */
264     void setFilterVisibility(bool iVisibility) const;
265 
266     /**
267      * Set the axis color
268      * @param iColor the color
269      */
270     void setAxisColor(const QColor& iColor = Qt::gray);
271 
272     /**
273      * Set the grid color
274      * @param iColor the color
275      */
276     void setGridColor(const QColor& iColor = Qt::lightGray);
277 
278     /**
279      * Set the min color
280      * @param iColor the color
281      */
282     void setMinColor(const QColor& iColor = Qt::red);
283 
284     /**
285      * Set the max color
286      * @param iColor the color
287      */
288     void setMaxColor(const QColor& iColor = Qt::green);
289 
290     /**
291      * Set the pareto color
292      * @param iColor the color
293      */
294     void setParetoColor(const QColor& iColor = Qt::darkRed);
295 
296     /**
297      * Set the average color
298      * @param iColor the color
299      */
300     void setAverageColor(const QColor& iColor = Qt::blue);
301 
302     /**
303      * Set the tendency color
304      * @param iColor the color
305      */
306     void setTendencyColor(const QColor& iColor = Qt::darkYellow);
307 
308     /**
309      * Set the outline color
310      * @param iColor the color
311      */
312     void setOutlineColor(const QColor& iColor = Qt::black);
313 
314     /**
315      * Set the background color
316      * @param iColor the color
317      */
318     void setBackgroundColor(const QColor& iColor = Qt::white);
319 
320     /**
321      * Set the text color
322      * @param iColor the color
323      */
324     void setTextColor(const QColor& iColor = Qt::black);
325 
326     /**
327      * Set antialiasing
328      * @param iAntialiasing enabled or disabled
329      */
330     void setAntialiasing(bool iAntialiasing = true);
331 
332     /**
333      * Redraw the graph after some milliseconds
334      */
335     void redrawGraphDelayed();
336 
337     /**
338      * Switch the limits visibility
339      * @return the new visibility
340      */
341     bool switchLimitsVisibility();
342 
343     /**
344      * Switch the average visibility
345      * @return the new visibility
346      */
347     bool switchAverageVisibility();
348 
349     /**
350      * Switch the linear regression visibility
351      * @return the new visibility
352      */
353     bool switchLinearRegressionVisibility();
354 
355     /**
356      * Switch the pareto curve visibility
357      * @return the new visibility
358      */
359     bool switchParetoVisibility();
360 
361     /**
362      * Switch the legend visibility
363      * @return the new visibility
364      */
365     bool switchLegendVisibility();
366 
367     /**
368      * Switch the origin visibility
369      * @return the new visibility
370      */
371     bool swithOriginVisibility();
372 
373     /**
374      * Switch the decimals visibility
375      * @return the new visibility
376      */
377     bool swithDecimalsVisibility();
378 
379     /**
380      * Reset the colors
381      */
382     void resetColors();
383 
384     /**
385      * Export to a file
386      * @param iFileName the file name
387      * @return an object managing the error
388      *   @see SKGError
389      */
390     SKGError exportInFile(const QString& iFileName);
391 
392 Q_SIGNALS:
393     /**
394      * Emitted when a cell is double clicked
395      * @param row row of the cell
396      * @param column column of the cell
397      */
398     void cellDoubleClicked(int row, int column);
399 
400     /**
401      * Selection changed
402      */
403     void selectionChanged();
404 
405     /**
406      * The object is modified
407      */
408     void modified();
409 
410 private Q_SLOTS:
411     void onExport();
412     void onSelectionChanged();
413     void onSelectionChangedInGraph();
414     void onDoubleClick(int row, int column);
415     void onDoubleClickGraph();
416     void onLinkClicked(const QUrl& url);
417     void onFilterModified();
418     void onDisplayModeChanged();
419     void onChangeColor();
420     void onHorizontalScrollBarChanged(int /*iValue*/);
421     void refresh();
422     void redrawText();
423     void redrawGraph();
424     void showMenu(QPoint iPos);
425 
426 private:
427     Q_DISABLE_COPY(SKGTableWithGraph)
428 
429     double computeStepSize(double iRange, double iTargetSteps);
430     void addArrow(QPointF iPeak, double iSize, double iArrowAngle = 45, double iDegree = 90);
431     void addLegend(QPointF iPosition, double iSize, double iScaleText, double iMaxY);
432     QGraphicsItem* drawPoint(qreal iX, qreal iY, qreal iRadius, int iMode, const QBrush& iBrush);
433     int getAverageColumnIndex() const;
434     int getMinColumnIndex() const;
435 
436     QStringList getSumItems(const QString& iString) const;
437     void addSums(SKGStringListList& ioTable, int& iNblines);
438 
439     Ui::skgtablewithgraph_base ui{};
440     SKGGraphicsScene* m_scene;
441 
442     SKGStringListList m_data;
443     QList<bool> m_sumRows;
444     SKGServices::SKGUnitInfo m_primaryUnit;
445     SKGServices::SKGUnitInfo m_secondaryUnit;
446     DisplayAdditionalFlag m_additionalInformation;
447     int m_nbVirtualColumns;
448     bool m_selectable;
449     bool m_toolBarVisible;
450     bool m_graphTypeVisible;
451     bool m_limitVisible;
452     bool m_averageVisible;
453     bool m_linearRegressionVisible;
454     bool m_paretoVisible;
455     bool m_legendVisible;
456     bool m_graphVisible;
457     bool m_tableVisible;
458     bool m_textVisible;
459     bool m_zeroVisible;
460     bool m_decimalsVisible;
461     bool m_shadow;
462 
463     QMenu* m_mainMenu;
464     QTimer m_timer;
465     QTimer m_timerRedraw;
466     QAction* m_actShowLimits;
467     QAction* m_actShowAverage;
468     QAction* m_actShowLinearRegression;
469     QAction* m_actShowPareto;
470     QAction* m_actShowLegend;
471     QAction* m_actShowZero;
472     QAction* m_actShowDecimal;
473     QAction* m_allPositiveMenu;
474     QWidgetAction* m_displayModeWidget{};
475 
476     int m_indexSum;
477     int m_indexAverage;
478     int m_indexMin;
479     int m_indexLinearRegression;
480     QMap<QString, QColor> m_mapTitleColor;
481     QMap<QTableWidgetItem*, QGraphicsItem*> m_mapItemGraphic{};
482 
483     QColor m_axisColor;
484     QColor m_backgroundColor;
485     QColor m_textColor;
486     QColor m_gridColor;
487     QColor m_minColor;
488     QColor m_maxColor;
489     QColor m_paretoColor;
490     QColor m_averageColor;
491     QColor m_tendencyColor;
492     QColor m_outlineColor;
493     QBrush m_NegativeColor;
494     QBrush m_WhiteColor;
495 
496     SKGComboBox* m_displayMode{};
497 
498     Qt::SortOrder m_sortOrder;
499     int m_sortColumn;
500 };
501 
502 Q_DECLARE_OPERATORS_FOR_FLAGS(SKGTableWithGraph::DisplayAdditionalFlag)
503 
504 #endif  // SKGTABLEWITHGRAPH_H
505