|
; LOAD A SIMPLE ICONTOUR
; Make a color table to pass to the ICONTOUR procedure
loadct, 5
tvlct, r, g, b, /get
rgb_table = bytarr(3,256)
rgb_table[0,*] = r
rgb_table[1,*] = g
rgb_table[2,*] = b
; Make the contour data
dummy_data = dist(360)
iContour, dummy_data, NAME='DIST Contour', RGB_TABLE=rgb_table, $
IDENTIFIER=idTool
; GET A REFERENCE TO THE CURRENT TOOL.
; This provides our main key to other object references and ID's in the
; visualization hierarchy.
void = itgetcurrent(TOOL=oTool)
; PRACTICE TRIGGERING AN OPERATION - INSERTING THE COLORBAR PROGRAMATICALLY
; For this we need the ID of the operation that does the menubar's
; 'Insert->Colorbar' action.
; Let's assume you are relatively new to iTool addressing syntax. To get a
; handle on that operation you have to figure that the iTool ID will contain
; the word "COLORBAR". Thus ...
temp = oTool->FindIdentifiers('*COLORBAR*')
help, temp
;TEMP STRING = Array[2]
print, temp, format='(a)'
;/TOOLS/CONTOUR TOOL/OPERATIONS/INSERT/COLORBAR
;/TOOLS/CONTOUR TOOL/CURRENT STYLE/VISUALIZATIONS/COLORBAR
; It is intuitive that the ID with the string "INSERT" is the one that we are
; looking for.
idOpInsertColorbar = oTool->FindIdentifiers('*INSERT/COLORBAR')
print, idOpInsertColorbar
;/TOOLS/CONTOUR TOOL/OPERATIONS/INSERT/COLORBAR
; We made the above queries, so that we can run this iTool method, which
; does programatically what the GUI menu selection would do.
print, oTool->DoAction(idOpInsertColorbar)
; Check the iTool GUI and observe the colorbar and its horizontal orientation. 1
; RESEARCH PROPERTIES AND METHODS OF THE COLORBAR
; My goal is to figure out how to turn the colorbar upright.
; For this I might want both its ID and its object reference.
; You have to figure the new colorbar object's ID has to have the word
; "COLORBAR" in it.
temp = oTool->FindIdentifiers('*COLORBAR*')
help, temp
;TEMP STRING = Array[3]
print, temp, format='(a)'
;/TOOLS/CONTOUR TOOL/OPERATIONS/INSERT/COLORBAR
;/TOOLS/CONTOUR TOOL/CURRENT STYLE/VISUALIZATIONS/COLORBAR
;/TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/ANNOTATION LAYER/COLORBAR
; It is pretty clear that the ID with "ANNOTATION LAYER" is what I am
; looking for.
idColorbar = oTool->FindIdentifiers('*ANNOTATION LAYER/COLORBAR')
print, idColorbar
;/TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/ANNOTATION LAYER/COLORBAR
; This it the main iTool routine for retrieving the object reference
; that corresponds to an ID.
oColorbar = oTool->GetByIdentifier(idColorbar)
; HELP, /OBJECTS is a nice quick reference tool that shows a lot more options
; than what you might find in the early generation iTool documentation. It
; provides quick reference to a lot of the methods and perhaps ALL of the
; superclasses that your object can call. It shows many, but not all, of the
; methods that it has inherited. Consequently, you sometimes have to check the
; direct documentation of the superclasses (or run "HELP, /OBJECTS" on an
; object of that type) to find what might be most useful to you.
help, oColorbar, /objects
;** Object class IDLITVISCOLORBAR, 1 direct superclass, 66 known methods
; Superclasses:
; IDLITVISUALIZATION
; _IDLITVISUALIZATION
; _IDLITCONTAINER
; _IDLITPROPERTYAGGREGATE
; IDLGRMODEL
; IDLGRCONTAINER
; IDL_CONTAINER
; IDLGRCOMPONENT
; IDLITCOMPONENT
; IDLITSELECTPARENT
; IDLITIMESSAGING
; IDLITPARAMETER
; Known Function Methods:
; _IDLITVISUALIZATION::CREATE
; _IDLITCONTAINER::GET
; _IDLITPROPERTYAGGREGATE::GETAGGREGATE
; _IDLITVISUALIZATION::GETCENTERROTATION
; _IDLITVISUALIZATION::GETDATASPACE
; _IDLITVISUALIZATION::GETDEFAULTSELECTIONVISUAL
; IDLITCOMPONENT::GETFULLIDENTIFIER
; _IDLITVISUALIZATION::GETMANIPULATORTARGET
; IDLITPARAMETER::GETPARAMETER
; IDLITCOMPONENT::GETPROPERTYBYIDENTIFIER
; _IDLITVISUALIZATION::GETREQUESTEDAXESSTYLE
; _IDLITVISUALIZATION::GETSELECTIONVISUAL
; IDLITIMESSAGING::GETTOOL
; IDLITVISUALIZATION::GETTYPES
; _IDLITVISUALIZATION::GETXYZRANGE
; IDLITVISCOLORBAR::INIT
; _IDLITVISUALIZATION::IS3D
; _IDLITPROPERTYAGGREGATE::ISAGGREGATEINTERSECTION
; _IDLITVISUALIZATION::ISISOTROPIC
; _IDLITVISUALIZATION::ISMANIPULATORTARGET
; _IDLITVISUALIZATION::ISSELECTED
; _IDLITVISUALIZATION::MATCHESTYPES
; IDLITPARAMETER::QUERYPARAMETER
; IDLITPARAMETER::QUERYPARAMETERDESCRIPTOR
; IDLITCOMPONENT::QUERYPROPERTY
; _IDLITVISUALIZATION::REQUESTSAXES
; _IDLITVISUALIZATION::SEEKPIXELATEDVISUALIZATION
; IDLITVISUALIZATION::SETPARAMETERSET
; _IDLITVISUALIZATION::_GETLAYER
; _IDLITVISUALIZATION::_GETWINDOWANDVIEWG
; _IDLITPROPERTYAGGREGATE::_GETALLPROPERTYDESCRIPTORS
; Known Procedure Methods:
; _IDLITVISUALIZATION::ADD
; _IDLITPROPERTYAGGREGATE::ADDAGGREGATE
; _IDLITVISUALIZATION::AGGREGATE
; IDLITIMESSAGING::DOONNOTIFY
; IDLGRMODEL::DRAW
; IDLGRMODEL::DRAWSELF
; _IDLITPROPERTYAGGREGATE::GETAGGREGATEPROPERTY
; IDLITPARAMETER::GETPARAMETERATTRIBUTE
; IDLITVISCOLORBAR::GETPROPERTY
; IDLITCOMPONENT::GETPROPERTYATTRIBUTE
; IDLITVISCOLORBAR::GETPROPERTY
; IDLITVISUALIZATION::ONDATACHANGE
; IDLITVISCOLORBAR::ONDATACHANGEUPDATE
; IDLITVISUALIZATION::ONDATACOMPLETE
; IDLITVISUALIZATION::ONDATADELETE
; _IDLITVISUALIZATION::ONWORLDDIMENSIONCHANGE
; IDLITPARAMETER::REGISTERPARAMETER
; IDLITCOMPONENT::REGISTERPROPERTY
; IDLGRMODEL::RESET
; _IDLITVISUALIZATION::SELECT
; _IDLITPROPERTYAGGREGATE::SETAGGREGATEPROPERTY
; _IDLITVISUALIZATION::SETCURRENTSELECTIONVISUAL
; IDLITPARAMETER::SETPARAMETER
; IDLITPARAMETER::SETPARAMETERATTRIBUTE
; IDLITVISCOLORBAR::SETPROPERTY
; IDLITCOMPONENT::SETPROPERTYBYIDENTIFIER
; IDLITVISCOLORBAR::SETPROPERTY
; IDLGRMODEL::TRANSLATE
; _IDLITVISUALIZATION::UPDATESCENE
; _IDLITVISUALIZATION::UPDATESELECTIONVISUAL
; _IDLITVISUALIZATION::UPDATESELECTIONVISUALVISIBILITY
; _IDLITVISUALIZATION::_ACCUMULATEXYZRANGE
; _IDLITVISUALIZATION::_CHECKDIMENSIONCHANGE
; IDLITVISCOLORBAR::_REGISTERPROPERTIES
; IDLITIMESSAGING::_SETTOOL
; Now that I know that a colorbar annotation is an 'IDLitVisColorbar' object
; I can look at IDL's Online Help.
?IDLitVisColorbar
; Notice how little information is yet documented there. So my next iTool
; research utility is the QUERYPROPERTY method that every iTool component
; has implemented. (I show this here for thoroughness. Further below I
; demonstrate ITPROPERTYREPORT, currently in everybody's IDL 'examples'
; directory and documented in the Developer's Guide. That provides some
; shortcuts compared to the below.)
propsColorbar = oColorbar->QueryProperty()
print, propsColorbar, format='(a)'
;NAME
;DESCRIPTION
;HIDE
;CLIP_PLANES
;DEPTH_TEST_DISABLE
;DEPTH_TEST_FUNCTION
;DEPTH_WRITE_DISABLE
;LIGHTING
;SELECT_TARGET
;TRANSFORM
;BORDER_ON
;ORIENTATION
;LOCATION
;DATA_POSITION
;TRANSPARENCY
;ALPHA_CHANNEL
;COLOR
;PALETTE
;DIRECTION
;GRIDSTYLE
;THICK
;MAJOR
;MINOR
;TICKLEN
;SUBTICKLEN
;TICKINTERVAL
;TICKLAYOUT
;TICKDIR
;LOG
;EXACT
;EXTEND
;NOTEXT
;TEXTPOS
;TICKFORMAT
;TICKUNITS
;TICK_DEFINEDFORMAT
;AXIS_TITLE
;TEXT_COLOR
;NORM_LOCATION
;RANGE
;CRANGE
;TICKFRMTDATA
;FONT_INDEX
;FONT_STYLE
;FONT_SIZE
; An "ORIENTATION" property AND a "DIRECTION" property; that's confusing!
; Maybe the source code can quickly reveal what I want. I know my object
; type is named "IDLitVisColorbar". Therefore, it is most likely defined
; in its own 'idlitviscolorbar__define.pro' file. This is where the IDL
; command line command .EDIT comes in handy. When the file opens in the
; editor, I search straight for the string "::SetProperty". That is where
; all of the component '__define.pro' files list (in the procedure comments)
; their settable properties.
.edit IDLitVisColorbar__define
; In this case the source code is not so straightforward, so I quickly
; see if the iContour GUI can help. Sure enough, there is an ORIENTATION
; property, but no DIRECTION. ORIENTATION is defined as "Horizontal". Is
; that 2-option property really stored as a string?
oColorbar->GetProperty, ORIENTATION=temp
print, temp
; 0
; It's an int; so I now check to see if this is an "enumerated list" as
; one might expect from a dropdown list on an iTools property sheet.
; 'GetPropertyAttribute' is available to all iTool components through
; the 'IDLitComponent' superclass.
oColorbar->GetPropertyAttribute, 'ORIENTATION', TYPE=orientationDatatype
print, orientationDatatype
; 9
; A link from Online Help for IDLitComponent::GetPropertyAttribute
; confirms that 9 = "enumerated list" and reveals this additional keyword
; option.
oColorbar->GetPropertyAttribute, 'ORIENTATION', $
ENUMLIST=orientationOptions
print, orientationOptions
;Horizontal Vertical
; Looks like I can be confident that "Vertical" orientation maps to the
; value of 1.
; PRACTICE MODIFYING VISUALIZATION PROPERTIES -
; STANDING THE COLORBAR VERTICAL AND CHANGING ITS TEXT PROPERTIES
; We made the above queries, so that we can run this iTool method, which
; does programatically what modifying a property on the Visualization
; Browser does.
print, oTool->DoSetProperty(idColorbar, 'ORIENTATION', 1)
; 1
oTool->CommitActions
; One consequence of calling DOSETPROPERTY is that your action is recorded
; in iTools' 'UNDO/REDO' buffer. When you are developing an application,
; you may prefer that such recording NOT occur, in which case the following
; call would substiture for the above two:
;oColorbar->SetProperty, ORIENTATION=1
; I want to clean up the appearance of the text on the colorbar. I found
; the property names I needed in the QUERYPROPERTY() list above.
oColorbar->GetProperty, TEXTPOS=temp
print, temp
; 0
print, oTool->DoSetProperty(idColorbar, 'TEXTPOS', 1)
; 1
oTool->CommitActions
oColorbar->GetProperty, FONT_SIZE=temp
print, temp
; 12
print, oTool->DoSetProperty(idColorbar, 'FONT_SIZE', 8)
; 1
oTool->CommitActions
; POSITIONING THE ANNOTATION WITH RESPECT TO THE PLOT
; The remaining steps in this procedure are not so intuitive as the above.
; A deeper understanding of the original IDL Object Graphics classes, from
; which iTools inherits, is useful here.
; The critical objects needed to finish this job are 1) the Contour object
; (IDLitVisContour) and 2) the Visualization Layer object (IDLitGrLayer).
; From the Contour object we just need its "graphics transform matrix".
; From the Layer we need the definitions of the coordinate system for our
; Contour. Those definitions provide the key to how to use the data in the
; Contour's transform matrix.
; I start with the information from Contour's visualization layer:
temp = oTool->FindIdentifiers('*VISUALIZATION LAYER')
help, temp
;TEMP STRING = Array[2]
print, temp, format='(a)'
;/TOOLS/CONTOUR TOOL/CURRENT STYLE/VISUALIZATIONS/VISUALIZATION LAYER
;/TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/VISUALIZATION LAYER
idVisLayer = oTool->FindIdentifiers('*VIEW_1/VISUALIZATION LAYER')
print, idVisLayer
;/TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/VISUALIZATION LAYER
oVisLayer = oTool->GetByIdentifier(idVisLayer)
; I use the next 2 calls to look for methods and/or properties that will
; show the coordinate system of the layer as a whole, and that will show
; what margins there are between the outside bounds of the Contour and
; the outside edges of the Layer. The Contour's bounds are identifiable
; by the axes box. The Layer's bounds are, at least when iContour first
; loads, identifiable by the outer edges of the view window. Both objects
; are working with normalized coordinates with their center in the center
; of the view window (at least when iContour first loads). You will find
; that they share the same coordinate system, which means that one or the
; other, perhaps both, do NOT have a simple -1.0 - +1.0 range. The below
; steps unravel the mysteries of the coordinate system we need to address.
help, oVisLayer, /objects
;** Object class IDLITGRLAYER, 4 direct superclasses, 35 known methods
; Superclasses:
; _IDLITCONTAINER
; IDLGRVIEW
; IDLGRCONTAINER
; IDL_CONTAINER
; IDLGRCOMPONENT
; IDLITCOMPONENT
; IDLITSELECTPARENT
; IDLITIMESSAGING
; Known Function Methods:
; IDLITGRLAYER::COMPUTEVIRTUALFRUSTUMRECT
; IDLITGRLAYER::CREATE
; IDLITGRLAYER::GET
; _IDLITCONTAINER::GETBYIDENTIFIER
; IDLITGRLAYER::GETCURRENTDATASPACE
; IDLITCOMPONENT::GETFULLIDENTIFIER
; IDLITCOMPONENT::GETPROPERTYBYIDENTIFIER
; IDLITIMESSAGING::GETTOOL
; IDLITGRLAYER::GETWORLD
; IDLITGRLAYER::INIT
; IDLITCOMPONENT::QUERYPROPERTY
; IDLITCOMPONENT::_GETALLPROPERTYDESCRIPTORS
; IDLITGRLAYER::_ROUNDMARGIN
; Known Procedure Methods:
; IDLITGRLAYER::ADD
; IDLITGRLAYER::CROPFRUSTUM
; IDLITIMESSAGING::DOONNOTIFY
; IDLGRVIEW::DRAW
; IDLITGRLAYER::GETPROPERTY
; IDLITCOMPONENT::GETPROPERTYATTRIBUTE
; IDLITGRLAYER::GETPROPERTY
; IDLITGRLAYER::ONDATACHANGE
; IDLITGRLAYER::ONDATACOMPLETE
; IDLITGRLAYER::ONVIEWPORTCHANGE
; IDLITCOMPONENT::REGISTERPROPERTY
; IDLITGRLAYER::SETCURRENTDATASPACE
; IDLITSELECTPARENT::SETPRIMARYSELECTEDITEM
; IDLITGRLAYER::SETPROPERTY
; IDLITCOMPONENT::SETPROPERTYATTRIBUTE
; IDLITCOMPONENT::SETPROPERTYBYIDENTIFIER
; IDLITGRLAYER::SETSELECTEDITEM
; IDLITGRLAYER::SETPROPERTY
; IDLITGRLAYER::_CORRECTFORASPECTRATIO
; IDLITGRLAYER::_CORRECTFORZOOM
; IDLITGRLAYER::_REGISTERPROPERTIES
; IDLITGRLAYER::_UPDATEMARGINS
; I don't see anything above that will return to me simple coordinate
; information, so I check the properties. This time I will use the
; thorough ITPROPERTYREPORT utility, introduced in 6.1, and documented
; on page 387 of the 6.1 'itooldevguide.pdf'.
itpropertyreport, oTool, idVisLayer
;% Compiled module: ITPROPERTYREPORT.
;
;Properties of /TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/VISUALIZATION LAYER
;
;Identifier Name Type
;---------- ---- ----
;NAME Name STRING
;DESCRIPTION Description STRING
;HIDE Show ENUMLIST
;COLOR Background color COLOR
;DEPTH_CUE Depth cue USERDEF
;DIMENSIONS Viewport dimensions USERDEF
;DOUBLE Double precision BOOLEAN
;EYE Eye distance FLOAT
;LOCATION Viewport location USERDEF
;PROJECTION Projection ENUMLIST
;TRANSPARENT Transparent BOOLEAN
;UNITS Units ENUMLIST
;VIEWPLANE_RECT Viewplane rectangle USERDEF
;ZCLIP Z clipping USERDEF
;_PROJECTION Projection ENUMLIST
;STRETCH_TO_FIT Stretch to fit BOOLEAN
;MARGIN_2D_X X margin FLOAT
;MARGIN_2D_Y Y margin FLOAT
;DEPTHCUE_BRIGHT Depth cue bright FLOAT
;DEPTHCUE_DIM Depth cue dim FLOAT
; Ahhh, VIEWPLANE_RECT and MARGIN_... properties; that's what we need.
oVisLayer->GetProperty, VIEWPLANE_RECT=vrVisLayer
print, vrVisLayer
; -1.3984375 -1.0000000 2.7968750 2.0000000
oVisLayer->GetProperty, MARGIN_2D_X=xMarginVisLayer
oVisLayer->GetProperty, MARGIN_2D_Y=yMarginVisLayer
print, xMarginVisLayer, yMarginVisLayer
; 0.24900000 0.15000000
; I better check that there isn't anything out of sync between the
; coordinate system of Contour's "Visualization Layer" and the coordinate
; system of Colorbar's "Annotation Layer".
idAnnoLayer = oTool->FindIdentifiers('*VIEW_1/ANNOTATION LAYER')
print, idAnnoLayer
;/TOOLS/CONTOUR TOOL/WINDOW/VIEW_1/ANNOTATION LAYER
oAnnoLayer = oTool->GetByIdentifier(idAnnoLayer)
oAnnoLayer->GetProperty, VIEWPLANE_RECT=vrAnnotationLayer
print, vrAnnotationLayer
; -1.3984375 -1.0000000 2.7968750 2.0000000
; Good! The two layers have the same coordinate system.
; How should we interpret these numbers?
; The TRANSFORM property of the IDLitVisColorbar object will help to
; DEMONSTRATE the interpretation. We can, namely, move an annotation
; object to a specific location by manipulating the values in the
; rightmost column of the object's "graphics transform matrix".
oColorbar->GetProperty, TRANSFORM=t
print, t
; 1.0000000 0.00000000 0.00000000 -0.50000000
; 0.00000000 1.0000000 0.00000000 -0.75000000
; 0.00000000 0.00000000 1.0000000 0.00000000
; 0.00000000 0.00000000 0.00000000 1.0000000
; The value in index [3,0] is giving the current X location of the
; colorbar object. Index [3,1] is giving the Y location. (2D graphics
; do not generally use Z location, which is stored at index [3,2].)
; Thus, we can get a better view of the coordinate system of the
; viewplane rectangle, if we try:
new_colorbar_t = t
new_colorbar_t[3,0] = vrVisLayer[0] ; -1.398
new_colorbar_t[3,1] = vrVisLayer[1] ; -1.0
print, oTool->DoSetProperty(idColorbar, 'TRANSFORM', new_colorbar_t)
; 1
oTool->CommitActions
; Notice how this positions the colorbar flush with the lower-left corner
; of the visualization. Thus, indexes 0 and 1 of the viewplane rectangle
; hold the X/Y-coordinate of the lower-left hand corner of the view window.
; Indexes 2 and 3 of the viewplane rectangle show the full height and
; width of the initial view window in coordinate units.
; [Why is the VIEWPLANE_RECT so uneven? See footnote at bottom.*]
; How do we find the coords for the boundaries of the plot axis box?
; This is where the Layer's margin information is required
print, xMarginVisLayer, yMarginVisLayer
; 0.24900000 0.15000000
; The above numbers are in percent, and are actually a property that is
; user-modifiable in the Visualization browser. What it means is that the
; edges of the initial contour are recessed 25% in from the left and 25%
; in from the right side of the view window. Thus, if the view window is
; 2.7968750 units wide and the left edge of the window is at coordinate
; -1.3984375, the left edge of the graph (the left Y-axis) will be at
; X-coordinate -0.699219 (= -1.3984375 + (0.25 * 2.7968750)). The bottom
; of the graph, with a 'yMargin' of 15% will be at
; -1.0 + (0.15 * 2.0) = -0.7.
; Thus, the following should put our colorbar at the origin of the graph.
new_colorbar_t[3,0] = -0.699219
new_colorbar_t[3,1] = -0.7
print, oTool->DoSetProperty(idColorbar, 'TRANSFORM', new_colorbar_t)
; 1
oTool->CommitActions
; Look at the iContour now, and notice how this works on the X dimension,
; but it produces a strange result in the Y dimension. The explanation for
; this has to do with the "anisotropic scaling" of the default dataspace.
; You will see what is meant by this by, on the Visualization Browser,
; highlighting the 'Visualization Layer -> Data Space', and changing its
; property to 'Isotropic Scaling'. Now you see how the above command
; actually DID in a way find the origin of our plot axes. (If you do not
; understand 'Isotropic Scaling' see footnote 2 below.**)
; Unfortunately, the above algorithm is not complete enough for the
; anisotropic view that most visualizations work with. So, we find an
; alternative property of iTools, one necessary for later moving our
; colorbar, that is also helpful for its initial positioning.
; USING THE CONTOUR TRANSFORM MATRIX FOR POSITIONING
; The Cumulative Transform Matrix, a property of every 'IDLgrModel' and,
; by inheritance, a part of the IDLitVisContour object, provides us with
; the last key to the coordinate system that we are looking for.
idContour = oTool->FindIdentifiers('*CONTOUR*', /VISUALIZATIONS)
oContour = oTool->GetByIdentifier(idContour)
; We try to find out how to get the current cumulative transform matrix
; through the usual iTools queries discussed above.
itpropertyreport, oTool, idContour
help, oContour, /objects
; The output of these calls reveals two items of interest: 'oContour' has
; a TRANSFORM property and 'oContour' has an inherited method
; 'IDLgrModel::GetCTM'. 'oContour's TRANSFORM property returns a unit
; matrix on iTools initialization. This must be the transform matrix of
; just the contour object by itself, not of the whole layer model that is
; containing it. Since we want to coordinate the contour's "layer" with the
; annotation's "layer" we need the cumulative transform matrix, and this is
; where the IDLgrModel::GetCTM method looks promising:
ctmContour = oContour->GetCTM()
print, ctmContour
; 0.0038997214 0.00000000 0.00000000 -0.70000000
; 0.00000000 0.0027298050 0.00000000 -0.49000000
; 0.00000000 0.00000000 1.0000000 0.00000000
; 0.00000000 0.00000000 0.00000000 1.0000000
; The above transform matrix is the only one we need, but the below call
; helps to better understand the meaning of transform matrix data.
ctmColorbar = oColorbar->GetCTM()
print, ctmColorbar
; 1.0000000 0.00000000 0.00000000 -0.69921899
; 0.00000000 1.0000000 0.00000000 -0.69999999
; 0.00000000 0.00000000 1.0000000 0.00000000
; 0.00000000 0.00000000 0.00000000 1.0000000
; Notice how the CTM for the colorbar object is identical to the value
; of the last 'new_colorbar_t' that we set the colorbar's TRANSFORM
; property to. I wonder what will happen if we set the colorbar's
; TRANSFORM location indexes equal to the contour's CTM values.
new_colorbar_t[3,0] = ctmContour[3,0] ; -0.70000000
new_colorbar_t[3,1] = ctmContour[3,1] ; -0.49000000
print, oTool->DoSetProperty(idColorbar, 'TRANSFORM', new_colorbar_t)
; 1
oTool->CommitActions
; View the iContour now. This turns out to be a pretty simple key to
; finding the contour plot's origin. I discover, however, that for the
; right-side plot border I still need the VIEWPOINT_RECT and MARGIN_X_2D
; information. Thus:
rightEdgeCoord = vrVisLayer[0] + vrVisLayer[2] - $
(xMarginVisLayer * vrVisLayer[2])
print, rightEdgeCoord
; 0.69921875
; ... then from the contour transform matrix:
bottomEdgeCoord = ctmContour[3,1]
new_colorbar_t[3,0] = rightEdgeCoord
new_colorbar_t[3,1] = bottomEdgeCoord
newCoords = [rightEdgeCoord, bottomEdgeCoord, 0]
print, oTool->DoSetProperty(idColorbar, 'TRANSFORM', new_colorbar_t)
; 1
oTool->CommitActions
; Voilą.
; USING THE CONTOUR TRANSFORM MATRIX FOR SYNCHRONIZING ANNOTATION/COLORBAR
; WITH CONTOUR MOVEMENT
; Simple dragging movement on a 2D plane is known in graphics parlance as
; "translation", and a possible method for performing such dragging pro-
; gramatically is currently only documented in the Online Help for the
; long-standing 'IDLgrModel' class.
; The values to feed to IDLgrModel::Translate turn out to be pretty simple.
; Notice the following test. First, I reprint the matrix from above:
ctmContourOld = ctmContour
print, ctmContourOld
; 0.0038997214 0.00000000 0.00000000 -0.70000000
; 0.00000000 0.0027298050 0.00000000 -0.49000000
; 0.00000000 0.00000000 1.0000000 0.00000000
; 0.00000000 0.00000000 0.00000000 1.0000000
; Then, I go to the iContour and drag the contour plot with my mouse.
; Let's look at what this drag did to the contour's CTM:
ctmContourNew = oContour->GetCTM()
print, ctmContourNew
; 0.0038997214 0.00000000 0.00000000 -1.0593750
; 0.00000000 0.0027298050 0.00000000 -0.82854167
; 0.00000000 0.00000000 1.0000000 0.00000000
; 0.00000000 0.00000000 0.00000000 1.0000000
; Everything is the same except the right-column numbers. And it is now
; not hard for me to see that those numbers correspond to the location
; of the origin of the contour plot with respect to the origin (center)
; of our view rectangle. The movement I just performed then, could be
; defined as follows:
dx = ctmContourNew[3,0] - ctmContourOld[3,0]
dy = ctmContourNew[3,1] - ctmContourOld[3,1]
; If this were a 3D plot with a Z direction, then I could also
; calculate a 'dz' with element [3,2] of the transform matrices. But
; I now have all I need to programatically move the colorbar to
; its former position relative to the contour.
oColorbar->Translate, dx, dy, 0
; Now that is the best method to call, if you do not care that this
; translation was not recorded in this iContour's UNDO/REDO buffer.
; This DOES update the TRANSFORM property of the colorbar object, but
; if you need to have it recorded for possible later User Interface
; 'Undo' actions, then you need to perform the DoSetProperty method
; that was demo'ed above, e.g.:
;new_colorbar_t[3,0] += dx
;new_colorbar_t[3,1] += dy
;print, oTool->DoSetProperty(idColorbar, 'TRANSFORM', new_colorbar_t)
; One other 'translation' option I should mention: Some annotation
; objects, like IDLitVisText objects for example, can be
; programatically added to the Visualization Layer. If you take that
; approach, then an alternative algorithm for synchronizing that
; object's movement with your plot object would be to programatically
; "group" the objects with a call to the 'Edit->Grouping->Group'
; operation after you have run the 'Select' procedure method on the
; objects you want to group. The group will then "transform" together
; until they are "ungroup"ed. You just need to remember that up to
; at least IDL 6.1 objects in the Annotation Layer cannot be
; "group"ed with objects in the Visualization Layer this way.
; * FOOTNOTE ON VIEWPLANE_RECT DIMENSIONS:
; Our example showed a VIEWPLANE_RECT values of:
; -1.3984375 -1.0000000 2.7968750 2.0000000
; The range of the width dimension (2.79 units wide) is explained by the
; uneven dimensions of the view window. By default, the initial iContour
; window starts at 537 x 384 pixels. iTools work with normalized
; coordinates. The design decision was made that the smaller pixel
; dimension, in this case the height, should be normalized to a range of
; -1.0 to +1.0. Hence, the other dimension, basing its measurements on
; the same pixel mapping, has a range extending beyond -1.0 to +1.0.
; The exact range is exactly -1.0*(537/384) to +1.0*(537/384), which
; equals -1.3984375 to +1.3984375.
; ** FOOTNOTE ON ISOTROPIC SCALING:
; To best understand 'Isotropic Scaling' run an exponential curve example
; like:
; iPlot, findgen(10), findgen(10)^2
; Change the 'Data Space' 'Isotropic Scaling' property from "Automatic" to
; "Isotropic Scaling". The result you see demonstrates how isotropic
; scaling enforces that the pixel-width-to-data ratio is identical to
; the pixel-height-to-data ratio, not a very good graph view if the X and
; Y data ranges are vastly different. The goal of anisotropic scaling is
; to set pixel-width-to-data and pixel-height-to-data ratios based on the
; window view dimensions, so that the plot display looks nice within the
; current window borders.
|