Occasionally neato produces graphs having height longer than width. Is there a way to rotate the graph so that it always have width longer than height? The problems are:
rankdir attribute is only for DOT
landscape attribute doesn't rotate the labels. Also the longest axis of the map isn't horizontal
Related
I'm developing an app where I'm facing an issue to achieve one UI layout only for iPhone devices. This is the layout that I'd like to achieve:
I want to achieve overlapped views that layout should be same on every device from 5s to 7 plus.
The key is setting proportional constraints.
Start with adding a UIView to hold the 4 elements - background, man, woman and heart.
Add a UIImage for the background, and pin the edges to the edges of the view - that's the easy part.
Add a UIImage for the Man...
Set the Aspect Ratio to 1:1 to keep it square (well, round in this case).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.6 is pretty close.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image left and above the centers. 0.64 on horizontal, and 0.9 on vertical work pretty good.
Add a UIImage for the Woman...
Set the Height and Width constraints equal to the Man image.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image right and below the centers. 1.4 on horizontal, and 1.2 on vertical work pretty good.
Add a UIImage for the Heart...
Set the Aspect Ratio to 1:1 (or whatever gives you the proper ratio for your heart image).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.15 is pretty close.
Set constraints for Centered Horizontally and Vertically... then it will need a little adjustment o note Vertical 1.05 worked for me.
Now, you just need to set appropriate constraints for the "containing" view, and all the elements will scale and position themselves within it.
When you're all done, it should (hopefully) look like this:
I put the project up in a GitHub repo for you to look at: https://github.com/DonMag/AnotherLayoutExample
I am trying to create this layout, but I am struggeling so badly that I have no words left for it. I have tried for three days but yet I can't create the layout.
I am trying to have the three imageviews in the middle scale if the height of the view changes, but they are not behaving correct. I have successfully manage to get the ratios correct though, but the images either goes behind the blue button, or the blue button suddenly looses its height or the text disappears.
Isn't it possible to have three image views in the middle that take whatever height is left after the title and text + blue button have been laid out and then properly show them with correct ratios?
You can try multiple approaches here:
Size Classes:
Lay out the views for each possible size (probably the easiest but the least flexible
Use Constraints with different priorities:
You can set a max-height for the image views by adding a constraint for the height and then setting its relationship to equal or less than. This allows the image to scale up until a maximum size is reached.
Then add a second constraint between the bottom box and the images. Set the priority of this constraint to 750. This makes the image grow in height, when the bottom view moves down.
Then add another constraint which sets the aspect ratio of the image. If you use the mode of the view to Aspect Fit, the image will now always be scaled up to fit the image view.
To make all images scale proportionally, add constraints for equal width and equal height between them, then set the factor to match the proportions between these images.
The last step is now to vertically align the images properly as you showed in the pictures. To do that, add constraints between the images, which align them by their vertical centers, bottoms, baselines or tops.
In my app for iOS 8, I have a UISegmentedControl that stretches to fit the width of the device's screen. So on an iPad it's more pixels wide than it is on an iPhone 6+, which is more pixels wide than the iPhone 6, etc.
Centered just beneath each segment of the UISegmentedControl, I have a UILabel. So there are 5 segments and 5 UILabels. Each UILabel has a fixed width (fixed by constraint). However if the display size increases they become uncentered.
How in Interface Builder can I specify a constraint that will force each UILabel to become centered beneath each segment? I would be happy if I could just get the elements to remain proportionally spaced with each other as the display size scales, but I can't figure out how to do that, either.
All I can seemingly do is to center the middle UILabel directly under the middle segment by specifying a Center X Alignment between that and the UISegmentedControl.
I specified a Horizontal Space constraint between all the UILabels, and between the outer UILabels and the edges of the view, and set all these to "greater than or equals". They all have the same priority, but strangely, they don't all scale proportionally to each other.
The resulting problem is that the amount of Horizontal Space between each of the UILabels does not scale smoothly as the width of the device's screen increases. If I align everything to be in the proper positions on the iPhone 5S width of screen, then on the iPad their alignment is all wonky, and only the middle one lines up with its segment. The rest of them are all off center.
It appears that there is no way to specify a percentage of the over-all display width as a constraint -- you can only specify things in terms of pixels. Really?!?!
Clearly I could make the width of the objects to be flexible, but because they are text labels with right-aligned text, that screws everything up.
Surely I'm missing something here... since the point of Auto Layout is to make your interface scale according to the screen size, surely there is a way to specify a constraint as a percentage of any given view or subview... surely!!! But how? I've read the documentation and I cannot, for the life of me, figure it out.
BTW I did see that in the past, people have used crude hacks like spacer views or multiple sets of constraints, but surely those are outdated answers, and I'm just overlooking something extraordinarily obvious... right?
You can do this by making the centerX constraint of your labels equal to the superview.trailing times 0.1, 0.3, 0.5, 0.7, and 0.9 with constants of 0. To make these constraints, add your 5 labels to the view. Give the left most one a vertical spacing constraint to the segmented control. Select all 5 labels and give give them a "vertical centers" alignment constraint. Now control-drag from each label to the right side of the screen, and select the "Trailing space to container margin" constraint. Edit each one of these trailing constraints to look like this (except for the multiplier that needs to be given the values I mentioned above):
You'll have to reverse the first and second item (which you do from the pull down on the first item), change the Label.trailing to Label.Center X, and uncheck the "relative to margin" box, then correct the constant and multiplier values.
This approach will only work if the segmented control stretches all the way across the screen with no padding to the edges. If you want padding to the edges, then you need to use a completely different approach. You would need to create 5 UIViews below your segmented control -- align the left edge of the left-most one to the left edge of the segmented control. Align the right edge of the right-most one to the right edge of the segmented control. Give the 5 views equal width, and 0 length horizontal spacing constraint from each to its neighbor. This will give you 5 views that mimic the segmented control in width, with each view being the same width as one of the segments (assuming all the segments are the same width -- if that's not the case, you're screwed). Then you only need to add your labels as subviews of these 5 views, and give them centerX and centerY constraints.
I have a UIButton and a UILabel constrained to be a standard distance from the bottom of the Superview. Works well on the iPad, but on the smaller iPhone screens, when other elements take up too much space, these views are pushed off the edge of the screen despite their constraint to remain a standard distance from the bottom. Why is this so?
What I would like to have happen is for the four rectangles to shrink in size so that there is still room for the "Go Back" and "Question" label to remain a standard distance from the bottom. The four rectangles can maintain aspect ratio and equal width/height by all shrinking at the same ratio. I have no constraints on their needing to be equal to or larger than a certain size. I've tried lowering their Content Compression Resistance Priority as well.
Configuration:
(I have also tried "equal" and "<=" in top spacing between "Go Back" & bottom left rectangle)
("Greater than or equal" works best on iPad to keep "Go Back" at the bottom of the screen)
How it looks on iPhone 6 and iPhone 6+ - with the labels cut off at bottom:
Did you try to lower those four buttons' height constraint's priority??
For example like this, try to set them to 750
You can make this work with a couple of changes and additions. Give the leading and trailing constraints between the top 2 rectangles and the superview a lower priority (I used 749), but still keep them as "equal". This will keep them at the standard distance from the edges if it's possible, but will allow them to have a larger spacing if the vertical space combined with the aspect ratio requires it. The problem with this, is that since they aren't required any more, when those constraints need to stretch, there's nothing that says they have to stretch equally; therefore, we need some way to keep the rectangles centered. So, instead of a spacing constraint between the left and right top rectangles, add a small view (I used 8x8) that has a centerY constraint to one of the rectangles, and zero constant spacing constraints to the two rectangles. Give this view a centerX constraint to the superview; this construct will give you the same spacing between your rectangles that you had before, but will keep them centered in the superview while allowing them to shrink in width (and height to keep the aspect ratio) if need to accommodate the vertical space.
I'm working with CorePlot to generate a bar graph with horizontal bars (CPTXYGraph and CPTBarPlot).
There are only 10 bars being plotted at any given time, but the labels for them are arbitrarily long. As a result of that the Y axis labels rotation is set to 0.5. For the longest labels there are clipping issues with the label going outside of the left and/or bottom of the plot area.
I've fixed this in the X direction by determining the width of the longest label (as rendered in the appropriate font) and rotated the appropriate way to set the left padding in the plotAreaFrame.
Due to the rotation of the labels, if the plot at the bottom of the graph has a long name it can still extend off the bottom edge of the graph and get clipped there.
I know how tall vertically the rotated label is, but where I'm stuck is trying to determine where in the plot area the axis label is being plotted so that I can determine how much bottom padding is required.
I'm not sure if I should be trying to determine how tall the X axis label section is and then subdividing the remaining height to determine where the ticks should fall, or if there's some other better way to go about it.
The label is offset from end of the nearest tick mark by the labelOffset. The position of the end of the tick mark depends on the tickDirection, tickLabelDirection, and majorTickLength.
There are methods that allow you to convert a point from the plot space coordinate system to the view coordinate system. I've ended up solving the problem with code like the following:
// Tell the graph to lay itself out if it needs to.
[self.graph layoutIfNeeded];
// Create a point that represents 0,1 as plotted on the graph.
NSDecimal plotPoint[2];
plotPoint[CPTCoordinateX] = CPTDecimalFromInt (0);
plotPoint[CPTCoordinateY] = CPTDecimalFromInt (1);
// Convert that point from the plot coordinate system to the view coordinate system
CGPoint point = [self.graph.defaultPlotSpace plotAreaViewPointForPlotPoint: plotPoint];
// If the difference between the height of the rotated label and the position that it
// will be plotted at is at least the bottom padding, then the height is too large,
// so fix the padding.
if (labelHeight - point.y >= self.graph.plotAreaFrame.paddingBottom)
[self.graph.plotAreaFrame setPaddingBottom: (labelHeight - point.y)];
My graphs have a default bottom padding already set as a minimum, allowing this code to bump it up if there isn't enough already.