Anylogic: Adding text label to Rectangular Wall - anylogic

Is it possible to add a text label on top of rectangular walls in Anylogic? I am trying to dynamically create rectangular walls using code and then adding labels. So far I am able to create the walls but the text label does not appear on top of the walls as I want it.

If you are creating walls dynamically I assume you also want to create your text dynamically.
There is a little trick in AnyLogic where you can view the code that gets created for you by AnyLogic discussed in this blog post
You can use the code snipped below to draw a Text object and add it to the presentation collection (which is needed for it to be displayed)
Font _text_Font = new Font("SansSerif", 0, 10 ); // Only needed if you don't have any text in your agent else _text_Font gets created for you.
ShapeText myProgramticallyCreatedText = new ShapeText(
SHAPE_DRAW_2D, true,170.0, 90.0, 0.0, 0.0,
black,"Programatically Created text",
_text_Font, ALIGNMENT_LEFT );
presentation.add(myProgramticallyCreatedText);
Here is the syntax for creating your
ShapeText(boolean ispublic, double x, double y, double rotation, java.awt.Color color, java.lang.String text, java.awt.Font font, TextAlignment alignment)
Constructs a 2D-only text shape with specific attributes.
ShapeText(ShapeDrawMode drawMode, boolean ispublic, double x, double y, double z, double rotation, java.awt.Color color, java.lang.String text, java.awt.Font font, TextAlignment alignment)
Constructs a text shape with specific attributes.
Depending on whether or not you have 3D or not you can rotate the text by changing the correct parameters
If you want to make it visible in 3d and also rotate it correctly you need to create a group, add the text to that group, then create a new group, and the group this new group and then rotate the first group. Like below
Font _text_Font = new Font("SansSerif", 0, 10 );
ShapeText myProgramticallyCreatedText = new ShapeText(
SHAPE_DRAW_2D3D, true,170.0, 90.0, 0.0, 0.0,
black,"Programatically Created text",
_text_Font, ALIGNMENT_LEFT );
ShapeGroup innerGroup = new ShapeGroup(this, SHAPE_DRAW_2D3D, true, 170.0, 20.0, 0.0, 0.0 , myProgramticallyCreatedText );
ShapeGroup outerGroup = new ShapeGroup(this, SHAPE_DRAW_2D3D, true, 170.0, 20.0, 0.0, 0.0 , innerGroup );
innerGroup.setRotationX(-PI/2 );
presentation.add(outerGroup);
(P.S. I figured all of this out using the trick from the blog post referenced above ;-) )

If it should show horizontally on top of the wall, just ensure it has the same x,y coordinates as the center of the wall and then set the z-coordinate higher than the wall height.
If you want to show it vertically (like a clock hanging from the wall), you need to set the xY coordinates carefully so it does not display inside the wall. Z coordinate half way of the wall height. And then you need to do a trick to turn the text: put it into a group and rotate the group. The example model "Airport terminal" does that, check it out

Related

iText 7 Adding colored text and fill to a rectangle

I am trying to add colored text to a rectangle and fill color in the rectangle but the
text seems to be behind the rectangle and so is not visible even though I can select it.
Paragraph = new Paragraph("The quick brown fox");
PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
Rectangle rect = new Rectangle(ps.getWidth() - 90, ps.getHeight() - 100, 50, 50);
new Canvas(canvas, pdfDoc, rect)
.setFontColor(ColorConstants.WHITE)
.setFontSize(12)
.add(p);
canvas.rectangle(rect)
.setFillColor(ColorConstants.LIGHT_GRAY)
.fillStroke();
You first draw the text and then fill the rectangle. Thus, obviously the text ends up behind the rectangle.
Switch the order of your instructions, first fill the rectangle rect on your PdfCanvas canvas and then add the Paragraph p to the Canvas on canvas.

leaflet editable restrict draw to a specific area

