Skip to main content

output formatting - How to resize the text content of a grid with it?


I am in a resizing mood these days. This code works quite well, up to a point.


Grid[Partition[
Table[Pane[Style[FromCharacterCode[96 + i], FontSize -> 150],
ImageSizeAction -> "ResizeToFit",
ImageSize -> {Scaled[1], Scaled[1]},
Alignment -> {Center, Center}], {i, 1, 25}], 5], Dividers -> All,

ItemSize -> {Scaled[.2], Scaled[.2]}]

It makes a 5x5 grid of 25 letters with boxes extending and shrinking according to the Notebook's width, and the strings centered in each box. The letters also shrink and expand accordingly. That's the minimal example of what I wanted.


But when I shrink the window a little too much, the result is clipped instead of shrinked:


enter image description here


And when I enlarge the window a little too much, depending on the fontsize used, the letters stop to enlarge as well, as you could probably guess, this is not what I want. Moreover, I would like the code not to be dependent on an heuristic font size.


I have tried various options but without success. Any idea, any better code ?



Answer



I don't think that you need to use either Dynamic as in Heike's answer, or FilledCurve as Mr. Wizard suggested. For this application I would just do it this way:


Grid[

Partition[
Table[Pane[Style[FromCharacterCode[96 + i]],
ImageSizeAction -> "ResizeToFit",
ImageSize -> Scaled[.5],
Alignment -> {Center, Center}
], {i, 1, 25}],
5],
Dividers -> All,
ItemSize -> {Scaled[.2], Scaled[.2]}]


I specified ImageSize -> Scaled[.5] to the Pane containing the glyphs. The Scaled here refers to the size of the enclosing object, which is the grid item whose size in turn is scaled with respect to the window width.


The FilledCurve approach is indeed pretty useful, especially when you have to resize the glyphs in a more unconventional way. E.g., if you want to stretch and squeeze them, as in this answer. But here it seems that you don't need that.


The Dynamic approach based on the CurrentValue of WindowSize has problems when your users have set a non-default view magnification for the notebook via the preferences. In that case the grid may look either too large for the window, or too small.


Edit


Since several answers mention the FilledCurve idea: the point of that idea is to replace the font glyphs by their outlines, represented as FilledCurve objects. The way I did that in the answer linked above is to export as PDF and re-import the result. But here, if you're going convert to outlines anyway, you may as well convert the whole grid to outlines instead of worrying about the dimensions of each cell entry individually.


Therefore, you could simply proceed as follows:


Show[
First@ImportString[ExportString[#, "PDF"],
"TextOutlines" -> True] &@
Grid[Partition[

Table[Pane[Style[FromCharacterCode[96 + i], FontSize -> 48],
ImageSize -> {Scaled[1], Scaled[1]},
Alignment -> {Center, Center}], {i, 1, 25}], 5],
Dividers -> All, ItemSize -> 4],
ImageSize -> Full]

The first three lines take your grid (from which I removed the automatic resizing entirely and replaced it with a completely rigid, fixed size), converts it to a Graphics object with outlined fonts, and then displays the result using ImageSize -> Full (I keep getting Full and All mixed up, and in an earlier edit I had accidentally used All, but it fortunately made no difference there).


The result resizes very smoothly in all its dimensions.


Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

equation solving - Invert and fit implicitly defined curve

I need to fit an implicitly defined curve. I thought I could get some data out of Solve , and then using FindFit . Therefore, I would like to find the relation the parametric curve defined by $F(x,y)=0$: Solve[-(1/2) + 1/2 (0.41202 BesselK[0, 0.1 Sqrt[x^2 + y^2]] + (0.101483 x BesselK[1, 0.1 Sqrt[x^2 + y^2]])/Sqrt[x^2 + y^2]) == 0, y] But I can't get an output: Solve was unable to solve the system with inexact coefficients or the system obtained by direct rationalization of inexact numbers present in the system. Since many of the methods used by Solve require exact input, providing Solve with an exact version of the system may help. >> Edit: In particular, I would like to fit the data coming from the curve with the expression of another curve, and not with a function $f(x)$. In particular, since this clearly looks like a cardioid , I would like it to fit to something like it. What other strategies could I try?

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...