Why is Sheet.setColumnWidth not in Points? Is there a workaround? - java

I'm curious why there is no implementation for Sheet.setColumnWidth that accepts a Points parameter.
There is a method to set the height of a Row in points, which is setHeightInPoints
The only available method to set the width is accepting a rather weird scale, defined as
width = Truncate([{Number of Visible Characters} * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256
This means it depends on some width of a digit, so the value used in the parameter is
just 1/256 of what is wanted here, some straight representation of a width. In Excel itself
you set the width in Points, too.
This means behaviour of Row-height and Column-width is not symetric.
Is there any rational reason for only having that version of setColumnWidth?
This leads to serious problems, as the best I can get has a different result on every computer,
because the width which is set is depending on the users default font setting.
I believe it has something to do with displaying nicely on many different setups, as the comment of pnuts suggests. But it is only usable in a very narrow field.
At the moment I believe that there is no simple workaround for that, and I cannot find one right now. (just one that works for my case perhaps)
Is there any good way to calculate a column width value from a desired points value?
I.e. I want 120 points on any computer that is using the excel export functionality. What is the width value to use as parameter here to get the wanted points width?

Related

Scale factor of a function plotter

I have done my own function plotter with java which works quite well.
All you have to do is to iterate over the with (pixels) of the panel and calculate the y-value. Then plot it with a poly-line onto the screen and that's it.
But here comes my problem: There is a scale factor between the number of pixels and the value which I want to plot.
For example I'm at the 304' iteration (iterating over the with value of the plot panel). Now I calculate the corresponding value for this pixel position (304) by the rule of three. This gives me 1.45436. Then I calculate the sin based on this value. Which is transcendetal number. Then I use again the rule of tree to determine which y-pixel this value corresponds to. Doing so, I have to round because the pixel is an integer. And there is my data loss. This data loss may give me the following result:
This looks not really nice. If I play around with resizing the window I sometimes get a smooth result.
How can I fix this problem? I've actually never seen such plots in any other function plotter.
If you do this in Java, you might consider composing your data points to a Path2D. That would have floating point coordinates, and the drawing engine would take care of smoothing things down. You might have to disable stroke control, though.

Line Break Height in android

Now I am having a code which counts the height and width of a paragraph and sets it accordingly. However I have been having this strange problems whenever a break line(\n) passes through my paragraph I use this code to calculate my Height. I also calculate the width and make sure a line is properly fit.
float textSize = t.getTextSize();
Paint paint = new Paint();
paint.setTextSize(textSize);
However for some reason a break line couldn't have the height calculated which would mean me missing a few lines or show me half a line cause of the break lines during my performed calculations.
My question is, how would I undergo the calculation of the height of a break line of the space it occupies?
I wasn't able to solve this issue. However I did try to just delete 3 more extra characters at the edge of the end point of the width. It worked. However the real problem lies more in the character width. If a character is not registered with android a calculation vs the actual out come can be very different if you have letters that are completely different that off the regular alphabet.
Using this code you can determine the edge of the endpoint.
totalCurrentWidth = t.getPaint().measureText(s.substring(start, end));
However characters not registered in the system may have a different end or no end at all(Chinese or taiwan for example).
During each individual characters used in verdana it produces a different spacing compared to the actual outcome of the text.
If anyone find something wrong with my logic feel free to comment me. I only strive to improve after all.

How to make PdfPTable calculate column-width dynamically

I want to create a PdfPTable with columns containing Strings of different lengths. I learned that the width of each cell/column are the same for each column (default) or one can set the fraction of space every column shall occupy.
However, I want the columns to be as wide as required, but not any wider, depending on the data inserted. Assume that the table fits easily on the page (no breaks!). Of course, I can manually step through all my data and calculate the maximum-String-length of each column, setting the properties of the table accordingly, but I wondered whether such a common option is already provided by itext itself.
iText is not HTML, so it doesn't have options to automatically adjust width, instead is page oriented and so you've to decide your widths, either as percentage or absolute values.
I'm afraid that to do what you ask, you've to implement your own extension by measuring the widths, as you said. See how to calculate the string with with iText.

dynamically change Y axis range in Jfreechart

I have a time series data which I can draw using jfreechart. the issue is, as new data comes in, the chart will change based on the new dataset. I used,
chart.fireChartChanged();
chartPanel.repaint();
the issue is, some data may be out of the current range of Y axis, I'm wondering how can the axis range be changed according to the maximum value in the timeseries I had so far? thanks!
I used chart.fireChartChanged(); chartPanel.repaint();… but the chart still has the old range after repaint.
This all seems unnecessarily complicated: axis ranging and notification should be automatic. In this example, the range changes as outliers accumulate, because add() "sends a SeriesChangeEvent to all registered listeners." In this example, the range is fixed, but the same notification happens.
As we can't guess how your program fails in this regard, it may help to provide an sscce that exhibits the problem(s) you describe.
Have a look at Range class .
There are many methods like
combine(Range range1, Range range2)
Creates a new range by combining two existing ranges.
expandToInclude(Range range, double value)
Returns a range that includes all the values in the specified range AND the specified value.
shift(Range base, double delta, boolean allowZeroCrossing)
Shifts the range by the specified amount.
You can use any depending upon your requirements
you might even have to add following [based on your comments]
timeaxis.setAutoRange(true);
timeaxis.setFixedAutoRange(1000.0);

"Zoom" text to be as big as possible within constraints/box

First problem: You have 400 pixels width to go on, and need to fit some text within that constraint as large as possible (thus, the text shall use that amount of space).
Throw in a new constraint: If the text is just "A", then it shall not zoom this above 100 pixels height (or some specific font size).
Then, a final situation: Linebreaks. Fit some text in the largest possible way within e.g. 400 x 150 pixels.
An obvious way is to simply start with point 1, and then increase until you can't fit it anymore. This would work for all three problems, but would be very crude. The fitting of a single line within bounds could be done by writing it with some fixed point size, check the resulting pixel bounds of the text, and then simply scale it with a transform (the text scales properly too then, check out TransformUI).
Any ideas of other ways to attack this would be greatly appreciated!
As what you are modelling is complex, especially with line breaks, then your initial proposal of trying all sizes is along the right lines, especially if it needs to be accurate.
However, rather than testing each value, you can use a binary search to find the appropriate font size. You know the size is somewhere between 1 and 100 (your upper range). using a binary search, each test sets the font size and checks the resulting layout. If the text is too large, then we search the lower half of the current range of possible values. If the font size fits, then we search the upper half. Your search will use at most 7 attempts (100 log base 2 rounded up), it will be exact, finding the largest size without going over, and it will be flexible if you need to add more requirements later, such as a mix of fonts or more stringent constraints on the layout.
I'm assuming you are using a text component that does line wrapping, and that you can set the maximum width to 400. So, you set the font size and it does the layout giving you back the required height, laying out text within the given width.
You can use hints to try to guide the algorithm to the result quicker, such as making your first guess close to the expected size, but text rendering is fast, that the performance increase may not be worth the implementation effort.
See Wikipedia - Binary Search Algorithm
I would do the following:
Assume you want W pixels wide text.
Pick an arbitrary size, say 10pt, and see what bounding box the text-string gets for that size. Lets say it gets N pixels wide.
Set the new size to 10pt * W/N, and repeat from step one, until you get within a reasonable threshold. (Hopefully it would work within one iteration.)
This relies on the fact that the width of the string, is roughly proportional to the size of the font.
I'd instantiate the Font at the largest desired size: say 72 for one inch glyphs at 72 dpi. Use TextLayout to get the bounds and scale using AffineTransform (direct) or AffineTransformOp (offscreen), while preserving the aspect ratio. Suitable RenderingHints help, too.

Categories

Resources