set legend position based on data driven pages

5690
6
Jump to solution
12-08-2015 07:29 AM
PSArcOnlinePSArcOnline
New Contributor III

Hello,

I want to set the position of my legend based on values of a "Data Driven Pages" attribute. Yet I don't have any code. This is just collection of what I think I need.

I had to read the value from the Data Driven Page attribute field.

posY = tempMap.dataDrivenPages.pageRow.posY

posX = tempMap.dataDrivenPages.pageRow.posX

And change the values of the legend objekt.

mylegend.elementPositionY = posY

mylegend.elementPositionX = posX

The script should trigger by changing the Data Driven Page. This should also work then I print all pages.

def pageIndexExtentChanged(seld, new_id)

Problem: I had to change the anchor position to set the correct X/Y values (height and width of the legend is dynamic and may change). How can I achieve this (see picture)?

0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

You can keep track of this by either adding or subtracting the elementWidth from elementPositionX, or elementHeight and elementPositionY.

For example, if your legend is set to anchor to the top left, then to trick it into anchoring in terms of the top right would be:

mylegend.elementPositionY = posY - myLegend.elementWidth # add some amount to move the legend

View solution in original post

6 Replies
DarrenWiens2
MVP Honored Contributor

You can keep track of this by either adding or subtracting the elementWidth from elementPositionX, or elementHeight and elementPositionY.

For example, if your legend is set to anchor to the top left, then to trick it into anchoring in terms of the top right would be:

mylegend.elementPositionY = posY - myLegend.elementWidth # add some amount to move the legend
PSArcOnlinePSArcOnline
New Contributor III

Hey Darren,

thanks for your answer. With your help I could make a arcgis extension add-in. Using the Python Add-In Wizard. And it works as I want (UPDATE: It does not. Working code below). In the index layer there is an attribute field which controls the position of the legend. (1 = lower left, 2= upper left, 3= upper right, 4 = lower right).

The position is hardcoded to fit my layout.

Here the code I use (don't know how to enable the code tag you are using )

<<<<<<<<<

import arcpy

import pythonaddins

class ExtensionClass1(object):

    """Implementation for MovableLegend_addin.extension2 (Extension)"""

    def __init__(self):

        # For performance considerations, please remove all unused methods in this class.

        self.enabled = True

    def pageIndexExtentChanged(self, new_id):

        mxd = arcpy.mapping.MapDocument("CURRENT")

        legend = arcpy.mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT")[0]

        if mxd.dataDrivenPages.pageRow.LegendPOS == 1:

           posX = 2

           posY = 3.1

        elif mxd.dataDrivenPages.pageRow.LegendPOS == 2:

           posX = 2

           posY = 24.6 - legend.elementHeight

        elif mxd.dataDrivenPages.pageRow.LegendPOS == 3:

           posX = 19 - legend.elementWidth

           posY = 24.6 - legend.elementHeight

        elif mxd.dataDrivenPages.pageRow.LegendPOS == 4:

           posX = 19 - legend.elementWidth

           posY = 3.1

        legend.elementPositionY = posY

        legend.elementPositionX = posX

>>>>>>>>>

So thanks for your help.

One last question. The addin produces no error if I open an arcgis project with a Data Driven Page Index Layer without the attribute LegendPOS. In this case it does simply nothing. This is good, but is this normal? Do I have to implement an error behavior for doing it right?

0 Kudos
PSArcOnlinePSArcOnline
New Contributor III

Unfortunately, it doesn't work correctly.

The value of the size of the legend is not changing. It is always those of the original legend.

Longer layer names (legend.elementWidth)

More layers (legend.elementHeight)

0 Kudos
PSArcOnlinePSArcOnline
New Contributor III

I added a view Pictures.

Test 1 and 2 works.

If I change the layer names to the same lenght it works. Test 3 and 4.

But If the names are Different it doesn't use the new width. TestERROR1 and TestERROR2

0 Kudos
PSArcOnlinePSArcOnline
New Contributor III

If I use the python console step by step, it works.

0 Kudos
PSArcOnlinePSArcOnline
New Contributor III

Now it works.

I implemented a arcpy.RefreshActiveView() for forcing the correct width and height values. Otherwise the actual drawing of the legend comes too late.

So my final question remains:

The addin produces no error if I open an arcgis project with a Data Driven Page Index Layer without the attribute LegendPOS. In this case it does simply nothing. This is good, but is this normal? Do I have to implement an error behavior for doing it right?

Here the code

def pageIndexExtentChanged(self, new_id):
mxd = arcpy.mapping.MapDocument("CURRENT")
#Only one legend in layout
legend = arcpy.mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT")[0]
#The heigt and width must be up to date
arcpy.RefreshActiveView()
#LegendPOS is a attribut field in the index layer (small integer)
#1 = lower left, 2= upper left, 3= upper right, 4 = lower right
#posX and posY hardcoded for this special layout
if mxd.dataDrivenPages.pageRow.LegendPOS == 1:
   posX = 2
   posY = 3.1
elif mxd.dataDrivenPages.pageRow.LegendPOS == 2:
   posX = 2
   posY = 24.6 - legend.elementHeight
elif mxd.dataDrivenPages.pageRow.LegendPOS == 3:
   posX = 19 - legend.elementWidth
   posY = 24.6 - legend.elementHeight
elif mxd.dataDrivenPages.pageRow.LegendPOS == 4:
   posX = 19 - legend.elementWidth
   posY = 3.1
legend.elementPositionY = posY
legend.elementPositionX = posX
0 Kudos