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