/*========================================================================= Program: Visualization Toolkit Module: vtkAxisActor2D.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkAxisActor2D * @brief Create an axis with tick marks and labels * * vtkAxisActor2D creates an axis with tick marks, labels, and/or a title, * depending on the particular instance variable settings. vtkAxisActor2D is * a 2D actor; that is, it is drawn on the overlay plane and is not * occluded by 3D geometry. To use this class, you typically specify two * points defining the start and end points of the line (x-y definition using * vtkCoordinate class), the number of labels, and the data range * (min,max). You can also control what parts of the axis are visible * including the line, the tick marks, the labels, and the title. You can * also specify the label format (a printf style format). * * This class decides what font size to use and how to locate the labels. It * also decides how to create reasonable tick marks and labels. The number * of labels and the range of values may not match the number specified, but * should be close. * * Labels are drawn on the "right" side of the axis. The "right" side is * the side of the axis on the right as you move from Position to Position2. * The way the labels and title line up with the axis and tick marks depends on * whether the line is considered horizontal or vertical. * * The vtkActor2D instance variables Position and Position2 are instances of * vtkCoordinate. Note that the Position2 is an absolute position in that * class (it was by default relative to Position in vtkActor2D). * * What this means is that you can specify the axis in a variety of coordinate * systems. Also, the axis does not have to be either horizontal or vertical. * The tick marks are created so that they are perpendicular to the axis. * * Set the text property/attributes of the title and the labels through the * vtkTextProperty objects associated to this actor. * * @sa * vtkCubeAxesActor2D can be used to create axes in world coordinate space. * * @sa * vtkActor2D vtkTextMapper vtkPolyDataMapper2D vtkScalarBarActor * vtkCoordinate vtkTextProperty */ #ifndef vtkAxisActor2D_h #define vtkAxisActor2D_h #include "vtkRenderingAnnotationModule.h" // For export macro #include "vtkActor2D.h" class vtkPolyDataMapper2D; class vtkPolyData; class vtkTextMapper; class vtkTextProperty; class VTKRENDERINGANNOTATION_EXPORT vtkAxisActor2D : public vtkActor2D { public: vtkTypeMacro(vtkAxisActor2D,vtkActor2D); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Instantiate object. */ static vtkAxisActor2D *New(); //@{ /** * Specify the position of the first point defining the axis. * Note: backward compatibility only, use vtkActor2D's Position instead. */ virtual vtkCoordinate *GetPoint1Coordinate() { return this->GetPositionCoordinate(); }; virtual void SetPoint1(double x[2]) { this->SetPosition(x); }; virtual void SetPoint1(double x, double y) { this->SetPosition(x,y); }; virtual double *GetPoint1() { return this->GetPosition(); }; //@} //@{ /** * Specify the position of the second point defining the axis. Note that * the order from Point1 to Point2 controls which side the tick marks * are drawn on (ticks are drawn on the right, if visible). * Note: backward compatibility only, use vtkActor2D's Position2 instead. */ virtual vtkCoordinate *GetPoint2Coordinate() { return this->GetPosition2Coordinate(); }; virtual void SetPoint2(double x[2]) { this->SetPosition2(x); }; virtual void SetPoint2(double x, double y) { this->SetPosition2(x,y); }; virtual double *GetPoint2() { return this->GetPosition2(); }; //@} //@{ /** * Specify the (min,max) axis range. This will be used in the generation * of labels, if labels are visible. */ vtkSetVector2Macro(Range,double); vtkGetVectorMacro(Range,double,2); //@} //@{ /** * Specify whether this axis should act like a measuring tape (or ruler) with * specified major tick spacing. If enabled, the distance between major ticks * is controlled by the RulerDistance ivar. */ vtkSetMacro(RulerMode,int); vtkGetMacro(RulerMode,int); vtkBooleanMacro(RulerMode,int); //@} //@{ /** * Specify the RulerDistance which indicates the spacing of the major ticks. * This ivar only has effect when the RulerMode is on. */ vtkSetClampMacro(RulerDistance,double,0,VTK_FLOAT_MAX); vtkGetMacro(RulerDistance,double); //@} enum LabelMax { VTK_MAX_LABELS = 25 }; //@{ /** * Set/Get the number of annotation labels to show. This also controls the * number of major ticks shown. Note that this ivar only holds meaning if * the RulerMode is off. */ vtkSetClampMacro(NumberOfLabels, int, 2, VTK_MAX_LABELS); vtkGetMacro(NumberOfLabels, int); //@} //@{ /** * Set/Get the format with which to print the labels on the scalar * bar. */ vtkSetStringMacro(LabelFormat); vtkGetStringMacro(LabelFormat); //@} //@{ /** * Set/Get the flag that controls whether the labels and ticks are * adjusted for "nice" numerical values to make it easier to read * the labels. The adjustment is based in the Range instance variable. * Call GetAdjustedRange and GetAdjustedNumberOfLabels to get the adjusted * range and number of labels. Note that if RulerMode is on, then the * number of labels is a function of the range and ruler distance. */ vtkSetMacro(AdjustLabels, int); vtkGetMacro(AdjustLabels, int); vtkBooleanMacro(AdjustLabels, int); virtual double *GetAdjustedRange() { this->UpdateAdjustedRange(); return this->AdjustedRange; } virtual void GetAdjustedRange(double &_arg1, double &_arg2) { this->UpdateAdjustedRange(); _arg1 = this->AdjustedRange[0]; _arg2 = this->AdjustedRange[1]; }; virtual void GetAdjustedRange(double _arg[2]) { this->GetAdjustedRange(_arg[0], _arg[1]); } virtual int GetAdjustedNumberOfLabels() { this->UpdateAdjustedRange(); return this->AdjustedNumberOfLabels; } //@} //@{ /** * Set/Get the title of the scalar bar actor, */ vtkSetStringMacro(Title); vtkGetStringMacro(Title); //@} //@{ /** * Set/Get the title text property. */ virtual void SetTitleTextProperty(vtkTextProperty *p); vtkGetObjectMacro(TitleTextProperty,vtkTextProperty); //@} //@{ /** * Set/Get the labels text property. */ virtual void SetLabelTextProperty(vtkTextProperty *p); vtkGetObjectMacro(LabelTextProperty,vtkTextProperty); //@} //@{ /** * Set/Get the length of the tick marks (expressed in pixels or display * coordinates). */ vtkSetClampMacro(TickLength, int, 0, 100); vtkGetMacro(TickLength, int); //@} //@{ /** * Number of minor ticks to be displayed between each tick. Default * is 0. */ vtkSetClampMacro(NumberOfMinorTicks, int, 0, 20); vtkGetMacro(NumberOfMinorTicks, int); //@} //@{ /** * Set/Get the length of the minor tick marks (expressed in pixels or * display coordinates). */ vtkSetClampMacro(MinorTickLength, int, 0, 100); vtkGetMacro(MinorTickLength, int); //@} //@{ /** * Set/Get the offset of the labels (expressed in pixels or display * coordinates). The offset is the distance of labels from tick marks * or other objects. */ vtkSetClampMacro(TickOffset, int, 0, 100); vtkGetMacro(TickOffset, int); //@} //@{ /** * Set/Get visibility of the axis line. */ vtkSetMacro(AxisVisibility, int); vtkGetMacro(AxisVisibility, int); vtkBooleanMacro(AxisVisibility, int); //@} //@{ /** * Set/Get visibility of the axis tick marks. */ vtkSetMacro(TickVisibility, int); vtkGetMacro(TickVisibility, int); vtkBooleanMacro(TickVisibility, int); //@} //@{ /** * Set/Get visibility of the axis labels. */ vtkSetMacro(LabelVisibility, int); vtkGetMacro(LabelVisibility, int); vtkBooleanMacro(LabelVisibility, int); //@} //@{ /** * Set/Get visibility of the axis title. */ vtkSetMacro(TitleVisibility, int); vtkGetMacro(TitleVisibility, int); vtkBooleanMacro(TitleVisibility, int); //@} //@{ /** * Set/Get position of the axis title. 0 is at the start of the * axis whereas 1 is at the end. */ vtkSetMacro(TitlePosition, double); vtkGetMacro(TitlePosition, double); //@} //@{ /** * Set/Get the factor that controls the overall size of the fonts used * to label and title the axes. This ivar used in conjunction with * the LabelFactor can be used to control font sizes. */ vtkSetClampMacro(FontFactor, double, 0.1, 2.0); vtkGetMacro(FontFactor, double); //@} //@{ /** * Set/Get the factor that controls the relative size of the axis labels * to the axis title. */ vtkSetClampMacro(LabelFactor, double, 0.1, 2.0); vtkGetMacro(LabelFactor, double); //@} //@{ /** * Draw the axis. */ int RenderOverlay(vtkViewport* viewport) override; int RenderOpaqueGeometry(vtkViewport* viewport) override; int RenderTranslucentPolygonalGeometry(vtkViewport *) override {return 0;} //@} /** * Does this prop have some translucent polygonal geometry? */ int HasTranslucentPolygonalGeometry() override; /** * Release any graphics resources that are being consumed by this actor. * The parameter window could be used to determine which graphic * resources to release. */ void ReleaseGraphicsResources(vtkWindow *) override; /** * This method computes the range of the axis given an input range. * It also computes the number of tick marks given a suggested number. * (The number of tick marks includes end ticks as well.) * The number of tick marks computed (in conjunction with the output * range) will yield "nice" tick values. For example, if the input range * is (0.25,96.7) and the number of ticks requested is 10, the output range * will be (0,100) with the number of computed ticks to 11 to yield tick * values of (0,10,20,...,100). */ static void ComputeRange(double inRange[2], double outRange[2], int inNumTicks, int &outNumTicks, double &interval); /** * General method to computes font size from a representative size on the * viewport (given by size[2]). The method returns the font size (in points) * and the string height/width (in pixels). It also sets the font size of the * instance of vtkTextMapper provided. The factor is used when you're trying * to create text of different size-factor (it is usually = 1 but you can * adjust the font size by making factor larger or smaller). */ static int SetMultipleFontSize(vtkViewport *viewport, vtkTextMapper **textMappers, int nbOfMappers, int *targetSize, double factor, int *stringSize); //@{ /** * Specify whether to size the fonts relative to the viewport or relative to * length of the axis. By default, fonts are resized relative to the viewport. */ vtkSetMacro(SizeFontRelativeToAxis,int); vtkGetMacro(SizeFontRelativeToAxis,int); vtkBooleanMacro(SizeFontRelativeToAxis,int); //@} /** * Shallow copy of an axis actor. Overloads the virtual vtkProp method. */ void ShallowCopy(vtkProp *prop) override; protected: vtkAxisActor2D(); ~vtkAxisActor2D() override; vtkTextProperty *TitleTextProperty; vtkTextProperty *LabelTextProperty; char *Title; double Range[2]; double TitlePosition; int RulerMode; double RulerDistance; int NumberOfLabels; char *LabelFormat; int AdjustLabels; double FontFactor; double LabelFactor; int TickLength; int MinorTickLength; int TickOffset; int NumberOfMinorTicks; double AdjustedRange[2]; int AdjustedNumberOfLabels; int NumberOfLabelsBuilt; int AxisVisibility; int TickVisibility; int LabelVisibility; int TitleVisibility; int LastPosition[2]; int LastPosition2[2]; int LastSize[2]; int LastMaxLabelSize[2]; int SizeFontRelativeToAxis; virtual void BuildAxis(vtkViewport *viewport); static double ComputeStringOffset(double width, double height, double theta); static void SetOffsetPosition(double xTick[3], double theta, int stringWidth, int stringHeight, int offset, vtkActor2D *actor); virtual void UpdateAdjustedRange(); vtkTextMapper *TitleMapper; vtkActor2D *TitleActor; vtkTextMapper **LabelMappers; vtkActor2D **LabelActors; vtkPolyData *Axis; vtkPolyDataMapper2D *AxisMapper; vtkActor2D *AxisActor; vtkTimeStamp AdjustedRangeBuildTime; vtkTimeStamp BuildTime; private: vtkAxisActor2D(const vtkAxisActor2D&) = delete; void operator=(const vtkAxisActor2D&) = delete; }; #endif