package external; import java.util.Arrays; import java.util.List; import java.util.logging.Logger; import org.python.core.Py; import org.python.core.PyInteger; import org.python.core.PyObject; import org.python.core.PyString; import org.autoplot.ScriptContext; import org.autoplot.dom.Annotation; import org.autoplot.dom.Application; import org.autoplot.dom.DomNode; import org.autoplot.dom.DomUtil; import org.autoplot.dom.Plot; import org.autoplot.jythonsupport.JythonOps; import org.das2.graph.AnchorPosition; import org.das2.graph.AnchorType; import org.das2.graph.BorderType; import org.das2.qds.ops.Ops; import org.python.core.PyJavaInstance; import org.python.core.PyList; /** * new implementation of the plot command allows for keywords in the * Jython environment. *
{@code
 * annotation( 0, 'Anno1' )
 * annotation( 1, 'Anno2', textColor='darkBlue', anchorPosition='NW'  )
 * plot( 'vap+cdaweb:ds=OMNI2_H0_MRG1HR&id=DST1800&timerange=Oct+2016' )
 * annotation( 2, 'Anno3', anchorType='DATA',pointAt='2016-10-14T07:51Z,-100', xrange='2016-10-20T00:00/PT30S', yrange='-150 to -100',
 *     anchorPosition='OutsideNE', anchorOffset='' )
 *}
* @see https://autoplot.org/help.annotationCommand * @author jbf */ public class AnnotationCommand extends PyObject { private static final Logger logger= org.das2.util.LoggerManager.getLogger("autoplot"); public static final PyString __doc__ = new PyString("

annotation([index],[named parameters])

" + "annotation puts an annotation on the canvas.\n" + "See https://autoplot.org/help.annotationCommand
\n" + "
named parameters:\n" + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "
textThe message, allowing Granny codes
textColor text color\n
background background color\n
foreground foreground color\n
fontSize size relative to parent (1.2em) or in pts (8pt)\n
borderType draw a border around the annotation text
none,rectangle,rounded_rectangle
.
anchorBorderType draw a border around the anchor box.
anchorPosition One of NE,NW,SE,SW,
N,E,W,S,
outsideN,outsideNNW
anchorOffset position relative to the anchor, like '1em,1em'
anchorType PLOT means relative to the plot.
DATA means relative to xrange and yrange
xrange, yrange anchor box when using data anchor
plotId ID of the plot containing axes. This will set the anchorType to CANVAS, unless xrange or yrange is set.
pointAt comma separated X and Y to point the annotation arrow at.
pointAtX X value to point the arrow at or to anchor the annotation.
pointAtX Y value to point the arrow at or to anchor the annotation.
rowId ID of the row containing for positioning this annotation, sets anchorType=CANVAS
(See dom.plots[0].rowId)
columnId ID of the column containing for positioning this annotation, sets anchorType=CANVAS
" + "See https://github.com/autoplot/documentation/blob/master/docs/annotations.md" + ""); private static AnchorPosition anchorPosition( PyObject val ) { AnchorPosition c=null; if (val.__tojava__(AnchorPosition.class) != Py.NoConversion) { c = (AnchorPosition) val.__tojava__(AnchorPosition.class); } else if (val instanceof PyString) { String sval = (String) val.__str__().__tojava__(String.class); c = (AnchorPosition) lookupEnum( AnchorPosition.values(), sval ); } else { throw new IllegalArgumentException("anchorPosition must be a string or AnchorPosition"); } return c; } private static Object lookupEnum( Object[] vs, String s ) { s= s.toLowerCase(); for ( Object v: vs ) { if ( v.toString().toLowerCase().equals(s) ) return v; } throw new IllegalArgumentException("unable to find enumerated value for "+s); } private static AnchorType anchorType( PyObject val ) { AnchorType c=null; if (val.__tojava__(AnchorType.class) != Py.NoConversion) { c = (AnchorType) val.__tojava__(AnchorType.class); } else if (val instanceof PyString) { String sval = (String) val.__str__().__tojava__(String.class); c = (AnchorType) lookupEnum( AnchorType.values(), sval ); } else { throw new IllegalArgumentException("anchorType must be a string or AnchorType"); } return c; } private static BorderType borderType( PyObject val ) { BorderType c=null; if ( val==Py.None ) { return BorderType.NONE; } else if (val.__tojava__(BorderType.class) != Py.NoConversion) { c = (BorderType) val.__tojava__(BorderType.class); } else if (val instanceof PyString) { String sval = (String) val.__str__().__tojava__(String.class); c = (BorderType) lookupEnum( BorderType.values(), sval ); } else { throw new IllegalArgumentException("borderType must be a string or BorderType"); } return c; } private static boolean booleanValue( PyObject arg0 ) { if ( arg0.isNumberType() ) { return arg0.__nonzero__(); } else { String s= String.valueOf(arg0); return s.equals("True") || s.equals("T") || s.equals("1"); } } /** * implement the python call. * @param args the "rightmost" elements are the keyword values. * @param keywords the names for the keywords. * @return the annotation */ @Override public PyObject __call__(PyObject[] args, String[] keywords) { FunctionSupport fs= new FunctionSupport( "annotation", new String[] { "index", "text", "textColor", "background", "foreground", "anchorPosition", "anchorOffset", "anchorType", "borderType", "anchorBorderType", "fontSize", "pointAtX", "pointAtY", "pointAt", "pointAtOffset", "xrange", "yrange", "plotId", "rowId", "columnId" }, new PyObject[] { new PyInteger(0), Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, Py.None, } ); fs.args( args, keywords ); int nparm= args.length - keywords.length; int index=0; int nargs= nparm; // If the first (zeroth) argument is an int, than this is the data source where the value should be inserted. Additional // data sources and plots will be added until there are enough. // this is an alias for the index argument. if ( args.length>0 ) { PyObject po0= args[0]; if ( po0 instanceof PyInteger ) { index= ((PyInteger)po0).getValue(); PyObject[] newArgs= new PyObject[args.length-1]; for ( int i=0; i=dom.getAnnotations().length ) { dom.getController().addAnnotation( new Annotation() ); } Annotation annotation= dom.getAnnotations(index); // reset the annotation. annotation.syncTo( new Annotation(), Arrays.asList( DomNode.PROP_ID, Annotation.PROP_PLOTID, Annotation.PROP_ROWID, Annotation.PROP_COLUMNID ) ); try { List keywordsList= Arrays.asList(keywords); for ( int i=nparm; i