How do I get the elementView size of UML classes using JointJS? - jointjs

I'm implementing the class diagram where the users can change the class' name, attributes and methods. I'm having trouble with resizing the class rectangle width depending on name, attribute or method length. These can overflow and go outside the rectangle, and I just can't find a method to get the correct size.
I also have added an element tool to the elementView, and set its x and y to "100%". According to documentation: "Use percentage strings (e.g. '40%') to position the button relatively to the element width/height." but I guess this isn't the model's size, as I typed JSON.stringify(graph.toJSON()) and got the following.
JSON.stringify(graph.toJSON())
The size is the default value I set (260x100).
I checked the size of the attribute using DevTools:
Size of attribute
The gray button detects the width number I need (330), so I guess that the x in element tools is the elementView's width. I looked at the documentation and can't find any method like .size() or .getSize() for the elementView. I need to resize the rectangle to the size of Max(name length, attribute length, method length) + some aditional space to not look cramped up. I have seen some solutions like "Use [number of letters] * [some constant]" but that is no good as typing 5 "W"s doesn't take the same space as typing 5 "i"s.
So how do I get the width of the whole element (in my case 330 from text length + the three pixels from the left border of the rectangle to the first text letter)?

Okay, so after searching through several Google Groups chats I found some pieces of code that helped me.
For getting the width I needed, I used elementView.getBBox().width.
Where I didn't have the element view right at hand, I at least had the model ID, and so I used paper.findViewByModel(modelId) to get the element view.

Related

Mplcursor hover showing _line0 on data points

Does anybody know why I would be getting "_line0" on certain points when using mplcursor hover on rectangles? I created a bunch of rectangles in a subplot and used the following code to create a cursor to show annotation when hovering over them:
def update_annotation(sel):
""" update the annotation belonging to the current selected item (sel) """
# get the label of the graphical element that is selected
label = sel.artist.get_label()
#point = sel.artist[sel.target.index]
# change the text of the annotation
sel.annotation.set_text(label)
sel.annotation.set(position=(1, 10), anncoords="offset points")
sel.annotation.get_bbox_patch().set(fc="yellow", alpha = 1)
sel.annotation.arrow_patch.set(arrowstyle="simple", fc="yellow", alpha=.5)
# create an mplcursor object that shows an annotation while hovering
cursor = mplcursors.cursor(axs[1], hover=True)
# call the function "update_annotation" each time a new element gets hovered over
cursor.connect("add", update_annotation)
However, when I hover over certain datapoint, not only is it REALLY slow to go to where I'm hovering over but it also shows me this:
My guess is that there are too many overlapping data points? If so, does anybody know a way around that and also can somebody explain to me what _line0 even means?
I realize the cursor is hovering over an empty space in the plot but it also shows _line0 when I hover over rectangles. Sometimes it will even show the label and then go back to _line0.

vtk render window GetZbufferData method

As I understand it, if I create a vtk render window, then I can add different renderers to it and for each renderer renders from a different perspective. No to actually render the scene I use the vtk render window method render() to render all renderers in parallel. Now there is a vtk render window method called GetZbufferData which apparently returns an array containing the zbuffer. So my question is, to which renderer does this zbuffer correspond to?
Thanks for any clarification.
If you have all renderers in the same window, then they will share the same framebuffer, so also the same z-buffer. So a simple answer to your question is "to all of them". To get the individual z-values, it depends on what you are exactly doing with the renderers.
If you are doing some kind of a "tiled view", you want to assign different viewports (vtkRenderer::SetViewport(), like here) to each of the renderers. Then you can access the z data for a given "tile" (renderer) by passing appropriate x,y coordinates to the GetZBufferData function. For example, to get the whole part of the z buffer that belongs to renderer ren1 of vtkRenderWindow renWin:
double x1 = ren1->GetViewport()[0] * (renWin->GetSize()[0] - 1);
double y1 = ren1->GetViewport()[1] * (renWin->GetSize()[1] - 1);
double x2 = ren1->GetViewport()[2] * (renWin->GetSize()[0] - 1);
double y2 = ren1->GetViewport()[3] * (renWin->GetSize()[1] - 1);
float *ren1Z = renWin->GetZbufferData(
static_cast<int>(x1),static_cast<int>(y1),static_cast<int>(x2),
static_cast<int>(y2));
If you have the same viewport, it would be more complicated. You can have a renderwindow with multiple "layers", by setting vtkRenderWindow::SetNumberOfLayers(int) and then you can assign each renderer to a different layer (vtkRenderer::SetLayer(0-based layer index)). The window then renders from layer 0 to the last layer over each other. If you are interested in getting only one specific renderer's z-data, you should get it if you have it render in the last layer. However, I am not sure if the z-buffer is cleaned in between individual renderer's renders, I would actually bet on that it is not, so you might also get some inconsistent mess.
I would like to complement tomj answer:
Any of the vtkRenderWindow::GetZbufferData() methods query the framebuffer for Z-values, which is contained in the vtkRenderWindow, but there is a slight remark:
You need to set this in your renderers: vtkRenderer::PreserveDepthBufferOn(). This is because as the documentation says:
"By default, the depth buffer is reset for each renderer.
If this flag is true, this renderer will use the existing depth buffer for its rendering."
So, that bring us to the vtkRenderers. There is a layering of vtkRenderers, which tells which "chain" or "precedence order" to make the drawing. Check the method vtkRenderer::SetLayer().
So, you first need to set up your layered vtkRenderers, attach them to the vtkRenderWindow, and then set up correctly if you want to preserve some depth buffers or not.
Notice that if the z-buffer has not been set (first draw of the first vtkRenderer), it will return 1.0. I'm still figuring out why, but currently that is the situation.

