1 /***************************************************************************
2     File                 : Graph.h
3     Project              : QtiPlot
4     --------------------------------------------------------------------
5     Copyright            : (C) 2004-2008 by Ion Vasilief
6     Email (use @ for *)  : ion_vasilief*yahoo.fr
7     Description          : Graph widget
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *  This program is free software; you can redistribute it and/or modify   *
14  *  it under the terms of the GNU General Public License as published by   *
15  *  the Free Software Foundation; either version 2 of the License, or      *
16  *  (at your option) any later version.                                    *
17  *                                                                         *
18  *  This program is distributed in the hope that it will be useful,        *
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
21  *  GNU General Public License for more details.                           *
22  *                                                                         *
23  *   You should have received a copy of the GNU General Public License     *
24  *   along with this program; if not, write to the Free Software           *
25  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
26  *   Boston, MA  02110-1301  USA                                           *
27  *                                                                         *
28  ***************************************************************************/
29 #ifndef GRAPH_H
30 #define GRAPH_H
31 
32 #include <QList>
33 #include <QPointer>
34 #include <QPrinter>
35 #include <QVector>
36 #include <QEvent>
37 #include <QMap>
38 
39 #include <qwt_text.h>
40 #include <qwt_plot.h>
41 #include <qwt_plot_marker.h>
42 #include <qwt_plot_curve.h>
43 
44 #include <AxesDialog.h>
45 #include <PlotToolInterface.h>
46 #include <ScaleDraw.h>
47 #include <FrameWidget.h>
48 #include <float.h>
49 
50 class QwtPlotPanner;
51 class QwtPlotMagnifier;
52 class QwtPlotCurve;
53 class QwtPlotZoomer;
54 class PieCurve;
55 class Table;
56 class ArrowMarker;
57 class ImageWidget;
58 class TitlePicker;
59 class ScalePicker;
60 class CanvasPicker;
61 class ApplicationWindow;
62 class Matrix;
63 class SelectionMoveResizer;
64 class RangeSelectorTool;
65 class ImageProfilesTool;
66 class DataCurve;
67 class PlotCurve;
68 class ErrorBarsCurve;
69 class MultiLayer;
70 class Spectrogram;
71 class FunctionCurve;
72 class VectorCurve;
73 class BoxCurve;
74 class QwtHistogram;
75 class Grid;
76 class TexWidget;
77 class LegendWidget;
78 
79 //! Structure containing curve layout parameters
80 typedef struct{
81   QColor lCol;     //!< line color
82   float lWidth;    //!< line width
83   int lStyle;      //!< line style
84   double filledArea;  //!< flag: toggles area filling under curve; if > 0 it containts the alphaF value of the brush color
85   QColor aCol;     //!< curve area color
86   int aStyle;      //!< area filling style
87   QColor symCol;   //!< symbol outline color
88   QColor fillCol;  //!< symbol fill color
89   float penWidth;  //!< symbol outline width
90   int sSize;       //!< symbol size
91   int sType;       //!< symbol type (shape)
92   int connectType; //!< symbol connection type
93 }  CurveLayout;
94 
95 /**
96  * \brief A 2D-plotting widget.
97  *
98  * Graphs are managed by a MultiLayer, where they are sometimes referred to as "graphs" and sometimes as "layers".
99  * Other parts of the code also call them "plots", regardless of the fact that there's also a class Plot.
100  * Within the user interface, they are quite consistently called "layers".
101  *
102  * Each graph owns a Plot called #d_plot, which handles parts of the curve, axis and marker management (similarly to QwtPlot),
103  * as well as the pickers #d_zoomer (a QwtPlotZoomer), #titlePicker (a TitlePicker), #scalePicker (a ScalePicker) and #cp (a CanvasPicker),
104  * which handle various parts of the user interaction.
105  *
106  * Graph contains support for various curve types (see #CurveType),
107  * some of them relying on Qtiplot-specific QwtPlotCurve subclasses for parts of the functionality.
108  *
109  * %Note that some of Graph's methods are implemented in analysis.cpp.
110  *
111  * \section future Future Plans
112  * Merge with Plot and CanvasPicker.
113  * Think about merging in TitlePicker and ScalePicker.
114  * On the other hand, things like range selection, peak selection or (re)moving data points could be split out into tool classes
115  * like QwtPlotZoomer or SelectionMoveResizer.
116  *
117  * What definitely should be split out are plot types like histograms and pie charts (TODO: which others?).
118  * We need a generic framework for this in any case so that new plot types can be implemented in plugins,
119  * and Graph could do with a little diet. Especially after merging in Plot and CanvasPicker.
120  * [ Framework needs to support plug-ins; assigned to ion ]
121  */
122 
123 class Graph: public QwtPlot
124 {
125 	Q_OBJECT
126 
127 	public:
128 		Graph (int x = 0, int y = 0, int width = 500, int height = 400, QWidget* parent=0, Qt::WFlags f=0);
129 		~Graph();
130 
131 		enum Axis{Left, Right, Bottom, Top};
132 		enum Scale{Linear, Log10, Ln, Log2, Reciprocal, Probability, Logit};
133 		enum Ticks{NoTicks = 0, Out = 1, InOut = 2, In = 3};
134 		enum MarkerType{None = -1, Text = 0, Arrow = 1, Image = 2};
135 		enum CurveType{Line, Scatter, LineSymbols, VerticalBars, Area, Pie, VerticalDropLines,
136 			Spline, HorizontalSteps, Histogram, HorizontalBars, VectXYXY, ErrorBars,
137 			Box, VectXYAM, VerticalSteps, ColorMap, GrayScale, Contour, Function, ImagePlot,
138 			StackBar, StackColumn};
139 		enum LegendDisplayMode{Auto, ColumnName, ColumnComment, TableName, TableLegend, DataSetName};
140 		enum AxisTitlePolicy{Default, ColName, ColComment, NameAndComment};
141 
142 		//! Returns a pointer to the parent MultiLayer object.
143 		MultiLayer *multiLayer() const;
144 
145 		//! Change the active tool, deleting the old one if it exists.
146 		void setActiveTool(PlotToolInterface *tool);
147 		//! Return the active tool, or NULL if none is active.
activeTool()148 		PlotToolInterface* activeTool() const { return d_active_tool; }
149 		//! Returns true if a plot/data tool is enabled.
150 		bool hasActiveTool();
151 
152 		QList <LegendWidget *> textsList();
153 		LegendWidget *activeText();
setActiveText(LegendWidget * l)154 		void setActiveText(LegendWidget *l){d_active_enrichment = (FrameWidget *)l;};
155 		void select(QWidget *l, bool add = false);
156 
activeEnrichment()157 		FrameWidget *activeEnrichment(){return d_active_enrichment;};
enrichmentsList()158 		QList <FrameWidget *> enrichmentsList(){return d_enrichments;};
159 		QList <FrameWidget *> increasingAreaEnrichmentsList();
160 
161 		bool hasSeletedItems();
162 		void deselect();
163 		void deselect(QWidget *);
164 		void selectCanvas();
165 
selectionMoveResizer()166 		QPointer<SelectionMoveResizer> selectionMoveResizer(){return d_markers_selector;};
167 
168 		QwtPlotItem* selectedCurveLabels();
169         //! Used when restoring DataCurve curveID from a project file
170         void restoreCurveLabels(int curveID, const QStringList& lst);
171 
grid()172 		Grid *grid(){return (Grid *)d_grid;};
curvesList()173 		QList<QwtPlotItem *> curvesList(){return d_curves;};
setCurvesList(QList<QwtPlotItem * > lst)174 		void setCurvesList(QList<QwtPlotItem *> lst){d_curves = lst;};
175 
176 		QwtPlotItem* closestCurve(int xpos, int ypos, int &dist, int &point);
177 
178 		void insertMarker(QwtPlotMarker *m);
179 
180 		QList<int> getMajorTicksType();
181 		void setMajorTicksType(int axis, int type);
182 
183 		QList<int> getMinorTicksType();
184 		void setMinorTicksType(int axis, int type);
185 
186 		int minorTickLength() const;
187 		int majorTickLength() const;
188 		void setTickLength (int minLength, int majLength);
189 
190 		int axesLinewidth() const;
191 		void setAxesLinewidth(int width);
192 
193     	void axisLabelFormat(int axis, char &f, int &prec) const;
194 
195 		int axisLabelFormat(int axis);
196 		int axisLabelPrecision(int axis);
197 
198 		QColor frameColor();
199 		const QColor & paletteBackgroundColor() const;
200 
201 		void print(QPainter *, const QRect &rect, const QwtPlotPrintFilter & = QwtPlotPrintFilter());
202 		void updateLayout();
203 		void setCanvasGeometry(const QRect &canvasRect);
204 		//!Convenience function for scripts
setCanvasGeometry(int x,int y,int w,int h)205 		void setCanvasGeometry(int x, int y, int w, int h){setCanvasGeometry(QRect(x, y, w, h));};
206 		void setCanvasSize(const QSize &size);
207 		//!Convenience function for scripts
setCanvasSize(int w,int h)208 		void setCanvasSize(int w, int h){setCanvasSize(QSize(w, h));};
209 
210     	void updateCurveLabels();
211 
212 		TexWidget* addTexFormula(const QString& s, const QPixmap& pix);
213 
214 		FrameWidget* add(FrameWidget* fw, bool copy = true);
215 		void remove(FrameWidget*);
216 
217 		QRect boundingRect();
218 		void raiseEnrichements();
219 		void addLegendItem();
isPrinting()220 		bool isPrinting(){return d_is_printing;};
221 
222 		void enablePanningMagnifier(bool on = true, int mode = 0);
hasPanningMagnifierEnabled()223 		bool hasPanningMagnifierEnabled(){if (d_magnifier && d_panner) return true; return false;};
magnifyTool()224 		QwtPlotMagnifier* magnifyTool(){return d_magnifier;};
225 
226 #ifdef TEX_OUTPUT
227 		static QString escapeTeXSpecialCharacters(const QString &);
228 		static QString texSuperscripts(const QString &);
229 #endif
230 		void changeCurveIndex(int fromIndex, int toIndex);
231 		void enableDouglasPeukerSpeedMode(double tolerance, int maxPoints = 3000);
232 
speedModeMaxPoints()233 		int speedModeMaxPoints(){return d_speed_mode_points;};
getDouglasPeukerTolerance()234 		double getDouglasPeukerTolerance(){return d_Douglas_Peuker_tolerance;};
235 
axisTitlePolicy()236 		AxisTitlePolicy axisTitlePolicy(){return d_axis_title_policy;};
setAxisTitlePolicy(const AxisTitlePolicy & policy)237 		void setAxisTitlePolicy(const AxisTitlePolicy& policy){d_axis_title_policy = policy;};
238 
hasSynchronizedScaleDivisions()239 		bool hasSynchronizedScaleDivisions(){return d_synchronize_scales;};
setSynchronizedScaleDivisions(bool on)240 		void setSynchronizedScaleDivisions(bool on){d_synchronize_scales = on;};
241 
pageGeometry()242 		QRectF pageGeometry(){return d_page_rect;}
setPageGeometry(const QRectF & r)243 		void setPageGeometry(const QRectF& r){d_page_rect = r;}
244 
245 	public slots:
246 		void copy(Graph* g);
247 		void copyCurves(Graph* g);
248 		void copyEnrichments(Graph* g);
249 		void copyScaleWidget(Graph* g, int i);
250 		void copyScaleDraw(Graph* g, int i);
251 
252 		//! \name Pie Curves
253 		//@{
254 		//! Returns true if this Graph is a pie plot, false otherwise.
255 		bool isPiePlot();
256 		//! Used when creating a pie plot.
257 		PieCurve* plotPie(Table* w,const QString& name, int startRow = 0, int endRow = -1);
258 		//! Used when restoring a pie plot from a project file.
259 		PieCurve* plotPie(Table* w, const QString& name, const QPen& pen, int brush, int size,
260 			int firstColor, int startRow = 0, int endRow = -1, bool visible = true,
261 			double d_start_azimuth = 270, double d_view_angle = 90, double d_thickness = 33,
262 			double d_horizontal_offset = 0.0, double d_edge_dist = 25, bool d_counter_clockwise = false,
263 			bool d_auto_labeling = true, bool d_values = false, bool d_percentages = true,
264 			bool d_categories = false, bool d_fixed_labels_pos = true);
265 
266 		void removePie();
267 		QString pieLegendText();
268 		QString savePieCurveLayout();
269 		//@}
270 
271 		bool addCurves(Table* w, const QStringList& names, int style = 0, double lWidth = 1, int sSize = 3, int startRow = 0, int endRow = -1);
272 		DataCurve* insertCurve(Table* w, const QString& name, int style, int startRow = 0, int endRow = -1);
273 		DataCurve* insertCurve(Table* w, int xcol, const QString& name, int style);
274 		DataCurve* insertCurve(Table* w, const QString& xColName, const QString& yColName, int style, int startRow = 0, int endRow = -1);
275 		DataCurve* insertCurve(Table* xt, const QString& xColName, Table* yt, const QString& yColName, int style, int startRow = 0, int endRow = -1);
276 		void insertPlotItem(QwtPlotItem *i, int type);
277 		void insertCurve(QwtPlotItem *c);
278 
279 		//! Shows/Hides a curve defined by its index.
280 		void showCurve(int index, bool visible = true);
281 		int visibleCurves();
282 
283 		void removeCurve(QwtPlotItem *it);
284 		//! Removes a curve defined by its index.
285 		void removeCurve(int index);
286 		/**
287 		 * \brief Removes a curve defined by its title string s.
288 		 */
289 		void removeCurve(const QString& s);
290 		/**
291 		 * \brief Removes all curves defined by the title/plot association string s.
292 		 */
293 		void removeCurves(const QString& s);
294 
295 		void updateCurvesData(Table* w, const QString& yColName);
296 		void reloadCurvesData();
297 
curveCount()298 		int curveCount(){return d_curves.size();};
299 		bool validCurvesDataSize();
300 		double selectedXStartValue();
301 		double selectedXEndValue();
302 
303 		//! Map curve pointer to index.
curveIndex(QwtPlotItem * c)304 		int curveIndex(QwtPlotItem *c){return d_curves.indexOf(c);};
305 		//! map curve title to index
curveIndex(const QString & title)306 		int curveIndex(const QString &title){return plotItemsList().indexOf(title);}
307 		DataCurve* dataCurve(int index);
308 		FunctionCurve* functionCurve(int index);
309 		//! get curve by index
310 		PlotCurve* curve(int index);
311 		//! get curve by name
curve(const QString & title)312 		PlotCurve* curve(const QString &title){return curve(curveIndex(title));};
313 		//! get curve title string by inde (convenience function for scripts)
314 		QString curveTitle(int index);
315 		//! returns the curve range information as a string: "curve_name [start:end]"
316 		QString curveRange(QwtPlotCurve *c);
317 
318 		//! Returns the names of all the curves suitable for data analysis, as a string list. The list excludes error bars and spectrograms.
319 		QStringList analysableCurvesList();
320 		//! Returns the names of all the QwtPlotCurve items on the plot, as a string list
321   		QStringList curveNamesList();
322   	    //! Returns the names of all plot items, including spectrograms, as a string list
323   		QStringList plotItemsList();
324   		 //! get plotted item by index
325   	    QwtPlotItem* plotItem(int index);
326 
327         void updateCurveNames(const QString& oldName, const QString& newName, bool updateTableName = true);
328 
329 		//! \name Customizing plot curves
330 		//@{
331 		void setCurveStyle(int index, int s);
332 		void setCurveFullRange(int curveIndex);
333 		void setCurveLineColor(int curveIndex, int colorIndex);
334 		void setCurveLineColor(int curveIndex, QColor qColor);
335 		void setCurveLineStyle(int curveIndex, Qt::PenStyle style);
336 		void setCurveLineWidth(int curveIndex, double width);
337 		void setGrayScale();
338 		void setIndexedColors();
339 		//@}
340 
341 		//! \name Output: Copy/Export/Print
342 		//@{
343 		void print();
344 		void copyImage();
345 		QPixmap graphPixmap(const QSize& size = QSize(), double scaleFontsFactor = 1.0, bool transparent = false);
346 		//! Provided for convenience in scripts
347 		void exportToFile(const QString& fileName);
348 		void exportSVG(const QString& fname, const QSizeF& customSize = QSizeF(), int unit = FrameWidget::Pixel, double fontsFactor = 1.0);
349 		void exportEMF(const QString& fname, const QSizeF& customSize = QSizeF(), int unit = FrameWidget::Pixel, double fontsFactor = 1.0);
350 		void exportTeX(const QString& fname, bool color = true, bool escapeStrings = true, bool fontSizes = true,
351 						const QSizeF& customSize = QSizeF(), int unit = FrameWidget::Pixel, double fontsFactor = 1.0);
352 #ifdef TEX_OUTPUT
isExportingTeX()353 		bool isExportingTeX(){return d_is_exporting_tex;};
354 		void setTeXExportingMode(bool on = true){d_is_exporting_tex = on;};
escapeTeXStrings()355 		bool escapeTeXStrings(){return d_tex_escape_strings;};
356 		void setEscapeTeXStringsMode(bool on = true){d_tex_escape_strings = on;};
357 #endif
358 		void exportVector(const QString& fileName, int res = 0, bool color = true,
359 						const QSizeF& customSize = QSizeF (), int unit = FrameWidget::Pixel, double fontsFactor = 1.0);
360 		void exportVector(QPrinter *printer, int res = 0, bool color = true,
361 						  const QSizeF& customSize = QSizeF (), int unit = FrameWidget::Pixel, double fontsFactor = 1.0);
362 		void exportImage(const QString& fileName, int quality = 100, bool transparent = false,
363 						 int dpi = 0, const QSizeF& customSize = QSizeF (),
364 						 int unit = FrameWidget::Pixel, double fontsFactor = 1.0, int compression = 0);
365 
366 		void draw(QPaintDevice *, const QSize& size, double fontsFactor = 1.0);
367 		static QSize customPrintSize(const QSizeF& customSize, int unit, int dpi);
368 		//@}
369 
370 		void updatePlot();
371 
372 		//! \name Error Bars
373 		//@{
374 		ErrorBarsCurve* addErrorBars(const QString& xColName, const QString& yColName, Table *errTable,
375 				const QString& errColName, int type = 1, double width = 1, int cap = 8, const QColor& color = QColor(Qt::black),
376 				bool through = true, bool minus = true, bool plus = true);
377 
378 		ErrorBarsCurve* addErrorBars(const QString& yColName, Table *errTable, const QString& errColName,
379 				int type = 1, double width = 1, int cap = 8, const QColor& color = QColor(Qt::black),
380 				bool through = true, bool minus = true, bool plus = true);
381 
382 		ErrorBarsCurve* addErrorBars(DataCurve *c, Table *errTable, const QString& errColName,
383 				int type = 1, double width = 1, int cap = 8, const QColor& color = QColor(Qt::black),
384 				bool through = true, bool minus = true, bool plus = true);
385 
386 		void updateErrorBars(ErrorBarsCurve *er, bool xErr, double width, int cap, const QColor& c, bool plus, bool minus, bool through);
387 		//! Used when restoring project files
388 		void loadErrorBars(QList<ErrorBarsCurve *> errBars, QList<int> mcIndexes);
389 
390 		//! Returns a valid master curve for the error bars curve.
391 		DataCurve* masterCurve(ErrorBarsCurve *er);
392 		//! Returns a valid master curve for a plot association.
393 		DataCurve* masterCurve(const QString& xColName, const QString& yColName);
394 		//@}
395 
396 		//! \name Event Handlers
397 		//@{
398 		bool mousePressed(QEvent *);
399 		void contextMenuEvent(QContextMenuEvent *);
400 		void closeEvent(QCloseEvent *e);
401 		bool focusNextPrevChild ( bool next );
402 		//@}
403 
404 		//! Set axis scale
405 		void invertScale(int axis);
406 		void setScale(int axis, double start, double end, double step = 0.0,
407 				int majorTicks = 5, int minorTicks = 5, int type = 0, bool inverted = false,
408 				double left_break = -DBL_MAX, double right_break = DBL_MAX, int pos = 50,
409 				double stepBeforeBreak = 0.0, double stepAfterBreak = 0.0, int minTicksBeforeBreak = 4,
410 				int minTicksAfterBreak = 4, bool log10AfterBreak = false, int breakWidth = 4, bool breakDecoration = true);
axisStep(int axis)411 		double axisStep(int axis){return d_user_step[axis];};
setAxisStep(int axis,double step)412 		void setAxisStep(int axis, double step){d_user_step[axis] = step;};
413 		void setCanvasCoordinates(const QRectF&);
414 
415 		//! \name Curves Layout
416 		//@{
417 		CurveLayout initCurveLayout(int style, int curves = 0, bool guessLayout = true);
418 		static CurveLayout initCurveLayout();
419 		void updateCurveLayout(PlotCurve* c, const CurveLayout *cL);
420 		//! Tries to guess not already used curve color and symbol style
421 		void guessUniqueCurveLayout(int& colorIndex, int& symbolIndex);
422 		//@}
423 
424 		//! \name Zoom
425 		//@{
426 		void zoomed (const QwtDoubleRect &);
427 		void zoom(bool on);
428 		void zoomOut();
429 		bool zoomOn();
430 		//@}
431 
432 		void setAutoScale();
433 		void updateScale();
434 
435 		//! \name Saving/Restoring to/from file
436 		//@{
437 		QString saveToString(bool saveAsTemplate = false);
438 		QString saveScale();
439 		QString saveScaleTitles();
440 		QString saveFonts();
441 		QString saveMarkers();
442 		QString saveCurveLayout(int index);
443 		QString saveAxesTitleColors();
444 		QString saveAxesColors();
445 		QString saveEnabledAxes();
446 		QString saveCanvas();
447 		QString saveTitle();
448 		QString saveAxesTitleAlignement();
449 		QString saveEnabledTickLabels();
450 		QString saveTicksType();
451 		QString saveCurves();
452 		QString saveLabelsFormat();
453 		QString saveLabelsRotation();
454 		QString saveAxesLabelsType();
455 		QString saveAxesBaseline();
456 		QString saveAxesFormulas();
457 		QString saveAxesBackbones();
458 		QString saveTickLabelsSpace();
459 		QString saveLabelsPrefixAndSuffix();
460 		QString saveBackgroundImage();
461 		void restoreBackgroundImage(const QStringList& lst);
462 		void restoreSymbolImage(int index, const QStringList& lst);
463 		static QString rgbaName(const QColor& color);
464 		//@}
465 
466 		//! \name Texts
467 		//@{
468 		LegendWidget* addText(LegendWidget*);
469 		//! Used when opening a project file
470 		LegendWidget* insertText(const QStringList& list, int fileVersion);
471 
472 		LegendWidget* addTimeStamp();
473 		void removeLegendItem(int index);
474 		void insertLegend(const QStringList& lst, int fileVersion);
475 
476 		LegendWidget* newLegend(const QString& text = QString());
477 		//! Creates a new legend text using the curves titles
478 		QString legendText(bool layerSpec = false, int fromIndex = 0);
479 		//@}
480 
481 		//! \name Obsolete functions provided to keep existing Python scripts working
482 		//@{
483 		LegendWidget* legend();
484 		void setLegend(const QString&);
485 		void removeLegend();
486 		//@}
487 
488 		//! \name Line Markers
489 		//@{
490 		ArrowMarker* addArrow(ArrowMarker* mrk);
491 		void remove(ArrowMarker* arrow);
492 
493 		//! Used when opening a project file
494 		void addArrow(QStringList list, int fileVersion);
arrowsList()495 		QList<ArrowMarker *> arrowsList(){return d_lines;};
numArrows()496 		int numArrows(){return d_lines.count();};
497 
498 		//!Draws a line/arrow depending on the value of "arrow"
499 		void drawLine(bool on, bool arrow = false);
drawArrow()500 		bool drawArrow(){return drawArrowOn;};
drawLineActive()501 		bool drawLineActive(){return drawLineOn;};
502         bool arrowMarkerSelected();
503 		//@}
504 
505 		//! \name Image Markers
506 		//@{
507 		ImageWidget* addImage(ImageWidget* i);
508 		ImageWidget* addImage(const QString& fileName);
509 		ImageWidget* addImage(const QImage& image);
510 
511 		void insertImageMarker(const QStringList& lst, int fileVersion);
512 		bool imageMarkerSelected();
513 		//@}
514 
515 		//! \name Common to all Markers
516 		//@{
517 		void removeMarker();
518 		//! Keep the markers on screen each time the scales are modified by adding/removing curves
519 		void updateMarkersBoundingRect(bool rescaleEvent = true);
520 
521 		/*!\brief Set the selected arrow.
522 		 * \param mrk key of the arrow to be selected.
523 		 * \param add whether the arrow is to be added to an existing selection.
524 		 * If <i>add</i> is false (the default) or there is no existing selection, a new SelectionMoveResizer is
525 		 * created and stored in #d_markers_selector.
526 		 */
527 		void setSelectedArrow(ArrowMarker* mrk, bool add = false);
selectedArrow()528 		ArrowMarker* selectedArrow(){return d_selected_arrow;};
529 		bool markerSelected();
530 		//! Reset any selection states on markers.
531 		void deselectMarker();
532 		//@}
533 
534 		//! \name Axes
535 		//@{
536 		QwtScaleWidget* currentScale();
537 		QwtScaleWidget* selectedScale();
538 		QRect axisTitleRect(const QwtScaleWidget *scale);
539 		bool axisTitleSelected();
540 
541 		ScaleDraw::ScaleType axisType(int axis);
542 
543 		void setXAxisTitle(const QString& text);
544 		void setYAxisTitle(const QString& text);
545 		void setRightAxisTitle(const QString& text);
546 		void setTopAxisTitle(const QString& text);
547 
548 		QString axisTitleString(int axis);
549 		void setAxisTitleString(int axis, const QString& text);
550 		void setAxisTitle(int axis, const QString& text);
551 		void updateAxesTitles();
552 		void updateAxisTitle(int axis);
553 		//! TODO: eliminate this function in version 0.9.1 (used only when restoring project files)
554 		void setScaleTitle(int axis, const QString& text);
555 
556 		QFont axisTitleFont(int axis);
557 		void setAxisTitleFont(int axis,const QFont &fnt);
558 
559 		void setAxisFont(int axis, const QFont &fnt);
560 		void initFonts(const QFont &scaleTitleFnt,const QFont &numbersFnt);
561 
562 		QColor axisTitleColor(int axis);
563 		void setAxisTitleColor(int axis, const QColor& c);
564 
565 		int axisTitleAlignment (int axis);
566 		void setAxisTitleAlignment(int axis, int align);
567 
568 		int axisTitleDistance(int axis);
569 		void setAxisTitleDistance(int axis, int dist);
570 
571         QColor axisColor(int axis);
572 		void setAxisColor(int axis, const QColor& color);
573 
574         QColor axisLabelsColor(int axis);
575 		void setAxisLabelsColor(int axis, const QColor& color);
576 
577 		void showAxis(int axis, int type, const QString& formatInfo, Table *table, bool axisOn,
578 				int majTicksType, int minTicksType, bool labelsOn, const QColor& c, int format,
579 				int prec, int rotation, int baselineDist, const QString& formula, const QColor& labelsColor,
580 				int spacing = 4, bool backbone = true, const ScaleDraw::ShowTicksPolicy& showTicks = ScaleDraw::ShowAll,
581 				const QString& prefix = QString::null, const QString& suffix = QString::null);
582 
583 		void enableAxis(int axis, bool on = true);
584 		void enableAxisLabels(int axis, bool on = true);
585 
586 		int labelsRotation(int axis);
587 		void setAxisLabelRotation(int axis, int rotation);
588 
589 		//! used when opening a project file
590 		void loadAxesLinewidth(int width);
591 
592 		void drawAxesBackbones(bool yes);
axesBackbones()593 		bool axesBackbones(){return drawAxesBackbone;};
594 		//! used when opening a project file
595 		void loadAxesOptions(const QStringList& lst);
596 
597 		void setAxisMargin(int axis, int margin);
598 
599 		void setMajorTicksType(const QList<int>& lst);
600 		void setMajorTicksType(const QStringList& lst);
601 
602 		void setMinorTicksType(const QList<int>& lst);
603 		void setMinorTicksType(const QStringList& lst);
604 
605 		void setAxisTicksLength(int axis, int majTicksType, int minTicksType, int minLength, int majLength);
606 		void setTicksLength(int minLength, int majLength);
607 		void changeTicksLength(int minLength, int majLength);
608         //! Used for restoring project files
609 		void setLabelsNumericFormat(const QStringList& l);
610 		void setLabelsNumericFormat(int axis, int format, int prec = 6, const QString& formula = QString());
611 		void setLabelsDateTimeFormat(int axis, int type, const QString& formatInfo);
612 		void setLabelsDayFormat(int axis, int format);
613 		void setLabelsMonthFormat(int axis, int format);
614 		void recoverObsoleteDateTimeScale(int axis, int type, const QString& origin, const QString& format);
615 
616 		QString axisFormatInfo(int axis);
617 
618 		void setLabelsTextFormat(int axis, int type, const QString& name, const QStringList& lst);
619 		void setLabelsTextFormat(int axis, int type, const QString& labelsColName, Table *table);
620 
621 		QString axisFormula(int axis);
622 		void setAxisFormula(int axis, const QString &);
623 		//@}
624 
625 		//! \name Canvas Frame
626 		//@{
627 		void setCanvasFrame(int width = 1, const QColor& color =  QColor(Qt::black));
628 		QColor canvasFrameColor();
629 		int canvasFrameWidth();
630 		//@}
631 
632 		//! \name Canvas Image Background
633 		//@{
canvasBackgroundFileName()634 		QString canvasBackgroundFileName(){return d_canvas_bkg_path;};
635 		void setCanvasBackgroundImage (const QString & fn = QString(), bool update = true);
backgroundPixmap()636 		QPixmap backgroundPixmap(){return d_canvas_bkg_pix;};
637 		//@}
638 
639 		//! \name Plot Title
640 		//@{
641 		void setTitleFont(const QFont &fnt);
642 		void setTitleColor(const QColor &c);
643 		void setTitleAlignment(int align);
644 
645 		bool titleSelected();
646 		void selectTitle(bool select = true);
647 		//! Sets the title to an "almost empty" string: " ", thus keeping the QwtText object visible
648 		void clearTitle();
649 		//! Sets title to an empty string and hides the text label
650 		void removeTitle();
651 		void initTitle( bool on, const QFont& fnt);
652 		//@}
653 
654 		void disableTools();
655 		void disableImageProfilesTool();
imageProfilesTool()656 		QPointer<ImageProfilesTool> imageProfilesTool(){return d_image_profiles_tool;}
657 
658 		/*! Enables the data range selector tool.
659 		 *
660 		 * This one is a bit special, because other tools can depend upon an existing selection.
661 		 * Therefore, range selection (like zooming) has to be provided in addition to the generic
662 		 * tool interface.
663 		 */
664 		bool enableRangeSelectors(const QObject *status_target=NULL, const char *status_slot="");
665 		bool rangeSelectorsEnabled();
rangeSelectorTool()666 		QPointer<RangeSelectorTool> rangeSelectorTool(){return d_range_selector;};
667 		//! \name Border and background
668 		//@{
669 		void setFrame(int width = 1, const QColor& color = Qt::black);
670 		void setBackgroundColor(const QColor& color);
671 		//@}
672 
673 		void addFitCurve(QwtPlotCurve *c);
674 		void deleteFitCurves();
fitCurvesList()675 		QList<QwtPlotCurve *> fitCurvesList(){return d_fit_curves;};
676 		/*! Set start and end to selected X range of curve "curveTitle" or, if there's no selection, to the curve's total range.
677 		 *
678 		 * \return the number of selected or total points
679 		 */
680 		int range(const QString& curveTitle, double *start, double *end);
681 		/*! Set start and end to selected X range of curve "curve" or, if there's no selection, to the curve's total range.
682 		 *
683 		 * \return the number of selected or total points
684 		 */
685 		int range(QwtPlotCurve *c, double *start, double *end);
686 
687 		//!  Used for VerticalBars, HorizontalBars and Histograms
688 		void setBarsGap(int curve, int gapPercent, int offset);
689 
690 		//! \name User-defined Functions
691 		//@{
692 		void modifyFunctionCurve(int curve, int type, const QStringList &formulas, const QString &var,
693 			double start, double end, int points, const QMap<QString, double>& constants);
694 		FunctionCurve* addFunction(const QStringList &formulas, double start, double end, int points = 100, const QString &var = "x", int type = 0, const QString& title = QString::null);
695 		//! Used when reading from a project file with version < 0.9.5.
696 		FunctionCurve* insertFunctionCurve(const QString& formula, int points, int fileVersion);
697 
698 		//! Returns an unique function name
699         QString generateFunctionName(const QString& name = tr("F"));
700 		//@}
701 
702         //! Provided for convenience in scripts.
703 		void createTable(const QString& curveName);
704         void createTable(const QwtPlotCurve* curve);
705 		void activateGraph();
706 
707 		//! \name Vector Curves
708 		//@{
709 		VectorCurve* plotVectors(Table* w, const QStringList& colList, int style, int startRow = 0, int endRow = -1);
710 		void updateVectorsLayout(int curve, const QColor& color, double width, int arrowLength, int arrowAngle, bool filled, int position,
711 				const QString& xEndColName = QString(), const QString& yEndColName = QString());
712 		//@}
713 
714 		//! \name Box Plots
715 		//@{
716 		BoxCurve* openBoxDiagram(Table *w, const QStringList& l, int fileVersion);
717 		void plotBox(Table *w, const QStringList& names, int startRow = 0, int endRow = -1);
718 		BoxCurve * boxCurve(int index);
719 		//@}
720 
721 		//! \name Resizing
722 		//@{
723 		void resizeEvent(QResizeEvent *e);
724 		void scaleFonts(double factor);
725 		//@}
726 
727 		void notifyChanges();
728 
729 		void updateSecondaryAxis(int axis, bool changeFormat = false);
730 		int oppositeAxis(int axis);
731 		void updateOppositeScaleDiv(int axis);
732 
isAutoscalingEnabled()733 		bool isAutoscalingEnabled(){return d_auto_scale;};
734 		void enableAutoscaling(bool on = true){d_auto_scale = on;};
735 
autoscaleFonts()736 		bool autoscaleFonts(){return autoScaleFonts;};
737 		void setAutoscaleFonts(bool on = true){autoScaleFonts = on;};
738 
739 		static int obsoleteSymbolStyle(int type);
740 		static QString penStyleName(Qt::PenStyle style);
741 		static Qt::PenStyle getPenStyle(const QString& s);
742 		static Qt::PenStyle getPenStyle(int style);
743 		static void showPlotErrorMessage(QWidget *parent, const QStringList& emptyColumns);
744 
745 		void showTitleContextMenu();
746 		void copyTitle();
747 		void cutTitle();
748 
749 		void clearAxisTitle();
750 		void removeAxisTitle();
751 		void cutAxisTitle();
752 		void copyAxisTitle();
753 		void showAxisTitleMenu();
754 		void showAxisContextMenu(int axis);
755 		void hideSelectedAxis();
756 		void showGrids();
757 
758 		//! Convenience function enabling the grid for QwtScaleDraw::Left and Bottom Scales
759 		void showGrid();
760 		//! Convenience function enabling the grid for a user defined axis
761 		void showGrid(int axis);
762 		void setGridOnTop(bool on = true, bool update = true);
hasGridOnTop()763 		bool hasGridOnTop(){return d_grid_on_top;}
764 
765 		void showAxisDialog();
766 		void showScaleDialog();
767 
768 		//! Returns a pointer to the spectrogram which data source is matrix m (the pointer can be NULL)
769 		Spectrogram* spectrogram(Matrix *m);
770 		//! Add a spectrogram to the graph
771   		Spectrogram* plotSpectrogram(Matrix *m, CurveType type);
772 		//! Restores a spectrogram. Used when opening a project file.
773   		void restoreSpectrogram(ApplicationWindow *app, const QStringList& lst);
774         //! Add a matrix histogram  to the graph
775         QwtHistogram* addHistogram(Matrix *m);
776         //! Restores a histogram from a project file.
777         QwtHistogram* restoreHistogram(Matrix *m, const QStringList& l);
778 
antialiasing()779 		bool antialiasing(){return d_antialiasing;};
780 		//! Enables/Disables antialiasing of plot items.
781 		void setAntialiasing(bool on = true, bool update = true);
782 
783 		void disableCurveAntialiasing(bool disable, int maxPoints);
784 		bool isCurveAntialiasingEnabled(QwtPlotItem *it);
isCurveAntialiasingDisabled()785 		bool isCurveAntialiasingDisabled(){return d_disable_curve_antialiasing;};
maxAntialisingSize()786 		int maxAntialisingSize(){return d_max_antialising_size;};
787 
788 		void setCurrentColor(const QColor& c);
notifyColorChange(const QColor & c)789 		void notifyColorChange(const QColor& c){emit currentColorChanged(c);};
790 		void setCurrentFont(const QFont& f);
notifyFontChange(const QFont & f)791 		void notifyFontChange(const QFont& f){emit currentFontChanged(f);};
792         void enableTextEditor();
793 
794 		void showMissingDataGap(bool on = true, bool update = true);
isMissingDataGapEnabled()795 		bool isMissingDataGapEnabled(){return d_missing_data_gap;}
796 
797 		//! \name Waterfall
798 		//@{
isWaterfallPlot()799 		bool isWaterfallPlot(){return d_waterfall_offset_x != 0 || d_waterfall_offset_y != 0;};
waterfallXOffset()800 		int waterfallXOffset(){return d_waterfall_offset_x;};
waterfallYOffset()801 		int waterfallYOffset(){return d_waterfall_offset_y;};
802 		void setWaterfallOffset(int x, int y, bool update = false);
803 		void setWaterfallXOffset(int);
804 		void setWaterfallYOffset(int);
805 		void setWaterfallSideLines(bool on = true);
806 		void setWaterfallFillColor(const QColor&);
807 		void updateWaterfallFill(bool on);
808 		//@}
809 		void updateDataCurves();
810 		void reverseCurveOrder();
811 
812 signals:
813 		void selectedGraph(Graph*);
814 		void selectedCanvas(Graph*);
815 		void closedGraph();
816 		void drawLineEnded(bool);
817 		void cursorInfo(const QString&);
818 		void showPlotDialog(int);
819 
820 		void viewLineDialog();
821 		void viewTitleDialog();
822 		void modifiedGraph();
823 		void hiddenPlot(QWidget*);
824 
825 		void showContextMenu();
826 		void showCurveContextMenu(QwtPlotItem *);
827 		void showMarkerPopupMenu();
828 
829 		void showAxisDialog(int);
830 		void axisDblClicked(int);
831 
832 		void showAxisTitleDialog();
833 
834 		void dataRangeChanged();
835 		void showFitResults(const QString&);
836 		void currentFontChanged(const QFont&);
837 		void currentColorChanged(const QColor&);
838         void enableTextEditor(Graph *);
839         void axisDivChanged(Graph *, int);
840 		void updatedLayout(Graph *);
841 		void selectionChanged(SelectionMoveResizer *);
842 
843 	private slots:
844 		void selectorDeleted();
845 
846 	private:
847 		QString parseAxisTitle(int axis);
848 		QList<FrameWidget*> stackingOrderEnrichmentsList() const;
849 		//! Finds bounding interval of the plot data.
850 		QwtDoubleInterval axisBoundingInterval(int axis);
851 		void deselectCurves();
852 
853 		void dropEvent(QDropEvent*);
854 		void dragEnterEvent(QDragEnterEvent*);
855 		void showEvent (QShowEvent * event);
856     	void printFrame(QPainter *painter, const QRect &rect) const;
857 		void printCanvas(QPainter *painter, const QRect &canvasRect,
858    			 const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const;
859 		virtual void printScale (QPainter *, int axisId, int startDist, int endDist,
860 			int baseDist, const QRect &) const;
861 		virtual void drawItems (QPainter *painter, const QRect &rect,
862 			const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const;
863 
864 		void drawInwardTicks(QPainter *painter, const QRect &rect,
865 							const QwtScaleMap&map, int axis, bool min, bool maj) const;
866    	 	void drawBreak(QPainter *painter, const QRect &rect, const QwtScaleMap &map, int axis) const;
867 
868 		QwtPlotZoomer *d_zoomer[2];
869 		TitlePicker *titlePicker;
870 		ScalePicker *scalePicker;
871 		CanvasPicker* cp;
872 		//! Pointer to the grid
873 		Grid *d_grid;
874 		//! List storing pointers to the curves on the plot.
875 		QList<QwtPlotItem*> d_curves;
876 		//! List storing pointers to the curves resulting after a fit session, in case the user wants to delete them later on.
877 		QList<QwtPlotCurve *>d_fit_curves;
878 		//! Render hint for plot items.
879 		bool d_antialiasing;
880 		bool d_disable_curve_antialiasing;
881 		int d_max_antialising_size;
882 		bool autoScaleFonts;
883 		bool drawLineOn, drawArrowOn, drawAxesBackbone;
884 		//! Flag telling if we are performing a print operation
885 		bool d_is_printing;
886 		//! Flag telling if the grid should be drawn on top of data
887 		bool d_grid_on_top;
888 		//! Flag telling if the curves line should be connected across missing data
889 		bool d_missing_data_gap;
890 		//! Stores the step the user specified for the four scale. If step = 0.0, the step will be calculated automatically by the Qwt scale engine.
891 		QVector<double> d_user_step;
892 		//! Arrows/lines on plot
893 		QList<ArrowMarker*> d_lines;
894 		//! Pointer to the currently selected line/image
895 		ArrowMarker* d_selected_arrow;
896 		//! The markers selected for move/resize operations or NULL if none are selected.
897 		QPointer<SelectionMoveResizer> d_markers_selector;
898 		//! The current curve selection, or NULL if none is active.
899 		QPointer<RangeSelectorTool> d_range_selector;
900 		QPointer<ImageProfilesTool> d_image_profiles_tool;
901 		//! The currently active tool, or NULL for default (pointer).
902 		PlotToolInterface *d_active_tool, *d_peak_fit_tool;
903 		//! Pointer to the currently selected text/legend
904 		FrameWidget *d_active_enrichment;
905         //! Flag indicating if the axes limits should be changed in order to show all data each time a curva data change occurs
906 		bool d_auto_scale;
907 		//! Axes tick lengths
908 		int d_min_tick_length, d_maj_tick_length;
909 #ifdef TEX_OUTPUT
910 		bool d_is_exporting_tex;
911 		bool d_tex_escape_strings;
912 #endif
913 		QList<FrameWidget*> d_enrichments;
914 		QwtPlotMagnifier *d_magnifier;
915 		QwtPlotPanner *d_panner;
916 
917 		double d_Douglas_Peuker_tolerance;
918 		int d_speed_mode_points;
919 		AxisTitlePolicy d_axis_title_policy;
920 		bool d_synchronize_scales;
921 		QStringList d_axis_titles;
922 
923 		QString d_canvas_bkg_path;
924 		QPixmap d_canvas_bkg_pix;
925 
926 		int d_waterfall_offset_x, d_waterfall_offset_y;
927 		QRectF d_page_rect;
928 };
929 
930 class ScaledFontsPrintFilter: public QwtPlotPrintFilter
931 {
932 
933 public:
ScaledFontsPrintFilter(double factor)934 	ScaledFontsPrintFilter(double factor){d_factor = factor;};
font(const QFont & f,Item item)935 	virtual QFont font(const QFont &f, Item item) const
936 	{
937 		if (d_factor == 1.0 || d_factor <= 0.0)
938 			return f;
939 
940 		if (item == Title || item == AxisScale || item == AxisTitle || item == Marker){
941 			QFont fnt(f);
942 			fnt.setPointSizeF(d_factor*f.pointSizeF());
943 			return fnt;
944 		}
945 		return f;
946 	}
947 
scaleFontsFactor()948 	double scaleFontsFactor(){return d_factor;}
949 
950 private:
951 	double d_factor;
952 };
953 #endif // GRAPH_H
954