# Easy Chart : pen control panel

**URL:** <https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559>\
**Category:** Ignition\
**Created:** [January 13, 2017, 3:24pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559 "2017-01-13T15:24:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![pascal](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pascal](https://forum.inductiveautomation.com/u/pascal)\
**Post date:** [January 13, 2017, 3:24pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/1 "2017-01-13T15:24:49Z")

</div>

Hello everybody,

Is there any way to change the pen control panel position in an easy chart ? I would like to put it on the right of my chart but i haven’t figured out how to do yet.  
Thanks in advance.

---

<div class="post-metadata">

**Author:** ![adam.morales](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/adam.morales/32/3405_2.png) [@adam.morales](https://forum.inductiveautomation.com/u/adam.morales)\
**Post date:** [February 7, 2017, 12:48am UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/2 "2017-02-07T00:48:16Z")

</div>

Unfortunately, there is not way to change the position of the pen control panel, although you can add cell update bindings to the Tag Pens dataset to allow other components to hide, show, enable, or disable the pens.

---

<div class="post-metadata">

**Author:** ![dawei.liu](https://avatars.discourse-cdn.com/v4/letter/d/76d3ee/32.png) [@dawei.liu](https://forum.inductiveautomation.com/u/dawei.liu)\
**Post date:** [September 20, 2019, 2:22pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/3 "2019-09-20T14:22:29Z")

</div>

@adam.morales

I have a similar issue. Want to relocate the checkbox of pen to be closer to the chart, but did not find the related options.

For the workaround, so do we still need to create an independent checkbox group and bind them to the visiable column of pen dataset?

 ![png](https://us1.discourse-cdn.com/inductiveautomation/original/2X/3/3821cc18095d502acbb3e9dc1967d6ae7b7de9f1.png)

---

<div class="post-metadata">

**Author:** ![paul.bouillon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul.bouillon/32/7980_2.png) [@paul.bouillon](https://forum.inductiveautomation.com/u/paul.bouillon)\
**Post date:** [February 3, 2020, 10:15pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/4 "2020-02-03T22:15:19Z")

</div>

Hey all,

I’m a little late to the party here – just encountered the same issue as well, thought I would share our solution…  
It seems as though pen control is a secondary jcomponent that sits under the easychart jpanel (e.g. if you were to call self.getComponents(), you would get two elements:

```auto
array(java.awt.Component, [javax.swing.JPanel[,0,0,400x442,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@325d8ca0,flags=16777217,maximumSize=,minimumSize=,preferredSize=], com.inductiveautomation.factorypmi.application.components.PMIEasyChart$PenPanel[,0,442,400x48,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@49a1e3ed,flags=16777217,maximumSize=,minimumSize=,preferredSize=]])

```

…that second element is the pen control panel (PMIEasyChart$PenPanel).

Luckily – you can use the ‘configureChart’ extension function to modify the layout position of this component prior to rendering (the base jpanel uses borderlayout for easychart)… I wanted the pen controls placed at the bottom of the screen, so that we could maximize the horizontal space for the trend area:

```auto
def configureChart(self, chart):
	"""
	Provides an opportunity to perform further chart configuration via
	scripting. Doesn't return anything.

	Arguments:
		self: A reference to the component that is invoking this function.
		chart: A JFreeChart object. Refer to the JFreeChart documentation for
		       API details.
	"""
	from java.awt import BorderLayout
	from com.inductiveautomation.factorypmi.application.components.PMIEasyChart import PenPanel
	for c in self.getComponents(): # iterate over the jcomponents
		if isinstance(c, PenPanel): # find the pen control panel
			self.remove(c) # remove it from the layout manager
			self.add(c, BorderLayout.PAGE_END) # add it back to the bottom
			self.validate() # repaint!

```

Voila – pen controls to the bottom 🙂  
 ![modified%20easychart](https://us1.discourse-cdn.com/inductiveautomation/original/2X/3/303a1ce97fa5098b20dbd0ce4be8ee9e9d72464b.png)

---

<div class="post-metadata">

**Author:** ![pascal](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pascal](https://forum.inductiveautomation.com/u/pascal)\
**Post date:** [February 13, 2020, 7:57am UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/5 "2020-02-13T07:57:57Z")

</div>

Thank you very much for this help ! I’m lacking of knoledge with all the java component properties but it is very interesting because it adds many functionnalities to ignition.

I’m wondering if the control pen panel can display the pens horizontally and not vertically as it is ?  
I’m looking for into the javadocs bu i didn’t figure out which property has to be changed.

---

<div class="post-metadata">

**Author:** ![paul.bouillon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul.bouillon/32/7980_2.png) [@paul.bouillon](https://forum.inductiveautomation.com/u/paul.bouillon)\
**Post date:** [February 14, 2020, 8:06pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/6 "2020-02-14T20:06:39Z")

</div>

Hi Pascal – I imagine so… guessing that the jcomponent for the pen control also has it’s own layout manager for the container…

Maybe take a look at the com.inductiveautomation.factorypmi.application.components.PMIEasyChart$PenPanel object.

e.g.

```auto
from com.inductiveautomation.factorypmi.application.components.PMIEasyChart import PenPanel

pp = PenPanel

print(dir(pp))

```

outputs this:

```auto
['ABORT', 'ALLBITS', 'AccessibleJComponent', 'BOTTOM_ALIGNMENT', 'BaselineResizeBehavior', 'CENTER_ALIGNMENT', 'ERROR', 'FRAMEBITS', 'HEIGHT', 'LEFT_ALIGNMENT', 'PROPERTIES', 'PenControl', 'RIGHT_ALIGNMENT', 'SOMEBITS', 'TOOL_TIP_TEXT_KEY', 'TOP_ALIGNMENT', 'UI', 'UIClassID', 'UNDEFINED_CONDITION', 'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT', 'WHEN_FOCUSED', 'WHEN_IN_FOCUSED_WINDOW', 'WIDTH', ' __class__', ' __copy__', ' __deepcopy__', ' __delattr__', ' __doc__', ' __ensure_finalizer__', ' __eq__', ' __format__', ' __getattribute__', ' __hash__', ' __init__', ' __ne__', ' __new__', ' __reduce__', ' __reduce_ex__', ' __repr__', ' __setattr__', ' __str__', ' __subclasshook__', ' __unicode__', 'accessibleContext', 'action', 'actionMap', 'actionPerformed', 'add', 'addAncestorListener', 'addComponentListener', 'addContainerListener', 'addFocusListener', 'addHierarchyBoundsListener', 'addHierarchyListener', 'addInputMethodListener', 'addKeyListener', 'addMouseListener', 'addMouseMotionListener', 'addMouseWheelListener', 'addNotify', 'addPropertyChangeListener', 'addVetoableChangeListener', 'alignmentX', 'alignmentY', 'ancestorAdded', 'ancestorListener', 'ancestorListeners', 'ancestorMoved', 'ancestorRemoved', 'ancestorResized', 'applyComponentOrientation', 'areFocusTraversalKeysSet', 'autoscrolls', 'background', 'backgroundSet', 'baselineResizeBehavior', 'border', 'bounds', 'caretPositionChanged', 'checkBoxes', 'checkImage', 'class', 'colorModel', 'componentAdded', 'componentCount', 'componentHidden', 'componentListener', 'componentListeners', 'componentMoved', 'componentOrientation', 'componentPopupMenu', 'componentRemoved', 'componentResized', 'componentShown', 'components', 'computeVisibleRect', 'containerListener', 'containerListeners', 'contains', 'countComponents', 'createGUI', 'createImage', 'createToolTip', 'createVolatileImage', 'cursor', 'cursorSet', 'debugGraphicsOptions', 'deliverEvent', 'disable', 'dispatchEvent', 'displayable', 'doLayout', 'doubleBuffered', 'dropTarget', 'enable', 'enableInputMethods', 'enabled', 'equals', 'findComponentAt', 'firePropertyChange', 'focusCycleRoot', 'focusCycleRootAncestor', 'focusGained', 'focusListener', 'focusListeners', 'focusLost', 'focusOwner', 'focusTraversable', 'focusTraversalKeysEnabled', 'focusTraversalPolicy', 'focusTraversalPolicyProvider', 'focusTraversalPolicySet', 'focusable', 'font', 'fontSet', 'foreground', 'foregroundSet', 'getAccessibleContext', 'getActionForKeyStroke', 'getActionMap', 'getAlignmentX', 'getAlignmentY', 'getAncestorListeners', 'getAutoscrolls', 'getBackground', 'getBaseline', 'getBaselineResizeBehavior', 'getBorder', 'getBounds', 'getCheckBoxes', 'getClass', 'getClientProperty', 'getColorModel', 'getComponent', 'getComponentAt', 'getComponentCount', 'getComponentListeners', 'getComponentOrientation', 'getComponentPopupMenu', 'getComponentZOrder', 'getComponents', 'getConditionForKeyStroke', 'getContainerListeners', 'getCursor', 'getDebugGraphicsOptions', 'getDefaultLocale', 'getDropTarget', 'getFocusCycleRootAncestor', 'getFocusListeners', 'getFocusTraversalKeys', 'getFocusTraversalKeysEnabled', 'getFocusTraversalPolicy', 'getFont', 'getFontMetrics', 'getForeground', 'getGraphics', 'getGraphicsConfiguration', 'getHeight', 'getHierarchyBoundsListeners', 'getHierarchyListeners', 'getIgnoreRepaint', 'getInheritsPopupMenu', 'getInputContext', 'getInputMap', 'getInputMethodListeners', 'getInputMethodRequests', 'getInputVerifier', 'getInsets', 'getKeyListeners', 'getLayout', 'getListeners', 'getLocale', 'getLocation', 'getLocationOnScreen', 'getMaximumSize', 'getMinimumSize', 'getMouseListeners', 'getMouseMotionListeners', 'getMousePosition', 'getMouseWheelListeners', 'getName', 'getNextFocusableComponent', 'getParent', 'getPopupLocation', 'getPreferredSize', 'getPropertyChangeListeners', 'getRegisteredKeyStrokes', 'getRootPane', 'getSize', 'getToolTipLocation', 'getToolTipText', 'getToolkit', 'getTopLevelAncestor', 'getTransferHandler', 'getTreeLock', 'getUI', 'getUIClassID', 'getVerifyInputWhenFocusTarget', 'getVetoableChangeListeners', 'getVisibleRect', 'getWidth', 'getX', 'getY', 'gotFocus', 'grabFocus', 'graphics', 'graphicsConfiguration', 'handleEvent', 'hasFocus', 'hashCode', 'height', 'hide', 'hierarchyBoundsListener', 'hierarchyBoundsListeners', 'hierarchyChanged', 'hierarchyListener', 'hierarchyListeners', 'ignoreRepaint', 'imageUpdate', 'inheritsPopupMenu', 'inputContext', 'inputMap', 'inputMethodListener', 'inputMethodListeners', 'inputMethodRequests', 'inputMethodTextChanged', 'inputVerifier', 'insets', 'inside', 'invalidate', 'isAncestorOf', 'isBackgroundSet', 'isCursorSet', 'isDisplayable', 'isDoubleBuffered', 'isEnabled', 'isFocusCycleRoot', 'isFocusOwner', 'isFocusTraversable', 'isFocusTraversalPolicyProvider', 'isFocusTraversalPolicySet', 'isFocusable', 'isFontSet', 'isForegroundSet', 'isLightweight', 'isLightweightComponent', 'isManagingFocus', 'isMaximumSizeSet', 'isMinimumSizeSet', 'isOpaque', 'isOptimizedDrawingEnabled', 'isPaintingForPrint', 'isPaintingTile', 'isPreferredSizeSet', 'isRequestFocusEnabled', 'isShowing', 'isValid', 'isValidateRoot', 'isVisible', 'keyDown', 'keyListener', 'keyListeners', 'keyPressed', 'keyReleased', 'keyTyped', 'keyUp', 'layout', 'lightweight', 'list', 'locale', 'localeChanged', 'locate', 'location', 'locationOnScreen', 'lostFocus', 'managingFocus', 'maximumSize', 'maximumSizeSet', 'minimumSize', 'minimumSizeSet', 'mixingCutoutShape', 'mouseClicked', 'mouseDown', 'mouseDrag', 'mouseDragged', 'mouseEnter', 'mouseEntered', 'mouseExit', 'mouseExited', 'mouseListener', 'mouseListeners', 'mouseMotionListener', 'mouseMotionListeners', 'mouseMove', 'mouseMoved', 'mousePosition', 'mousePressed', 'mouseReleased', 'mouseUp', 'mouseWheelListener', 'mouseWheelListeners', 'mouseWheelMoved', 'move', 'name', 'nextFocus', 'nextFocusableComponent', 'notify', 'notifyAll', 'opaque', 'optimizedDrawingEnabled', 'paint', 'paintAll', 'paintComponents', 'paintImmediately', 'paintingForPrint', 'paintingTile', 'parent', 'postEvent', 'preferredSize', 'preferredSizeSet', 'prepareImage', 'print', 'printAll', 'printComponents', 'propertyChange', 'propertyChangeListener', 'propertyChangeListeners', 'putClientProperty', 'recreateGUI', 'registerKeyboardAction', 'registeredKeyStrokes', 'remove', 'removeAll', 'removeAncestorListener', 'removeComponentListener', 'removeContainerListener', 'removeFocusListener', 'removeHierarchyBoundsListener', 'removeHierarchyListener', 'removeInputMethodListener', 'removeKeyListener', 'removeMouseListener', 'removeMouseMotionListener', 'removeMouseWheelListener', 'removeNotify', 'removePropertyChangeListener', 'removeVetoableChangeListener', 'repaint', 'requestDefaultFocus', 'requestFocus', 'requestFocusEnabled', 'requestFocusInWindow', 'resetKeyboardActions', 'reshape', 'resize', 'revalidate', 'rootPane', 'scrollRectToVisible', 'setActionMap', 'setAlignmentX', 'setAlignmentY', 'setAutoscrolls', 'setBackground', 'setBorder', 'setBounds', 'setComponentOrientation', 'setComponentPopupMenu', 'setComponentZOrder', 'setCursor', 'setDebugGraphicsOptions', 'setDefaultLocale', 'setDoubleBuffered', 'setDropTarget', 'setEnabled', 'setFocusCycleRoot', 'setFocusTraversalKeys', 'setFocusTraversalKeysEnabled', 'setFocusTraversalPolicy', 'setFocusTraversalPolicyProvider', 'setFocusable', 'setFont', 'setForeground', 'setIgnoreRepaint', 'setInheritsPopupMenu', 'setInputMap', 'setInputVerifier', 'setLayout', 'setLocale', 'setLocation', 'setMaximumSize', 'setMinimumSize', 'setMixingCutoutShape', 'setName', 'setNextFocusableComponent', 'setOpaque', 'setPreferredSize', 'setRequestFocusEnabled', 'setSize', 'setToolTipText', 'setTransferHandler', 'setUI', 'setVerifyInputWhenFocusTarget', 'setVisible', 'show', 'showing', 'size', 'toString', 'toolTipText', 'toolkit', 'topLevelAncestor', 'transferFocus', 'transferFocusBackward', 'transferFocusDownCycle', 'transferFocusUpCycle', 'transferHandler', 'treeLock', 'unregisterKeyboardAction', 'update', 'updateUI', 'valid', 'validate', 'validateRoot', 'verifyInputWhenFocusTarget', 'vetoableChange', 'vetoableChangeListener', 'vetoableChangeListeners', 'visible', 'visibleRect', 'wait', 'width', 'x', 'y']

```

so you should be able to do a “.setLayout()” on that component as well… (not sure if the pen/checkboxes are embedded directly under this jcomponent) – you might have to do some testing/trial & error

Kind Regards,

-Paul

---

<div class="post-metadata">

**Author:** ![pascal](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pascal](https://forum.inductiveautomation.com/u/pascal)\
**Post date:** [February 17, 2020, 7:42am UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/7 "2020-02-17T07:42:32Z")

</div>

That is what i did last week but when it did’nt work. I used setLayout(FlowLayout()) but the output is always the same.  
I’ll have to dig that up.

Thanks anyways !

---

<div class="post-metadata">

**Author:** ![paul.bouillon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul.bouillon/32/7980_2.png) [@paul.bouillon](https://forum.inductiveautomation.com/u/paul.bouillon)\
**Post date:** [February 18, 2020, 11:56pm UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/8 "2020-02-18T23:56:04Z")

</div>

Hey Pascal,

I’m thinking that there are a few components embedded within the pen control… one JPanel, and JScrollPane – the latter, I presume is to resize based on the tag count?

I would imagine that you would need to change/update the layout manager for the JScrollPane… e.g.

```auto
from java.awt import BorderLayout, FlowLayout
	from javax.swing import JScrollPane
	from com.inductiveautomation.factorypmi.application.components.PMIEasyChart import PenPanel
	for c in self.getComponents(): # iterate over the jcomponents
		if isinstance(c, PenPanel): # find the pen control panel
			print(dir(c))

			for ch in c.getComponents(): # inspect the children of the pen control
				if isinstance(ch, JScrollPane): # find the tag list portion of the pen control
					pass
					#do something with this layout manager?
			self.remove(c) # remove it from the layout manager
			self.add(c, BorderLayout.PAGE_END) # add it back to the bottom
			self.validate() # repaint!

```

Hope this helps!

-Paul

---

<div class="post-metadata">

**Author:** ![Vaishnavi.V](https://avatars.discourse-cdn.com/v4/letter/v/b19c9b/32.png) [@Vaishnavi.V](https://forum.inductiveautomation.com/u/Vaishnavi.V)\
**Post date:** [April 20, 2021, 10:17am UTC](https://forum.inductiveautomation.com/t/easy-chart-pen-control-panel/12559/9 "2021-04-20T10:17:18Z")

</div>

Hi paul, I would like to access the checkboxes in the pencontrolpanel of the easy chart.I would like to display the tooltip text whenever we hover on the checkbox.Please help me out!
