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

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...