Add dynamically SKLabelNode to MKTVIew - swift

I am working on metal view that shows the heart rate graph. between every peak of this graph, I need to add a label.
In this process, chart moving from right to left
I have an array that dynamically shows the x coordinate of this label
for example when one value should show in the screen, this array contain only element and if there are more, it contain more element, this array is named coordinates
I use a for loop to get every element
for coordinate in coordinates {
}
I also have another array that dynamically shows the text of the label, and it works same as coordinates. It's named rrIntervalData.
to define this label, I asked another question here: Render text with SKRenderer
here is my code
skScene.size = CGSize(width: CGFloat(viewportSize.x), height: CGFloat(viewportSize.y))
for coordinate in coordinates {
var index = 0
skLabel.text = "\(rrIntervalData[index].value)"
skLabel.position = CGPoint(x: Int(coordinate), y: 200)
skLabel.fontSize = 20
skLabel.fontColor = SKColor.red
index += 1
}
skLabel is a SKLabelNode.
I also have skScene.addChild(skLabel), that I added in the init of the parent class (I know this is not correct), If I add it here, the app get crashed because skLabel is already added to skScene.
In the current version, the label is created in every point, and it moves with graph (as expected), but when the coordinate of the new label comes to screen, the first label is gone and it shows in the second position, and If I zoom out the graph when it should show more than 20 label in a same time, it always show the label in the last label in the right side.
how can I create a dynamic number of labels that set set here and stick with every coordinate and value?
Your help will be appreciated, It has been more than a week that I couldn't deal with adding this label.

Related

Map Center & Bounds do not update when Container Div is Resized

(pretty new to Mapbox and JS, so I'm in a bit over my head)
I'm working on a page where the user needs to adjust the size of map container. It needs to be able to get accurate bounds and center point of the resized map (via map.getBounds and map.getCenter).
When I use JS to adjust the size of the container div, the center and bounds are not adjusted.
Fiddle: http://jsfiddle.net/xcow63sm/3/
Panning/zooming results in updated center and bounds. Browser window resize (if you have width or height set to 100%) works too. I would expect changing the container dimensions would adjust center and bounds.
However, if you use the form fields to adjust the height/width of the container div, the center and bounds do not. I've tried (with increasing desperation):
function resize (){
var inputwidth = document.getElementsByName("mapwidth")[0].value;
var inputheight = document.getElementsByName("mapheight")[0].value;
var mapDiv = document.getElementById('map');
var mapcenter = map.getCenter();
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.updateSize();
map.update();
map.resize();
map.invalidateSize();
document.getElementById("mapcenter").value = mapcenter;
Edit: this seems to apply but I can't make sense of it: Resizing a leaflet map on container resize
If I understand you, you have two issues: you don't like how the map is positioned after its size changes, and you're getting white space.
Map positioning after resize
There are at least three valid options for how a map should update if, say, its width and height are suddenly doubled:
keep the same northern and western bound, extend the eastern and southern bounds. (Expanding the viewing area right and down)
move all four bounds outwards (keeping the centre of the map in the same place)
leave all four bounds where they are are, but change the zoom, so the same geographic area is displayed, but in more detail.
I think your issue is that Mapbox is choosing option 1, but you want one of the other two options. The solution, as I think you've discovered, is simply to do your own maths and set the bounds how you want them.
Map failing to repaint correctly
Your second issue is that when you resize, calling map.resize() isn't updating the internal size of the map properly, and you're left with white space. The reason for this is you're using animated CSS properties. So when you do this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.resize();
This doesn't work because the map's size hasn't actually transitioned to the new size yet. You can work around it like this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
window.setTimeout(()=>map.resize(), 500);
There's probably a better event you can listen to, to keep updating as the map area expands.
Updated fiddle here: http://jsfiddle.net/xcow63sm/11/
Btw you should consult the documentation here. I'm not sure where you got map.updateSize() from but that's not Mapbox-GL-JS :)

Prevent insertText from placing text on previously inserted text?

I have a picture, for which I have the x and y coordinates for multiple objects. Each object has a name. I wish to use insertText to place the name in the middle of the object. Considering the large amount of objects per image, sometimes the text overlaps.
Currently, i use this which writes the text exactly to the middle.
I = imread(some_image.jpg); % load image
for i = 1:length(object) % for each object
m = mean(object(i,1:2))); % get the middle
I = insertText(I,m,[name]); % and write label.
end
What I want is a new label to be moved slightly, so that the newest label does not overlap with an old label.

