/*========================================================================= Program: Visualization Toolkit Module: vtkScalarBarActor.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 vtkScalarBarActor * @brief Create a scalar bar with labels * * vtkScalarBarActor creates a scalar bar with tick marks. A scalar * bar is a legend that indicates to the viewer the correspondence between * color value and data value. The legend consists of a rectangular bar * made of rectangular pieces each colored a constant value. Since * vtkScalarBarActor is a subclass of vtkActor2D, it is drawn in the image * plane (i.e., in the renderer's viewport) on top of the 3D graphics window. * * To use vtkScalarBarActor you must associate a vtkScalarsToColors (or * subclass) with it. The lookup table defines the colors and the * range of scalar values used to map scalar data. Typically, the * number of colors shown in the scalar bar is not equal to the number * of colors in the lookup table, in which case sampling of * the lookup table is performed. * * Other optional capabilities include specifying the fraction of the * viewport size (both x and y directions) which will control the size * of the scalar bar and the number of tick labels. The actual position * of the scalar bar on the screen is controlled by using the * vtkActor2D::SetPosition() method (by default the scalar bar is * centered in the viewport). Other features include the ability to * orient the scalar bar horizontally of vertically and controlling * the format (printf style) with which to print the labels on the * scalar bar. Also, the vtkScalarBarActor's property is applied to * the scalar bar and annotations (including layer, and * compositing operator). * * Set the text property/attributes of the title and the labels through the * vtkTextProperty objects associated to this actor. * * @warning * If a vtkLogLookupTable is specified as the lookup table to use, then the * labels are created using a logarithmic scale. * * @sa * vtkActor2D vtkTextProperty vtkTextMapper vtkPolyDataMapper2D */ #ifndef vtkScalarBarActor_h #define vtkScalarBarActor_h #include "vtkActor2D.h" #include "vtkDoubleArray.h" // for ivars #include "vtkRenderingAnnotationModule.h" // For export macro class vtkColor3ub; class vtkPolyData; class vtkPolyDataMapper2D; class vtkProperty2D; class vtkScalarsToColors; class vtkScalarBarActorInternal; class vtkTextActor; class vtkTextMapper; class vtkTextProperty; class vtkTexture; class vtkTexturedActor2D; #define VTK_ORIENT_HORIZONTAL 0 #define VTK_ORIENT_VERTICAL 1 class VTKRENDERINGANNOTATION_EXPORT vtkScalarBarActor : public vtkActor2D { public: vtkTypeMacro(vtkScalarBarActor, vtkActor2D); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label * format, no title, and vertical orientation. The initial scalar bar * size is (0.05 x 0.8) of the viewport size. */ static vtkScalarBarActor* New(); ///@{ /** * Draw the scalar bar and annotation text to the screen. */ int RenderOpaqueGeometry(vtkViewport* viewport) override; int RenderTranslucentPolygonalGeometry(vtkViewport*) override { return 0; } int RenderOverlay(vtkViewport* viewport) override; ///@} /** * Does this prop have some translucent polygonal geometry? */ vtkTypeBool 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; /** * Fills rect with the dimensions of the scalar bar in viewport coordinates. * Only the color bar is considered -- text labels are not considered. * rect is {xmin, xmax, width, height} */ virtual void GetScalarBarRect(int rect[4], vtkViewport* viewport); ///@{ /** * Set/Get the lookup table to use. The lookup table specifies the number * of colors to use in the table (if not overridden), the scalar range, * and any annotated values. * Annotated values are rendered using vtkTextActor. */ virtual void SetLookupTable(vtkScalarsToColors*); vtkGetObjectMacro(LookupTable, vtkScalarsToColors); ///@} ///@{ /** * Should be display the opacity as well. This is displayed by changing * the opacity of the scalar bar in accordance with the opacity of the * given color. For clarity, a texture grid is placed in the background * if Opacity is ON. You might also want to play with SetTextureGridWith * in that case. [Default: off] */ vtkSetMacro(UseOpacity, vtkTypeBool); vtkGetMacro(UseOpacity, vtkTypeBool); vtkBooleanMacro(UseOpacity, vtkTypeBool); ///@} ///@{ /** * Set/Get the maximum number of scalar bar segments to show. This may * differ from the number of colors in the lookup table, in which case * the colors are samples from the lookup table. */ vtkSetClampMacro(MaximumNumberOfColors, int, 2, VTK_INT_MAX); vtkGetMacro(MaximumNumberOfColors, int); ///@} ///@{ /** * Set/Get the number of automatic tick labels to show. */ vtkSetClampMacro(NumberOfLabels, int, 0, 64); vtkGetMacro(NumberOfLabels, int); ///@} ///@{ /** * Set/Get the fixed locations to use. */ virtual void SetCustomLabels(vtkDoubleArray* labels); vtkGetObjectMacro(CustomLabels, vtkDoubleArray); ///@} ///@{ /** * Get/Set whether custom labels will be used. * bonds. Default: Off. */ vtkGetMacro(UseCustomLabels, bool); vtkSetMacro(UseCustomLabels, bool); vtkBooleanMacro(UseCustomLabels, bool); ///@} ///@{ /** * Control the orientation of the scalar bar. */ vtkSetClampMacro(Orientation, int, VTK_ORIENT_HORIZONTAL, VTK_ORIENT_VERTICAL); vtkGetMacro(Orientation, int); void SetOrientationToHorizontal() { this->SetOrientation(VTK_ORIENT_HORIZONTAL); } void SetOrientationToVertical() { this->SetOrientation(VTK_ORIENT_VERTICAL); } ///@} ///@{ /** * 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 annotation text property. */ virtual void SetAnnotationTextProperty(vtkTextProperty* p); vtkGetObjectMacro(AnnotationTextProperty, vtkTextProperty); ///@} ///@{ /** * Set/Get the format with which to print the labels on the scalar * bar. */ vtkSetStringMacro(LabelFormat); vtkGetStringMacro(LabelFormat); ///@} ///@{ /** * Set/Get the title of the scalar bar actor, */ vtkSetStringMacro(Title); vtkGetStringMacro(Title); ///@} ///@{ /** * Set/Get the title for the component that is selected, */ vtkSetStringMacro(ComponentTitle); vtkGetStringMacro(ComponentTitle); ///@} /** * Shallow copy of a scalar bar actor. Overloads the virtual vtkProp method. */ void ShallowCopy(vtkProp* prop) override; ///@{ /** * Set the width of the texture grid. Used only if UseOpacity is ON. */ vtkSetMacro(TextureGridWidth, double); vtkGetMacro(TextureGridWidth, double); ///@} ///@{ /** * Get the texture actor.. you may want to change some properties on it */ vtkGetObjectMacro(TextureActor, vtkTexturedActor2D); ///@} enum { PrecedeScalarBar = 0, SucceedScalarBar }; ///@{ /** * Should the title and tick marks precede the scalar bar or succeed it? * This is measured along the viewport coordinate direction perpendicular * to the long axis of the scalar bar, not the reading direction. * Thus, succeed implies the that the text is above scalar bar if * the orientation is horizontal or right of scalar bar if the orientation * is vertical. Precede is the opposite. */ vtkSetClampMacro(TextPosition, int, PrecedeScalarBar, SucceedScalarBar); vtkGetMacro(TextPosition, int); virtual void SetTextPositionToPrecedeScalarBar() { this->SetTextPosition(vtkScalarBarActor::PrecedeScalarBar); } virtual void SetTextPositionToSucceedScalarBar() { this->SetTextPosition(vtkScalarBarActor::SucceedScalarBar); } ///@} ///@{ /** * Set/Get the maximum width and height in pixels. Specifying the size as * a relative fraction of the viewport can sometimes undesirably stretch * the size of the actor too much. These methods allow the user to set * bounds on the maximum size of the scalar bar in pixels along any * direction. Defaults to unbounded. */ vtkSetMacro(MaximumWidthInPixels, int); vtkGetMacro(MaximumWidthInPixels, int); vtkSetMacro(MaximumHeightInPixels, int); vtkGetMacro(MaximumHeightInPixels, int); ///@} ///@{ /** * Set/get the padding between the scalar bar and the text annotations. * This space is used to draw leader lines. * The default is 8 pixels. */ vtkSetMacro(AnnotationLeaderPadding, double); vtkGetMacro(AnnotationLeaderPadding, double); ///@} ///@{ /** * Set/get whether text annotations should be rendered or not. * Currently, this only affects rendering when \a IndexedLookup is true. * The default is true. */ vtkSetMacro(DrawAnnotations, vtkTypeBool); vtkGetMacro(DrawAnnotations, vtkTypeBool); vtkBooleanMacro(DrawAnnotations, vtkTypeBool); ///@} ///@{ /** * Set/get whether the NaN annotation should be rendered or not. * This only affects rendering when \a DrawAnnotations is true. * The default is false. */ vtkSetMacro(DrawNanAnnotation, vtkTypeBool); vtkGetMacro(DrawNanAnnotation, vtkTypeBool); vtkBooleanMacro(DrawNanAnnotation, vtkTypeBool); ///@} ///@{ /** * Set/get whether the Below range swatch should be rendered or not. * This only affects rendering when \a DrawAnnotations is true. * The default is false. */ vtkSetMacro(DrawBelowRangeSwatch, bool); vtkGetMacro(DrawBelowRangeSwatch, bool); vtkBooleanMacro(DrawBelowRangeSwatch, bool); ///@} ///@{ /** * Set/get the annotation text for "Below Range" values. */ vtkSetStringMacro(BelowRangeAnnotation); vtkGetStringMacro(BelowRangeAnnotation); ///@} ///@{ /** * Set/get whether the Above range swatch should be rendered or not. * This only affects rendering when \a DrawAnnotations is true. * The default is false. */ vtkSetMacro(DrawAboveRangeSwatch, bool); vtkGetMacro(DrawAboveRangeSwatch, bool); vtkBooleanMacro(DrawAboveRangeSwatch, bool); ///@} ///@{ /** * Set/get the annotation text for "Above Range Swatch" values. */ vtkSetStringMacro(AboveRangeAnnotation); vtkGetStringMacro(AboveRangeAnnotation); ///@} ///@{ /** * Set/get how leader lines connecting annotations to values should be colored. * When true, leader lines are all the same color (and match the LabelTextProperty color). * When false, leader lines take on the color of the value they correspond to. * This only affects rendering when \a DrawAnnotations is true. * The default is false. */ vtkSetMacro(FixedAnnotationLeaderLineColor, vtkTypeBool); vtkGetMacro(FixedAnnotationLeaderLineColor, vtkTypeBool); vtkBooleanMacro(FixedAnnotationLeaderLineColor, vtkTypeBool); ///@} ///@{ /** * Set/get the annotation text for "NaN" values. */ vtkSetStringMacro(NanAnnotation); vtkGetStringMacro(NanAnnotation); ///@} ///@{ /** * Set/get whether annotation labels should be scaled with the viewport. * The default value is 0 (no scaling). * If non-zero, the vtkTextActor instances used to render annotation * labels will have their TextScaleMode set to viewport-based scaling, * which nonlinearly scales font size with the viewport size. */ vtkSetMacro(AnnotationTextScaling, vtkTypeBool); vtkGetMacro(AnnotationTextScaling, vtkTypeBool); vtkBooleanMacro(AnnotationTextScaling, vtkTypeBool); ///@} ///@{ /** * Set/Get whether a background should be drawn around the scalar bar. * Default is off. */ vtkSetMacro(DrawBackground, vtkTypeBool); vtkGetMacro(DrawBackground, vtkTypeBool); vtkBooleanMacro(DrawBackground, vtkTypeBool); ///@} ///@{ /** * Set/Get whether a frame should be drawn around the scalar bar. * Default is off. */ vtkSetMacro(DrawFrame, vtkTypeBool); vtkGetMacro(DrawFrame, vtkTypeBool); vtkBooleanMacro(DrawFrame, vtkTypeBool); ///@} ///@{ /** * Set/Get whether the color bar should be drawn. If off, only the tickmarks * and text will be drawn. Default is on. */ vtkSetMacro(DrawColorBar, vtkTypeBool); vtkGetMacro(DrawColorBar, vtkTypeBool); vtkBooleanMacro(DrawColorBar, vtkTypeBool); ///@} ///@{ /** * Set/Get whether the tick labels should be drawn. Default is on. */ vtkSetMacro(DrawTickLabels, vtkTypeBool); vtkGetMacro(DrawTickLabels, vtkTypeBool); vtkBooleanMacro(DrawTickLabels, vtkTypeBool); ///@} ///@{ /** * Set/Get the background property. */ virtual void SetBackgroundProperty(vtkProperty2D* p); vtkGetObjectMacro(BackgroundProperty, vtkProperty2D); ///@} ///@{ /** * Set/Get the frame property. */ virtual void SetFrameProperty(vtkProperty2D* p); vtkGetObjectMacro(FrameProperty, vtkProperty2D); ///@} ///@{ /** * Set/get the amount of padding around text boxes. * The default is 1 pixel. */ vtkGetMacro(TextPad, int); vtkSetMacro(TextPad, int); ///@} ///@{ /** * Set/get the margin in pixels, between the title and the bar, * when the \a Orientation is vertical. * The default is 0 pixels. */ vtkGetMacro(VerticalTitleSeparation, int); vtkSetMacro(VerticalTitleSeparation, int); ///@} ///@{ /** * Set/get the thickness of the color bar relative to the widget frame. * The default is 0.375 and must always be in the range ]0, 1[. */ vtkGetMacro(BarRatio, double); vtkSetClampMacro(BarRatio, double, 0., 1.); ///@} ///@{ /** * Set/get the ratio of the title height to the tick label height * (used only when the \a Orientation is horizontal). * The default is 0.5, which attempts to make the labels and title * the same size. This must be a number in the range ]0, 1[. */ vtkGetMacro(TitleRatio, double); vtkSetClampMacro(TitleRatio, double, 0., 1.); ///@} ///@{ /** * Set/Get whether the font size of title and labels is unconstrained. Default is off. * When it is constrained, the size of the scalar bar will constrain the font size. * When it is not, the size of the font will always be respected. * Using custom labels will force this mode to be on. */ vtkSetMacro(UnconstrainedFontSize, bool); vtkGetMacro(UnconstrainedFontSize, bool); vtkBooleanMacro(UnconstrainedFontSize, bool); ///@} protected: vtkScalarBarActor(); ~vtkScalarBarActor() override; /** * Called from within \a RenderOpaqueGeometry when the internal state * members need to be updated before rendering. * This method invokes many virtual methods that first lay out the * scalar bar and then use the layout to position actors and create * datasets used to represent the scalar bar. * Specifically, it invokes: FreeLayoutStorage, ComputeFrame, * ComputeScalarBarThickness, LayoutNanSwatch, PrepareTitleText, * LayoutTitle, ComputeScalarBarLength, LayoutTicks, and LayoutAnnotations * to perform the layout step. * Then, it invokes ConfigureAnnotations, ConfigureFrame, * ConfigureScalarBar, ConfigureTitle, ConfigureTicks, and * ConfigureNanSwatch to create and position actors used to render * portions of the scalar bar. * By overriding one or more of these virtual methods, subclasses * may change the appearance of the scalar bar. * In the layout phase, text actors must have their text properties * and input strings updated, but the position of the actors should * not be set or relied upon as subsequent layout steps may alter * their placement. */ virtual void RebuildLayout(vtkViewport* viewport); /** * Calls RebuildLayout if it is needed such as when * positions etc have changed. Return 1 on success * zero on error */ virtual int RebuildLayoutIfNeeded(vtkViewport* viewport); /** * Free internal storage used by the previous layout. */ virtual void FreeLayoutStorage(); /** * If the scalar bar should be inset into a frame or rendered with a * solid background, this method will inset the outermost scalar bar * rectangle by a small amount to avoid having the scalar bar * illustration overlap any edges. * This method must set the frame coordinates (this->P->Frame). */ virtual void ComputeFrame(); /** * Determine how thick the scalar bar should be (on an axis perpendicular * to the direction in which scalar values vary). * This method must set the scalar bar thickness * (this->P->ScalarBarBox.Size[0]). * It may depend on layout performed by ComputeFrame * (i.e., the frame coordinates in this->P->Frame). */ virtual void ComputeScalarBarThickness(); /** * Compute a correct SwatchPad */ virtual void ComputeSwatchPad(); // This method must set this->P->NanSwatchSize and this->P->NanBox. // It may depend on layout performed by ComputeScalarBarThickness. virtual void LayoutNanSwatch(); /** * Determine the size of the Below Range if it is to be rendered. * This method must set this->P->BelowSwatchSize and this->P->BelowBox. * It may depend on layout performed by ComputeScalarBarThickness. */ virtual void LayoutBelowRangeSwatch(); /** * Determine the size of the Above Range if it is to be rendered. * This method must set this->P->AboveBox. * It may depend on layout performed by ComputeScalarBarThickness. */ virtual void LayoutAboveRangeSwatch(); /** * Determine the position of the Above Range if it is to be rendered. * This method must set this->P->AboveRangeSize. * It may depend on layout performed by ComputeScalarBarLength. */ virtual void LayoutAboveRangeSwatchPosn(); /** * Set the title actor's input to the latest title (and subtitle) text. */ virtual void PrepareTitleText(); /** * Determine the position and size of the scalar bar title box. * This method must set this->P->TitleBox * It may depend on layout performed by LayoutNanSwatch. * If useTickBox is true, it should increase the target area * for the label to touch the tick box. It is called in this * way when the tick labels are small due to constraints other * than the title box. */ virtual void LayoutTitle(); /** * This method sets the title and tick-box size and position * for the UnconstrainedFontSize mode. */ virtual void LayoutForUnconstrainedFont(); /** * Determine how long the scalar bar should be (on an axis parallel * to the direction in which scalar values vary). * This method must set this->P->ScalarBarBox.Size[1] and should * estimate this->P->ScalarBarBox.Posn. * It may depend on layout performed by LayoutTitle. */ virtual void ComputeScalarBarLength(); /** * Determine the size and placement of any tick marks to be rendered. * This method must set this->P->TickBox. * It may depend on layout performed by ComputeScalarBarLength. * The default implementation creates exactly this->NumberOfLabels * tick marks, uniformly spaced on a linear or logarithmic scale, * or creates them based on the numbers and values this->CustomLabels * when this->UseCustomLabels is true. */ virtual void LayoutTicks(); /** * This method must lay out annotation text and leader lines so * they do not overlap. * This method must set this->P->AnnotationAnchors. * It may depend on layout performed by LayoutTicks. */ virtual void LayoutAnnotations(); /** * Generate/configure the annotation labels using the laid-out geometry. */ virtual void ConfigureAnnotations(); /** * Generate/configure the representation of the frame from laid-out geometry. */ virtual void ConfigureFrame(); /** * For debugging, add placement boxes to the frame polydata. */ virtual void DrawBoxes(); /** * Generate/configure the scalar bar representation from laid-out geometry. */ virtual void ConfigureScalarBar(); /** * Generate/configure the title actor using the laid-out geometry. */ virtual void ConfigureTitle(); /** * Generate/configure the tick-mark actors using the laid-out geometry. */ virtual void ConfigureTicks(); /** * Generate/configure the NaN swatch using the laid-out geometry. * Currently the NaN swatch is rendered by the same actor as the scalar bar. * This may change in the future. */ virtual void ConfigureNanSwatch(); /** * Generate/configure the above/below range swatch using the laid-out * geometry. */ virtual void ConfigureAboveBelowRangeSwatch(bool above); /** * Subclasses may override this method to alter this->P->Labels, allowing * the addition and removal of annotations. The member maps viewport coordinates * along the long axis of the scalar bar to text (which may include MathText; * see vtkTextActor). It is a single-valued map, so you must perturb * the coordinate if you wish multiple labels to annotate the same position. * Each entry in this->P->Labels must have a matching entry in this->P->LabelColors. */ virtual void EditAnnotations() {} /** * Compute the best size for the legend title. * This guarantees that the title will fit within the frame defined by Position and Position2. */ virtual void SizeTitle(double* titleSize, int* size, vtkViewport* viewport); /** * Allocate actors for lookup table annotations and position them properly. */ int MapAnnotationLabels( vtkScalarsToColors* lkup, double start, double delta, const double* range); /** * This method is called by \a ConfigureAnnotationLabels when Orientation is VTK_ORIENT_VERTICAL. */ int PlaceAnnotationsVertically( double barX, double barY, double barWidth, double barHeight, double delta, double pad); /** * This method is called by \a ConfigureAnnotationLabels when Orientation is * VTK_ORIENT_HORIZONTAL. */ int PlaceAnnotationsHorizontally( double barX, double barY, double barWidth, double barHeight, double delta, double pad); /// User-changeable settings ///@{ int MaximumNumberOfColors; int NumberOfLabels; int NumberOfLabelsBuilt; int Orientation; vtkDoubleArray* CustomLabels = nullptr; bool UseCustomLabels = false; vtkTypeBool DrawBackground; // off by default vtkTypeBool DrawFrame; // off by default vtkTypeBool DrawColorBar; // on by default vtkTypeBool DrawTickLabels; // on by default vtkTypeBool DrawAnnotations; vtkTypeBool DrawNanAnnotation; vtkTypeBool AnnotationTextScaling; // off by default vtkTypeBool FixedAnnotationLeaderLineColor; vtkProperty2D* BackgroundProperty; vtkProperty2D* FrameProperty; char* Title; char* ComponentTitle; char* LabelFormat; vtkTypeBool UseOpacity; // off by default double TextureGridWidth; int TextPosition; char* NanAnnotation; char* BelowRangeAnnotation; char* AboveRangeAnnotation; double AnnotationLeaderPadding; int MaximumWidthInPixels; int MaximumHeightInPixels; int TextPad; int VerticalTitleSeparation; double BarRatio; double TitleRatio; bool UnconstrainedFontSize; // off by default bool DrawBelowRangeSwatch; bool DrawAboveRangeSwatch; ///@} /// Internal state used for rendering ///@{ vtkTimeStamp BuildTime; //!< Last time internal state changed. int LastSize[2]; //!< Projected size in viewport coordinates of last build. int LastOrigin[2]; //!< Projected origin (viewport coordinates) of last build. vtkScalarBarActorInternal* P; //!< Containers shared with subclasses vtkScalarsToColors* LookupTable; //!< The object this actor illustrates vtkTextProperty* TitleTextProperty; //!< Font for the legend title. vtkTextProperty* LabelTextProperty; //!< Font for tick labels. vtkTextProperty* AnnotationTextProperty; //!< Font for annotation labels. vtkTextActor* TitleActor; //!< The legend title text renderer. vtkPolyData* ScalarBar; //!< Polygon(s) colored by \a LookupTable. vtkPolyDataMapper2D* ScalarBarMapper; //!< Mapper for \a ScalarBar. vtkActor2D* ScalarBarActor; //!< Actor for \a ScalarBar. vtkPolyData* TexturePolyData; //!< Polygon colored when UseOpacity is true. vtkTexture* Texture; //!< Color data for \a TexturePolyData. vtkTexturedActor2D* TextureActor; //!< Actor for \a TexturePolyData. vtkPolyData* Background; //!< Polygon used to fill the background. vtkPolyDataMapper2D* BackgroundMapper; //!< Mapper for \a Background. vtkActor2D* BackgroundActor; //!< Actor for \a Background. vtkPolyData* Frame; //!< Polyline used to highlight frame. vtkPolyDataMapper2D* FrameMapper; //!< Mapper for \a Frame. vtkActor2D* FrameActor; //!< Actor for \a Frame. ///@} private: vtkScalarBarActor(const vtkScalarBarActor&) = delete; void operator=(const vtkScalarBarActor&) = delete; }; #endif