In Leaflet.Editable I want to confine/limit my customers to draw only in a specific area/bounds.
actually im trying to limit them to (90, -90, 180, -180) bounds of map..
maxBounds: [[-90, -180], [90, 180]]
I was not able to find anything anywhere and it seems that i am missing something.
CODEPEN DEMO
please help.
EDIT:
the Y axis is blocking correctly and mouse cannot stretch shape beyond top and bottom.
the problem is in X axis (as seen in pictures)
as for now i solved it with after save check and clear shape if it out of map bounds (BAD USER EXPERIENCE). i need a mouse confinement just like y axis does.
Without knowing your use case (why the whole world map??) Quickest and easiest fix would be to simply set the map's minZoom to something a bit higher, for example, I found that minZoom: 5 was adequate except for cases where the map was both really short and really wide (which is rarely the case in most apps I've seen).
But the real fix involves writing your own custom overrides for dragging markers and shapes.
According to API doc the L.Editable plugin allows you to override a bunch of stuff including the VertexMarker class, via map.editTools.options.vertexMarkerClass.
Fixed codepen: http://codepen.io/anon/pen/GrPpRY?editors=0010
This snippet of code that allows you to constrain the longitude for dragging vertex markers by correcting values under -180 and over 180 is this:
// create custom vertex marker editor
var vertexMarkerClass = L.Editable.VertexMarker.extend({
onDrag: function(e) {
e.vertex = this;
var iconPos = L.DomUtil.getPosition(this._icon),
latlng = this._map.layerPointToLatLng(iconPos);
// fix out of range vertex
if (latlng.lng < -180) {
e.latlng.lng = latlng.lng = -180;
this.setLatLng(latlng);
}
if (latlng.lng > 180) {
e.latlng.lng = latlng.lng = 180;
this.setLatLng(latlng);
}
this.editor.onVertexMarkerDrag(e);
this.latlng.update(latlng);
this._latlng = this.latlng; // Push back to Leaflet our reference.
this.editor.refresh();
if (this.middleMarker) this.middleMarker.updateLatLng();
var next = this.getNext();
if (next && next.middleMarker) next.middleMarker.updateLatLng();
}
});
// attach custom editor
map.editTools.options.vertexMarkerClass = vertexMarkerClass;
I didn't code for dragging the shape as a whole (the rectangle, in this case). While the VertexMarker fix should address all kinds of vertex dragging, you need to override each shape's drag handler to properly constrain the bounds. And if bounds are exceeded, crop the shape appropriately. As was pointed out, Leaflet already does this for latitude, but because Leaflet allows wrapping the map around horizontally you have your essential problem. Using rec.on("drag") to correct the bounds when they cross over your min/max longitude is the only way to address it. It is basically the same solution as I have laid out for the vertexMarkerClass - actual code left as exercise for the diligent reader.

How do I add a units label to a ILNumerics Colorbar

I would like to display the units in text for the values displayed on the colorbar. I have a colorbar added to my ILSurface and I'd like to show my units in text on the color bar along with the range.
Edit: I want to display text at the bottom of the color bar below the bottom tick just the one label.
I was able to get this to work this way
new ILColorbar()
{
Children = { new ILLabel("nm") {Position = new Vector3(.2f,.98f,0) } }
}
I have to say the Position coordinates are not very intuitive. I had to basically adjust the numbers by trial and error until it fit. I knew that the values range 0..1 so the X value was 1 at the bottom but I wanted it up from the border. And the Y value would need to be indented in some but I wasn't sure what was a good value but .2 works.
You can access the axis of ILColorbar and configure it in the usual way. Use the LabelTransformFunc on the ticks to set your own label text. You can use the default transform func and add your unit string.
Example:
var cb = scene.First<ILColorbar>();
cb.Axis.Ticks.LabelTransformFunc = (ind, val) =>
{
return ILTickCollection.DefaultLabelTransformFunc(ind, val) + "nm";
};
You can read more about the axis configuration here:
Axis Configuration
LabelTransformFunc in ApiDoc
Edit:
If only one label is needed, then add a new ILLabel object in ILColorbar group as follows:
new ILColorbar() {
new ILLabel("z(nm)") {
Position = new Vector3(0.5,1,0),
Anchor = new PointF(0.5f,0)
}
}
The ILColorbar area have the relative coordinates 0..1 over the width and the height of the color bar. So we set position x in the middle of the ILColorbar, and position y at the bottom.
The Anchor position is used as relative position in relation to the Position point.
ILLabel Documentation

How to draw border around the chart area in Google Charts?

I need a border around just the chart area and not the whole chart. I can't find what property to set. This is in the Google Visualization API.
The appropriate option is undocumented. You need to set the chartArea.backgroundColor.stroke and chartArea.backgroundColor.strokeWidth options. The stroke option controls the color of the border, and takes any valid HTML color string. The strokeWidth option controls the width of the border, and takes an integer for the width in pixels:
chartArea: {
backgroundColor: {
stroke: '#4322c0',
strokeWidth: 3
}
}

CGAffineTransform help, flipping a label

I basically have a pie chart where I have lines coming out of each segment of the pie chart. So in the case where the line comes out of the circle to the left, when I draw my text, it is reversed. "100%" would look like => "%001" (Note, the 1 and % sign are actually drawn in reverse to, like if a mirror. So the little overhang on top of the 1 points to the right, rather than the left.)
I tried reading through Apple's docs for the AffineTransform, but it doesn't make complete sense to me. I tried making this transformation matrix to start:
CGAffineTransform transform1 = CGAffineTransformMake(-1, 0, 0, 1, 0, 0);
This does flip the text around its x-axis so the text now looks correct on the left side of the circle. However, the text is now on the line, rather than at the end of the line like it originally was. So I thought I could translate it by moving the text in the x-axis direction by changing the tx value in the matrix. So instead of using the above matrix, I used this:
CGAffineTransform transform1 = CGAffineTransformMake(-1, 0, 0, 1, -strlen(t1AsChar), 0);
However, the text just stays where it's at. What am I doing wrong? Thanks.
strlen() doesn't give you the size of the rendered text box, it just gives you the length of the string itself (how many characters that string has). If you're using a UITextField you can use textField.frame.size.width instead.