Unity Resizing Dropdown Dynamically

I have a dropdown list on a filter panel which needs to stretch dynamically to fit the content as shown:
I have tried several content size fitters but cannot find anything, If possible I would like to set a max width it can expand to then truncate everything longer than that, I would also like it to expand only to the right with a right pivot point. I have found a similar example here: https://forum.unity3d.com/threads/resize-standard-dropdown-to-fit-content-width.400502/
Thanks!
Well. Lets start with the code from that Unity forum thread.
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
widest = Mathf.Max(item.preferredWidth, widest);
}
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
We want to have a max-width allowed, so any content longer than this will be truncated. So let's add that variable:
var maxWidth = 250f;
//or whatever value; you may wish this to be a property so you can edit it in the inspector
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
Now we use the smaller of the two width values. Then apply it to the content layout:
}
widest = Mathf.Min(maxWidth, widest);
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
The +40 should be retained because that deals with the scrollbar. Your maxWidth value should be chosen to account for this.
Finally we want the longer items to get cut off nicely.
Give each dropdown item a Rect Mask 2D component (Component -> UI -> Rect Mask 2D). The template object exists in the scene hierarchy before the game is run, just disabled. You can just add the component to the parent transform, the one with the image (so the text is clipped).
You'll need to make sure that the mask covers the same width as the image graphic and expands along with it, possibly slightly shorter on the X direction so the text gets cut off before the image border is drawn. This should happen automatically, but you will need to check and possibly make some alterations to the template object. Alternatively you can use an Image Mask, but you'll have to play with that one yourself, but it will allow for non-rectangular clipping.
That's it!

plotsymbol label

I'm playing with core-plot to generate a scatter plot. I've added a plot symbol and want to add a label near every symbol.
I able to do that but want to change the position of this label. I can set the offset but it move the label only vertically, I need to move the label horizontally.
Any way to do that?
this picture shows what i'd like.
screen shot
Thanks
The automatic labels will always appear above the point. You can create annotations to label your data points. For each label, use CPTPlotSpaceAnnotation, anchor it to the coordinates of the data point, and set the displacement and content anchor.
To put the labels to the right of the point, set the displacement to (x, 0) where x is the number of pixels between the label and the center of the data point. Set the content anchor to (0, 0.5).

why do getOffsetWidth() and getElement().getClientWidth() return 0 for a Widget in GWT?

I'm using RaphaelGWT to draw shapes with the underlying RaphaelJS library. Both projects are wonderful. However I was stuck for awhile on the issue of Text objects in Raphael being displayed as centered by default.
I've tried to create one Text object and let it be centered by default, then measure its width in order to adjust the position for a 2nd text object and then remove the first. But I can't get the width of the original Text object.
FYI, in RaphaelGWT, the Shape objects used extend Widget. So I've tried getAbsoluteLeft(), getElement().getAbsoluteRight(), getOffsetWidth(), getElement().getClientWidth(). getAbsoluteLeft() is the only one that returns what I would expect. getAbsoluteRight()returns the same value as getAbsoluteLeft(), and both getOffsetWidth() and getElement().getClientWidth() return 0.
Why?
FYI, I calculated the width from the original x value used to create the Text Shape (x then became the center) and getAbsoluteLeft(), which actually returned the expected value.
The element has to be visible for getOffsetWidth() to return correct values.