Set z-index of shapes in a Kinetic.Group

How do I set z-index on the shapes that I'm adding to Kinetic.Group? My group contains rectangles and images. I want to do this:
rectangle.setZIndex(1);
image.setZIndex(2);
This gives me the following error: Uncaught TypeError: Cannot read property 'children' of undefined.
I'm using drag and drop and then grouping the objects together. I want the images to be on top of the rectangle. the moveToTop() method gives errors when I call it inside my code.
EDIT :
http://jsfiddle.net/Dcevd/ . Try this use case: drag&drop two rects, then drag the image and drop it on the first rect, then move it to the second one (when you do it inversely it works). it moves to top only on dragend.
Answer to your edit
You are calling moveToTop() on a child of the group, so it will only put the image on the op of that specific group. Once you place the second rectangle on the right stage, it gets a higher z-index then the first one your placed and will therefor be 'on top of' the first rectangle (including it's images). To solve this I've set the parent of the image (the group) to move to top on the dragstart, this fixes it for me:
cloneImg.on('dragstart', function(){
this.startX=this.x();
this.startY=this.y();
this.getParent().moveToTop();
});
See also the fiddle: http://jsfiddle.net/Dcevd/3/
PS. If you look in the KineticJS docs, you see that setZIndex is available on Kinetic images (as with all other Shapes). http://kineticjs.com/docs/Kinetic.Image.html

Change z-index of marker in openlayers

I've a layer with multiple markers with rather big icons, so they overlap. Via the list on the side of the map users can select a marker and the map will pan (and zoom) to it. But it will still be behind some other makers.
How do I get a individual makers z-index and set it? I would be useful to get the highest used z-index and just add one. (another solution is to add the total number of markers to the z-index)
The markers (or features) are in a myLib.features array. The console doesn't show any z-index type functions.
I can't find a appropriate example or api function for this.
EDIT:
I found this example: http://dev.openlayers.org/examples/ordering.html
I don't really understand it. Somehow the created feature takes the next z-index given by the layer via somekind of symbolizer. I have no idea how to work this static sort into a dynamic one.
Try this:
First of all, make sure you are using a OpenLayers.Layer.Vector layer, not a OpenLayers.Layer.Markers layer. Apparently the Markers layer is old news and all new development is done in the Vector layer. It has more features. (I wasted a pile of time with the Markers layer myself).
Then, each of your markers needs to be a OpenLayers.Feature.Vector object. The constructor takes three arguments, the third of which is called the style. The style is where you set your image attributes, the background shadow, the mouse-over text, and the z-index, which has the property name "graphicZIndex". I think that's what you're looking for.
http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Feature/Vector-js.html#OpenLayers.Feature.Vector.OpenLayers.Feature.Vector.style
Add your "markers" (which are Vector's) to your Vector layer with the addFeatures function. And just ignore the "options" argument.
http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Layer/Vector-js.html#OpenLayers.Layer.Vector.addFeatures
I found that example page too, and I found it confusing too. It was setting all the markers' styles in the Vector layer's constructor (as default values to be used if the marker style was omitted) instead of the marker's constructor. I think it makes more sense to set the marker style in the marker constructor.
To change the style in real-time, take one of your OpenLayers.Feature.Vector markers, called "marker" and do this. And let's call the Vector Layer "layer".
marker.style.graphicZIndex = 13;
layer.redraw();

How to know the number of pixels that a String is occupying?

I have an item ( TextField, or TextArea, ...). It has a content value , say "hello world". How to know the number of pixels that this "hello world" String value is occupying on the screen ?
You can get the preferred width/height to get a rough estimation (you would also need to add the margin's to get accurate sizing). However the layout manager views these as guidelines not as final sizes and can decide on placing a component anywhere.
During runtime e.g. paint etc. the getX/Y/Width/Height argument provide accurate component size and position. However, these are only valid for the current paint operation since a device may be rotated or might require layout reflow.
You need to be more specific on what you are trying to accomplish.

Resources