Calculating the pixel size of a string - r

I'm building a GUI using R and gWidgets (primarily with RGtk2 toolkit). This GUI will display in some places labels based on a (data-defined) string. This string can be arbitrarily long, but if it is too long it will break the GUI because it will force the widget to enlarge, therefore enlarging all the parents.
So, I need to trim the string to a length based on the space available for the label. I can see two solutions:
Force the glabel to have a max size = the size of its parent; this does not appear to be doable, but I'm happy to be corrected here;
determine the length of the string and, if it is too long, clip it before rendering. This seems easier, probably using low level pango functions, but I can not find out how to use them.
Pseudocode:
interface <- gwindow()
text <- "A Very very long label just to see what happens if you try to deliberately break the identification panel with stupidly long strings"
box <- gvbox(cont = interface)
lab <- glabel(text = text, cont = box)
Idea 1:
lab <- glabel(text = text, cont = box,maxsize = size(box))
Idea 2:
strLength <- strwidth(text, font = ???)
if strLength > size(box)[1] {
# Do something about it...
}
Here my problem is the syntax of font=. How can I read the definition of the font currently used by the widget, and convert it to R-friendly font syntax? Or is there perhaps a better way (low level pango function?) to get the string size?

Related

Loading CSV with fread stops because of to large string

This is the command I'm using :
dallData <- fread("data.csv", showProgress = TRUE, colClasses = c(rep("NULL", 2), "character", rep("NULL", 37)))
but I get this error when trying to load it: R character strings are limited to 2^31-1 bytes|
Anyway to skip those values ?
Here's a strategy that may work or at least narrow down the possible sources of error. It assumes you have enough working memory to hold the data and that your separators are really commas. If you actually have tabs as separators then you will need to modify accordingly. The plan is to read using readLines which will basically ignore the quotes that are probably mismatched. Then figure out which line or lines are at fault using count.fields, table, and which.
input <- readLines("data.csv") # ignores quotes
counts.def <- count.fields(textConnection(input),
sep=",") # defaults quotes are both ' and "
table(counts.def) # might show a variety of line counts.
# Second try with just double-quotes
counts.dbl <- count.fields(textConnection(input),
sep=",", quote="\"") # just dbl-quotes
table(counts.dbl) # if all the same, then all you do is change the quotes argument
Depending on the results you may need to edit cerain lines which can be identified using which(counts.def < 40) assuming most of them are 40 as your input efforts suggest is the expected number of fields per line.
(If the tag for [ram] means you are limited and getting warnings or using virtual memory which slows things down horribly, then you should restart your OS, and only load R before trying again. R needs contiguous block of memory and Windoze isn't very good at memory management.)
Here's a small test case to work with:
input <- readLines(textConnection(
"v1,v2,v3,v4,v5,v6
text, text, text, text, text, text
text, text, O'Malley, text,text,text
junk,junk, more junk, \"text\", tex\"t, nothing
3,4,5,6,7,8")

Interactive R session - Get window width for print truncation?

Is is possible to access the current window width (in terms of characters) in an interactive session?
Say that we have a long string
x <- paste0(c(rep(letters, 10)), collapse = "")
One can use stringr to truncate the string and view it. For example:
stringr::str_trunc(x, 50)
results in
[1] "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu..."
Would it be possible to make the truncating width variable so that the printed string is as large as possible while fitting in a single line?

How to add a space to an object name in R

Piston_Rings<-diameter[1:25,]
I want my quality control graph NOT to have the underscore in the object name.
At the moment there is an underscore (not a hyphen) in that object name. It is possible to construct objects whose names have spaces in them but in order to access them you will then always need to use backticks in order to get the interpreter to understand what you want:
> `Piston Rings` <- list(1,2)
> `Piston Rings`[[1]]
[1] 1
> `Piston Rings`[[2]]
[1] 2
The problem you incur is cluttering up your code, at least relative to obeying the usual conventions in R where a space is a token-ending marker to the parser. Hyphens (at least short-hyphens) are actually minus signs.
If on the other hand you only want to use a modified version of a name that contains an underscore as the title for a graph, then try something like this:
Piston_Rings <- list() # just for testing purposes so there will be an object.
plot( 1:10,10:1, main = sub("_", " ", quote(Piston_Rings)) )
#BondedDust's answer is correct, but (guessing, since you haven't been very specific) a simpler way to get what you want is just to specify xlab or ylab arguments to the plot() function. Let's say you have variables stuff (x) and Piston_Rings (y). If you just
plot(stuff,Piston_Rings)
then the plot will have "Piston_Rings" as the y-axis label. But if you
plot(stuff,Piston_Rings,ylab="Piston Rings")
you'll get the label you want. You can also include lots more information this way:
plot(stuff,Piston_Rings,
xlab="Important stuff (really)",
ylab="Piston Rings (number per segment)")
See ?plot.default for many more options.

abcpdf7 vb6 is letter wrapping, rather than word wrapping

I am working on some legacy code and system, and trying to get auto -resizing of text working.
however, despite the code working really well. This also wraps actual single words into two words.
for example QUALITY
becomes
Has anybody any idea how to keep the word wrapping, but remove the letter wrapping.
thanks
the code:
truncated = 1
fontSize = 127
thewords = Request("words") ' try QUALITY
do while Cint(truncated) = 1
set theDoc = Server.CreateObject("ABCpdf7.Doc")
fontSize = fontSize - 2
if fontSize <= 0 Then
exit do
end if
theDoc.Rect.Width = 273
theDoc.Rect.Height = 202
theDoc.Color.Alpha = 0
theDoc.FillRect()
theDoc.Color.Alpha = 255
theDoc.FrameRect()
theFont1 = "C:\inetpub\wwwroot\fonts\fonts\Helvetica.ttf"
theDoc.Font = theDoc.EmbedFont(theFont1, Latin, False, False, True)
theDoc.Fontsize = fontsize
theDoc.VPos = 0.5
theDoc.color = "75 68 67 90"
oText = theDoc.AddTEXT(thewords)
truncated = theDoc.GetInfo(oText, "Truncated")
'Response.Write(truncated & "<br>")
Loop
Data = theDoc.Rendering.GetData("testing.png")
Response.ContentType = "image/png"
Response.BinaryWrite Data
I know this is old code, and even an old version but this is what the system runs. If anyone has a clue then it would be much appreciated.
thanks
abcPDF will only letter wrap if:
wrapping is on
There is not enough horizontal space to fit one of the words being set
There is vertical room for another line in the active rect
These conditions therefore amount to there being plenty of vertical room but not enough horizontal room for some particularly long word. So a heuristic for finding the correct font size would be to test horizontally first, using only the longest word from your string, in a temporary rect that shrinks to one more than the font size as you reduce font size; then, once you have the right font size to avoid letter wrapping, go back to testing with the original rect and full string, continuing to decrease font size until truncation completely disappears.
This will get much hairier if what you're trying to set is actually HTML with variant fonts or sizes; but for plain text in a single font and style, it should be ok.

Tool/script to find and modify numerical values in CSS file?

I simply want to go through and find every numerical value in a single, or batch of, CSS files and multiple times two, then save.
Any suggestions for the easiest way to do this?
Using regular expressions could solve your problem. For example, in python you could do the following:
import re
input = "#content {width:100px;height:20.5%;font-size:150.25%;margin-left:-20px;padding:2 0 -20 14.33333;}"
regex = re.compile("-?[.0-9]+")
scaled_numbers = [float(n)*2 for n in re.findall(regex, input)]
split_text = re.split(regex, input)
output = ''
for i in range(len(scaled_numbers)):
output += "%s%.2f" % (split_text[i], scaled_numbers[i])
output += split_text[-1]
This code could be reduced in length, but I've deliberately left it less compact for readability. One flaw with it is that it contracts floats to only 2 decimal places, but that can be easily changed if you really need extended decimals (change the number in "%s%.2f" to the desired number of places).
Note also that this code could change the names of CSS selectors (for example, #footer-2 would become #footer-4.00). If you wanted to avoid that, you'll need to adjust the code to ignore text outside of {...}.

Resources